Initial version of libomxil-e9110-v4l2 92/196892/1 accepted/tizen/unified/20190114.060208 submit/tizen/20190114.032700
authorSejun Park <sejun79.park@samsung.com>
Mon, 7 Jan 2019 10:11:33 +0000 (19:11 +0900)
committerSejun Park <sejun79.park@samsung.com>
Mon, 7 Jan 2019 10:11:33 +0000 (19:11 +0900)
Change-Id: I970b7b27cbc227dad0586911b006cab8bf8d7b4c

158 files changed:
COPYING [new file with mode: 0755]
Makefile.am [new file with mode: 0755]
autogen.sh [new file with mode: 0755]
config.guess [new file with mode: 0755]
config.sub [new file with mode: 0755]
configure.ac [new file with mode: 0755]
exynos/Makefile.am [new file with mode: 0755]
exynos/libvideocodec/ExynosVideoInterface.c [new file with mode: 0755]
exynos/libvideocodec/Makefile.am [new file with mode: 0755]
exynos/libvideocodec/dec/ExynosVideoDecoder.c [new file with mode: 0755]
exynos/libvideocodec/enc/ExynosVideoEncoder.c [new file with mode: 0755]
exynos/libvideocodec/include/ExynosVideoApi.h [new file with mode: 0755]
exynos/libvideocodec/include/ExynosVideoDec.h [new file with mode: 0755]
exynos/libvideocodec/include/ExynosVideoEnc.h [new file with mode: 0755]
exynos/libvideocodec/mfc_headers/exynos_mfc_media.h [new file with mode: 0755]
exynos/libvideocodec/osal/ExynosVideo_OSAL.c [new file with mode: 0755]
exynos/libvideocodec/osal/include/ExynosVideo_OSAL.h [new file with mode: 0755]
exynos/libvideocodec/osal/include/ExynosVideo_OSAL_Dec.h [new file with mode: 0755]
exynos/libvideocodec/osal/include/ExynosVideo_OSAL_Enc.h [new file with mode: 0755]
libomxil-e9110-v4l2.manifest [new file with mode: 0755]
omxil-e9110-v4l2.pc.in [new file with mode: 0755]
openmax/Makefile.am [new file with mode: 0755]
openmax/component/Makefile.am [new file with mode: 0755]
openmax/component/common/Exynos_OMX_Basecomponent.c [new file with mode: 0755]
openmax/component/common/Exynos_OMX_Basecomponent.h [new file with mode: 0755]
openmax/component/common/Exynos_OMX_Baseport.c [new file with mode: 0755]
openmax/component/common/Exynos_OMX_Baseport.h [new file with mode: 0755]
openmax/component/common/Exynos_OMX_Resourcemanager.c [new file with mode: 0755]
openmax/component/common/Exynos_OMX_Resourcemanager.h [new file with mode: 0755]
openmax/component/common/Makefile.am [new file with mode: 0755]
openmax/component/video/Makefile.am [new file with mode: 0755]
openmax/component/video/dec/Exynos_OMX_Vdec.c [new file with mode: 0755]
openmax/component/video/dec/Exynos_OMX_Vdec.h [new file with mode: 0755]
openmax/component/video/dec/Exynos_OMX_VdecControl.c [new file with mode: 0755]
openmax/component/video/dec/Exynos_OMX_VdecControl.h [new file with mode: 0755]
openmax/component/video/dec/Makefile.am [new file with mode: 0755]
openmax/component/video/dec/h264/Exynos_OMX_H264dec.c [new file with mode: 0755]
openmax/component/video/dec/h264/Exynos_OMX_H264dec.h [new file with mode: 0755]
openmax/component/video/dec/h264/Makefile.am [new file with mode: 0755]
openmax/component/video/dec/h264/library_register.c [new file with mode: 0755]
openmax/component/video/dec/h264/library_register.h [new file with mode: 0755]
openmax/component/video/dec/hevc/Exynos_OMX_HEVCdec.c [new file with mode: 0755]
openmax/component/video/dec/hevc/Exynos_OMX_HEVCdec.h [new file with mode: 0755]
openmax/component/video/dec/hevc/Makefile.am [new file with mode: 0755]
openmax/component/video/dec/hevc/library_register.c [new file with mode: 0755]
openmax/component/video/dec/hevc/library_register.h [new file with mode: 0755]
openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c [new file with mode: 0755]
openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h [new file with mode: 0755]
openmax/component/video/dec/mpeg2/Makefile.am [new file with mode: 0755]
openmax/component/video/dec/mpeg2/library_register.c [new file with mode: 0755]
openmax/component/video/dec/mpeg2/library_register.h [new file with mode: 0755]
openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c [new file with mode: 0755]
openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h [new file with mode: 0755]
openmax/component/video/dec/mpeg4/Makefile.am [new file with mode: 0755]
openmax/component/video/dec/mpeg4/library_register.c [new file with mode: 0755]
openmax/component/video/dec/mpeg4/library_register.h [new file with mode: 0755]
openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.c [new file with mode: 0755]
openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h [new file with mode: 0755]
openmax/component/video/dec/vc1/Makefile.am [new file with mode: 0755]
openmax/component/video/dec/vc1/library_register.c [new file with mode: 0755]
openmax/component/video/dec/vc1/library_register.h [new file with mode: 0755]
openmax/component/video/dec/vp8/Exynos_OMX_Vp8dec.c [new file with mode: 0755]
openmax/component/video/dec/vp8/Exynos_OMX_Vp8dec.h [new file with mode: 0755]
openmax/component/video/dec/vp8/Makefile.am [new file with mode: 0755]
openmax/component/video/dec/vp8/library_register.c [new file with mode: 0755]
openmax/component/video/dec/vp8/library_register.h [new file with mode: 0755]
openmax/component/video/dec/vp9/Exynos_OMX_Vp9dec.c [new file with mode: 0755]
openmax/component/video/dec/vp9/Exynos_OMX_Vp9dec.h [new file with mode: 0755]
openmax/component/video/dec/vp9/Makefile.am [new file with mode: 0755]
openmax/component/video/dec/vp9/library_register.c [new file with mode: 0755]
openmax/component/video/dec/vp9/library_register.h [new file with mode: 0755]
openmax/component/video/enc/Exynos_OMX_Venc.c [new file with mode: 0755]
openmax/component/video/enc/Exynos_OMX_Venc.h [new file with mode: 0755]
openmax/component/video/enc/Exynos_OMX_VencControl.c [new file with mode: 0755]
openmax/component/video/enc/Exynos_OMX_VencControl.h [new file with mode: 0755]
openmax/component/video/enc/Makefile.am [new file with mode: 0755]
openmax/component/video/enc/h264/Exynos_OMX_H264enc.c [new file with mode: 0755]
openmax/component/video/enc/h264/Exynos_OMX_H264enc.h [new file with mode: 0755]
openmax/component/video/enc/h264/Makefile.am [new file with mode: 0755]
openmax/component/video/enc/h264/library_register.c [new file with mode: 0755]
openmax/component/video/enc/h264/library_register.h [new file with mode: 0755]
openmax/component/video/enc/h264wfd/Exynos_OMX_H264enc_wfd.c [new file with mode: 0755]
openmax/component/video/enc/h264wfd/Exynos_OMX_H264enc_wfd.h [new file with mode: 0755]
openmax/component/video/enc/h264wfd/NOTICE [new file with mode: 0755]
openmax/component/video/enc/h264wfd/library_register.c [new file with mode: 0755]
openmax/component/video/enc/h264wfd/library_register.h [new file with mode: 0755]
openmax/component/video/enc/hevc/Exynos_OMX_HEVCenc.c [new file with mode: 0755]
openmax/component/video/enc/hevc/Exynos_OMX_HEVCenc.h [new file with mode: 0755]
openmax/component/video/enc/hevc/Makefile.am [new file with mode: 0755]
openmax/component/video/enc/hevc/library_register.c [new file with mode: 0755]
openmax/component/video/enc/hevc/library_register.h [new file with mode: 0755]
openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c [new file with mode: 0755]
openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h [new file with mode: 0755]
openmax/component/video/enc/mpeg4/Makefile.am [new file with mode: 0755]
openmax/component/video/enc/mpeg4/library_register.c [new file with mode: 0755]
openmax/component/video/enc/mpeg4/library_register.h [new file with mode: 0755]
openmax/component/video/enc/vp8/Exynos_OMX_Vp8enc.c [new file with mode: 0755]
openmax/component/video/enc/vp8/Exynos_OMX_Vp8enc.h [new file with mode: 0755]
openmax/component/video/enc/vp8/Makefile.am [new file with mode: 0755]
openmax/component/video/enc/vp8/library_register.c [new file with mode: 0755]
openmax/component/video/enc/vp8/library_register.h [new file with mode: 0755]
openmax/component/video/enc/vp9/Exynos_OMX_Vp9enc.c [new file with mode: 0755]
openmax/component/video/enc/vp9/Exynos_OMX_Vp9enc.h [new file with mode: 0755]
openmax/component/video/enc/vp9/Makefile.am [new file with mode: 0755]
openmax/component/video/enc/vp9/library_register.c [new file with mode: 0755]
openmax/component/video/enc/vp9/library_register.h [new file with mode: 0755]
openmax/core/Exynos_OMX_Component_Register.c [new file with mode: 0755]
openmax/core/Exynos_OMX_Component_Register.h [new file with mode: 0755]
openmax/core/Exynos_OMX_Core.c [new file with mode: 0755]
openmax/core/Exynos_OMX_Core.h [new file with mode: 0755]
openmax/core/Makefile.am [new file with mode: 0755]
openmax/include/exynos/Exynos_OMX_Def.h [new file with mode: 0755]
openmax/include/exynos/Exynos_OMX_Macros.h [new file with mode: 0755]
openmax/include/khronos/OMX_Audio.h [new file with mode: 0755]
openmax/include/khronos/OMX_Component.h [new file with mode: 0755]
openmax/include/khronos/OMX_ComponentExt.h [new file with mode: 0755]
openmax/include/khronos/OMX_ContentPipe.h [new file with mode: 0755]
openmax/include/khronos/OMX_Core.h [new file with mode: 0755]
openmax/include/khronos/OMX_CoreExt.h [new file with mode: 0755]
openmax/include/khronos/OMX_IVCommon.h [new file with mode: 0755]
openmax/include/khronos/OMX_Image.h [new file with mode: 0755]
openmax/include/khronos/OMX_ImageExt.h [new file with mode: 0755]
openmax/include/khronos/OMX_Index.h [new file with mode: 0755]
openmax/include/khronos/OMX_IndexExt.h [new file with mode: 0755]
openmax/include/khronos/OMX_Other.h [new file with mode: 0755]
openmax/include/khronos/OMX_Types.h [new file with mode: 0755]
openmax/include/khronos/OMX_Video.h [new file with mode: 0755]
openmax/include/khronos/OMX_VideoExt.h [new file with mode: 0755]
openmax/include/skype/OMX_Video_Extensions.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_ETC.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_ETC.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Event.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Event.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Library.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Library.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Log.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Log.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Memory.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Memory.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Mutex.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Mutex.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Platform.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Queue.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Queue.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Semaphore.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Semaphore.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_SharedMemory.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_SharedMemory.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_SkypeHD.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_SkypeHD.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Thread.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Thread.h [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Tizen.c [new file with mode: 0755]
openmax/osal/Exynos_OSAL_Tizen.h [new file with mode: 0755]
openmax/osal/Makefile.am [new file with mode: 0755]
openmax/osal/NOTICE [new file with mode: 0755]
packaging/libomxil-e9110-v4l2.spec [new file with mode: 0755]
srp.pc.in [new file with mode: 0755]

diff --git a/COPYING b/COPYING
new file mode 100755 (executable)
index 0000000..4a67574
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,203 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100755 (executable)
index 0000000..90e25c3
--- /dev/null
@@ -0,0 +1,8 @@
+ACLOCAL_AMFLAGS = -I m4
+SUBDIRS = exynos openmax
+
+pcfiles = omxil-e9110-v4l2.pc \
+          srp.pc
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = $(pcfiles)
+EXTRA_DIST = $(pcfiles)
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..a2bf629
--- /dev/null
@@ -0,0 +1,6 @@
+aclocal
+libtoolize --copy
+autoheader
+autoconf
+automake --add-missing --copy --foreign
+#./configure --with-xo-machine=W1
diff --git a/config.guess b/config.guess
new file mode 100755 (executable)
index 0000000..40eaed4
--- /dev/null
@@ -0,0 +1,1517 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
+
+timestamp='2011-05-11'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+       for c in cc gcc c89 c99 ; do
+         if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       if test x"$CC_FOR_BUILD" = x ; then
+         CC_FOR_BUILD=no_compiler_found ;
+       fi
+       ;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+       # NetBSD (nbsd) targets should (where applicable) match one or
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       #
+       # Note: NetBSD doesn't particularly care about the vendor
+       # portion of the name.  We always set it to "unknown".
+       sysctl="sysctl -n hw.machine_arch"
+       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+       case "${UNAME_MACHINE_ARCH}" in
+           armeb) machine=armeb-unknown ;;
+           arm*) machine=arm-unknown ;;
+           sh3el) machine=shl-unknown ;;
+           sh3eb) machine=sh-unknown ;;
+           sh5el) machine=sh5le-unknown ;;
+           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+       esac
+       # The Operating System including object format, if it has switched
+       # to ELF recently, or will in the future.
+       case "${UNAME_MACHINE_ARCH}" in
+           arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+               eval $set_cc_for_build
+               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+                       | grep -q __ELF__
+               then
+                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+                   # Return netbsd for either.  FIX?
+                   os=netbsd
+               else
+                   os=netbsdelf
+               fi
+               ;;
+           *)
+               os=netbsd
+               ;;
+       esac
+       # The OS release
+       # Debian GNU/NetBSD machines have a different userland, and
+       # thus, need a distinct triplet. However, they do not need
+       # kernel version information, so it can be replaced with a
+       # suitable tag, in the style of linux-gnu.
+       case "${UNAME_VERSION}" in
+           Debian*)
+               release='-gnu'
+               ;;
+           *)
+               release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+               ;;
+       esac
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit ;;
+    *:OpenBSD:*:*)
+       UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+       echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+       exit ;;
+    *:ekkoBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+       exit ;;
+    *:SolidBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+       exit ;;
+    macppc:MirBSD:*:*)
+       echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+       exit ;;
+    *:MirBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+       exit ;;
+    alpha:OSF1:*:*)
+       case $UNAME_RELEASE in
+       *4.0)
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+               ;;
+       *5.*)
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+               ;;
+       esac
+       # According to Compaq, /usr/sbin/psrinfo has been available on
+       # OSF/1 and Tru64 systems produced since 1995.  I hope that
+       # covers most systems running today.  This code pipes the CPU
+       # types through head -n 1, so we only detect the type of CPU 0.
+       ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+       case "$ALPHA_CPU_TYPE" in
+           "EV4 (21064)")
+               UNAME_MACHINE="alpha" ;;
+           "EV4.5 (21064)")
+               UNAME_MACHINE="alpha" ;;
+           "LCA4 (21066/21068)")
+               UNAME_MACHINE="alpha" ;;
+           "EV5 (21164)")
+               UNAME_MACHINE="alphaev5" ;;
+           "EV5.6 (21164A)")
+               UNAME_MACHINE="alphaev56" ;;
+           "EV5.6 (21164PC)")
+               UNAME_MACHINE="alphapca56" ;;
+           "EV5.7 (21164PC)")
+               UNAME_MACHINE="alphapca57" ;;
+           "EV6 (21264)")
+               UNAME_MACHINE="alphaev6" ;;
+           "EV6.7 (21264A)")
+               UNAME_MACHINE="alphaev67" ;;
+           "EV6.8CB (21264C)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.8AL (21264B)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.8CX (21264D)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.9A (21264/EV69A)")
+               UNAME_MACHINE="alphaev69" ;;
+           "EV7 (21364)")
+               UNAME_MACHINE="alphaev7" ;;
+           "EV7.9 (21364A)")
+               UNAME_MACHINE="alphaev79" ;;
+       esac
+       # A Pn.n version is a patched version.
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+       exitcode=$?
+       trap '' 0
+       exit $exitcode ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-morphos
+       exit ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit ;;
+    *:z/VM:*:*)
+       echo s390-ibm-zvmoe
+       exit ;;
+    *:OS400:*:*)
+       echo powerpc-ibm-os400
+       exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+       echo arm-unknown-riscos
+       exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit ;;
+    DRS?6000:unix:4.0:6*)
+       echo sparc-icl-nx6
+       exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+       case `/usr/bin/uname -p` in
+           sparc) echo sparc-icl-nx7; exit ;;
+       esac ;;
+    s390x:SunOS:*:*)
+       echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+       echo i386-pc-auroraux${UNAME_RELEASE}
+       exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+       eval $set_cc_for_build
+       SUN_ARCH="i386"
+       # If there is a compiler, see if it is configured for 64-bit objects.
+       # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+       # This test works for both compilers.
+       if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+           if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+               (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+               grep IS_64BIT_ARCH >/dev/null
+           then
+               SUN_ARCH="x86_64"
+           fi
+       fi
+       echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+       exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+       exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+       exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+       echo m68k-milan-mint${UNAME_RELEASE}
+       exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+       echo m68k-hades-mint${UNAME_RELEASE}
+       exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+       echo m68k-unknown-mint${UNAME_RELEASE}
+       exit ;;
+    m68k:machten:*:*)
+       echo m68k-apple-machten${UNAME_RELEASE}
+       exit ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c &&
+         dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+         SYSTEM_NAME=`$dummy $dummyarg` &&
+           { echo "$SYSTEM_NAME"; exit; }
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit ;;
+    Motorola:*:4.3:PL8-*)
+       echo powerpc-harris-powermax
+       exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+       echo powerpc-harris-powermax
+       exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit ;;
+    AViiON:dgux:*:*)
+       # DG/UX returns AViiON for all architectures
+       UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+       exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit ;;
+    ia64:AIX:*:*)
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       exit ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               eval $set_cc_for_build
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+               then
+                       echo "$SYSTEM_NAME"
+               else
+                       echo rs6000-ibm-aix3.2.5
+               fi
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit ;;
+    *:AIX:*:[4567])
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit ;;
+    9000/[34678]??:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+               if [ -x /usr/bin/getconf ]; then
+                   sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                   sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                   case "${sc_cpu_version}" in
+                     523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                     528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                     532)                      # CPU_PA_RISC2_0
+                       case "${sc_kernel_bits}" in
+                         32) HP_ARCH="hppa2.0n" ;;
+                         64) HP_ARCH="hppa2.0w" ;;
+                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                       esac ;;
+                   esac
+               fi
+               if [ "${HP_ARCH}" = "" ]; then
+                   eval $set_cc_for_build
+                   sed 's/^            //' << EOF >$dummy.c
+
+               #define _HPUX_SOURCE
+               #include <stdlib.h>
+               #include <unistd.h>
+
+               int main ()
+               {
+               #if defined(_SC_KERNEL_BITS)
+                   long bits = sysconf(_SC_KERNEL_BITS);
+               #endif
+                   long cpu  = sysconf (_SC_CPU_VERSION);
+
+                   switch (cpu)
+                       {
+                       case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+                       case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+                       case CPU_PA_RISC2_0:
+               #if defined(_SC_KERNEL_BITS)
+                           switch (bits)
+                               {
+                               case 64: puts ("hppa2.0w"); break;
+                               case 32: puts ("hppa2.0n"); break;
+                               default: puts ("hppa2.0"); break;
+                               } break;
+               #else  /* !defined(_SC_KERNEL_BITS) */
+                           puts ("hppa2.0"); break;
+               #endif
+                       default: puts ("hppa1.0"); break;
+                       }
+                   exit (0);
+               }
+EOF
+                   (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+                   test -z "$HP_ARCH" && HP_ARCH=hppa
+               fi ;;
+       esac
+       if [ ${HP_ARCH} = "hppa2.0w" ]
+       then
+           eval $set_cc_for_build
+
+           # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+           # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+           # generating 64-bit code.  GNU and HP use different nomenclature:
+           #
+           # $ CC_FOR_BUILD=cc ./config.guess
+           # => hppa2.0w-hp-hpux11.23
+           # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+           # => hppa64-hp-hpux11.23
+
+           if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+               grep -q __LP64__
+           then
+               HP_ARCH="hppa2.0w"
+           else
+               HP_ARCH="hppa64"
+           fi
+       fi
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit ;;
+    3050*:HI-UX:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+               { echo "$SYSTEM_NAME"; exit; }
+       echo unknown-hitachi-hiuxwe2
+       exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+       exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+       exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+       exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+       exit ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    *:UNICOS/mp:*:*)
+       echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+       FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+       echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+       exit ;;
+    5000:UNIX_System_V:4.*:*)
+       FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+       FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+       echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+       exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit ;;
+    *:FreeBSD:*:*)
+       case ${UNAME_MACHINE} in
+           pc98)
+               echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+           amd64)
+               echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+           *)
+               echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+       esac
+       exit ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit ;;
+    *:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit ;;
+    i*:windows32*:*)
+       # uname -m includes "-pc" on this system.
+       echo ${UNAME_MACHINE}-mingw32
+       exit ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit ;;
+    *:Interix*:*)
+       case ${UNAME_MACHINE} in
+           x86)
+               echo i586-pc-interix${UNAME_RELEASE}
+               exit ;;
+           authenticamd | genuineintel | EM64T)
+               echo x86_64-unknown-interix${UNAME_RELEASE}
+               exit ;;
+           IA64)
+               echo ia64-unknown-interix${UNAME_RELEASE}
+               exit ;;
+       esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+       echo i${UNAME_MACHINE}-pc-mks
+       exit ;;
+    8664:Windows_NT:*)
+       echo x86_64-pc-mks
+       exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i586-pc-interix
+       exit ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+       echo x86_64-unknown-cygwin
+       exit ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    *:GNU:*:*)
+       # the GNU system
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit ;;
+    *:GNU/*:*:*)
+       # other systems with GNU libc and userland
+       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+       exit ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit ;;
+    alpha:Linux:*:*)
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev68 ;;
+       esac
+       objdump --private-headers /bin/sh | grep -q ld.so.1
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       exit ;;
+    arm*:Linux:*:*)
+       eval $set_cc_for_build
+       if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+           | grep -q __ARM_EABI__
+       then
+           echo ${UNAME_MACHINE}-unknown-linux-gnu
+       else
+           if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+               | grep -q __ARM_PCS_VFP
+           then
+               echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+           else
+               echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+           fi
+       fi
+       exit ;;
+    avr32*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    cris:Linux:*:*)
+       echo cris-axis-linux-gnu
+       exit ;;
+    crisv32:Linux:*:*)
+       echo crisv32-axis-linux-gnu
+       exit ;;
+    frv:Linux:*:*)
+       echo frv-unknown-linux-gnu
+       exit ;;
+    i*86:Linux:*:*)
+       LIBC=gnu
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #ifdef __dietlibc__
+       LIBC=dietlibc
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+       echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+       exit ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    m32r*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef ${UNAME_MACHINE}
+       #undef ${UNAME_MACHINE}el
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+       CPU=${UNAME_MACHINE}el
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+       CPU=${UNAME_MACHINE}
+       #else
+       CPU=
+       #endif
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+       ;;
+    or32:Linux:*:*)
+       echo or32-unknown-linux-gnu
+       exit ;;
+    padre:Linux:*:*)
+       echo sparc-unknown-linux-gnu
+       exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+       # Look for CPU level
+       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+         PA7*) echo hppa1.1-unknown-linux-gnu ;;
+         PA8*) echo hppa2.0-unknown-linux-gnu ;;
+         *)    echo hppa-unknown-linux-gnu ;;
+       esac
+       exit ;;
+    ppc64:Linux:*:*)
+       echo powerpc64-unknown-linux-gnu
+       exit ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit ;;
+    sh64*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    tile*:Linux:*:*)
+       echo ${UNAME_MACHINE}-tilera-linux-gnu
+       exit ;;
+    vax:Linux:*:*)
+       echo ${UNAME_MACHINE}-dec-linux-gnu
+       exit ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit ;;
+    xtensa*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
+       echo i386-sequent-sysv4
+       exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+       # Unixware is an offshoot of SVR4, but it has its own version
+       # number series starting with 2...
+       # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+       # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit ;;
+    i*86:OS/2:*:*)
+       # If we were able to find `uname', then EMX Unix compatibility
+       # is probably installed.
+       echo ${UNAME_MACHINE}-pc-os2-emx
+       exit ;;
+    i*86:XTS-300:*:STOP)
+       echo ${UNAME_MACHINE}-unknown-stop
+       exit ;;
+    i*86:atheos:*:*)
+       echo ${UNAME_MACHINE}-unknown-atheos
+       exit ;;
+    i*86:syllable:*:*)
+       echo ${UNAME_MACHINE}-pc-syllable
+       exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit ;;
+    i*86:*:5:[678]*)
+       # UnixWare 7.x, OpenUNIX and OpenServer 6.
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       exit ;;
+    i*86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+       # uname -m prints for DJGPP always 'pc', but it prints nothing about
+       # the processor, so we play safe by assuming i586.
+       # Note: whatever this is, it MUST be the same as what config.sub
+       # prints for the "djgpp" host, or else GDB configury will decide that
+       # this is a cross-build.
+       echo i586-pc-msdosdjgpp
+       exit ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+       echo m68k-convergent-sysv
+       exit ;;
+    M680?0:D-NIX:5.3:*)
+       echo m68k-diab-dnix
+       exit ;;
+    M68*:*:R3V[5678]*:*)
+       test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+       OS_REL='.3'
+       test -r /etc/.relid \
+           && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+           && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+           && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+       /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+           && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit ;;
+    PENTIUM:*:4.0*:*)  # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                       # says <Richard.M.Bartel@ccMail.Census.GOV>
+       echo i586-unisys-sysv4
+       exit ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit ;;
+    i*86:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo ${UNAME_MACHINE}-stratus-vos
+       exit ;;
+    *:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo hppa1.1-stratus-vos
+       exit ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+       exit ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit ;;
+    BePC:Haiku:*:*)    # Haiku running on Intel PC compatible.
+       echo i586-pc-haiku
+       exit ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-6:SUPER-UX:*:*)
+       echo sx6-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-7:SUPER-UX:*:*)
+       echo sx7-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-8:SUPER-UX:*:*)
+       echo sx8-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-8R:SUPER-UX:*:*)
+       echo sx8r-nec-superux${UNAME_RELEASE}
+       exit ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit ;;
+    *:Darwin:*:*)
+       UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+       case $UNAME_PROCESSOR in
+           i386)
+               eval $set_cc_for_build
+               if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+                 if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+                     (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+                     grep IS_64BIT_ARCH >/dev/null
+                 then
+                     UNAME_PROCESSOR="x86_64"
+                 fi
+               fi ;;
+           unknown) UNAME_PROCESSOR=powerpc ;;
+       esac
+       echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+       exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       UNAME_PROCESSOR=`uname -p`
+       if test "$UNAME_PROCESSOR" = "x86"; then
+               UNAME_PROCESSOR=i386
+               UNAME_MACHINE=pc
+       fi
+       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+       exit ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+       echo neo-tandem-nsk${UNAME_RELEASE}
+       exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+       echo nse-tandem-nsk${UNAME_RELEASE}
+       exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit ;;
+    *:Plan9:*:*)
+       # "uname -m" is not consistent, so use $cputype instead. 386
+       # is converted to i386 for consistency with other x86
+       # operating systems.
+       if test "$cputype" = "386"; then
+           UNAME_MACHINE=i386
+       else
+           UNAME_MACHINE="$cputype"
+       fi
+       echo ${UNAME_MACHINE}-unknown-plan9
+       exit ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit ;;
+    SEI:*:*:SEIUX)
+       echo mips-sei-seiux${UNAME_RELEASE}
+       exit ;;
+    *:DragonFly:*:*)
+       echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit ;;
+    *:*VMS:*:*)
+       UNAME_MACHINE=`(uname -p) 2>/dev/null`
+       case "${UNAME_MACHINE}" in
+           A*) echo alpha-dec-vms ; exit ;;
+           I*) echo ia64-dec-vms ; exit ;;
+           V*) echo vax-dec-vms ; exit ;;
+       esac ;;
+    *:XENIX:*:SysV)
+       echo i386-pc-xenix
+       exit ;;
+    i*86:skyos:*:*)
+       echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+       exit ;;
+    i*86:rdos:*:*)
+       echo ${UNAME_MACHINE}-pc-rdos
+       exit ;;
+    i*86:AROS:*:*)
+       echo ${UNAME_MACHINE}-pc-aros
+       exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+       "4"
+#else
+       ""
+#endif
+       ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+       { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit ;;
+    c34*)
+       echo c34-convex-bsd
+       exit ;;
+    c38*)
+       echo c38-convex-bsd
+       exit ;;
+    c4*)
+       echo c4-convex-bsd
+       exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.sub b/config.sub
new file mode 100755 (executable)
index 0000000..30fdca8
--- /dev/null
@@ -0,0 +1,1760 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
+
+timestamp='2011-03-23'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple | -axis | -knuth | -cray | -microblaze)
+               os=
+               basic_machine=$1
+               ;;
+       -bluegene*)
+               os=-cnk
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -chorusos*)
+               os=-chorusos
+               basic_machine=$1
+               ;;
+       -chorusrdb)
+               os=-chorusrdb
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco6)
+               os=-sco5v6
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco5v6*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       1750a | 580 \
+       | a29k \
+       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+       | am33_2.0 \
+       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+       | bfin \
+       | c4x | clipper \
+       | d10v | d30v | dlx | dsp16xx \
+       | fido | fr30 | frv \
+       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | i370 | i860 | i960 | ia64 \
+       | ip2k | iq2000 \
+       | lm32 \
+       | m32c | m32r | m32rle | m68000 | m68k | m88k \
+       | maxq | mb | microblaze | mcore | mep | metag \
+       | mips | mipsbe | mipseb | mipsel | mipsle \
+       | mips16 \
+       | mips64 | mips64el \
+       | mips64octeon | mips64octeonel \
+       | mips64orion | mips64orionel \
+       | mips64r5900 | mips64r5900el \
+       | mips64vr | mips64vrel \
+       | mips64vr4100 | mips64vr4100el \
+       | mips64vr4300 | mips64vr4300el \
+       | mips64vr5000 | mips64vr5000el \
+       | mips64vr5900 | mips64vr5900el \
+       | mipsisa32 | mipsisa32el \
+       | mipsisa32r2 | mipsisa32r2el \
+       | mipsisa64 | mipsisa64el \
+       | mipsisa64r2 | mipsisa64r2el \
+       | mipsisa64sb1 | mipsisa64sb1el \
+       | mipsisa64sr71k | mipsisa64sr71kel \
+       | mipstx39 | mipstx39el \
+       | mn10200 | mn10300 \
+       | moxie \
+       | mt \
+       | msp430 \
+       | nds32 | nds32le | nds32be \
+       | nios | nios2 \
+       | ns16k | ns32k \
+       | open8 \
+       | or32 \
+       | pdp10 | pdp11 | pj | pjl \
+       | powerpc | powerpc64 | powerpc64le | powerpcle \
+       | pyramid \
+       | rx \
+       | score \
+       | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+       | sh64 | sh64le \
+       | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+       | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+       | spu \
+       | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+       | ubicom32 \
+       | v850 | v850e \
+       | we32k \
+       | x86 | xc16x | xstormy16 | xtensa \
+       | z8k | z80)
+               basic_machine=$basic_machine-unknown
+               ;;
+       c54x)
+               basic_machine=tic54x-unknown
+               ;;
+       c55x)
+               basic_machine=tic55x-unknown
+               ;;
+       c6x)
+               basic_machine=tic6x-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+               # Motorola 68HC11/12.
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+               ;;
+       ms1)
+               basic_machine=mt-unknown
+               ;;
+
+       strongarm | thumb | xscale)
+               basic_machine=arm-unknown
+               ;;
+
+       xscaleeb)
+               basic_machine=armeb-unknown
+               ;;
+
+       xscaleel)
+               basic_machine=armel-unknown
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       580-* \
+       | a29k-* \
+       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+       | avr-* | avr32-* \
+       | bfin-* | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c4x-* \
+       | clipper-* | craynv-* | cydra-* \
+       | d10v-* | d30v-* | dlx-* \
+       | elxsi-* \
+       | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+       | h8300-* | h8500-* \
+       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | i*86-* | i860-* | i960-* | ia64-* \
+       | ip2k-* | iq2000-* \
+       | lm32-* \
+       | m32c-* | m32r-* | m32rle-* \
+       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+       | mips16-* \
+       | mips64-* | mips64el-* \
+       | mips64octeon-* | mips64octeonel-* \
+       | mips64orion-* | mips64orionel-* \
+       | mips64r5900-* | mips64r5900el-* \
+       | mips64vr-* | mips64vrel-* \
+       | mips64vr4100-* | mips64vr4100el-* \
+       | mips64vr4300-* | mips64vr4300el-* \
+       | mips64vr5000-* | mips64vr5000el-* \
+       | mips64vr5900-* | mips64vr5900el-* \
+       | mipsisa32-* | mipsisa32el-* \
+       | mipsisa32r2-* | mipsisa32r2el-* \
+       | mipsisa64-* | mipsisa64el-* \
+       | mipsisa64r2-* | mipsisa64r2el-* \
+       | mipsisa64sb1-* | mipsisa64sb1el-* \
+       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+       | mipstx39-* | mipstx39el-* \
+       | mmix-* \
+       | mt-* \
+       | msp430-* \
+       | nds32-* | nds32le-* | nds32be-* \
+       | nios-* | nios2-* \
+       | none-* | np1-* | ns16k-* | ns32k-* \
+       | open8-* \
+       | orion-* \
+       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+       | pyramid-* \
+       | romp-* | rs6000-* | rx-* \
+       | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+       | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+       | sparclite-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+       | tahoe-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+       | tile-* | tilegx-* \
+       | tron-* \
+       | ubicom32-* \
+       | v850-* | v850e-* | vax-* \
+       | we32k-* \
+       | x86-* | x86_64-* | xc16x-* | xps100-* \
+       | xstormy16-* | xtensa*-* \
+       | ymp-* \
+       | z8k-* | z80-*)
+               ;;
+       # Recognize the basic CPU types without company name, with glob match.
+       xtensa*)
+               basic_machine=$basic_machine-unknown
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       abacus)
+               basic_machine=abacus-unknown
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amd64)
+               basic_machine=x86_64-pc
+               ;;
+       amd64-*)
+               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-unknown
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-unknown
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-unknown
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aros)
+               basic_machine=i386-pc
+               os=-aros
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       blackfin)
+               basic_machine=bfin-unknown
+               os=-linux
+               ;;
+       blackfin-*)
+               basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+               os=-linux
+               ;;
+       bluegene*)
+               basic_machine=powerpc-ibm
+               os=-cnk
+               ;;
+       c54x-*)
+               basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       c55x-*)
+               basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       c6x-*)
+               basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       c90)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       cegcc)
+               basic_machine=arm-unknown
+               os=-cegcc
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | j90)
+               basic_machine=j90-cray
+               os=-unicos
+               ;;
+       craynv)
+               basic_machine=craynv-cray
+               os=-unicosmp
+               ;;
+       cr16 | cr16-*)
+               basic_machine=cr16-unknown
+               os=-elf
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       crisv32 | crisv32-* | etraxfs*)
+               basic_machine=crisv32-axis
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       crx)
+               basic_machine=crx-unknown
+               os=-elf
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       decsystem10* | dec10*)
+               basic_machine=pdp10-dec
+               os=-tops10
+               ;;
+       decsystem20* | dec20*)
+               basic_machine=pdp10-dec
+               os=-tops20
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dicos)
+               basic_machine=i686-pc
+               os=-dicos
+               ;;
+       djgpp)
+               basic_machine=i586-pc
+               os=-msdosdjgpp
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       go32)
+               basic_machine=i386-pc
+               os=-go32
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i*86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i*86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i*86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i*86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m68knommu)
+               basic_machine=m68k-unknown
+               os=-linux
+               ;;
+       m68knommu-*)
+               basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+               os=-linux
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       microblaze)
+               basic_machine=microblaze-xilinx
+               ;;
+       mingw32)
+               basic_machine=i386-pc
+               os=-mingw32
+               ;;
+       mingw32ce)
+               basic_machine=arm-unknown
+               os=-mingw32ce
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       morphos)
+               basic_machine=powerpc-unknown
+               os=-morphos
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       ms1-*)
+               basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       nonstopux)
+               basic_machine=mips-compaq
+               os=-nonstopux
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       neo-tandem)
+               basic_machine=neo-tandem
+               ;;
+       nse-tandem)
+               basic_machine=nse-tandem
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       openrisc | openrisc-*)
+               basic_machine=or32-unknown
+               ;;
+       os400)
+               basic_machine=powerpc-ibm
+               os=-os400
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       parisc)
+               basic_machine=hppa-unknown
+               os=-linux
+               ;;
+       parisc-*)
+               basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+               os=-linux
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+       pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pc98)
+               basic_machine=i386-pc
+               ;;
+       pc98-*)
+               basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentium | p5 | k5 | k6 | nexgen | viac3)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon | athlon_*)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2 | pentiumiii | pentium3)
+               basic_machine=i686-pc
+               ;;
+       pentium4)
+               basic_machine=i786-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-* | athlon-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentium4-*)
+               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=power-ibm
+               ;;
+       ppc | ppcbe)    basic_machine=powerpc-unknown
+               ;;
+       ppc-* | ppcbe-*)
+               basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64)  basic_machine=powerpc64-unknown
+               ;;
+       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+               basic_machine=powerpc64le-unknown
+               ;;
+       ppc64le-* | powerpc64little-*)
+               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       pw32)
+               basic_machine=i586-unknown
+               os=-pw32
+               ;;
+       rdos)
+               basic_machine=i386-pc
+               os=-rdos
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       s390 | s390-*)
+               basic_machine=s390-ibm
+               ;;
+       s390x | s390x-*)
+               basic_machine=s390x-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sb1)
+               basic_machine=mipsisa64sb1-unknown
+               ;;
+       sb1el)
+               basic_machine=mipsisa64sb1el-unknown
+               ;;
+       sde)
+               basic_machine=mipsisa32-sde
+               os=-elf
+               ;;
+       sei)
+               basic_machine=mips-sei
+               os=-seiux
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sh5el)
+               basic_machine=sh5le-unknown
+               ;;
+       sh64)
+               basic_machine=sh64-unknown
+               ;;
+       sparclite-wrs | simso-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       strongarm-* | thumb-*)
+               basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3e)
+               basic_machine=alphaev5-cray
+               os=-unicos
+               ;;
+       t90)
+               basic_machine=t90-cray
+               os=-unicos
+               ;;
+       # This must be matched before tile*.
+       tilegx*)
+               basic_machine=tilegx-unknown
+               os=-linux-gnu
+               ;;
+       tile*)
+               basic_machine=tile-unknown
+               os=-linux-gnu
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       toad1)
+               basic_machine=pdp10-xkl
+               os=-tops20
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       tpf)
+               basic_machine=s390x-ibm
+               os=-tpf
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       xbox)
+               basic_machine=i686-pc
+               os=-mingw32
+               ;;
+       xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       xscale-* | xscalee[bl]-*)
+               basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+               ;;
+       ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       z80-*-coff)
+               basic_machine=z80-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       mmix)
+               basic_machine=mmix-knuth
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp10)
+               # there are many clones, so DEC is not a safe bet
+               basic_machine=pdp10-unknown
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+               basic_machine=sh-unknown
+               ;;
+       sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+               basic_machine=sparc-sun
+               ;;
+       cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       *-unknown)
+               # Make sure to match an already-canonicalized machine name.
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+       # First match some system type aliases
+       # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -auroraux)
+               os=-auroraux
+               ;;
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+             | -sym* | -kopensolaris* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* | -aros* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+             | -openbsd* | -solidbsd* \
+             | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+             | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -chorusos* | -chorusrdb* | -cegcc* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -linux-android* \
+             | -linux-newlib* | -linux-uclibc* \
+             | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+             | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i*86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto-qnx*)
+               ;;
+       -nto*)
+               os=`echo $os | sed -e 's|nto|nto-qnx|'`
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux-dietlibc)
+               os=-linux-dietlibc
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+       -os400*)
+               os=-os400
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -atheos*)
+               os=-atheos
+               ;;
+       -syllable*)
+               os=-syllable
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -nova*)
+               os=-rtmk-nova
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk*)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -tpf*)
+               os=-tpf
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+               os=-mint
+               ;;
+       -aros*)
+               os=-aros
+               ;;
+       -kaos*)
+               os=-kaos
+               ;;
+       -zvmoe)
+               os=-zvmoe
+               ;;
+       -dicos*)
+               os=-dicos
+               ;;
+       -nacl*)
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       score-*)
+               os=-elf
+               ;;
+       spu-*)
+               os=-elf
+               ;;
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+       c4x-* | tic4x-*)
+               os=-coff
+               ;;
+       tic54x-*)
+               os=-coff
+               ;;
+       tic55x-*)
+               os=-coff
+               ;;
+       tic6x-*)
+               os=-coff
+               ;;
+       # This must come before the *-dec entry.
+       pdp10-*)
+               os=-tops20
+               ;;
+       pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mep-*)
+               os=-elf
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       or32-*)
+               os=-coff
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-haiku)
+               os=-haiku
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-knuth)
+               os=-mmixware
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+       *-gould)
+               os=-sysv
+               ;;
+       *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+       *-sgi)
+               os=-irix
+               ;;
+       *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f30[01]-fujitsu | f700-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -cnk*|-aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -os400*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -tpf*)
+                               vendor=ibm
+                               ;;
+                       -vxsim* | -vxworks* | -windiss*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                               vendor=atari
+                               ;;
+                       -vos*)
+                               vendor=stratus
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure.ac b/configure.ac
new file mode 100755 (executable)
index 0000000..b4528d6
--- /dev/null
@@ -0,0 +1,128 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.65])
+AC_INIT([libomxil-e9110], [0.1])
+AM_INIT_AUTOMAKE([tar-ustar])
+#AC_CONFIG_HEADERS([config.h])
+
+# Set to 'm4' the directory where the extra autoconf macros are stored
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_CONFIG_FILES([
+    omxil-e9110-v4l2.pc
+    srp.pc
+    Makefile
+    exynos/Makefile
+    exynos/libvideocodec/Makefile
+    openmax/Makefile
+    openmax/osal/Makefile
+    openmax/core/Makefile
+    openmax/component/Makefile
+    openmax/component/common/Makefile
+    openmax/component/video/Makefile
+    openmax/component/video/dec/Makefile
+    openmax/component/video/dec/h264/Makefile
+    openmax/component/video/dec/hevc/Makefile
+    openmax/component/video/dec/mpeg4/Makefile
+    openmax/component/video/dec/mpeg2/Makefile
+    openmax/component/video/dec/vc1/Makefile
+    openmax/component/video/dec/vp8/Makefile
+    openmax/component/video/enc/Makefile
+    openmax/component/video/enc/h264/Makefile
+    openmax/component/video/enc/hevc/Makefile
+    openmax/component/video/enc/mpeg4/Makefile
+    openmax/component/video/enc/vp8/Makefile
+])
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_CXX
+AM_PROG_CC_C_O
+AC_PROG_LIBTOOL
+AC_PROG_AWK
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_CXX
+AM_PROG_AS
+
+# Check for libtool
+AM_PROG_LIBTOOL
+
+# Checks for libraries.
+
+# Check for pthread
+AC_SEARCH_LIBS([pthread_create], [pthread], [], [AC_MSG_ERROR([pthread is required])])
+
+# Check for libdl
+AC_SEARCH_LIBS([dlopen], [dl], [], [AC_MSG_ERROR([libdl is required])])
+
+# Checks for header files.
+AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/ioctl.h sys/time.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_INLINE
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_FUNC_MMAP
+AC_FUNC_REALLOC
+AC_CHECK_FUNCS([gettimeofday memmove memset munmap])
+
+AC_DEFINE([SLP_PLATFORM])
+AC_DEFINE([USE_IMMEDIATE_DISPLAY])
+
+
+PKG_CHECK_MODULES(EXYNOSCOMMON,exynos-common)
+AC_SUBST(EXYNOSCOMMON_CFLAGS)
+AC_SUBST(EXYNOSCOMMON_LIBS)
+
+PKG_CHECK_MODULES(TBM, libtbm)
+AC_SUBST(TBM_CFLAGS)
+AC_SUBST(TBM_LIBS)
+
+dnl use dlog ------------------------------------------------------------------
+AC_ARG_ENABLE(dlog, AC_HELP_STRING([--enable-dlog], [using dlog]),
+        [
+          case "${enableval}" in
+           yes) USE_DLOG=yes ;;
+           no)  USE_DLOG=no ;;
+           *)   AC_MSG_ERROR(bad value ${enableval} for --enable-dlog) ;;
+          esac
+        ],[USE_DLOG=no])
+
+if test "x$USE_DLOG" = "xyes"; then
+        PKG_CHECK_MODULES(DLOG, dlog)
+        AC_SUBST(DLOG_CFLAGS)
+        AC_SUBST(DLOG_LIBS)
+fi
+AM_CONDITIONAL(USE_DLOG, test "x$USE_DLOG" = "xyes")
+dnl end -----------------------------------------------------------------------
+
+AC_ARG_ENABLE([exynos9110], AC_HELP_STRING([--enable-exynos9110], [Enable exynos9110 specific code]),
+        [
+         case "${enableval}" in
+          yes) EXYNOS_9110=yes ;;
+          no)  EXYNOS_9110=no ;;
+          *)   AC_MSG_ERROR(bad value ${enableval} for --enable-exynos9110) ;;
+         esac
+        ],
+        [EXYNOS_9110=no])
+AM_CONDITIONAL([EXYNOS_9110], [test "x$EXYNOS_9110" = "xyes"])
+
+AC_ARG_ENABLE(s3dsupport, AC_HELP_STRING([--enable-s3dsupport], [use s3d support]),
+        [
+          case "${enableval}" in
+           yes) BOARD_USE_S3D_SUPPORT=yes ;;
+           no)  BOARD_USE_S3D_SUPPORT=no ;;
+           *)   AC_MSG_ERROR(bad value ${enableval} for --enable-s3dsupport) ;;
+          esac
+        ],
+        [BOARD_USE_S3D_SUPPORT=no])
+AM_CONDITIONAL([BOARD_USE_S3D_SUPPORT], [test "x$BOARD_USE_S3D_SUPPORT" = "xyes"])
+
+AC_OUTPUT
diff --git a/exynos/Makefile.am b/exynos/Makefile.am
new file mode 100755 (executable)
index 0000000..db29672
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = libvideocodec
diff --git a/exynos/libvideocodec/ExynosVideoInterface.c b/exynos/libvideocodec/ExynosVideoInterface.c
new file mode 100755 (executable)
index 0000000..f5444f2
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       ExynosVideoInterface.c
+ * @brief
+ * @author     Satish Kumar Reddy (palli.satish@samsung.com)
+ * @version    1.0
+ * @history
+ *    2013.08.14 : Initial versaion
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "ExynosVideoApi.h"
+#include "ExynosVideoDec.h"
+#include "ExynosVideoEnc.h"
+
+/* #define LOG_NDEBUG 0 */
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "ExynosVideoInterface"
+
+#define EXYNOS_MULIPCODEC_SHAREDLIB_NAME "/system/lib/libMulIPExynosVideoApi.so"
+static  void *glibMulIPHandle = NULL;
+
+ExynosVideoErrorType Exynos_Video_GetInstInfo(
+    ExynosVideoInstInfo *pVideoInstInfo,
+    ExynosVideoBoolType  bIsDec)
+{
+    if (bIsDec == VIDEO_TRUE)
+        return MFC_Exynos_Video_GetInstInfo_Decoder(pVideoInstInfo);
+    else
+        return MFC_Exynos_Video_GetInstInfo_Encoder(pVideoInstInfo);
+}
+
+int Exynos_Video_Register_Decoder(
+    ExynosVideoDecOps       *pDecOps,
+    ExynosVideoDecBufferOps *pInbufOps,
+    ExynosVideoDecBufferOps *pOutbufOps)
+{
+    ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
+    int (*MulIPRegisterDecoder)(ExynosVideoDecOps       *pDecOps,
+                                ExynosVideoDecBufferOps *pInbufOps,
+                                ExynosVideoDecBufferOps *pOutbufOps);
+
+    if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    /* Check for Multiple IP codec library */
+    glibMulIPHandle = dlopen(EXYNOS_MULIPCODEC_SHAREDLIB_NAME, RTLD_NOW);
+    if (glibMulIPHandle == NULL) {
+        ret = MFC_Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
+    } else {
+        MulIPRegisterDecoder = dlsym(glibMulIPHandle, "MulIP_Exynos_Video_Register_Decoder");
+        if (MulIPRegisterDecoder == NULL) {
+            ALOGE("%s: dlsym Failed to get MulIP_Exynos_Video_Register_Decoder symbol", __func__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        ret = MulIPRegisterDecoder(pDecOps, pInbufOps, pOutbufOps);
+    }
+
+EXIT:
+    return ret;
+}
+
+int Exynos_Video_Register_Encoder(
+    ExynosVideoEncOps       *pEncOps,
+    ExynosVideoEncBufferOps *pInbufOps,
+    ExynosVideoEncBufferOps *pOutbufOps)
+{
+    ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
+    int (*MulIPRegisterEncoder)(ExynosVideoEncOps       *pEncOps,
+                                ExynosVideoEncBufferOps *pInbufOps,
+                                ExynosVideoEncBufferOps *pOutbufOps);
+
+    if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    /* Check for Multiple IP codec library */
+    glibMulIPHandle = dlopen(EXYNOS_MULIPCODEC_SHAREDLIB_NAME, RTLD_NOW);
+    if (glibMulIPHandle == NULL) {
+        ret = MFC_Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps);
+    } else {
+        MulIPRegisterEncoder = dlsym(glibMulIPHandle, "MulIP_Exynos_Video_Register_Encoder");
+        if (MulIPRegisterEncoder == NULL) {
+            ALOGE("%s: dlsym Failed to get MulIP_Exynos_Video_Register_Encoder symbol", __func__);
+            ret = VIDEO_ERROR_BADPARAM;
+            goto EXIT;
+        }
+
+        ret = MulIPRegisterEncoder(pEncOps, pInbufOps, pOutbufOps);
+    }
+
+EXIT:
+    return ret;
+}
+
+void Exynos_Video_Unregister_Decoder(
+    ExynosVideoDecOps       *pDecOps,
+    ExynosVideoDecBufferOps *pInbufOps,
+    ExynosVideoDecBufferOps *pOutbufOps)
+{
+    if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        goto EXIT;
+    }
+
+    memset(pDecOps, 0, sizeof(ExynosVideoDecOps));
+    memset(pInbufOps, 0, sizeof(ExynosVideoDecBufferOps));
+    memset(pOutbufOps, 0, sizeof(ExynosVideoDecBufferOps));
+
+EXIT:
+    if (glibMulIPHandle != NULL) {
+        dlclose(glibMulIPHandle);
+        glibMulIPHandle = NULL;
+    }
+}
+
+void Exynos_Video_Unregister_Encoder(
+    ExynosVideoEncOps       *pEncOps,
+    ExynosVideoEncBufferOps *pInbufOps,
+    ExynosVideoEncBufferOps *pOutbufOps)
+{
+    if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        goto EXIT;
+    }
+
+    memset(pEncOps, 0, sizeof(ExynosVideoEncOps));
+    memset(pInbufOps, 0, sizeof(ExynosVideoEncBufferOps));
+    memset(pOutbufOps, 0, sizeof(ExynosVideoEncBufferOps));
+
+EXIT:
+    if (glibMulIPHandle != NULL) {
+        dlclose(glibMulIPHandle);
+        glibMulIPHandle = NULL;
+    }
+}
diff --git a/exynos/libvideocodec/Makefile.am b/exynos/libvideocodec/Makefile.am
new file mode 100755 (executable)
index 0000000..993a914
--- /dev/null
@@ -0,0 +1,23 @@
+lib_LTLIBRARIES = libExynosVideoApi.la
+
+libExynosVideoApi_la_SOURCES = ExynosVideoInterface.c \
+                               osal/ExynosVideo_OSAL.c \
+                               dec/ExynosVideoDecoder.c \
+                               enc/ExynosVideoEncoder.c
+
+libExynosVideoApi_la_LIBADD = $(EXYNOSCOMMON_LIBS)
+
+libExynosVideoApi_la_CFLAGS = -I$(CURDIR)/include \
+                              -I$(CURDIR)/osal/include \
+                              -I$(CURDIR)/mfc_headers \
+                              -I$(top_srcdir)/openmax/include/khronos \
+                              -I$(top_srcdir)/openmax/osal \
+                              $(EXYNOSCOMMON_CFLAGS)
+
+libExynosVideoApi_la_CFLAGS += -DUSE_DEFINE_H264_SEI_TYPE -DUSE_ORIGINAL_HEADER -DUSE_MFC_HEADER
+libExynosVideoApi_la_CFLAGS += -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-function
+
+if USE_DLOG
+libExynosVideoApi_la_CFLAGS += $(DLOG_CFLAGS) -DUSE_DLOG
+libExynosVideoApi_la_LIBADD += $(DLOG_LIBS)
+endif
diff --git a/exynos/libvideocodec/dec/ExynosVideoDecoder.c b/exynos/libvideocodec/dec/ExynosVideoDecoder.c
new file mode 100755 (executable)
index 0000000..47b1bc2
--- /dev/null
@@ -0,0 +1,3086 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        ExynosVideoDecoder.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim   (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.01.15: Initial Version
+ *   2016.01.28: Update Version to support OSAL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <pthread.h>
+
+#include <sys/poll.h>
+
+#include "ExynosVideoApi.h"
+#include "ExynosVideoDec.h"
+#include "ExynosVideo_OSAL_Dec.h"
+#include "OMX_Core.h"
+
+/* #define LOG_NDEBUG 0 */
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "ExynosVideoDecoder"
+
+#define MAX_INPUTBUFFER_COUNT 32
+#define MAX_OUTPUTBUFFER_COUNT 32
+
+#define HAS_HDR_STATIC_INFO     0x3
+#define HAS_COLOR_ASPECTS_INFO  0x1C
+#define HAS_BLACK_BAR_CROP_INFO 0x20
+
+/*
+ * [Common] __Set_SupportFormat
+ */
+static void __Set_SupportFormat(ExynosVideoInstInfo *pVideoInstInfo)
+{
+    int nLastIndex = 0;
+
+    if (pVideoInstInfo == NULL) {
+        ALOGE("%s: ExynosVideoInstInfo must be supplied", __FUNCTION__);
+        goto EXIT;
+    }
+
+    memset(pVideoInstInfo->supportFormat, (int)VIDEO_COLORFORMAT_UNKNOWN,
+            sizeof(pVideoInstInfo->supportFormat));
+
+#ifdef USE_HEVC_HWIP
+    if (pVideoInstInfo->eCodecType == VIDEO_CODING_HEVC) {
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV21M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_YV12M;
+        goto EXIT;
+    }
+#endif
+
+    switch (pVideoInstInfo->HwVersion) {
+    case MFC_120:  /* NV12, NV21, I420, YV12, NV12_10B, NV21_10B */
+    case MFC_1220:
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV21M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_YV12M;
+
+        if ((pVideoInstInfo->eCodecType == VIDEO_CODING_HEVC) ||
+            (pVideoInstInfo->eCodecType == VIDEO_CODING_VP9)) {
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12_S10B;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M_S10B;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M_P010;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV21M_S10B;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV21M_P010;
+        }
+        break;
+    case MFC_110:  /* NV12, NV21, I420, YV12 */
+    case MFC_1120:
+    case MFC_101:
+    case MFC_100:
+    case MFC_1010:
+    case MFC_1011:
+    case MFC_90:
+    case MFC_80:
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV21M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_YV12M;
+        break;
+    case MFC_92:  /* NV12, NV21 */
+    case MFC_78D:
+    case MFC_1020:
+    case MFC_1021:
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV21M;
+        break;
+    case MFC_723:  /* NV12T, [NV12, NV21, I420, YV12] */
+    case MFC_72:
+    case MFC_77:
+#if 0
+        if (pVideoInstInfo->supportInfo.dec.bDualDPBSupport == VIDEO_TRUE) {
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV21M;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420M;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_YV12M;
+        }
+#endif
+    case MFC_78:  /* NV12T */
+    case MFC_65:
+    case MFC_61:
+    case MFC_51:
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12_TILED;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M_TILED;
+        break;
+    default:
+        break;
+    }
+
+EXIT:
+    return;
+}
+
+/*
+ * [Decoder OPS] Init
+ */
+static void *MFC_Decoder_Init(ExynosVideoInstInfo *pVideoInfo)
+{
+    CodecOSALVideoContext *pCtx     = NULL;
+    pthread_mutex_t       *pMutex   = NULL;
+
+    int ret = 0;
+    long hIonClient = 0;
+
+    if (pVideoInfo == NULL) {
+        ALOGE("%s: bad parameter", __FUNCTION__);
+        goto EXIT_ALLOC_FAIL;
+    }
+
+    pCtx = (CodecOSALVideoContext *)malloc(sizeof(CodecOSALVideoContext));
+    if (pCtx == NULL) {
+        ALOGE("%s: Failed to allocate decoder context buffer", __FUNCTION__);
+        goto EXIT_ALLOC_FAIL;
+    }
+    memset(pCtx, 0, sizeof(*pCtx));
+
+    /* node open */
+#ifdef USE_HEVC_HWIP
+    if (pVideoInfo->eCodecType == VIDEO_CODING_HEVC) {
+        if (pVideoInfo->eSecurityType == VIDEO_SECURE)
+            ret = Codec_OSAL_DevOpen(VIDEO_HEVC_SECURE_DECODER_NAME, O_RDWR, pCtx);
+        else
+            ret = Codec_OSAL_DevOpen(VIDEO_HEVC_DECODER_NAME, O_RDWR, pCtx);
+    } else
+#endif
+    {
+        if (pVideoInfo->eSecurityType == VIDEO_SECURE)
+            ret = Codec_OSAL_DevOpen(VIDEO_MFC_SECURE_DECODER_NAME, O_RDWR, pCtx);
+        else
+            ret = Codec_OSAL_DevOpen(VIDEO_MFC_DECODER_NAME, O_RDWR, pCtx);
+    }
+
+    if (ret < 0) {
+        ALOGE("%s: Failed to open decoder device", __FUNCTION__);
+        goto EXIT_OPEN_FAIL;
+    }
+
+    memcpy(&pCtx->videoCtx.instInfo, pVideoInfo, sizeof(*pVideoInfo));
+
+    ALOGV("%s: HW version is %x", __FUNCTION__, pCtx->videoCtx.instInfo.HwVersion);
+
+    if (Codec_OSAL_QueryCap(pCtx) != 0) {
+        ALOGE("%s: Failed to querycap", __FUNCTION__);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+
+    pCtx->videoCtx.bStreamonInbuf  = VIDEO_FALSE;
+    pCtx->videoCtx.bStreamonOutbuf = VIDEO_FALSE;
+
+    /* mutex for input */
+    pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
+    if (pMutex == NULL) {
+        ALOGE("%s: Failed to allocate mutex for input buffer", __FUNCTION__);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+
+    if (pthread_mutex_init(pMutex, NULL) != 0) {
+        free(pMutex);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+    pCtx->videoCtx.pInMutex = (void*)pMutex;
+
+    /* mutex for output */
+    pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
+    if (pMutex == NULL) {
+        ALOGE("%s: Failed to allocate mutex for output buffer", __FUNCTION__);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+
+    if (pthread_mutex_init(pMutex, NULL) != 0) {
+        free(pMutex);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+    pCtx->videoCtx.pOutMutex = (void*)pMutex;
+
+    /* for shared memory : referenced DPB handling */
+    hIonClient = (long)ion_open();
+#ifdef USE_ANDROID
+    if (hIonClient < 0) {
+#else
+    if (hIonClient <= 0) {
+#endif
+        ALOGE("%s: Failed to create ion_client", __FUNCTION__);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+
+    pCtx->videoCtx.hIONHandle = (unsigned long)hIonClient;
+
+    if (ion_alloc_fd(pCtx->videoCtx.hIONHandle,
+                     sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM,
+                     0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED,
+                     (void *)&(pCtx->videoCtx.specificInfo.dec.nPrivateDataShareFD)) < 0) {
+        ALOGE("%s: Failed to ion_alloc_fd for nPrivateDataShareFD", __FUNCTION__);
+        pCtx->videoCtx.specificInfo.dec.nPrivateDataShareFD = 0;
+        goto EXIT_QUERYCAP_FAIL;
+    }
+
+    pCtx->videoCtx.specificInfo.dec.pPrivateDataShareAddress =
+                                    Codec_OSAL_MemoryMap(NULL, (sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM),
+                                          PROT_READ | PROT_WRITE, MAP_SHARED,
+                                          pCtx->videoCtx.specificInfo.dec.nPrivateDataShareFD, 0);
+    if (pCtx->videoCtx.specificInfo.dec.pPrivateDataShareAddress == MAP_FAILED) {
+        ALOGE("%s: Failed to mmap for pPrivateDataShareAddress", __FUNCTION__);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+
+    memset(pCtx->videoCtx.specificInfo.dec.pPrivateDataShareAddress,
+            0, sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM);
+
+    return (void *)pCtx;
+
+EXIT_QUERYCAP_FAIL:
+    if (pCtx->videoCtx.pInMutex != NULL) {
+        pthread_mutex_destroy(pCtx->videoCtx.pInMutex);
+        free(pCtx->videoCtx.pInMutex);
+    }
+
+    if (pCtx->videoCtx.pOutMutex != NULL) {
+        pthread_mutex_destroy(pCtx->videoCtx.pOutMutex);
+        free(pCtx->videoCtx.pOutMutex);
+    }
+
+    /* free a ion_buffer */
+    if (pCtx->videoCtx.specificInfo.dec.nPrivateDataShareFD > 0) {
+        ion_close(pCtx->videoCtx.specificInfo.dec.nPrivateDataShareFD);
+        pCtx->videoCtx.specificInfo.dec.nPrivateDataShareFD = 0;
+    }
+
+    /* free a ion_client */
+    if (pCtx->videoCtx.hIONHandle > 0) {
+        ion_close(pCtx->videoCtx.hIONHandle);
+        pCtx->videoCtx.hIONHandle = 0;
+    }
+
+    Codec_OSAL_DevClose(pCtx);
+
+EXIT_OPEN_FAIL:
+    free(pCtx);
+
+EXIT_ALLOC_FAIL:
+    return NULL;
+}
+
+/*
+ * [Decoder OPS] Finalize
+ */
+static ExynosVideoErrorType MFC_Decoder_Finalize(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx         = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoPlane      *pVideoPlane  = NULL;
+    pthread_mutex_t       *pMutex       = NULL;
+    ExynosVideoErrorType   ret          = VIDEO_ERROR_NONE;
+    int i, j;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.specificInfo.dec.pPrivateDataShareAddress != NULL) {
+        Codec_OSAL_MemoryUnmap(pCtx->videoCtx.specificInfo.dec.pPrivateDataShareAddress,
+                sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM);
+        pCtx->videoCtx.specificInfo.dec.pPrivateDataShareAddress = NULL;
+    }
+
+    /* free a ion_buffer */
+    if (pCtx->videoCtx.specificInfo.dec.nPrivateDataShareFD > 0) {
+        ion_close(pCtx->videoCtx.specificInfo.dec.nPrivateDataShareFD);
+        pCtx->videoCtx.specificInfo.dec.nPrivateDataShareFD = 0;
+    }
+
+    /* free a ion_client */
+    if (pCtx->videoCtx.hIONHandle > 0) {
+        ion_close(pCtx->videoCtx.hIONHandle);
+        pCtx->videoCtx.hIONHandle = 0;
+    }
+
+    if (pCtx->videoCtx.pOutMutex != NULL) {
+        pMutex = (pthread_mutex_t*)pCtx->videoCtx.pOutMutex;
+        pthread_mutex_destroy(pMutex);
+        free(pMutex);
+        pCtx->videoCtx.pOutMutex = NULL;
+    }
+
+    if (pCtx->videoCtx.pInMutex != NULL) {
+        pMutex = (pthread_mutex_t*)pCtx->videoCtx.pInMutex;
+        pthread_mutex_destroy(pMutex);
+        free(pMutex);
+        pCtx->videoCtx.pInMutex = NULL;
+    }
+
+    if (pCtx->videoCtx.bShareInbuf == VIDEO_FALSE) {
+        for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+            for (j = 0; j < pCtx->videoCtx.nInbufPlanes; j++) {
+                pVideoPlane = &pCtx->videoCtx.pInbuf[i].planes[j];
+                if (pVideoPlane->addr != NULL) {
+                    Codec_OSAL_MemoryUnmap(pVideoPlane->addr, pVideoPlane->allocSize);
+                    pVideoPlane->addr = NULL;
+                    pVideoPlane->allocSize = 0;
+                    pVideoPlane->dataSize = 0;
+                }
+
+                pCtx->videoCtx.pInbuf[i].pGeometry = NULL;
+                pCtx->videoCtx.pInbuf[i].bQueued = VIDEO_FALSE;
+                pCtx->videoCtx.pInbuf[i].bRegistered = VIDEO_FALSE;
+            }
+        }
+    }
+
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_FALSE) {
+        for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+            for (j = 0; j < pCtx->videoCtx.nOutbufPlanes; j++) {
+                pVideoPlane = &pCtx->videoCtx.pOutbuf[i].planes[j];
+                if (pVideoPlane->addr != NULL) {
+                    Codec_OSAL_MemoryUnmap(pVideoPlane->addr, pVideoPlane->allocSize);
+                    pVideoPlane->addr = NULL;
+                    pVideoPlane->allocSize = 0;
+                    pVideoPlane->dataSize = 0;
+                }
+
+                pCtx->videoCtx.pOutbuf[i].pGeometry = NULL;
+                pCtx->videoCtx.pOutbuf[i].bQueued = VIDEO_FALSE;
+                pCtx->videoCtx.pOutbuf[i].bRegistered = VIDEO_FALSE;
+            }
+        }
+    }
+
+    if (pCtx->videoCtx.pInbuf != NULL)
+        free(pCtx->videoCtx.pInbuf);
+
+    if (pCtx->videoCtx.pOutbuf != NULL)
+        free(pCtx->videoCtx.pOutbuf);
+
+    Codec_OSAL_DevClose(pCtx);
+
+    free(pCtx);
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Set Frame Tag
+ */
+static ExynosVideoErrorType MFC_Decoder_Set_FrameTag(
+    void *pHandle,
+    int   nFrameTag)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_VIDEO_FRAME_TAG, nFrameTag) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Get Frame Tag
+ */
+static int MFC_Decoder_Get_FrameTag(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    int nFrameTag = -1;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        goto EXIT;
+    }
+
+    Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_VIDEO_FRAME_TAG, &nFrameTag);
+
+EXIT:
+    return nFrameTag;
+}
+
+/*
+ * [Decoder OPS] Get Buffer Count
+ */
+static int MFC_Decoder_Get_ActualBufferCount(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    int bufferCount = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        goto EXIT;
+    }
+
+    Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_DEC_NUM_MIN_BUFFERS, &bufferCount);
+
+EXIT:
+    return bufferCount;
+}
+
+/*
+ * [Decoder OPS] Set Display Delay
+ */
+static ExynosVideoErrorType MFC_Decoder_Set_DisplayDelay(
+    void *pHandle,
+    int   nDelay)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_DISPLAY_DELAY, nDelay) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Set Immediate Display
+ */
+static ExynosVideoErrorType MFC_Decoder_Set_ImmediateDisplay(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_IMMEDIATE_DISPLAY, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Set I-Frame Decoding
+ */
+static ExynosVideoErrorType MFC_Decoder_Set_IFrameDecoding(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+#ifdef USE_HEVC_HWIP
+    if ((pCtx->videoCtx.instInfo.eCodecType != VIDEO_CODING_HEVC) &&
+        (pCtx->videoCtx.instInfo.HwVersion == (int)MFC_51))
+#else
+    if (pCtx->videoCtx.instInfo.HwVersion == (int)MFC_51)
+#endif
+        return MFC_Decoder_Set_DisplayDelay(pHandle, 0);
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_I_FRAME_DECODING, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Enable Packed PB
+ */
+static ExynosVideoErrorType MFC_Decoder_Enable_PackedPB(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_PACKED_PB, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Enable Loop Filter
+ */
+static ExynosVideoErrorType MFC_Decoder_Enable_LoopFilter(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_DEBLOCK_FILTER, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Enable Slice Mode
+ */
+static ExynosVideoErrorType MFC_Decoder_Enable_SliceMode(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_SLICE_MODE, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Enable SEI Parsing
+ */
+static ExynosVideoErrorType MFC_Decoder_Enable_SEIParsing(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_SEI_PARSING, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Get Frame Packing information
+ */
+static ExynosVideoErrorType MFC_Decoder_Get_FramePackingInfo(
+    void                    *pHandle,
+    ExynosVideoFramePacking *pFramePacking)
+{
+    CodecOSALVideoContext   *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType     ret  = VIDEO_ERROR_NONE;
+
+    if ((pCtx == NULL) || (pFramePacking == NULL)) {
+        ALOGE("%s: Video context info or FramePacking pointer must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_GetControls(pCtx, CODEC_OSAL_CID_DEC_SEI_INFO, (void *)pFramePacking) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Enable Decoding Timestamp Mode
+ */
+static ExynosVideoErrorType MFC_Decoder_Enable_DTSMode(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_DTS_MODE, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Set Qos Ratio
+ */
+static ExynosVideoErrorType MFC_Decoder_Set_QosRatio(
+    void *pHandle,
+    int   nRatio)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_VIDEO_QOS_RATIO, nRatio) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Enable Dual DPB Mode
+ */
+static ExynosVideoErrorType MFC_Decoder_Enable_DualDPBMode(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_DUAL_DPB_MODE, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Enable Dynamic DPB
+ */
+static ExynosVideoErrorType MFC_Decoder_Enable_DynamicDPB(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_DYNAMIC_DPB_MODE, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_SET_USER_SHARED_HANDLE,
+                                pCtx->videoCtx.specificInfo.dec.nPrivateDataShareFD) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Enable Discard RCV header
+ */
+static ExynosVideoErrorType MFC_Decoder_Enable_DiscardRcvHeader(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+#if 0  // TODO
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_DISCARD_RCVHEADER, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+#else
+    ALOGW("%s: not implemented yet", __FUNCTION__);
+#endif
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Get HDR Info
+ */
+static ExynosVideoErrorType MFC_Decoder_Get_HDRInfo(void *pHandle, ExynosVideoHdrInfo *pHdrInfo)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if ((pCtx == NULL) ||
+        (pHdrInfo == NULL)) {
+        ALOGE("%s: Video context info or HDR Info pointer must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_GetControls(pCtx, CODEC_OSAL_CID_DEC_HDR_INFO,
+                                (void *)&(pCtx->videoCtx.outbufGeometry.HdrInfo)) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    memcpy(pHdrInfo, &(pCtx->videoCtx.outbufGeometry.HdrInfo), sizeof(ExynosVideoHdrInfo));
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Set Search Black Bar
+ */
+static ExynosVideoErrorType MFC_Decoder_Set_SearchBlackBar(void *pHandle, ExynosVideoBoolType bUse)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_SEARCH_BLACK_BAR, bUse) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Enable Cacheable (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_VIDEO_CACHEABLE_BUFFER, 2) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Enable Cacheable (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_VIDEO_CACHEABLE_BUFFER, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Set Shareable Buffer (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.bShareInbuf = VIDEO_TRUE;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Set Shareable Buffer (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.bShareOutbuf = VIDEO_TRUE;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Get Buffer (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Inbuf(
+    void               *pHandle,
+    int                 nIndex,
+    ExynosVideoBuffer **pBuffer)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        *pBuffer = NULL;
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if ((nIndex < 0) ||
+        (pCtx->videoCtx.nInbufs <= nIndex)) {
+        *pBuffer = NULL;
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    *pBuffer = (ExynosVideoBuffer *)&pCtx->videoCtx.pInbuf[nIndex];
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Get Buffer (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Outbuf(
+    void               *pHandle,
+    int                 nIndex,
+    ExynosVideoBuffer **pBuffer)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        *pBuffer = NULL;
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if ((nIndex < 0) ||
+        (pCtx->videoCtx.nOutbufs <= nIndex)) {
+        *pBuffer = NULL;
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    *pBuffer = (ExynosVideoBuffer *)&pCtx->videoCtx.pOutbuf[nIndex];
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Set Geometry (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Inbuf(
+    void                *pHandle,
+    ExynosVideoGeometry *pBufferConf)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    CodecOSAL_Format fmt;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pBufferConf == NULL) {
+        ALOGE("%s: Buffer geometry must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&fmt, 0, sizeof(fmt));
+    fmt.type            = CODEC_OSAL_BUF_TYPE_SRC;
+    fmt.format          = Codec_OSAL_CodingTypeToCompressdFormat(pBufferConf->eCompressionFormat);
+    fmt.planeSize[0]    = pBufferConf->nSizeImage;
+    fmt.nPlane          = pBufferConf->nPlaneCnt;
+
+    if (Codec_OSAL_SetFormat(pCtx, &fmt) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    memcpy(&pCtx->videoCtx.inbufGeometry, pBufferConf, sizeof(pCtx->videoCtx.inbufGeometry));
+    pCtx->videoCtx.nInbufPlanes = pBufferConf->nPlaneCnt;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Set Geometry (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Outbuf(
+    void                *pHandle,
+    ExynosVideoGeometry *pBufferConf)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    CodecOSAL_Format fmt;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pBufferConf == NULL) {
+        ALOGE("%s: Buffer geometry must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&fmt, 0, sizeof(fmt));
+    fmt.type    = CODEC_OSAL_BUF_TYPE_DST;
+    fmt.format  = Codec_OSAL_ColorFormatToPixelFormat(
+                        pBufferConf->eColorFormat, pCtx->videoCtx.instInfo.HwVersion);
+    fmt.nPlane  = pBufferConf->nPlaneCnt;
+
+    if (Codec_OSAL_SetFormat(pCtx, &fmt) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    memcpy(&pCtx->videoCtx.outbufGeometry, pBufferConf, sizeof(pCtx->videoCtx.outbufGeometry));
+    pCtx->videoCtx.nOutbufPlanes = pBufferConf->nPlaneCnt;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Get Geometry (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Get_Geometry_Outbuf(
+    void                *pHandle,
+    ExynosVideoGeometry *pBufferConf)
+{
+    CodecOSALVideoContext *pCtx             = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret              = VIDEO_ERROR_NONE;
+    ExynosVideoGeometry   *pCodecBufferConf = NULL;
+
+    CodecOSAL_Format fmt;
+    CodecOSAL_Crop   crop;
+    int i, value;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pBufferConf == NULL) {
+        ALOGE("%s: Buffer geometry must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&fmt, 0, sizeof(fmt));
+    memset(&crop, 0, sizeof(crop));
+
+    fmt.type = CODEC_OSAL_BUF_TYPE_DST;
+    if (Codec_OSAL_GetFormat(pCtx, &fmt) != 0) {
+        if (errno == EAGAIN)
+            ret = VIDEO_ERROR_HEADERINFO;
+        else
+            ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    crop.type = CODEC_OSAL_BUF_TYPE_DST;
+    if (Codec_OSAL_GetCrop(pCtx, &crop) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pCodecBufferConf = &(pCtx->videoCtx.outbufGeometry);
+
+    pCodecBufferConf->nFrameWidth     = fmt.width;
+    pCodecBufferConf->nFrameHeight    = fmt.height;
+    pCodecBufferConf->eColorFormat    = Codec_OSAL_PixelFormatToColorFormat(fmt.format);
+    pCodecBufferConf->nStride         = fmt.stride;
+
+#ifdef USE_DEINTERLACING_SUPPORT
+    if ((fmt.field == CODEC_OSAL_INTER_TYPE_INTER) ||
+        (fmt.field == CODEC_OSAL_INTER_TYPE_TB) ||
+        (fmt.field == CODEC_OSAL_INTER_TYPE_BT))
+        pCodecBufferConf->bInterlaced = VIDEO_TRUE;
+    else
+#endif
+        pCodecBufferConf->bInterlaced = VIDEO_FALSE;
+
+    switch (pCodecBufferConf->eColorFormat) {
+        /* if it is 10bit contents, the format obtained from MFC D/D will be one of 10bit formats */
+    case VIDEO_COLORFORMAT_NV12_S10B:
+        pCodecBufferConf->eFilledDataType = DATA_8BIT_WITH_2BIT;
+        pCtx->videoCtx.nOutbufPlanes = 1;
+        break;
+    case VIDEO_COLORFORMAT_NV12M_S10B:
+    case VIDEO_COLORFORMAT_NV21M_S10B:
+        pCodecBufferConf->eFilledDataType = DATA_8BIT_WITH_2BIT;
+        pCtx->videoCtx.nOutbufPlanes = 2;
+        break;
+    case VIDEO_COLORFORMAT_NV12M_P010:
+    case VIDEO_COLORFORMAT_NV21M_P010:
+        pCodecBufferConf->eFilledDataType = DATA_10BIT;
+        pCtx->videoCtx.nOutbufPlanes = 2;
+        break;
+    default:
+        /* for backward compatibility : MFC D/D only supports g_ctrl */
+        Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_DEC_GET_10BIT_INFO, &value);
+        if (value == 1) {
+            /* supports only S10B format */
+            pCodecBufferConf->eFilledDataType = DATA_8BIT_WITH_2BIT;
+            pCodecBufferConf->eColorFormat = VIDEO_COLORFORMAT_NV12M_S10B;
+            pCtx->videoCtx.nOutbufPlanes = 2;
+
+#ifdef USE_SINGLE_PALNE_SUPPORT
+            if (pCtx->videoCtx.instInfo.eSecurityType == VIDEO_SECURE) {
+                pCodecBufferConf->eColorFormat = VIDEO_COLORFORMAT_NV12_S10B;
+                pCtx->videoCtx.nOutbufPlanes = 1;
+            }
+#endif
+        }
+        break;
+    }
+
+    /* Get planes aligned buffer size */
+    for (i = 0; i < pCtx->videoCtx.nOutbufPlanes; i++)
+        pCodecBufferConf->nAlignPlaneSize[i] = fmt.planeSize[i];
+
+    pCodecBufferConf->cropRect.nTop       = crop.top;
+    pCodecBufferConf->cropRect.nLeft      = crop.left;
+    pCodecBufferConf->cropRect.nWidth     = crop.width;
+    pCodecBufferConf->cropRect.nHeight    = crop.height;
+
+    ALOGV("%s: %s contents", __FUNCTION__, (pCodecBufferConf->eFilledDataType & DATA_10BIT)? "10bit":"8bit");
+
+    /* HdrInfo in pBufferConf is not used by OMX component */
+    memcpy(pBufferConf, pCodecBufferConf, sizeof(ExynosVideoGeometry));
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Get BlackBarCrop (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Get_BlackBarCrop_Outbuf(
+        void                *pHandle,
+        ExynosVideoRect     *pBufferCrop)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    CodecOSAL_Crop  crop;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pBufferCrop == NULL) {
+        ALOGE("%s: Buffer Crop must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&crop, 0, sizeof(crop));
+
+    crop.type = CODEC_OSAL_BUF_TYPE_DST;
+    if (Codec_OSAL_GetCrop(pCtx, &crop) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pBufferCrop->nTop      = crop.top;
+    pBufferCrop->nLeft     = crop.left;
+    pBufferCrop->nWidth    = crop.width;
+    pBufferCrop->nHeight   = crop.height;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Setup (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_Setup_Inbuf(
+    void         *pHandle,
+    unsigned int  nBufferCount)
+{
+    CodecOSALVideoContext *pCtx         = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoPlane      *pVideoPlane  = NULL;
+    ExynosVideoErrorType   ret          = VIDEO_ERROR_NONE;
+
+    CodecOSAL_ReqBuf reqBuf;
+    CodecOSAL_Buffer buf;
+
+    int i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (nBufferCount == 0) {
+        nBufferCount = MAX_INPUTBUFFER_COUNT;
+        ALOGV("%s: Change buffer count %d", __FUNCTION__, nBufferCount);
+    }
+
+    ALOGV("%s: setting up inbufs(%d) shared = %s\n", __FUNCTION__, nBufferCount,
+          pCtx->videoCtx.bShareInbuf ? "true" : "false");
+
+    memset(&reqBuf, 0, sizeof(reqBuf));
+
+    reqBuf.type = CODEC_OSAL_BUF_TYPE_SRC;
+    reqBuf.count = nBufferCount;
+    if (pCtx->videoCtx.bShareInbuf == VIDEO_TRUE)
+        reqBuf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    else
+        reqBuf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+
+    if (Codec_OSAL_RequestBuf(pCtx, &reqBuf) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    if (reqBuf.count != nBufferCount) {
+        ALOGE("%s: asked for %d, got %d\n", __FUNCTION__, nBufferCount, reqBuf.count);
+        ret = VIDEO_ERROR_NOMEM;
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.nInbufs = (int)reqBuf.count;
+
+    pCtx->videoCtx.pInbuf = malloc(sizeof(*pCtx->videoCtx.pInbuf) * pCtx->videoCtx.nInbufs);
+    if (pCtx->videoCtx.pInbuf == NULL) {
+        ALOGE("Failed to allocate input buffer context");
+        ret = VIDEO_ERROR_NOMEM;
+        goto EXIT;
+    }
+    memset(pCtx->videoCtx.pInbuf, 0, sizeof(*pCtx->videoCtx.pInbuf) * pCtx->videoCtx.nInbufs);
+
+    memset(&buf, 0, sizeof(buf));
+
+    if (pCtx->videoCtx.bShareInbuf == VIDEO_FALSE) {
+        buf.type    = CODEC_OSAL_BUF_TYPE_SRC;
+        buf.memory  = CODEC_OSAL_MEM_TYPE_MMAP;
+        buf.nPlane  = pCtx->videoCtx.nInbufPlanes;
+
+        for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+            buf.index = i;
+
+            if (Codec_OSAL_QueryBuf(pCtx, &buf) != 0) {
+                ret = VIDEO_ERROR_APIFAIL;
+                goto EXIT;
+            }
+
+            pVideoPlane = &pCtx->videoCtx.pInbuf[i].planes[0];
+
+            pVideoPlane->addr = Codec_OSAL_MemoryMap(NULL,
+                    buf.planes[0].bufferSize, PROT_READ | PROT_WRITE,
+                    MAP_SHARED, (unsigned long)buf.planes[0].addr, buf.planes[0].offset);
+            if (pVideoPlane->addr == MAP_FAILED) {
+                ret = VIDEO_ERROR_MAPFAIL;
+                goto EXIT;
+            }
+
+            pVideoPlane->allocSize  = buf.planes[0].bufferSize;
+            pVideoPlane->dataSize   = 0;
+
+            pCtx->videoCtx.pInbuf[i].pGeometry      = &pCtx->videoCtx.inbufGeometry;
+            pCtx->videoCtx.pInbuf[i].bQueued        = VIDEO_FALSE;
+            pCtx->videoCtx.pInbuf[i].bRegistered    = VIDEO_TRUE;
+        }
+    }
+
+    return ret;
+
+EXIT:
+    if ((pCtx != NULL) &&
+        (pCtx->videoCtx.pInbuf != NULL)) {
+        if (pCtx->videoCtx.bShareInbuf == VIDEO_FALSE) {
+            for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+                pVideoPlane = &pCtx->videoCtx.pInbuf[i].planes[0];
+                if (pVideoPlane->addr == MAP_FAILED) {
+                    pVideoPlane->addr = NULL;
+                    break;
+                }
+
+                Codec_OSAL_MemoryUnmap(pVideoPlane->addr, pVideoPlane->allocSize);
+            }
+        }
+
+        free(pCtx->videoCtx.pInbuf);
+        pCtx->videoCtx.pInbuf  = NULL;
+        pCtx->videoCtx.nInbufs = 0;
+    }
+
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Setup (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf(
+    void         *pHandle,
+    unsigned int  nBufferCount)
+{
+    CodecOSALVideoContext *pCtx         = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoPlane      *pVideoPlane  = NULL;
+    ExynosVideoErrorType   ret          = VIDEO_ERROR_NONE;
+
+    CodecOSAL_ReqBuf reqBuf;
+    CodecOSAL_Buffer buf;
+
+    int i, j;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (nBufferCount == 0) {
+        nBufferCount = MAX_OUTPUTBUFFER_COUNT;
+        ALOGV("%s: Change buffer count %d", __FUNCTION__, nBufferCount);
+    }
+
+    ALOGV("%s: setting up outbufs(%d) shared = %s\n", __FUNCTION__, nBufferCount,
+          pCtx->videoCtx.bShareOutbuf ? "true" : "false");
+
+    memset(&reqBuf, 0, sizeof(reqBuf));
+
+    reqBuf.type = CODEC_OSAL_BUF_TYPE_DST;
+    reqBuf.count = nBufferCount;
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_TRUE)
+        reqBuf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    else
+        reqBuf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+
+    if (Codec_OSAL_RequestBuf(pCtx, &reqBuf) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    if (reqBuf.count != nBufferCount) {
+        ALOGE("%s: asked for %d, got %d\n", __FUNCTION__, nBufferCount, reqBuf.count);
+        ret = VIDEO_ERROR_NOMEM;
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.nOutbufs = reqBuf.count;
+
+    pCtx->videoCtx.pOutbuf = malloc(sizeof(*pCtx->videoCtx.pOutbuf) * pCtx->videoCtx.nOutbufs);
+    if (pCtx->videoCtx.pOutbuf == NULL) {
+        ALOGE("Failed to allocate output buffer context");
+        ret = VIDEO_ERROR_NOMEM;
+        goto EXIT;
+    }
+    memset(pCtx->videoCtx.pOutbuf, 0, sizeof(*pCtx->videoCtx.pOutbuf) * pCtx->videoCtx.nOutbufs);
+
+    memset(&buf, 0, sizeof(buf));
+
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_FALSE) {
+        buf.type    = CODEC_OSAL_BUF_TYPE_DST;
+        buf.memory  = CODEC_OSAL_MEM_TYPE_MMAP;
+        buf.nPlane  = pCtx->videoCtx.nOutbufPlanes;
+
+        for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+            buf.index = i;
+
+            if (Codec_OSAL_QueryBuf(pCtx, &buf) != 0) {
+                ret = VIDEO_ERROR_APIFAIL;
+                goto EXIT;
+            }
+
+            for (j = 0; j < pCtx->videoCtx.nOutbufPlanes; j++) {
+                pVideoPlane = &pCtx->videoCtx.pOutbuf[i].planes[j];
+
+                pVideoPlane->addr = Codec_OSAL_MemoryMap(NULL,
+                        buf.planes[j].bufferSize, PROT_READ | PROT_WRITE,
+                        MAP_SHARED, (unsigned long)buf.planes[j].addr, buf.planes[j].offset);
+                if (pVideoPlane->addr == MAP_FAILED) {
+                    ret = VIDEO_ERROR_MAPFAIL;
+                    goto EXIT;
+                }
+
+                pVideoPlane->allocSize  = buf.planes[j].bufferSize;
+                pVideoPlane->dataSize   = 0;
+            }
+
+            pCtx->videoCtx.pOutbuf[i].pGeometry     = &pCtx->videoCtx.outbufGeometry;
+            pCtx->videoCtx.pOutbuf[i].bQueued       = VIDEO_FALSE;
+            pCtx->videoCtx.pOutbuf[i].bSlotUsed     = VIDEO_FALSE;
+            pCtx->videoCtx.pOutbuf[i].nIndexUseCnt  = 0;
+            pCtx->videoCtx.pOutbuf[i].bRegistered   = VIDEO_TRUE;
+        }
+    } else {
+        for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+            pCtx->videoCtx.pOutbuf[i].pGeometry    = &pCtx->videoCtx.outbufGeometry;
+            pCtx->videoCtx.pOutbuf[i].bQueued      = VIDEO_FALSE;
+            pCtx->videoCtx.pOutbuf[i].bSlotUsed    = VIDEO_FALSE;
+            pCtx->videoCtx.pOutbuf[i].nIndexUseCnt = 0;
+            pCtx->videoCtx.pOutbuf[i].bRegistered  = VIDEO_FALSE;
+        }
+        /* Initialize initial values */
+    }
+
+    return ret;
+
+EXIT:
+    if ((pCtx != NULL) &&
+        (pCtx->videoCtx.pOutbuf != NULL)) {
+        if (pCtx->videoCtx.bShareOutbuf == VIDEO_FALSE) {
+            for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+                for (j = 0; j < pCtx->videoCtx.nOutbufPlanes; j++) {
+                    pVideoPlane = &pCtx->videoCtx.pOutbuf[i].planes[j];
+                    if (pVideoPlane->addr == MAP_FAILED) {
+                        pVideoPlane->addr = NULL;
+                        break;
+                    }
+
+                    Codec_OSAL_MemoryUnmap(pVideoPlane->addr, pVideoPlane->allocSize);
+                }
+            }
+        }
+
+        free(pCtx->videoCtx.pOutbuf);
+        pCtx->videoCtx.pOutbuf = NULL;
+    }
+
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Run (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_Run_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonInbuf == VIDEO_FALSE) {
+        if (Codec_OSAL_SetStreamOn(pCtx, CODEC_OSAL_BUF_TYPE_SRC) != 0) {
+            ALOGE("%s: Failed to streamon for input buffer", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        pCtx->videoCtx.bStreamonInbuf = VIDEO_TRUE;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Run (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Run_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonOutbuf == VIDEO_FALSE) {
+        if (Codec_OSAL_SetStreamOn(pCtx, CODEC_OSAL_BUF_TYPE_DST) != 0) {
+            ALOGE("%s: Failed to streamon for output buffer", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        pCtx->videoCtx.bStreamonOutbuf = VIDEO_TRUE;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Stop (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_Stop_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonInbuf == VIDEO_TRUE) {
+        if (Codec_OSAL_SetStreamOff(pCtx, CODEC_OSAL_BUF_TYPE_SRC) != 0) {
+            ALOGE("%s: Failed to streamoff for input buffer", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        pCtx->videoCtx.bStreamonInbuf = VIDEO_FALSE;
+    }
+
+    for (i = 0; i <  pCtx->videoCtx.nInbufs; i++)
+        pCtx->videoCtx.pInbuf[i].bQueued = VIDEO_FALSE;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Stop (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Stop_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonOutbuf == VIDEO_TRUE) {
+        if (Codec_OSAL_SetStreamOff(pCtx, CODEC_OSAL_BUF_TYPE_DST) != 0) {
+            ALOGE("%s: Failed to streamoff for output buffer", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        pCtx->videoCtx.bStreamonOutbuf = VIDEO_FALSE;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+        pCtx->videoCtx.pOutbuf[i].bQueued      = VIDEO_FALSE;
+        pCtx->videoCtx.pOutbuf[i].bSlotUsed    = VIDEO_FALSE;
+        pCtx->videoCtx.pOutbuf[i].nIndexUseCnt = 0;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Wait (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_Wait_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    struct pollfd poll_events;
+    int poll_state;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    poll_events.fd = pCtx->videoCtx.hDevice;
+    poll_events.events = POLLOUT | POLLERR;
+    poll_events.revents = 0;
+
+    do {
+        poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_DECODER_POLL_TIMEOUT);
+        if (poll_state > 0) {
+            if (poll_events.revents & POLLOUT) {
+                break;
+            } else {
+                ALOGE("%s: Poll return error", __FUNCTION__);
+                ret = VIDEO_ERROR_POLL;
+                break;
+            }
+        } else if (poll_state < 0) {
+            ALOGE("%s: Poll state error", __FUNCTION__);
+            ret = VIDEO_ERROR_POLL;
+            break;
+        }
+    } while (poll_state == 0);
+
+EXIT:
+    return ret;
+}
+
+static ExynosVideoErrorType MFC_Decoder_Register_Inbuf(
+    void             *pHandle,
+    ExynosVideoPlane *pPlanes,
+    int               nPlanes)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i, j;
+
+    if ((pCtx == NULL) ||
+        (pPlanes == NULL) ||
+        (nPlanes != pCtx->videoCtx.nInbufPlanes)) {
+        ALOGE("%s: params must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+        if (pCtx->videoCtx.pInbuf[i].bRegistered == VIDEO_FALSE) {
+            for (j = 0; j < nPlanes; j++) {
+                pCtx->videoCtx.pInbuf[i].planes[j].addr        = pPlanes[j].addr;
+                pCtx->videoCtx.pInbuf[i].planes[j].allocSize   = pPlanes[j].allocSize;
+                pCtx->videoCtx.pInbuf[i].planes[j].fd          = pPlanes[j].fd;
+
+                ALOGV("%s: registered buf[%d][%d]: addr = %p, alloc_sz = %u, fd = %lu",
+                        __FUNCTION__, i, j, pPlanes[j].addr, pPlanes[j].allocSize, pPlanes[j].fd);
+            }
+
+            pCtx->videoCtx.pInbuf[i].bRegistered = VIDEO_TRUE;
+            break;
+        }
+    }
+
+    if (i == pCtx->videoCtx.nInbufs) {
+        ALOGE("%s: can not find non-registered input buffer", __FUNCTION__);
+        ret = VIDEO_ERROR_NOBUFFERS;
+    }
+
+EXIT:
+    return ret;
+}
+
+static ExynosVideoErrorType MFC_Decoder_Register_Outbuf(
+    void             *pHandle,
+    ExynosVideoPlane *pPlanes,
+    int               nPlanes)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i, j;
+
+    if ((pCtx == NULL) ||
+        (pPlanes == NULL) ||
+        (nPlanes != pCtx->videoCtx.nOutbufPlanes)) {
+        ALOGE("%s: params must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+        if (pCtx->videoCtx.pOutbuf[i].bRegistered == VIDEO_FALSE) {
+            for (j = 0; j < nPlanes; j++) {
+                pCtx->videoCtx.pOutbuf[i].planes[j].addr       = pPlanes[j].addr;
+                pCtx->videoCtx.pOutbuf[i].planes[j].allocSize  = pPlanes[j].allocSize;
+                pCtx->videoCtx.pOutbuf[i].planes[j].fd         = pPlanes[j].fd;
+
+                ALOGV("%s: registered buf[%d][%d]: addr = %p, alloc_sz = %d, fd = %lu",
+                      __FUNCTION__, i, j, pPlanes[j].addr, pPlanes[j].allocSize, pPlanes[j].fd);
+            }
+
+            /* this is for saving interlaced type or HDR info */
+            if ((pCtx->videoCtx.outbufGeometry.bInterlaced == VIDEO_TRUE) ||
+                (pCtx->videoCtx.outbufGeometry.eFilledDataType & DATA_10BIT)) {
+                pCtx->videoCtx.pOutbuf[i].planes[2].addr    = pPlanes[2].addr;
+                pCtx->videoCtx.pOutbuf[i].planes[2].fd      = pPlanes[2].fd;
+            }
+
+            pCtx->videoCtx.pOutbuf[i].bRegistered = VIDEO_TRUE;
+            break;
+        }
+    }
+
+    if (i == pCtx->videoCtx.nOutbufs) {
+        ALOGE("%s: can not find non-registered output buffer", __FUNCTION__);
+        ret = VIDEO_ERROR_NOBUFFERS;
+    }
+
+EXIT:
+    return ret;
+}
+
+static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i, j;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+        for (j = 0; j < pCtx->videoCtx.nInbufPlanes; j++) {
+            pCtx->videoCtx.pInbuf[i].planes[j].addr = NULL;
+            pCtx->videoCtx.pInbuf[i].planes[j].fd   = 0;
+        }
+
+        pCtx->videoCtx.pInbuf[i].bRegistered = VIDEO_FALSE;
+    }
+
+EXIT:
+    return ret;
+}
+
+static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i, j;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+        for (j = 0; j < pCtx->videoCtx.nOutbufPlanes; j++) {
+            pCtx->videoCtx.pOutbuf[i].planes[j].addr = NULL;
+            pCtx->videoCtx.pOutbuf[i].planes[j].fd = 0;
+        }
+
+        /* this is for saving interlaced type or HDR info */
+        if ((pCtx->videoCtx.outbufGeometry.bInterlaced == VIDEO_TRUE) ||
+            (pCtx->videoCtx.outbufGeometry.eFilledDataType & DATA_10BIT)) {
+            pCtx->videoCtx.pOutbuf[i].planes[2].addr    = NULL;
+            pCtx->videoCtx.pOutbuf[i].planes[2].fd      = 0;
+        }
+
+        pCtx->videoCtx.pOutbuf[i].bRegistered = VIDEO_FALSE;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Find (Input)
+ */
+static int MFC_Decoder_Find_Inbuf(
+    void          *pHandle,
+    unsigned char *pBuffer)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    int nIndex = -1, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+        if (pCtx->videoCtx.pInbuf[i].bQueued == VIDEO_FALSE) {
+            if ((pBuffer == NULL) ||
+                (pCtx->videoCtx.pInbuf[i].planes[0].addr == pBuffer)) {
+                nIndex = i;
+                break;
+            }
+        }
+    }
+
+EXIT:
+    return nIndex;
+}
+
+/*
+ * [Decoder Buffer OPS] Find (Outnput)
+ */
+static int MFC_Decoder_Find_Outbuf(
+    void          *pHandle,
+    unsigned char *pBuffer)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    int nIndex = -1, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+        if (pCtx->videoCtx.pOutbuf[i].bQueued == VIDEO_FALSE) {
+            if ((pBuffer == NULL) ||
+                (pCtx->videoCtx.pOutbuf[i].planes[0].addr == pBuffer)) {
+                nIndex = i;
+                break;
+            }
+        }
+    }
+
+EXIT:
+    return nIndex;
+}
+
+/*
+ * [Decoder Buffer OPS] Enqueue (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_Enqueue_Inbuf(
+    void          *pHandle,
+    void          *pBuffer[],
+    unsigned int   nDataSize[],
+    int            nPlanes,
+    void          *pPrivate)
+{
+    CodecOSALVideoContext *pCtx     = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret      = VIDEO_ERROR_NONE;
+    pthread_mutex_t       *pMutex   = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int index, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.nInbufPlanes < nPlanes) {
+        ALOGE("%s: Number of max planes : %d, nPlanes : %d", __FUNCTION__,
+                                    pCtx->videoCtx.nInbufPlanes, nPlanes);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_SRC;
+    buf.nPlane  = pCtx->videoCtx.nInbufPlanes;
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pInMutex;
+    pthread_mutex_lock(pMutex);
+
+    index = MFC_Decoder_Find_Inbuf(pCtx, pBuffer[0]);
+    if (index == -1) {
+        pthread_mutex_unlock(pMutex);
+        ALOGE("%s: Failed to get index", __FUNCTION__);
+        ret = VIDEO_ERROR_NOBUFFERS;
+        goto EXIT;
+    }
+    buf.index = index;
+    ALOGV("%s: index:%d pCtx->videoCtx.pInbuf[buf.index].bQueued:%d, pBuffer[0]:%p",
+           __FUNCTION__, index, pCtx->videoCtx.pInbuf[buf.index].bQueued, pBuffer[0]);
+
+    if (pCtx->videoCtx.bShareInbuf == VIDEO_TRUE) {
+        buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+        for (i = 0; i < buf.nPlane; i++) {
+            if (buf.memory == CODEC_OSAL_MEM_TYPE_USERPTR)
+                buf.planes[i].addr = pBuffer[i];
+            else
+                buf.planes[i].addr = (void *)(unsigned long)pCtx->videoCtx.pInbuf[index].planes[i].fd;
+
+            buf.planes[i].bufferSize    = pCtx->videoCtx.pInbuf[index].planes[i].allocSize;
+            buf.planes[i].dataLen       = nDataSize[i];
+
+            ALOGV("%s: shared inbuf(%d) plane(%d) addr = %p len = %d used = %d", __FUNCTION__,
+                  index, i,
+                  buf.planes[i].addr,
+                  buf.planes[i].bufferSize,
+                  buf.planes[i].dataLen);
+        }
+    } else {
+        buf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+        for (i = 0; i < nPlanes; i++)
+            buf.planes[i].dataLen = nDataSize[i];
+    }
+
+    if (nDataSize[0] <= 0) {
+        buf.flags = EMPTY_DATA | LAST_FRAME;
+        ALOGD("%s: EMPTY DATA", __FUNCTION__);
+    } else {
+        if ((((OMX_BUFFERHEADERTYPE *)pPrivate)->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
+            buf.flags = LAST_FRAME;
+
+        if ((((OMX_BUFFERHEADERTYPE *)pPrivate)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == OMX_BUFFERFLAG_CODECCONFIG)
+            buf.flags |= CSD_FRAME;
+
+        if (buf.flags & (CSD_FRAME | LAST_FRAME))
+            ALOGD("%s: DATA with flags(0x%x)", __FUNCTION__, buf.flags);
+    }
+
+    signed long long sec  = (((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp / 1E6);
+    signed long long usec = (((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp) - (sec * 1E6);
+    buf.timestamp.tv_sec  = (long)sec;
+    buf.timestamp.tv_usec = (long)usec;
+
+    pCtx->videoCtx.pInbuf[buf.index].pPrivate = pPrivate;
+    pCtx->videoCtx.pInbuf[buf.index].bQueued = VIDEO_TRUE;
+    pthread_mutex_unlock(pMutex);
+
+    if (Codec_OSAL_EnqueueBuf(pCtx, &buf) != 0) {
+        ALOGE("%s: Failed to enqueue input buffer", __FUNCTION__);
+        pthread_mutex_lock(pMutex);
+        pCtx->videoCtx.pInbuf[buf.index].pPrivate = NULL;
+        pCtx->videoCtx.pInbuf[buf.index].bQueued  = VIDEO_FALSE;
+        pthread_mutex_unlock(pMutex);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Enqueue (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Enqueue_Outbuf(
+    void          *pHandle,
+    void          *pBuffer[],
+    unsigned int   nDataSize[],
+    int            nPlanes,
+    void          *pPrivate)
+{
+    CodecOSALVideoContext *pCtx   = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret    = VIDEO_ERROR_NONE;
+    pthread_mutex_t       *pMutex = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int i, index, state = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.nOutbufPlanes < nPlanes) {
+        ALOGE("%s: Number of max planes : %d, nPlanes : %d", __FUNCTION__,
+                                    pCtx->videoCtx.nOutbufPlanes, nPlanes);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_DST;
+    buf.nPlane  = pCtx->videoCtx.nOutbufPlanes;
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pOutMutex;
+    pthread_mutex_lock(pMutex);
+
+    index = MFC_Decoder_Find_Outbuf(pCtx, pBuffer[0]);
+    if (index == -1) {
+        pthread_mutex_unlock(pMutex);
+        ALOGE("%s: Failed to get index", __FUNCTION__);
+        ret = VIDEO_ERROR_NOBUFFERS;
+        goto EXIT;
+    }
+    buf.index = index;
+    ALOGV("%s: index:%d pCtx->videoCtx.pOutbuf[buf.index].bQueued:%d, pBuffer[0]:%p",
+           __FUNCTION__, index, pCtx->videoCtx.pOutbuf[buf.index].bQueued, pBuffer[0]);
+
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_TRUE) {
+        buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+        for (i = 0; i < buf.nPlane; i++) {
+            if (buf.memory == CODEC_OSAL_MEM_TYPE_USERPTR)
+                buf.planes[i].addr = pBuffer[i];
+            else
+                buf.planes[i].addr = (void *)(unsigned long)pCtx->videoCtx.pOutbuf[index].planes[i].fd;
+
+            buf.planes[i].bufferSize    = pCtx->videoCtx.pOutbuf[index].planes[i].allocSize;
+            buf.planes[i].dataLen       = nDataSize[i];
+
+            ALOGV("%s: shared outbuf(%d) plane = %d addr = %p len = %d used = %d", __FUNCTION__,
+                  index, i,
+                  buf.planes[i].addr,
+                  buf.planes[i].bufferSize,
+                  buf.planes[i].dataLen);
+        }
+    } else {
+        ALOGV("%s: non-shared outbuf(%d)\n", __FUNCTION__, index);
+        buf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+    }
+
+    pCtx->videoCtx.pOutbuf[buf.index].pPrivate = pPrivate;
+    pCtx->videoCtx.pOutbuf[buf.index].bQueued = VIDEO_TRUE;
+    pthread_mutex_unlock(pMutex);
+
+    if (Codec_OSAL_EnqueueBuf(pCtx, &buf) != 0) {
+        pthread_mutex_lock(pMutex);
+        pCtx->videoCtx.pOutbuf[buf.index].pPrivate = NULL;
+        pCtx->videoCtx.pOutbuf[buf.index].bQueued = VIDEO_FALSE;
+        Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_DEC_CHECK_STATE, &state);
+        if (state == 1) {
+            /* The case of Resolution is changed */
+            ret = VIDEO_ERROR_WRONGBUFFERSIZE;
+        } else {
+            ALOGE("%s: Failed to enqueue output buffer", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+        }
+        pthread_mutex_unlock(pMutex);
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Dequeue (Input)
+ */
+static ExynosVideoBuffer *MFC_Decoder_Dequeue_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx     = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoBuffer     *pInbuf   = NULL;
+    pthread_mutex_t       *pMutex   = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonInbuf == VIDEO_FALSE) {
+        pInbuf = NULL;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_SRC;
+    buf.nPlane  = pCtx->videoCtx.nInbufPlanes;
+    if (pCtx->videoCtx.bShareInbuf == VIDEO_TRUE)
+        buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    else
+        buf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+
+    if (Codec_OSAL_DequeueBuf(pCtx, &buf) != 0) {
+        pInbuf = NULL;
+        goto EXIT;
+    }
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pInMutex;
+    pthread_mutex_lock(pMutex);
+
+    pInbuf = &pCtx->videoCtx.pInbuf[buf.index];
+    if (pInbuf->bQueued == VIDEO_FALSE) {
+        pInbuf = NULL;
+        pthread_mutex_unlock(pMutex);
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.pInbuf[buf.index].bQueued = VIDEO_FALSE;
+
+    if (pCtx->videoCtx.bStreamonInbuf == VIDEO_FALSE)
+        pInbuf = NULL;
+
+    pthread_mutex_unlock(pMutex);
+
+EXIT:
+    return pInbuf;
+}
+
+/*
+ * [Decoder Buffer OPS] Dequeue (Output)
+ */
+static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx    = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoBuffer     *pOutbuf = NULL;
+    pthread_mutex_t       *pMutex  = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int value = 0, state = 0;
+    int ret = 0;
+    int i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonOutbuf == VIDEO_FALSE) {
+        pOutbuf = NULL;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_DST;
+    buf.nPlane  = pCtx->videoCtx.nOutbufPlanes;
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_TRUE)
+        buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    else
+        buf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+
+    /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */
+    ret = Codec_OSAL_DequeueBuf(pCtx, &buf);
+    if (ret != 0) {
+        if (errno == EIO)
+            pOutbuf = (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO;
+        else
+            pOutbuf = NULL;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonOutbuf == VIDEO_FALSE) {
+        pOutbuf = NULL;
+        goto EXIT;
+    }
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pOutMutex;
+    pthread_mutex_lock(pMutex);
+
+    pOutbuf = &pCtx->videoCtx.pOutbuf[buf.index];
+    if (pOutbuf->bQueued == VIDEO_FALSE) {
+        pOutbuf = NULL;
+        ret = VIDEO_ERROR_NOBUFFERS;
+        pthread_mutex_unlock(pMutex);
+        goto EXIT;
+    }
+
+    for (i = 0; i < buf.nPlane; i++)
+        pOutbuf->planes[i].dataSize = buf.planes[i].dataLen;
+
+    Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_DEC_DISPLAY_STATUS, &value);
+
+    switch (value) {
+    case 0:
+        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_ONLY;
+#ifdef USE_HEVC_HWIP
+        if ((pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_HEVC) ||
+            (pCtx->videoCtx.instInfo.HwVersion != (int)MFC_51)) {
+#else
+        if (pCtx->videoCtx.instInfo.HwVersion != (int)MFC_51) {
+#endif
+            Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_DEC_CHECK_STATE, &state);
+            if (state == 4) /* DPB realloc for S3D SEI */
+                pOutbuf->displayStatus = VIDEO_FRAME_STATUS_ENABLED_S3D;
+        }
+        break;
+    case 1:
+        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_DECODING;
+        break;
+    case 2:
+        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY;
+        break;
+    case 3:
+        Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_DEC_CHECK_STATE, &state);
+        if (state == 1) /* Resolution is changed */
+            pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL;
+        else            /* Decoding is finished */
+            pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_FINISHED;
+        break;
+    case 4:
+        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_LAST_FRAME;
+        break;
+    default:
+        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
+        break;
+    }
+
+    pOutbuf->frameType = buf.frameType;
+
+    if (pCtx->videoCtx.outbufGeometry.bInterlaced == VIDEO_TRUE) {
+        if ((buf.field == CODEC_OSAL_INTER_TYPE_TB) ||
+            (buf.field == CODEC_OSAL_INTER_TYPE_BT)) {
+            pOutbuf->interlacedType = buf.field;
+        } else {
+            ALOGV("%s: buf.field's value is invald(%d)", __FUNCTION__, buf.field);
+            pOutbuf->interlacedType = CODEC_OSAL_INTER_TYPE_NONE;
+        }
+    }
+
+#ifdef USE_ANDROID
+    if (buf.flags & (HAS_HDR_STATIC_INFO | HAS_COLOR_ASPECTS_INFO)) {
+        /* for HDR information */
+        ExynosVideoHdrInfo  *pHdrInfo = &(pCtx->videoCtx.outbufGeometry.HdrInfo);
+
+        pHdrInfo->eChangedType = buf.flags;
+        pOutbuf->frameType |= VIDEO_FRAME_WITH_HDR_INFO;
+    }
+#endif
+
+    if (buf.flags & HAS_BLACK_BAR_CROP_INFO)
+        pOutbuf->frameType |= VIDEO_FRAME_WITH_BLACK_BAR;
+
+    pOutbuf->bQueued = VIDEO_FALSE;
+
+    pthread_mutex_unlock(pMutex);
+
+EXIT:
+    return pOutbuf;
+}
+
+static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nInbufs; i++)
+        pCtx->videoCtx.pInbuf[i].bQueued = VIDEO_FALSE;
+
+EXIT:
+    return ret;
+}
+
+static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++)
+        pCtx->videoCtx.pOutbuf[i].bQueued = VIDEO_FALSE;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Cleanup Buffer (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_Cleanup_Buffer_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    CodecOSAL_ReqBuf reqBuf;
+    int nBufferCount = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    nBufferCount = 0; /* for clean-up */
+
+    memset(&reqBuf, 0, sizeof(reqBuf));
+
+    reqBuf.type = CODEC_OSAL_BUF_TYPE_SRC;
+    reqBuf.count = nBufferCount;
+    if (pCtx->videoCtx.bShareInbuf == VIDEO_TRUE)
+        reqBuf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    else
+        reqBuf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+
+    if (Codec_OSAL_RequestBuf(pCtx, &reqBuf) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.nInbufs = (int)reqBuf.count;
+
+    if (pCtx->videoCtx.pInbuf != NULL) {
+        free(pCtx->videoCtx.pInbuf);
+        pCtx->videoCtx.pInbuf = NULL;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Cleanup Buffer (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Cleanup_Buffer_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    CodecOSAL_ReqBuf reqBuf;
+    int nBufferCount = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    nBufferCount = 0; /* for clean-up */
+
+    memset(&reqBuf, 0, sizeof(reqBuf));
+
+    reqBuf.type = CODEC_OSAL_BUF_TYPE_DST;
+    reqBuf.count = nBufferCount;
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_TRUE)
+        reqBuf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    else
+        reqBuf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+
+    if (Codec_OSAL_RequestBuf(pCtx, &reqBuf) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.nOutbufs = (int)reqBuf.count;
+
+    if (pCtx->videoCtx.pOutbuf != NULL) {
+        free(pCtx->videoCtx.pOutbuf);
+        pCtx->videoCtx.pOutbuf = NULL;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] Apply Registered Buffer (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_Apply_RegisteredBuffer_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_DEC_WAIT_DECODING_START, 1) != 0) {
+        ALOGW("%s: The requested function is not implemented", __FUNCTION__);
+        //ret = VIDEO_ERROR_APIFAIL;
+        //goto EXIT;    /* For Backward compatibility */
+    }
+
+    ret = MFC_Decoder_Run_Outbuf(pHandle);
+    if (VIDEO_ERROR_NONE != ret)
+        goto EXIT;
+
+    ret = MFC_Decoder_Stop_Outbuf(pHandle);
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] FindIndex (Input)
+ */
+static int MFC_Decoder_FindEmpty_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    int nIndex = -1, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+        if (pCtx->videoCtx.pInbuf[i].bQueued == VIDEO_FALSE) {
+            nIndex = i;
+            break;
+        }
+    }
+
+EXIT:
+    return nIndex;
+}
+
+/*
+ * [Decoder Buffer OPS] ExtensionEnqueue (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_ExtensionEnqueue_Inbuf(
+    void          *pHandle,
+    void          *pBuffer[],
+    unsigned long  pFd[],
+    unsigned int   nAllocLen[],
+    unsigned int   nDataSize[],
+    int            nPlanes,
+    void          *pPrivate)
+{
+    CodecOSALVideoContext *pCtx   = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret    = VIDEO_ERROR_NONE;
+    pthread_mutex_t       *pMutex = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int index, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.nInbufPlanes < nPlanes) {
+        ALOGE("%s: Number of max planes : %d, nPlanes : %d", __FUNCTION__,
+                                    pCtx->videoCtx.nInbufPlanes, nPlanes);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_SRC;
+    buf.nPlane  = pCtx->videoCtx.nInbufPlanes;
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pInMutex;
+    pthread_mutex_lock(pMutex);
+
+    index = MFC_Decoder_FindEmpty_Inbuf(pCtx);
+    if (index == -1) {
+        pthread_mutex_unlock(pMutex);
+        ALOGE("%s: Failed to get index", __FUNCTION__);
+        ret = VIDEO_ERROR_NOBUFFERS;
+        goto EXIT;
+    }
+    buf.index = index;
+    ALOGV("%s: index:%d pCtx->videoCtx.pInbuf[buf.index].bQueued:%d, pFd[0]:%lu",
+           __FUNCTION__, index, pCtx->videoCtx.pInbuf[buf.index].bQueued, pFd[0]);
+
+    buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    for (i = 0; i < buf.nPlane; i++) {
+        if (buf.memory == CODEC_OSAL_MEM_TYPE_USERPTR)
+            buf.planes[i].addr = pBuffer[i];
+        else
+            buf.planes[i].addr = (void *)pFd[i];
+
+        buf.planes[i].bufferSize    = nAllocLen[i];
+        buf.planes[i].dataLen       = nDataSize[i];
+
+        /* Temporary storage for Dequeue */
+        pCtx->videoCtx.pInbuf[buf.index].planes[i].addr         = pBuffer[i];
+        pCtx->videoCtx.pInbuf[buf.index].planes[i].fd           = pFd[i];
+        pCtx->videoCtx.pInbuf[buf.index].planes[i].allocSize    = nAllocLen[i];
+
+        ALOGV("%s: shared inbuf(%d) plane=%d addr=%p fd=%lu len=%d used=%d",
+              __FUNCTION__, index, i,
+              pBuffer[i], pFd[i],
+              nAllocLen[i], nDataSize[i]);
+    }
+
+    if (nDataSize[0] <= 0) {
+        buf.flags = EMPTY_DATA | LAST_FRAME;
+        ALOGD("%s: EMPTY DATA", __FUNCTION__);
+    } else {
+        if ((((OMX_BUFFERHEADERTYPE *)pPrivate)->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
+            buf.flags = LAST_FRAME;
+
+        if ((((OMX_BUFFERHEADERTYPE *)pPrivate)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == OMX_BUFFERFLAG_CODECCONFIG)
+            buf.flags |= CSD_FRAME;
+
+        if (buf.flags & (CSD_FRAME | LAST_FRAME))
+            ALOGD("%s: DATA with flags(0x%x)", __FUNCTION__, buf.flags);
+    }
+
+    signed long long sec  = (((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp / 1E6);
+    signed long long usec = (((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp) - (sec * 1E6);
+    buf.timestamp.tv_sec  = (long)sec;
+    buf.timestamp.tv_usec = (long)usec;
+
+    pCtx->videoCtx.pInbuf[buf.index].pPrivate = pPrivate;
+    pCtx->videoCtx.pInbuf[buf.index].bQueued = VIDEO_TRUE;
+    pthread_mutex_unlock(pMutex);
+
+    if (Codec_OSAL_EnqueueBuf(pCtx, &buf) != 0) {
+        ALOGE("%s: Failed to enqueue input buffer", __FUNCTION__);
+        pthread_mutex_lock(pMutex);
+        pCtx->videoCtx.pInbuf[buf.index].pPrivate = NULL;
+        pCtx->videoCtx.pInbuf[buf.index].bQueued  = VIDEO_FALSE;
+        pthread_mutex_unlock(pMutex);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] ExtensionDequeue (Input)
+ */
+static ExynosVideoErrorType MFC_Decoder_ExtensionDequeue_Inbuf(
+    void              *pHandle,
+    ExynosVideoBuffer *pVideoBuffer)
+{
+    CodecOSALVideoContext *pCtx   = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret    = VIDEO_ERROR_NONE;
+    pthread_mutex_t       *pMutex = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonInbuf == VIDEO_FALSE) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type = CODEC_OSAL_BUF_TYPE_SRC;
+    buf.nPlane = pCtx->videoCtx.nInbufPlanes;
+    buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+
+    if (Codec_OSAL_DequeueBuf(pCtx, &buf) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pInMutex;
+    pthread_mutex_lock(pMutex);
+
+    if (pCtx->videoCtx.pInbuf[buf.index].bQueued == VIDEO_TRUE)
+        memcpy(pVideoBuffer, &pCtx->videoCtx.pInbuf[buf.index], sizeof(ExynosVideoBuffer));
+    else
+        ret = VIDEO_ERROR_NOBUFFERS;
+    memset(&pCtx->videoCtx.pInbuf[buf.index], 0, sizeof(ExynosVideoBuffer));
+
+    pCtx->videoCtx.pInbuf[buf.index].bQueued = VIDEO_FALSE;
+    pthread_mutex_unlock(pMutex);
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] FindIndex (Output)
+ */
+static int MFC_Decoder_FindEmpty_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    int nIndex = -1, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+        if ((pCtx->videoCtx.pOutbuf[i].bQueued == VIDEO_FALSE) &&
+            (pCtx->videoCtx.pOutbuf[i].bSlotUsed == VIDEO_FALSE)) {
+            nIndex = i;
+            break;
+        }
+    }
+
+EXIT:
+    return nIndex;
+}
+
+/*
+ * [Decoder Buffer OPS] BufferIndexFree (Output)
+ */
+void MFC_Decoder_BufferIndexFree_Outbuf(
+    void                   *pHandle,
+    PrivateDataShareBuffer *pPDSB,
+    int                     nIndex)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    int i, j;
+
+    ALOGV("De-queue buf.index:%d, fd:%lu", nIndex, pCtx->videoCtx.pOutbuf[nIndex].planes[0].fd);
+
+    if (pCtx->videoCtx.pOutbuf[nIndex].nIndexUseCnt == 0)
+        pCtx->videoCtx.pOutbuf[nIndex].bSlotUsed = VIDEO_FALSE;
+
+    for (i = 0; i < VIDEO_BUFFER_MAX_NUM; i++) {
+        if (pPDSB->dpbFD[i].fd <= 0)
+            break;
+
+        ALOGV("pPDSB->dpbFD[%d].fd:%llu", i, pPDSB->dpbFD[i].fd);
+        for (j = 0; j < pCtx->videoCtx.nOutbufs; j++) {
+            if (pPDSB->dpbFD[i].fd == pCtx->videoCtx.pOutbuf[j].planes[0].fd) {
+                if (pCtx->videoCtx.pOutbuf[j].bQueued == VIDEO_FALSE) {
+                    if (pCtx->videoCtx.pOutbuf[j].nIndexUseCnt > 0)
+                        pCtx->videoCtx.pOutbuf[j].nIndexUseCnt--;
+                } else if(pCtx->videoCtx.pOutbuf[j].bQueued == VIDEO_TRUE) {
+                    if (pCtx->videoCtx.pOutbuf[j].nIndexUseCnt > 1) {
+                        /* The buffer being used as the reference buffer came again. */
+                        pCtx->videoCtx.pOutbuf[j].nIndexUseCnt--;
+                    } else {
+                        /* Reference DPB buffer is internally reused. */
+                    }
+                }
+
+                ALOGV("dec Cnt : FD:%llu, pCtx->videoCtx.pOutbuf[%d].nIndexUseCnt:%d",
+                        pPDSB->dpbFD[i].fd, j, pCtx->videoCtx.pOutbuf[j].nIndexUseCnt);
+
+                if ((pCtx->videoCtx.pOutbuf[j].nIndexUseCnt == 0) &&
+                    (pCtx->videoCtx.pOutbuf[j].bQueued == VIDEO_FALSE)) {
+                    pCtx->videoCtx.pOutbuf[j].bSlotUsed = VIDEO_FALSE;
+                }
+            }
+        }
+    }
+
+    memset((char *)pPDSB, 0, sizeof(PrivateDataShareBuffer));
+
+    return;
+}
+
+/*
+ * [Decoder Buffer OPS] ExtensionEnqueue (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_ExtensionEnqueue_Outbuf(
+    void          *pHandle,
+    void          *pBuffer[],
+    unsigned long  pFd[],
+    unsigned int   nAllocLen[],
+    unsigned int   nDataSize[],
+    int            nPlanes,
+    void          *pPrivate)
+{
+    CodecOSALVideoContext *pCtx   = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret    = VIDEO_ERROR_NONE;
+    pthread_mutex_t       *pMutex = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int i, index, state = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.nOutbufPlanes < nPlanes) {
+        ALOGE("%s: Number of max planes : %d, nPlanes : %d", __FUNCTION__,
+                                    pCtx->videoCtx.nOutbufPlanes, nPlanes);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_DST;
+    buf.nPlane  = pCtx->videoCtx.nOutbufPlanes;
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pOutMutex;
+    pthread_mutex_lock(pMutex);
+
+    index = MFC_Decoder_Find_Outbuf(pCtx, pBuffer[0]);
+    if (index == -1) {
+        ALOGV("%s: Failed to find index", __FUNCTION__);
+        index = MFC_Decoder_FindEmpty_Outbuf(pCtx);
+        if (index == -1) {
+            pthread_mutex_unlock(pMutex);
+            ALOGE("%s: Failed to get index", __FUNCTION__);
+            ret = VIDEO_ERROR_NOBUFFERS;
+            goto EXIT;
+        }
+    }
+    buf.index = index;
+    ALOGV("%s: index:%d pCtx->videoCtx.pOutbuf[buf.index].bQueued:%d, pFd[0]:%lu",
+           __FUNCTION__, index, pCtx->videoCtx.pOutbuf[buf.index].bQueued, pFd[0]);
+
+    buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    for (i = 0; i < buf.nPlane; i++) {
+        if (buf.memory == CODEC_OSAL_MEM_TYPE_USERPTR)
+            buf.planes[i].addr = pBuffer[i];
+        else
+            buf.planes[i].addr = (void *)(unsigned long)pFd[i];
+
+        buf.planes[i].bufferSize    = nAllocLen[i];
+        buf.planes[i].dataLen       = nDataSize[i];
+
+        /* Temporary storage for Dequeue */
+        pCtx->videoCtx.pOutbuf[buf.index].planes[i].addr        = pBuffer[i];
+        pCtx->videoCtx.pOutbuf[buf.index].planes[i].fd          = pFd[i];
+        pCtx->videoCtx.pOutbuf[buf.index].planes[i].allocSize   = nAllocLen[i];
+
+        ALOGV("%s: shared outbuf(%d) plane=%d addr=%p fd=%lu len=%d used=%d",
+                  __FUNCTION__, index, i,
+                  pBuffer[i], pFd[i],
+                  nAllocLen[i], nDataSize[i]);
+    }
+
+    /* this is for saving interlaced type or HDR info */
+    if ((pCtx->videoCtx.outbufGeometry.bInterlaced == VIDEO_TRUE) ||
+        (pCtx->videoCtx.outbufGeometry.eFilledDataType & DATA_10BIT)) {
+        pCtx->videoCtx.pOutbuf[buf.index].planes[2].addr = pBuffer[2];
+        pCtx->videoCtx.pOutbuf[buf.index].planes[2].fd   = pFd[2];
+    }
+
+    pCtx->videoCtx.pOutbuf[buf.index].pPrivate = pPrivate;
+    pCtx->videoCtx.pOutbuf[buf.index].bQueued = VIDEO_TRUE;
+    pCtx->videoCtx.pOutbuf[buf.index].bSlotUsed = VIDEO_TRUE;
+    pCtx->videoCtx.pOutbuf[buf.index].nIndexUseCnt++;
+    pthread_mutex_unlock(pMutex);
+
+    if (Codec_OSAL_EnqueueBuf(pCtx, &buf) != 0) {
+        pthread_mutex_lock(pMutex);
+        pCtx->videoCtx.pOutbuf[buf.index].nIndexUseCnt--;
+        pCtx->videoCtx.pOutbuf[buf.index].pPrivate = NULL;
+        pCtx->videoCtx.pOutbuf[buf.index].bQueued = VIDEO_FALSE;
+
+        if (pCtx->videoCtx.pOutbuf[buf.index].nIndexUseCnt == 0)
+            pCtx->videoCtx.pOutbuf[buf.index].bSlotUsed = VIDEO_FALSE;
+
+        Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_DEC_CHECK_STATE, &state);
+        if (state == 1) {
+            /* The case of Resolution is changed */
+            ret = VIDEO_ERROR_WRONGBUFFERSIZE;
+        } else {
+            ALOGE("%s: Failed to enqueue output buffer", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+        }
+
+        pthread_mutex_unlock(pMutex);
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder Buffer OPS] ExtensionDequeue (Output)
+ */
+static ExynosVideoErrorType MFC_Decoder_ExtensionDequeue_Outbuf(
+    void              *pHandle,
+    ExynosVideoBuffer *pVideoBuffer)
+{
+    CodecOSALVideoContext  *pCtx    = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType    ret     = VIDEO_ERROR_NONE;
+    pthread_mutex_t        *pMutex  = NULL;
+    ExynosVideoBuffer      *pOutbuf = NULL;
+    PrivateDataShareBuffer *pPDSB   = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int value = 0, state = 0;
+    int i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: Video context info must be supplied", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonOutbuf == VIDEO_FALSE) {
+        pOutbuf = NULL;
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_DST;
+    buf.nPlane  = pCtx->videoCtx.nOutbufPlanes;
+    buf.memory  = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+
+    /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */
+    if (Codec_OSAL_DequeueBuf(pCtx, &buf) != 0) {
+        if (errno == EIO)
+            ret = VIDEO_ERROR_DQBUF_EIO;
+        else
+            ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pOutMutex;
+    pthread_mutex_lock(pMutex);
+
+    pOutbuf = &pCtx->videoCtx.pOutbuf[buf.index];
+    if (pOutbuf->bQueued == VIDEO_FALSE) {
+        pOutbuf = NULL;
+        ret = VIDEO_ERROR_NOBUFFERS;
+        pthread_mutex_unlock(pMutex);
+        goto EXIT;
+    }
+
+    for (i = 0; i < buf.nPlane; i++)
+        pOutbuf->planes[i].dataSize = buf.planes[i].dataLen;
+
+    Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_DEC_DISPLAY_STATUS, &value);
+
+    switch (value) {
+    case 0:
+        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_ONLY;
+#ifdef USE_HEVC_HWIP
+        if ((pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_HEVC) ||
+            (pCtx->videoCtx.instInfo.HwVersion != (int)MFC_51)) {
+#else
+        if (pCtx->videoCtx.instInfo.HwVersion != (int)MFC_51) {
+#endif
+            Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_DEC_CHECK_STATE, &state);
+            if (state == 4) /* DPB realloc for S3D SEI */
+                pOutbuf->displayStatus = VIDEO_FRAME_STATUS_ENABLED_S3D;
+        }
+        break;
+    case 1:
+        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_DECODING;
+        break;
+    case 2:
+        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY;
+        break;
+    case 3:
+        Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_DEC_CHECK_STATE, &state);
+        if (state == 1) /* Resolution is changed */
+            pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL;
+        else            /* Decoding is finished */
+            pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_FINISHED;
+        break;
+    case 4:
+        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_LAST_FRAME;
+        break;
+    default:
+        pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
+        break;
+    }
+
+    pOutbuf->frameType = buf.frameType;
+
+    if (pCtx->videoCtx.outbufGeometry.bInterlaced == VIDEO_TRUE) {
+        if ((buf.field == CODEC_OSAL_INTER_TYPE_TB) ||
+            (buf.field == CODEC_OSAL_INTER_TYPE_BT)) {
+            pOutbuf->interlacedType = buf.field;
+        } else {
+            ALOGV("%s: buf.field's value is invald(%d)", __FUNCTION__, buf.field);
+            pOutbuf->interlacedType = CODEC_OSAL_INTER_TYPE_NONE;
+        }
+    }
+
+#ifdef USE_ANDROID
+    if (buf.flags & (HAS_HDR_STATIC_INFO | HAS_COLOR_ASPECTS_INFO)) {
+        /* for HDR information */
+        ExynosVideoHdrInfo  *pHdrInfo = &(pCtx->videoCtx.outbufGeometry.HdrInfo);
+
+        pHdrInfo->eChangedType = buf.flags;
+        pOutbuf->frameType |= VIDEO_FRAME_WITH_HDR_INFO;
+    }
+#endif
+
+    if (buf.flags & HAS_BLACK_BAR_CROP_INFO)
+        pOutbuf->frameType |= VIDEO_FRAME_WITH_BLACK_BAR;
+
+    pPDSB = ((PrivateDataShareBuffer *)pCtx->videoCtx.specificInfo.dec.pPrivateDataShareAddress) + buf.index;
+    if (pCtx->videoCtx.pOutbuf[buf.index].bQueued == VIDEO_TRUE) {
+        memcpy(pVideoBuffer, pOutbuf, sizeof(ExynosVideoBuffer));
+        memcpy((char *)(&(pVideoBuffer->PDSB)), (char *)pPDSB, sizeof(PrivateDataShareBuffer));
+    } else {
+        ret = VIDEO_ERROR_NOBUFFERS;
+    }
+
+    MFC_Decoder_BufferIndexFree_Outbuf(pHandle, pPDSB, buf.index);
+    pCtx->videoCtx.pOutbuf[buf.index].bQueued = VIDEO_FALSE;
+    pthread_mutex_unlock(pMutex);
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Decoder OPS] Common
+ */
+static ExynosVideoDecOps defDecOps = {
+    .nSize                      = 0,
+    .Init                       = MFC_Decoder_Init,
+    .Finalize                   = MFC_Decoder_Finalize,
+    .Set_DisplayDelay           = MFC_Decoder_Set_DisplayDelay,
+    .Set_IFrameDecoding         = MFC_Decoder_Set_IFrameDecoding,
+    .Enable_PackedPB            = MFC_Decoder_Enable_PackedPB,
+    .Enable_LoopFilter          = MFC_Decoder_Enable_LoopFilter,
+    .Enable_SliceMode           = MFC_Decoder_Enable_SliceMode,
+    .Get_ActualBufferCount      = MFC_Decoder_Get_ActualBufferCount,
+    .Set_FrameTag               = MFC_Decoder_Set_FrameTag,
+    .Get_FrameTag               = MFC_Decoder_Get_FrameTag,
+    .Enable_SEIParsing          = MFC_Decoder_Enable_SEIParsing,
+    .Get_FramePackingInfo       = MFC_Decoder_Get_FramePackingInfo,
+    .Set_ImmediateDisplay       = MFC_Decoder_Set_ImmediateDisplay,
+    .Enable_DTSMode             = MFC_Decoder_Enable_DTSMode,
+    .Set_QosRatio               = MFC_Decoder_Set_QosRatio,
+    .Enable_DiscardRcvHeader    = MFC_Decoder_Enable_DiscardRcvHeader,
+    .Enable_DualDPBMode         = MFC_Decoder_Enable_DualDPBMode,
+    .Enable_DynamicDPB          = MFC_Decoder_Enable_DynamicDPB,
+    .Get_HDRInfo                = MFC_Decoder_Get_HDRInfo,
+    .Set_SearchBlackBar         = MFC_Decoder_Set_SearchBlackBar,
+};
+
+/*
+ * [Decoder Buffer OPS] Input
+ */
+static ExynosVideoDecBufferOps defInbufOps = {
+    .nSize                  = 0,
+    .Enable_Cacheable       = MFC_Decoder_Enable_Cacheable_Inbuf,
+    .Set_Shareable          = MFC_Decoder_Set_Shareable_Inbuf,
+    .Get_Buffer             = NULL,
+    .Set_Geometry           = MFC_Decoder_Set_Geometry_Inbuf,
+    .Get_Geometry           = NULL,
+    .Get_BlackBarCrop       = NULL,
+    .Setup                  = MFC_Decoder_Setup_Inbuf,
+    .Run                    = MFC_Decoder_Run_Inbuf,
+    .Stop                   = MFC_Decoder_Stop_Inbuf,
+    .Enqueue                = MFC_Decoder_Enqueue_Inbuf,
+    .Enqueue_All            = NULL,
+    .Dequeue                = MFC_Decoder_Dequeue_Inbuf,
+    .Register               = MFC_Decoder_Register_Inbuf,
+    .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Inbuf,
+    .Clear_Queue            = MFC_Decoder_Clear_Queued_Inbuf,
+    .Cleanup_Buffer         = MFC_Decoder_Cleanup_Buffer_Inbuf,
+    .Apply_RegisteredBuffer = NULL,
+    .ExtensionEnqueue       = MFC_Decoder_ExtensionEnqueue_Inbuf,
+    .ExtensionDequeue       = MFC_Decoder_ExtensionDequeue_Inbuf,
+};
+
+/*
+ * [Decoder Buffer OPS] Output
+ */
+static ExynosVideoDecBufferOps defOutbufOps = {
+    .nSize                  = 0,
+    .Enable_Cacheable       = MFC_Decoder_Enable_Cacheable_Outbuf,
+    .Set_Shareable          = MFC_Decoder_Set_Shareable_Outbuf,
+    .Get_Buffer             = MFC_Decoder_Get_Buffer_Outbuf,
+    .Set_Geometry           = MFC_Decoder_Set_Geometry_Outbuf,
+    .Get_Geometry           = MFC_Decoder_Get_Geometry_Outbuf,
+    .Get_BlackBarCrop       = MFC_Decoder_Get_BlackBarCrop_Outbuf,
+    .Setup                  = MFC_Decoder_Setup_Outbuf,
+    .Run                    = MFC_Decoder_Run_Outbuf,
+    .Stop                   = MFC_Decoder_Stop_Outbuf,
+    .Enqueue                = MFC_Decoder_Enqueue_Outbuf,
+    .Enqueue_All            = NULL,
+    .Dequeue                = MFC_Decoder_Dequeue_Outbuf,
+    .Register               = MFC_Decoder_Register_Outbuf,
+    .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Outbuf,
+    .Clear_Queue            = MFC_Decoder_Clear_Queued_Outbuf,
+    .Cleanup_Buffer         = MFC_Decoder_Cleanup_Buffer_Outbuf,
+    .Apply_RegisteredBuffer = MFC_Decoder_Apply_RegisteredBuffer_Outbuf,
+    .ExtensionEnqueue       = MFC_Decoder_ExtensionEnqueue_Outbuf,
+    .ExtensionDequeue       = MFC_Decoder_ExtensionDequeue_Outbuf,
+};
+
+ExynosVideoErrorType MFC_Exynos_Video_GetInstInfo_Decoder(
+    ExynosVideoInstInfo *pVideoInstInfo)
+{
+    CodecOSALVideoContext   videoCtx;
+    ExynosVideoErrorType    ret = VIDEO_ERROR_NONE;
+
+    int codecRet = 0;
+    int mode = 0, version = 0;
+
+    if (pVideoInstInfo == NULL) {
+        ALOGE("%s: bad parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&videoCtx, 0, sizeof(videoCtx));
+
+#ifdef USE_HEVC_HWIP
+    if (pVideoInstInfo->eCodecType == VIDEO_CODING_HEVC)
+        codecRet = Codec_OSAL_DevOpen(VIDEO_HEVC_DECODER_NAME, O_RDWR, &videoCtx);
+    else
+#endif
+        codecRet = Codec_OSAL_DevOpen(VIDEO_MFC_DECODER_NAME, O_RDWR, &videoCtx);
+
+    if (codecRet < 0) {
+        ALOGE("%s: Failed to open decoder device", __FUNCTION__);
+        ret = VIDEO_ERROR_OPENFAIL;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_GetControl(&videoCtx, CODEC_OSAL_CID_VIDEO_GET_VERSION_INFO, &version) != 0) {
+        ALOGW("%s: HW version information is not available", __FUNCTION__);
+#ifdef USE_HEVC_HWIP
+        if (pVideoInstInfo->eCodecType == VIDEO_CODING_HEVC)
+            pVideoInstInfo->HwVersion = (int)HEVC_10;
+        else
+#endif
+            pVideoInstInfo->HwVersion = (int)MFC_65;
+    } else {
+        pVideoInstInfo->HwVersion = version;
+    }
+
+    if (Codec_OSAL_GetControl(&videoCtx, CODEC_OSAL_CID_VIDEO_GET_EXT_INFO, &mode) != 0) {
+        pVideoInstInfo->supportInfo.dec.bSkypeSupport = VIDEO_FALSE;
+        goto EXIT;
+    }
+
+    pVideoInstInfo->supportInfo.dec.bSkypeSupport = (mode & (0x1 << 3))? VIDEO_TRUE:VIDEO_FALSE;
+
+    pVideoInstInfo->SwVersion = 0;
+    if (pVideoInstInfo->supportInfo.dec.bSkypeSupport == VIDEO_TRUE) {
+        int swVersion = 0;
+
+        if (Codec_OSAL_GetControl(&videoCtx, CODEC_OSAL_CID_VIDEO_GET_DRIVER_VERSION, &swVersion) != 0) {
+            ALOGE("%s: g_ctrl is failed(CODEC_OSAL_CID_VIDEO_GET_DRIVER_VERSION)", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        pVideoInstInfo->SwVersion = (unsigned int)swVersion;
+    }
+
+    __Set_SupportFormat(pVideoInstInfo);
+
+EXIT:
+    Codec_OSAL_DevClose(&videoCtx);
+
+    return ret;
+}
+
+ExynosVideoErrorType MFC_Exynos_Video_Register_Decoder(
+    ExynosVideoDecOps       *pDecOps,
+    ExynosVideoDecBufferOps *pInbufOps,
+    ExynosVideoDecBufferOps *pOutbufOps)
+{
+    ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
+
+    if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    defDecOps.nSize = sizeof(defDecOps);
+    defInbufOps.nSize = sizeof(defInbufOps);
+    defOutbufOps.nSize = sizeof(defOutbufOps);
+
+    memcpy((char *)pDecOps + sizeof(pDecOps->nSize), (char *)&defDecOps + sizeof(defDecOps.nSize),
+            pDecOps->nSize - sizeof(pDecOps->nSize));
+
+    memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize),
+            pInbufOps->nSize - sizeof(pInbufOps->nSize));
+
+    memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize),
+            pOutbufOps->nSize - sizeof(pOutbufOps->nSize));
+
+EXIT:
+    return ret;
+}
diff --git a/exynos/libvideocodec/enc/ExynosVideoEncoder.c b/exynos/libvideocodec/enc/ExynosVideoEncoder.c
new file mode 100755 (executable)
index 0000000..b76e90a
--- /dev/null
@@ -0,0 +1,3058 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        ExynosVideoDecoder.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim   (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.01.15: Initial Version
+ *   2016.01.28: Update Version to support OSAL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <pthread.h>
+
+#include <sys/poll.h>
+
+#include "ExynosVideoApi.h"
+#include "ExynosVideoEnc.h"
+#include "ExynosVideo_OSAL_Enc.h"
+#include "OMX_Core.h"
+
+/* #define LOG_NDEBUG 0 */
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "ExynosVideoEncoder"
+
+#define MAX_INPUTBUFFER_COUNT 32
+#define MAX_OUTPUTBUFFER_COUNT 32
+
+/*
+ * [Common] __Set_SupportFormat
+ */
+static void __Set_SupportFormat(ExynosVideoInstInfo *pVideoInstInfo)
+{
+    int nLastIndex = 0;
+
+    if (pVideoInstInfo == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    memset(pVideoInstInfo->supportFormat, (int)VIDEO_COLORFORMAT_UNKNOWN, sizeof(pVideoInstInfo->supportFormat));
+
+    pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12;
+    pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M;
+    pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV21M;
+
+    switch ((int)pVideoInstInfo->HwVersion) {
+    case MFC_120:  /* NV12, NV21, I420, YV12, NV12_S10B, NV21_S10B */
+    case MFC_1220:
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_YV12M;
+
+        if ((pVideoInstInfo->eCodecType == VIDEO_CODING_HEVC) ||
+            (pVideoInstInfo->eCodecType == VIDEO_CODING_VP9)) {
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12_S10B;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M_S10B;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M_P010;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV21M_S10B;
+            pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV21M_P010;
+        }
+        break;
+    case MFC_110:  /* NV12, NV21, I420, YV12 */
+    case MFC_1120:
+    case MFC_101:
+    case MFC_100:
+    case MFC_1010:
+    case MFC_1011:
+    case MFC_1020:
+    case MFC_1021:
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_YV12M;
+        break;
+    case MFC_90:  /* NV12, NV21, BGRA, RGBA, I420, YV12, ARGB */
+    case MFC_80:
+#ifdef USE_HEVC_HWIP
+    case HEVC_10:
+#endif
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_BGRA8888;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_RGBA8888;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_YV12M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_ARGB8888;
+        break;
+    case MFC_723:  /* NV12, NV21, BGRA, RGBA, I420, YV12, ARGB, NV12T */
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_BGRA8888;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_RGBA8888;
+    case MFC_72:  /* NV12, NV21, I420, YV12, ARGB, NV12T */
+    case MFC_77:
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_I420M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_YV12M;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_ARGB8888;
+    case MFC_78:  /* NV12, NV21, NV12T */
+    case MFC_65:
+    case MFC_61:
+    case MFC_51:
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12_TILED;
+        pVideoInstInfo->supportFormat[nLastIndex++] = VIDEO_COLORFORMAT_NV12M_TILED;
+        break;
+    default:
+        break;
+    }
+
+EXIT:
+    return;
+}
+
+/*
+ * [Encoder OPS] Init
+ */
+static void *MFC_Encoder_Init(ExynosVideoInstInfo *pVideoInfo)
+{
+    CodecOSALVideoContext *pCtx     = NULL;
+    pthread_mutex_t       *pMutex   = NULL;
+
+    int ret = 0;
+    long hIonClient = 0;
+
+    if (pVideoInfo == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        goto EXIT_ALLOC_FAIL;
+    }
+
+    pCtx = (CodecOSALVideoContext *)malloc(sizeof(*pCtx));
+    if (pCtx == NULL) {
+        ALOGE("%s: Failed to allocate encoder context buffer", __FUNCTION__);
+        goto EXIT_ALLOC_FAIL;
+    }
+
+    memset(pCtx, 0, sizeof(*pCtx));
+
+    /* node open */
+#ifdef USE_HEVC_HWIP
+    if (pVideoInfo->eCodecType == VIDEO_CODING_HEVC) {
+        if (pVideoInfo->eSecurityType == VIDEO_SECURE)
+            ret = Codec_OSAL_DevOpen(VIDEO_HEVC_SECURE_ENCODER_NAME, O_RDWR, pCtx);
+        else
+            ret = Codec_OSAL_DevOpen(VIDEO_HEVC_ENCODER_NAME, O_RDWR, pCtx);
+    } else
+#endif
+    {
+        if (pVideoInfo->bOTFMode == VIDEO_TRUE) {
+            if (pVideoInfo->eSecurityType == VIDEO_SECURE)
+                ret = Codec_OSAL_DevOpen(VIDEO_MFC_OTF_SECURE_ENCODER_NAME, O_RDWR, pCtx);
+            else
+                ret = Codec_OSAL_DevOpen(VIDEO_MFC_OTF_ENCODER_NAME, O_RDWR, pCtx);
+        } else {
+            if (pVideoInfo->eSecurityType == VIDEO_SECURE)
+                ret = Codec_OSAL_DevOpen(VIDEO_MFC_SECURE_ENCODER_NAME, O_RDWR, pCtx);
+            else
+                ret = Codec_OSAL_DevOpen(VIDEO_MFC_ENCODER_NAME, O_RDWR, pCtx);
+        }
+    }
+
+    if (ret < 0) {
+        ALOGE("%s: Failed to open encoder device", __FUNCTION__);
+        goto EXIT_OPEN_FAIL;
+    }
+
+    memcpy(&pCtx->videoCtx.instInfo, pVideoInfo, sizeof(pCtx->videoCtx.instInfo));
+
+    ALOGV("%s: MFC version is %x", __FUNCTION__, pCtx->videoCtx.instInfo.HwVersion);
+
+    if (Codec_OSAL_QueryCap(pCtx) != 0) {
+        ALOGE("%s: Failed to QueryCap", __FUNCTION__);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+
+    pCtx->videoCtx.bStreamonInbuf  = VIDEO_FALSE;
+    pCtx->videoCtx.bStreamonOutbuf = VIDEO_FALSE;
+
+    /* mutex for input */
+    pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
+    if (pMutex == NULL) {
+        ALOGE("%s: Failed to allocate mutex about input buffer", __FUNCTION__);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+    if (pthread_mutex_init(pMutex, NULL) != 0) {
+        free(pMutex);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+    pCtx->videoCtx.pInMutex = (void*)pMutex;
+
+    /* mutex for output */
+    pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
+    if (pMutex == NULL) {
+        ALOGE("%s: Failed to allocate mutex about output buffer", __FUNCTION__);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+    if (pthread_mutex_init(pMutex, NULL) != 0) {
+        free(pMutex);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+    pCtx->videoCtx.pOutMutex = (void*)pMutex;
+
+    /* for shared memory : temporal svc info, ROI info */
+    hIonClient = (long)ion_open();
+#ifdef USE_ANDROID
+    if (hIonClient < 0) {
+#else
+    if (hIonClient <= 0) {
+#endif
+        ALOGE("%s: Failed to create ion_client", __FUNCTION__);
+        goto EXIT_QUERYCAP_FAIL;
+    }
+
+    pCtx->videoCtx.hIONHandle = (unsigned long)hIonClient;
+
+    if (pCtx->videoCtx.instInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_TRUE) {
+        if (ion_alloc_fd(pCtx->videoCtx.hIONHandle, sizeof(TemporalLayerShareBuffer),
+                         0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED, (void *)&(pCtx->videoCtx.specificInfo.enc.nTemporalLayerShareBufferFD)) < 0 ) {
+            ALOGE("%s: Failed to ion_alloc_fd for nTemporalLayerShareBufferFD", __FUNCTION__);
+            pCtx->videoCtx.specificInfo.enc.nTemporalLayerShareBufferFD = 0;
+            goto EXIT_QUERYCAP_FAIL;
+        }
+
+        pCtx->videoCtx.specificInfo.enc.pTemporalLayerShareBufferAddr = Codec_OSAL_MemoryMap(NULL, sizeof(TemporalLayerShareBuffer),
+                                                   PROT_READ | PROT_WRITE, MAP_SHARED,  pCtx->videoCtx.specificInfo.enc.nTemporalLayerShareBufferFD, 0);
+        if (pCtx->videoCtx.specificInfo.enc.pTemporalLayerShareBufferAddr == MAP_FAILED) {
+            ALOGE("%s: Failed to mmap for nTemporalLayerShareBufferFD", __FUNCTION__);
+            goto EXIT_QUERYCAP_FAIL;
+        }
+
+        memset(pCtx->videoCtx.specificInfo.enc.pTemporalLayerShareBufferAddr, 0, sizeof(TemporalLayerShareBuffer));
+    }
+
+    if (pCtx->videoCtx.instInfo.supportInfo.enc.bRoiInfoSupport == VIDEO_TRUE) {
+        if (ion_alloc_fd(pCtx->videoCtx.hIONHandle, sizeof(RoiInfoShareBuffer),
+                         0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED, (void *)&(pCtx->videoCtx.specificInfo.enc.nRoiShareBufferFD)) < 0 ) {
+            ALOGE("%s: Failed to ion_alloc_fd for nRoiShareBufferFD", __FUNCTION__);
+            pCtx->videoCtx.specificInfo.enc.nRoiShareBufferFD = 0;
+            goto EXIT_QUERYCAP_FAIL;
+        }
+
+        pCtx->videoCtx.specificInfo.enc.pRoiShareBufferAddr = Codec_OSAL_MemoryMap(NULL, sizeof(RoiInfoShareBuffer),
+                                                   PROT_READ | PROT_WRITE, MAP_SHARED,  pCtx->videoCtx.specificInfo.enc.nRoiShareBufferFD, 0);
+        if (pCtx->videoCtx.specificInfo.enc.pRoiShareBufferAddr == MAP_FAILED) {
+            ALOGE("%s: Failed to mmap for nRoiShareBufferFD", __FUNCTION__);
+            goto EXIT_QUERYCAP_FAIL;
+        }
+
+        memset(pCtx->videoCtx.specificInfo.enc.pRoiShareBufferAddr, 0, sizeof(RoiInfoShareBuffer));
+    }
+
+    return (void *)pCtx;
+
+EXIT_QUERYCAP_FAIL:
+    if (pCtx->videoCtx.pInMutex != NULL) {
+        pthread_mutex_destroy(pCtx->videoCtx.pInMutex);
+        free(pCtx->videoCtx.pInMutex);
+    }
+
+    if (pCtx->videoCtx.pOutMutex != NULL) {
+        pthread_mutex_destroy(pCtx->videoCtx.pOutMutex);
+        free(pCtx->videoCtx.pOutMutex);
+    }
+
+    if (pCtx->videoCtx.instInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_TRUE) {
+        if (pCtx->videoCtx.specificInfo.enc.pTemporalLayerShareBufferAddr != NULL) {
+            Codec_OSAL_MemoryUnmap(pCtx->videoCtx.specificInfo.enc.pTemporalLayerShareBufferAddr, sizeof(TemporalLayerShareBuffer));
+            pCtx->videoCtx.specificInfo.enc.pTemporalLayerShareBufferAddr = NULL;
+        }
+
+        /* free a ion_buffer */
+        if (pCtx->videoCtx.specificInfo.enc.nTemporalLayerShareBufferFD > 0) {
+            ion_close(pCtx->videoCtx.specificInfo.enc.nTemporalLayerShareBufferFD);
+            pCtx->videoCtx.specificInfo.enc.nTemporalLayerShareBufferFD = 0;
+        }
+    }
+
+    if (pCtx->videoCtx.instInfo.supportInfo.enc.bRoiInfoSupport == VIDEO_TRUE) {
+        if (pCtx->videoCtx.specificInfo.enc.pRoiShareBufferAddr != NULL) {
+            Codec_OSAL_MemoryUnmap(pCtx->videoCtx.specificInfo.enc.pRoiShareBufferAddr, sizeof(RoiInfoShareBuffer));
+            pCtx->videoCtx.specificInfo.enc.pRoiShareBufferAddr = NULL;
+        }
+
+        /* free a ion_buffer */
+        if (pCtx->videoCtx.specificInfo.enc.nRoiShareBufferFD > 0) {
+            ion_close(pCtx->videoCtx.specificInfo.enc.nRoiShareBufferFD);
+            pCtx->videoCtx.specificInfo.enc.nRoiShareBufferFD = 0;
+        }
+    }
+
+    /* free a ion_client */
+    if (pCtx->videoCtx.hIONHandle > 0) {
+        ion_close(pCtx->videoCtx.hIONHandle);
+        pCtx->videoCtx.hIONHandle = 0;
+    }
+
+    Codec_OSAL_DevClose(pCtx);
+
+EXIT_OPEN_FAIL:
+    free(pCtx);
+
+EXIT_ALLOC_FAIL:
+    return NULL;
+}
+
+/*
+ * [Encoder OPS] Finalize
+ */
+static ExynosVideoErrorType MFC_Encoder_Finalize(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx         = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoPlane      *pVideoPlane  = NULL;
+    pthread_mutex_t       *pMutex       = NULL;
+    ExynosVideoErrorType   ret          = VIDEO_ERROR_NONE;
+    int i, j;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.instInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_TRUE) {
+        if (pCtx->videoCtx.specificInfo.enc.pTemporalLayerShareBufferAddr != NULL) {
+            Codec_OSAL_MemoryUnmap(pCtx->videoCtx.specificInfo.enc.pTemporalLayerShareBufferAddr, sizeof(TemporalLayerShareBuffer));
+            pCtx->videoCtx.specificInfo.enc.pTemporalLayerShareBufferAddr = NULL;
+        }
+
+        /* free a ion_buffer */
+        if (pCtx->videoCtx.specificInfo.enc.nTemporalLayerShareBufferFD > 0) {
+            ion_close(pCtx->videoCtx.specificInfo.enc.nTemporalLayerShareBufferFD);
+            pCtx->videoCtx.specificInfo.enc.nTemporalLayerShareBufferFD = 0;
+        }
+    }
+
+    if (pCtx->videoCtx.instInfo.supportInfo.enc.bRoiInfoSupport == VIDEO_TRUE) {
+        if (pCtx->videoCtx.specificInfo.enc.pRoiShareBufferAddr != NULL) {
+            Codec_OSAL_MemoryUnmap(pCtx->videoCtx.specificInfo.enc.pRoiShareBufferAddr, sizeof(RoiInfoShareBuffer));
+            pCtx->videoCtx.specificInfo.enc.pRoiShareBufferAddr = NULL;
+        }
+
+        /* free a ion_buffer */
+        if (pCtx->videoCtx.specificInfo.enc.nRoiShareBufferFD > 0) {
+            ion_close(pCtx->videoCtx.specificInfo.enc.nRoiShareBufferFD);
+            pCtx->videoCtx.specificInfo.enc.nRoiShareBufferFD = 0;
+        }
+    }
+
+    /* free a ion_client */
+    if (pCtx->videoCtx.hIONHandle > 0) {
+        ion_close(pCtx->videoCtx.hIONHandle);
+        pCtx->videoCtx.hIONHandle = 0;
+    }
+
+    if (pCtx->videoCtx.pOutMutex != NULL) {
+        pMutex = (pthread_mutex_t*)pCtx->videoCtx.pOutMutex;
+        pthread_mutex_destroy(pMutex);
+        free(pMutex);
+        pCtx->videoCtx.pOutMutex = NULL;
+    }
+
+    if (pCtx->videoCtx.pInMutex != NULL) {
+        pMutex = (pthread_mutex_t*)pCtx->videoCtx.pInMutex;
+        pthread_mutex_destroy(pMutex);
+        free(pMutex);
+        pCtx->videoCtx.pInMutex = NULL;
+    }
+
+    if (pCtx->videoCtx.bShareInbuf == VIDEO_FALSE) {
+        for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+            for (j = 0; j < pCtx->videoCtx.nInbufPlanes; j++) {
+                pVideoPlane = &pCtx->videoCtx.pInbuf[i].planes[j];
+                if (pVideoPlane->addr != NULL) {
+                    Codec_OSAL_MemoryUnmap(pVideoPlane->addr, pVideoPlane->allocSize);
+                    pVideoPlane->addr = NULL;
+                    pVideoPlane->allocSize = 0;
+                    pVideoPlane->dataSize = 0;
+                }
+
+                pCtx->videoCtx.pInbuf[i].pGeometry = NULL;
+                pCtx->videoCtx.pInbuf[i].bQueued = VIDEO_FALSE;
+                pCtx->videoCtx.pInbuf[i].bRegistered = VIDEO_FALSE;
+            }
+        }
+    }
+
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_FALSE) {
+        for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+            for (j = 0; j < pCtx->videoCtx.nOutbufPlanes; j++) {
+                pVideoPlane = &pCtx->videoCtx.pOutbuf[i].planes[j];
+                if (pVideoPlane->addr != NULL) {
+                    Codec_OSAL_MemoryUnmap(pVideoPlane->addr, pVideoPlane->allocSize);
+                    pVideoPlane->addr = NULL;
+                    pVideoPlane->allocSize = 0;
+                    pVideoPlane->dataSize = 0;
+                }
+
+                pCtx->videoCtx.pOutbuf[i].pGeometry = NULL;
+                pCtx->videoCtx.pOutbuf[i].bQueued = VIDEO_FALSE;
+                pCtx->videoCtx.pOutbuf[i].bRegistered = VIDEO_FALSE;
+            }
+        }
+    }
+
+    if (pCtx->videoCtx.pInbuf != NULL) {
+        free(pCtx->videoCtx.pInbuf);
+        pCtx->videoCtx.pInbuf = NULL;
+    }
+
+    if (pCtx->videoCtx.pOutbuf != NULL) {
+        free(pCtx->videoCtx.pOutbuf);
+        pCtx->videoCtx.pOutbuf = NULL;
+    }
+
+    Codec_OSAL_DevClose(pCtx);
+
+    free(pCtx);
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Extended Control
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_EncParam (
+    void                *pHandle,
+    ExynosVideoEncParam *pEncParam)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if ((pCtx == NULL) ||
+        (pEncParam == NULL)) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControls(pCtx, CODEC_OSAL_CID_ENC_SET_PARAMS, (void *)pEncParam) != 0) {
+        ALOGE("%s: Failed to SetControls", __FUNCTION__);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Frame Tag
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_FrameTag(
+    void   *pHandle,
+    int     nFrameTag)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_VIDEO_FRAME_TAG, nFrameTag) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, nFrameTag);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Get Frame Tag
+ */
+static int MFC_Encoder_Get_FrameTag(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+
+    int nFrameTag = -1;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_GetControl(pCtx, CODEC_OSAL_CID_VIDEO_FRAME_TAG, &nFrameTag) != 0) {
+        ALOGE("%s: Failed to GetControl(val : 0x%x)", __FUNCTION__, nFrameTag);
+        goto EXIT;
+    }
+
+EXIT:
+    return nFrameTag;
+}
+
+/*
+ * [Encoder OPS] Set Frame Type
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_FrameType(
+    void                    *pHandle,
+    ExynosVideoFrameType     eFrameType)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_FRAME_TYPE, eFrameType) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, eFrameType);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Frame Rate
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_FrameRate(
+    void   *pHandle,
+    int     nFramerate)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_FRAME_RATE, nFramerate) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, nFramerate);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Bit Rate
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_BitRate(
+    void   *pHandle,
+    int     nBitrate)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_BIT_RATE, nBitrate) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, nBitrate);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Quantization Min/Max
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_QuantizationRange(
+    void                *pHandle,
+    ExynosVideoQPRange   qpRange)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (qpRange.QpMin_I > qpRange.QpMax_I) {
+        ALOGE("%s: QP(I) range(%d, %d) is wrong", __FUNCTION__, qpRange.QpMin_I, qpRange.QpMax_I);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControls(pCtx, CODEC_OSAL_CID_ENC_QP_RANGE, &qpRange) != 0) {
+        ALOGE("%s: Failed to SetControl", __FUNCTION__);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Frame Skip
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_FrameSkip(
+    void   *pHandle,
+    int     nFrameSkip)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_FRAME_SKIP_MODE, nFrameSkip) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, nFrameSkip);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set IDR Period
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_IDRPeriod(
+    void   *pHandle,
+    int     nIDRPeriod)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_IDR_PERIOD, nIDRPeriod) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, nIDRPeriod);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Slice Mode
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_SliceMode(
+    void *pHandle,
+    int   nSliceMode,
+    int   nSliceArgument)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int value;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    value = (((nSliceMode << 16) & 0xffff0000) | (nSliceArgument & 0xffff));
+
+#if 0  // TODO
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_SLICE_MODE, value) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, value);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+#else
+    ALOGW("%s: not implemented yet", __FUNCTION__);
+#endif
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Enable Prepend SPS and PPS to every IDR Frames
+ */
+static ExynosVideoErrorType MFC_Encoder_Enable_PrependSpsPpsToIdr(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    switch ((int)pCtx->videoCtx.instInfo.eCodecType) {
+    case VIDEO_CODING_AVC:
+        if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_H264_PREPEND_SPSPPS_TO_IDR, 1) != 0) {
+            ALOGE("%s: Failed to SetControl", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+        break;
+    case VIDEO_CODING_HEVC:
+        if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_HEVC_PREPEND_SPSPPS_TO_IDR, 1) != 0) {
+            ALOGE("%s: Failed to SetControl", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+        break;
+    default:
+        ALOGE("%s: codec(%x) can't support PrependSpsPpsToIdr", __FUNCTION__, pCtx->videoCtx.instInfo.eCodecType);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Qos Ratio
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_QosRatio(
+    void *pHandle,
+    int   nRatio)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_VIDEO_QOS_RATIO, nRatio) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, nRatio);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Layer Change
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_LayerChange(
+    void                        *pHandle,
+    TemporalLayerShareBuffer     TemporalSVC)
+{
+    CodecOSALVideoContext      *pCtx  = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType        ret   = VIDEO_ERROR_NONE;
+    TemporalLayerShareBuffer   *pTLSB = NULL;
+
+    unsigned int CID = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    pTLSB = (TemporalLayerShareBuffer *)pCtx->videoCtx.specificInfo.enc.pTemporalLayerShareBufferAddr;
+
+    switch ((int)pCtx->videoCtx.instInfo.eCodecType) {
+    case VIDEO_CODING_AVC:
+        CID = CODEC_OSAL_CID_ENC_H264_TEMPORAL_SVC_LAYER_CH;
+        break;
+    case VIDEO_CODING_HEVC:
+        CID = CODEC_OSAL_CID_ENC_HEVC_TEMPORAL_SVC_LAYER_CH;
+        break;
+    case VIDEO_CODING_VP8:
+        CID = CODEC_OSAL_CID_ENC_VP8_TEMPORAL_SVC_LAYER_CH;
+        break;
+    case VIDEO_CODING_VP9:
+        CID = CODEC_OSAL_CID_ENC_VP9_TEMPORAL_SVC_LAYER_CH;
+        break;
+    default:
+        ALOGE("%s: this codec type is not supported(%x), F/W ver(%x)",
+                __FUNCTION__, pCtx->videoCtx.instInfo.eCodecType, pCtx->videoCtx.instInfo.HwVersion);
+        ret = VIDEO_ERROR_NOSUPPORT;
+        goto EXIT;
+        break;
+    }
+
+    memcpy(pTLSB, &TemporalSVC, sizeof(TemporalLayerShareBuffer));
+    if (Codec_OSAL_SetControl(pCtx, CID,
+                                pCtx->videoCtx.specificInfo.enc.nTemporalLayerShareBufferFD) != 0) {
+        ALOGE("%s: Failed to SetControl", __FUNCTION__);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Dynamic QP Control
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_DynamicQpControl(
+    void    *pHandle,
+    int      nQp)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_SET_CONFIG_QP, nQp) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, nQp);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Mark LTR-frame
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_MarkLTRFrame(
+    void    *pHandle,
+    int      nLongTermFrmIdx)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_H264_LTR_MARK_INDEX, nLongTermFrmIdx) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, nLongTermFrmIdx);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Used LTR-frame
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_UsedLTRFrame(
+    void    *pHandle,
+    int      nUsedLTRFrameNum)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_H264_LTR_USE_INDEX, nUsedLTRFrameNum) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, nUsedLTRFrameNum);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Base PID
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_BasePID(
+    void    *pHandle,
+    int      nPID)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_H264_LTR_BASE_PID, nPID) != 0) {
+        ALOGE("%s: Failed to SetControl(val : 0x%x)", __FUNCTION__, nPID);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Roi Information
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_RoiInfo(
+    void                   *pHandle,
+    RoiInfoShareBuffer     *pRoiInfo)
+{
+    CodecOSALVideoContext   *pCtx  = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType     ret   = VIDEO_ERROR_NONE;
+    RoiInfoShareBuffer      *pRISB = NULL;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    pRISB = (RoiInfoShareBuffer *)pCtx->videoCtx.specificInfo.enc.pRoiShareBufferAddr;
+    if (pCtx->videoCtx.instInfo.supportInfo.enc.bRoiInfoSupport == VIDEO_FALSE) {
+        ALOGE("%s: ROI Info setting is not supported :: codec type(%x), F/W ver(%x)",
+                    __FUNCTION__, pCtx->videoCtx.instInfo.eCodecType, pCtx->videoCtx.instInfo.HwVersion);
+        ret = VIDEO_ERROR_NOSUPPORT;
+        goto EXIT;
+    }
+
+    memcpy(pRISB, pRoiInfo, sizeof(RoiInfoShareBuffer));
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_ROI_INFO,
+                                pCtx->videoCtx.specificInfo.enc.nRoiShareBufferFD) != 0) {
+        ALOGE("%s: Failed to SetControl", __FUNCTION__);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Enable Weighted Prediction Encoding
+ */
+static ExynosVideoErrorType MFC_Encoder_Enable_WeightedPrediction(void *pHandle)
+{
+    CodecOSALVideoContext   *pCtx  = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType     ret   = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_WP_ENABLE, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Y-SUM Data
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_YSumData(
+    void           *pHandle,
+    unsigned int    nHighData,
+    unsigned int    nLowData)
+{
+    CodecOSALVideoContext   *pCtx  = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType     ret   = VIDEO_ERROR_NONE;
+
+    unsigned long long nYSumData = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    nYSumData = (((unsigned long long)nHighData) << 32) | nLowData;  /* 64bit data */
+
+    /* MFC D/D just want a LowData */
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_YSUM_DATA, (int)nLowData) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set I-frame ratio (It is applied only CBR mode)
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_IFrameRatio(
+    void           *pHandle,
+    int             nRatio)
+{
+    CodecOSALVideoContext   *pCtx  = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType     ret   = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    switch ((int)pCtx->videoCtx.instInfo.eCodecType) {
+    case VIDEO_CODING_AVC:
+    case VIDEO_CODING_HEVC:
+        if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_I_FRAME_RATIO, nRatio) != 0) {
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        ret = VIDEO_ERROR_NONE;
+        break;
+    default:
+        ALOGE("%s: codec(%x) can't support Set_IFrameRatio", __FUNCTION__, pCtx->videoCtx.instInfo.eCodecType);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Set Color Aspects
+ */
+ExynosVideoErrorType MFC_Encoder_Set_ColorAspects(
+    void                    *pHandle,
+    ExynosVideoColorAspects *pColorAspects)
+{
+    CodecOSALVideoContext   *pCtx  = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType     ret   = VIDEO_ERROR_NONE;
+
+    if ((pCtx == NULL) ||
+        (pColorAspects == NULL)) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.instInfo.supportInfo.enc.bColorAspectsSupport == VIDEO_FALSE) {
+        ALOGE("%s: can't support Set_ColorAspects. // codec type(%x), F/W ver(%x)",
+                    __FUNCTION__, pCtx->videoCtx.instInfo.eCodecType, pCtx->videoCtx.instInfo.HwVersion);
+        ret = VIDEO_ERROR_NOSUPPORT;
+        goto EXIT;
+    }
+
+    switch ((int)pCtx->videoCtx.instInfo.eCodecType) {
+    case VIDEO_CODING_AVC:
+    case VIDEO_CODING_HEVC:
+    case VIDEO_CODING_VP9:
+        if (Codec_OSAL_SetControls(pCtx, CODEC_OSAL_CID_ENC_COLOR_ASPECTS, (void *)pColorAspects) != 0) {
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        ret = VIDEO_ERROR_NONE;
+        break;
+    default:
+        ALOGE("%s: codec(%x) can't support Set_ColorAspects", __FUNCTION__, pCtx->videoCtx.instInfo.eCodecType);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Enable Cacheable (Input)
+ */
+static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_VIDEO_CACHEABLE_BUFFER, 2) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Enable Cacheable (Output)
+ */
+static ExynosVideoErrorType MFC_Encoder_Enable_Cacheable_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_VIDEO_CACHEABLE_BUFFER, 1) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Set Shareable Buffer (Input)
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.bShareInbuf = VIDEO_TRUE;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Set Shareable Buffer (Output)
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_Shareable_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.bShareOutbuf = VIDEO_TRUE;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Get Buffer (Input)
+ */
+static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Inbuf(
+    void               *pHandle,
+    int                 nIndex,
+    ExynosVideoBuffer **pBuffer)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        *pBuffer = NULL;
+        ret = VIDEO_ERROR_NOBUFFERS;
+        goto EXIT;
+    }
+
+    if ((nIndex < 0) ||
+        (pCtx->videoCtx.nInbufs <= nIndex)) {
+        *pBuffer = NULL;
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    *pBuffer = (ExynosVideoBuffer *)&pCtx->videoCtx.pInbuf[nIndex];
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Get Buffer (Output)
+ */
+static ExynosVideoErrorType MFC_Encoder_Get_Buffer_Outbuf(
+    void               *pHandle,
+    int                 nIndex,
+    ExynosVideoBuffer **pBuffer)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        *pBuffer = NULL;
+        ret = VIDEO_ERROR_NOBUFFERS;
+        goto EXIT;
+    }
+
+    if ((nIndex < 0) ||
+        (pCtx->videoCtx.nOutbufs <= nIndex)) {
+        *pBuffer = NULL;
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    *pBuffer = (ExynosVideoBuffer *)&pCtx->videoCtx.pOutbuf[nIndex];
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Set Geometry (Src)
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Inbuf(
+    void                *pHandle,
+    ExynosVideoGeometry *pBufferConf)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    CodecOSAL_Format fmt;
+
+    if ((pCtx == NULL) ||
+        (pBufferConf == NULL)) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&fmt, 0, sizeof(fmt));
+
+    fmt.type   = CODEC_OSAL_BUF_TYPE_SRC;
+    fmt.format = Codec_OSAL_ColorFormatToPixelFormat(pBufferConf->eColorFormat, pCtx->videoCtx.instInfo.HwVersion);
+    fmt.width  = pBufferConf->nFrameWidth;
+    fmt.height = pBufferConf->nFrameHeight;
+    fmt.stride = pBufferConf->nStride;
+    fmt.nPlane = pBufferConf->nPlaneCnt;
+
+    if (Codec_OSAL_SetFormat(pCtx, &fmt) != 0) {
+        ALOGE("%s: Failed to SetFormat", __FUNCTION__);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    memcpy(&pCtx->videoCtx.inbufGeometry, pBufferConf, sizeof(pCtx->videoCtx.inbufGeometry));
+    pCtx->videoCtx.nInbufPlanes = pBufferConf->nPlaneCnt;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Get Geometry (Src)
+ */
+static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Inbuf(
+    void                *pHandle,
+    ExynosVideoGeometry *pBufferConf)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    CodecOSAL_Format fmt;
+
+    if ((pCtx == NULL) ||
+        (pBufferConf == NULL)) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&fmt, 0, sizeof(fmt));
+    fmt.type = CODEC_OSAL_BUF_TYPE_SRC;
+
+    if (Codec_OSAL_GetFormat(pCtx, &fmt) != 0) {
+        ALOGE("%s: Failed to GetFormat", __FUNCTION__);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pBufferConf->nFrameWidth    = fmt.width;
+    pBufferConf->nFrameHeight   = fmt.height;
+    pBufferConf->nSizeImage     = fmt.planeSize[0];
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Set Geometry (Dst)
+ */
+static ExynosVideoErrorType MFC_Encoder_Set_Geometry_Outbuf(
+    void                *pHandle,
+    ExynosVideoGeometry *pBufferConf)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    CodecOSAL_Format fmt;
+
+    if ((pCtx == NULL) ||
+        (pBufferConf == NULL)) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&fmt, 0, sizeof(fmt));
+    fmt.type            = CODEC_OSAL_BUF_TYPE_DST;
+    fmt.format          = Codec_OSAL_CodingTypeToCompressdFormat(pBufferConf->eCompressionFormat);
+    fmt.planeSize[0]    = pBufferConf->nSizeImage;
+    fmt.nPlane          = pBufferConf->nPlaneCnt;
+
+    if (Codec_OSAL_SetFormat(pCtx, &fmt) != 0) {
+        ALOGE("%s: Failed to SetFormat", __FUNCTION__);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    memcpy(&pCtx->videoCtx.outbufGeometry, pBufferConf, sizeof(pCtx->videoCtx.outbufGeometry));
+    pCtx->videoCtx.nOutbufPlanes = pBufferConf->nPlaneCnt;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Get Geometry (Dst)
+ */
+static ExynosVideoErrorType MFC_Encoder_Get_Geometry_Outbuf(
+    void                *pHandle,
+    ExynosVideoGeometry *pBufferConf)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    CodecOSAL_Format fmt;
+
+    if ((pCtx == NULL) ||
+        (pBufferConf == NULL)) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&fmt, 0, sizeof(fmt));
+    fmt.type = CODEC_OSAL_BUF_TYPE_DST;
+
+    if (Codec_OSAL_GetFormat(pCtx, &fmt) != 0) {
+        ALOGE("%s: Failed to GetFormat", __FUNCTION__);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pBufferConf->nSizeImage = fmt.planeSize[0];
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Setup (Src)
+ */
+static ExynosVideoErrorType MFC_Encoder_Setup_Inbuf(
+    void           *pHandle,
+    unsigned int    nBufferCount)
+{
+    CodecOSALVideoContext *pCtx         = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoPlane      *pVideoPlane  = NULL;
+    ExynosVideoErrorType   ret          = VIDEO_ERROR_NONE;
+
+    CodecOSAL_ReqBuf reqBuf;
+    CodecOSAL_Buffer buf;
+
+    int i, j;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (nBufferCount == 0) {
+        nBufferCount = MAX_INPUTBUFFER_COUNT;
+        ALOGV("%s: Change buffer count %d", __FUNCTION__, nBufferCount);
+    }
+
+    memset(&reqBuf, 0, sizeof(reqBuf));
+
+    reqBuf.type = CODEC_OSAL_BUF_TYPE_SRC;
+    reqBuf.count = nBufferCount;
+    if (pCtx->videoCtx.bShareInbuf == VIDEO_TRUE)
+        reqBuf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    else
+        reqBuf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+
+    if (Codec_OSAL_RequestBuf(pCtx, &reqBuf) != 0) {
+        ALOGE("Failed to RequestBuf");
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.nInbufs = (int)reqBuf.count;
+
+    pCtx->videoCtx.pInbuf = malloc(sizeof(*pCtx->videoCtx.pInbuf) * pCtx->videoCtx.nInbufs);
+    if (pCtx->videoCtx.pInbuf == NULL) {
+        ALOGE("%s: Failed to allocate input buffer context", __FUNCTION__);
+        ret = VIDEO_ERROR_NOMEM;
+        goto EXIT;
+    }
+    memset(pCtx->videoCtx.pInbuf, 0, sizeof(*pCtx->videoCtx.pInbuf) * pCtx->videoCtx.nInbufs);
+
+    memset(&buf, 0, sizeof(buf));
+
+    if (pCtx->videoCtx.bShareInbuf == VIDEO_FALSE) {
+        buf.type    = CODEC_OSAL_BUF_TYPE_SRC;
+        buf.memory  = CODEC_OSAL_MEM_TYPE_MMAP;
+        buf.nPlane  = pCtx->videoCtx.nInbufPlanes;
+
+        for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+            buf.index = i;
+
+            if (Codec_OSAL_QueryBuf(pCtx, &buf) != 0) {
+                ALOGE("%s: Failed to QueryBuf", __FUNCTION__);
+                ret = VIDEO_ERROR_APIFAIL;
+                goto EXIT;
+            }
+
+            for (j = 0; j < pCtx->videoCtx.nInbufPlanes; j++) {
+                pVideoPlane = &pCtx->videoCtx.pInbuf[i].planes[j];
+
+                pVideoPlane->addr = Codec_OSAL_MemoryMap(NULL,
+                        buf.planes[j].bufferSize, PROT_READ | PROT_WRITE,
+                        MAP_SHARED, (unsigned long)buf.planes[j].addr, buf.planes[j].offset);
+                if (pVideoPlane->addr == MAP_FAILED) {
+                    ALOGE("%s: Failed to map", __FUNCTION__);
+                    ret = VIDEO_ERROR_MAPFAIL;
+                    goto EXIT;
+                }
+
+                pVideoPlane->allocSize = buf.planes[j].bufferSize;
+                pVideoPlane->dataSize = 0;
+            }
+
+            pCtx->videoCtx.pInbuf[i].pGeometry = &pCtx->videoCtx.inbufGeometry;
+            pCtx->videoCtx.pInbuf[i].bQueued = VIDEO_FALSE;
+            pCtx->videoCtx.pInbuf[i].bRegistered = VIDEO_TRUE;
+
+        }
+    } else {
+        for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+            pCtx->videoCtx.pInbuf[i].pGeometry = &pCtx->videoCtx.inbufGeometry;
+            pCtx->videoCtx.pInbuf[i].bQueued = VIDEO_FALSE;
+            pCtx->videoCtx.pInbuf[i].bRegistered = VIDEO_FALSE;
+        }
+    }
+
+    return ret;
+
+EXIT:
+    if ((pCtx != NULL) && (pCtx->videoCtx.pInbuf != NULL)) {
+        if (pCtx->videoCtx.bShareInbuf == VIDEO_FALSE) {
+            for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+                for (j = 0; j < pCtx->videoCtx.nInbufPlanes; j++) {
+                    pVideoPlane = &pCtx->videoCtx.pInbuf[i].planes[j];
+
+                    if (pVideoPlane->addr == MAP_FAILED) {
+                        pVideoPlane->addr = NULL;
+                        break;
+                    }
+
+                    Codec_OSAL_MemoryUnmap(pVideoPlane->addr, pVideoPlane->allocSize);
+                }
+            }
+        }
+
+        free(pCtx->videoCtx.pInbuf);
+        pCtx->videoCtx.pInbuf = NULL;
+    }
+
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Setup (Dst)
+ */
+static ExynosVideoErrorType MFC_Encoder_Setup_Outbuf(
+    void           *pHandle,
+    unsigned int    nBufferCount)
+{
+    CodecOSALVideoContext *pCtx         = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoPlane      *pVideoPlane  = NULL;
+    ExynosVideoErrorType   ret          = VIDEO_ERROR_NONE;
+
+    CodecOSAL_ReqBuf reqBuf;
+    CodecOSAL_Buffer buf;
+
+    int i, j;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (nBufferCount == 0) {
+        nBufferCount = MAX_OUTPUTBUFFER_COUNT;
+        ALOGV("%s: Change buffer count %d", __FUNCTION__, nBufferCount);
+    }
+
+    memset(&reqBuf, 0, sizeof(reqBuf));
+
+    reqBuf.type = CODEC_OSAL_BUF_TYPE_DST;
+    reqBuf.count = nBufferCount;
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_TRUE)
+        reqBuf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    else
+        reqBuf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+
+    if (Codec_OSAL_RequestBuf(pCtx, &reqBuf) != 0) {
+        ALOGE("%s: Failed to RequestBuf", __FUNCTION__);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.nOutbufs = reqBuf.count;
+
+    pCtx->videoCtx.pOutbuf = malloc(sizeof(*pCtx->videoCtx.pOutbuf) * pCtx->videoCtx.nOutbufs);
+    if (pCtx->videoCtx.pOutbuf == NULL) {
+        ALOGE("%s: Failed to allocate output buffer context", __FUNCTION__);
+        ret = VIDEO_ERROR_NOMEM;
+        goto EXIT;
+    }
+    memset(pCtx->videoCtx.pOutbuf, 0, sizeof(*pCtx->videoCtx.pOutbuf) * pCtx->videoCtx.nOutbufs);
+
+    memset(&buf, 0, sizeof(buf));
+
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_FALSE) {
+        buf.type    = CODEC_OSAL_BUF_TYPE_DST;
+        buf.memory  = CODEC_OSAL_MEM_TYPE_MMAP;
+        buf.nPlane  = pCtx->videoCtx.nOutbufPlanes;
+
+        for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+            buf.index = i;
+
+            if (Codec_OSAL_QueryBuf(pCtx, &buf) != 0) {
+                ALOGE("%s: Failed to QueryBuf", __FUNCTION__);
+                ret = VIDEO_ERROR_APIFAIL;
+                goto EXIT;
+            }
+
+            for (j = 0; j < pCtx->videoCtx.nOutbufPlanes; j++) {
+                pVideoPlane = &pCtx->videoCtx.pOutbuf[i].planes[j];
+
+                pVideoPlane->addr = Codec_OSAL_MemoryMap(NULL,
+                        buf.planes[j].bufferSize, PROT_READ | PROT_WRITE,
+                        MAP_SHARED, (unsigned long)buf.planes[j].addr, buf.planes[j].offset);
+                if (pVideoPlane->addr == MAP_FAILED) {
+                    ALOGE("%s: Failed to map", __FUNCTION__);
+                    ret = VIDEO_ERROR_MAPFAIL;
+                    goto EXIT;
+                }
+
+                pVideoPlane->allocSize = buf.planes[j].bufferSize;
+                pVideoPlane->dataSize = 0;
+            }
+
+            pCtx->videoCtx.pOutbuf[i].pGeometry = &pCtx->videoCtx.outbufGeometry;
+            pCtx->videoCtx.pOutbuf[i].bQueued = VIDEO_FALSE;
+            pCtx->videoCtx.pOutbuf[i].bRegistered = VIDEO_TRUE;
+        }
+    } else {
+        for (i = 0; i < pCtx->videoCtx.nOutbufs; i++ ) {
+            pCtx->videoCtx.pOutbuf[i].pGeometry = &pCtx->videoCtx.outbufGeometry;
+            pCtx->videoCtx.pOutbuf[i].bQueued = VIDEO_FALSE;
+            pCtx->videoCtx.pOutbuf[i].bRegistered = VIDEO_FALSE;
+        }
+    }
+
+    return ret;
+
+EXIT:
+    if ((pCtx != NULL) && (pCtx->videoCtx.pOutbuf != NULL)) {
+        if (pCtx->videoCtx.bShareOutbuf == VIDEO_FALSE) {
+            for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+                for (j = 0; j < pCtx->videoCtx.nOutbufPlanes; j++) {
+                    pVideoPlane = &pCtx->videoCtx.pOutbuf[i].planes[j];
+
+                    if (pVideoPlane->addr == MAP_FAILED) {
+                        pVideoPlane->addr = NULL;
+                        break;
+                    }
+
+                    Codec_OSAL_MemoryUnmap(pVideoPlane->addr, pVideoPlane->allocSize);
+                }
+            }
+        }
+
+        free(pCtx->videoCtx.pOutbuf);
+        pCtx->videoCtx.pOutbuf = NULL;
+    }
+
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Run (src)
+ */
+static ExynosVideoErrorType MFC_Encoder_Run_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonInbuf == VIDEO_FALSE) {
+        if (Codec_OSAL_SetStreamOn(pCtx, CODEC_OSAL_BUF_TYPE_SRC) != 0) {
+            ALOGE("%s: Failed to streamon for input buffer", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        pCtx->videoCtx.bStreamonInbuf = VIDEO_TRUE;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Run (Dst)
+ */
+static ExynosVideoErrorType MFC_Encoder_Run_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonOutbuf == VIDEO_FALSE) {
+        if (Codec_OSAL_SetStreamOn(pCtx, CODEC_OSAL_BUF_TYPE_DST) != 0) {
+            ALOGE("%s: Failed to streamon for output buffer", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        pCtx->videoCtx.bStreamonOutbuf = VIDEO_TRUE;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Stop (Src)
+ */
+static ExynosVideoErrorType MFC_Encoder_Stop_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonInbuf == VIDEO_TRUE) {
+        if (Codec_OSAL_SetStreamOff(pCtx, CODEC_OSAL_BUF_TYPE_SRC) != 0) {
+            ALOGE("%s: Failed to streamoff for input buffer", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        pCtx->videoCtx.bStreamonInbuf = VIDEO_FALSE;
+    }
+
+    for (i = 0; i <  pCtx->videoCtx.nInbufs; i++)
+        pCtx->videoCtx.pInbuf[i].bQueued = VIDEO_FALSE;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Stop (Dst)
+ */
+static ExynosVideoErrorType MFC_Encoder_Stop_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonOutbuf == VIDEO_TRUE) {
+        if (Codec_OSAL_SetStreamOff(pCtx, CODEC_OSAL_BUF_TYPE_DST) != 0) {
+            ALOGE("%s: Failed to streamoff for output buffer", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        pCtx->videoCtx.bStreamonOutbuf = VIDEO_FALSE;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++)
+        pCtx->videoCtx.pOutbuf[i].bQueued = VIDEO_FALSE;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Wait (Src)
+ */
+static ExynosVideoErrorType MFC_Encoder_Wait_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    struct pollfd poll_events;
+    int poll_state;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    poll_events.fd = pCtx->videoCtx.hDevice;
+    poll_events.events = POLLOUT | POLLERR;
+    poll_events.revents = 0;
+
+    do {
+        poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT);
+        if (poll_state > 0) {
+            if (poll_events.revents & POLLOUT) {
+                break;
+            } else {
+                ALOGE("%s: Poll return error", __FUNCTION__);
+                ret = VIDEO_ERROR_POLL;
+                break;
+            }
+        } else if (poll_state < 0) {
+            ALOGE("%s: Poll state error", __FUNCTION__);
+            ret = VIDEO_ERROR_POLL;
+            break;
+        }
+    } while (poll_state == 0);
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Wait (Dst)
+ */
+static ExynosVideoErrorType MFC_Encoder_Wait_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    struct pollfd poll_events;
+    int poll_state;
+    int bframe_count = 0; // FIXME
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    poll_events.fd = pCtx->videoCtx.hDevice;
+    poll_events.events = POLLIN | POLLERR;
+    poll_events.revents = 0;
+
+    do {
+        poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_ENCODER_POLL_TIMEOUT);
+        if (poll_state > 0) {
+            if (poll_events.revents & POLLIN) {
+                break;
+            } else {
+                ALOGE("%s: Poll return error", __FUNCTION__);
+                ret = VIDEO_ERROR_POLL;
+                break;
+            }
+        } else if (poll_state < 0) {
+            ALOGE("%s: Poll state error", __FUNCTION__);
+            ret = VIDEO_ERROR_POLL;
+            break;
+        } else {
+            bframe_count++; // FIXME
+        }
+    } while (poll_state == 0 && bframe_count < 5); // FIXME
+
+EXIT:
+    return ret;
+}
+
+static ExynosVideoErrorType MFC_Encoder_Register_Inbuf(
+    void             *pHandle,
+    ExynosVideoPlane *pPlanes,
+    int               nPlanes)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i, j;
+
+    if ((pCtx == NULL) ||
+        (pPlanes == NULL) ||
+        (nPlanes != pCtx->videoCtx.nInbufPlanes)) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+        if (pCtx->videoCtx.pInbuf[i].bRegistered == VIDEO_FALSE) {
+            for (j = 0; j < nPlanes; j++) {
+                pCtx->videoCtx.pInbuf[i].planes[j].addr        = pPlanes[j].addr;
+                pCtx->videoCtx.pInbuf[i].planes[j].allocSize   = pPlanes[j].allocSize;
+                pCtx->videoCtx.pInbuf[i].planes[j].fd          = pPlanes[j].fd;
+
+                ALOGV("%s: registered buf[%d][%d]: addr = %p, alloc_sz = %u, fd = %lu",
+                        __FUNCTION__, i, j, pPlanes[j].addr, pPlanes[j].allocSize, pPlanes[j].fd);
+            }
+
+            pCtx->videoCtx.pInbuf[i].bRegistered = VIDEO_TRUE;
+            break;
+        }
+    }
+
+    if (i == pCtx->videoCtx.nInbufs) {
+        ALOGE("%s: can not find non-registered input buffer", __FUNCTION__);
+        ret = VIDEO_ERROR_NOBUFFERS;
+    }
+
+EXIT:
+    return ret;
+}
+
+static ExynosVideoErrorType MFC_Encoder_Register_Outbuf(
+    void             *pHandle,
+    ExynosVideoPlane *pPlanes,
+    int               nPlanes)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i, j;
+
+    if ((pCtx == NULL) ||
+        (pPlanes == NULL) ||
+        (nPlanes != pCtx->videoCtx.nOutbufPlanes)) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+        if (pCtx->videoCtx.pOutbuf[i].bRegistered == VIDEO_FALSE) {
+            for (j = 0; j < nPlanes; j++) {
+                pCtx->videoCtx.pOutbuf[i].planes[j].addr       = pPlanes[j].addr;
+                pCtx->videoCtx.pOutbuf[i].planes[j].allocSize  = pPlanes[j].allocSize;
+                pCtx->videoCtx.pOutbuf[i].planes[j].fd         = pPlanes[j].fd;
+
+                ALOGV("%s: registered buf[%d][%d]: addr = %p, alloc_sz = %d, fd = %lu",
+                      __FUNCTION__, i, j, pPlanes[j].addr, pPlanes[j].allocSize, pPlanes[j].fd);
+            }
+
+            pCtx->videoCtx.pOutbuf[i].bRegistered = VIDEO_TRUE;
+            break;
+        }
+    }
+
+    if (i == pCtx->videoCtx.nOutbufs) {
+        ALOGE("%s: can not find non-registered output buffer", __FUNCTION__);
+        ret = VIDEO_ERROR_NOBUFFERS;
+    }
+
+EXIT:
+    return ret;
+}
+
+static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i, j;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+        for (j = 0; j < pCtx->videoCtx.nInbufPlanes; j++) {
+            pCtx->videoCtx.pInbuf[i].planes[j].addr = NULL;
+            pCtx->videoCtx.pInbuf[i].planes[j].fd   = 0;
+        }
+
+        pCtx->videoCtx.pInbuf[i].bRegistered = VIDEO_FALSE;
+    }
+
+EXIT:
+    return ret;
+}
+
+static ExynosVideoErrorType MFC_Encoder_Clear_RegisteredBuffer_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i, j;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+        for (j = 0; j < pCtx->videoCtx.nOutbufPlanes; j++) {
+            pCtx->videoCtx.pOutbuf[i].planes[j].addr = NULL;
+            pCtx->videoCtx.pOutbuf[i].planes[j].fd   = 0;
+        }
+
+        pCtx->videoCtx.pOutbuf[i].bRegistered = VIDEO_FALSE;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Find (Input)
+ */
+static int MFC_Encoder_Find_Inbuf(
+    void          *pHandle,
+    unsigned char *pBuffer)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    int nIndex = -1, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+        if (pCtx->videoCtx.pInbuf[i].bQueued == VIDEO_FALSE) {
+            if ((pBuffer == NULL) ||
+                (pCtx->videoCtx.pInbuf[i].planes[0].addr == pBuffer)) {
+                nIndex = i;
+                break;
+            }
+        }
+    }
+
+EXIT:
+    return nIndex;
+}
+
+/*
+ * [Encoder Buffer OPS] Find (Output)
+ */
+static int MFC_Encoder_Find_Outbuf(
+    void          *pHandle,
+    unsigned char *pBuffer)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    int nIndex = -1, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+        if (pCtx->videoCtx.pOutbuf[i].bQueued == VIDEO_FALSE) {
+            if ((pBuffer == NULL) ||
+                (pCtx->videoCtx.pOutbuf[i].planes[0].addr == pBuffer)) {
+                nIndex = i;
+                break;
+            }
+        }
+    }
+
+EXIT:
+    return nIndex;
+}
+
+/*
+ * [Encoder Buffer OPS] Enqueue (Input)
+ */
+static ExynosVideoErrorType MFC_Encoder_Enqueue_Inbuf(
+    void          *pHandle,
+    void          *pBuffer[],
+    unsigned int   nDataSize[],
+    int            nPlanes,
+    void          *pPrivate)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    pthread_mutex_t       *pMutex = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int index, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.nInbufPlanes < nPlanes) {
+        ALOGE("%s: Number of max planes : %d, nPlanes : %d", __FUNCTION__,
+                                    pCtx->videoCtx.nInbufPlanes, nPlanes);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_SRC;
+    buf.nPlane  = pCtx->videoCtx.nInbufPlanes;
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pInMutex;
+    pthread_mutex_lock(pMutex);
+
+    index = MFC_Encoder_Find_Inbuf(pCtx, pBuffer[0]);
+    if (index == -1) {
+        pthread_mutex_unlock(pMutex);
+        ALOGW("%s: Matching Buffer index not found", __FUNCTION__);
+        ret = VIDEO_ERROR_NOBUFFERS;
+        goto EXIT;
+    }
+    buf.index = index;
+    ALOGV("%s: index:%d pCtx->videoCtx.pInbuf[buf.index].bQueued:%d, pBuffer[0]:%p",
+           __FUNCTION__, index, pCtx->videoCtx.pInbuf[buf.index].bQueued, pBuffer[0]);
+
+    if (pCtx->videoCtx.bShareInbuf == VIDEO_TRUE) {
+        buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+        for (i = 0; i < buf.nPlane; i++) {
+            if (buf.memory == CODEC_OSAL_MEM_TYPE_USERPTR)
+                buf.planes[i].addr = pBuffer[i];
+            else
+                buf.planes[i].addr = (void *)(unsigned long)pCtx->videoCtx.pInbuf[buf.index].planes[i].fd;
+
+            buf.planes[i].bufferSize    = pCtx->videoCtx.pInbuf[index].planes[i].allocSize;
+            buf.planes[i].dataLen       = nDataSize[i];
+
+            ALOGV("%s: shared inbuf(%d) plane=%d addr=%p len=%d used=%d\n", __FUNCTION__,
+                  index, i,
+                  buf.planes[i].addr,
+                  buf.planes[i].bufferSize,
+                  buf.planes[i].dataLen);
+        }
+    } else {
+        buf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+        for (i = 0; i < nPlanes; i++)
+            buf.planes[i].dataLen = nDataSize[i];
+    }
+
+    if (nDataSize[0] <= 0) {
+        buf.flags = EMPTY_DATA | LAST_FRAME;
+        ALOGD("%s: EMPTY DATA", __FUNCTION__);
+    } else {
+        if ((((OMX_BUFFERHEADERTYPE *)pPrivate)->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
+            buf.flags = LAST_FRAME;
+
+        if (buf.flags & LAST_FRAME)
+            ALOGD("%s: DATA with flags(0x%x)", __FUNCTION__, buf.flags);
+    }
+
+    signed long long sec = (((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp / 1E6);
+    signed long long usec = (((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp) - (sec * 1E6);
+    buf.timestamp.tv_sec = (long)sec;
+    buf.timestamp.tv_usec = (long)usec;
+
+    pCtx->videoCtx.pInbuf[buf.index].pPrivate = pPrivate;
+    pCtx->videoCtx.pInbuf[buf.index].bQueued = VIDEO_TRUE;
+
+    if ((pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_VP8) ||
+        (pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_VP9) ||
+        (pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_AVC) ||
+        (pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_HEVC)) {
+        int     oldFrameRate   = 0;
+        int     curFrameRate   = 0;
+        int64_t curDuration    = 0;
+
+        curDuration = ((int64_t)((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp - pCtx->videoCtx.specificInfo.enc.oldTimeStamp);
+        if ((curDuration > 0) && (pCtx->videoCtx.specificInfo.enc.oldDuration > 0)) {
+            oldFrameRate = (1E6 / pCtx->videoCtx.specificInfo.enc.oldDuration);
+            curFrameRate = (1E6 / curDuration);
+
+            if (((curFrameRate - oldFrameRate) >= FRAME_RATE_CHANGE_THRESH_HOLD) ||
+                ((oldFrameRate - curFrameRate) >= FRAME_RATE_CHANGE_THRESH_HOLD)) {
+                if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_FRAME_RATE, curFrameRate) != 0) {
+                    ALOGE("%s: Failed to SetControl", __FUNCTION__);
+                    pthread_mutex_unlock(pMutex);
+                    ret = VIDEO_ERROR_APIFAIL;
+                    goto EXIT;
+                }
+                pCtx->videoCtx.specificInfo.enc.oldFrameRate = curFrameRate;
+            }
+        }
+
+        if (curDuration > 0)
+            pCtx->videoCtx.specificInfo.enc.oldDuration = curDuration;
+        pCtx->videoCtx.specificInfo.enc.oldTimeStamp = (int64_t)((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp;
+    }
+
+    pthread_mutex_unlock(pMutex);
+
+    if (Codec_OSAL_EnqueueBuf(pCtx, &buf) != 0) {
+        ALOGE("%s: Failed to enqueue input buffer", __FUNCTION__);
+        pthread_mutex_lock(pMutex);
+        pCtx->videoCtx.pInbuf[buf.index].pPrivate = NULL;
+        pCtx->videoCtx.pInbuf[buf.index].bQueued = VIDEO_FALSE;
+        pthread_mutex_unlock(pMutex);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Enqueue (Output)
+ */
+static ExynosVideoErrorType MFC_Encoder_Enqueue_Outbuf(
+    void          *pHandle,
+    void          *pBuffer[],
+    unsigned int   nDataSize[],
+    int            nPlanes,
+    void          *pPrivate)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    pthread_mutex_t       *pMutex = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int i, index;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.nOutbufPlanes < nPlanes) {
+        ALOGE("%s: Number of max planes : %d, nPlanes : %d", __FUNCTION__,
+                                    pCtx->videoCtx.nOutbufPlanes, nPlanes);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_DST;
+    buf.nPlane  = pCtx->videoCtx.nOutbufPlanes;
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pOutMutex;
+    pthread_mutex_lock(pMutex);
+
+    index = MFC_Encoder_Find_Outbuf(pCtx, pBuffer[0]);
+    if (index == -1) {
+        pthread_mutex_unlock(pMutex);
+        ALOGE("%s: Failed to get index", __FUNCTION__);
+        ret = VIDEO_ERROR_NOBUFFERS;
+        goto EXIT;
+    }
+    buf.index = index;
+    ALOGV("%s: index:%d pCtx->videoCtx.pOutbuf[buf.index].bQueued:%d, pBuffer[0]:%p",
+           __FUNCTION__, index, pCtx->videoCtx.pOutbuf[buf.index].bQueued, pBuffer[0]);
+
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_TRUE) {
+        buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+        for (i = 0; i < nPlanes; i++) {
+            if (buf.memory == CODEC_OSAL_MEM_TYPE_USERPTR)
+                buf.planes[i].addr = pBuffer[i];
+            else
+                buf.planes[i].addr = (void *)(unsigned long)pCtx->videoCtx.pOutbuf[index].planes[i].fd;
+
+            buf.planes[i].bufferSize    = pCtx->videoCtx.pOutbuf[index].planes[i].allocSize;
+            buf.planes[i].dataLen       = nDataSize[i];
+
+            ALOGV("%s: shared outbuf(%d) plane=%d addr=%p len=%d used=%d\n", __FUNCTION__,
+                  index, i,
+                  buf.planes[i].addr,
+                  buf.planes[i].bufferSize,
+                  buf.planes[i].dataLen);
+        }
+    } else {
+        buf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+    }
+
+    pCtx->videoCtx.pOutbuf[buf.index].pPrivate = pPrivate;
+    pCtx->videoCtx.pOutbuf[buf.index].bQueued = VIDEO_TRUE;
+    pthread_mutex_unlock(pMutex);
+
+    if (Codec_OSAL_EnqueueBuf(pCtx, &buf) != 0) {
+        ALOGE("%s: Failed to enqueue output buffer", __FUNCTION__);
+        pthread_mutex_lock(pMutex);
+        pCtx->videoCtx.pOutbuf[buf.index].pPrivate = NULL;
+        pCtx->videoCtx.pOutbuf[buf.index].bQueued = VIDEO_FALSE;
+        pthread_mutex_unlock(pMutex);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Enqueue All (Output)
+ */
+static ExynosVideoErrorType MFC_Encoder_Enqueue_All_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+
+    void           *pBuffer[VIDEO_BUFFER_MAX_PLANES]  = {NULL, };
+    unsigned int    nDataSize[VIDEO_BUFFER_MAX_PLANES] = {0, };
+
+    int i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+        ret = MFC_Encoder_Enqueue_Outbuf(pCtx, pBuffer, nDataSize, 1, NULL);
+        if (ret != VIDEO_ERROR_NONE)
+            goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] Dequeue (Input)
+ */
+static ExynosVideoBuffer *MFC_Encoder_Dequeue_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx     = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoBuffer     *pInbuf   = NULL;
+    pthread_mutex_t       *pMutex   = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonInbuf == VIDEO_FALSE) {
+        pInbuf = NULL;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+
+    buf.type    = CODEC_OSAL_BUF_TYPE_SRC;
+    buf.nPlane  = pCtx->videoCtx.nInbufPlanes;
+    if (pCtx->videoCtx.bShareInbuf == VIDEO_TRUE)
+        buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    else
+        buf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+
+    if (Codec_OSAL_DequeueBuf(pCtx, &buf) != 0) {
+        pInbuf = NULL;
+        goto EXIT;
+    }
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pInMutex;
+    pthread_mutex_lock(pMutex);
+
+    pInbuf = &pCtx->videoCtx.pInbuf[buf.index];
+    if (pInbuf->bQueued == VIDEO_FALSE) {
+        pInbuf = NULL;
+        pthread_mutex_unlock(pMutex);
+        goto EXIT;
+    }
+
+    pCtx->videoCtx.pInbuf[buf.index].bQueued = VIDEO_FALSE;
+    pthread_mutex_unlock(pMutex);
+
+EXIT:
+    return pInbuf;
+}
+
+/*
+ * [Encoder Buffer OPS] Dequeue (Output)
+ */
+static ExynosVideoBuffer *MFC_Encoder_Dequeue_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx    = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoBuffer     *pOutbuf = NULL;
+    pthread_mutex_t       *pMutex  = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int ret = 0;
+    int i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonOutbuf == VIDEO_FALSE) {
+        pOutbuf = NULL;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_DST;
+    buf.nPlane  = pCtx->videoCtx.nOutbufPlanes;
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_TRUE)
+        buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    else
+        buf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+
+    /* returning DQBUF_EIO means MFC H/W status is invalid */
+    ret = Codec_OSAL_DequeueBuf(pCtx, &buf);
+    if (ret != 0) {
+        if (errno == EIO)
+            pOutbuf = (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO;
+        else
+            pOutbuf = NULL;
+        goto EXIT;
+    }
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pOutMutex;
+    pthread_mutex_lock(pMutex);
+
+    pOutbuf = &pCtx->videoCtx.pOutbuf[buf.index];
+    if (pOutbuf->bQueued == VIDEO_FALSE) {
+        pOutbuf = NULL;
+        pthread_mutex_unlock(pMutex);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufPlanes; i++)
+        pOutbuf->planes[i].dataSize = buf.planes[i].dataLen;
+
+    pOutbuf->frameType  = buf.frameType;
+
+    {
+        int64_t sec  = (int64_t)(buf.timestamp.tv_sec * 1E6);
+        int64_t usec = (int64_t)buf.timestamp.tv_usec;
+        pOutbuf->timestamp = sec + usec;
+    }
+
+    pOutbuf->bQueued    = VIDEO_FALSE;
+    pthread_mutex_unlock(pMutex);
+
+EXIT:
+    return pOutbuf;
+}
+
+static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nInbufs; i++)
+        pCtx->videoCtx.pInbuf[i].bQueued = VIDEO_FALSE;
+
+EXIT:
+    return ret;
+}
+
+static ExynosVideoErrorType MFC_Encoder_Clear_Queued_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    int i = 0;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++)
+        pCtx->videoCtx.pOutbuf[i].bQueued = VIDEO_FALSE;
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] FindIndex (Input)
+ */
+static int MFC_Encoder_FindEmpty_Inbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    int nIndex = -1, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nInbufs; i++) {
+        if (pCtx->videoCtx.pInbuf[i].bQueued == VIDEO_FALSE) {
+            nIndex = i;
+            break;
+        }
+    }
+
+EXIT:
+    return nIndex;
+}
+
+/*
+ * [Encoder Buffer OPS] FindIndex (Output)
+ */
+static int MFC_Encoder_FindEmpty_Outbuf(void *pHandle)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    int nIndex = -1, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pCtx->videoCtx.nOutbufs; i++) {
+        if (pCtx->videoCtx.pOutbuf[i].bQueued == VIDEO_FALSE) {
+            nIndex = i;
+            break;
+        }
+    }
+
+EXIT:
+    return nIndex;
+}
+
+/*
+ * [Encoder Buffer OPS] ExtensionEnqueue (Input)
+ */
+static ExynosVideoErrorType MFC_Encoder_ExtensionEnqueue_Inbuf(
+    void          *pHandle,
+    void          *pBuffer[],
+    unsigned long  pFd[],
+    unsigned int   nAllocLen[],
+    unsigned int   nDataSize[],
+    int            nPlanes,
+    void          *pPrivate)
+{
+    CodecOSALVideoContext *pCtx = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret  = VIDEO_ERROR_NONE;
+    pthread_mutex_t       *pMutex = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int index, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.nInbufPlanes < nPlanes) {
+        ALOGE("%s: Number of max planes : %d, nPlanes : %d", __FUNCTION__,
+                                    pCtx->videoCtx.nInbufPlanes, nPlanes);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_SRC;
+    buf.nPlane  = pCtx->videoCtx.nInbufPlanes;
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pInMutex;
+    pthread_mutex_lock(pMutex);
+
+    index = MFC_Encoder_FindEmpty_Inbuf(pCtx);
+    if (index == -1) {
+        pthread_mutex_unlock(pMutex);
+        ALOGE("%s: Failed to get index", __FUNCTION__);
+        ret = VIDEO_ERROR_NOBUFFERS;
+        goto EXIT;
+    }
+    buf.index = index;
+    ALOGV("%s: index:%d pCtx->videoCtx.pInbuf[buf.index].bQueued:%d, pFd[0]:%lu",
+           __FUNCTION__, index, pCtx->videoCtx.pInbuf[buf.index].bQueued, pFd[0]);
+
+    buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    for (i = 0; i < nPlanes; i++) {
+        if (buf.memory == CODEC_OSAL_MEM_TYPE_USERPTR)
+            buf.planes[i].addr = pBuffer[i];
+        else
+            buf.planes[i].addr = (void *)pFd[i];
+
+        buf.planes[i].bufferSize    = nAllocLen[i];
+        buf.planes[i].dataLen       = nDataSize[i];
+
+        /* Temporary storage for Dequeue */
+        pCtx->videoCtx.pInbuf[buf.index].planes[i].addr         = pBuffer[i];
+        pCtx->videoCtx.pInbuf[buf.index].planes[i].fd           = pFd[i];
+        pCtx->videoCtx.pInbuf[buf.index].planes[i].allocSize    = nAllocLen[i];
+
+        ALOGV("%s: shared inbuf(%d) plane = %d addr = %p len = %d used = %d\n", __FUNCTION__,
+              index, i,
+              buf.planes[i].addr,
+              buf.planes[i].bufferSize,
+              buf.planes[i].dataLen);
+    }
+
+    if (nDataSize[0] <= 0) {
+        buf.flags = EMPTY_DATA | LAST_FRAME;
+        ALOGD("%s: EMPTY DATA", __FUNCTION__);
+    } else {
+        if ((((OMX_BUFFERHEADERTYPE *)pPrivate)->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
+            buf.flags = LAST_FRAME;
+
+        if (buf.flags & LAST_FRAME)
+            ALOGD("%s: DATA with flags(0x%x)", __FUNCTION__, buf.flags);
+    }
+
+    signed long long sec = (((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp / 1E6);
+    signed long long usec = (((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp) - (sec * 1E6);
+    buf.timestamp.tv_sec = (long)sec;
+    buf.timestamp.tv_usec = (long)usec;
+
+    pCtx->videoCtx.pInbuf[buf.index].pPrivate = pPrivate;
+    pCtx->videoCtx.pInbuf[buf.index].bQueued = VIDEO_TRUE;
+
+    if (pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_VP8) {
+        int     oldFrameRate   = 0;
+        int     curFrameRate   = 0;
+        int64_t curDuration    = 0;
+
+        curDuration = ((int64_t)((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp - pCtx->videoCtx.specificInfo.enc.oldTimeStamp);
+        if ((curDuration > 0) && (pCtx->videoCtx.specificInfo.enc.oldDuration > 0)) {
+            oldFrameRate = (1E6 / pCtx->videoCtx.specificInfo.enc.oldDuration);
+            curFrameRate = (1E6 / curDuration);
+
+            if (((curFrameRate - oldFrameRate) >= FRAME_RATE_CHANGE_THRESH_HOLD) ||
+                ((oldFrameRate - curFrameRate) >= FRAME_RATE_CHANGE_THRESH_HOLD)) {
+                if (Codec_OSAL_SetControl(pCtx, CODEC_OSAL_CID_ENC_FRAME_RATE, curFrameRate) != 0) {
+                    ALOGE("%s: Failed to SetControl", __FUNCTION__);
+                    pthread_mutex_unlock(pMutex);
+                    ret = VIDEO_ERROR_APIFAIL;
+                    goto EXIT;
+                }
+                pCtx->videoCtx.specificInfo.enc.oldFrameRate = curFrameRate;
+            }
+        }
+
+        if (curDuration > 0)
+            pCtx->videoCtx.specificInfo.enc.oldDuration = curDuration;
+        pCtx->videoCtx.specificInfo.enc.oldTimeStamp = (int64_t)((OMX_BUFFERHEADERTYPE *)pPrivate)->nTimeStamp;
+    }
+
+    pthread_mutex_unlock(pMutex);
+
+    if (Codec_OSAL_EnqueueBuf(pCtx, &buf) != 0) {
+        ALOGE("%s: Failed to enqueue input buffer", __FUNCTION__);
+        pthread_mutex_lock(pMutex);
+        pCtx->videoCtx.pInbuf[buf.index].pPrivate = NULL;
+        pCtx->videoCtx.pInbuf[buf.index].bQueued = VIDEO_FALSE;
+        pthread_mutex_unlock(pMutex);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] ExtensionDequeue (Input)
+ */
+static ExynosVideoErrorType MFC_Encoder_ExtensionDequeue_Inbuf(
+    void              *pHandle,
+    ExynosVideoBuffer *pVideoBuffer)
+{
+    CodecOSALVideoContext *pCtx     = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret      = VIDEO_ERROR_NONE;
+    pthread_mutex_t       *pMutex   = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonInbuf == VIDEO_FALSE) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_SRC;
+    buf.nPlane  = pCtx->videoCtx.nInbufPlanes;
+    buf.memory  = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+
+    if (Codec_OSAL_DequeueBuf(pCtx, &buf) != 0) {
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pInMutex;
+    pthread_mutex_lock(pMutex);
+
+    if (pCtx->videoCtx.pInbuf[buf.index].bQueued == VIDEO_TRUE)
+        memcpy(pVideoBuffer, &pCtx->videoCtx.pInbuf[buf.index], sizeof(ExynosVideoBuffer));
+    else
+        ret = VIDEO_ERROR_NOBUFFERS;
+    memset(&pCtx->videoCtx.pInbuf[buf.index], 0, sizeof(ExynosVideoBuffer));
+
+    pCtx->videoCtx.pInbuf[buf.index].bQueued = VIDEO_FALSE;
+    pthread_mutex_unlock(pMutex);
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] ExtensionEnqueue (Output)
+ */
+static ExynosVideoErrorType MFC_Encoder_ExtensionEnqueue_Outbuf(
+    void          *pHandle,
+    void          *pBuffer[],
+    unsigned long  pFd[],
+    unsigned int   nAllocLen[],
+    unsigned int   nDataSize[],
+    int            nPlanes,
+    void          *pPrivate)
+{
+    CodecOSALVideoContext *pCtx   = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret    = VIDEO_ERROR_NONE;
+    pthread_mutex_t       *pMutex = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int index, i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.nOutbufPlanes < nPlanes) {
+        ALOGE("%s: Number of max planes : %d, nPlanes : %d", __FUNCTION__,
+                                    pCtx->videoCtx.nOutbufPlanes, nPlanes);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_DST;
+    buf.nPlane  = pCtx->videoCtx.nOutbufPlanes;
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pOutMutex;
+    pthread_mutex_lock(pMutex);
+
+    index = MFC_Encoder_FindEmpty_Outbuf(pCtx);
+    if (index == -1) {
+        pthread_mutex_unlock(pMutex);
+        ALOGE("%s: Failed to get index", __FUNCTION__);
+        ret = VIDEO_ERROR_NOBUFFERS;
+        goto EXIT;
+    }
+    buf.index = index;
+    ALOGV("%s: index:%d pCtx->videoCtx.pOutbuf[buf.index].bQueued:%d, pFd[0]:%lu",
+           __FUNCTION__, index, pCtx->videoCtx.pOutbuf[buf.index].bQueued, pFd[0]);
+
+    buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    for (i = 0; i < nPlanes; i++) {
+        if (buf.memory == CODEC_OSAL_MEM_TYPE_USERPTR)
+            buf.planes[i].addr = pBuffer[i];
+        else
+            buf.planes[i].addr = (void *)pFd[i];
+
+        buf.planes[i].bufferSize    = nAllocLen[i];
+        buf.planes[i].dataLen       = nDataSize[i];
+
+        /* Temporary storage for Dequeue */
+        pCtx->videoCtx.pOutbuf[buf.index].planes[i].addr        = pBuffer[i];
+        pCtx->videoCtx.pOutbuf[buf.index].planes[i].fd          = pFd[i];
+        pCtx->videoCtx.pOutbuf[buf.index].planes[i].allocSize   = nAllocLen[i];
+
+        ALOGV("%s: shared outbuf(%d) plane = %d addr = %p len = %d used = %d\n", __FUNCTION__,
+              index, i,
+              buf.planes[i].addr,
+              buf.planes[i].bufferSize,
+              buf.planes[i].dataLen);
+    }
+
+    pCtx->videoCtx.pOutbuf[buf.index].pPrivate = pPrivate;
+    pCtx->videoCtx.pOutbuf[buf.index].bQueued = VIDEO_TRUE;
+    pthread_mutex_unlock(pMutex);
+
+    if (Codec_OSAL_EnqueueBuf(pCtx, &buf) != 0) {
+        ALOGE("%s: Failed to enqueue output buffer", __FUNCTION__);
+        pthread_mutex_lock(pMutex);
+        pCtx->videoCtx.pOutbuf[buf.index].pPrivate = NULL;
+        pCtx->videoCtx.pOutbuf[buf.index].bQueued = VIDEO_FALSE;
+        pthread_mutex_unlock(pMutex);
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder Buffer OPS] ExtensionDequeue (Output)
+ */
+static ExynosVideoErrorType MFC_Encoder_ExtensionDequeue_Outbuf(
+    void              *pHandle,
+    ExynosVideoBuffer *pVideoBuffer)
+{
+    CodecOSALVideoContext *pCtx    = (CodecOSALVideoContext *)pHandle;
+    ExynosVideoErrorType   ret     = VIDEO_ERROR_NONE;
+    ExynosVideoBuffer     *pOutbuf = NULL;
+    pthread_mutex_t       *pMutex  = NULL;
+
+    CodecOSAL_Buffer buf;
+
+    int i;
+
+    if (pCtx == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    if (pCtx->videoCtx.bStreamonOutbuf == VIDEO_FALSE) {
+        pOutbuf = NULL;
+        ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    memset(&buf, 0, sizeof(buf));
+    buf.type    = CODEC_OSAL_BUF_TYPE_DST;
+    buf.nPlane  = pCtx->videoCtx.nOutbufPlanes;
+    if (pCtx->videoCtx.bShareOutbuf == VIDEO_TRUE)
+        buf.memory = Codec_OSAL_VideoMemoryToSystemMemory(pCtx->videoCtx.instInfo.nMemoryType);
+    else
+        buf.memory = CODEC_OSAL_MEM_TYPE_MMAP;
+
+    /* returning DQBUF_EIO means MFC H/W status is invalid */
+    if (Codec_OSAL_DequeueBuf(pCtx, &buf) != 0) {
+        if (errno == EIO)
+            ret = VIDEO_ERROR_DQBUF_EIO;
+        else
+            ret = VIDEO_ERROR_APIFAIL;
+        goto EXIT;
+    }
+
+    pMutex = (pthread_mutex_t*)pCtx->videoCtx.pOutMutex;
+    pthread_mutex_lock(pMutex);
+
+    pOutbuf = &pCtx->videoCtx.pOutbuf[buf.index];
+    for (i = 0; i < pCtx->videoCtx.nOutbufPlanes; i++)
+        pOutbuf->planes[i].dataSize = buf.planes[i].dataLen;
+
+    pOutbuf->frameType = buf.frameType;
+
+    {
+        int64_t sec  = (int64_t)(buf.timestamp.tv_sec * 1E6);
+        int64_t usec = (int64_t)buf.timestamp.tv_usec;
+        pOutbuf->timestamp = sec + usec;
+    }
+
+    if (pCtx->videoCtx.pOutbuf[buf.index].bQueued == VIDEO_TRUE)
+        memcpy(pVideoBuffer, pOutbuf, sizeof(ExynosVideoBuffer));
+    else
+        ret = VIDEO_ERROR_NOBUFFERS;
+    memset(pOutbuf, 0, sizeof(ExynosVideoBuffer));
+
+    pCtx->videoCtx.pOutbuf[buf.index].bQueued = VIDEO_FALSE;
+    pthread_mutex_unlock(pMutex);
+
+EXIT:
+    return ret;
+}
+
+/*
+ * [Encoder OPS] Common
+ */
+static ExynosVideoEncOps defEncOps = {
+    .nSize                      = 0,
+    .Init                       = MFC_Encoder_Init,
+    .Finalize                   = MFC_Encoder_Finalize,
+    .Set_EncParam               = MFC_Encoder_Set_EncParam,
+    .Set_FrameType              = MFC_Encoder_Set_FrameType,
+    .Set_FrameRate              = MFC_Encoder_Set_FrameRate,
+    .Set_BitRate                = MFC_Encoder_Set_BitRate,
+    .Set_QpRange                = MFC_Encoder_Set_QuantizationRange,
+    .Set_FrameSkip              = MFC_Encoder_Set_FrameSkip,
+    .Set_IDRPeriod              = MFC_Encoder_Set_IDRPeriod,
+    .Set_SliceMode              = MFC_Encoder_Set_SliceMode,
+    .Set_FrameTag               = MFC_Encoder_Set_FrameTag,
+    .Get_FrameTag               = MFC_Encoder_Get_FrameTag,
+    .Enable_PrependSpsPpsToIdr  = MFC_Encoder_Enable_PrependSpsPpsToIdr,
+    .Set_QosRatio               = MFC_Encoder_Set_QosRatio,
+    .Set_LayerChange            = MFC_Encoder_Set_LayerChange,
+    .Set_DynamicQpControl       = MFC_Encoder_Set_DynamicQpControl,
+    .Set_MarkLTRFrame           = MFC_Encoder_Set_MarkLTRFrame,
+    .Set_UsedLTRFrame           = MFC_Encoder_Set_UsedLTRFrame,
+    .Set_BasePID                = MFC_Encoder_Set_BasePID,
+    .Set_RoiInfo                = MFC_Encoder_Set_RoiInfo,
+    .Enable_WeightedPrediction  = MFC_Encoder_Enable_WeightedPrediction,
+    .Set_YSumData               = MFC_Encoder_Set_YSumData,
+    .Set_IFrameRatio            = MFC_Encoder_Set_IFrameRatio,
+    .Set_ColorAspects           = MFC_Encoder_Set_ColorAspects,
+};
+
+/*
+ * [Encoder Buffer OPS] Input
+ */
+static ExynosVideoEncBufferOps defInbufOps = {
+    .nSize                  = 0,
+    .Enable_Cacheable       = MFC_Encoder_Enable_Cacheable_Inbuf,
+    .Set_Shareable          = MFC_Encoder_Set_Shareable_Inbuf,
+    .Get_Buffer             = NULL,
+    .Set_Geometry           = MFC_Encoder_Set_Geometry_Inbuf,
+    .Get_Geometry           = MFC_Encoder_Get_Geometry_Inbuf,
+    .Setup                  = MFC_Encoder_Setup_Inbuf,
+    .Run                    = MFC_Encoder_Run_Inbuf,
+    .Stop                   = MFC_Encoder_Stop_Inbuf,
+    .Enqueue                = MFC_Encoder_Enqueue_Inbuf,
+    .Enqueue_All            = NULL,
+    .Dequeue                = MFC_Encoder_Dequeue_Inbuf,
+    .Register               = MFC_Encoder_Register_Inbuf,
+    .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Inbuf,
+    .Clear_Queue            = MFC_Encoder_Clear_Queued_Inbuf,
+    .ExtensionEnqueue       = MFC_Encoder_ExtensionEnqueue_Inbuf,
+    .ExtensionDequeue       = MFC_Encoder_ExtensionDequeue_Inbuf,
+};
+
+/*
+ * [Encoder Buffer OPS] Output
+ */
+static ExynosVideoEncBufferOps defOutbufOps = {
+    .nSize                  = 0,
+    .Enable_Cacheable       = MFC_Encoder_Enable_Cacheable_Outbuf,
+    .Set_Shareable          = MFC_Encoder_Set_Shareable_Outbuf,
+    .Get_Buffer             = MFC_Encoder_Get_Buffer_Outbuf,
+    .Set_Geometry           = MFC_Encoder_Set_Geometry_Outbuf,
+    .Get_Geometry           = MFC_Encoder_Get_Geometry_Outbuf,
+    .Setup                  = MFC_Encoder_Setup_Outbuf,
+    .Run                    = MFC_Encoder_Run_Outbuf,
+    .Stop                   = MFC_Encoder_Stop_Outbuf,
+    .Enqueue                = MFC_Encoder_Enqueue_Outbuf,
+    .Enqueue_All            = NULL,
+    .Dequeue                = MFC_Encoder_Dequeue_Outbuf,
+    .Register               = MFC_Encoder_Register_Outbuf,
+    .Clear_RegisteredBuffer = MFC_Encoder_Clear_RegisteredBuffer_Outbuf,
+    .Clear_Queue            = MFC_Encoder_Clear_Queued_Outbuf,
+    .ExtensionEnqueue       = MFC_Encoder_ExtensionEnqueue_Outbuf,
+    .ExtensionDequeue       = MFC_Encoder_ExtensionDequeue_Outbuf,
+};
+
+ExynosVideoErrorType MFC_Exynos_Video_GetInstInfo_Encoder(
+    ExynosVideoInstInfo *pVideoInstInfo)
+{
+    CodecOSALVideoContext   videoCtx;
+    ExynosVideoErrorType    ret = VIDEO_ERROR_NONE;
+
+    int codecRet = -1;
+    int mode = 0, version = 0;
+
+    if (pVideoInstInfo == NULL) {
+        ALOGE("%s: invalid parameter", __FUNCTION__);
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    memset(&videoCtx, 0, sizeof(videoCtx));
+
+#ifdef USE_HEVC_HWIP
+    if (pVideoInstInfo->eCodecType == VIDEO_CODING_HEVC)
+        codecRet = Codec_OSAL_DevOpen(VIDEO_HEVC_ENCODER_NAME, O_RDWR, &videoCtx);
+    else
+#endif
+        if (pVideoInstInfo->bOTFMode == VIDEO_TRUE)
+            codecRet = Codec_OSAL_DevOpen(VIDEO_MFC_OTF_ENCODER_NAME, O_RDWR, &videoCtx);
+        else
+            codecRet = Codec_OSAL_DevOpen(VIDEO_MFC_ENCODER_NAME, O_RDWR, &videoCtx);
+
+    if (codecRet < 0) {
+        ALOGE("%s: Failed to open decoder device", __FUNCTION__);
+        ret = VIDEO_ERROR_OPENFAIL;
+        goto EXIT;
+    }
+
+    if (Codec_OSAL_GetControl(&videoCtx, CODEC_OSAL_CID_VIDEO_GET_VERSION_INFO, &version) != 0) {
+        ALOGW("%s: MFC version information is not available", __FUNCTION__);
+#ifdef USE_HEVC_HWIP
+        if (pVideoInstInfo->eCodecType == VIDEO_CODING_HEVC)
+            pVideoInstInfo->HwVersion = (int)HEVC_10;
+        else
+#endif
+            pVideoInstInfo->HwVersion = (int)MFC_65;
+    } else {
+        pVideoInstInfo->HwVersion = version;
+    }
+
+    if (Codec_OSAL_GetControl(&videoCtx, CODEC_OSAL_CID_VIDEO_GET_EXT_INFO, &mode) != 0) {
+        memset(&(pVideoInstInfo->supportInfo.enc), 0, sizeof(pVideoInstInfo->supportInfo.enc));
+        goto EXIT;
+    }
+
+    pVideoInstInfo->supportInfo.enc.bColorAspectsSupport = (mode & (0x1 << 9))? VIDEO_TRUE:VIDEO_FALSE;
+    pVideoInstInfo->supportInfo.enc.bIFrameRatioSupport  = (mode & (0x1 << 8))? VIDEO_TRUE:VIDEO_FALSE;
+    pVideoInstInfo->supportInfo.enc.bPVCSupport          = (mode & (0x1 << 7))? VIDEO_TRUE:VIDEO_FALSE;
+    pVideoInstInfo->supportInfo.enc.bFixedSliceSupport   = (mode & (0x1 << 6))? VIDEO_TRUE:VIDEO_FALSE;
+    pVideoInstInfo->supportInfo.enc.bQpRangePBSupport    = (mode & (0x1 << 5))? VIDEO_TRUE:VIDEO_FALSE;
+    pVideoInstInfo->supportInfo.enc.bRoiInfoSupport      = (mode & (0x1 << 4))? VIDEO_TRUE:VIDEO_FALSE;
+    pVideoInstInfo->supportInfo.enc.bSkypeSupport        = (mode & (0x1 << 3))? VIDEO_TRUE:VIDEO_FALSE;
+    pVideoInstInfo->supportInfo.enc.bTemporalSvcSupport  = (mode & (0x1 << 2))? VIDEO_TRUE:VIDEO_FALSE;
+    if (mode & (0x1 << 1)) {
+        if (Codec_OSAL_GetControl(&videoCtx, CODEC_OSAL_CID_ENC_EXT_BUFFER_SIZE, &(pVideoInstInfo->supportInfo.enc.nSpareSize)) != 0) {
+            ALOGE("%s: Failed to GetControl(CODEC_OSAL_CID_ENC_EXT_BUFFER_SIZE)", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+    }
+
+    pVideoInstInfo->SwVersion = 0;
+    if (pVideoInstInfo->supportInfo.enc.bSkypeSupport == VIDEO_TRUE) {
+        int swVersion = 0;
+
+        if (Codec_OSAL_GetControl(&videoCtx, CODEC_OSAL_CID_VIDEO_GET_DRIVER_VERSION, &swVersion) != 0) {
+            ALOGE("%s: Failed to GetControl(CODEC_OSAL_CID_VIDEO_GET_DRIVER_VERSION)", __FUNCTION__);
+            ret = VIDEO_ERROR_APIFAIL;
+            goto EXIT;
+        }
+
+        pVideoInstInfo->SwVersion = (unsigned int)swVersion;
+    }
+
+    __Set_SupportFormat(pVideoInstInfo);
+
+EXIT:
+    Codec_OSAL_DevClose(&videoCtx);
+
+    return ret;
+}
+
+ExynosVideoErrorType MFC_Exynos_Video_Register_Encoder(
+    ExynosVideoEncOps       *pEncOps,
+    ExynosVideoEncBufferOps *pInbufOps,
+    ExynosVideoEncBufferOps *pOutbufOps)
+{
+    ExynosVideoErrorType ret = VIDEO_ERROR_NONE;
+
+    if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        ret = VIDEO_ERROR_BADPARAM;
+        goto EXIT;
+    }
+
+    defEncOps.nSize = sizeof(defEncOps);
+    defInbufOps.nSize = sizeof(defInbufOps);
+    defOutbufOps.nSize = sizeof(defOutbufOps);
+
+    memcpy((char *)pEncOps + sizeof(pEncOps->nSize), (char *)&defEncOps + sizeof(defEncOps.nSize),
+            pEncOps->nSize - sizeof(pEncOps->nSize));
+
+    memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize),
+            pInbufOps->nSize - sizeof(pInbufOps->nSize));
+
+    memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize),
+            pOutbufOps->nSize - sizeof(pOutbufOps->nSize));
+
+EXIT:
+    return ret;
+}
diff --git a/exynos/libvideocodec/include/ExynosVideoApi.h b/exynos/libvideocodec/include/ExynosVideoApi.h
new file mode 100755 (executable)
index 0000000..39e7c2d
--- /dev/null
@@ -0,0 +1,727 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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 _EXYNOS_VIDEO_API_H_
+#define _EXYNOS_VIDEO_API_H_
+
+#define VIDEO_BUFFER_MAX_PLANES 3
+#define VIDEO_BUFFER_MAX_NUM    32
+
+#define LAST_FRAME     0x80000000
+#define EMPTY_DATA     0x40000000
+#define CSD_FRAME      0x20000000
+
+/* Temporal SVC */
+#define VIDEO_MIN_TEMPORAL_LAYERS 1
+#define VIDEO_MAX_TEMPORAL_LAYERS 7
+
+// Porting exynos 9110, TEMP
+// (2018-05-25) Please, check if these definitions are required or not.
+// (2018-05-28) Only the definition of int64_t is required.
+//typedef unsigned long long int uint64_t;
+typedef long long int int64_t;
+
+typedef enum _ExynosVideoBoolType {
+    VIDEO_FALSE = 0,
+    VIDEO_TRUE  = 1,
+} ExynosVideoBoolType;
+
+typedef enum _ExynosVideoMemoryType {
+    VIDEO_MEMORY_DMABUF     = 0,
+    VIDEO_MEMORY_USERPTR    = 1,
+    VIDEO_MEMORY_MMAP       = 2,
+} ExynosVideoMemoryType;
+
+typedef enum _ExynosVideoErrorType {
+    VIDEO_ERROR_NONE            =  1,
+    VIDEO_ERROR_BADPARAM        = -1,
+    VIDEO_ERROR_OPENFAIL        = -2,
+    VIDEO_ERROR_NOMEM           = -3,
+    VIDEO_ERROR_APIFAIL         = -4,
+    VIDEO_ERROR_MAPFAIL         = -5,
+    VIDEO_ERROR_NOBUFFERS       = -6,
+    VIDEO_ERROR_POLL            = -7,
+    VIDEO_ERROR_DQBUF_EIO       = -8,
+    VIDEO_ERROR_NOSUPPORT       = -9,
+    VIDEO_ERROR_HEADERINFO      = -10,
+    VIDEO_ERROR_WRONGBUFFERSIZE = -11,
+} ExynosVideoErrorType;
+
+typedef enum _ExynosVideoCodingType {
+    VIDEO_CODING_UNKNOWN = 0,
+    VIDEO_CODING_MPEG2,
+    VIDEO_CODING_H263,
+    VIDEO_CODING_MPEG4,
+    VIDEO_CODING_VC1,
+    VIDEO_CODING_VC1_RCV,
+    VIDEO_CODING_AVC,
+    VIDEO_CODING_MVC,
+    VIDEO_CODING_VP8,
+    VIDEO_CODING_HEVC,
+    VIDEO_CODING_VP9,
+    VIDEO_CODING_XVID,
+    VIDEO_CODING_FIMV1,
+    VIDEO_CODING_FIMV2,
+    VIDEO_CODING_FIMV3,
+    VIDEO_CODING_FIMV4,
+    VIDEO_CODING_RESERVED,
+} ExynosVideoCodingType;
+
+typedef enum _ExynosVideoColorFormatType {
+    VIDEO_COLORFORMAT_UNKNOWN = 0,
+    VIDEO_COLORFORMAT_NV12,
+    VIDEO_COLORFORMAT_NV12_S10B,
+    VIDEO_COLORFORMAT_NV12M,
+    VIDEO_COLORFORMAT_NV12M_S10B,
+    VIDEO_COLORFORMAT_NV12M_P010,
+    VIDEO_COLORFORMAT_NV21M,
+    VIDEO_COLORFORMAT_NV21M_S10B,
+    VIDEO_COLORFORMAT_NV21M_P010,
+    VIDEO_COLORFORMAT_NV12_TILED,
+    VIDEO_COLORFORMAT_NV12M_TILED,
+    VIDEO_COLORFORMAT_I420,
+    VIDEO_COLORFORMAT_I420M,
+    VIDEO_COLORFORMAT_YV12M,
+    VIDEO_COLORFORMAT_ARGB8888,
+    VIDEO_COLORFORMAT_BGRA8888,
+    VIDEO_COLORFORMAT_RGBA8888,
+    VIDEO_COLORFORMAT_MAX,
+} ExynosVideoColorFormatType;
+
+typedef enum _ExynosVideoFrameType {
+    VIDEO_FRAME_NOT_CODED           = 0,
+    VIDEO_FRAME_I                   = 0x1 << 0,
+    VIDEO_FRAME_P                   = 0x1 << 1,
+    VIDEO_FRAME_B                   = 0x1 << 2,
+    VIDEO_FRAME_SKIPPED             = 0x1 << 3,
+    VIDEO_FRAME_CORRUPT             = 0x1 << 4,
+    VIDEO_FRAME_OTHERS              = 0x1 << 5,
+    VIDEO_FRAME_WITH_HDR_INFO       = 0x1 << 6,
+    VIDEO_FRAME_WITH_BLACK_BAR      = 0x1 << 7,
+} ExynosVideoFrameType;
+
+typedef enum _ExynosVideoFrameStatusType {
+    VIDEO_FRAME_STATUS_UNKNOWN = 0,
+    VIDEO_FRAME_STATUS_DECODING_ONLY,
+    VIDEO_FRAME_STATUS_DISPLAY_DECODING,
+    VIDEO_FRAME_STATUS_DISPLAY_ONLY,
+    VIDEO_FRAME_STATUS_DECODING_FINISHED,
+    VIDEO_FRAME_STATUS_CHANGE_RESOL,
+    VIDEO_FRAME_STATUS_ENABLED_S3D,
+    VIDEO_FRAME_STATUS_LAST_FRAME,
+} ExynosVideoFrameStatusType;
+
+typedef enum _ExynosVideoFrameSkipMode {
+    VIDEO_FRAME_SKIP_DISABLED = 0,
+    VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT,
+    VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,
+} ExynosVideoFrameSkipMode;
+
+typedef enum _ExynosVideoMFCVersion {
+    MFC_ERROR   = 0,
+    MFC_51      = 0x51,
+    MFC_61      = 0x61,
+    MFC_65      = 0x65,
+    MFC_72      = 0x72,
+    MFC_723     = 0x723,
+    MFC_77      = 0x77,
+    MFC_78      = 0x78,
+    MFC_78D     = 0x78D,
+    MFC_80      = 0x80,
+    MFC_90      = 0x90,
+    MFC_92      = 0x92,
+    MFC_100     = 0xA0,
+    MFC_101     = 0xA01,
+    MFC_1010    = 0xA0A0,
+    MFC_1011    = 0xA0B0,
+    MFC_1020    = 0xA140,
+    MFC_110     = 0x1100,
+    MFC_1120    = 0x1120,
+    MFC_120     = 0x1200,
+    MFC_1220    = 0x1220,
+    MFC_1021    = 0x1021,
+} ExynosVideoMFCVersion;
+
+typedef enum _ExynosVideoHEVCVersion {
+    HEVC_ERROR   = 0,
+    HEVC_10      = 0x10,
+} ExynosVideoHEVCVersion;
+
+typedef enum _ExynosVideoSecurityType {
+    VIDEO_NORMAL = 0,
+    VIDEO_SECURE = 1,
+} ExynosVideoSecurityType;
+
+typedef enum _ExynosFilledDataType {
+    DATA_8BIT           = 0x00,
+    DATA_10BIT          = 0x01,
+    DATA_8BIT_WITH_2BIT = 0x11,
+} ExynosFilledDataType;
+
+typedef enum _ExynosHdrInfoType {
+    HDR_INFO_NO_CHANGES             = 0,
+    HDR_INFO_LIGHT                  = 0x1 << 0,  /* SEI */
+    HDR_INFO_LUMINANCE              = 0x1 << 1,  /* SEI, Luminance, Display primariy 0, 1, 2, White point */
+    HDR_INFO_MATRIX_COEFF_ONLY      = 0x1 << 2,  /* SPS */
+    HDR_INFO_COLOR_ASPECTS          = 0x1 << 3,  /* SPS, MaxtixCoeff + Primaries + Transfer */
+    HDR_INFO_RANGE                  = 0x1 << 4,  /* SPS */
+} ExynosHdrInfoType;
+
+typedef struct _ExynosVideoRect {
+    unsigned int nTop;
+    unsigned int nLeft;
+    unsigned int nWidth;
+    unsigned int nHeight;
+} ExynosVideoRect;
+
+typedef enum _ExynosRangeType {
+    RANGE_UNSPECIFIED   = 0,
+    RANGE_FULL          = 1,
+    RANGE_LIMITED       = 2,
+} ExynosRangeType;
+
+typedef enum _ExynosPrimariesType {
+    PRIMARIES_RESERVED      = 0,
+    PRIMARIES_BT709_5       = 1,
+    PRIMARIES_UNSPECIFIED   = 2,
+    PRIMARIES_BT470_6M      = 4,
+    PRIMARIES_BT601_6_625   = 5,
+    PRIMARIES_BT601_6_525   = 6,
+    PRIMARIES_SMPTE_240M    = 7,
+    PRIMARIES_GENERIC_FILM  = 8,
+    PRIMARIES_BT2020        = 9,
+} ExynosPrimariesType;
+
+typedef enum _ExynosTransferType {
+    TRANSFER_RESERVED       = 0,
+    TRANSFER_BT709          = 1,
+    TRANSFER_UNSPECIFIED    = 2,
+    TRANSFER_GAMMA_22       = 4, /* Assumed display gamma 2.2 */
+    TRANSFER_GAMMA_28       = 5, /* Assumed display gamma 2.8 */
+    TRANSFER_SMPTE_170M     = 6,
+    TRANSFER_SMPTE_240M     = 7,
+    TRANSFER_LINEAR         = 8,
+    TRANSFER_XvYCC          = 11,
+    TRANSFER_BT1361         = 12,
+    TRANSFER_SRGB           = 13,
+    TRANSFER_BT2020_1       = 14, /* functionally the same as the 1, 6, 15 */
+    TRANSFER_BT2020_2       = 15, /* functionally the same as the 1, 6, 14 */
+    TRANSFER_ST2084         = 16,
+    TRANSFER_ST428          = 17,
+    TRANSFER_HLG            = 18,
+} ExynosTransferType;
+
+typedef enum _ExynosMatrixCoeffType {
+    MATRIX_COEFF_IDENTITY        = 0,
+    MATRIX_COEFF_REC709          = 1,
+    MATRIX_COEFF_UNSPECIFIED     = 2,
+    MATRIX_COEFF_RESERVED        = 3,
+    MATRIX_COEFF_470_SYSTEM_M    = 4,
+    MATRIX_COEFF_470_SYSTEM_BG   = 5,
+    MATRIX_COEFF_SMPTE170M       = 6,
+    MATRIX_COEFF_SMPTE240M       = 7,
+    MATRIX_COEFF_BT2020          = 9,
+    MATRIX_COEFF_BT2020_CONSTANT = 10,
+} ExynosMatrixCoeffType;
+
+typedef struct _ExynosVideoPrimaries {
+    unsigned short x;
+    unsigned short y;
+} ExynosVideoPrimaries;
+
+typedef struct _ExynosVideoHdr {
+    int max_pic_average_light;
+    int max_content_light;
+    int max_display_luminance;
+    int min_display_luminance;
+    ExynosVideoPrimaries red;
+    ExynosVideoPrimaries green;
+    ExynosVideoPrimaries blue;
+    ExynosVideoPrimaries white;
+} ExynosVideoHdr;
+
+typedef struct _ExynosVideoColorAspects {
+    ExynosRangeType         eRangeType;
+    ExynosPrimariesType     ePrimariesType;
+    ExynosTransferType      eTransferType;
+    ExynosMatrixCoeffType   eCoeffType;
+} ExynosVideoColorAspects;
+
+typedef struct _ExynosVideoHdrInfo {
+    ExynosHdrInfoType        eChangedType;
+    ExynosHdrInfoType        eValidType;
+    ExynosVideoHdr           sHdrStatic;
+    ExynosVideoColorAspects  sColorAspects;
+} ExynosVideoHdrInfo;
+
+typedef struct _ExynosVideoGeometry {
+    unsigned int                 nFrameWidth;
+    unsigned int                 nFrameHeight;
+    unsigned int                 nStride;
+    unsigned int                 nSizeImage;
+    unsigned int                 nAlignPlaneSize[VIDEO_BUFFER_MAX_PLANES];
+    unsigned int                 nPlaneCnt;
+    ExynosVideoRect              cropRect;
+    ExynosVideoCodingType        eCompressionFormat;
+    ExynosVideoColorFormatType   eColorFormat;
+    ExynosVideoBoolType          bInterlaced;
+    ExynosFilledDataType         eFilledDataType;
+    ExynosVideoHdrInfo           HdrInfo;
+} ExynosVideoGeometry;
+
+typedef struct _ExynosVideoPlane {
+    void          *addr;
+    unsigned int   allocSize;
+    unsigned int   dataSize;
+    unsigned long  offset;
+    unsigned long  fd;
+} ExynosVideoPlane;
+
+typedef struct _ReleaseDPB {
+    unsigned long long fd;
+    unsigned long long fd1;
+    unsigned long long fd2;
+} ReleaseDPB;
+
+typedef struct _PrivateDataShareBuffer {
+    int index;
+    ReleaseDPB dpbFD[VIDEO_BUFFER_MAX_NUM];
+} PrivateDataShareBuffer;
+
+typedef struct _ExynosVideoBuffer {
+    ExynosVideoPlane                planes[VIDEO_BUFFER_MAX_PLANES];
+    ExynosVideoGeometry            *pGeometry;
+    ExynosVideoFrameStatusType      displayStatus;
+    ExynosVideoFrameType            frameType;
+    int                             interlacedType;
+    ExynosVideoBoolType             bQueued;
+    ExynosVideoBoolType             bSlotUsed;
+    ExynosVideoBoolType             bRegistered;
+    void                           *pPrivate;
+    PrivateDataShareBuffer          PDSB;
+    int                             nIndexUseCnt;
+    int64_t                         timestamp;
+} ExynosVideoBuffer;
+
+typedef struct _ExynosVideoFramePacking{
+    int           available;
+    unsigned int  arrangement_id;
+    int           arrangement_cancel_flag;
+    unsigned char arrangement_type;
+    int           quincunx_sampling_flag;
+    unsigned char content_interpretation_type;
+    int           spatial_flipping_flag;
+    int           frame0_flipped_flag;
+    int           field_views_flag;
+    int           current_frame_is_frame0_flag;
+    unsigned char frame0_grid_pos_x;
+    unsigned char frame0_grid_pos_y;
+    unsigned char frame1_grid_pos_x;
+    unsigned char frame1_grid_pos_y;
+} ExynosVideoFramePacking;
+
+typedef struct _ExynosVideoQPRange {
+    int QpMin_I;
+    int QpMax_I;
+    int QpMin_P;
+    int QpMax_P;
+    int QpMin_B;
+    int QpMax_B;
+} ExynosVideoQPRange;
+
+/* for Temporal SVC */
+typedef struct _TemporalLayerShareBuffer {
+    /* In case of H.264 codec,
+     * nTemporalLayerCount contains the following data format.
+     * --------------------------------------------------------------------
+     * | Temporal SVC Coding Style (16bit) | Temporal Layer Count (16bit) |
+     * --------------------------------------------------------------------
+     * - Temporal SVC Coding Style Value
+     *   0 : default
+     *   1 : custom Temporal SVC mode(for MCD)
+     *
+     * - Temporal Layer Count Value
+     *   0       : Temporal SVC is disabled
+     *   1 ~ MAX : Temporal SVC is enabled
+     */
+    unsigned int nTemporalLayerCount;
+    unsigned int nTemporalLayerBitrateRatio[VIDEO_MAX_TEMPORAL_LAYERS];
+} TemporalLayerShareBuffer;
+
+/* for Roi Info */
+typedef struct _RoiInfoShareBuffer {
+    unsigned long long     pRoiMBInfo; /* For 32/64 bit compatibility */
+    int                    nRoiMBInfoSize;
+    int                    nUpperQpOffset;
+    int                    nLowerQpOffset;
+    ExynosVideoBoolType    bUseRoiInfo;
+} RoiInfoShareBuffer;
+
+typedef struct _ExynosVideoEncInitParam{
+    /* Initial parameters */
+    ExynosVideoFrameSkipMode FrameSkip; /* [IN] frame skip mode */
+    int FMO;
+    int ASO;
+}ExynosVideoEncInitParam;
+
+typedef struct _ExynosVideoEncCommonParam{
+    /* common parameters */
+    int SourceWidth;                    /* [IN] width of video to be encoded */
+    int SourceHeight;                   /* [IN] height of video to be encoded */
+    int IDRPeriod;                      /* [IN] GOP number(interval of I-frame) */
+    int SliceMode;                      /* [IN] Multi slice mode */
+    int RandomIntraMBRefresh;           /* [IN] cyclic intra refresh */
+    int EnableFRMRateControl;           /* [IN] frame based rate control enable */
+    int EnableMBRateControl;            /* [IN] Enable macroblock-level rate control */
+    int Bitrate;                        /* [IN] rate control parameter(bit rate) */
+    int FrameQp;                        /* [IN] The quantization parameter of the frame */
+    int FrameQp_P;                      /* [IN] The quantization parameter of the P frame */
+    int EnableFRMQpControl;             /* [IN] Enable quantization parameter per frame */
+    ExynosVideoQPRange QpRange;         /* [IN] Quantization range */
+    int CBRPeriodRf;                    /* [IN] Reaction coefficient parameter for rate control */
+    int PadControlOn;                   /* [IN] Enable padding control */
+    int LumaPadVal;                     /* [IN] Luma pel value used to fill padding area */
+    int CbPadVal;                       /* [IN] CB pel value used to fill padding area */
+    int CrPadVal;                       /* [IN] CR pel value used to fill padding area */
+    int FrameMap;                       /* [IN] Encoding input mode(tile mode or linear mode) */
+    ExynosVideoBoolType PerceptualMode; /* [IN] Enable Perceptual video coding */
+    ExynosVideoBoolType bFixedSlice;    /* [IN] Whether Slice(MBs or bytes) size is fixed or not */
+}ExynosVideoEncCommonParam;
+
+typedef struct _ExynosVideoEncH264Param{
+    /* H.264 specific parameters */
+    int ProfileIDC;                     /* [IN] profile */
+    int LevelIDC;                       /* [IN] level */
+    int FrameQp_B;                      /* [IN] The quantization parameter of the B frame */
+    int FrameRate;                      /* [IN] rate control parameter(frame rate) */
+    int SliceArgument;                  /* [IN] MB number or byte number */
+    int NumberBFrames;                  /* [IN] The number of consecutive B frame inserted */
+    int NumberReferenceFrames;          /* [IN] The number of reference pictures used */
+    int NumberRefForPframes;            /* [IN] The number of reference pictures used for encoding P pictures */
+    int LoopFilterDisable;              /* [IN] disable the loop filter */
+    int LoopFilterAlphaC0Offset;        /* [IN] Alpha & C0 offset for H.264 loop filter */
+    int LoopFilterBetaOffset;           /* [IN] Beta offset for H.264 loop filter */
+    int SymbolMode;                     /* [IN] The mode of entropy coding(CABAC, CAVLC) */
+    int PictureInterlace;               /* [IN] Enables the interlace mode */
+    int Transform8x8Mode;               /* [IN] Allow 8x8 transform(This is allowed only for high profile) */
+    int DarkDisable;                    /* [IN] Disable adaptive rate control on dark region */
+    int SmoothDisable;                  /* [IN] Disable adaptive rate control on smooth region */
+    int StaticDisable;                  /* [IN] Disable adaptive rate control on static region */
+    int ActivityDisable;                /* [IN] Disable adaptive rate control on high activity region */
+    TemporalLayerShareBuffer TemporalSVC;   /* [IN] Temporal SVC */
+    int MaxTemporalLayerCount;          /* [IN] Max Temporal Layer count */
+    int HierarType;                     /* [IN] Hierarchal P & B */
+    int VuiRestrictionEnable;           /* [IN] Num Reorder Frames 0 enable */
+    int HeaderWithIFrame;               /* [IN] Header With I-Frame 0:disable, 1:enable*/
+    int SarEnable;                      /* [IN] SarEnable */
+    int SarIndex;                       /* [IN] SarIndex */
+    int SarWidth;                       /* [IN] SarWidth */
+    int SarHeight;                      /* [IN] SarHeight */
+    int LTRFrames;                      /* [IN] LTR frames */
+    int ROIEnable;                      /* [IN] ROIEnable */
+} ExynosVideoEncH264Param;
+
+typedef struct _ExynosVideoEncMpeg4Param {
+    /* MPEG4 specific parameters */
+    int ProfileIDC;                     /* [IN] profile */
+    int LevelIDC;                       /* [IN] level */
+    int FrameQp_B;                      /* [IN] The quantization parameter of the B frame */
+    int TimeIncreamentRes;              /* [IN] frame rate */
+    int VopTimeIncreament;              /* [IN] frame rate */
+    int SliceArgument;                  /* [IN] MB number or byte number */
+    int NumberBFrames;                  /* [IN] The number of consecutive B frame inserted */
+    int DisableQpelME;                  /* [IN] disable quarter-pixel motion estimation */
+} ExynosVideoEncMpeg4Param;
+
+typedef struct _ExynosVideoEncH263Param {
+    /* H.263 specific parameters */
+    int FrameRate;                      /* [IN] rate control parameter(frame rate) */
+} ExynosVideoEncH263Param;
+
+typedef struct _ExynosVideoEncVp8Param {
+    /* VP8 specific parameters */
+    int FrameRate;                    /* [IN] rate control parameter(frame rate) */
+    int Vp8Version;                   /* [IN] vp8 version */
+    int Vp8NumberOfPartitions;        /* [IN] number of partitions */
+    int Vp8FilterLevel;               /* [IN] filter level */
+    int Vp8FilterSharpness;           /* [IN] filter sharpness */
+    int Vp8GoldenFrameSel;            /* [IN] indication of golden frame */
+    int Vp8GFRefreshPeriod;           /* [IN] refresh period of golden frame */
+    int RefNumberForPFrame;           /* [IN] number of refernce picture for p frame */
+    int DisableIntraMd4x4;            /* [IN] prevent intra 4x4 mode */
+    TemporalLayerShareBuffer TemporalSVC;   /* [IN] Temporal SVC */
+} ExynosVideoEncVp8Param;
+
+typedef struct _ExynosVideoEncHevcParam{
+    /* HEVC specific parameters */
+    int ProfileIDC;                   /* [IN] profile */
+    int TierIDC;                      /* [IN] tier flag(MAIN, HIGH) */
+    int LevelIDC;                     /* [IN] level */
+    int FrameQp_B;                    /* [IN] The quantization parameter of the B frame */
+    int FrameRate;                    /* [IN] rate control parameter(frame rate) */
+    int MaxPartitionDepth;            /* [IN] Max partition depth */
+    int NumberBFrames;                /* [IN] The number of consecutive B frame inserted */
+    int NumberReferenceFrames;        /* [IN] The number of reference pictures used */
+    int NumberRefForPframes;          /* [IN] The number of reference pictures used for encoding P pictures */
+    int LoopFilterDisable;            /* [IN] disable the loop filter */
+    int LoopFilterSliceFlag;          /* [IN] in loop filter, select across or not slice boundary */
+    int LoopFilterTcOffset;           /* [IN] TC offset for HEVC loop filter */
+    int LoopFilterBetaOffset;         /* [IN] Beta offset for HEVC loop filter */
+    int LongtermRefEnable;            /* [IN] long term reference enable */
+    int LongtermUserRef;              /* [IN] use long term reference index (0 or 1) */
+    int LongtermStoreRef;             /* [IN] use long term frame index (0 or 1) */
+    int DarkDisable;                  /* [IN] Disable adaptive rate control on dark region */
+    int SmoothDisable;                /* [IN] Disable adaptive rate control on smooth region */
+    int StaticDisable;                /* [IN] Disable adaptive rate control on static region */
+    int ActivityDisable;              /* [IN] Disable adaptive rate control on high activity region */
+    TemporalLayerShareBuffer TemporalSVC;   /* [IN] Temporal SVC */
+    int MaxTemporalLayerCount;        /* [IN] Max Temporal Layer count */
+    int ROIEnable;                    /* [IN] ROIEnable */
+} ExynosVideoEncHevcParam;
+
+typedef struct _ExynosVideoEncVp9Param {
+    /* VP9 specific parameters */
+    int FrameRate;                    /* [IN] rate control parameter(frame rate) */
+    int Vp9Version;                   /* [IN] vp8 version */
+    int Vp9GoldenFrameSel;            /* [IN] indication of golden frame */
+    int Vp9GFRefreshPeriod;           /* [IN] refresh period of golden frame */
+    int RefNumberForPFrame;           /* [IN] number of refernce picture for p frame */
+    int MaxPartitionDepth;            /* [IN] Max partition depth */
+    TemporalLayerShareBuffer TemporalSVC;   /* [IN] Temporal SVC */
+} ExynosVideoEncVp9Param;
+
+typedef union _ExynosVideoEncCodecParam {
+    ExynosVideoEncH264Param     h264;
+    ExynosVideoEncMpeg4Param    mpeg4;
+    ExynosVideoEncH263Param     h263;
+    ExynosVideoEncVp8Param      vp8;
+    ExynosVideoEncHevcParam     hevc;
+    ExynosVideoEncVp9Param      vp9;
+} ExynosVideoEncCodecParam;
+
+typedef struct _ExynosVideoEncParam {
+    ExynosVideoCodingType       eCompressionFormat;
+    ExynosVideoEncInitParam     initParam;
+    ExynosVideoEncCommonParam   commonParam;
+    ExynosVideoEncCodecParam    codecParam;
+} ExynosVideoEncParam;
+
+typedef struct _ExynosVideoDecSupportInfo {
+    ExynosVideoBoolType bSkypeSupport;          /* H.264 only */
+} ExynosVideoDecSupportInfo;
+
+typedef struct _ExynosVideoEncSupportInfo {
+    int                 nSpareSize;
+    ExynosVideoBoolType bTemporalSvcSupport;    /* H.264, HEVC, VP8, VP9 */
+    ExynosVideoBoolType bSkypeSupport;          /* H.264 only */
+    ExynosVideoBoolType bRoiInfoSupport;        /* H.264, HEVC */
+    ExynosVideoBoolType bQpRangePBSupport;
+    ExynosVideoBoolType bFixedSliceSupport;     /* H.264 only */
+    ExynosVideoBoolType bPVCSupport;            /* H.264, HEVC, VP8, VP9 */
+    ExynosVideoBoolType bIFrameRatioSupport;    /* H.264, HEVC */
+    ExynosVideoBoolType bColorAspectsSupport;   /* H.264, HEVC, VP9 */
+} ExynosVideoEncSupportInfo;
+
+typedef struct _ExynosVideoInstInfo {
+    unsigned int               nSize;
+
+    unsigned int               nWidth;
+    unsigned int               nHeight;
+    unsigned int               nBitrate;
+    unsigned int               xFramerate;
+    ExynosVideoMemoryType      nMemoryType;
+    ExynosVideoCodingType      eCodecType;
+    int                        HwVersion;
+    unsigned int               SwVersion;
+    ExynosVideoSecurityType    eSecurityType;
+    ExynosVideoColorFormatType supportFormat[VIDEO_COLORFORMAT_MAX];
+
+    union {
+        ExynosVideoDecSupportInfo dec;
+        ExynosVideoEncSupportInfo enc;
+    }                          supportInfo;
+
+    ExynosVideoBoolType        bOTFMode;
+} ExynosVideoInstInfo;
+
+typedef struct _ExynosVideoDecInfo {
+    unsigned long           nPrivateDataShareFD;
+    void                   *pPrivateDataShareAddress;
+} ExynosVideoDecInfo;
+
+typedef struct _ExynosVideoEncInfo {
+    unsigned long           nTemporalLayerShareBufferFD;
+    void                   *pTemporalLayerShareBufferAddr;
+    unsigned long           nRoiShareBufferFD;
+    void                   *pRoiShareBufferAddr;
+    int                     oldFrameRate;
+    signed long long        oldTimeStamp;
+    signed long long        oldDuration;
+} ExynosVideoEncInfo;
+
+typedef struct _ExynosVideoContext {
+    int                     hDevice;
+    ExynosVideoBoolType     bShareInbuf;
+    ExynosVideoBoolType     bShareOutbuf;
+    ExynosVideoBuffer      *pInbuf;
+    ExynosVideoBuffer      *pOutbuf;
+    ExynosVideoGeometry     inbufGeometry;
+    ExynosVideoGeometry     outbufGeometry;
+    int                     nInbufs;
+    int                     nInbufPlanes;
+    int                     nOutbufs;
+    int                     nOutbufPlanes;
+    ExynosVideoBoolType     bStreamonInbuf;
+    ExynosVideoBoolType     bStreamonOutbuf;
+    void                   *pPrivate;
+    void                   *pInMutex;
+    void                   *pOutMutex;
+    unsigned long           hIONHandle;
+    ExynosVideoInstInfo     instInfo;
+    union ExynosVideoSpecificInfo {
+        ExynosVideoDecInfo dec;
+        ExynosVideoEncInfo enc;
+    }                       specificInfo;
+} ExynosVideoContext;
+
+typedef struct _ExynosVideoDecOps {
+    unsigned int            nSize;
+
+    void *                (*Init)(ExynosVideoInstInfo *pVideoInfo);
+    ExynosVideoErrorType  (*Finalize)(void *pHandle);
+
+    /* Add new ops at the end of structure, no order change */
+    ExynosVideoErrorType  (*Set_FrameTag)(void *pHandle, int nFrameTag);
+    int                   (*Get_FrameTag)(void *pHandle);
+    int                   (*Get_ActualBufferCount)(void *pHandle);
+    ExynosVideoErrorType  (*Set_DisplayDelay)(void *pHandle, int nDelay);
+    ExynosVideoErrorType  (*Set_IFrameDecoding)(void *pHandle);
+    ExynosVideoErrorType  (*Enable_PackedPB)(void *pHandle);
+    ExynosVideoErrorType  (*Enable_LoopFilter)(void *pHandle);
+    ExynosVideoErrorType  (*Enable_SliceMode)(void *pHandle);
+    ExynosVideoErrorType  (*Enable_SEIParsing)(void *pHandle);
+    ExynosVideoErrorType  (*Get_FramePackingInfo)(void *pHandle, ExynosVideoFramePacking *pFramepacking);
+    ExynosVideoErrorType  (*Set_ImmediateDisplay)(void *pHandle);
+    ExynosVideoErrorType  (*Enable_DTSMode)(void *pHandle);
+    ExynosVideoErrorType  (*Set_QosRatio)(void *pHandle, int nRatio);
+    ExynosVideoErrorType  (*Enable_DualDPBMode)(void *pHandle);
+    ExynosVideoErrorType  (*Enable_DynamicDPB)(void *pHandle);
+    ExynosVideoErrorType  (*Enable_DiscardRcvHeader)(void *pHandle);
+    ExynosVideoErrorType  (*Get_HDRInfo)(void *pHandle, ExynosVideoHdrInfo *pHdrInfo);
+    ExynosVideoErrorType  (*Set_SearchBlackBar)(void *pHandle, ExynosVideoBoolType bUse);
+} ExynosVideoDecOps;
+
+typedef struct _ExynosVideoEncOps {
+    unsigned int           nSize;
+    void *               (*Init)(ExynosVideoInstInfo *pVideoInfo);
+    ExynosVideoErrorType (*Finalize)(void *pHandle);
+
+    /* Add new ops at the end of structure, no order change */
+    ExynosVideoErrorType (*Set_EncParam)(void *pHandle, ExynosVideoEncParam*encParam);
+    ExynosVideoErrorType (*Set_FrameTag)(void *pHandle, int nFrameTag);
+    int (*Get_FrameTag)(void *pHandle);
+    ExynosVideoErrorType (*Set_FrameType)(void *pHandle, ExynosVideoFrameType eFrameType);
+    ExynosVideoErrorType (*Set_FrameRate)(void *pHandle, int nFramerate);
+    ExynosVideoErrorType (*Set_BitRate)(void *pHandle, int nBitrate);
+    ExynosVideoErrorType (*Set_QpRange)(void *pHandle, ExynosVideoQPRange qpRange);
+    ExynosVideoErrorType (*Set_FrameSkip)(void *pHandle, int nFrameSkip);
+    ExynosVideoErrorType (*Set_IDRPeriod)(void *pHandle, int nPeriod);
+    ExynosVideoErrorType (*Set_SliceMode)(void *pHandle, int nSliceMode, int nSliceArgument);
+    ExynosVideoErrorType (*Enable_PrependSpsPpsToIdr)(void *pHandle);
+    ExynosVideoErrorType (*Set_QosRatio)(void *pHandle, int nRatio);
+    ExynosVideoErrorType (*Set_LayerChange)(void *pHandle, TemporalLayerShareBuffer TemporalSVC);
+    ExynosVideoErrorType (*Set_DynamicQpControl)(void *pHandle, int nQp);
+    ExynosVideoErrorType (*Set_MarkLTRFrame)(void *pHandle, int nLongTermFrmIdx);
+    ExynosVideoErrorType (*Set_UsedLTRFrame)(void *pHandle, int nUsedLTRFrameNum);
+    ExynosVideoErrorType (*Set_BasePID)(void *pHandle, int nPID);
+    ExynosVideoErrorType (*Set_RoiInfo)(void *pHandle, RoiInfoShareBuffer *pRoiInfo);
+    ExynosVideoErrorType (*Enable_WeightedPrediction)(void *pHandle);
+    ExynosVideoErrorType (*Set_YSumData)(void *pHandle, unsigned int nHighData, unsigned int nLowData);
+    ExynosVideoErrorType (*Set_IFrameRatio)(void *pHandle, int nRatio);
+    ExynosVideoErrorType (*Set_ColorAspects)(void *pHandle, ExynosVideoColorAspects *pColorAspects);
+} ExynosVideoEncOps;
+
+typedef struct _ExynosVideoDecBufferOps {
+    unsigned int            nSize;
+
+    /* Add new ops at the end of structure, no order change */
+    ExynosVideoErrorType  (*Enable_Cacheable)(void *pHandle);
+    ExynosVideoErrorType  (*Set_Shareable)(void *pHandle);
+    ExynosVideoErrorType  (*Get_Buffer)(void *pHandle, int nIndex, ExynosVideoBuffer **pBuffer);
+    ExynosVideoErrorType  (*Set_Geometry)(void *pHandle, ExynosVideoGeometry *pBufferConf);
+    ExynosVideoErrorType  (*Get_Geometry)(void *pHandle, ExynosVideoGeometry *pBufferConf);
+    ExynosVideoErrorType  (*Get_BlackBarCrop)(void *pHandle, ExynosVideoRect *pBufferCrop);
+    ExynosVideoErrorType  (*Setup)(void *pHandle, unsigned int nBufferCount);
+    ExynosVideoErrorType  (*Run)(void *pHandle);
+    ExynosVideoErrorType  (*Stop)(void *pHandle);
+    ExynosVideoErrorType  (*Enqueue)(void *pHandle, void *pBuffer[], unsigned int nDataSize[], int nPlanes, void *pPrivate);
+    ExynosVideoErrorType  (*Enqueue_All)(void *pHandle);
+    ExynosVideoBuffer *   (*Dequeue)(void *pHandle);
+    ExynosVideoErrorType  (*Register)(void *pHandle, ExynosVideoPlane *pPlanes, int nPlanes);
+    ExynosVideoErrorType  (*Clear_RegisteredBuffer)(void *pHandle);
+    ExynosVideoErrorType  (*Clear_Queue)(void *pHandle);
+    ExynosVideoErrorType  (*Cleanup_Buffer)(void *pHandle);
+    ExynosVideoErrorType  (*Apply_RegisteredBuffer)(void *pHandle);
+    ExynosVideoErrorType  (*ExtensionEnqueue)(void *pHandle, void *pBuffer[], unsigned long pFd[], unsigned int nAllocLen[], unsigned int nDataSize[], int nPlanes, void *pPrivate);
+    ExynosVideoErrorType  (*ExtensionDequeue)(void *pHandle, ExynosVideoBuffer *pVideoBuffer);
+} ExynosVideoDecBufferOps;
+
+typedef struct _ExynosVideoEncBufferOps {
+    unsigned int            nSize;
+
+    /* Add new ops at the end of structure, no order change */
+    ExynosVideoErrorType  (*Enable_Cacheable)(void *pHandle);
+    ExynosVideoErrorType  (*Set_Shareable)(void *pHandle);
+    ExynosVideoErrorType  (*Get_Buffer)(void *pHandle, int nIndex, ExynosVideoBuffer **pBuffer);
+    ExynosVideoErrorType  (*Set_Geometry)(void *pHandle, ExynosVideoGeometry *pBufferConf);
+    ExynosVideoErrorType  (*Get_Geometry)(void *pHandle, ExynosVideoGeometry *pBufferConf);
+    ExynosVideoErrorType  (*Setup)(void *pHandle, unsigned int nBufferCount);
+    ExynosVideoErrorType  (*Run)(void *pHandle);
+    ExynosVideoErrorType  (*Stop)(void *pHandle);
+    ExynosVideoErrorType  (*Enqueue)(void *pHandle, void *pBuffer[], unsigned int nDataSize[], int nPlanes, void *pPrivate);
+    ExynosVideoErrorType  (*Enqueue_All)(void *pHandle);
+    ExynosVideoBuffer *   (*Dequeue)(void *pHandle);
+    ExynosVideoErrorType  (*Register)(void *pHandle, ExynosVideoPlane *pPlanes, int nPlanes);
+    ExynosVideoErrorType  (*Clear_RegisteredBuffer)(void *pHandle);
+    ExynosVideoErrorType  (*Clear_Queue)(void *pHandle);
+    ExynosVideoErrorType  (*ExtensionEnqueue)(void *pHandle, void *pBuffer[], unsigned long pFd[], unsigned int nAllocLen[], unsigned int nDataSize[], int nPlanes, void *pPrivate);
+    ExynosVideoErrorType  (*ExtensionDequeue)(void *pHandle, ExynosVideoBuffer *pVideoBuffer);
+} ExynosVideoEncBufferOps;
+
+ExynosVideoErrorType Exynos_Video_GetInstInfo(
+    ExynosVideoInstInfo *pVideoInstInfo, ExynosVideoBoolType bIsDec);
+
+ExynosVideoErrorType Exynos_Video_Register_Decoder(
+    ExynosVideoDecOps       *pDecOps,
+    ExynosVideoDecBufferOps *pInbufOps,
+    ExynosVideoDecBufferOps *pOutbufOps);
+
+ExynosVideoErrorType Exynos_Video_Register_Encoder(
+    ExynosVideoEncOps       *pEncOps,
+    ExynosVideoEncBufferOps *pInbufOps,
+    ExynosVideoEncBufferOps *pOutbufOps);
+
+void Exynos_Video_Unregister_Decoder(
+    ExynosVideoDecOps       *pDecOps,
+    ExynosVideoDecBufferOps *pInbufOps,
+    ExynosVideoDecBufferOps *pOutbufOps);
+
+void Exynos_Video_Unregister_Encoder(
+    ExynosVideoEncOps       *pEncOps,
+    ExynosVideoEncBufferOps *pInbufOps,
+    ExynosVideoEncBufferOps *pOutbufOps);
+#endif /* _EXYNOS_VIDEO_API_H_ */
diff --git a/exynos/libvideocodec/include/ExynosVideoDec.h b/exynos/libvideocodec/include/ExynosVideoDec.h
new file mode 100755 (executable)
index 0000000..a3c85d8
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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 _EXYNOS_VIDEO_DEC_H_
+#define _EXYNOS_VIDEO_DEC_H_
+
+#include "ExynosVideoApi.h"
+
+#define VIDEO_DECODER_INBUF_SIZE        (1920 * 1080 * 3 / 2)
+#define VIDEO_DECODER_DEFAULT_INBUF_PLANES  1
+#define VIDEO_DECODER_DEFAULT_OUTBUF_PLANES 2
+#define VIDEO_DECODER_POLL_TIMEOUT      25
+
+ExynosVideoErrorType MFC_Exynos_Video_GetInstInfo_Decoder(
+    ExynosVideoInstInfo *pVideoInstInfo);
+
+int MFC_Exynos_Video_Register_Decoder(
+    ExynosVideoDecOps       *pDecOps,
+    ExynosVideoDecBufferOps *pInbufOps,
+    ExynosVideoDecBufferOps *pOutbufOps);
+
+#endif /* _EXYNOS_VIDEO_DEC_H_ */
diff --git a/exynos/libvideocodec/include/ExynosVideoEnc.h b/exynos/libvideocodec/include/ExynosVideoEnc.h
new file mode 100755 (executable)
index 0000000..ca5e898
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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 _EXYNOS_VIDEO_ENC_H_
+#define _EXYNOS_VIDEO_ENC_H_
+
+#include "ExynosVideoApi.h"
+#include "ExynosVideo_OSAL.h"
+
+#define VIDEO_ENCODER_DEFAULT_INBUF_PLANES  2
+#define VIDEO_ENCODER_DEFAULT_OUTBUF_PLANES 1
+#define VIDEO_ENCODER_POLL_TIMEOUT      25
+
+#define FRAME_RATE_CHANGE_THRESH_HOLD 5
+
+static const int vp8_qp_trans[] =
+{
+    0,   1,  2,  3,  4,  5,  7,  8,
+    9,  10, 12, 13, 15, 17, 18, 19,
+    20,  21, 23, 24, 25, 26, 27, 28,
+    29,  30, 31, 33, 35, 37, 39, 41,
+    43,  45, 47, 49, 51, 53, 55, 57,
+    59,  61, 64, 67, 70, 73, 76, 79,
+    82,  85, 88, 91, 94, 97, 100, 103,
+    106, 109, 112, 115, 118, 121, 124, 127,
+};
+
+static const int vp9_qp_trans[] = {
+  0,    4,   8,  12,  16,  20,  24,  28,
+  32,   36,  40,  44,  48,  52,  56,  60,
+  64,   68,  72,  76,  80,  84,  88,  92,
+  96,  100, 104, 108, 112, 116, 120, 124,
+  128, 132, 136, 140, 144, 148, 152, 156,
+  160, 164, 168, 172, 176, 180, 184, 188,
+  192, 196, 200, 204, 208, 212, 216, 220,
+  224, 228, 232, 236, 240, 244, 249, 255,
+};
+
+#define GET_VALUE(value, min, max) ((value < min)? min:(value > max)? max:value)
+#define GET_H264_QP_VALUE(value) GET_VALUE(value, 0, 51)
+#define GET_MPEG4_QP_VALUE(value) GET_VALUE(value, 1, 31)
+#define GET_H263_QP_VALUE(value) GET_VALUE(value, 1, 31)
+#define GET_VP8_QP_VALUE(value) (vp8_qp_trans[GET_VALUE(value, 0, ((int)(sizeof(vp8_qp_trans)/sizeof(int)) - 1))])
+
+// Porting exynos 9110, error fix
+#define GET_HEVC_QP_VALUE(value, version) GET_VALUE(value, 0, 51)
+#define GET_VP9_QP_VALUE(value) (vp9_qp_trans[GET_VALUE(value, 1, ((int)(sizeof(vp9_qp_trans)/sizeof(int)) - 1))])
+
+ExynosVideoErrorType MFC_Exynos_Video_GetInstInfo_Encoder(
+    ExynosVideoInstInfo *pVideoInstInfo);
+
+int MFC_Exynos_Video_Register_Encoder(
+    ExynosVideoEncOps       *pEncOps,
+    ExynosVideoEncBufferOps *pInbufOps,
+    ExynosVideoEncBufferOps *pOutbufOps);
+
+#endif /* _EXYNOS_VIDEO_ENC_H_ */
diff --git a/exynos/libvideocodec/mfc_headers/exynos_mfc_media.h b/exynos/libvideocodec/mfc_headers/exynos_mfc_media.h
new file mode 100755 (executable)
index 0000000..f329835
--- /dev/null
@@ -0,0 +1,308 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __EXYNOS_MFC_MEDIA_H
+#define __EXYNOS_MFC_MEDIA_H __FILE__
+#define V4L2_PIX_FMT_RGB32X v4l2_fourcc('R', 'G', 'B', 'X')
+#define V4L2_PIX_FMT_YUV444_2P v4l2_fourcc('Y', 'U', '2', 'P')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_YVU444_2P v4l2_fourcc('Y', 'V', '2', 'P')
+#define V4L2_PIX_FMT_YUV444_3P v4l2_fourcc('Y', 'U', '3', 'P')
+#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1')
+#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4')
+#define V4L2_PIX_FMT_FIMV v4l2_fourcc('F', 'I', 'M', 'V')
+#define V4L2_PIX_FMT_FIMV1 v4l2_fourcc('F', 'I', 'M', '1')
+#define V4L2_PIX_FMT_FIMV2 v4l2_fourcc('F', 'I', 'M', '2')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_FIMV3 v4l2_fourcc('F', 'I', 'M', '3')
+#define V4L2_PIX_FMT_FIMV4 v4l2_fourcc('F', 'I', 'M', '4')
+#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0')
+#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0')
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C')
+#define V4L2_CID_MPEG_MFC_BASE (V4L2_CTRL_CLASS_MPEG | 0x2000)
+#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL (V4L2_CID_MPEG_MFC_BASE + 1)
+#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID (V4L2_CID_MPEG_MFC_BASE + 2)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO (V4L2_CID_MPEG_MFC_BASE + 3)
+#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS (V4L2_CID_MPEG_MFC_BASE + 4)
+#define V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB (V4L2_CID_MPEG_MFC_BASE + 5)
+#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG (V4L2_CID_MPEG_MFC_BASE + 6)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_ENABLE (V4L2_CID_MPEG_MFC_BASE + 7)
+#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA (V4L2_CID_MPEG_MFC_BASE + 8)
+#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA (V4L2_CID_MPEG_MFC_BASE + 9)
+#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA_BOT (V4L2_CID_MPEG_MFC_BASE + 10)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA_BOT (V4L2_CID_MPEG_MFC_BASE + 11)
+#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_GENERATED (V4L2_CID_MPEG_MFC_BASE + 12)
+#define V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE (V4L2_CID_MPEG_MFC_BASE + 13)
+#define V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS (V4L2_CID_MPEG_MFC_BASE + 14)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC51_VIDEO_LUMA_ADDR (V4L2_CID_MPEG_MFC_BASE + 15)
+#define V4L2_CID_MPEG_MFC51_VIDEO_CHROMA_ADDR (V4L2_CID_MPEG_MFC_BASE + 16)
+#define V4L2_CID_MPEG_MFC51_VIDEO_STREAM_SIZE (V4L2_CID_MPEG_MFC_BASE + 17)
+#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_COUNT (V4L2_CID_MPEG_MFC_BASE + 18)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TYPE (V4L2_CID_MPEG_MFC_BASE + 19)
+enum v4l2_mpeg_mfc51_video_frame_type {
+  V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_NOT_CODED = 0,
+  V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_I_FRAME = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_P_FRAME = 2,
+  V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_B_FRAME = 3,
+  V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_SKIPPED = 4,
+  V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_OTHERS = 5,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE (V4L2_CID_MPEG_MFC_BASE + 20)
+#define V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE (V4L2_CID_MPEG_MFC_BASE + 21)
+#define V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES (V4L2_CID_MPEG_MFC_BASE + 22)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA (V4L2_CID_MPEG_MFC_BASE + 23)
+#define V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE (V4L2_CID_MPEG_MFC_BASE + 24)
+#define V4L2_CID_MPEG_MFC6X_VIDEO_FRAME_DELTA (V4L2_CID_MPEG_MFC_BASE + 25)
+#define V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH V4L2_CID_MPEG_VIDEO_GOP_SIZE
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE
+#define V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH V4L2_CID_MPEG_VIDEO_BITRATE
+#define V4L2_MPEG_VIDEO_MPEG4_LEVEL_6 8
+#define V4L2_MPEG_VIDEO_HEADER_MODE_AT_THE_READY 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB_ROW 3
+#define V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH 17
+#define V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_S_B V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_H264_MVC_VIEW_ID (V4L2_CID_MPEG_MFC_BASE + 42)
+#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS (V4L2_CID_MPEG_MFC_BASE + 43)
+#define V4L2_CID_MPEG_MFC51_VIDEO_I_FRAME_DECODING (V4L2_CID_MPEG_MFC_BASE + 44)
+#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE (V4L2_CID_MPEG_MFC_BASE + 45)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_MFC_BASE + 46)
+#define V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY (V4L2_CID_MPEG_MFC_BASE + 47)
+#define V4L2_CID_MPEG_VIDEO_DECODER_DECODING_TIMESTAMP_MODE (V4L2_CID_MPEG_MFC_BASE + 48)
+#define V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START (V4L2_CID_MPEG_MFC_BASE + 49)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_QOS_RATIO (V4L2_CID_MPEG_MFC_BASE + 50)
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT (V4L2_CID_MPEG_MFC_BASE + 51)
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH (V4L2_CID_MPEG_MFC_BASE + 52)
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT0 (V4L2_CID_MPEG_MFC_BASE + 53)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT1 (V4L2_CID_MPEG_MFC_BASE + 54)
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT2 (V4L2_CID_MPEG_MFC_BASE + 55)
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT3 (V4L2_CID_MPEG_MFC_BASE + 56)
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT4 (V4L2_CID_MPEG_MFC_BASE + 57)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT5 (V4L2_CID_MPEG_MFC_BASE + 58)
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT6 (V4L2_CID_MPEG_MFC_BASE + 59)
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_VERSION (V4L2_CID_MPEG_MFC_BASE + 60)
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_RC_FRAME_RATE (V4L2_CID_MPEG_MFC_BASE + 61)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_VP8_MIN_QP (V4L2_CID_MPEG_MFC_BASE + 62)
+#define V4L2_CID_MPEG_VIDEO_VP8_MAX_QP (V4L2_CID_MPEG_MFC_BASE + 63)
+#define V4L2_CID_MPEG_VIDEO_VP8_I_FRAME_QP (V4L2_CID_MPEG_MFC_BASE + 64)
+#define V4L2_CID_MPEG_VIDEO_VP8_P_FRAME_QP (V4L2_CID_MPEG_MFC_BASE + 65)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_OF_PARTITIONS (V4L2_CID_MPEG_MFC_BASE + 66)
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_LEVEL (V4L2_CID_MPEG_MFC_BASE + 67)
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_SHARPNESS (V4L2_CID_MPEG_MFC_BASE + 68)
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_GOLDEN_FRAMESEL (V4L2_CID_MPEG_MFC_BASE + 69)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_GF_REFRESH_PERIOD (V4L2_CID_MPEG_MFC_BASE + 70)
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_ENABLE (V4L2_CID_MPEG_MFC_BASE + 71)
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER0 (V4L2_CID_MPEG_MFC_BASE + 72)
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER1 (V4L2_CID_MPEG_MFC_BASE + 73)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER2 (V4L2_CID_MPEG_MFC_BASE + 74)
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_REF_NUMBER_FOR_PFRAMES (V4L2_CID_MPEG_MFC_BASE + 75)
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_DISABLE_INTRA_MD4X4 (V4L2_CID_MPEG_MFC_BASE + 76)
+#define V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_TEMPORAL_LAYER (V4L2_CID_MPEG_MFC_BASE + 77)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT (V4L2_CID_MPEG_MFC_BASE + 78)
+#define V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH (V4L2_CID_MPEG_MFC_BASE + 79)
+#define V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT0 (V4L2_CID_MPEG_MFC_BASE + 80)
+#define V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT1 (V4L2_CID_MPEG_MFC_BASE + 81)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT2 (V4L2_CID_MPEG_MFC_BASE + 82)
+#define V4L2_CID_MPEG_MFC_GET_VERSION_INFO (V4L2_CID_MPEG_MFC_BASE + 91)
+#define V4L2_CID_MPEG_MFC_GET_EXTRA_BUFFER_SIZE (V4L2_CID_MPEG_MFC_BASE + 92)
+#define V4L2_CID_MPEG_MFC_SET_DUAL_DPB_MODE (V4L2_CID_MPEG_MFC_BASE + 93)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE (V4L2_CID_MPEG_MFC_BASE + 95)
+#define V4L2_CID_MPEG_MFC_SET_USER_SHARED_HANDLE (V4L2_CID_MPEG_MFC_BASE + 96)
+#define V4L2_CID_MPEG_MFC_GET_EXT_INFO (V4L2_CID_MPEG_MFC_BASE + 97)
+#define V4L2_CID_MPEG_MFC_SET_BUF_PROCESS_TYPE (V4L2_CID_MPEG_MFC_BASE + 98)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC_GET_10BIT_INFO (V4L2_CID_MPEG_MFC_BASE + 99)
+#define V4L2_CID_MPEG_MFC_H264_ENABLE_LTR (V4L2_CID_MPEG_MFC_BASE + 100)
+#define V4L2_CID_MPEG_MFC_H264_MARK_LTR (V4L2_CID_MPEG_MFC_BASE + 101)
+#define V4L2_CID_MPEG_MFC_H264_USE_LTR (V4L2_CID_MPEG_MFC_BASE + 102)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB_ROW (V4L2_CID_MPEG_MFC_BASE + 103)
+#define V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY (V4L2_CID_MPEG_MFC_BASE + 104)
+#define V4L2_CID_MPEG_MFC_CONFIG_QP (V4L2_CID_MPEG_MFC_BASE + 105)
+#define V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE (V4L2_CID_MPEG_MFC_BASE + 106)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC_GET_DRIVER_INFO (V4L2_CID_MPEG_MFC_BASE + 107)
+#define V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE (V4L2_CID_MPEG_MFC_BASE + 108)
+#define V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP (V4L2_CID_MPEG_MFC_BASE + 110)
+#define V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP (V4L2_CID_MPEG_MFC_BASE + 111)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP (V4L2_CID_MPEG_MFC_BASE + 112)
+#define V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP (V4L2_CID_MPEG_MFC_BASE + 113)
+#define V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP (V4L2_CID_MPEG_MFC_BASE + 114)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_QP_ENABLE (V4L2_CID_MPEG_MFC_BASE + 115)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE (V4L2_CID_MPEG_MFC_BASE + 116)
+enum v4l2_mpeg_video_hevc_hierarchical_coding_type {
+  V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B = 0,
+  V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P = 1,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER (V4L2_CID_MPEG_MFC_BASE + 117)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_MFC_BASE + 118)
+#define V4L2_CID_MPEG_VIDEO_HEVC_PROFILE (V4L2_CID_MPEG_MFC_BASE + 120)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_HEVC_LEVEL (V4L2_CID_MPEG_MFC_BASE + 121)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_RC_FRAME_RATE (V4L2_CID_MPEG_MFC_BASE + 122)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TIER_FLAG (V4L2_CID_MPEG_MFC_BASE + 123)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_PARTITION_DEPTH (V4L2_CID_MPEG_MFC_BASE + 124)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REF_NUMBER_FOR_PFRAMES (V4L2_CID_MPEG_MFC_BASE + 125)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_DISABLE (V4L2_CID_MPEG_MFC_BASE + 126)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_SLICE_BOUNDARY (V4L2_CID_MPEG_MFC_BASE + 127)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_BETA_OFFSET_DIV2 (V4L2_CID_MPEG_MFC_BASE + 128)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_TC_OFFSET_DIV2 (V4L2_CID_MPEG_MFC_BASE + 129)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_TYPE (V4L2_CID_MPEG_MFC_BASE + 130)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_PERIOD (V4L2_CID_MPEG_MFC_BASE + 131)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LOSSLESS_CU_ENABLE (V4L2_CID_MPEG_MFC_BASE + 132)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_CONST_INTRA_PRED_ENABLE (V4L2_CID_MPEG_MFC_BASE + 133)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_WAVEFRONT_ENABLE (V4L2_CID_MPEG_MFC_BASE + 134)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LTR_ENABLE (V4L2_CID_MPEG_MFC_BASE + 135)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_USER_REF (V4L2_CID_MPEG_MFC_BASE + 136)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STORE_REF (V4L2_CID_MPEG_MFC_BASE + 137)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIGN_DATA_HIDING (V4L2_CID_MPEG_MFC_BASE + 138)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_GENERAL_PB_ENABLE (V4L2_CID_MPEG_MFC_BASE + 139)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TEMPORAL_ID_ENABLE (V4L2_CID_MPEG_MFC_BASE + 140)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STRONG_SMOTHING_FLAG (V4L2_CID_MPEG_MFC_BASE + 141)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1 (V4L2_CID_MPEG_MFC_BASE + 142)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_DARK (V4L2_CID_MPEG_MFC_BASE + 143)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_SMOOTH (V4L2_CID_MPEG_MFC_BASE + 144)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC_BASE + 145)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_ACTIVITY (V4L2_CID_MPEG_MFC_BASE + 146)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_INTRA_PU_SPLIT (V4L2_CID_MPEG_MFC_BASE + 147)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_TMV_PREDICTION (V4L2_CID_MPEG_MFC_BASE + 148)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_WITHOUT_STARTCODE_ENABLE (V4L2_CID_MPEG_MFC_BASE + 149)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_QP_INDEX_CR (V4L2_CID_MPEG_MFC_BASE + 150)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_QP_INDEX_CB (V4L2_CID_MPEG_MFC_BASE + 151)
+#define V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD (V4L2_CID_MPEG_MFC_BASE + 152)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_HEVC_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_MFC_BASE + 153)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH (V4L2_CID_MPEG_MFC_BASE + 154)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT0 (V4L2_CID_MPEG_MFC_BASE + 155)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT1 (V4L2_CID_MPEG_MFC_BASE + 156)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT2 (V4L2_CID_MPEG_MFC_BASE + 157)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT3 (V4L2_CID_MPEG_MFC_BASE + 158)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT4 (V4L2_CID_MPEG_MFC_BASE + 159)
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT5 (V4L2_CID_MPEG_MFC_BASE + 160)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT6 (V4L2_CID_MPEG_MFC_BASE + 161)
+#define V4L2_CID_MPEG_VIDEO_VP9_VERSION (V4L2_CID_MPEG_MFC_BASE + 163)
+#define V4L2_CID_MPEG_VIDEO_VP9_RC_FRAME_RATE (V4L2_CID_MPEG_MFC_BASE + 164)
+#define V4L2_CID_MPEG_VIDEO_VP9_MIN_QP (V4L2_CID_MPEG_MFC_BASE + 165)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_VP9_MAX_QP (V4L2_CID_MPEG_MFC_BASE + 166)
+#define V4L2_CID_MPEG_VIDEO_VP9_I_FRAME_QP (V4L2_CID_MPEG_MFC_BASE + 167)
+#define V4L2_CID_MPEG_VIDEO_VP9_P_FRAME_QP (V4L2_CID_MPEG_MFC_BASE + 168)
+#define V4L2_CID_MPEG_VIDEO_VP9_GOLDEN_FRAMESEL (V4L2_CID_MPEG_MFC_BASE + 169)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_VP9_GF_REFRESH_PERIOD (V4L2_CID_MPEG_MFC_BASE + 170)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHY_QP_ENABLE (V4L2_CID_MPEG_MFC_BASE + 171)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_MFC_BASE + 172)
+#define V4L2_CID_MPEG_VIDEO_VP9_REF_NUMBER_FOR_PFRAMES (V4L2_CID_MPEG_MFC_BASE + 173)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER (V4L2_CID_MPEG_MFC_BASE + 174)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH (V4L2_CID_MPEG_MFC_BASE + 175)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT0 (V4L2_CID_MPEG_MFC_BASE + 176)
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT1 (V4L2_CID_MPEG_MFC_BASE + 177)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT2 (V4L2_CID_MPEG_MFC_BASE + 178)
+#define V4L2_CID_MPEG_VIDEO_VP9_MAX_PARTITION_DEPTH (V4L2_CID_MPEG_MFC_BASE + 179)
+#define V4L2_CID_MPEG_VIDEO_VP9_DISABLE_INTRA_PU_SPLIT (V4L2_CID_MPEG_MFC_BASE + 180)
+#define V4L2_CID_MPEG_VIDEO_DISABLE_IVF_HEADER (V4L2_CID_MPEG_MFC_BASE + 181)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_ROI_CONTROL (V4L2_CID_MPEG_MFC_BASE + 190)
+#define V4L2_CID_MPEG_VIDEO_ROI_ENABLE (V4L2_CID_MPEG_MFC_BASE + 191)
+#define V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE (V4L2_CID_MPEG_MFC_BASE + 192)
+#define V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER (V4L2_CID_MPEG_MFC_BASE + 193)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_BLACK_BAR_DETECT (V4L2_CID_MPEG_MFC_BASE + 194)
+#define V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR (V4L2_CID_MPEG_MFC_BASE + 195)
+#define V4L2_CID_MPEG_VIDEO_WEIGHTED_ENABLE (V4L2_CID_MPEG_MFC_BASE + 196)
+#define V4L2_CID_MPEG_VIDEO_YSUM (V4L2_CID_MPEG_MFC_BASE + 197)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA (V4L2_CID_MPEG_MFC_BASE + 198)
+#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P (V4L2_CID_MPEG_MFC_BASE + 201)
+#define V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P (V4L2_CID_MPEG_MFC_BASE + 202)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P (V4L2_CID_MPEG_MFC_BASE + 203)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P (V4L2_CID_MPEG_MFC_BASE + 204)
+#define V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P (V4L2_CID_MPEG_MFC_BASE + 205)
+#define V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P (V4L2_CID_MPEG_MFC_BASE + 206)
+#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P (V4L2_CID_MPEG_MFC_BASE + 207)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P (V4L2_CID_MPEG_MFC_BASE + 208)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P (V4L2_CID_MPEG_MFC_BASE + 209)
+#define V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P (V4L2_CID_MPEG_MFC_BASE + 210)
+#define V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P (V4L2_CID_MPEG_MFC_BASE + 211)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P (V4L2_CID_MPEG_MFC_BASE + 212)
+#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B (V4L2_CID_MPEG_MFC_BASE + 213)
+#define V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B (V4L2_CID_MPEG_MFC_BASE + 214)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B (V4L2_CID_MPEG_MFC_BASE + 215)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B (V4L2_CID_MPEG_MFC_BASE + 216)
+#define V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B (V4L2_CID_MPEG_MFC_BASE + 217)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B (V4L2_CID_MPEG_MFC_BASE + 218)
+#define V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT (V4L2_CID_MPEG_MFC_BASE + 219)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT (V4L2_CID_MPEG_MFC_BASE + 220)
+#define V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE (V4L2_CID_MPEG_MFC_BASE + 221)
+#define V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE (V4L2_CID_MPEG_MFC_BASE + 222)
+#define V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS (V4L2_CID_MPEG_MFC_BASE + 223)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_FORMAT (V4L2_CID_MPEG_MFC_BASE + 224)
+#define V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT (V4L2_CID_MPEG_MFC_BASE + 225)
+#define V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0 (V4L2_CID_MPEG_MFC_BASE + 226)
+#define V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1 (V4L2_CID_MPEG_MFC_BASE + 227)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2 (V4L2_CID_MPEG_MFC_BASE + 228)
+#define V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG (V4L2_CID_MPEG_MFC_BASE + 229)
+#define V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES (V4L2_CID_MPEG_MFC_BASE + 230)
+#define V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS (V4L2_CID_MPEG_MFC_BASE + 231)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#endif
diff --git a/exynos/libvideocodec/osal/ExynosVideo_OSAL.c b/exynos/libvideocodec/osal/ExynosVideo_OSAL.c
new file mode 100755 (executable)
index 0000000..275e1f3
--- /dev/null
@@ -0,0 +1,1997 @@
+/*
+ *
+ * Copyright 2016 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file    ExynosVideo_OSAL.c
+ * @brief   ExynosVideo OSAL
+ * @author  SeungBeom Kim (sbcrux.kim@samsung.com)
+ *          Taehwan Kim   (t_h.kim@samsung.com)
+ * @version    1.0.0
+ * @history
+ *   2016.01.07 : Create
+ */
+
+#include <string.h>
+#include <sys/mman.h>
+
+#include "ExynosVideo_OSAL.h"
+#include "ExynosVideo_OSAL_Dec.h"
+#include "ExynosVideo_OSAL_Enc.h"
+
+#include "ExynosVideoDec.h"
+#include "ExynosVideoEnc.h"
+
+/* #define LOG_NDEBUG 0 */
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "ExynosVideoOSAL"
+
+#define GET_16BIT_HIGH(x)    ((x >> 16) & 0xFFFF)
+#define GET_16BIT_LOW(x)      (x & 0xFFFF)
+
+static struct {
+    int primaries;
+    int transfer;
+    int coeff;
+} ColorSpaceToColorAspects[] =
+{
+    {PRIMARIES_UNSPECIFIED, TRANSFER_UNSPECIFIED, MATRIX_COEFF_UNSPECIFIED},   /* Unknown */
+    {PRIMARIES_BT601_6_525, TRANSFER_SMPTE_170M,  MATRIX_COEFF_SMPTE170M},     /* Rec. ITU-R BT.601-7 */
+    {PRIMARIES_BT709_5,     TRANSFER_SMPTE_170M,  MATRIX_COEFF_REC709},        /* Rec. ITU-R BT.709-6 */
+    {PRIMARIES_BT601_6_525, TRANSFER_SMPTE_170M,  MATRIX_COEFF_SMPTE170M},     /* SMPTE-170 */
+    {PRIMARIES_BT601_6_525, TRANSFER_SMPTE_240M,  MATRIX_COEFF_SMPTE240M},     /* SMPTE-240 */
+    {PRIMARIES_BT2020,      TRANSFER_SMPTE_170M,  MATRIX_COEFF_BT2020},        /* Rec. ITU-R BT.2020-2 */
+    {PRIMARIES_RESERVED,    TRANSFER_RESERVED,    MATRIX_COEFF_IDENTITY},      /* Reserved */
+    {PRIMARIES_RESERVED,    TRANSFER_SMPTE_170M,  MATRIX_COEFF_REC709},        /* sRGB (IEC 61966-2-1) */
+};
+
+int Codec_OSAL_VideoMemoryToSystemMemory(
+    ExynosVideoMemoryType eMemoryType)
+{
+    if (eMemoryType == VIDEO_MEMORY_DMABUF)
+        return V4L2_MEMORY_DMABUF;
+
+    if (eMemoryType == VIDEO_MEMORY_USERPTR)
+        return V4L2_MEMORY_USERPTR;
+
+    return V4L2_MEMORY_MMAP;
+}
+
+unsigned int Codec_OSAL_CodingTypeToCompressdFormat(
+    ExynosVideoCodingType eCodingType)
+{
+    unsigned int nCompressdFormat = V4L2_PIX_FMT_H264;
+
+    switch (eCodingType) {
+    case VIDEO_CODING_AVC:
+        nCompressdFormat = V4L2_PIX_FMT_H264;
+        break;
+    case VIDEO_CODING_MPEG4:
+        nCompressdFormat = V4L2_PIX_FMT_MPEG4;
+        break;
+    case VIDEO_CODING_VP8:
+        nCompressdFormat = V4L2_PIX_FMT_VP8;
+        break;
+    case VIDEO_CODING_H263:
+        nCompressdFormat = V4L2_PIX_FMT_H263;
+        break;
+    case VIDEO_CODING_VC1:
+        nCompressdFormat = V4L2_PIX_FMT_VC1_ANNEX_G;
+        break;
+    case VIDEO_CODING_VC1_RCV:
+        nCompressdFormat = V4L2_PIX_FMT_VC1_ANNEX_L;
+        break;
+    case VIDEO_CODING_MPEG2:
+        nCompressdFormat = V4L2_PIX_FMT_MPEG2;
+        break;
+    case VIDEO_CODING_HEVC:
+        nCompressdFormat = V4L2_PIX_FMT_HEVC;
+        break;
+    case VIDEO_CODING_VP9:
+        nCompressdFormat = V4L2_PIX_FMT_VP9;
+        break;
+    default:
+        nCompressdFormat = V4L2_PIX_FMT_H264;
+        break;
+    }
+
+    return nCompressdFormat;
+}
+
+ExynosVideoColorFormatType Codec_OSAL_PixelFormatToColorFormat(
+    unsigned int nPixelFormat)
+{
+    ExynosVideoColorFormatType eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
+
+    switch (nPixelFormat) {
+    case V4L2_PIX_FMT_NV12M:
+        eColorFormat = VIDEO_COLORFORMAT_NV12M;
+        break;
+    case V4L2_PIX_FMT_NV12M_S10B:
+        eColorFormat = VIDEO_COLORFORMAT_NV12M_S10B;
+        break;
+    case V4L2_PIX_FMT_NV12M_P010:
+        eColorFormat = VIDEO_COLORFORMAT_NV12M_P010;
+        break;
+    case V4L2_PIX_FMT_NV21M:
+        eColorFormat = VIDEO_COLORFORMAT_NV21M;
+        break;
+    case V4L2_PIX_FMT_NV21M_S10B:
+        eColorFormat = VIDEO_COLORFORMAT_NV21M_S10B;
+        break;
+    case V4L2_PIX_FMT_NV21M_P010:
+        eColorFormat = VIDEO_COLORFORMAT_NV21M_P010;
+        break;
+    case V4L2_PIX_FMT_YUV420M:
+        eColorFormat = VIDEO_COLORFORMAT_I420M;
+        break;
+    case V4L2_PIX_FMT_YVU420M:
+        eColorFormat = VIDEO_COLORFORMAT_YV12M;
+        break;
+#ifdef USE_SINGLE_PALNE_SUPPORT
+    case V4L2_PIX_FMT_NV12N:
+        eColorFormat = VIDEO_COLORFORMAT_NV12;
+        break;
+    case V4L2_PIX_FMT_NV12N_10B:
+        eColorFormat = VIDEO_COLORFORMAT_NV12_S10B;
+        break;
+    case V4L2_PIX_FMT_YUV420N:
+        eColorFormat = VIDEO_COLORFORMAT_I420;
+        break;
+    case V4L2_PIX_FMT_NV12NT:
+        eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
+        break;
+#endif
+    case V4L2_PIX_FMT_ARGB32:
+        eColorFormat = VIDEO_COLORFORMAT_ARGB8888;
+        break;
+    case V4L2_PIX_FMT_BGR32:
+        eColorFormat = VIDEO_COLORFORMAT_BGRA8888;
+        break;
+    case V4L2_PIX_FMT_RGB32X:
+        eColorFormat = VIDEO_COLORFORMAT_RGBA8888;
+        break;
+    case V4L2_PIX_FMT_NV12MT:
+    case V4L2_PIX_FMT_NV12MT_16X16:
+    default:
+        eColorFormat = VIDEO_COLORFORMAT_NV12M_TILED;
+        break;
+    }
+
+    return eColorFormat;
+}
+
+unsigned int Codec_OSAL_ColorFormatToPixelFormat(
+    ExynosVideoColorFormatType  eColorFormat,
+    int                         nHwVersion)
+{
+    unsigned int nPixelFormat = V4L2_PIX_FMT_NV12M;
+
+    switch (eColorFormat) {
+    case VIDEO_COLORFORMAT_NV12M:
+        nPixelFormat = V4L2_PIX_FMT_NV12M;
+        break;
+    case VIDEO_COLORFORMAT_NV12M_S10B:
+        nPixelFormat = V4L2_PIX_FMT_NV12M_S10B;
+        break;
+    case VIDEO_COLORFORMAT_NV12M_P010:
+        nPixelFormat = V4L2_PIX_FMT_NV12M_P010;
+        break;
+    case VIDEO_COLORFORMAT_NV21M:
+        nPixelFormat = V4L2_PIX_FMT_NV21M;
+        break;
+    case VIDEO_COLORFORMAT_NV21M_S10B:
+        nPixelFormat = V4L2_PIX_FMT_NV21M_S10B;
+        break;
+    case VIDEO_COLORFORMAT_NV21M_P010:
+        nPixelFormat = V4L2_PIX_FMT_NV21M_P010;
+        break;
+    case VIDEO_COLORFORMAT_I420M:
+        nPixelFormat = V4L2_PIX_FMT_YUV420M;
+        break;
+    case VIDEO_COLORFORMAT_YV12M:
+        nPixelFormat = V4L2_PIX_FMT_YVU420M;
+        break;
+#ifdef USE_SINGLE_PALNE_SUPPORT
+    case VIDEO_COLORFORMAT_NV12:
+        nPixelFormat = V4L2_PIX_FMT_NV12N;
+        break;
+    case VIDEO_COLORFORMAT_NV12_S10B:
+        nPixelFormat = V4L2_PIX_FMT_NV12N_10B;
+        break;
+    case VIDEO_COLORFORMAT_I420:
+        nPixelFormat = V4L2_PIX_FMT_YUV420N;
+        break;
+    case VIDEO_COLORFORMAT_NV12_TILED:
+        nPixelFormat = V4L2_PIX_FMT_NV12NT;
+        break;
+#endif
+    case VIDEO_COLORFORMAT_ARGB8888:
+        nPixelFormat = V4L2_PIX_FMT_ARGB32;
+        break;
+    case VIDEO_COLORFORMAT_BGRA8888:
+        nPixelFormat = V4L2_PIX_FMT_BGR32;
+        break;
+    case VIDEO_COLORFORMAT_RGBA8888:
+        nPixelFormat = V4L2_PIX_FMT_RGB32X;
+        break;
+    case VIDEO_COLORFORMAT_NV12M_TILED:
+        if (nHwVersion == (int)MFC_51)
+            nPixelFormat = V4L2_PIX_FMT_NV12MT;
+        else
+            nPixelFormat = V4L2_PIX_FMT_NV12MT_16X16;
+        break;
+    default:
+        nPixelFormat = V4L2_PIX_FMT_NV12M;
+        break;
+    }
+
+    return nPixelFormat;
+}
+
+int Codec_OSAL_DevOpen(
+    const char              *sDevName,
+    int                      nFlag,
+    CodecOSALVideoContext   *pCtx)
+{
+    if ((sDevName != NULL) &&
+        (pCtx != NULL)) {
+        pCtx->videoCtx.hDevice = exynos_v4l2_open_devname(sDevName, nFlag, 0);
+        return pCtx->videoCtx.hDevice;
+    }
+
+    return -1;
+}
+
+void Codec_OSAL_DevClose(CodecOSALVideoContext *pCtx)
+{
+    if ((pCtx != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        exynos_v4l2_close(pCtx->videoCtx.hDevice);
+    }
+
+    return;
+}
+
+int Codec_OSAL_QueryCap(CodecOSALVideoContext *pCtx)
+{
+    int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING);
+
+    if ((pCtx != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        if (exynos_v4l2_querycap(pCtx->videoCtx.hDevice, needCaps))
+            return 0;
+    }
+
+    return -1;
+}
+
+int Codec_OSAL_EnqueueBuf(
+    CodecOSALVideoContext   *pCtx,
+    CodecOSAL_Buffer        *pBuf)
+{
+    if ((pCtx != NULL) &&
+        (pBuf != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        struct v4l2_buffer  buf;
+        struct v4l2_plane   planes[VIDEO_BUFFER_MAX_PLANES];
+        int i;
+
+        memset(&buf, 0, sizeof(buf));
+        memset(&planes, 0, sizeof(planes));
+
+        buf.type        = pBuf->type;
+        buf.m.planes    = planes;
+        buf.length      = pBuf->nPlane;
+        buf.memory      = pBuf->memory;
+        buf.index       = pBuf->index;
+
+        if (pCtx->videoCtx.bShareInbuf == VIDEO_TRUE) {
+            for (i = 0; i < pBuf->nPlane; i++) {
+                if ((unsigned int)buf.memory == (unsigned int)CODEC_OSAL_MEM_TYPE_USERPTR)
+                    buf.m.planes[i].m.userptr = (unsigned long)pBuf->planes[i].addr;
+                else
+                    buf.m.planes[i].m.fd = (int)(unsigned long)pBuf->planes[i].addr;
+
+                buf.m.planes[i].length      = pBuf->planes[i].bufferSize;
+                buf.m.planes[i].bytesused   = pBuf->planes[i].dataLen;
+                buf.m.planes[i].data_offset = 0;
+            }
+        } else {
+            for (i = 0; i < pBuf->nPlane; i++) {
+                buf.m.planes[i].bytesused   = pBuf->planes[i].dataLen;
+                buf.m.planes[i].data_offset = 0;
+            }
+        }
+#ifdef USE_ORIGINAL_HEADER
+        buf.reserved2 = pBuf->flags;
+#else
+        buf.input = pBuf->flags;
+#endif
+        memcpy(&(buf.timestamp), &(pBuf->timestamp), sizeof(struct timeval));
+
+        return exynos_v4l2_qbuf(pCtx->videoCtx.hDevice, &buf);
+    }
+
+    return -1;
+}
+
+int Codec_OSAL_DequeueBuf(
+    CodecOSALVideoContext   *pCtx,
+    CodecOSAL_Buffer        *pBuf)
+{
+    if ((pCtx != NULL) &&
+        (pBuf != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        struct v4l2_buffer  buf;
+        struct v4l2_plane   planes[VIDEO_BUFFER_MAX_PLANES];
+        int i;
+
+        memset(&buf, 0, sizeof(buf));
+        memset(&planes, 0, sizeof(planes));
+
+        buf.type        = pBuf->type;
+        buf.m.planes    = planes;
+        buf.length      = pBuf->nPlane;
+        buf.memory      = pBuf->memory;
+
+        if (exynos_v4l2_dqbuf(pCtx->videoCtx.hDevice, &buf) == 0) {
+            pBuf->index     = buf.index;
+#ifdef USE_ORIGINAL_HEADER
+            pBuf->flags     = buf.reserved2;
+#else
+            pBuf->flags     = buf.input;
+#endif
+            pBuf->field     = buf.field;
+            pBuf->timestamp = buf.timestamp;
+
+            for (i = 0; i < pBuf->nPlane; i++)
+                pBuf->planes[i].dataLen = buf.m.planes[i].bytesused;
+
+            switch (buf.flags & (0x7 << 3)) {
+            case V4L2_BUF_FLAG_KEYFRAME:
+                pBuf->frameType = VIDEO_FRAME_I;
+                break;
+            case V4L2_BUF_FLAG_PFRAME:
+                pBuf->frameType = VIDEO_FRAME_P;
+                break;
+            case V4L2_BUF_FLAG_BFRAME:
+                pBuf->frameType = VIDEO_FRAME_B;
+                break;
+            default:
+                pBuf->frameType = VIDEO_FRAME_OTHERS;
+                break;
+            };
+
+            if (buf.flags & V4L2_BUF_FLAG_ERROR)
+                pBuf->frameType |= VIDEO_FRAME_CORRUPT;
+
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+int Codec_OSAL_GetControls(
+    CodecOSALVideoContext   *pCtx,
+    unsigned int             nCID,
+    void                    *pInfo)
+{
+    int ret = -1;
+
+    if ((pCtx != NULL) &&
+        (pInfo != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        ret = 0;
+
+        switch (nCID) {
+        case CODEC_OSAL_CID_DEC_SEI_INFO:
+        {
+            ExynosVideoFramePacking *pFramePacking = (ExynosVideoFramePacking *)pInfo;
+
+            struct v4l2_ext_control  ext_ctrl[FRAME_PACK_SEI_INFO_NUM];
+            struct v4l2_ext_controls ext_ctrls;
+
+            int seiAvailable, seiInfo, seiGridPos, i;
+            unsigned int seiArgmtId;
+
+            memset(pFramePacking, 0, sizeof(*pFramePacking));
+            memset(ext_ctrl, 0, sizeof(ext_ctrl));
+
+            ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+            ext_ctrls.count = FRAME_PACK_SEI_INFO_NUM;
+            ext_ctrls.controls = ext_ctrl;
+            ext_ctrl[0].id =  V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL;
+            ext_ctrl[1].id =  V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID;
+            ext_ctrl[2].id =  V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO;
+            ext_ctrl[3].id =  V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS;
+
+            if (exynos_v4l2_g_ext_ctrl(pCtx->videoCtx.hDevice, &ext_ctrls) != 0) {
+                ret = -1;
+                goto EXIT;
+            }
+
+            seiAvailable = ext_ctrl[0].value;
+            seiArgmtId   = ext_ctrl[1].value;
+            seiInfo      = ext_ctrl[2].value;
+            seiGridPos   = ext_ctrl[3].value;
+
+            pFramePacking->available = seiAvailable;
+            pFramePacking->arrangement_id = seiArgmtId;
+
+            pFramePacking->arrangement_cancel_flag = OPERATE_BIT(seiInfo, 0x1, 0);
+            pFramePacking->arrangement_type = OPERATE_BIT(seiInfo, 0x3f, 1);
+            pFramePacking->quincunx_sampling_flag = OPERATE_BIT(seiInfo, 0x1, 8);
+            pFramePacking->content_interpretation_type = OPERATE_BIT(seiInfo, 0x3f, 9);
+            pFramePacking->spatial_flipping_flag = OPERATE_BIT(seiInfo, 0x1, 15);
+            pFramePacking->frame0_flipped_flag = OPERATE_BIT(seiInfo, 0x1, 16);
+            pFramePacking->field_views_flag = OPERATE_BIT(seiInfo, 0x1, 17);
+            pFramePacking->current_frame_is_frame0_flag = OPERATE_BIT(seiInfo, 0x1, 18);
+
+            pFramePacking->frame0_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 0);
+            pFramePacking->frame0_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 4);
+            pFramePacking->frame1_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 8);
+            pFramePacking->frame1_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 12);
+        }
+            break;
+        case CODEC_OSAL_CID_DEC_HDR_INFO:
+        {
+            ExynosVideoHdrInfo *pHdrInfo = (ExynosVideoHdrInfo *)pInfo;
+
+            struct v4l2_ext_control     ext_ctrl[HDR_INFO_NUM];
+            struct v4l2_ext_controls    ext_ctrls;
+
+            int infoType = pHdrInfo->eChangedType;
+            int i = 0;
+
+            memset(ext_ctrl, 0, (sizeof(struct v4l2_ext_control) * HDR_INFO_NUM));
+            ext_ctrls.ctrl_class    = V4L2_CTRL_CLASS_MPEG;
+            ext_ctrls.controls      = ext_ctrl;
+
+            if (infoType & HDR_INFO_LIGHT) {
+                ext_ctrl[i].id      = V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT;
+                ext_ctrl[i + 1].id  = V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT;
+                i += 2;
+                pHdrInfo->eValidType |= HDR_INFO_LIGHT;
+            }
+
+            if (infoType & HDR_INFO_LUMINANCE) {
+                ext_ctrl[i].id       = V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE;
+                ext_ctrl[i + 1].id   = V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE;
+                ext_ctrl[i + 2].id   = V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT;
+                ext_ctrl[i + 3].id   = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0;
+                ext_ctrl[i + 4].id   = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1;
+                ext_ctrl[i + 5].id   = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2;
+                i += 6;
+                pHdrInfo->eValidType |= HDR_INFO_LUMINANCE;
+            }
+
+            if (infoType & HDR_INFO_COLOR_ASPECTS) {
+                if (pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_VP9) {
+                    ext_ctrl[i].id          = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES;
+                    i++;
+                } else {
+                    ext_ctrl[i].id          = V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS;
+                    ext_ctrl[i + 1].id      = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES;
+                    ext_ctrl[i + 2].id      = V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS;
+                    i += 3;
+                }
+                pHdrInfo->eValidType |= HDR_INFO_COLOR_ASPECTS;
+            } else if (infoType & HDR_INFO_MATRIX_COEFF_ONLY) {
+                ext_ctrl[i].id      = V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS;
+                i++;
+                pHdrInfo->eValidType |= HDR_INFO_MATRIX_COEFF_ONLY;
+            }
+
+            if (infoType & HDR_INFO_RANGE) {
+                ext_ctrl[i].id      = V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG;
+                i++;
+                pHdrInfo->eValidType |= HDR_INFO_RANGE;
+            }
+
+            ext_ctrls.count = i;
+
+            if (exynos_v4l2_g_ext_ctrl(pCtx->videoCtx.hDevice, &ext_ctrls) != 0) {
+                ret = VIDEO_ERROR_APIFAIL;
+                goto EXIT;
+            }
+
+            i = 0;
+            pHdrInfo->eChangedType = HDR_INFO_NO_CHANGES;
+            /* eType will be set when value is changed */
+            if (infoType & HDR_INFO_LIGHT) {
+                if ((pHdrInfo->sHdrStatic.max_pic_average_light != ext_ctrl[i].value) ||
+                    (pHdrInfo->sHdrStatic.max_content_light != ext_ctrl[i + 1].value)) {
+                    pHdrInfo->eChangedType = HDR_INFO_LIGHT;
+                }
+
+                pHdrInfo->sHdrStatic.max_pic_average_light = ext_ctrl[i].value;
+                pHdrInfo->sHdrStatic.max_content_light     = ext_ctrl[i + 1].value;
+                i += 2;
+            }
+
+            if (infoType & HDR_INFO_LUMINANCE) {
+                if ((pHdrInfo->sHdrStatic.max_display_luminance != ext_ctrl[i].value) ||
+                    (pHdrInfo->sHdrStatic.min_display_luminance != ext_ctrl[i + 1].value)   ||
+                    (pHdrInfo->sHdrStatic.white.x != GET_16BIT_HIGH(ext_ctrl[i + 2].value)) ||
+                    (pHdrInfo->sHdrStatic.white.y != GET_16BIT_LOW(ext_ctrl[i + 2].value))  ||
+                    (pHdrInfo->sHdrStatic.red.x   != GET_16BIT_HIGH(ext_ctrl[i + 3].value)) ||
+                    (pHdrInfo->sHdrStatic.red.y   != GET_16BIT_LOW(ext_ctrl[i + 3].value))  ||
+                    (pHdrInfo->sHdrStatic.green.x != GET_16BIT_HIGH(ext_ctrl[i + 4].value)) ||
+                    (pHdrInfo->sHdrStatic.green.y != GET_16BIT_LOW(ext_ctrl[i + 4].value))  ||
+                    (pHdrInfo->sHdrStatic.blue.x  != GET_16BIT_HIGH(ext_ctrl[i + 5].value)) ||
+                    (pHdrInfo->sHdrStatic.blue.y  != GET_16BIT_LOW(ext_ctrl[i + 5].value))) {
+                    pHdrInfo->eChangedType |= HDR_INFO_LUMINANCE;
+                }
+
+                pHdrInfo->sHdrStatic.max_display_luminance  = ext_ctrl[i].value;
+                pHdrInfo->sHdrStatic.min_display_luminance  = ext_ctrl[i + 1].value;
+                pHdrInfo->sHdrStatic.white.x                = GET_16BIT_HIGH(ext_ctrl[i + 2].value); /* [31:16] */
+                pHdrInfo->sHdrStatic.white.y                = GET_16BIT_LOW(ext_ctrl[i + 2].value);  /* [15:0]  */
+                pHdrInfo->sHdrStatic.red.x                  = GET_16BIT_HIGH(ext_ctrl[i + 3].value);
+                pHdrInfo->sHdrStatic.red.y                  = GET_16BIT_LOW(ext_ctrl[i + 3].value);
+                pHdrInfo->sHdrStatic.green.x                = GET_16BIT_HIGH(ext_ctrl[i + 4].value);
+                pHdrInfo->sHdrStatic.green.y                = GET_16BIT_LOW(ext_ctrl[i + 4].value);
+                pHdrInfo->sHdrStatic.blue.x                 = GET_16BIT_HIGH(ext_ctrl[i + 5].value);
+                pHdrInfo->sHdrStatic.blue.y                 = GET_16BIT_LOW(ext_ctrl[i + 5].value);
+                i += 6;
+            }
+
+            if (infoType & HDR_INFO_COLOR_ASPECTS) {
+                if (pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_VP9) {
+                    if (((int)pHdrInfo->sColorAspects.eCoeffType != ColorSpaceToColorAspects[ext_ctrl[i].value].coeff) ||
+                        ((int)pHdrInfo->sColorAspects.ePrimariesType != ColorSpaceToColorAspects[ext_ctrl[i].value].primaries) ||
+                        ((int)pHdrInfo->sColorAspects.eTransferType != ColorSpaceToColorAspects[ext_ctrl[i].value].transfer)) {
+                        pHdrInfo->eChangedType |= HDR_INFO_COLOR_ASPECTS;
+                    }
+
+                    pHdrInfo->sColorAspects.eCoeffType     = (ExynosMatrixCoeffType)ColorSpaceToColorAspects[ext_ctrl[i].value].coeff;
+                    pHdrInfo->sColorAspects.ePrimariesType = (ExynosPrimariesType)ColorSpaceToColorAspects[ext_ctrl[i].value].primaries;
+                    pHdrInfo->sColorAspects.eTransferType  = (ExynosTransferType)ColorSpaceToColorAspects[ext_ctrl[i].value].transfer;
+                    i++;
+                } else {
+                    if (((int)pHdrInfo->sColorAspects.eCoeffType != ext_ctrl[i].value) ||
+                        ((int)pHdrInfo->sColorAspects.ePrimariesType != ext_ctrl[i + 1].value) ||
+                        ((int)pHdrInfo->sColorAspects.eTransferType  != ext_ctrl[i + 2].value)) {
+                        pHdrInfo->eChangedType |= HDR_INFO_COLOR_ASPECTS;
+                    }
+
+                    pHdrInfo->sColorAspects.eCoeffType     = (ExynosMatrixCoeffType)ext_ctrl[i].value;
+                    pHdrInfo->sColorAspects.ePrimariesType = (ExynosPrimariesType)ext_ctrl[i + 1].value;
+                    pHdrInfo->sColorAspects.eTransferType  = (ExynosTransferType)ext_ctrl[i + 2].value;
+                    i += 3;
+                }
+            } else if (infoType & HDR_INFO_MATRIX_COEFF_ONLY) {
+                if ((int)pHdrInfo->sColorAspects.eCoeffType != ext_ctrl[i].value) {
+                    pHdrInfo->eChangedType |= HDR_INFO_MATRIX_COEFF_ONLY;
+                }
+
+                pHdrInfo->sColorAspects.eCoeffType  = (ExynosMatrixCoeffType)ext_ctrl[i].value;
+                i++;
+            }
+
+            if (infoType & HDR_INFO_RANGE) {
+                ExynosRangeType eRangeType = RANGE_UNSPECIFIED;
+
+                if (pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_VP9) {
+                    eRangeType = (ExynosRangeType)((ext_ctrl[i].value == 0)? RANGE_LIMITED:RANGE_FULL);
+                } else {
+                    eRangeType = (ExynosRangeType)ext_ctrl[i].value;
+                }
+
+                if (pHdrInfo->sColorAspects.eRangeType != eRangeType) {
+                    pHdrInfo->eChangedType |= HDR_INFO_RANGE;
+                }
+
+                pHdrInfo->sColorAspects.eRangeType = eRangeType;
+                i++;
+            }
+        }
+            break;
+        default:
+        {
+            ALOGE("%s: unsupported type(%x)", __FUNCTION__, nCID);
+            ret = -1;
+        }
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+int Codec_OSAL_SetControls(
+    CodecOSALVideoContext   *pCtx,
+    unsigned int             nCID,
+    void                    *pInfo)
+{
+    int ret = -1;
+
+    if ((pCtx != NULL) &&
+        (pInfo != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        ret = 0;
+
+        switch (nCID) {
+        case CODEC_OSAL_CID_ENC_SET_PARAMS:
+        {
+            ExynosVideoEncParam         *pEncParam      = (ExynosVideoEncParam *)pInfo;
+            ExynosVideoEncInitParam     *pInitParam     = &pEncParam->initParam;
+            ExynosVideoEncCommonParam   *pCommonParam   = &pEncParam->commonParam;
+
+            int i;
+            struct v4l2_ext_control  ext_ctrl[MAX_CTRL_NUM];
+            struct v4l2_ext_controls ext_ctrls;
+
+            /* common parameters */
+            ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
+            ext_ctrl[0].value = pCommonParam->IDRPeriod;
+            ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
+
+            if ((pCtx->videoCtx.instInfo.supportInfo.enc.bFixedSliceSupport == VIDEO_TRUE) &&
+                (pCommonParam->bFixedSlice == VIDEO_TRUE) &&
+                (pCommonParam->SliceMode != 0)) {
+                ext_ctrl[1].value = 4;  /* fixed bytes */
+            } else {
+                ext_ctrl[1].value = pCommonParam->SliceMode;  /* 0: one, 1: fixed #mb, 2: fixed #bytes */
+            }
+            ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB;
+            ext_ctrl[2].value = pCommonParam->RandomIntraMBRefresh;
+            ext_ctrl[3].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING;
+            ext_ctrl[3].value = pCommonParam->PadControlOn;
+            ext_ctrl[4].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV;
+            ext_ctrl[4].value = pCommonParam->CrPadVal;
+            ext_ctrl[4].value |= (pCommonParam->CbPadVal << 8);
+            ext_ctrl[4].value |= (pCommonParam->LumaPadVal << 16);
+            ext_ctrl[5].id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
+            ext_ctrl[5].value = pCommonParam->EnableFRMRateControl;
+            ext_ctrl[6].id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE;
+            ext_ctrl[6].value = pCommonParam->EnableMBRateControl;
+            ext_ctrl[7].id = V4L2_CID_MPEG_VIDEO_BITRATE;
+
+            /* FIXME temporary fix */
+            if (pCommonParam->Bitrate)
+                ext_ctrl[7].value = pCommonParam->Bitrate;
+            else
+                ext_ctrl[7].value = 1; /* just for testing Movie studio */
+
+            /* codec specific parameters */
+            switch (pEncParam->eCompressionFormat) {
+            case VIDEO_CODING_AVC:
+            {
+                ExynosVideoEncH264Param *pH264Param = &pEncParam->codecParam.h264;
+
+                /* common parameters but id is depends on codec */
+                ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
+                ext_ctrl[8].value = pCommonParam->FrameQp;
+                ext_ctrl[9].id =  V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
+                ext_ctrl[9].value = pCommonParam->FrameQp_P;
+                ext_ctrl[10].id =  V4L2_CID_MPEG_VIDEO_H264_MAX_QP;  /* QP range : I frame */
+                ext_ctrl[10].value = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMax_I);
+                ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
+                ext_ctrl[11].value = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMin_I);
+                ext_ctrl[12].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
+                ext_ctrl[12].value = pCommonParam->CBRPeriodRf;
+
+                /* H.264 specific parameters */
+                switch (pCommonParam->SliceMode) {
+                case 0:
+                    ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
+                    ext_ctrl[13].value = 1;  /* default */
+                    ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
+                    ext_ctrl[14].value = 2800; /* based on MFC6.x */
+                    break;
+                case 1:
+                    ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
+                    ext_ctrl[13].value = pH264Param->SliceArgument;
+                    ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
+                    ext_ctrl[14].value = 2800; /* based on MFC6.x */
+                    break;
+                case 2:
+                    ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
+                    ext_ctrl[13].value = 1; /* default */
+                    ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
+                    ext_ctrl[14].value = pH264Param->SliceArgument;
+                    break;
+                default:
+                    break;
+                }
+
+                ext_ctrl[15].id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
+                ext_ctrl[15].value = pH264Param->ProfileIDC;
+                ext_ctrl[16].id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
+                ext_ctrl[16].value = pH264Param->LevelIDC;
+                ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P;
+                ext_ctrl[17].value = pH264Param->NumberRefForPframes;
+                /*
+                 * It should be set using h264Param->NumberBFrames after being handled by appl.
+                 */
+                ext_ctrl[18].id =  V4L2_CID_MPEG_VIDEO_B_FRAMES;
+                ext_ctrl[18].value = pH264Param->NumberBFrames;
+                ext_ctrl[19].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
+                ext_ctrl[19].value = pH264Param->LoopFilterDisable;
+                ext_ctrl[20].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
+                ext_ctrl[20].value = pH264Param->LoopFilterAlphaC0Offset;
+                ext_ctrl[21].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
+                ext_ctrl[21].value = pH264Param->LoopFilterBetaOffset;
+                ext_ctrl[22].id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
+                ext_ctrl[22].value = pH264Param->SymbolMode;
+                ext_ctrl[23].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE;
+                ext_ctrl[23].value = pH264Param->PictureInterlace;
+                ext_ctrl[24].id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM;
+                ext_ctrl[24].value = pH264Param->Transform8x8Mode;
+                ext_ctrl[25].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE;
+                ext_ctrl[25].value = pH264Param->FrameRate;
+                ext_ctrl[26].id =  V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
+                ext_ctrl[26].value = pH264Param->FrameQp_B;
+                ext_ctrl[27].id =  V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK;
+                ext_ctrl[27].value = pH264Param->DarkDisable;
+                ext_ctrl[28].id =  V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH;
+                ext_ctrl[28].value = pH264Param->SmoothDisable;
+                ext_ctrl[29].id =  V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC;
+                ext_ctrl[29].value = pH264Param->StaticDisable;
+                ext_ctrl[30].id =  V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY;
+                ext_ctrl[30].value = pH264Param->ActivityDisable;
+
+                /* doesn't have to be set */
+                ext_ctrl[31].id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE;
+                ext_ctrl[31].value = 1;
+                ext_ctrl[32].id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD;
+                ext_ctrl[32].value = 0;
+                ext_ctrl[33].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
+                ext_ctrl[33].value = 0;
+                ext_ctrl[34].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
+
+                if (pH264Param->HeaderWithIFrame == 0) {
+                    /* default */
+                    ext_ctrl[34].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;              /* 0: seperated header */
+                } else {
+                    ext_ctrl[34].value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME; /* 1: header + first frame */
+                }
+                ext_ctrl[35].id =  V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE;
+                ext_ctrl[35].value = pH264Param->SarEnable;
+                ext_ctrl[36].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC;
+                ext_ctrl[36].value = pH264Param->SarIndex;
+                ext_ctrl[37].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH;
+                ext_ctrl[37].value = pH264Param->SarWidth;
+                ext_ctrl[38].id =  V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT;
+                ext_ctrl[38].value = pH264Param->SarHeight;
+
+                /* Initial parameters : Frame Skip */
+                switch (pInitParam->FrameSkip) {
+                case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
+                    ext_ctrl[39].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[39].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
+                    break;
+                case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
+                    ext_ctrl[39].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[39].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
+                    break;
+                default:
+                    /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
+                    ext_ctrl[39].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[39].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
+                    break;
+                }
+
+                /* SVC is not supported yet */
+                ext_ctrl[40].id =  V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING;
+                ext_ctrl[40].value = 0;
+                switch (pH264Param->HierarType) {
+                case 1:
+                    ext_ctrl[41].id =  V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
+                    ext_ctrl[41].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B;
+                    break;
+                case 0:
+                default:
+                    ext_ctrl[41].id =  V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
+                    ext_ctrl[41].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P;
+                    break;
+                }
+                ext_ctrl[42].id =  V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER;
+                ext_ctrl[42].value = pH264Param->TemporalSVC.nTemporalLayerCount;
+                ext_ctrl[43].id =  V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
+                ext_ctrl[43].value = (0 << 16 | 29);
+                ext_ctrl[44].id =  V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
+                ext_ctrl[44].value = (1 << 16 | 29);
+                ext_ctrl[45].id =  V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
+                ext_ctrl[45].value = (2 << 16 | 29);
+
+                ext_ctrl[46].id =  V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING;
+                ext_ctrl[46].value = 0;
+                ext_ctrl[47].id =  V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0;
+                ext_ctrl[47].value = 0;
+                ext_ctrl[48].id =  V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE;
+                ext_ctrl[48].value = V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE;
+
+                /* FMO is not supported yet */
+                ext_ctrl[49].id =  V4L2_CID_MPEG_VIDEO_H264_FMO;
+                ext_ctrl[49].value = 0;
+                ext_ctrl[50].id =  V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE;
+                ext_ctrl[50].value = V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES;
+                ext_ctrl[51].id = V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP;
+                ext_ctrl[51].value = 4;
+                ext_ctrl[52].id =  V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
+                ext_ctrl[52].value = (0 << 30 | 0);
+                ext_ctrl[53].id =  V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
+                ext_ctrl[53].value = (1 << 30 | 0);
+                ext_ctrl[54].id =  V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
+                ext_ctrl[54].value = (2 << 30 | 0);
+                ext_ctrl[55].id =  V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
+                ext_ctrl[55].value = (3 << 30 | 0);
+                ext_ctrl[56].id =  V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION;
+                ext_ctrl[56].value = V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT;
+                ext_ctrl[57].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE;
+                ext_ctrl[57].value = 0;
+
+                /* ASO is not supported yet */
+                ext_ctrl[58].id =  V4L2_CID_MPEG_VIDEO_H264_ASO;
+                ext_ctrl[58].value = 0;
+                for (i = 0; i < 32; i++) {
+                    ext_ctrl[59 + i].id =  V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER;
+                    ext_ctrl[59 + i].value = (i << 16 | 0);
+                }
+                ext_ctrls.count = H264_CTRL_NUM;
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id          = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT0;
+                    ext_ctrl[i].value       = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[0];
+                    ext_ctrl[i + 1].id      = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT1;
+                    ext_ctrl[i + 1].value   = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[1];
+                    ext_ctrl[i + 2].id      = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT2;
+                    ext_ctrl[i + 2].value   = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[2];
+                    ext_ctrl[i + 3].id      = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT3;
+                    ext_ctrl[i + 3].value   = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[3];
+                    ext_ctrl[i + 4].id      = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT4;
+                    ext_ctrl[i + 4].value   = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[4];
+                    ext_ctrl[i + 5].id      = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT5;
+                    ext_ctrl[i + 5].value   = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[5];
+                    ext_ctrl[i + 6].id      = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT6;
+                    ext_ctrl[i + 6].value   = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[6];
+                    ext_ctrls.count += 7;
+                }
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bSkypeSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+
+                    /* VUI RESRICTION ENABLE */
+                    ext_ctrl[i].id          = V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE;
+                    ext_ctrl[i].value       = pH264Param->VuiRestrictionEnable;
+
+                    /* H264 LTR FRAMES (0: disable, LTRFrames > 0: enable) */
+                    ext_ctrl[i + 1].id      = V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR;
+                    ext_ctrl[i + 1].value   = pH264Param->LTRFrames;
+
+                    /* FRAME LEVEL QP ENABLE */
+                    ext_ctrl[i + 2].id      = V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE;
+                    ext_ctrl[i + 2].value   = pCommonParam->EnableFRMQpControl;
+
+                    /* CONFIG QP VALUE */
+                    ext_ctrl[i + 3].id      = V4L2_CID_MPEG_MFC_CONFIG_QP;
+                    ext_ctrl[i + 3].value   = pCommonParam->FrameQp;
+
+                    /* MAX LAYER COUNT for SHORT TERM */
+                    ext_ctrl[i + 4].id      = V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER;
+                    ext_ctrl[i + 4].value   = pH264Param->MaxTemporalLayerCount;
+
+                    ext_ctrls.count += 5;
+                }
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bRoiInfoSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id     = V4L2_CID_MPEG_VIDEO_ROI_ENABLE;
+                    ext_ctrl[i].value  = pH264Param->ROIEnable;
+
+                    ext_ctrls.count += 1;
+                }
+
+                /* optional : if these are not set, set value are same as I frame */
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id          = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P;  /* P frame */
+                    ext_ctrl[i].value       = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMin_P);
+                    ext_ctrl[i + 1].id      =  V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P;
+                    ext_ctrl[i + 1].value   = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMax_P);
+                    ext_ctrl[i + 2].id      = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B;  /* B frame */
+                    ext_ctrl[i + 2].value   = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMin_B);
+                    ext_ctrl[i + 3].id      =  V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B;
+                    ext_ctrl[i + 3].value   = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMax_B);
+
+                    ext_ctrls.count += 4;
+                }
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bPVCSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE;
+                    ext_ctrl[i].value = pCommonParam->PerceptualMode;
+
+                    ext_ctrls.count += 1;
+                }
+            }
+                break;
+            case VIDEO_CODING_MPEG4:
+            {
+                ExynosVideoEncMpeg4Param *pMpeg4Param = &pEncParam->codecParam.mpeg4;
+
+                /* common parameters but id is depends on codec */
+                ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP;
+                ext_ctrl[8].value = pCommonParam->FrameQp;
+                ext_ctrl[9].id =  V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP;
+                ext_ctrl[9].value = pCommonParam->FrameQp_P;
+                ext_ctrl[10].id =  V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP;  /* I frame */
+                ext_ctrl[10].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMax_I);
+                ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP;
+                ext_ctrl[11].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMin_I);
+                ext_ctrl[12].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
+                ext_ctrl[12].value = pCommonParam->CBRPeriodRf;
+
+                /* MPEG4 specific parameters */
+                switch (pCommonParam->SliceMode) {
+                case 0:
+                    ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
+                    ext_ctrl[13].value = 1;  /* default */
+                    ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
+                    ext_ctrl[14].value = 2800; /* based on MFC6.x */
+                    break;
+                case 1:
+                    ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
+                    ext_ctrl[13].value = pMpeg4Param->SliceArgument;
+                    ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
+                    ext_ctrl[14].value = 2800; /* based on MFC6.x */
+                    break;
+                case 2:
+                    ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
+                    ext_ctrl[13].value = 1; /* default */
+                    ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
+                    ext_ctrl[14].value = pMpeg4Param->SliceArgument;
+                    break;
+                default:
+                    break;
+                }
+
+                ext_ctrl[15].id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
+                ext_ctrl[15].value = pMpeg4Param->ProfileIDC;
+                ext_ctrl[16].id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
+                ext_ctrl[16].value = pMpeg4Param->LevelIDC;
+                ext_ctrl[17].id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL;
+                ext_ctrl[17].value = pMpeg4Param->DisableQpelME;
+
+                /*
+                 * It should be set using mpeg4Param->NumberBFrames after being handled by appl.
+                 */
+                ext_ctrl[18].id =  V4L2_CID_MPEG_VIDEO_B_FRAMES;
+                ext_ctrl[18].value = pMpeg4Param->NumberBFrames;
+
+                ext_ctrl[19].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES;
+                ext_ctrl[19].value = pMpeg4Param->TimeIncreamentRes;
+                ext_ctrl[20].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA;
+                ext_ctrl[20].value = pMpeg4Param->VopTimeIncreament;
+                ext_ctrl[21].id =  V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP;
+                ext_ctrl[21].value = pMpeg4Param->FrameQp_B;
+                ext_ctrl[22].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
+                ext_ctrl[22].value = 0;
+                ext_ctrl[23].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
+                ext_ctrl[23].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
+                ext_ctrl[24].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
+                ext_ctrl[24].value = 1;
+
+                /* Initial parameters : Frame Skip */
+                switch (pInitParam->FrameSkip) {
+                case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
+                    ext_ctrl[25].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[25].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
+                    break;
+                case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
+                    ext_ctrl[25].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[25].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
+                    break;
+                default:
+                    /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
+                    ext_ctrl[25].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[25].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
+                    break;
+                }
+                ext_ctrls.count = MPEG4_CTRL_NUM;
+
+                /* optional : if these are not set, set value are same as I frame */
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P;  /* P frame */
+                    ext_ctrl[i].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMin_P);
+                    ext_ctrl[i + 1].id =  V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P;
+                    ext_ctrl[i + 1].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMax_P);
+                    ext_ctrl[i + 2].id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B;  /* B frame */
+                    ext_ctrl[i + 2].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMin_B);
+                    ext_ctrl[i + 3].id =  V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B;
+                    ext_ctrl[i + 3].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMax_B);
+
+                    ext_ctrls.count += 4;
+                }
+            }
+                break;
+            case VIDEO_CODING_H263:
+            {
+                ExynosVideoEncH263Param *pH263Param = &pEncParam->codecParam.h263;
+
+                /* common parameters but id is depends on codec */
+                ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP;
+                ext_ctrl[8].value = pCommonParam->FrameQp;
+                ext_ctrl[9].id =  V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP;
+                ext_ctrl[9].value = pCommonParam->FrameQp_P;
+                ext_ctrl[10].id =  V4L2_CID_MPEG_VIDEO_H263_MAX_QP;  /* I frame */
+                ext_ctrl[10].value = GET_H263_QP_VALUE(pCommonParam->QpRange.QpMax_I);
+                ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP;
+                ext_ctrl[11].value = GET_H263_QP_VALUE(pCommonParam->QpRange.QpMin_I);
+                ext_ctrl[12].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
+                ext_ctrl[12].value = pCommonParam->CBRPeriodRf;
+
+                /* H263 specific parameters */
+                ext_ctrl[13].id = V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE;
+                ext_ctrl[13].value = pH263Param->FrameRate;
+                ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
+                ext_ctrl[14].value = 0;
+                ext_ctrl[15].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
+                ext_ctrl[15].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
+                ext_ctrl[16].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
+                ext_ctrl[16].value = 1;
+
+                /* Initial parameters : Frame Skip */
+                switch (pInitParam->FrameSkip) {
+                case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
+                    ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
+                    break;
+                case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
+                    ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
+                    break;
+                default:
+                    /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
+                    ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
+                    break;
+                }
+                ext_ctrls.count = H263_CTRL_NUM;
+
+                /* optional : if these are not set, set value are same as I frame */
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P;  /* P frame */
+                    ext_ctrl[i].value = GET_H263_QP_VALUE(pCommonParam->QpRange.QpMin_P);
+                    ext_ctrl[i + 1].id =  V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P;
+                    ext_ctrl[i + 1].value = GET_H263_QP_VALUE(pCommonParam->QpRange.QpMax_P);
+
+                    ext_ctrls.count += 2;
+                }
+            }
+                break;
+            case VIDEO_CODING_VP8:
+            {
+                ExynosVideoEncVp8Param *pVp8Param = &pEncParam->codecParam.vp8;
+
+                /* common parameters but id is depends on codec */
+                ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_VP8_I_FRAME_QP;
+                ext_ctrl[8].value = pCommonParam->FrameQp;
+                ext_ctrl[9].id =  V4L2_CID_MPEG_VIDEO_VP8_P_FRAME_QP;
+                ext_ctrl[9].value = pCommonParam->FrameQp_P;
+                ext_ctrl[10].id =  V4L2_CID_MPEG_VIDEO_VP8_MAX_QP;  /* I frame */
+                ext_ctrl[10].value = GET_VP8_QP_VALUE(pCommonParam->QpRange.QpMax_I);
+                ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP;
+                ext_ctrl[11].value = GET_VP8_QP_VALUE(pCommonParam->QpRange.QpMin_I);
+                ext_ctrl[12].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
+                ext_ctrl[12].value = pCommonParam->CBRPeriodRf;
+
+                /* VP8 specific parameters */
+                ext_ctrl[13].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_RC_FRAME_RATE;
+                ext_ctrl[13].value = pVp8Param->FrameRate;
+                ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
+                ext_ctrl[14].value = 0;
+                ext_ctrl[15].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
+                ext_ctrl[15].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
+                ext_ctrl[16].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
+                ext_ctrl[16].value = 1;
+
+                /* Initial parameters : Frame Skip */
+                switch (pInitParam->FrameSkip) {
+                case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
+                    ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
+                    break;
+                case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
+                    ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
+                    break;
+                default:
+                    /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
+                    ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
+                    break;
+                }
+
+                ext_ctrl[18].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_VERSION;
+                ext_ctrl[18].value = pVp8Param->Vp8Version;
+
+                ext_ctrl[19].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_OF_PARTITIONS;
+                ext_ctrl[19].value = pVp8Param->Vp8NumberOfPartitions;
+
+                ext_ctrl[20].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_LEVEL;
+                ext_ctrl[20].value = pVp8Param->Vp8FilterLevel;
+
+                ext_ctrl[21].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_SHARPNESS;
+                ext_ctrl[21].value = pVp8Param->Vp8FilterSharpness;
+
+                ext_ctrl[22].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_GOLDEN_FRAMESEL;
+                ext_ctrl[22].value = pVp8Param->Vp8GoldenFrameSel;
+
+                ext_ctrl[23].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_ENABLE;
+                ext_ctrl[23].value = 0;
+
+                ext_ctrl[24].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER0;
+                ext_ctrl[24].value = (0 << 16 | 37);
+
+                ext_ctrl[25].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER1;
+                ext_ctrl[25].value = (1 << 16 | 37);
+
+                ext_ctrl[26].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER2;
+                ext_ctrl[26].value = (2 << 16 | 37);
+
+                ext_ctrl[27].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_REF_NUMBER_FOR_PFRAMES;
+                ext_ctrl[27].value = pVp8Param->RefNumberForPFrame;
+
+                ext_ctrl[28].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_DISABLE_INTRA_MD4X4;
+                ext_ctrl[28].value = pVp8Param->DisableIntraMd4x4;
+
+                ext_ctrl[29].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_TEMPORAL_LAYER;
+                ext_ctrl[29].value = pVp8Param->TemporalSVC.nTemporalLayerCount;
+                ext_ctrls.count = VP8_CTRL_NUM;
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id         = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT0;
+                    ext_ctrl[i].value      = pVp8Param->TemporalSVC.nTemporalLayerBitrateRatio[0];
+                    ext_ctrl[i + 1].id     = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT1;
+                    ext_ctrl[i + 1].value  = pVp8Param->TemporalSVC.nTemporalLayerBitrateRatio[1];
+                    ext_ctrl[i + 2].id     = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT2;
+                    ext_ctrl[i + 2].value  = pVp8Param->TemporalSVC.nTemporalLayerBitrateRatio[2];
+
+                    ext_ctrls.count += 3;
+                }
+
+                /* optional : if these are not set, set value are same as I frame */
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P;  /* P frame */
+                    ext_ctrl[i].value = GET_VP8_QP_VALUE(pCommonParam->QpRange.QpMin_P);
+                    ext_ctrl[i + 1].id =  V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P;
+                    ext_ctrl[i + 1].value = GET_VP8_QP_VALUE(pCommonParam->QpRange.QpMax_P);
+
+                    ext_ctrls.count += 2;
+                }
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bPVCSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE;
+                    ext_ctrl[i].value = pCommonParam->PerceptualMode;
+
+                    ext_ctrls.count += 1;
+                }
+            }
+                break;
+            case VIDEO_CODING_HEVC:
+            {
+                ExynosVideoEncHevcParam *pHevcParam = &pEncParam->codecParam.hevc;
+
+                /* common parameters but id is depends on codec */
+                ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP;
+                ext_ctrl[8].value = pCommonParam->FrameQp;
+                ext_ctrl[9].id =  V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP;
+                ext_ctrl[9].value = pCommonParam->FrameQp_P;
+                ext_ctrl[10].id =  V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP;  /* I frame */
+                ext_ctrl[10].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMax_I,
+                                                    pCtx->videoCtx.instInfo.HwVersion);
+                ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP;
+                ext_ctrl[11].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMin_I,
+                                                    pCtx->videoCtx.instInfo.HwVersion);
+                ext_ctrl[12].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
+                ext_ctrl[12].value = pCommonParam->CBRPeriodRf;
+
+                /* HEVC specific parameters */
+                ext_ctrl[13].id =  V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP;
+                ext_ctrl[13].value = pHevcParam->FrameQp_B;
+                ext_ctrl[14].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_RC_FRAME_RATE;
+                ext_ctrl[14].value = pHevcParam->FrameRate;
+
+                /* Initial parameters : Frame Skip */
+                switch (pInitParam->FrameSkip) {
+                case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
+                    ext_ctrl[15].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[15].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
+                    break;
+                case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
+                    ext_ctrl[15].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[15].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
+                    break;
+                default:
+                    /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
+                    ext_ctrl[15].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[15].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
+                    break;
+                }
+
+                ext_ctrl[16].id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
+                ext_ctrl[16].value = pHevcParam->ProfileIDC;
+
+                ext_ctrl[17].id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL;
+                ext_ctrl[17].value = pHevcParam->LevelIDC;
+
+                ext_ctrl[18].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TIER_FLAG;
+                ext_ctrl[18].value = pHevcParam->TierIDC;
+
+                ext_ctrl[19].id =  V4L2_CID_MPEG_VIDEO_B_FRAMES;
+                ext_ctrl[19].value = pHevcParam->NumberBFrames;
+
+                ext_ctrl[20].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_PARTITION_DEPTH;
+                ext_ctrl[20].value = pHevcParam->MaxPartitionDepth;
+
+                ext_ctrl[21].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REF_NUMBER_FOR_PFRAMES;
+                ext_ctrl[21].value = pHevcParam->NumberRefForPframes;
+
+                ext_ctrl[22].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_DISABLE;
+                ext_ctrl[22].value = pHevcParam->LoopFilterDisable;
+
+                ext_ctrl[23].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_SLICE_BOUNDARY;
+                ext_ctrl[23].value = pHevcParam->LoopFilterSliceFlag;
+
+                ext_ctrl[24].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_TC_OFFSET_DIV2;
+                ext_ctrl[24].value = pHevcParam->LoopFilterTcOffset;
+
+                ext_ctrl[25].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_BETA_OFFSET_DIV2;
+                ext_ctrl[25].value = pHevcParam->LoopFilterBetaOffset;
+
+                ext_ctrl[26].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LTR_ENABLE;
+                ext_ctrl[26].value = pHevcParam->LongtermRefEnable;
+
+                ext_ctrl[27].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_USER_REF;
+                ext_ctrl[27].value = pHevcParam->LongtermUserRef;
+
+                ext_ctrl[28].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STORE_REF;
+                ext_ctrl[28].value = pHevcParam->LongtermStoreRef;
+
+                /* should be set V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE first */
+                ext_ctrl[29].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_DARK;
+                ext_ctrl[29].value = pHevcParam->DarkDisable;
+
+                ext_ctrl[30].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_SMOOTH;
+                ext_ctrl[30].value = pHevcParam->SmoothDisable;
+
+                ext_ctrl[31].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_STATIC;
+                ext_ctrl[31].value = pHevcParam->StaticDisable;
+
+                ext_ctrl[32].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_ACTIVITY;
+                ext_ctrl[32].value = pHevcParam->ActivityDisable;
+
+                /* doesn't have to be set */
+                ext_ctrl[33].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_TYPE;
+                ext_ctrl[33].value = 2;
+                ext_ctrl[34].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_PERIOD;
+                ext_ctrl[34].value = 0;
+                ext_ctrl[35].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LOSSLESS_CU_ENABLE;
+                ext_ctrl[35].value = 0;
+                ext_ctrl[36].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_CONST_INTRA_PRED_ENABLE;
+                ext_ctrl[36].value = 0;
+                ext_ctrl[37].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_WAVEFRONT_ENABLE;
+                ext_ctrl[37].value = 0;
+                ext_ctrl[38].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIGN_DATA_HIDING;
+                ext_ctrl[38].value = 1;
+                ext_ctrl[39].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_GENERAL_PB_ENABLE;
+                ext_ctrl[39].value = 1;
+                ext_ctrl[40].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TEMPORAL_ID_ENABLE;
+                ext_ctrl[40].value = 1;
+                ext_ctrl[41].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STRONG_SMOTHING_FLAG;
+                ext_ctrl[41].value = 1;
+                ext_ctrl[42].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1;
+                ext_ctrl[42].value = 4;
+                ext_ctrl[43].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_INTRA_PU_SPLIT;
+                ext_ctrl[43].value = 0;
+                ext_ctrl[44].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_TMV_PREDICTION;
+                ext_ctrl[44].value = 0;
+                ext_ctrl[45].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
+                ext_ctrl[45].value = 0;
+                ext_ctrl[46].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
+                ext_ctrl[46].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
+
+                /* SVC is not supported yet */
+                ext_ctrl[47].id =  V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_QP_ENABLE;
+                ext_ctrl[47].value = 0;
+                ext_ctrl[48].id =  V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE;
+                ext_ctrl[48].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P;
+                ext_ctrl[49].id =  V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER;
+                ext_ctrl[49].value = pHevcParam->TemporalSVC.nTemporalLayerCount;
+                ext_ctrl[50].id =  V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP;
+                ext_ctrl[50].value = (0 << 16 | 29);
+                ext_ctrl[51].id =  V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP;
+                ext_ctrl[51].value = (1 << 16 | 29);
+                ext_ctrl[52].id =  V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP;
+                ext_ctrl[52].value = (2 << 16 | 29);
+                ext_ctrls.count = HEVC_CTRL_NUM;
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id         = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT0;
+                    ext_ctrl[i].value      = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[0];
+                    ext_ctrl[i + 1].id     = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT1;
+                    ext_ctrl[i + 1].value  = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[1];
+                    ext_ctrl[i + 2].id     = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT2;
+                    ext_ctrl[i + 2].value  = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[2];
+                    ext_ctrl[i + 3].id     = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT3;
+                    ext_ctrl[i + 3].value  = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[3];
+                    ext_ctrl[i + 4].id     = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT4;
+                    ext_ctrl[i + 4].value  = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[4];
+                    ext_ctrl[i + 5].id     = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT5;
+                    ext_ctrl[i + 5].value  = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[5];
+                    ext_ctrl[i + 6].id     = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT6;
+                    ext_ctrl[i + 6].value  = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[6];
+                    ext_ctrls.count += 7;
+                }
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bSkypeSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    /* MAX LAYER COUNT */
+                    ext_ctrl[i].id      = V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER;
+                    ext_ctrl[i].value   = pHevcParam->MaxTemporalLayerCount;
+
+                    ext_ctrls.count += 1;
+                }
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bRoiInfoSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id     = V4L2_CID_MPEG_VIDEO_ROI_ENABLE;
+                    ext_ctrl[i].value  = pHevcParam->ROIEnable;
+
+                    ext_ctrls.count += 1;
+                }
+
+                /* optional : if these are not set, set value are same as I frame */
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P;  /* P frame */
+                    ext_ctrl[i].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMin_P,
+                                                            pCtx->videoCtx.instInfo.HwVersion);
+                    ext_ctrl[i + 1].id =  V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P;
+                    ext_ctrl[i + 1].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMax_P,
+                                                            pCtx->videoCtx.instInfo.HwVersion);
+                    ext_ctrl[i + 2].id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B;  /* B frame */
+                    ext_ctrl[i + 2].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMin_B,
+                                                            pCtx->videoCtx.instInfo.HwVersion);
+                    ext_ctrl[i + 3].id =  V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B;
+                    ext_ctrl[i + 3].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMax_B,
+                                                            pCtx->videoCtx.instInfo.HwVersion);
+
+                    ext_ctrls.count += 4;
+                }
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bPVCSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE;
+                    ext_ctrl[i].value = pCommonParam->PerceptualMode;
+
+                    ext_ctrls.count += 1;
+                }
+            }
+                break;
+            case VIDEO_CODING_VP9:
+            {
+                ExynosVideoEncVp9Param *pVp9Param = &pEncParam->codecParam.vp9;
+
+                /* VP9 specific parameters */
+                ext_ctrl[8].id      = V4L2_CID_MPEG_VIDEO_VP9_I_FRAME_QP;
+                ext_ctrl[8].value   = pCommonParam->FrameQp;
+
+                ext_ctrl[9].id      = V4L2_CID_MPEG_VIDEO_VP9_P_FRAME_QP;
+                ext_ctrl[9].value   = pCommonParam->FrameQp_P;
+
+                ext_ctrl[10].id     = V4L2_CID_MPEG_VIDEO_VP9_MAX_QP;  /* I frame */
+                ext_ctrl[10].value  = GET_VP9_QP_VALUE(pCommonParam->QpRange.QpMax_I);
+
+                ext_ctrl[11].id     = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP;
+                ext_ctrl[11].value  = GET_VP9_QP_VALUE(pCommonParam->QpRange.QpMin_I);
+
+                ext_ctrl[12].id     = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
+                ext_ctrl[12].value  = pCommonParam->CBRPeriodRf;
+
+                ext_ctrl[13].id     = V4L2_CID_MPEG_VIDEO_VP9_RC_FRAME_RATE;
+                ext_ctrl[13].value  = pVp9Param->FrameRate;
+
+                ext_ctrl[14].id     = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
+                ext_ctrl[14].value  = 0;
+
+                ext_ctrl[15].id     = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
+                ext_ctrl[15].value  = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
+
+                ext_ctrl[16].id     = V4L2_CID_MPEG_VIDEO_VP9_DISABLE_INTRA_PU_SPLIT;
+                ext_ctrl[16].value  = 0;
+
+                /* Initial parameters : Frame Skip */
+                switch (pInitParam->FrameSkip) {
+                case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
+                    ext_ctrl[17].id     = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[17].value  = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
+                    break;
+                case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
+                    ext_ctrl[17].id     = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[17].value  = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
+                    break;
+                default:
+                    /* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
+                    ext_ctrl[17].id     = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
+                    ext_ctrl[17].value  = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
+                    break;
+                }
+
+                ext_ctrl[18].id     = V4L2_CID_MPEG_VIDEO_VP9_VERSION;
+                ext_ctrl[18].value  = pVp9Param->Vp9Version;
+
+                ext_ctrl[19].id     = V4L2_CID_MPEG_VIDEO_VP9_MAX_PARTITION_DEPTH;
+                ext_ctrl[19].value  = pVp9Param->MaxPartitionDepth;
+
+                ext_ctrl[20].id     = V4L2_CID_MPEG_VIDEO_VP9_GOLDEN_FRAMESEL;
+                ext_ctrl[20].value  = pVp9Param->Vp9GoldenFrameSel;
+
+                ext_ctrl[21].id     = V4L2_CID_MPEG_VIDEO_VP9_GF_REFRESH_PERIOD;
+                ext_ctrl[21].value  = pVp9Param->Vp9GFRefreshPeriod;
+
+                ext_ctrl[22].id     = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHY_QP_ENABLE;
+                ext_ctrl[22].value  = 0;
+
+                ext_ctrl[23].id     = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP;
+                ext_ctrl[23].value  = (0 << 16 | 90);
+
+                ext_ctrl[24].id     = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP;
+                ext_ctrl[24].value  = (1 << 16 | 90);
+
+                ext_ctrl[25].id     = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP;
+                ext_ctrl[25].value  = (2 << 16 | 90);
+
+                ext_ctrl[26].id     = V4L2_CID_MPEG_VIDEO_VP9_REF_NUMBER_FOR_PFRAMES;
+                ext_ctrl[26].value  = pVp9Param->RefNumberForPFrame;
+
+                ext_ctrl[27].id     = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER;
+                ext_ctrl[27].value  = pVp9Param->TemporalSVC.nTemporalLayerCount;
+
+                ext_ctrl[28].id     = V4L2_CID_MPEG_VIDEO_DISABLE_IVF_HEADER;
+                ext_ctrl[28].value  = 1;
+                ext_ctrls.count = VP9_CTRL_NUM;
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id          = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT0;
+                    ext_ctrl[i].value       = pVp9Param->TemporalSVC.nTemporalLayerBitrateRatio[0];
+                    ext_ctrl[i + 1].id      = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT1;
+                    ext_ctrl[i + 1].value   = pVp9Param->TemporalSVC.nTemporalLayerBitrateRatio[1];
+                    ext_ctrl[i + 2].id      = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT2;
+                    ext_ctrl[i + 2].value   = pVp9Param->TemporalSVC.nTemporalLayerBitrateRatio[2];
+
+                    ext_ctrls.count += 3;
+                }
+
+                /* optional : if these are not set, set value are same as I frame */
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P;  /* P frame */
+                    ext_ctrl[i].value = GET_VP9_QP_VALUE(pCommonParam->QpRange.QpMin_P);
+                    ext_ctrl[i + 1].id =  V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P;
+                    ext_ctrl[i + 1].value = GET_VP9_QP_VALUE(pCommonParam->QpRange.QpMax_P);
+
+                    ext_ctrls.count += 2;
+                }
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bPVCSupport == VIDEO_TRUE) {
+                    i = ext_ctrls.count;
+                    ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE;
+                    ext_ctrl[i].value = pCommonParam->PerceptualMode;
+
+                    ext_ctrls.count += 1;
+                }
+            }
+                break;
+            default:
+            {
+                ALOGE("[%s] Undefined codec type",__FUNCTION__);
+                ret = -1;
+                goto EXIT;
+            }
+                break;
+            }
+
+            ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+            ext_ctrls.controls = ext_ctrl;
+
+            if (exynos_v4l2_s_ext_ctrl(pCtx->videoCtx.hDevice, &ext_ctrls) != 0) {
+                ret = -1;
+                goto EXIT;
+            }
+        }
+            break;  // CODEC_OSAL_CID_ENC_SET_PARAMS
+        case CODEC_OSAL_CID_ENC_QP_RANGE:
+        {
+            ExynosVideoQPRange *pQpRange = (ExynosVideoQPRange *)pInfo;
+
+            int cids[3][2], values[3][2];  /* I, P, B : min & max */
+            int i;
+
+            memset(cids, 0, sizeof(cids));
+            memset(values, 0, sizeof(values));
+
+            /* codec specific parameters */
+            /* common parameters but id is depends on codec */
+            switch (pCtx->videoCtx.instInfo.eCodecType) {
+            case VIDEO_CODING_AVC:
+            {
+                cids[0][0] = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
+                cids[0][1] = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
+
+                values[0][0] = GET_H264_QP_VALUE(pQpRange->QpMin_I);
+                values[0][1] = GET_H264_QP_VALUE(pQpRange->QpMax_I);
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    if (pQpRange->QpMin_P > pQpRange->QpMax_P) {
+                        ALOGE("%s: QP(P) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_P, pQpRange->QpMax_P);
+                        ret = -1;
+                        goto EXIT;
+                    }
+
+                    if (pQpRange->QpMin_B > pQpRange->QpMax_B) {
+                        ALOGE("%s: QP(B) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_B, pQpRange->QpMax_B);
+                        ret = -1;
+                        goto EXIT;
+                    }
+
+                    cids[1][0] = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P;
+                    cids[1][1] = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P;
+                    cids[2][0] = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B;
+                    cids[2][1] = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B;
+
+                    values[1][0] = GET_H264_QP_VALUE(pQpRange->QpMin_P);
+                    values[1][1] = GET_H264_QP_VALUE(pQpRange->QpMax_P);
+                    values[2][0] = GET_H264_QP_VALUE(pQpRange->QpMin_B);
+                    values[2][1] = GET_H264_QP_VALUE(pQpRange->QpMax_B);
+                }
+            }
+                break;
+            case VIDEO_CODING_MPEG4:
+            {
+                cids[0][0] = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP;
+                cids[0][1] = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP;
+
+                values[0][0] = GET_MPEG4_QP_VALUE(pQpRange->QpMin_I);
+                values[0][1] = GET_MPEG4_QP_VALUE(pQpRange->QpMax_I);
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    if (pQpRange->QpMin_P > pQpRange->QpMax_P) {
+                        ALOGE("%s: QP(P) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_P, pQpRange->QpMax_P);
+                        ret = -1;
+                        goto EXIT;
+                    }
+
+                    if (pQpRange->QpMin_B > pQpRange->QpMax_B) {
+                        ALOGE("%s: QP(B) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_B, pQpRange->QpMax_B);
+                        ret = -1;
+                        goto EXIT;
+                    }
+
+                    cids[1][0] = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P;
+                    cids[1][1] = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P;
+                    cids[2][0] = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B;
+                    cids[2][1] = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B;
+
+                    values[1][0] = GET_MPEG4_QP_VALUE(pQpRange->QpMin_P);
+                    values[1][1] = GET_MPEG4_QP_VALUE(pQpRange->QpMax_P);
+                    values[2][0] = GET_MPEG4_QP_VALUE(pQpRange->QpMin_B);
+                    values[2][1] = GET_MPEG4_QP_VALUE(pQpRange->QpMax_B);
+                }
+            }
+                break;
+            case VIDEO_CODING_H263:
+            {
+                cids[0][0] = V4L2_CID_MPEG_VIDEO_H263_MIN_QP;
+                cids[0][1] = V4L2_CID_MPEG_VIDEO_H263_MAX_QP;
+
+                values[0][0] = GET_H263_QP_VALUE(pQpRange->QpMin_I);
+                values[0][1] = GET_H263_QP_VALUE(pQpRange->QpMax_I);
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    if (pQpRange->QpMin_P > pQpRange->QpMax_P) {
+                        ALOGE("%s: QP(P) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_P, pQpRange->QpMax_P);
+                        ret = -1;
+                        goto EXIT;
+                    }
+
+                    cids[1][0] = V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P;
+                    cids[1][1] = V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P;
+
+                    values[1][0] = GET_H263_QP_VALUE(pQpRange->QpMin_P);
+                    values[1][1] = GET_H263_QP_VALUE(pQpRange->QpMax_P);
+                }
+            }
+                break;
+            case VIDEO_CODING_VP8:
+            {
+                cids[0][0] = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP;
+                cids[0][1] = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP;
+
+                values[0][0] = GET_VP8_QP_VALUE(pQpRange->QpMin_I);
+                values[0][1] = GET_VP8_QP_VALUE(pQpRange->QpMax_I);
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    if (pQpRange->QpMin_P > pQpRange->QpMax_P) {
+                        ALOGE("%s: QP(P) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_P, pQpRange->QpMax_P);
+                        ret = -1;
+                        goto EXIT;
+                    }
+
+                    cids[1][0] = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P;
+                    cids[1][1] = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P;
+
+                    values[1][0] = GET_VP8_QP_VALUE(pQpRange->QpMin_P);
+                    values[1][1] = GET_VP8_QP_VALUE(pQpRange->QpMax_P);
+                }
+            }
+                break;
+            case VIDEO_CODING_HEVC:
+            {
+                cids[0][0] = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP;
+                cids[0][1] = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP;
+
+                values[0][0] = GET_HEVC_QP_VALUE(pQpRange->QpMin_I,
+                                                pCtx->videoCtx.instInfo.HwVersion);
+                values[0][1] = GET_HEVC_QP_VALUE(pQpRange->QpMax_I,
+                                                pCtx->videoCtx.instInfo.HwVersion);
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    if (pQpRange->QpMin_P > pQpRange->QpMax_P) {
+                        ALOGE("%s: QP(P) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_P, pQpRange->QpMax_P);
+                        ret = -1;
+                        goto EXIT;
+                    }
+
+                    if (pQpRange->QpMin_B > pQpRange->QpMax_B) {
+                        ALOGE("%s: QP(B) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_B, pQpRange->QpMax_B);
+                        ret = -1;
+                        goto EXIT;
+                    }
+
+                    cids[1][0] = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P;
+                    cids[1][1] = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P;
+                    cids[2][0] = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B;
+                    cids[2][1] = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B;
+
+                    values[1][0] = GET_HEVC_QP_VALUE(pQpRange->QpMin_P,
+                                                    pCtx->videoCtx.instInfo.HwVersion);
+                    values[1][1] = GET_HEVC_QP_VALUE(pQpRange->QpMax_P,
+                                                    pCtx->videoCtx.instInfo.HwVersion);
+                    values[2][0] = GET_HEVC_QP_VALUE(pQpRange->QpMin_B,
+                                                    pCtx->videoCtx.instInfo.HwVersion);
+                    values[2][1] = GET_HEVC_QP_VALUE(pQpRange->QpMax_B,
+                                                    pCtx->videoCtx.instInfo.HwVersion);
+                }
+            }
+                break;
+            case VIDEO_CODING_VP9:
+            {
+                cids[0][0] = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP;
+                cids[0][1] = V4L2_CID_MPEG_VIDEO_VP9_MAX_QP;
+
+                values[0][0] = GET_VP9_QP_VALUE(pQpRange->QpMin_I);
+                values[0][1] = GET_VP9_QP_VALUE(pQpRange->QpMax_I);
+
+                if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
+                    cids[1][0] = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P;
+                    cids[1][1] = V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P;
+
+                    values[1][0] = GET_VP9_QP_VALUE(pQpRange->QpMin_P);
+                    values[1][1] = GET_VP9_QP_VALUE(pQpRange->QpMax_P);
+                }
+            }
+                break;
+            default:
+            {
+                ALOGE("[%s] Undefined codec type", __FUNCTION__);
+                ret = -1;
+                goto EXIT;
+            }
+                break;
+            }
+
+            for (i = 0; i < (int)(sizeof(cids)/sizeof(cids[0])); i++) {
+                if (cids[i][0] == 0)
+                    break;
+
+                ALOGV("%s: QP[%d] range (%d / %d)", __FUNCTION__, i, values[i][0], values[i][1]);
+
+                /* keep a calling sequence as Max->Min because dirver has a restriction */
+                if (exynos_v4l2_s_ctrl(pCtx->videoCtx.hDevice, cids[i][1], values[i][1]) != 0) {
+                    ALOGE("%s: Failed to s_ctrl for max value", __FUNCTION__);
+                    ret = -1;
+                    goto EXIT;
+                }
+
+                if (exynos_v4l2_s_ctrl(pCtx->videoCtx.hDevice, cids[i][0], values[i][0]) != 0) {
+                    ALOGE("%s: Failed to s_ctrl for min value", __FUNCTION__);
+                    ret = -1;
+                    goto EXIT;
+                }
+            }
+        }
+            break;
+        case CODEC_OSAL_CID_ENC_COLOR_ASPECTS:
+        {
+            ExynosVideoColorAspects *pColorAspects = (ExynosVideoColorAspects *)pInfo;
+            struct v4l2_ext_control  ext_ctrl[4];  /* range, primaries, transfer, matrix coeff */
+            struct v4l2_ext_controls ext_ctrls;
+
+            if (pColorAspects->eRangeType == RANGE_UNSPECIFIED) {
+                /* refer to standard spec */
+                ALOGD("%s: color range is unspecified. ColorAspects info won't be set", __FUNCTION__);
+                goto EXIT;
+            }
+
+            ext_ctrl[0].id    = V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG;
+            ext_ctrl[0].value = (pColorAspects->eRangeType == RANGE_FULL)? 1:0;
+
+            if (pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_VP9) {
+                int i;
+
+                ext_ctrl[1].id    = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES;
+                ext_ctrl[1].value = 0;
+
+                for (i = 0; i < (int)(sizeof(ColorSpaceToColorAspects)/sizeof(ColorSpaceToColorAspects[0])); i++) {
+                    if ((ColorSpaceToColorAspects[i].primaries == pColorAspects->ePrimariesType) &&
+                        (ColorSpaceToColorAspects[i].transfer == pColorAspects->eTransferType) &&
+                        (ColorSpaceToColorAspects[i].coeff == pColorAspects->eCoeffType)) {
+                        ext_ctrl[1].value = i;
+                        break;
+                    }
+                }
+
+                ext_ctrls.count = 2;
+            } else {
+                ext_ctrl[1].id    = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES;
+                ext_ctrl[1].value = pColorAspects->ePrimariesType;
+
+                ext_ctrl[2].id    = V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS;
+                ext_ctrl[2].value = pColorAspects->eTransferType;
+
+                ext_ctrl[3].id    = V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS;
+                ext_ctrl[3].value = pColorAspects->eCoeffType;
+
+                ext_ctrls.count = 4;
+            }
+
+            ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+            ext_ctrls.controls   = ext_ctrl;
+
+            if (exynos_v4l2_s_ext_ctrl(pCtx->videoCtx.hDevice, &ext_ctrls) != 0) {
+                ret = -1;
+                goto EXIT;
+            }
+        }
+            break;
+        default:
+        {
+            ALOGE("%s: unsupported CID(%x)", __FUNCTION__, nCID);
+            ret = -1;
+        }
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+int Codec_OSAL_GetControl(
+    CodecOSALVideoContext   *pCtx,
+    unsigned int             uCID,
+    int                     *pValue)
+{
+    if ((pCtx != NULL) &&
+        (pValue != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        return exynos_v4l2_g_ctrl(pCtx->videoCtx.hDevice, uCID, pValue);
+    }
+
+    return -1;
+}
+
+int Codec_OSAL_SetControl(
+    CodecOSALVideoContext  *pCtx,
+    unsigned int            uCID,
+    unsigned long           nValue)
+{
+    if ((pCtx != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        return exynos_v4l2_s_ctrl(pCtx->videoCtx.hDevice, uCID, nValue);
+    }
+
+    return -1;
+}
+
+int Codec_OSAL_GetCrop(
+    CodecOSALVideoContext   *pCtx,
+    CodecOSAL_Crop          *pCrop)
+{
+    if ((pCtx != NULL) &&
+        (pCrop != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        struct v4l2_crop crop;
+
+        memset(&crop, 0, sizeof(crop));
+        crop.type = pCrop->type;
+
+        if (exynos_v4l2_g_crop(pCtx->videoCtx.hDevice, &crop) == 0) {
+            pCrop->top      = crop.c.top;
+            pCrop->left     = crop.c.left;
+            pCrop->width    = crop.c.width;
+            pCrop->height   = crop.c.height;
+
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+int Codec_OSAL_GetFormat(
+    CodecOSALVideoContext   *pCtx,
+    CodecOSAL_Format        *pFmt)
+{
+    if ((pCtx != NULL) &&
+        (pFmt != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        struct v4l2_format fmt;
+        int i;
+
+        memset(&fmt, 0, sizeof(fmt));
+        fmt.type = pFmt->type;
+
+        if (exynos_v4l2_g_fmt(pCtx->videoCtx.hDevice, &fmt) == 0) {
+            pFmt->format = fmt.fmt.pix_mp.pixelformat;
+            pFmt->width  = fmt.fmt.pix_mp.width;
+            pFmt->height = fmt.fmt.pix_mp.height;
+            pFmt->stride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
+            pFmt->nPlane = fmt.fmt.pix_mp.num_planes;
+            pFmt->field  = fmt.fmt.pix_mp.field;
+
+            for (i = 0; i < fmt.fmt.pix_mp.num_planes; i++)
+                pFmt->planeSize[i] = fmt.fmt.pix_mp.plane_fmt[i].sizeimage;
+
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+int Codec_OSAL_SetFormat(
+    CodecOSALVideoContext   *pCtx,
+    CodecOSAL_Format        *pFmt)
+{
+    if ((pCtx != NULL) &&
+        (pFmt != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        struct v4l2_format fmt;
+        int i;
+
+        memset(&fmt, 0, sizeof(fmt));
+        fmt.type                                    = pFmt->type;
+        fmt.fmt.pix_mp.pixelformat                  = pFmt->format;
+        fmt.fmt.pix_mp.width                        = pFmt->width;
+        fmt.fmt.pix_mp.height                       = pFmt->height;
+        fmt.fmt.pix_mp.plane_fmt[0].bytesperline    = pFmt->stride;
+        fmt.fmt.pix_mp.num_planes                   = pFmt->nPlane;
+
+        for (i = 0; i < pFmt->nPlane; i++)
+            fmt.fmt.pix_mp.plane_fmt[i].sizeimage = pFmt->planeSize[i];
+
+        return exynos_v4l2_s_fmt(pCtx->videoCtx.hDevice, &fmt);
+    }
+
+    return -1;
+}
+
+int Codec_OSAL_RequestBuf(
+    CodecOSALVideoContext   *pCtx,
+    CodecOSAL_ReqBuf        *pReqBuf)
+{
+    if ((pCtx != NULL) &&
+        (pReqBuf != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        return exynos_v4l2_reqbufs(pCtx->videoCtx.hDevice, pReqBuf);
+    }
+
+    return -1;
+}
+
+int Codec_OSAL_QueryBuf(
+    CodecOSALVideoContext   *pCtx,
+    CodecOSAL_Buffer        *pBuf)
+{
+    if ((pCtx != NULL) &&
+        (pBuf != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        struct v4l2_buffer  buf;
+        struct v4l2_plane   planes[VIDEO_BUFFER_MAX_PLANES];
+        int i;
+
+        memset(&buf, 0, sizeof(buf));
+        memset(&planes, 0, sizeof(planes));
+
+        buf.type        = pBuf->type;
+        buf.m.planes    = planes;
+        buf.length      = pBuf->nPlane;
+        buf.memory      = pBuf->memory;
+
+        if (exynos_v4l2_querybuf(pCtx->videoCtx.hDevice, &buf) == 0) {
+            for (i = 0; i < (int)buf.length; i++) {
+                pBuf->planes[i].bufferSize  = buf.m.planes[i].length;
+                pBuf->planes[i].offset      = buf.m.planes[i].m.mem_offset;
+            }
+
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+int Codec_OSAL_SetStreamOn(
+    CodecOSALVideoContext  *pCtx,
+    int                     nPort)
+{
+    if ((pCtx != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        return exynos_v4l2_streamon(pCtx->videoCtx.hDevice, nPort);
+    }
+
+    return -1;
+}
+
+int Codec_OSAL_SetStreamOff(
+    CodecOSALVideoContext  *pCtx,
+    int                     nPort)
+{
+    if ((pCtx != NULL) &&
+        (pCtx->videoCtx.hDevice >= 0)) {
+        return exynos_v4l2_streamoff(pCtx->videoCtx.hDevice, nPort);
+    }
+
+    return -1;
+}
+
+void *Codec_OSAL_MemoryMap(void *addr, size_t len, int prot, int flags, unsigned long fd, off_t offset)
+{
+    return mmap(addr, len, prot, flags, fd, offset);
+}
+
+int Codec_OSAL_MemoryUnmap(void *addr, size_t len)
+{
+    return munmap(addr, len);
+}
diff --git a/exynos/libvideocodec/osal/include/ExynosVideo_OSAL.h b/exynos/libvideocodec/osal/include/ExynosVideo_OSAL.h
new file mode 100755 (executable)
index 0000000..778c79e
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ *
+ * Copyright 2016 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file    ExynosVideo_OSAL.h
+ * @brief   ExynosVideo OSAL define
+ * @author  SeungBeom Kim (sbcrux.kim@samsung.com)
+ *          Taehwan Kim   (t_h.kim@samsung.com)
+ * @version    1.0.0
+ * @history
+ *   2016.01.07 : Create
+ */
+
+#ifndef _EXYNOS_VIDEO_OSAL_H_
+#define _EXYNOS_VIDEO_OSAL_H_
+
+#include "exynos_v4l2.h"
+
+#include <linux/videodev2_exynos_media.h>
+#ifdef USE_EXYNOS_MEDIA_EXT
+#include "videodev2_exynos_media_ext.h"
+#endif
+#ifdef USE_MFC_HEADER
+#include "exynos_mfc_media.h"
+#endif
+
+#include <ion.h>
+#include <exynos_ion.h>
+
+//#include <utils/Log.h>
+//#define ENABLE_DEBUG_LOG
+#include <exynos_log.h>
+
+#include "ExynosVideoApi.h"
+
+typedef enum _CodecOSAL_MemType {
+    CODEC_OSAL_MEM_TYPE_MMAP    = V4L2_MEMORY_MMAP,
+    CODEC_OSAL_MEM_TYPE_USERPTR = V4L2_MEMORY_USERPTR,
+    CODEC_OSAL_MEM_TYPE_DMABUF  = V4L2_MEMORY_DMABUF,
+} CodecOSAL_MemType;
+
+typedef enum _CodecOSAL_BufType {
+    CODEC_OSAL_BUF_TYPE_SRC = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+    CODEC_OSAL_BUF_TYPE_DST = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+} CodecOSAL_BufType;
+
+typedef enum _CodecOSAL_CID {
+    CODEC_OSAL_CID_DEC_NUM_MIN_BUFFERS          = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
+    CODEC_OSAL_CID_DEC_DISPLAY_DELAY            = V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY,
+    CODEC_OSAL_CID_DEC_IMMEDIATE_DISPLAY        = V4L2_CID_MPEG_VIDEO_DECODER_IMMEDIATE_DISPLAY,
+    CODEC_OSAL_CID_DEC_I_FRAME_DECODING         = V4L2_CID_MPEG_MFC51_VIDEO_I_FRAME_DECODING,
+    CODEC_OSAL_CID_DEC_PACKED_PB                = V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB,
+    CODEC_OSAL_CID_DEC_DEBLOCK_FILTER           = V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER,
+    CODEC_OSAL_CID_DEC_SLICE_MODE               = V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE,
+    CODEC_OSAL_CID_DEC_SEI_PARSING              = V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING,
+    CODEC_OSAL_CID_DEC_DTS_MODE                 = V4L2_CID_MPEG_VIDEO_DECODER_DECODING_TIMESTAMP_MODE,
+    CODEC_OSAL_CID_DEC_DUAL_DPB_MODE            = V4L2_CID_MPEG_MFC_SET_DUAL_DPB_MODE,
+    CODEC_OSAL_CID_DEC_DYNAMIC_DPB_MODE         = V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE,
+    CODEC_OSAL_CID_DEC_SET_USER_SHARED_HANDLE   = V4L2_CID_MPEG_MFC_SET_USER_SHARED_HANDLE,
+    CODEC_OSAL_CID_DEC_GET_10BIT_INFO           = V4L2_CID_MPEG_MFC_GET_10BIT_INFO,
+    CODEC_OSAL_CID_DEC_CHECK_STATE              = V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE,
+    CODEC_OSAL_CID_DEC_DISPLAY_STATUS           = V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS,
+    CODEC_OSAL_CID_DEC_WAIT_DECODING_START      = V4L2_CID_MPEG_VIDEO_DECODER_WAIT_DECODING_START,
+    CODEC_OSAL_CID_DEC_SEARCH_BLACK_BAR         = V4L2_CID_MPEG_VIDEO_BLACK_BAR_DETECT,
+
+
+    CODEC_OSAL_CID_ENC_FRAME_TYPE                   = V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE,
+    CODEC_OSAL_CID_ENC_FRAME_RATE                   = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH,
+    CODEC_OSAL_CID_ENC_BIT_RATE                     = V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH,
+    CODEC_OSAL_CID_ENC_FRAME_SKIP_MODE              = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE,
+    CODEC_OSAL_CID_ENC_IDR_PERIOD                   = V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH,
+    CODEC_OSAL_CID_ENC_H264_PREPEND_SPSPPS_TO_IDR   = V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR,
+    CODEC_OSAL_CID_ENC_HEVC_PREPEND_SPSPPS_TO_IDR   = V4L2_CID_MPEG_VIDEO_HEVC_PREPEND_SPSPPS_TO_IDR,
+    CODEC_OSAL_CID_ENC_H264_TEMPORAL_SVC_LAYER_CH   = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH,
+    CODEC_OSAL_CID_ENC_HEVC_TEMPORAL_SVC_LAYER_CH   = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH,
+    CODEC_OSAL_CID_ENC_VP8_TEMPORAL_SVC_LAYER_CH    = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH,
+    CODEC_OSAL_CID_ENC_VP9_TEMPORAL_SVC_LAYER_CH    = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH,
+    CODEC_OSAL_CID_ENC_SET_CONFIG_QP                = V4L2_CID_MPEG_MFC_CONFIG_QP,
+    CODEC_OSAL_CID_ENC_H264_LTR_MARK_INDEX          = V4L2_CID_MPEG_MFC_H264_MARK_LTR,
+    CODEC_OSAL_CID_ENC_H264_LTR_USE_INDEX           = V4L2_CID_MPEG_MFC_H264_USE_LTR,
+    CODEC_OSAL_CID_ENC_H264_LTR_BASE_PID            = V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY,
+    CODEC_OSAL_CID_ENC_ROI_INFO                     = V4L2_CID_MPEG_VIDEO_ROI_CONTROL,
+    CODEC_OSAL_CID_ENC_EXT_BUFFER_SIZE              = V4L2_CID_MPEG_MFC_GET_EXTRA_BUFFER_SIZE,
+    CODEC_OSAL_CID_ENC_WP_ENABLE                    = V4L2_CID_MPEG_VIDEO_WEIGHTED_ENABLE,
+    CODEC_OSAL_CID_ENC_YSUM_DATA                    = V4L2_CID_MPEG_VIDEO_YSUM,
+    CODEC_OSAL_CID_ENC_I_FRAME_RATIO                = V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA,
+
+
+    CODEC_OSAL_CID_VIDEO_FRAME_TAG          = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
+    CODEC_OSAL_CID_VIDEO_QOS_RATIO          = V4L2_CID_MPEG_VIDEO_QOS_RATIO,
+    CODEC_OSAL_CID_VIDEO_CACHEABLE_BUFFER   = V4L2_CID_CACHEABLE,
+    CODEC_OSAL_CID_VIDEO_GET_VERSION_INFO   = V4L2_CID_MPEG_MFC_GET_VERSION_INFO,
+    CODEC_OSAL_CID_VIDEO_GET_EXT_INFO       = V4L2_CID_MPEG_MFC_GET_EXT_INFO,
+    CODEC_OSAL_CID_VIDEO_GET_DRIVER_VERSION = V4L2_CID_MPEG_MFC_GET_DRIVER_INFO,
+
+
+    CODEC_OSAL_CID_DEC_SEI_INFO             = 0xFFFF0000,
+    CODEC_OSAL_CID_ENC_SET_PARAMS,
+    CODEC_OSAL_CID_ENC_QP_RANGE,
+    CODEC_OSAL_CID_DEC_DISCARD_RCVHEADER,  /* not implemented */
+    CODEC_OSAL_CID_ENC_SLICE_MODE,         /* not implemented : V4L2_CID_MPEG_MFC_SET_SLICE_MODE */
+    CODEC_OSAL_CID_DEC_HDR_INFO,
+    CODEC_OSAL_CID_ENC_COLOR_ASPECTS,
+} CodecOSAL_CID;
+
+typedef enum _CodecOSAL_InterlaceType {
+    CODEC_OSAL_INTER_TYPE_NONE  = V4L2_FIELD_NONE,
+    CODEC_OSAL_INTER_TYPE_INTER = V4L2_FIELD_INTERLACED,
+    CODEC_OSAL_INTER_TYPE_TB    = V4L2_FIELD_INTERLACED_TB,
+    CODEC_OSAL_INTER_TYPE_BT    = V4L2_FIELD_INTERLACED_BT,
+} CodecOSAL_InterlaceType;
+
+#ifdef USE_DEFINE_H264_SEI_TYPE
+enum v4l2_mpeg_video_h264_sei_fp_type {
+    V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_CHEKERBOARD    = 0,
+    V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_COLUMN         = 1,
+    V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_ROW            = 2,
+    V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE   = 3,
+    V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_TOP_BOTTOM     = 4,
+    V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_TEMPORAL       = 5,
+};
+#endif
+
+typedef struct _CodecOSAL_Format {
+    CodecOSAL_BufType       type;
+    ExynosVideoCodingType   format;
+    int                     field;
+    int                     planeSize[VIDEO_BUFFER_MAX_PLANES];
+    unsigned int            width;
+    unsigned int            height;
+    unsigned int            stride;
+    int                     nPlane;
+} CodecOSAL_Format;
+
+typedef struct _CodecOSAL_Crop {
+    CodecOSAL_BufType   type;
+    int                 left;
+    int                 top;
+    int                 width;
+    int                 height;
+} CodecOSAL_Crop;
+
+typedef struct _CodecOSAL_Plane {
+    void               *addr;
+    int                 bufferSize;
+    int                 dataLen;
+    unsigned            offset;
+} CodecOSAL_Plane;
+
+typedef struct _CodecOSAL_Buffer {
+    CodecOSAL_BufType  type;
+    int                memory;
+    int                nPlane;
+    CodecOSAL_Plane    planes[VIDEO_BUFFER_MAX_PLANES];
+    int                index;
+    unsigned int       flags;
+    struct timeval     timestamp;
+
+    unsigned int            field;
+    ExynosVideoFrameType    frameType;
+} CodecOSAL_Buffer;
+
+typedef struct v4l2_requestbuffers CodecOSAL_ReqBuf;
+
+typedef struct _CodecOSALInfo {
+    int reserved;
+} CodecOSALInfo;
+
+typedef struct _CodecOSALVideoContext {
+    ExynosVideoContext videoCtx;
+    CodecOSALInfo      osalCtx;
+} CodecOSALVideoContext;
+
+int Codec_OSAL_VideoMemoryToSystemMemory(ExynosVideoMemoryType eMemoryType);
+
+unsigned int Codec_OSAL_CodingTypeToCompressdFormat(ExynosVideoCodingType eCodingType);
+ExynosVideoColorFormatType Codec_OSAL_PixelFormatToColorFormat(unsigned int nPixelFormat);
+unsigned int Codec_OSAL_ColorFormatToPixelFormat(ExynosVideoColorFormatType eColorFormat, int nHwVersion);
+
+int Codec_OSAL_DevOpen(const char *sDevName, int nFlag, CodecOSALVideoContext *pCtx);
+void Codec_OSAL_DevClose(CodecOSALVideoContext *pCtx);
+
+int Codec_OSAL_QueryCap(CodecOSALVideoContext *pCtx);
+
+int Codec_OSAL_EnqueueBuf(CodecOSALVideoContext *pCtx, CodecOSAL_Buffer *pBuf);
+int Codec_OSAL_DequeueBuf(CodecOSALVideoContext *pCtx, CodecOSAL_Buffer *pBuf);
+
+int Codec_OSAL_GetControls(CodecOSALVideoContext *pCtx, unsigned int nCID, void *pInfo);
+int Codec_OSAL_SetControls(CodecOSALVideoContext *pCtx, unsigned int nCID, void *pInfo);
+
+int Codec_OSAL_GetControl(CodecOSALVideoContext *pCtx, unsigned int nCID, int *pValue);
+int Codec_OSAL_SetControl(CodecOSALVideoContext *pCtx, unsigned int nCID, unsigned long nValue);
+
+int Codec_OSAL_GetCrop(CodecOSALVideoContext *pCtx, CodecOSAL_Crop *pCrop);
+
+int Codec_OSAL_GetFormat(CodecOSALVideoContext *pCtx, CodecOSAL_Format *pFmt);
+int Codec_OSAL_SetFormat(CodecOSALVideoContext *pCtx, CodecOSAL_Format *pFmt);
+
+int Codec_OSAL_RequestBuf(CodecOSALVideoContext *pCtx, CodecOSAL_ReqBuf *pReqBuf);
+int Codec_OSAL_QueryBuf(CodecOSALVideoContext *pCtx, CodecOSAL_Buffer *pBuf);
+
+int Codec_OSAL_SetStreamOn(CodecOSALVideoContext *pCtx, int nPort);
+int Codec_OSAL_SetStreamOff(CodecOSALVideoContext *pCtx, int nPort);
+
+void *Codec_OSAL_MemoryMap(void *addr, size_t len, int prot, int flags, unsigned long fd, off_t offset);
+int Codec_OSAL_MemoryUnmap(void *addr, size_t len);
+#endif
diff --git a/exynos/libvideocodec/osal/include/ExynosVideo_OSAL_Dec.h b/exynos/libvideocodec/osal/include/ExynosVideo_OSAL_Dec.h
new file mode 100755 (executable)
index 0000000..06051c7
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright 2016 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file    ExynosVideo_OSAL_Dec.h
+ * @brief   ExynosVideo OSAL define related with Decoder
+ * @author  SeungBeom Kim (sbcrux.kim@samsung.com)
+ *          Taehwan Kim   (t_h.kim@samsung.com)
+ * @version    1.0.0
+ * @history
+ *   2016.01.07 : Create
+ */
+
+#ifndef _EXYNOS_VIDEO_OSAL_DEC_H_
+#define _EXYNOS_VIDEO_OSAL_DEC_H_
+
+#include "ExynosVideoApi.h"
+#include "ExynosVideo_OSAL.h"
+
+/* Normal Node */
+#define VIDEO_MFC_DECODER_NAME               "s5p-mfc-dec"
+#define VIDEO_HEVC_DECODER_NAME              "exynos-hevc-dec"
+/* Secure Node */
+#define VIDEO_MFC_SECURE_DECODER_NAME        "s5p-mfc-dec-secure"
+#define VIDEO_HEVC_SECURE_DECODER_NAME       "exynos-hevc-dec-secure"
+
+#define FRAME_PACK_SEI_INFO_NUM         4
+#define HDR_INFO_NUM                    12
+
+#define OPERATE_BIT(x, mask, shift)     ((x & (mask << shift)) >> shift)
+
+#endif
diff --git a/exynos/libvideocodec/osal/include/ExynosVideo_OSAL_Enc.h b/exynos/libvideocodec/osal/include/ExynosVideo_OSAL_Enc.h
new file mode 100755 (executable)
index 0000000..98b1512
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2016 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file    ExynosVideo_OSAL_Enc.h
+ * @brief   ExynosVideo OSAL define related with Encoder
+ * @author  SeungBeom Kim (sbcrux.kim@samsung.com)
+ *          Taehwan Kim   (t_h.kim@samsung.com)
+ * @version    1.0.0
+ * @history
+ *   2016.01.07 : Create
+ */
+
+#ifndef _EXYNOS_VIDEO_OSAL_ENC_H_
+#define _EXYNOS_VIDEO_OSAL_ENC_H_
+
+#include "ExynosVideoApi.h"
+#include "ExynosVideo_OSAL.h"
+
+/* Normal Node */
+#define VIDEO_MFC_ENCODER_NAME               "s5p-mfc-enc"
+#define VIDEO_HEVC_ENCODER_NAME              "exynos-hevc-enc"
+/* Secure Node */
+#define VIDEO_MFC_SECURE_ENCODER_NAME        "s5p-mfc-enc-secure"
+#define VIDEO_HEVC_SECURE_ENCODER_NAME       "exynos-hevc-enc-secure"
+/* OTF Node */
+#define VIDEO_MFC_OTF_ENCODER_NAME           "s5p-mfc-enc-otf"
+#define VIDEO_MFC_OTF_SECURE_ENCODER_NAME    "s5p-mfc-enc-otf-secure"
+
+#define MAX_CTRL_NUM          109
+#define H264_CTRL_NUM         91  /* +7(svc), +5(skype), +1(roi), +4(qp range) +1(pvc)*/
+#define MPEG4_CTRL_NUM        26  /* +4(qp range) */
+#define H263_CTRL_NUM         18  /* +2(qp range) */
+#define VP8_CTRL_NUM          30  /* +3(svc), +2(qp range) */
+#define HEVC_CTRL_NUM         53  /* +7(svc), +1(roi), +4(qp range)*/
+#define VP9_CTRL_NUM          29  /* +3(svc), +4(qp range) */
+
+#endif
diff --git a/libomxil-e9110-v4l2.manifest b/libomxil-e9110-v4l2.manifest
new file mode 100755 (executable)
index 0000000..a76fdba
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
diff --git a/omxil-e9110-v4l2.pc.in b/omxil-e9110-v4l2.pc.in
new file mode 100755 (executable)
index 0000000..3871ad2
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+libdir=@prefix@/lib
+includedir=@prefix@/include
+
+Name: Samsung OpenMAX IL package
+Description: Samsung E9110 codec
+Version: @VERSION@
+Requires: exynos-common
+Libs: -L${libdir} -lExynosOMX_Core
+
+Cflags: -I${includedir}/libomxil-e9110-v4l2 -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
diff --git a/openmax/Makefile.am b/openmax/Makefile.am
new file mode 100755 (executable)
index 0000000..0c89c75
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = osal component core
diff --git a/openmax/component/Makefile.am b/openmax/component/Makefile.am
new file mode 100755 (executable)
index 0000000..f61f35f
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = common video
diff --git a/openmax/component/common/Exynos_OMX_Basecomponent.c b/openmax/component/common/Exynos_OMX_Basecomponent.c
new file mode 100755 (executable)
index 0000000..f9fd4ab
--- /dev/null
@@ -0,0 +1,2528 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Basecomponent.c
+ * @brief
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ *             Taehwan Kim (t_h.kim@samsung.com)
+ * @version    2.5.0
+ * @history
+ *    2012.02.20 : Create
+ *    2017.08.03 : Change event handling
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OSAL_Thread.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Resourcemanager.h"
+#include "Exynos_OMX_Macros.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_BASE_COMP"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+static OMX_ERRORTYPE Exynos_CheckStateSet(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam);
+static OMX_ERRORTYPE Exynos_CheckPortFlush(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam);
+static OMX_ERRORTYPE Exynos_CheckPortDisable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam);
+static OMX_ERRORTYPE Exynos_CheckPortEnable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam);
+static OMX_ERRORTYPE Exynos_CheckMarkBuffer(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam);
+static OMX_ERRORTYPE Exynos_OMX_CommandQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_COMMANDTYPE Cmd, OMX_U32 nParam, OMX_PTR pCmdData);
+
+/* Change CHECK_SIZE_VERSION Macro */
+OMX_ERRORTYPE Exynos_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size)
+{
+    OMX_ERRORTYPE        ret        = OMX_ErrorNone;
+    OMX_VERSIONTYPE     *version    = NULL;
+
+    if (header == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    version = (OMX_VERSIONTYPE*)((char*)header + sizeof(OMX_U32));
+    if (*((OMX_U32*)header) != size) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_FUNC_TRACE, "[%s] nVersionMajor:%d, nVersionMinor:%d", __FUNCTION__, version->s.nVersionMajor, version->s.nVersionMinor);
+
+    if ((version->s.nVersionMajor != VERSIONMAJOR_NUMBER) ||
+        (version->s.nVersionMinor > VERSIONMINOR_NUMBER)) {
+        ret = OMX_ErrorVersionMismatch;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    return ret;
+}
+
+
+/* OMX Interface */
+OMX_ERRORTYPE Exynos_OMX_GetComponentVersion(
+    OMX_IN  OMX_HANDLETYPE   hComponent,
+    OMX_OUT OMX_STRING       pComponentName,
+    OMX_OUT OMX_VERSIONTYPE *pComponentVersion,
+    OMX_OUT OMX_VERSIONTYPE *pSpecVersion,
+    OMX_OUT OMX_UUIDTYPE    *pComponentUUID)
+{
+    OMX_ERRORTYPE             ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+    unsigned long             compUUID[3];
+
+    FunctionIn();
+
+    /* check parameters */
+    if (hComponent     == NULL ||
+        pComponentName == NULL || pComponentVersion == NULL ||
+        pSpecVersion   == NULL || pComponentUUID    == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Strcpy(pComponentName, pExynosComponent->componentName);
+    Exynos_OSAL_Memcpy(pComponentVersion, &(pExynosComponent->componentVersion), sizeof(OMX_VERSIONTYPE));
+    Exynos_OSAL_Memcpy(pSpecVersion, &(pExynosComponent->specVersion), sizeof(OMX_VERSIONTYPE));
+
+    /* Fill UUID with handle address, PID and UID.
+     * This should guarantee uiniqness */
+    compUUID[0] = (unsigned long)pOMXComponent;
+    compUUID[1] = (unsigned long)getpid();
+    compUUID[2] = (unsigned long)getuid();
+    Exynos_OSAL_Memcpy(*pComponentUUID, compUUID, 3 * sizeof(*compUUID));
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_SendCommand(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_COMMANDTYPE Cmd,
+    OMX_IN OMX_U32         nParam,
+    OMX_IN OMX_PTR         pCmdData)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    switch (Cmd) {
+    case OMX_CommandStateSet :
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_CommandStateSet(%s)",
+                                                pExynosComponent, __FUNCTION__, stateString(nParam));
+        ret = Exynos_CheckStateSet(pExynosComponent, nParam);
+        break;
+    case OMX_CommandFlush :
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_CommandFlush(port:0x%x)",
+                                                pExynosComponent, __FUNCTION__, nParam);
+        ret = Exynos_CheckPortFlush(pExynosComponent, nParam);
+        break;
+    case OMX_CommandPortDisable :
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_CommandPortDisable(port:0x%x)",
+                                                pExynosComponent, __FUNCTION__, nParam);
+        ret = Exynos_CheckPortDisable(pExynosComponent, nParam);
+        break;
+    case OMX_CommandPortEnable :
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_CommandPortEnable(port:0x%x)",
+                                                pExynosComponent, __FUNCTION__, nParam);
+        ret = Exynos_CheckPortEnable(pExynosComponent, nParam);
+        break;
+    case OMX_CommandMarkBuffer :
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_CommandMarkBuffer(0x%x)",
+                                                pExynosComponent, __FUNCTION__, nParam);
+
+        ret = Exynos_CheckMarkBuffer(pExynosComponent, nParam);
+        break;
+    default:
+        ret = OMX_ErrorBadParameter;
+        break;
+    }
+
+    if (ret == OMX_ErrorNone) {
+        ret = Exynos_OMX_CommandQueue(pExynosComponent, Cmd, nParam, pCmdData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OMX_CommandQueue()", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        /* wait for msg handler's ack except for MarkBuffer */
+        if (Cmd != OMX_CommandMarkBuffer)
+            Exynos_OSAL_SemaphoreWait(pExynosComponent->hSemaMsgProgress);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_GetState(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_OUT OMX_STATETYPE *pState)
+{
+    OMX_ERRORTYPE             ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL || pState == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    *pState = pExynosComponent->currentState;
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_SetCallbacks(
+    OMX_IN OMX_HANDLETYPE    hComponent,
+    OMX_IN OMX_CALLBACKTYPE* pCallbacks,
+    OMX_IN OMX_PTR           pAppData)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pCallbacks == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->currentState != OMX_StateLoaded) {
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    pExynosComponent->pCallbacks   = pCallbacks;
+    pExynosComponent->callbackData = pAppData;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+#ifdef EGL_IMAGE_SUPPORT
+OMX_ERRORTYPE Exynos_OMX_UseEGLImage(
+    OMX_IN OMX_HANDLETYPE            hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32                   nPortIndex,
+    OMX_IN OMX_PTR                   pAppPrivate,
+    OMX_IN void                     *eglImage)
+{
+    return OMX_ErrorNotImplemented;
+}
+#endif
+
+static OMX_ERRORTYPE Exynos_CheckStateSet(
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+    OMX_U32                     nParam)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorUndefined;
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->currentState == (OMX_STATETYPE)nParam) {
+         ret = OMX_ErrorSameState;
+         goto EXIT;
+    }
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    switch ((OMX_STATETYPE)nParam) {
+    case OMX_StateInvalid:
+    {
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_StateLoaded:
+    {
+        if ((pExynosComponent->currentState != OMX_StateIdle) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateTransition;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_StateWaitForResources:
+    {
+        if (pExynosComponent->currentState != OMX_StateLoaded) {
+            ret = OMX_ErrorIncorrectStateTransition;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_StateIdle:
+    {
+        if (pExynosComponent->currentState == OMX_StateInvalid) {
+            ret = OMX_ErrorIncorrectStateTransition;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_StateExecuting:
+    {
+        if ((pExynosComponent->currentState != OMX_StateIdle) &&
+            (pExynosComponent->currentState != OMX_StatePause)) {
+            ret = OMX_ErrorIncorrectStateTransition;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_StatePause:
+    {
+        if ((pExynosComponent->currentState != OMX_StateIdle) &&
+            (pExynosComponent->currentState != OMX_StateExecuting)) {
+            ret = OMX_ErrorIncorrectStateTransition;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    default:
+        ret = OMX_ErrorBadParameter;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_CheckPortFlush(
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+    OMX_U32                     nParam)
+{
+    OMX_ERRORTYPE        ret         = OMX_ErrorUndefined;
+    EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+    OMX_U32              nPortIndex  = nParam;
+
+    OMX_U32 i = 0;
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
+        (nPortIndex >= pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((pExynosComponent->currentState == OMX_StateExecuting) ||
+        (pExynosComponent->currentState == OMX_StatePause)) {
+        if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
+           (nPortIndex >= pExynosComponent->portParam.nPorts)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
+            for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+                pExynosPort = &pExynosComponent->pExynosPort[i];
+
+                if (!CHECK_PORT_ENABLED(pExynosPort)) {
+                    ret = OMX_ErrorIncorrectStateOperation;
+                    goto EXIT;
+                }
+            }
+        } else {
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            if (!CHECK_PORT_ENABLED(pExynosPort)) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorIncorrectStateOperation;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_CheckPortDisable(
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+    OMX_U32                     nParam)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorUndefined;
+    EXYNOS_OMX_BASEPORT *pExynosPort    = NULL;
+    OMX_U32              nPortIndex     = nParam;
+
+    OMX_U32 i = 0;
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
+        (nPortIndex >= pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
+        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+            pExynosPort = &pExynosComponent->pExynosPort[i];
+
+            if (!CHECK_PORT_ENABLED(pExynosPort)) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        ret = OMX_ErrorNone;
+    } else {
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if (!CHECK_PORT_ENABLED(pExynosPort)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_CheckPortEnable(
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+    OMX_U32                     nParam)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorUndefined;
+    EXYNOS_OMX_BASEPORT *pExynosPort    = NULL;
+    OMX_U32              nPortIndex     = nParam;
+
+    OMX_U32 i = 0;
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
+        (nPortIndex >= pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
+        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+            pExynosPort = &pExynosComponent->pExynosPort[i];
+
+            if (CHECK_PORT_ENABLED(pExynosPort)) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        ret = OMX_ErrorNone;
+    } else {
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if (CHECK_PORT_ENABLED(pExynosPort)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_CheckMarkBuffer(
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+    OMX_U32                     nParam)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorUndefined;
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if (nParam >= pExynosComponent->portParam.nPorts) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((pExynosComponent->currentState == OMX_StateExecuting) ||
+        (pExynosComponent->currentState == OMX_StatePause)) {
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorIncorrectStateOperation;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_SetStateSet(
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+    OMX_U32                     nParam)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    OMX_U32 i = 0;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    switch ((OMX_STATETYPE)nParam) {
+    case OMX_StateIdle:
+    {
+        /* Loaded to Idle */
+        if (pExynosComponent->currentState == OMX_StateLoaded) {
+            pExynosComponent->transientState = EXYNOS_OMX_TransStateLoadedToIdle;
+
+            for(i = 0; i < pExynosComponent->portParam.nPorts; i++)
+                pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateEnabling;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateLoaded to OMX_StateIdle", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        /* Executing to Idle */
+        if (pExynosComponent->currentState == OMX_StateExecuting) {
+            EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+            pExynosComponent->transientState = EXYNOS_OMX_TransStateExecutingToIdle;
+
+            pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]);
+            if ((pExynosPort->portDefinition.bEnabled == OMX_FALSE) &&
+                (pExynosPort->portState == EXYNOS_OMX_PortStateEnabling)) {
+                pExynosPort->exceptionFlag = INVALID_STATE;
+            }
+
+            pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+            if ((pExynosPort->portDefinition.bEnabled == OMX_FALSE) &&
+                (pExynosPort->portState == EXYNOS_OMX_PortStateEnabling)) {
+                pExynosPort->exceptionFlag = INVALID_STATE;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateExecuting to OMX_StateIdle", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        /* Pause to Idle */
+        if (pExynosComponent->currentState == OMX_StatePause) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StatePause to OMX_StateIdle", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        if (pExynosComponent->currentState == OMX_StateInvalid) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_StateExecuting:
+    {
+        /* Idle to Executing */
+        if (pExynosComponent->currentState == OMX_StateIdle) {
+            pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToExecuting;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateIdle to OMX_StateExecuting", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        /* Pause to Executing */
+        if (pExynosComponent->currentState == OMX_StatePause) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StatePause to OMX_StateIdle", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorBadParameter;
+    }
+        break;
+    case OMX_StateLoaded:
+    {
+        /* Idle to Loaded */
+        if (pExynosComponent->currentState == OMX_StateIdle) {
+            pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToLoaded;
+
+            for (i = 0; i < pExynosComponent->portParam.nPorts; i++)
+                pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateDisabling;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateIdle to OMX_StateLoaded", pExynosComponent, __FUNCTION__);
+        }
+    }
+        break;
+    case OMX_StateInvalid:
+    {
+        for (i = 0; i < pExynosComponent->portParam.nPorts; i++)
+            pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateInvalid;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, stateString(pExynosComponent->currentState));
+    }
+        break;
+    default:
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s to %s", pExynosComponent, __FUNCTION__,
+                                            stateString(pExynosComponent->currentState), stateString(nParam));
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_SetPortFlush(
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+    OMX_U32                     nParam)
+{
+    OMX_ERRORTYPE        ret         = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+    OMX_U32              nPortIndex  = nParam;
+
+    OMX_U32 i;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if ((pExynosComponent->currentState == OMX_StateExecuting) ||
+        (pExynosComponent->currentState == OMX_StatePause)) {
+        if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
+            (nPortIndex >= pExynosComponent->portParam.nPorts)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
+            for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+                pExynosPort = &pExynosComponent->pExynosPort[i];
+
+                if (!CHECK_PORT_ENABLED(pExynosPort)) {
+                    ret = OMX_ErrorIncorrectStateOperation;
+                    goto EXIT;
+                }
+
+                pExynosPort->portState = EXYNOS_OMX_PortStateFlushing;
+            }
+        } else {
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+            if (!CHECK_PORT_ENABLED(pExynosPort)) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+
+            pExynosPort->portState = EXYNOS_OMX_PortStateFlushing;
+        }
+    } else {
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_SetPortDisable(
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+    OMX_U32                     nParam)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT *pExynosPort    = NULL;
+    OMX_U32              nPortIndex     = nParam;
+
+    OMX_U32 i = 0;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
+        (nPortIndex >= pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
+        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+            pExynosPort = &pExynosComponent->pExynosPort[i];
+
+            if (!CHECK_PORT_ENABLED(pExynosPort)) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+
+            pExynosPort->portState = EXYNOS_OMX_PortStateDisabling;
+        }
+    } else {
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if (!CHECK_PORT_ENABLED(pExynosPort)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        pExynosPort->portState = EXYNOS_OMX_PortStateDisabling;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_SetPortEnable(
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+    OMX_U32                     nParam)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT *pExynosPort    = NULL;
+    OMX_U32              nPortIndex     = nParam;
+
+    OMX_U32 i;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if ((nPortIndex != (OMX_U32)ALL_PORT_INDEX) &&
+        (nPortIndex >= pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == (OMX_U32)ALL_PORT_INDEX) {
+        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+            pExynosPort = &pExynosComponent->pExynosPort[i];
+
+            if (CHECK_PORT_ENABLED(pExynosPort)) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+
+            pExynosPort->portState = EXYNOS_OMX_PortStateEnabling;
+        }
+    } else {
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if (CHECK_PORT_ENABLED(pExynosPort)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        pExynosPort->portState = EXYNOS_OMX_PortStateEnabling;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+
+}
+
+static OMX_ERRORTYPE Exynos_SetMarkBuffer(
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+    OMX_U32                     nParam)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if (nParam >= pExynosComponent->portParam.nPorts) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((pExynosComponent->currentState == OMX_StateExecuting) ||
+        (pExynosComponent->currentState == OMX_StatePause)) {
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorIncorrectStateOperation;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              destState)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+    OMX_STATETYPE             currentState      = OMX_StateLoaded;
+
+    int i;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    currentState     = pExynosComponent->currentState;
+
+    if (pExynosComponent->currentState == (OMX_STATETYPE)destState) {
+         ret = OMX_ErrorSameState;
+         goto EXIT;
+    }
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] current:(%s) dest:(%s)", pExynosComponent, __FUNCTION__,
+                                        stateString(currentState), stateString(destState));
+    switch ((OMX_STATETYPE)destState) {
+    case OMX_StateInvalid:
+    {
+        switch (currentState) {
+        case OMX_StateWaitForResources:
+            Exynos_OMX_Out_WaitForResource(pOMXComponent);
+        case OMX_StateIdle:
+        case OMX_StateExecuting:
+        case OMX_StatePause:
+        case OMX_StateLoaded:
+            pExynosComponent->currentState = OMX_StateInvalid;
+
+            ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent);
+
+            for (i = 0; i < ALL_PORT_NUM; i++) {
+                /* terminate mutex in way */
+                if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
+                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
+                    pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
+                } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
+                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
+                    pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
+
+                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
+                    pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
+                }
+
+                /* terminate mutex for port */
+                Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
+                pExynosComponent->pExynosPort[i].hPortMutex = NULL;
+            }
+
+            /* terminate signal about pause */
+            for (i = 0; i < ALL_PORT_NUM; i++) {
+                Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
+                pExynosComponent->pExynosPort[i].pauseEvent = NULL;
+            }
+
+            /* terminate sema for buffer handling on port */
+            for (i = 0; i < ALL_PORT_NUM; i++) {
+                Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
+                pExynosComponent->pExynosPort[i].bufferSemID = NULL;
+            }
+
+            if (currentState != OMX_StateLoaded)
+                pExynosComponent->exynos_codec_componentTerminate(pOMXComponent);
+
+            ret = OMX_ErrorInvalidState;
+
+            if (pExynosComponent->abendState == OMX_TRUE)
+                goto NO_EVENT_EXIT;
+
+            break;
+        default:
+            ret = OMX_ErrorInvalidState;
+            break;
+        }
+    }
+        break;
+    case OMX_StateLoaded:
+    {
+        switch (currentState) {
+        case OMX_StateIdle:
+            for(i = 0; i < (int)pExynosComponent->portParam.nPorts; i++)
+                pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateDisabling;
+
+            ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent);
+
+            for (i = 0; i < ALL_PORT_NUM; i++) {
+                /* terminate mutex in way */
+                if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
+                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
+                    pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
+                } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
+                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
+                    pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
+
+                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
+                    pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
+                }
+
+                /* terminate mutex for port */
+                Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
+                pExynosComponent->pExynosPort[i].hPortMutex = NULL;
+            }
+
+            /* terminate signal about pause */
+            for (i = 0; i < ALL_PORT_NUM; i++) {
+                Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
+                pExynosComponent->pExynosPort[i].pauseEvent = NULL;
+            }
+
+            /* terminate sema for buffer handling on port */
+            for (i = 0; i < ALL_PORT_NUM; i++) {
+                Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
+                pExynosComponent->pExynosPort[i].bufferSemID = NULL;
+            }
+
+            pExynosComponent->exynos_codec_componentTerminate(pOMXComponent);
+
+#ifdef TUNNELING_SUPPORT
+            for (i = 0; i < (pExynosComponent->portParam.nPorts); i++) {
+                pExynosPort = &(pExynosComponent->pExynosPort[i]);
+                if (CHECK_PORT_TUNNELED(pExynosPort) &&
+                    CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    while (Exynos_OSAL_GetElemNum(&(pExynosPort->bufferQ)) > 0) {
+                        EXYNOS_OMX_MESSAGE *pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+                        if (pMessage != NULL)
+                            Exynos_OSAL_Free(pMessage);
+                    }
+
+                    ret = pExynosComponent->exynos_FreeTunnelBuffer(pExynosPort, i);
+                    if (OMX_ErrorNone != ret)
+                        goto EXIT;
+                }
+            }
+#endif
+
+            /* if all buffers are freed, send an event */
+            if ((pExynosComponent->pExynosPort[INPUT_PORT_INDEX].assignedBufferNum <= 0) &&
+                (pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].assignedBufferNum <= 0)) {
+                Exynos_OMX_SendEventCommand(pExynosComponent, EVENT_CMD_STATE_TO_LOAD_STATE, NULL);
+            }
+
+            goto NO_EVENT_EXIT;
+        case OMX_StateWaitForResources:
+            ret = Exynos_OMX_Out_WaitForResource(pOMXComponent);
+
+            pExynosComponent->currentState = OMX_StateLoaded;
+            break;
+        case OMX_StateExecuting:
+        case OMX_StatePause:
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+    }
+        break;
+    case OMX_StateIdle:
+    {
+        switch (currentState) {
+        case OMX_StateLoaded:
+            for (i = 0; i < (int)pExynosComponent->portParam.nPorts; i++) {
+                pExynosPort = &(pExynosComponent->pExynosPort[i]);
+
+                pExynosPort->portState = EXYNOS_OMX_PortStateEnabling;
+
+#ifdef TUNNELING_SUPPORT
+                if (CHECK_PORT_TUNNELED(pExynosPort) &&
+                    CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) &&
+                    CHECK_PORT_ENABLED(pExynosPort)) {
+                    ret = pExynosComponent->exynos_AllocateTunnelBuffer(pExynosPort, i);
+                    if (ret!=OMX_ErrorNone)
+                        goto EXIT;
+                }
+#endif
+            }
+
+            Exynos_OSAL_Get_Log_Property(); // For debuging, Function called when GetHandle function is success
+
+            ret = pExynosComponent->exynos_codec_componentInit(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to exynos_codec_componentInit() (0x%x)", pExynosComponent, __FUNCTION__, ret);
+#ifdef TUNNELING_SUPPORT
+                /*
+                 * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
+                 */
+#endif
+                goto EXIT;
+            }
+
+            /* create sema for buffer handling on port */
+            for (i = 0; i < ALL_PORT_NUM; i++) {
+                ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->pExynosPort[i].bufferSemID);
+                if (ret != OMX_ErrorNone) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SemaphoreCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
+                    ret = OMX_ErrorInsufficientResources;
+                    goto FAIL_TO_IDLE;
+                }
+            }
+
+            /* create signal about pause */
+            for (i = 0; i < ALL_PORT_NUM; i++) {
+                ret = Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].pauseEvent);
+                if (ret != OMX_ErrorNone) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_SignalCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
+                    ret = OMX_ErrorInsufficientResources;
+                    goto FAIL_TO_IDLE;
+                }
+            }
+
+            for (i = 0; i < ALL_PORT_NUM; i++) {
+                /* create mutex in way */
+                if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
+                    ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
+                    if (ret != OMX_ErrorNone) {
+                        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
+                        ret = OMX_ErrorInsufficientResources;
+                        goto FAIL_TO_IDLE;
+                    }
+                } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
+                    ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
+                    if (ret != OMX_ErrorNone) {
+                        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
+                        ret = OMX_ErrorInsufficientResources;
+                        goto FAIL_TO_IDLE;
+                    }
+                    ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
+                    if (ret != OMX_ErrorNone) {
+                        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
+                        ret = OMX_ErrorInsufficientResources;
+                        goto FAIL_TO_IDLE;
+                    }
+                }
+
+                /* create mutex for port */
+                ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].hPortMutex);
+                if (ret != OMX_ErrorNone) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
+                    ret = OMX_ErrorInsufficientResources;
+                    goto FAIL_TO_IDLE;
+                }
+            }
+
+            ret = pExynosComponent->exynos_BufferProcessCreate(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+FAIL_TO_IDLE:
+#ifdef TUNNELING_SUPPORT
+                /*
+                 * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
+                 */
+#endif
+                for (i = 0; i < ALL_PORT_NUM; i++) {
+                    /* terminate mutex in way */
+                    if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
+                        Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
+                        pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
+                    } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
+                        Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
+                        pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
+
+                        Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
+                        pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
+                    }
+
+                    /* terminate mutex for port */
+                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
+                    pExynosComponent->pExynosPort[i].hPortMutex = NULL;
+                }
+
+                /* terminate signal about pause */
+                for (i = 0; i < ALL_PORT_NUM; i++) {
+                    Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
+                    pExynosComponent->pExynosPort[i].pauseEvent = NULL;
+                }
+
+                /* terminate sema for buffer handling on port */
+                for (i = 0; i < ALL_PORT_NUM; i++) {
+                    Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
+                    pExynosComponent->pExynosPort[i].bufferSemID = NULL;
+                }
+
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+
+            /* if all buffers are allocated, send an event */
+            if (CHECK_PORT_POPULATED(&(pExynosComponent->pExynosPort[INPUT_PORT_INDEX])) &&
+                CHECK_PORT_POPULATED(&(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]))) {
+                Exynos_OMX_SendEventCommand(pExynosComponent, EVENT_CMD_STATE_TO_IDLE_STATE, NULL);
+            }
+
+            goto NO_EVENT_EXIT;
+            break;
+        case OMX_StateExecuting:
+            Exynos_SetPortFlush(pExynosComponent, ALL_PORT_INDEX);
+
+            ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, ALL_PORT_INDEX, OMX_FALSE);
+
+            pExynosComponent->transientState    = EXYNOS_OMX_TransStateMax;
+            pExynosComponent->currentState      = OMX_StateIdle;
+            break;
+        case OMX_StatePause:
+            Exynos_SetPortFlush(pExynosComponent, ALL_PORT_INDEX);
+
+            ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, ALL_PORT_INDEX, OMX_FALSE);
+
+            pExynosComponent->currentState = OMX_StateIdle;
+            break;
+        case OMX_StateWaitForResources:
+            pExynosComponent->currentState = OMX_StateIdle;
+            break;
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+    }
+        break;
+    case OMX_StateExecuting:
+    {
+        int j;
+
+        switch (currentState) {
+        case OMX_StateLoaded:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        case OMX_StateIdle:
+#ifdef TUNNELING_SUPPORT
+            for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+                pExynosPort = &pExynosComponent->pExynosPort[i];
+
+                if (CHECK_PORT_TUNNELED(pExynosPort) &&
+                    CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) &&
+                    CHECK_PORT_ENABLED(pExynosPort)) {
+                    for (j = 0; j < pExynosPort->tunnelBufferNum; j++)
+                        Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID);
+                }
+            }
+#endif
+            pExynosComponent->transientState    = EXYNOS_OMX_TransStateMax;
+            pExynosComponent->currentState      = OMX_StateExecuting;
+
+            /* set signal about pause */
+            for (i = 0; i < ALL_PORT_NUM; i++)
+                Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent);
+            break;
+        case OMX_StatePause:
+#ifdef TUNNELING_SUPPORT
+            for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+                pExynosPort = &pExynosComponent->pExynosPort[i];
+
+                if (CHECK_PORT_TUNNELED(pExynosPort) &&
+                    CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) &&
+                    CHECK_PORT_ENABLED(pExynosPort)) {
+                    OMX_S32 semaValue = 0, cnt = 0;
+
+                    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[i].bufferSemID, &semaValue);
+                    if (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > semaValue) {
+                        cnt = Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) - semaValue;
+                        for (j = 0; j < cnt; j++)
+                            Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID);
+                    }
+                }
+            }
+#endif
+            pExynosComponent->currentState = OMX_StateExecuting;
+
+            /* set signal about pause */
+            for (i = 0; i < ALL_PORT_NUM; i++)
+                Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent);
+            break;
+        case OMX_StateWaitForResources:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+    }
+        break;
+    case OMX_StatePause:
+    {
+        switch (currentState) {
+        case OMX_StateLoaded:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        case OMX_StateIdle:
+            pExynosComponent->currentState = OMX_StatePause;
+            break;
+        case OMX_StateExecuting:
+            pExynosComponent->currentState = OMX_StatePause;
+            break;
+        case OMX_StateWaitForResources:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+    }
+        break;
+    case OMX_StateWaitForResources:
+    {
+        switch (currentState) {
+        case OMX_StateLoaded:
+            ret = Exynos_OMX_In_WaitForResource(pOMXComponent);
+            pExynosComponent->currentState = OMX_StateWaitForResources;
+            break;
+        case OMX_StateIdle:
+        case OMX_StateExecuting:
+        case OMX_StatePause:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+    }
+        break;
+    default:
+        ret = OMX_ErrorIncorrectStateTransition;
+        break;
+    }
+
+EXIT:
+    if (ret == OMX_ErrorNone) {
+        if (pExynosComponent->pCallbacks != NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(%s)",
+                                        pExynosComponent, __FUNCTION__, stateString(destState));
+
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventCmdComplete, OMX_CommandStateSet,
+                                                       destState, NULL);
+        }
+    } else {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OMX_ComponentStateSet(%s) (0x%x)",
+                                            pExynosComponent, __FUNCTION__, stateString(destState), ret);
+        if ((pExynosComponent != NULL) &&
+            (pExynosComponent->pCallbacks != NULL)) {
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+NO_EVENT_EXIT:  /* postpone to send event */
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_EventHandler(
+    OMX_COMPONENTTYPE *pOMXComponent,
+    EVENT_COMMAD_TYPE  cmd)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    int i = 0;
+
+    if ((pOMXComponent == NULL) ||
+        (pOMXComponent->pComponentPrivate == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    switch (cmd) {
+    case EVENT_CMD_STATE_TO_LOAD_STATE:  /* Idle to Loaded */
+    {
+        EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+        if (pExynosComponent->currentState == OMX_StateLoaded) {
+            /* event was already handled */
+            break;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateIdle) ||
+            (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid state(state:0x%x, transient:0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                pExynosComponent->currentState, pExynosComponent->transientState);
+            break;
+        }
+
+        for (i = 0; i < (int)pExynosComponent->portParam.nPorts; i++) {
+            pExynosPort = &(pExynosComponent->pExynosPort[i]);
+
+            if (CHECK_PORT_ENABLED(pExynosPort)) {
+                while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
+                    EXYNOS_OMX_MESSAGE *pMsg = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+                    if (pMsg != NULL)
+                        Exynos_OSAL_Free(pMsg);
+                }
+            }
+
+            pExynosPort->portState = EXYNOS_OMX_PortStateLoaded;
+        }
+
+        pExynosComponent->transientState = EXYNOS_OMX_TransStateMax;
+        pExynosComponent->currentState   = OMX_StateLoaded;
+
+        if (pExynosComponent->pCallbacks != NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(OMX_StateLoaded)", pExynosComponent, __FUNCTION__);
+
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventCmdComplete,
+                                                       OMX_CommandStateSet,
+                                                       OMX_StateLoaded,
+                                                       NULL);
+        }
+    }
+        break;
+    case EVENT_CMD_STATE_TO_IDLE_STATE:  /* Loaded to Idle */
+    {
+        if (pExynosComponent->currentState == OMX_StateIdle) {
+            /* event was already handled */
+            break;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) ||
+            (pExynosComponent->transientState != EXYNOS_OMX_TransStateLoadedToIdle)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid state(state:0x%x, transient:0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                pExynosComponent->currentState, pExynosComponent->transientState);
+            break;
+        }
+
+        for (i = 0; i < (int)pExynosComponent->portParam.nPorts; i++)
+            pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateIdle;
+
+        pExynosComponent->transientState = EXYNOS_OMX_TransStateMax;
+        pExynosComponent->currentState   = OMX_StateIdle;
+
+        if (pExynosComponent->pCallbacks != NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(OMX_StateIdle)", pExynosComponent, __FUNCTION__);
+
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventCmdComplete,
+                                                       OMX_CommandStateSet,
+                                                       OMX_StateIdle,
+                                                       NULL);
+        }
+    }
+        break;
+    case EVENT_CMD_DISABLE_INPUT_PORT:  /* PortDisable(INPUT_PORT) */
+    {
+        if (!CHECK_PORT_ENABLED((&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]))) {
+            /* event was already handled */
+            break;
+        }
+
+        Exynos_OMX_DisablePort(pOMXComponent, INPUT_PORT_INDEX);
+
+        pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portState = EXYNOS_OMX_PortStateLoaded;
+
+        if (pExynosComponent->pCallbacks != NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_EventCmdComplete(Disable/input port)", pExynosComponent, __FUNCTION__);
+
+            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventCmdComplete,
+                                                       OMX_CommandPortDisable, INPUT_PORT_INDEX, NULL);
+        }
+    }
+        break;
+    case EVENT_CMD_DISABLE_OUTPUT_PORT:
+    {
+        if (!CHECK_PORT_ENABLED((&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]))) {
+            /* event was already handled */
+            break;
+        }
+
+        Exynos_OMX_DisablePort(pOMXComponent, OUTPUT_PORT_INDEX);
+
+        pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portState = EXYNOS_OMX_PortStateLoaded;
+
+        if (pExynosComponent->pCallbacks != NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_EventCmdComplete(Disable/output port)", pExynosComponent, __FUNCTION__);
+
+            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventCmdComplete,
+                                                       OMX_CommandPortDisable, OUTPUT_PORT_INDEX, NULL);
+        }
+    }
+        break;
+    case EVENT_CMD_ENABLE_INPUT_PORT:  /* PortEnable(INPUT_PORT) */
+    {
+        if (CHECK_PORT_ENABLED((&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]))) {
+            /* event was already handled */
+            break;
+        }
+
+        Exynos_OMX_EnablePort(pOMXComponent, INPUT_PORT_INDEX);
+
+        pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portState = EXYNOS_OMX_PortStateIdle;
+
+        if (pExynosComponent->pCallbacks != NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(Enable/input port)", pExynosComponent, __FUNCTION__);
+
+            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventCmdComplete,
+                                                       OMX_CommandPortEnable, INPUT_PORT_INDEX, NULL);
+        }
+    }
+        break;
+    case EVENT_CMD_ENABLE_OUTPUT_PORT:  /* PortEnable(OUTPUT_PORT) */
+    {
+        if (CHECK_PORT_ENABLED((&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]))) {
+            /* event was already handled */
+            break;
+        }
+
+        Exynos_OMX_EnablePort(pOMXComponent, OUTPUT_PORT_INDEX);
+
+        pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portState = EXYNOS_OMX_PortStateIdle;
+
+        if (pExynosComponent->pCallbacks != NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(Enable/output port)", pExynosComponent, __FUNCTION__);
+
+            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventCmdComplete,
+                                                       OMX_CommandPortEnable, OUTPUT_PORT_INDEX, NULL);
+        }
+    }
+        break;
+    default:
+        ret = OMX_ErrorBadParameter;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_MessageHandlerThread(OMX_PTR threadData)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if (threadData == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    while (pExynosComponent->bExitMessageHandlerThread == OMX_FALSE) {
+        EXYNOS_OMX_MESSAGE *pMessage = NULL;
+
+        Exynos_OSAL_SemaphoreWait(pExynosComponent->hSemaMsgWait);
+
+        pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosComponent->messageQ);
+        if (pMessage != NULL) {
+            switch ((int)pMessage->type) {
+            case OMX_CommandStateSet:
+            {
+                Exynos_SetStateSet(pExynosComponent, pMessage->param);
+
+                if (pMessage->param != OMX_StateInvalid)
+                    Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgProgress);
+
+                ret = Exynos_OMX_ComponentStateSet(pOMXComponent, pMessage->param);
+
+                if (pMessage->param == OMX_StateInvalid)
+                    Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgProgress);
+            }
+                break;
+            case OMX_CommandFlush:
+            {
+                Exynos_SetPortFlush(pExynosComponent, pMessage->param);
+
+                Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgProgress);
+
+                ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, pMessage->param, OMX_TRUE);
+            }
+                break;
+            case OMX_CommandPortDisable:
+            {
+                Exynos_SetPortDisable(pExynosComponent, pMessage->param);
+
+                Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgProgress);
+
+                ret = Exynos_OMX_PortDisableProcess(pOMXComponent, pMessage->param);
+            }
+                break;
+            case OMX_CommandPortEnable:
+            {
+                Exynos_SetPortEnable(pExynosComponent, pMessage->param);
+
+                Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgProgress);
+
+                ret = Exynos_OMX_PortEnableProcess(pOMXComponent, pMessage->param);
+            }
+                break;
+            case OMX_CommandMarkBuffer:
+            {
+                OMX_U32 nPortIndex = pMessage->param;
+
+                if ((pMessage->pCmdData != NULL) &&
+                    ((nPortIndex == INPUT_PORT_INDEX) ||
+                     (nPortIndex == OUTPUT_PORT_INDEX))) {
+                    OMX_MARKTYPE *pMarkType = (OMX_MARKTYPE *)(pMessage->pCmdData);
+
+                    pExynosComponent->pExynosPort[nPortIndex].markType.hMarkTargetComponent = pMarkType->hMarkTargetComponent;
+                    pExynosComponent->pExynosPort[nPortIndex].markType.pMarkData            = pMarkType->pMarkData;
+                }
+            }
+                break;
+            case Exynos_OMX_CommandSendEvent:
+            {
+                Exynos_OMX_EventHandler(pOMXComponent, (EVENT_COMMAD_TYPE)pMessage->param);
+            }
+                break;
+            case EXYNOS_OMX_CommandComponentDeInit:
+            {
+                pExynosComponent->bExitMessageHandlerThread = OMX_TRUE;
+            }
+                break;
+            default:
+                break;
+            }
+
+            Exynos_OSAL_Free(pMessage);
+            pMessage = NULL;
+        }
+    }
+
+    Exynos_OSAL_ThreadExit(NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_CommandQueue(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
+    OMX_COMMANDTYPE           Cmd,
+    OMX_U32                   nParam,
+    OMX_PTR                   pCmdData)
+{
+    OMX_ERRORTYPE       ret     = OMX_ErrorNone;
+    EXYNOS_OMX_MESSAGE *command = NULL;
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    command = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
+    if (command == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Exynos_OSAL_Malloc()", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    command->type       = (OMX_U32)Cmd;
+    command->param      = nParam;
+    command->pCmdData   = pCmdData;
+
+    ret = Exynos_OSAL_Queue(&pExynosComponent->messageQ, (void *)command);
+    if (ret != 0) {
+        Exynos_OSAL_Free(command);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgWait);
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pParams)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pParams == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    switch (nParamIndex) {
+    case OMX_IndexParamAudioInit:
+    case OMX_IndexParamVideoInit:
+    case OMX_IndexParamImageInit:
+    case OMX_IndexParamOtherInit:
+    {
+        OMX_PORT_PARAM_TYPE *pPortParam = (OMX_PORT_PARAM_TYPE *)pParams;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortParam, sizeof(OMX_PORT_PARAM_TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pPortParam->nPorts               = 0;
+        pPortParam->nStartPortNumber     = 0;
+    }
+        break;
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pDstPortDef    = (OMX_PARAM_PORTDEFINITIONTYPE *)pParams;
+        OMX_U32                       nPortIndex     = pDstPortDef->nPortIndex;
+        EXYNOS_OMX_BASEPORT          *pExynosPort    = NULL;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+        Exynos_OSAL_Memcpy(((char *)pDstPortDef) + nOffset,
+                           ((char *)&pExynosPort->portDefinition) + nOffset,
+                           pDstPortDef->nSize - nOffset);
+    }
+        break;
+    case OMX_IndexParamPriorityMgmt:
+    {
+        OMX_PRIORITYMGMTTYPE *pPriority = (OMX_PRIORITYMGMTTYPE *)pParams;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPriority, sizeof(OMX_PRIORITYMGMTTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pPriority->nGroupID       = pExynosComponent->compPriority.nGroupID;
+        pPriority->nGroupPriority = pExynosComponent->compPriority.nGroupPriority;
+    }
+        break;
+
+    case OMX_IndexParamCompBufferSupplier:
+    {
+        OMX_PARAM_BUFFERSUPPLIERTYPE *pSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE *)pParams;
+        OMX_U32                       nPortIndex    = pSupplierType->nPortIndex;
+        EXYNOS_OMX_BASEPORT          *pExynosPort   = NULL;
+
+        if ((pExynosComponent->currentState == OMX_StateLoaded) ||
+            (pExynosComponent->currentState == OMX_StateWaitForResources)) {
+            if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+                ret = OMX_ErrorBadPortIndex;
+                goto EXIT;
+            }
+
+            ret = Exynos_OMX_Check_SizeVersion(pSupplierType, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+                goto EXIT;
+            }
+
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+            if (pExynosPort->portDefinition.eDir == OMX_DirInput) {
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    pSupplierType->eBufferSupplier = OMX_BufferSupplyInput;
+                } else if (CHECK_PORT_TUNNELED(pExynosPort)) {
+                    pSupplierType->eBufferSupplier = OMX_BufferSupplyOutput;
+                } else {
+                    pSupplierType->eBufferSupplier = OMX_BufferSupplyUnspecified;
+                }
+            } else {
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    pSupplierType->eBufferSupplier = OMX_BufferSupplyOutput;
+                } else if (CHECK_PORT_TUNNELED(pExynosPort)) {
+                    pSupplierType->eBufferSupplier = OMX_BufferSupplyInput;
+                } else {
+                    pSupplierType->eBufferSupplier = OMX_BufferSupplyUnspecified;
+                }
+            }
+        }
+        else
+        {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+    }
+        break;
+    default:
+    {
+        ret = OMX_ErrorUnsupportedIndex;
+        goto EXIT;
+    }
+        break;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_IN OMX_PTR        pParams)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pParams == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    switch (nParamIndex) {
+    case OMX_IndexParamAudioInit:
+    case OMX_IndexParamVideoInit:
+    case OMX_IndexParamImageInit:
+    case OMX_IndexParamOtherInit:
+    {
+        OMX_PORT_PARAM_TYPE *pPortParam = (OMX_PORT_PARAM_TYPE *)pParams;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortParam, sizeof(OMX_PORT_PARAM_TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        /* ret = OMX_ErrorUndefined; */
+        /* Exynos_OSAL_Memcpy(&pExynosComponent->portParam, pPortParam, sizeof(OMX_PORT_PARAM_TYPE)); */
+    }
+        break;
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pSrcPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *)pParams;
+        OMX_U32                       nPortIndex  = pSrcPortDef->nPortIndex;
+        EXYNOS_OMX_BASEPORT          *pExynosPort = NULL;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+        if (pSrcPortDef->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Memcpy(((char *)&pExynosPort->portDefinition) + nOffset,
+                           ((char *)pSrcPortDef) + nOffset,
+                           pSrcPortDef->nSize - nOffset);
+    }
+        break;
+    case OMX_IndexParamPriorityMgmt:
+    {
+        OMX_PRIORITYMGMTTYPE *pPriority = (OMX_PRIORITYMGMTTYPE *)pParams;
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pPriority, sizeof(OMX_PRIORITYMGMTTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosComponent->compPriority.nGroupID         = pPriority->nGroupID;
+        pExynosComponent->compPriority.nGroupPriority   = pPriority->nGroupPriority;
+    }
+        break;
+    case OMX_IndexParamCompBufferSupplier:
+    {
+        OMX_PARAM_BUFFERSUPPLIERTYPE *pSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE *)pParams;
+        OMX_U32                       nPortIndex    = pSupplierType->nPortIndex;
+        EXYNOS_OMX_BASEPORT          *pExynosPort   = NULL;
+
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pSupplierType, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        if (pSupplierType->eBufferSupplier == OMX_BufferSupplyUnspecified) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        if (CHECK_PORT_TUNNELED(pExynosPort) == 0) {
+            ret = OMX_ErrorNone; /*OMX_ErrorNone ?????*/
+            goto EXIT;
+        }
+
+        if (pExynosPort->portDefinition.eDir == OMX_DirInput) {
+            if (pSupplierType->eBufferSupplier == OMX_BufferSupplyInput) {
+                /*
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    ret = OMX_ErrorNone;
+                }
+                */
+                pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER;
+                pSupplierType->nPortIndex = pExynosPort->tunneledPort;
+
+                ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, pSupplierType);
+
+                goto EXIT;
+            } else if (pSupplierType->eBufferSupplier == OMX_BufferSupplyOutput) {
+                ret = OMX_ErrorNone;
+
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER;
+                    pSupplierType->nPortIndex = pExynosPort->tunneledPort;
+
+                    ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, pSupplierType);
+                }
+
+                goto EXIT;
+            }
+        } else if (pExynosPort->portDefinition.eDir == OMX_DirOutput) {
+            if (pSupplierType->eBufferSupplier == OMX_BufferSupplyInput) {
+                ret = OMX_ErrorNone;
+
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER;
+                    ret = OMX_ErrorNone;
+                }
+
+                goto EXIT;
+            } else if (pSupplierType->eBufferSupplier == OMX_BufferSupplyOutput) {
+                /*
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    ret = OMX_ErrorNone;
+                }
+                */
+
+                pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER;
+                ret = OMX_ErrorNone;
+
+                goto EXIT;
+            }
+        }
+    }
+        break;
+    default:
+    {
+        ret = OMX_ErrorUnsupportedIndex;
+        goto EXIT;
+    }
+        break;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_GetConfig(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nConfigIndex,
+    OMX_INOUT OMX_PTR     pConfigs)
+{
+    OMX_ERRORTYPE             ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pConfigs == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    switch (nConfigIndex) {
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_SetConfig(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nConfigIndex,
+    OMX_IN OMX_PTR        pConfigs)
+{
+    OMX_ERRORTYPE             ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pConfigs == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    switch (nConfigIndex) {
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_GetExtensionIndex(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE *pIndexType)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorBadParameter;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_PTR Exynos_OMX_MakeDynamicConfig(
+    OMX_INDEXTYPE   nConfigIndex,
+    OMX_PTR         pConfigs)
+{
+    OMX_PTR ret                  = NULL;
+    OMX_S32 nConfigSize = 0;
+
+    switch ((int)nConfigIndex) {
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        nConfigSize = sizeof(OMX_U32);
+
+        ret = Exynos_OSAL_Malloc(sizeof(OMX_U32) + nConfigSize);
+    }
+        break;
+    case OMX_IndexConfigVideoRoiInfo:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *pRoiInfo       = (EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *)pConfigs;
+        OMX_S32                          nRoiMBInfoSize = 0;
+
+        nConfigSize = *(OMX_U32 *)pConfigs;
+
+        if (pRoiInfo->bUseRoiInfo == OMX_TRUE)
+            nRoiMBInfoSize = pRoiInfo->nRoiMBInfoSize;
+
+        ret = Exynos_OSAL_Malloc(sizeof(OMX_U32) + nConfigSize + nRoiMBInfoSize);
+
+        if (ret != NULL)
+            Exynos_OSAL_Memcpy((OMX_PTR)((OMX_U8 *)ret + sizeof(OMX_U32) + nConfigSize), pRoiInfo->pRoiMBInfo, nRoiMBInfoSize);
+    }
+        break;
+    default:
+        nConfigSize = *(OMX_U32 *)pConfigs;
+
+        ret = Exynos_OSAL_Malloc(sizeof(OMX_U32) + nConfigSize);
+        break;
+    }
+
+    if (ret != NULL) {
+        *((OMX_S32 *)ret) = (OMX_S32)nConfigIndex;
+        Exynos_OSAL_Memcpy((OMX_PTR)((OMX_U8 *)ret + sizeof(OMX_U32)), pConfigs, nConfigSize);
+    }
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_SendEventCommand(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    EVENT_COMMAD_TYPE            Cmd,
+    OMX_PTR                      pCmdData)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] current state is OMX_StateInvalid", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_CommandQueue(pExynosComponent, (OMX_COMMANDTYPE)Exynos_OMX_CommandSendEvent, Cmd, pCmdData);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+void Exynos_OMX_Component_AbnormalTermination(OMX_HANDLETYPE hComponent)
+{
+    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort      = NULL;
+
+    int i = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    if (pOMXComponent->pComponentPrivate == NULL)
+        goto EXIT;
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    /* clear a msg command piled on queue */
+    while(Exynos_OSAL_GetElemNum(&pExynosComponent->messageQ) > 0)
+        Exynos_OSAL_Free(Exynos_OSAL_Dequeue(&pExynosComponent->messageQ));
+
+    pExynosComponent->abendState = OMX_TRUE;
+
+    /* change to invalid state */
+    Exynos_OMX_SendCommand(hComponent, OMX_CommandStateSet, OMX_StateInvalid, NULL);
+
+EXIT:
+    FunctionOut();
+
+    return;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BaseComponent_Constructor(
+    OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE             ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] lib version is %s", __FUNCTION__, IS_64BIT_OS? "64bit":"32bit");
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] OMX_ErrorBadParameter (0x%x)", __FUNCTION__, ret);
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASECOMPONENT));
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Malloc (0x%x)", __FUNCTION__, ret);
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent, 0, sizeof(EXYNOS_OMX_BASECOMPONENT));
+    pOMXComponent->pComponentPrivate = (OMX_PTR)pExynosComponent;
+
+    ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->hSemaMsgWait);
+    if (ret != OMX_ErrorNone) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SemaphoreCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->hSemaMsgProgress);
+    if (ret != OMX_ErrorNone) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SemaphoreCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_MutexCreate(&pExynosComponent->compMutex);
+    if (ret != OMX_ErrorNone) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_MutexCreate(&pExynosComponent->compEventMutex);
+    if (ret != OMX_ErrorNone) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to MutexCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        goto EXIT;
+    }
+
+    pExynosComponent->bExitMessageHandlerThread = OMX_FALSE;
+    Exynos_OSAL_QueueCreate(&pExynosComponent->messageQ, MAX_QUEUE_ELEMENTS);
+    ret = Exynos_OSAL_ThreadCreate(&pExynosComponent->hMessageHandler, Exynos_OMX_MessageHandlerThread, pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ThreadCreate (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        goto EXIT;
+    }
+
+    Exynos_OSAL_QueueCreate(&pExynosComponent->dynamicConfigQ, MAX_QUEUE_ELEMENTS);
+
+    pOMXComponent->GetComponentVersion = &Exynos_OMX_GetComponentVersion;
+    pOMXComponent->SendCommand         = &Exynos_OMX_SendCommand;
+    pOMXComponent->GetState            = &Exynos_OMX_GetState;
+    pOMXComponent->SetCallbacks        = &Exynos_OMX_SetCallbacks;
+
+#ifdef EGL_IMAGE_SUPPORT
+    pOMXComponent->UseEGLImage         = &Exynos_OMX_UseEGLImage;
+#endif
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor(
+    OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE             ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+    OMX_S32                   semaValue = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    while(Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+        Exynos_OSAL_Free(Exynos_OSAL_Dequeue(&pExynosComponent->dynamicConfigQ));
+    }
+    Exynos_OSAL_QueueTerminate(&pExynosComponent->dynamicConfigQ);
+
+    Exynos_OMX_CommandQueue(pExynosComponent, (OMX_COMMANDTYPE)EXYNOS_OMX_CommandComponentDeInit, 0, NULL);
+    Exynos_OSAL_SleepMillisec(0);
+    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->hSemaMsgWait, &semaValue);
+    if (semaValue == 0)
+        Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgWait);
+    Exynos_OSAL_SemaphorePost(pExynosComponent->hSemaMsgWait);
+
+    Exynos_OSAL_ThreadTerminate(pExynosComponent->hMessageHandler);
+    pExynosComponent->hMessageHandler = NULL;
+
+    Exynos_OSAL_MutexTerminate(pExynosComponent->compEventMutex);
+    pExynosComponent->compMutex = NULL;
+
+    Exynos_OSAL_MutexTerminate(pExynosComponent->compMutex);
+    pExynosComponent->compMutex = NULL;
+
+    Exynos_OSAL_SemaphoreTerminate(pExynosComponent->hSemaMsgProgress);
+    pExynosComponent->hSemaMsgProgress = NULL;
+
+    Exynos_OSAL_SemaphoreTerminate(pExynosComponent->hSemaMsgWait);
+    pExynosComponent->hSemaMsgWait = NULL;
+    Exynos_OSAL_QueueTerminate(&pExynosComponent->messageQ);
+
+    Exynos_OSAL_Free(pExynosComponent);
+    pExynosComponent = NULL;
+
+    ret = OMX_ErrorNone;
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/common/Exynos_OMX_Basecomponent.h b/openmax/component/common/Exynos_OMX_Basecomponent.h
new file mode 100755 (executable)
index 0000000..3e1769c
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Basecomponent.h
+ * @brief
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ *             Taehwan Kim (t_h.kim@samsung.com)
+ * @version    2.5.0
+ * @history
+ *    2012.02.20 : Create
+*    2017.08.03 : Change event handling
+ */
+
+#ifndef EXYNOS_OMX_BASECOMP
+#define EXYNOS_OMX_BASECOMP
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OSAL_Queue.h"
+#include "Exynos_OMX_Baseport.h"
+
+
+typedef struct _EXYNOS_OMX_MESSAGE
+{
+    OMX_U32 type;
+    OMX_U32 param;
+    OMX_PTR pCmdData;
+} EXYNOS_OMX_MESSAGE;
+
+/* for Check TimeStamp after Seek */
+typedef struct _EXYNOS_OMX_TIMESTAMP
+{
+    OMX_BOOL  needSetStartTimeStamp;
+    OMX_BOOL  needCheckStartTimeStamp;
+    OMX_TICKS startTimeStamp;
+    OMX_U32   nStartFlags;
+} EXYNOS_OMX_TIMESTAMP;
+
+typedef struct _EXYNOS_OMX_BASECOMPONENT
+{
+    OMX_STRING                  componentName;
+    OMX_VERSIONTYPE             componentVersion;
+    OMX_VERSIONTYPE             specVersion;
+
+    OMX_STATETYPE               currentState;
+    EXYNOS_OMX_TRANS_STATETYPE  transientState;
+    OMX_BOOL                    abendState;
+
+    EXYNOS_CODEC_TYPE           codecType;
+    EXYNOS_OMX_PRIORITYMGMTTYPE compPriority;
+    OMX_MARKTYPE                propagateMarkType;
+    OMX_HANDLETYPE              compMutex;
+    OMX_HANDLETYPE              compEventMutex;
+
+    OMX_HANDLETYPE              hComponentHandle;
+
+    /* Message Handler */
+    OMX_BOOL                    bExitMessageHandlerThread;
+    OMX_HANDLETYPE              hMessageHandler;
+    OMX_HANDLETYPE              hSemaMsgWait;
+    OMX_HANDLETYPE              hSemaMsgProgress;
+    EXYNOS_QUEUE                messageQ;
+    EXYNOS_QUEUE                dynamicConfigQ;
+
+    /* Port */
+    OMX_PORT_PARAM_TYPE         portParam;
+    EXYNOS_OMX_BASEPORT        *pExynosPort;
+
+    /* Callback function */
+    OMX_CALLBACKTYPE           *pCallbacks;
+    OMX_PTR                     callbackData;
+
+    /* Save Timestamp */
+    OMX_BOOL                    bTimestampSlotUsed[MAX_TIMESTAMP];
+    OMX_TICKS                   timeStamp[MAX_TIMESTAMP];
+    EXYNOS_OMX_TIMESTAMP        checkTimeStamp;
+
+    /* Save Flags */
+    OMX_U32                     nFlags[MAX_FLAGS];
+
+    OMX_BOOL                    getAllDelayBuffer;
+    OMX_BOOL                    reInputData;
+
+    OMX_BOOL bUseFlagEOF;
+    OMX_BOOL bSaveFlagEOS;    /* bSaveFlagEOS is OMX_TRUE, if EOS flag is incoming. */
+    OMX_BOOL bBehaviorEOS;    /* bBehaviorEOS is OMX_TRUE, if EOS flag with Data are incoming. */
+
+    OMX_PTR                     vendorExts[MAX_VENDOR_EXT_NUM];
+
+    OMX_ERRORTYPE (*exynos_codec_componentInit)(OMX_COMPONENTTYPE *pOMXComponent);
+    OMX_ERRORTYPE (*exynos_codec_componentTerminate)(OMX_COMPONENTTYPE *pOMXComponent);
+
+#ifdef TUNNELING_SUPPORT
+    OMX_ERRORTYPE (*exynos_AllocateTunnelBuffer)(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex);
+    OMX_ERRORTYPE (*exynos_FreeTunnelBuffer)(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex);
+#endif
+
+    OMX_ERRORTYPE (*exynos_BufferProcessCreate)(OMX_HANDLETYPE pOMXComponent);
+    OMX_ERRORTYPE (*exynos_BufferProcessTerminate)(OMX_HANDLETYPE pOMXComponent);
+    OMX_ERRORTYPE (*exynos_BufferFlush)(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent);
+} EXYNOS_OMX_BASECOMPONENT;
+
+OMX_ERRORTYPE Exynos_OMX_GetParameter(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nParamIndex,
+    OMX_PTR        pParams);
+
+OMX_ERRORTYPE Exynos_OMX_SetParameter(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nParamIndex,
+    OMX_PTR        pParams);
+
+OMX_ERRORTYPE Exynos_OMX_GetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nConfigIndex,
+    OMX_PTR        pConfigs);
+
+OMX_ERRORTYPE Exynos_OMX_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nConfigIndex,
+    OMX_PTR        pConfigs);
+
+OMX_ERRORTYPE Exynos_OMX_GetExtensionIndex(
+    OMX_HANDLETYPE  hComponent,
+    OMX_STRING      cParameterName,
+    OMX_INDEXTYPE  *pIndexType);
+
+OMX_PTR Exynos_OMX_MakeDynamicConfig(OMX_INDEXTYPE nConfigIndex, OMX_PTR pConfigs);
+OMX_ERRORTYPE Exynos_OMX_SendEventCommand(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, EVENT_COMMAD_TYPE Cmd, OMX_PTR pCmdData);
+void Exynos_OMX_Component_AbnormalTermination(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_BaseComponent_Constructor(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor(OMX_HANDLETYPE hComponent);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_ERRORTYPE Exynos_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size);
+
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/common/Exynos_OMX_Baseport.c b/openmax/component/common/Exynos_OMX_Baseport.c
new file mode 100755 (executable)
index 0000000..29d50ef
--- /dev/null
@@ -0,0 +1,1167 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Baseport.c
+ * @brief
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ *             Taehwan Kim (t_h.kim@samsung.com)
+ * @version    2.5.0
+ * @history
+ *    2012.02.20 : Create
+ *    2017.08.03 : Change event handling
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OSAL_Memory.h"
+
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Basecomponent.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_BASE_PORT"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+#ifdef PERFORMANCE_DEBUG
+#include "Exynos_OSAL_ETC.h"
+#endif
+
+#include "Exynos_OSAL_Platform.h"
+
+
+OMX_ERRORTYPE Exynos_OMX_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader)
+{
+    OMX_ERRORTYPE             ret = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT      *pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_U32                   i = 0;
+    OMX_BOOL                  bBufferFind = OMX_FALSE;
+
+    Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (bufferHeader == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
+            if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_TRUE) {
+                pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_FALSE;
+                bBufferFind = OMX_TRUE;
+                break;
+            } else {
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Trying to return the input buffer without ownership!!", pExynosComponent, __FUNCTION__);
+            }
+        }
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_CountDecrease(pExynosPort->hBufferCount, bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+    Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+
+    if ((bBufferFind == OMX_TRUE) &&
+        (bufferHeader != NULL) &&
+        (bufferHeader->pBuffer != NULL) &&
+        (pExynosComponent->pCallbacks != NULL)) {
+        pExynosComponent->pCallbacks->EmptyBufferDone(pOMXComponent,
+                                                      pExynosComponent->callbackData,
+                                                      bufferHeader);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bufferHeader: %p", pExynosComponent, __FUNCTION__, bufferHeader);
+    }
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader)
+{
+    OMX_ERRORTYPE             ret = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT      *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                   i = 0;
+    OMX_BOOL                  bBufferFind = OMX_FALSE;
+    Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
+    for (i = 0; i < MAX_BUFFER_NUM; i++) {
+        if (bufferHeader == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
+            if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_TRUE) {
+                bBufferFind = OMX_TRUE;
+                pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_FALSE;
+                break;
+            } else {
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Trying to return the output buffer without ownership!!", pExynosComponent, __FUNCTION__);
+            }
+        }
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    {
+        EXYNOS_OMX_BASEPORT      *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+        EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+        BUFFER_TIME inputBufferInfo, outBufferInfo;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "################################################################################");
+        Exynos_OSAL_GetCountInfoUseTimestamp(pExynosInputPort->hBufferCount, bufferHeader->nTimeStamp, &inputBufferInfo);
+        Exynos_OSAL_GetCountInfoUseTimestamp(pExynosOutputPort->hBufferCount, bufferHeader->nTimeStamp, &outBufferInfo);
+        Exynos_OSAL_PrintCountInfo(inputBufferInfo, outBufferInfo);
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "################################################################################");
+    }
+
+    Exynos_OSAL_CountDecrease(pExynosPort->hBufferCount, bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+
+    if ((bBufferFind == OMX_TRUE) &&
+        (bufferHeader != NULL) &&
+        (bufferHeader->pBuffer != NULL) &&
+        (pExynosComponent->pCallbacks != NULL)) {
+        pExynosComponent->pCallbacks->FillBufferDone(pOMXComponent,
+                                                     pExynosComponent->callbackData,
+                                                     bufferHeader);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bufferHeader: %p", pExynosComponent, __FUNCTION__, bufferHeader);
+    }
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BufferFlushProcess(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_S32             nPortIndex,
+    OMX_BOOL            bEvent)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+    OMX_S32                   nIndex            = 0;
+
+    OMX_U32 i, cnt;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    cnt = (nPortIndex == ALL_PORT_INDEX)? ALL_PORT_NUM:1;
+    for (i = 0; i < cnt; i++) {
+        if (nPortIndex == ALL_PORT_INDEX)
+            nIndex = i;
+        else
+            nIndex = nPortIndex;
+
+        pExynosPort = &(pExynosComponent->pExynosPort[nIndex]);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Flush %s Port", pExynosComponent, __FUNCTION__,
+                                (nIndex == INPUT_PORT_INDEX)? "input":"output");
+        ret = pExynosComponent->exynos_BufferFlush(pOMXComponent, nIndex, bEvent);
+        if (ret == OMX_ErrorNone) {
+            pExynosPort->portState = EXYNOS_OMX_PortStateIdle;
+
+            if ((bEvent == OMX_TRUE) &&
+                (pExynosComponent->pCallbacks != NULL)) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_EventCmdComplete(Flush/%s port)",
+                                                pExynosComponent, __FUNCTION__, (nIndex == INPUT_PORT_INDEX)? "input":"output");
+
+                pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                           pExynosComponent->callbackData,
+                                                           OMX_EventCmdComplete,
+                                                           OMX_CommandFlush, nIndex, NULL);
+            }
+        }
+    }
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] (0x%x)", pExynosComponent, __FUNCTION__, ret);
+
+        if ((pExynosComponent != NULL) &&
+            (pExynosComponent->pCallbacks != NULL)) {
+            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventError,
+                                                       ret, 0, NULL);
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_DisablePort(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_S32             nPortIndex)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    pExynosPort->portDefinition.bEnabled = OMX_FALSE;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_PortDisableProcess(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_S32             nPortIndex)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort      = NULL;
+    OMX_S32                   nIndex           = 0;
+
+    OMX_U32 i, cnt;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    cnt = (nPortIndex == ALL_PORT_INDEX)? ALL_PORT_NUM:1;
+    for (i = 0; i < cnt; i++) {
+        if (nPortIndex == ALL_PORT_INDEX)
+            nIndex = i;
+        else
+            nIndex = nPortIndex;
+
+        pExynosPort = &(pExynosComponent->pExynosPort[nIndex]);
+
+        if ((pExynosComponent->currentState == OMX_StateExecuting) ||
+            (pExynosComponent->currentState == OMX_StatePause)) {
+            /* do port flush */
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] Before disabling %s port, do flush",
+                                                pExynosComponent, __FUNCTION__,
+                                                (nIndex == INPUT_PORT_INDEX)? "input":"output");
+
+            pExynosPort->portState = EXYNOS_OMX_PortStateFlushingForDisable;
+
+            ret = pExynosComponent->exynos_BufferFlush(pOMXComponent, nIndex, OMX_FALSE);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port is flushed", pExynosComponent, __FUNCTION__,
+                                    (nIndex == INPUT_PORT_INDEX)? "input":"output");
+            if (ret != OMX_ErrorNone)
+                goto EXIT;
+
+            pExynosPort->portState = EXYNOS_OMX_PortStateDisabling;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] Disable %s Port", pExynosComponent, __FUNCTION__,
+                                (nIndex == INPUT_PORT_INDEX)? "input":"output");
+
+        if (CHECK_PORT_ENABLED(pExynosPort)) {
+            if (pExynosComponent->currentState != OMX_StateLoaded) {
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
+                        EXYNOS_OMX_MESSAGE *pMessage = (EXYNOS_OMX_MESSAGE*)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+                        if (pMessage != NULL)
+                            Exynos_OSAL_Free(pMessage);
+                    }
+                }
+
+                if (pExynosPort->exceptionFlag == NEED_PORT_DISABLE)
+                    pExynosPort->exceptionFlag = GENERAL_STATE;
+            }
+
+            if (pExynosPort->assignedBufferNum <= 0) {
+                Exynos_OMX_SendEventCommand(pExynosComponent,
+                                            ((nIndex == INPUT_PORT_INDEX)? EVENT_CMD_DISABLE_INPUT_PORT:EVENT_CMD_DISABLE_OUTPUT_PORT),
+                                            NULL);
+            }
+        }
+    }
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] (0x%x)", pExynosComponent, __FUNCTION__, ret);
+
+        if ((pExynosComponent != NULL) &&
+            (pExynosComponent->pCallbacks != NULL)) {
+            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventError,
+                                                       ret, 0, NULL);
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_EnablePort(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_S32             nPortIndex)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+
+    OMX_U32 i = 0;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    pExynosPort->exceptionFlag              = GENERAL_STATE;
+    pExynosPort->portDefinition.bEnabled    = OMX_TRUE;
+
+    if (pExynosPort->portWayType == WAY2_PORT) {
+        for (i = 0; i < ALL_WAY_NUM; i++) {
+            if (pExynosPort->semWaitPortEnable[i] != NULL)
+                Exynos_OSAL_SemaphorePost(pExynosPort->semWaitPortEnable[i]);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_PortEnableProcess(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_S32             nPortIndex)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort      = NULL;
+    OMX_S32                   nIndex           = 0;
+
+    OMX_U32 i, cnt;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    cnt = (nPortIndex == ALL_PORT_INDEX)? ALL_PORT_NUM:1;
+    for (i = 0; i < cnt; i++) {
+        if (nPortIndex == ALL_PORT_INDEX)
+            nIndex = i;
+        else
+            nIndex = nPortIndex;
+
+        pExynosPort = &(pExynosComponent->pExynosPort[nIndex]);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] Enable %s Port", pExynosComponent, __FUNCTION__,
+                                (nIndex == INPUT_PORT_INDEX)? "input":"output");
+
+        if (CHECK_PORT_POPULATED(pExynosPort)) {
+            Exynos_OMX_SendEventCommand(pExynosComponent,
+                                        ((nIndex == INPUT_PORT_INDEX)? EVENT_CMD_ENABLE_INPUT_PORT:EVENT_CMD_ENABLE_OUTPUT_PORT),
+                                        NULL);
+        }
+    }
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] (0x%x)", pExynosComponent, __FUNCTION__, ret);
+
+        if ((pExynosComponent != NULL) &&
+            (pExynosComponent->pCallbacks != NULL)) {
+            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventError,
+                                                       ret, 0, NULL);
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_EmptyThisBuffer(
+    OMX_IN OMX_HANDLETYPE        hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT         *pExynosPort        = NULL;
+    EXYNOS_OMX_MESSAGE          *message            = NULL;
+
+    OMX_U32 i = 0;
+    OMX_BOOL bFindBuffer = OMX_FALSE;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pBuffer->nInputPortIndex != INPUT_PORT_INDEX) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if ((pExynosComponent->currentState != OMX_StateIdle) &&
+        (pExynosComponent->currentState != OMX_StateExecuting) &&
+        (pExynosComponent->currentState != OMX_StatePause)) {
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    if ((!CHECK_PORT_ENABLED(pExynosPort)) ||
+        (CHECK_PORT_BEING_FLUSHED(pExynosPort) &&
+        (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) ||
+        ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) &&
+        (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] enabled(%d), state(%x), tunneld(%d), supplier(%d)", pExynosComponent, __FUNCTION__,
+                                CHECK_PORT_ENABLED(pExynosPort), pExynosPort->portState,
+                                CHECK_PORT_TUNNELED(pExynosPort), CHECK_PORT_BUFFER_SUPPLIER(pExynosPort));
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
+            if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_FALSE) {
+                pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_TRUE;
+                bFindBuffer = OMX_TRUE;
+                break;
+            } else {
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] input buffer(%p) was already entered!", pExynosComponent, __FUNCTION__, pBuffer);
+            }
+        }
+    }
+
+    if (bFindBuffer == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] EmptyThisBuffer is failed : %p", pExynosComponent, __FUNCTION__, pBuffer);
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+        goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_CountIncrease(pExynosPort->hBufferCount, pBuffer, INPUT_PORT_INDEX);
+#endif
+
+    message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
+    if (message == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+        goto EXIT;
+    }
+    message->type       = EXYNOS_OMX_CommandEmptyBuffer;
+    message->param      = (OMX_U32) i;
+    message->pCmdData   = (OMX_PTR)pBuffer;
+
+    ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message);
+    if (ret != 0) {
+        ret = OMX_ErrorUndefined;
+        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+        goto EXIT;
+    }
+    ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bufferHeader:%p, nAllocLen:%d, nFilledLen:%d, nOffset:%d, nFlags:%x",
+                                            pExynosComponent, __FUNCTION__,
+                                            pBuffer, pBuffer->nAllocLen, pBuffer->nFilledLen, pBuffer->nOffset, pBuffer->nFlags);
+
+    Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FillThisBuffer(
+    OMX_IN OMX_HANDLETYPE        hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT         *pExynosPort        = NULL;
+    EXYNOS_OMX_MESSAGE          *message            = NULL;
+
+    OMX_U32 i = 0;
+    OMX_BOOL bFindBuffer = OMX_FALSE;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pBuffer->nOutputPortIndex != OUTPUT_PORT_INDEX) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if ((pExynosComponent->currentState != OMX_StateIdle) &&
+        (pExynosComponent->currentState != OMX_StateExecuting) &&
+        (pExynosComponent->currentState != OMX_StatePause)) {
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    if ((!CHECK_PORT_ENABLED(pExynosPort)) ||
+        ((CHECK_PORT_BEING_FLUSHED(pExynosPort)) &&
+         (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) ||
+        ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) &&
+         (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] enabled(%d), state(%x), tunneld(%d), supplier(%d)", pExynosComponent, __FUNCTION__,
+                                CHECK_PORT_ENABLED(pExynosPort), pExynosPort->portState,
+                                CHECK_PORT_TUNNELED(pExynosPort), CHECK_PORT_BUFFER_SUPPLIER(pExynosPort));
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
+    for (i = 0; i < MAX_BUFFER_NUM; i++) {
+        if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
+            if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_FALSE) {
+                pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_TRUE;
+                bFindBuffer = OMX_TRUE;
+                break;
+            } else {
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] output buffer(%p) was already entered!", pExynosComponent, __FUNCTION__, pBuffer);
+            }
+        }
+    }
+
+    if (bFindBuffer == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] FillThisBuffer is failed : %p", pExynosComponent, __FUNCTION__, pBuffer);
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+        goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_CountIncrease(pExynosPort->hBufferCount, pBuffer, OUTPUT_PORT_INDEX);
+#endif
+
+    message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
+    if (message == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+        goto EXIT;
+    }
+    message->type       = EXYNOS_OMX_CommandFillBuffer;
+    message->param      = (OMX_U32) i;
+    message->pCmdData   = (OMX_PTR)pBuffer;
+
+    ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message);
+    if (ret != 0) {
+        ret = OMX_ErrorUndefined;
+        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bufferHeader:%p", pExynosComponent, __FUNCTION__, pBuffer);
+
+    Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FillThisBufferAgain(
+    OMX_IN OMX_HANDLETYPE        hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT         *pExynosPort        = NULL;
+    EXYNOS_OMX_MESSAGE          *message            = NULL;
+
+    OMX_U32 i = 0;
+    OMX_BOOL bFindBuffer = OMX_FALSE;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pBuffer->nOutputPortIndex != OUTPUT_PORT_INDEX) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if ((pExynosComponent->currentState != OMX_StateIdle) &&
+        (pExynosComponent->currentState != OMX_StateExecuting) &&
+        (pExynosComponent->currentState != OMX_StatePause)) {
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    if ((!CHECK_PORT_ENABLED(pExynosPort)) ||
+        (CHECK_PORT_BEING_FLUSHED(pExynosPort) &&
+        (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) ||
+        ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) &&
+        (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] enabled(%d), state(%x), tunneld(%d), supplier(%d)", pExynosComponent, __FUNCTION__,
+                                CHECK_PORT_ENABLED(pExynosPort), pExynosPort->portState,
+                                CHECK_PORT_TUNNELED(pExynosPort), CHECK_PORT_BUFFER_SUPPLIER(pExynosPort));
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
+    for (i = 0; i < MAX_BUFFER_NUM; i++) {
+        if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
+            if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_TRUE) {
+                bFindBuffer = OMX_TRUE;
+                break;
+            } else {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] output buffer(%p) is firstly entered!", pExynosComponent, __FUNCTION__, pBuffer);
+            }
+        }
+    }
+
+    if (bFindBuffer == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] FillThisBufferAgain is failed : %p", pExynosComponent, __FUNCTION__, pBuffer);
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+        goto EXIT;
+    }
+
+    message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
+    if (message == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+        goto EXIT;
+    }
+    message->type       = EXYNOS_OMX_CommandFillBuffer;
+    message->param      = (OMX_U32) i;
+    message->pCmdData   = (OMX_PTR)pBuffer;
+
+    ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message);
+    if (ret != 0) {
+        ret = OMX_ErrorUndefined;
+        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
+    Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosInputPort  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosOutputPort = NULL;
+    int i = 0, j = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] OMX_ErrorBadParameter (0x%x) Line:%d", __FUNCTION__, ret, __LINE__);
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] OMX_ErrorBadParameter (0x%x) Line:%d", __FUNCTION__, ret, __LINE__);
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    INIT_SET_SIZE_VERSION(&pExynosComponent->portParam, OMX_PORT_PARAM_TYPE);
+    pExynosComponent->portParam.nPorts = ALL_PORT_NUM;
+    pExynosComponent->portParam.nStartPortNumber = INPUT_PORT_INDEX;
+
+    pExynosPort = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM);
+    if (pExynosPort == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosPort, 0, sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM);
+    pExynosComponent->pExynosPort = pExynosPort;
+
+    /* Input Port */
+    pExynosInputPort = &pExynosPort[INPUT_PORT_INDEX];
+
+    Exynos_OSAL_QueueCreate(&pExynosInputPort->bufferQ, MAX_QUEUE_ELEMENTS);
+
+    pExynosInputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
+    if (pExynosInputPort->extendBufferHeader == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosInputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
+
+    pExynosInputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM);
+    if (pExynosInputPort->bufferStateAllocate == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM);
+
+    pExynosInputPort->bufferSemID = NULL;
+    pExynosInputPort->assignedBufferNum = 0;
+    pExynosInputPort->portState = EXYNOS_OMX_PortStateLoaded;
+    pExynosInputPort->tunneledComponent = NULL;
+    pExynosInputPort->tunneledPort = 0;
+    pExynosInputPort->tunnelBufferNum = 0;
+    pExynosInputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
+    pExynosInputPort->tunnelFlags = 0;
+    pExynosInputPort->supportFormat = NULL;
+    pExynosInputPort->bNeedContigMem = OMX_FALSE;
+    pExynosInputPort->latestTimeStamp = DEFAULT_TIMESTAMP_VAL;
+
+    for (i = 0; i < ALL_WAY_NUM; i++) {
+        ret = Exynos_OSAL_SemaphoreCreate(&(pExynosInputPort->semWaitPortEnable[i]));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SemaphoreCreate (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+            goto EXIT;
+        }
+    }
+
+    INIT_SET_SIZE_VERSION(&pExynosInputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
+    pExynosInputPort->portDefinition.nPortIndex = INPUT_PORT_INDEX;
+    pExynosInputPort->portDefinition.eDir = OMX_DirInput;
+    pExynosInputPort->portDefinition.nBufferCountActual = 0;
+    pExynosInputPort->portDefinition.nBufferCountMin = 0;
+    pExynosInputPort->portDefinition.nBufferSize = 0;
+    pExynosInputPort->portDefinition.bEnabled = OMX_FALSE;
+    pExynosInputPort->portDefinition.bPopulated = OMX_FALSE;
+    pExynosInputPort->portDefinition.eDomain = OMX_PortDomainMax;
+    pExynosInputPort->portDefinition.bBuffersContiguous = OMX_FALSE;
+    pExynosInputPort->portDefinition.nBufferAlignment = 0;
+    pExynosInputPort->markType.hMarkTargetComponent = NULL;
+    pExynosInputPort->markType.pMarkData = NULL;
+    pExynosInputPort->exceptionFlag = GENERAL_STATE;
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_CountCreate(&pExynosInputPort->hBufferCount);
+#endif
+
+    /* Output Port */
+    pExynosOutputPort = &pExynosPort[OUTPUT_PORT_INDEX];
+
+    Exynos_OSAL_QueueCreate(&pExynosOutputPort->bufferQ, MAX_QUEUE_ELEMENTS); /* For in case of "Output Buffer Share", MAX ELEMENTS(DPB + EDPB) */
+
+    pExynosOutputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
+    if (pExynosOutputPort->extendBufferHeader == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosOutputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
+
+    pExynosOutputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM);
+    if (pExynosOutputPort->bufferStateAllocate == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosOutputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM);
+
+    pExynosOutputPort->bufferSemID = NULL;
+    pExynosOutputPort->assignedBufferNum = 0;
+    pExynosOutputPort->portState = EXYNOS_OMX_PortStateLoaded;
+    pExynosOutputPort->tunneledComponent = NULL;
+    pExynosOutputPort->tunneledPort = 0;
+    pExynosOutputPort->tunnelBufferNum = 0;
+    pExynosOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
+    pExynosOutputPort->tunnelFlags = 0;
+    pExynosOutputPort->supportFormat = NULL;
+    pExynosOutputPort->bNeedContigMem = OMX_FALSE;
+    pExynosOutputPort->latestTimeStamp = DEFAULT_TIMESTAMP_VAL;
+
+    for (i = 0; i < ALL_WAY_NUM; i++) {
+        ret = Exynos_OSAL_SemaphoreCreate(&(pExynosOutputPort->semWaitPortEnable[i]));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SemaphoreCreate (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+            goto EXIT;
+        }
+    }
+
+    INIT_SET_SIZE_VERSION(&pExynosOutputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
+    pExynosOutputPort->portDefinition.nPortIndex = OUTPUT_PORT_INDEX;
+    pExynosOutputPort->portDefinition.eDir = OMX_DirOutput;
+    pExynosOutputPort->portDefinition.nBufferCountActual = 0;
+    pExynosOutputPort->portDefinition.nBufferCountMin = 0;
+    pExynosOutputPort->portDefinition.nBufferSize = 0;
+    pExynosOutputPort->portDefinition.bEnabled = OMX_FALSE;
+    pExynosOutputPort->portDefinition.bPopulated = OMX_FALSE;
+    pExynosOutputPort->portDefinition.eDomain = OMX_PortDomainMax;
+    pExynosOutputPort->portDefinition.bBuffersContiguous = OMX_FALSE;
+    pExynosOutputPort->portDefinition.nBufferAlignment = 0;
+    pExynosOutputPort->markType.hMarkTargetComponent = NULL;
+    pExynosOutputPort->markType.pMarkData = NULL;
+    pExynosOutputPort->exceptionFlag = GENERAL_STATE;
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_CountCreate(&pExynosOutputPort->hBufferCount);
+#endif
+
+    pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+    pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
+    pExynosComponent->checkTimeStamp.startTimeStamp = 0;
+    pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
+
+    pOMXComponent->EmptyThisBuffer = &Exynos_OMX_EmptyThisBuffer;
+    pOMXComponent->FillThisBuffer  = &Exynos_OMX_FillThisBuffer;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent != NULL) &&
+        (pExynosComponent->pExynosPort != NULL)) {
+        for (i = 0; i < ALL_PORT_NUM; i++) {
+            pExynosPort = &pExynosComponent->pExynosPort[i];
+
+#ifdef PERFORMANCE_DEBUG
+            Exynos_OSAL_CountTerminate(&pExynosPort->hBufferCount);
+#endif
+            for (j = 0; j < ALL_WAY_NUM; j++) {
+                Exynos_OSAL_SemaphoreTerminate(pExynosPort->semWaitPortEnable[j]);
+                pExynosPort->semWaitPortEnable[j] = NULL;
+            }
+
+            Exynos_OSAL_Free(pExynosPort->bufferStateAllocate);
+            pExynosPort->bufferStateAllocate = NULL;
+            Exynos_OSAL_Free(pExynosPort->extendBufferHeader);
+            pExynosPort->extendBufferHeader = NULL;
+
+            Exynos_OSAL_QueueTerminate(&pExynosPort->bufferQ);
+        }
+
+        Exynos_OSAL_Free(pExynosComponent->pExynosPort);
+        pExynosComponent->pExynosPort = NULL;
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_Port_Destructor(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+
+    int i = 0, j = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    for (i = 0; i < ALL_PORT_NUM; i++) {
+        pExynosPort = &pExynosComponent->pExynosPort[i];
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_CountTerminate(&pExynosPort->hBufferCount);
+#endif
+
+        for (j = 0; j < ALL_WAY_NUM; j++) {
+            Exynos_OSAL_SemaphoreTerminate(pExynosPort->semWaitPortEnable[j]);
+            pExynosPort->semWaitPortEnable[j] = NULL;
+        }
+
+        Exynos_OSAL_Free(pExynosPort->bufferStateAllocate);
+        pExynosPort->bufferStateAllocate = NULL;
+        Exynos_OSAL_Free(pExynosPort->extendBufferHeader);
+        pExynosPort->extendBufferHeader = NULL;
+
+        Exynos_OSAL_QueueTerminate(&pExynosPort->bufferQ);
+    }
+
+    Exynos_OSAL_Free(pExynosComponent->pExynosPort);
+    pExynosComponent->pExynosPort = NULL;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_ResetDataBuffer(EXYNOS_OMX_DATABUFFER *pDataBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if (pDataBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pDataBuffer->dataValid     = OMX_FALSE;
+    pDataBuffer->dataLen       = 0;
+    pDataBuffer->remainDataLen = 0;
+    pDataBuffer->usedDataLen   = 0;
+    pDataBuffer->bufferHeader  = NULL;
+    pDataBuffer->nFlags        = 0;
+    pDataBuffer->timeStamp     = 0;
+    pDataBuffer->pPrivate      = NULL;
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_ResetCodecData(EXYNOS_OMX_DATA *pData)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if (pData == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    /* caution: nPlanes in buffer structure might be used all times */
+    Exynos_OSAL_Memset(&(pData->buffer.fd), 0, sizeof(pData->buffer.fd));
+    Exynos_OSAL_Memset(&(pData->buffer.addr), 0, sizeof(pData->buffer.addr));
+
+    pData->dataLen       = 0;
+    pData->usedDataLen   = 0;
+    pData->remainDataLen = 0;
+    pData->nFlags        = 0;
+    pData->timeStamp     = 0;
+    pData->pPrivate      = NULL;
+    pData->bufferHeader  = NULL;
+
+EXIT:
+    return ret;
+}
+
+int Exynos_GetPlaneFromPort(EXYNOS_OMX_BASEPORT *pPort)
+{
+    int ret = 0;
+
+    if (pPort == NULL)
+        goto EXIT;
+
+    ret = pPort->processData.buffer.nPlanes;
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_SetPlaneToPort(EXYNOS_OMX_BASEPORT *pPort, int nPlaneNum)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if (pPort == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pPort->processData.buffer.nPlanes = nPlaneNum;
+
+EXIT:
+    return ret;
+}
+
diff --git a/openmax/component/common/Exynos_OMX_Baseport.h b/openmax/component/common/Exynos_OMX_Baseport.h
new file mode 100755 (executable)
index 0000000..74d60e2
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Baseport.h
+ * @brief
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ *             Taehwan Kim (t_h.kim@samsung.com)
+ * @version    2.5.0
+ * @history
+ *    2012.02.20 : Create
+ *    2017.08.03 : Change event handling
+ */
+
+#ifndef EXYNOS_OMX_BASE_PORT
+#define EXYNOS_OMX_BASE_PORT
+
+#include "OMX_Component.h"
+#include "Exynos_OMX_Def.h"
+#include "Exynos_OSAL_Queue.h"
+#include "Exynos_OMX_Def.h"
+
+#ifdef PERFORMANCE_DEBUG
+#include <sys/time.h>
+#endif
+
+#define BUFFER_STATE_ALLOCATED  (1 << 0)
+#define BUFFER_STATE_ASSIGNED   (1 << 1)
+#define HEADER_STATE_ALLOCATED  (1 << 2)
+#define BUFFER_STATE_FREE        0
+
+#define DEFAULT_FRAME_WIDTH                 176
+#define DEFAULT_FRAME_HEIGHT                144
+
+#define MAX_BUFFER_NUM          40
+
+#define INPUT_PORT_INDEX    0
+#define OUTPUT_PORT_INDEX   1
+#define ALL_PORT_INDEX     -1
+#define ALL_PORT_NUM        2
+
+#define INPUT_WAY_INDEX    0
+#define OUTPUT_WAY_INDEX   1
+#define ALL_WAY_NUM        2
+
+typedef struct _EXYNOS_OMX_BUFFERHEADERTYPE
+{
+    OMX_BUFFERHEADERTYPE *OMXBufferHeader;
+    OMX_BOOL              bBufferInOMX;
+    OMX_HANDLETYPE        ANBHandle;
+    void                 *pYUVBuf[MAX_BUFFER_PLANE];
+    unsigned long         buf_fd[MAX_BUFFER_PLANE];
+} EXYNOS_OMX_BUFFERHEADERTYPE;
+
+typedef struct _EXYNOS_OMX_DATABUFFER
+{
+    OMX_HANDLETYPE        bufferMutex;
+    OMX_BUFFERHEADERTYPE* bufferHeader;
+    OMX_BOOL              dataValid;
+    OMX_U32               allocSize;
+    OMX_U32               dataLen;
+    OMX_U32               usedDataLen;
+    OMX_U32               remainDataLen;
+    OMX_U32               nFlags;
+    OMX_TICKS             timeStamp;
+    OMX_PTR               pPrivate;
+} EXYNOS_OMX_DATABUFFER;
+
+typedef void* CODEC_EXTRA_BUFFERINFO;
+
+typedef struct _EXYNOS_OMX_MULTIPLANE_BUFFER
+{
+    OMX_U32                 nPlanes;
+    unsigned long           fd[MAX_BUFFER_PLANE];
+    OMX_PTR                 addr[MAX_BUFFER_PLANE];
+    OMX_COLOR_FORMATTYPE    eColorFormat;
+} EXYNOS_OMX_MULTIPLANE_BUFFER;
+
+typedef struct _EXYNOS_OMX_DATA
+{
+    EXYNOS_OMX_MULTIPLANE_BUFFER buffer;
+    OMX_U32   allocSize;
+    OMX_U32   dataLen;
+    OMX_U32   usedDataLen;
+    OMX_U32   remainDataLen;
+    OMX_U32   nFlags;
+    OMX_TICKS timeStamp;
+    OMX_PTR   pPrivate;
+    CODEC_EXTRA_BUFFERINFO extInfo;
+
+    /* For Share Buffer */
+    OMX_BUFFERHEADERTYPE *bufferHeader;
+} EXYNOS_OMX_DATA;
+
+typedef struct _EXYNOS_OMX_WAY1_PORT_DATABUFFER
+{
+    EXYNOS_OMX_DATABUFFER dataBuffer;
+} EXYNOS_OMX_PORT_1WAY_DATABUFFER;
+
+typedef struct _EXYNOS_OMX_WAY2_PORT_DATABUFFER
+{
+    EXYNOS_OMX_DATABUFFER inputDataBuffer;
+    EXYNOS_OMX_DATABUFFER outputDataBuffer;
+} EXYNOS_OMX_PORT_2WAY_DATABUFFER;
+
+typedef enum _EXYNOS_OMX_PORT_WAY_TYPE
+{
+    WAY1_PORT = 0x00,
+    WAY2_PORT,
+} EXYNOS_OMX_PORT_WAY_TYPE;
+
+typedef enum _EXYNOS_OMX_EXCEPTION_STATE
+{
+    GENERAL_STATE = 0x00,
+    NEED_PORT_FLUSH,
+    NEED_PORT_DISABLE,
+    INVALID_STATE,
+} EXYNOS_OMX_EXCEPTION_STATE;
+
+typedef enum _EXYNOS_OMX_PLANE
+{
+    ONE_PLANE       = 0x01,
+    TWO_PLANE       = 0x02,
+    THREE_PLANE     = 0x03,
+/*
+    ANB_START_PLANE = 0x10,
+    ANB_ONE_PLANE   = 0x11,
+    ANB_TWO_PLANE   = 0x12,
+    ANB_THREE_PLANE = 0x13,
+*/
+} EXYNOS_OMX_PLANE;
+
+typedef struct _EXYNOS_OMX_BASEPORT
+{
+    EXYNOS_OMX_BUFFERHEADERTYPE   *extendBufferHeader;
+    OMX_U32                       *bufferStateAllocate;
+    OMX_PARAM_PORTDEFINITIONTYPE   portDefinition;
+    OMX_HANDLETYPE                 bufferSemID;
+    EXYNOS_QUEUE                   bufferQ;
+    OMX_S32                        assignedBufferNum;
+    EXYNOS_OMX_PORT_STATETYPE      portState;
+    OMX_HANDLETYPE                 semWaitPortEnable[ALL_WAY_NUM];
+
+    OMX_MARKTYPE                   markType;
+
+    OMX_CONFIG_RECTTYPE            cropRectangle;
+
+    /* Tunnel Info */
+    OMX_HANDLETYPE                 tunneledComponent;
+    OMX_U32                        tunneledPort;
+    OMX_U32                        tunnelBufferNum;
+    OMX_BUFFERSUPPLIERTYPE         bufferSupplier;
+    OMX_U32                        tunnelFlags;
+
+    OMX_COLOR_FORMATTYPE          *supportFormat;
+    EXYNOS_METADATA_TYPE           eMetaDataType;
+    OMX_BOOL                       bNeedContigMem;   /* contiguous memory : WFD(HDCP) */
+    PLANE_TYPE                     ePlaneType;
+
+    EXYNOS_OMX_BUFFERPROCESS_TYPE  bufferProcessType;
+    EXYNOS_OMX_PORT_WAY_TYPE       portWayType;
+    OMX_HANDLETYPE                 codecSemID;
+    EXYNOS_QUEUE                   codecBufferQ;
+
+    OMX_HANDLETYPE                 pauseEvent;
+
+    /* Buffer */
+    union {
+        EXYNOS_OMX_PORT_1WAY_DATABUFFER port1WayDataBuffer;
+        EXYNOS_OMX_PORT_2WAY_DATABUFFER port2WayDataBuffer;
+    } way;
+
+    /* Data */
+    EXYNOS_OMX_DATA                processData;
+
+    EXYNOS_OMX_VIDEO_HDRSTATICINFO HDRStaticInfo;
+    EXYNOS_OMX_VIDEO_COLORASPECTS  ColorAspects;
+
+    OMX_HANDLETYPE                 hPortMutex;
+    EXYNOS_OMX_EXCEPTION_STATE     exceptionFlag;
+
+    OMX_TICKS                      latestTimeStamp;
+
+#ifdef PERFORMANCE_DEBUG
+    /* For performance debug */
+    OMX_HANDLETYPE                 hBufferCount;
+#endif
+} EXYNOS_OMX_BASEPORT;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_ERRORTYPE Exynos_OMX_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE *bufferHeader);
+OMX_ERRORTYPE Exynos_OMX_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE *bufferHeader);
+
+OMX_ERRORTYPE Exynos_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent);
+
+OMX_ERRORTYPE Exynos_OMX_DisablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex);
+OMX_ERRORTYPE Exynos_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex);
+OMX_ERRORTYPE Exynos_OMX_EnablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex);
+OMX_ERRORTYPE Exynos_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex);
+
+OMX_ERRORTYPE Exynos_OMX_FillThisBufferAgain(OMX_HANDLETYPE hComponent, OMX_BUFFERHEADERTYPE *pBuffer);
+
+OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_Port_Destructor(OMX_HANDLETYPE hComponent);
+
+OMX_ERRORTYPE Exynos_ResetDataBuffer(EXYNOS_OMX_DATABUFFER *pDataBuffer);
+OMX_ERRORTYPE Exynos_ResetCodecData(EXYNOS_OMX_DATA *pData);
+
+int Exynos_GetPlaneFromPort(EXYNOS_OMX_BASEPORT *pPort);
+OMX_ERRORTYPE Exynos_SetPlaneToPort(EXYNOS_OMX_BASEPORT *pPort, int nPlaneNum);
+
+#ifdef __cplusplus
+};
+#endif
+
+
+#endif
diff --git a/openmax/component/common/Exynos_OMX_Resourcemanager.c b/openmax/component/common/Exynos_OMX_Resourcemanager.c
new file mode 100755 (executable)
index 0000000..463e1c5
--- /dev/null
@@ -0,0 +1,591 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Resourcemanager.c
+ * @brief
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *    2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Def.h"
+#include "Exynos_OMX_Resourcemanager.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_Mutex.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_RM"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+#define MAX_RESOURCE_VIDEO_DEC RESOURCE_VIDEO_DEC
+#define MAX_RESOURCE_VIDEO_ENC RESOURCE_VIDEO_ENC
+#define MAX_RESOURCE_AUDIO_DEC RESOURCE_AUDIO_DEC
+#define MAX_RESOURCE_VIDEO_SECURE 2
+/* Add new resource block */
+
+typedef enum _EXYNOS_OMX_RESOURCE
+{
+    VIDEO_DEC,
+    VIDEO_ENC,
+    AUDIO_DEC,
+    VIDEO_SECURE,
+    /* Add new resource block */
+    RESOURCE_MAX
+} EXYNOS_OMX_RESOURCE;
+
+typedef struct _EXYNOS_OMX_RM_COMPONENT_LIST
+{
+    OMX_COMPONENTTYPE   *pOMXStandComp;
+    OMX_U32              groupPriority;
+    struct _EXYNOS_OMX_RM_COMPONENT_LIST *pNext;
+} EXYNOS_OMX_RM_COMPONENT_LIST;
+
+/* Max allowable scheduler component instance */
+static EXYNOS_OMX_RM_COMPONENT_LIST *gpRMList[RESOURCE_MAX];
+static EXYNOS_OMX_RM_COMPONENT_LIST *gpRMWaitList[RESOURCE_MAX];
+static OMX_HANDLETYPE                ghVideoRMComponentListMutex = NULL;
+
+EXYNOS_OMX_RM_COMPONENT_LIST *getRMList(
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent,
+    EXYNOS_OMX_RM_COMPONENT_LIST    *pRMList[],
+    int                             *pMaxResource)
+{
+    EXYNOS_OMX_RM_COMPONENT_LIST *ret = NULL;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    switch (pExynosComponent->codecType) {
+    case HW_VIDEO_DEC_CODEC:
+        ret = pRMList[VIDEO_DEC];
+        if (pMaxResource != NULL)
+            *pMaxResource = MAX_RESOURCE_VIDEO_DEC;
+        break;
+    case HW_VIDEO_ENC_CODEC:
+        ret = pRMList[VIDEO_ENC];
+        if (pMaxResource != NULL)
+            *pMaxResource = MAX_RESOURCE_VIDEO_ENC;
+        break;
+    case HW_VIDEO_DEC_SECURE_CODEC:
+    case HW_VIDEO_ENC_SECURE_CODEC:
+        ret = pRMList[VIDEO_SECURE];
+        if (pMaxResource != NULL) {
+            *pMaxResource = MAX_RESOURCE_VIDEO_SECURE;
+#ifdef USE_SINGLE_DRM
+            *pMaxResource = 1;
+#endif
+        }
+        break;
+    case HW_AUDIO_DEC_CODEC:
+        ret = pRMList[AUDIO_DEC];
+        if (pMaxResource != NULL)
+            *pMaxResource = MAX_RESOURCE_AUDIO_DEC;
+        break;
+    /* Add new resource block */
+    default:
+        ret = NULL;
+        if (pMaxResource != NULL)
+            *pMaxResource = 0;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE setRMList(
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent,
+    EXYNOS_OMX_RM_COMPONENT_LIST    *pRMList[],
+    EXYNOS_OMX_RM_COMPONENT_LIST    *pRMComponentList)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    switch (pExynosComponent->codecType) {
+    case HW_VIDEO_DEC_CODEC:
+        pRMList[VIDEO_DEC] = pRMComponentList;
+        break;
+    case HW_VIDEO_ENC_CODEC:
+        pRMList[VIDEO_ENC] = pRMComponentList;
+        break;
+    case HW_VIDEO_DEC_SECURE_CODEC:
+    case HW_VIDEO_ENC_SECURE_CODEC:
+        pRMList[VIDEO_SECURE] = pRMComponentList;
+        break;
+    case HW_AUDIO_DEC_CODEC:
+        pRMList[AUDIO_DEC] = pRMComponentList;
+        break;
+    /* Add new resource block */
+    default:
+        ret = OMX_ErrorUndefined;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE addElementList(
+    EXYNOS_OMX_RM_COMPONENT_LIST    **ppList,
+    OMX_COMPONENTTYPE                *pOMXComponent)
+{
+    OMX_ERRORTYPE                 ret               = OMX_ErrorNone;
+    EXYNOS_OMX_RM_COMPONENT_LIST *pTempComp         = NULL;
+    EXYNOS_OMX_BASECOMPONENT     *pExynosComponent  = NULL;
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (*ppList != NULL) {
+        pTempComp = *ppList;
+        while (pTempComp->pNext != NULL) {
+            pTempComp = pTempComp->pNext;
+        }
+
+        pTempComp->pNext = (EXYNOS_OMX_RM_COMPONENT_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_RM_COMPONENT_LIST));
+        if (pTempComp->pNext == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        ((EXYNOS_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pNext = NULL;
+        ((EXYNOS_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pOMXStandComp = pOMXComponent;
+        ((EXYNOS_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->groupPriority = pExynosComponent->compPriority.nGroupPriority;
+        goto EXIT;
+    } else {
+        *ppList = (EXYNOS_OMX_RM_COMPONENT_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_RM_COMPONENT_LIST));
+        if (*ppList == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pTempComp = *ppList;
+        pTempComp->pNext = NULL;
+        pTempComp->pOMXStandComp = pOMXComponent;
+        pTempComp->groupPriority = pExynosComponent->compPriority.nGroupPriority;
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE removeElementList(
+    EXYNOS_OMX_RM_COMPONENT_LIST   **ppList,
+    OMX_COMPONENTTYPE               *pOMXComponent)
+{
+    OMX_ERRORTYPE                 ret           = OMX_ErrorNone;
+    EXYNOS_OMX_RM_COMPONENT_LIST *pCurrComp     = NULL;
+    EXYNOS_OMX_RM_COMPONENT_LIST *pPrevComp     = NULL;
+    OMX_BOOL                      bDetectComp   = OMX_FALSE;
+
+    if (*ppList == NULL) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    pCurrComp = *ppList;
+    while (pCurrComp != NULL) {
+        if (pCurrComp->pOMXStandComp == pOMXComponent) {
+            if (*ppList == pCurrComp) {
+                *ppList = pCurrComp->pNext;
+                Exynos_OSAL_Free(pCurrComp);
+                pCurrComp = NULL;
+            } else {
+                if (pPrevComp != NULL)
+                    pPrevComp->pNext = pCurrComp->pNext;
+
+                Exynos_OSAL_Free(pCurrComp);
+                pCurrComp = NULL;
+            }
+
+            bDetectComp = OMX_TRUE;
+            break;
+        } else {
+            pPrevComp = pCurrComp;
+            pCurrComp = pCurrComp->pNext;
+        }
+    }
+
+    if (bDetectComp == OMX_FALSE)
+        ret = OMX_ErrorComponentNotFound;
+    else
+        ret = OMX_ErrorNone;
+
+EXIT:
+    return ret;
+}
+
+int searchLowPriority(
+    EXYNOS_OMX_RM_COMPONENT_LIST  *pRMComponentList,
+    OMX_U32                        inComp_priority,
+    EXYNOS_OMX_RM_COMPONENT_LIST **outLowComp)
+{
+    int                           ret               = 0;
+    EXYNOS_OMX_RM_COMPONENT_LIST *pTempComp         = NULL;
+    EXYNOS_OMX_RM_COMPONENT_LIST *pCandidateComp    = NULL;
+
+    if (pRMComponentList == NULL) {
+        ret = -1;
+        goto EXIT;
+    }
+
+    pTempComp   = pRMComponentList;
+    *outLowComp = 0;
+
+    while (pTempComp != NULL) {
+        if (pTempComp->groupPriority > inComp_priority) {
+            if (pCandidateComp != NULL) {
+                if (pCandidateComp->groupPriority < pTempComp->groupPriority)
+                    pCandidateComp = pTempComp;
+            } else {
+                pCandidateComp = pTempComp;
+            }
+        }
+
+        pTempComp = pTempComp->pNext;
+    }
+
+    *outLowComp = pCandidateComp;
+    if (pCandidateComp == NULL)
+        ret = 0;
+    else
+        ret = 1;
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE removeComponent(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateIdle) {
+        (*(pExynosComponent->pCallbacks->EventHandler))(pOMXComponent,
+                                                        pExynosComponent->callbackData,
+                                                        OMX_EventError,
+                                                        OMX_ErrorResourcesLost,
+                                                        0,
+                                                        NULL);
+        ret = OMX_SendCommand(pOMXComponent, OMX_CommandStateSet, OMX_StateLoaded, NULL);
+        if (ret != OMX_ErrorNone) {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    } else if ((pExynosComponent->currentState == OMX_StateExecuting) ||
+               (pExynosComponent->currentState == OMX_StatePause)) {
+        /* Todo */
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    return ret;
+}
+
+
+OMX_ERRORTYPE Exynos_OMX_ResourceManager_Init()
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    ret = Exynos_OSAL_MutexCreate(&ghVideoRMComponentListMutex);
+
+    if (ret == OMX_ErrorNone) {
+        Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);
+        Exynos_OSAL_Memset(gpRMList, 0, (sizeof(EXYNOS_OMX_RM_COMPONENT_LIST*) * RESOURCE_MAX));
+        Exynos_OSAL_Memset(gpRMWaitList, 0, (sizeof(EXYNOS_OMX_RM_COMPONENT_LIST*) * RESOURCE_MAX));
+        Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ResourceManager_Deinit()
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_RM_COMPONENT_LIST    *pCurrComponent = NULL;
+    EXYNOS_OMX_RM_COMPONENT_LIST    *pNextComponent = NULL;
+    int i = 0;
+
+    FunctionIn();
+
+    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);
+
+    for (i = 0; i < RESOURCE_MAX; i++) {
+        if (gpRMList[i]) {
+            pCurrComponent = gpRMList[i];
+            while (pCurrComponent != NULL) {
+                pNextComponent = pCurrComponent->pNext;
+                Exynos_OSAL_Free(pCurrComponent);
+                pCurrComponent = pNextComponent;
+            }
+            gpRMList[i] = NULL;
+        }
+
+        if (gpRMWaitList[i]) {
+            pCurrComponent = gpRMWaitList[i];
+            while (pCurrComponent != NULL) {
+                pNextComponent = pCurrComponent->pNext;
+                Exynos_OSAL_Free(pCurrComponent);
+                pCurrComponent = pNextComponent;
+            }
+            gpRMWaitList[i] = NULL;
+        }
+    }
+
+    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
+
+    Exynos_OSAL_MutexTerminate(ghVideoRMComponentListMutex);
+    ghVideoRMComponentListMutex = NULL;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                 ret                   = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT     *pExynosComponent      = NULL;
+    EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentList      = NULL;
+    EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp        = NULL;
+    EXYNOS_OMX_RM_COMPONENT_LIST *pComponentCandidate   = NULL;
+    int numElem       = 0;
+    int lowCompDetect = 0;
+    int maxResource   = 0;
+
+    FunctionIn();
+
+    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pRMComponentList = getRMList(pExynosComponent, gpRMList, &maxResource);
+
+#ifndef USE_SECURE_WITH_NONSECURE
+    if ((pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) ||
+        (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC)) {
+        if (gpRMList[VIDEO_SECURE] != NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s][%s] can't use secure with non-secure",
+                                                pExynosComponent, __FUNCTION__, pExynosComponent->componentName);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    } else if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) ||
+               (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)) {
+        if ((gpRMList[VIDEO_DEC] != NULL) ||
+            (gpRMList[VIDEO_ENC] != NULL)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s][%s] can't use secure with non-secure",
+                                                pExynosComponent, __FUNCTION__, pExynosComponent->componentName);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+#endif
+
+    pComponentTemp = pRMComponentList;
+    if (pComponentTemp != NULL) {
+        while (pComponentTemp) {
+            numElem++;
+            pComponentTemp = pComponentTemp->pNext;
+        }
+    } else {
+        numElem = 0;
+    }
+
+    if (numElem >= maxResource) {
+        lowCompDetect = searchLowPriority(pRMComponentList,
+                                          pExynosComponent->compPriority.nGroupPriority,
+                                          &pComponentCandidate);
+        if (lowCompDetect <= 0) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        } else {
+            ret = removeComponent(pComponentCandidate->pOMXStandComp);
+            if (ret != OMX_ErrorNone) {
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            } else {
+                ret = removeElementList(&pRMComponentList, pComponentCandidate->pOMXStandComp);
+                if (ret != OMX_ErrorNone)
+                    goto EXIT;
+
+                ret = addElementList(&pRMComponentList, pOMXComponent);
+                if (ret != OMX_ErrorNone)
+                    goto EXIT;
+            }
+        }
+    } else {
+        ret = addElementList(&pRMComponentList, pOMXComponent);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+    }
+
+    ret = setRMList(pExynosComponent, gpRMList, pRMComponentList);
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    ret = OMX_ErrorNone;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s][%s] has got a resource", pExynosComponent, __FUNCTION__, pExynosComponent->componentName);
+
+EXIT:
+    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                 ret                   = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT     *pExynosComponent      = NULL;
+    EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentList      = NULL;
+    EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentWaitList  = NULL;
+    EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp        = NULL;
+    OMX_COMPONENTTYPE            *pOMXWaitComponent     = NULL;
+    int numElem = 0;
+
+    FunctionIn();
+
+    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pRMComponentList = getRMList(pExynosComponent, gpRMList, NULL);
+    if (pRMComponentList == NULL) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    ret = removeElementList(&pRMComponentList, pOMXComponent);
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    ret = setRMList(pExynosComponent, gpRMList, pRMComponentList);
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+#ifdef TIZEN_OMXIL_COMMERCIAL_FEATURE
+    // (2018-05-21) The following part is differently implemented from Tizen's for e7270.
+    // The only reason for the change is to follow Android's newest implementation, 
+    // and according to our analysis, they do have the same effect.
+    // One thing to note is that the variable 'nunElem" does not have any specific purpose 
+    // for being counted for now, other than that as a flag.
+    pRMComponentWaitList    = getRMList(pExynosComponent, gpRMWaitList, NULL);
+    pComponentTemp          = pRMComponentWaitList;
+
+    while (pComponentTemp) {
+        numElem++;
+        pComponentTemp = pComponentTemp->pNext;
+    }
+
+    if (numElem > 0) {
+        pOMXWaitComponent = pRMComponentWaitList->pOMXStandComp;
+        ret = removeElementList(&pRMComponentWaitList, pOMXWaitComponent);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        ret = setRMList(pExynosComponent, gpRMWaitList, pRMComponentWaitList);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+    }
+#endif
+
+EXIT:
+    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                    = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent       = NULL;
+    EXYNOS_OMX_RM_COMPONENT_LIST    *pRMComponentWaitList   = NULL;
+
+    FunctionIn();
+
+    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);
+
+    pExynosComponent        = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pRMComponentWaitList    = getRMList(pExynosComponent, gpRMWaitList, NULL);
+
+    ret = addElementList(&pRMComponentWaitList, pOMXComponent);
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    ret = setRMList(pExynosComponent, gpRMWaitList, pRMComponentWaitList);
+
+EXIT:
+    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                    = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent       = NULL;
+    EXYNOS_OMX_RM_COMPONENT_LIST    *pRMComponentWaitList   = NULL;
+
+    FunctionIn();
+
+    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);
+
+    pExynosComponent        = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pRMComponentWaitList    = getRMList(pExynosComponent, gpRMWaitList, NULL);
+
+    ret = removeElementList(&pRMComponentWaitList, pOMXComponent);
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    ret = setRMList(pExynosComponent, gpRMWaitList, pRMComponentWaitList);
+
+EXIT:
+    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
+
+    FunctionOut();
+
+    return ret;
+}
+
diff --git a/openmax/component/common/Exynos_OMX_Resourcemanager.h b/openmax/component/common/Exynos_OMX_Resourcemanager.h
new file mode 100755 (executable)
index 0000000..fb896a7
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Resourcemanager.h
+ * @brief
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *    2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_RESOURCEMANAGER
+#define EXYNOS_OMX_RESOURCEMANAGER
+
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_ERRORTYPE Exynos_OMX_ResourceManager_Init();
+OMX_ERRORTYPE Exynos_OMX_ResourceManager_Deinit();
+OMX_ERRORTYPE Exynos_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent);
+OMX_ERRORTYPE Exynos_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent);
+OMX_ERRORTYPE Exynos_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent);
+OMX_ERRORTYPE Exynos_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/common/Makefile.am b/openmax/component/common/Makefile.am
new file mode 100755 (executable)
index 0000000..53f89d1
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libExynosOMX_Resourcemanager.la \
+                  libExynosOMX_Basecomponent.la 
+
+
+libExynosOMX_Resourcemanager_la_SOURCES = Exynos_OMX_Resourcemanager.c
+
+libExynosOMX_Resourcemanager_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la
+libExynosOMX_Resourcemanager_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                         -I$(top_srcdir)/openmax/include/exynos \
+                                         -I$(top_srcdir)/openmax/osal
+libExynosOMX_Resourcemanager_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
+libExynosOMX_Resourcemanager_la_CFLAGS += -Wno-unused-label
+
+
+libExynosOMX_Basecomponent_la_SOURCES = Exynos_OMX_Basecomponent.c \
+                                        Exynos_OMX_Baseport.c
+
+libExynosOMX_Basecomponent_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                       $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la
+
+libExynosOMX_Basecomponent_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                       -I$(top_srcdir)/openmax/include/exynos \
+                                       -I$(top_srcdir)/openmax/osal
+libExynosOMX_Basecomponent_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
diff --git a/openmax/component/video/Makefile.am b/openmax/component/video/Makefile.am
new file mode 100755 (executable)
index 0000000..5b86dc8
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = dec enc
diff --git a/openmax/component/video/dec/Exynos_OMX_Vdec.c b/openmax/component/video/dec/Exynos_OMX_Vdec.c
new file mode 100755 (executable)
index 0000000..2af7519
--- /dev/null
@@ -0,0 +1,1968 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Vdec.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              HyeYeon Chung (hyeon.chung@samsung.com)
+ *              Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OMX_Vdec.h"
+#include "Exynos_OMX_VdecControl.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Thread.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OSAL_ETC.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VIDEO_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+typedef struct __IMG_INFO {
+    OMX_S32 nFrameWidth;
+    OMX_S32 nFrameHeight;
+    OMX_S32 nImageWidth;
+    OMX_S32 nImageHeight;
+
+    /* crop */
+    OMX_S32 nLeft;
+    OMX_S32 nTop;
+    OMX_S32 nWidth;
+    OMX_S32 nHeight;
+} IMG_INFO;
+
+void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT      *exynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    OMX_U32 width = 0, height = 0;
+
+    FunctionIn();
+
+    if ((exynosOutputPort->portDefinition.format.video.nFrameWidth !=
+            exynosInputPort->portDefinition.format.video.nFrameWidth) ||
+        (exynosOutputPort->portDefinition.format.video.nFrameHeight !=
+            exynosInputPort->portDefinition.format.video.nFrameHeight) ||
+        (exynosOutputPort->portDefinition.format.video.nStride !=
+            exynosInputPort->portDefinition.format.video.nStride) ||
+        (exynosOutputPort->portDefinition.format.video.nSliceHeight !=
+            exynosInputPort->portDefinition.format.video.nSliceHeight)) {
+
+        exynosOutputPort->portDefinition.format.video.nFrameWidth =
+            exynosInputPort->portDefinition.format.video.nFrameWidth;
+        exynosOutputPort->portDefinition.format.video.nFrameHeight =
+            exynosInputPort->portDefinition.format.video.nFrameHeight;
+        exynosOutputPort->portDefinition.format.video.nStride =
+            exynosInputPort->portDefinition.format.video.nStride;
+        exynosOutputPort->portDefinition.format.video.nSliceHeight =
+            exynosInputPort->portDefinition.format.video.nSliceHeight;
+    }
+
+    width  = exynosOutputPort->portDefinition.format.video.nStride;
+    height = exynosOutputPort->portDefinition.format.video.nSliceHeight;
+
+    if (width && height) {
+        switch((int)exynosOutputPort->portDefinition.format.video.eColorFormat) {
+        case OMX_COLOR_FormatYUV420Planar:
+        case OMX_COLOR_FormatYUV420SemiPlanar:
+        case OMX_SEC_COLOR_Format10bitYUV420SemiPlanar:
+        case OMX_SEC_COLOR_FormatNV12Tiled:
+        case OMX_SEC_COLOR_FormatYVU420Planar:
+        case OMX_SEC_COLOR_FormatNV21Linear:
+            exynosOutputPort->portDefinition.nBufferSize = (ALIGN(width, 16) * ALIGN(height, 16) * 3) / 2;
+            break;
+        case OMX_COLOR_Format32bitARGB8888:
+            exynosOutputPort->portDefinition.format.video.nStride = exynosInputPort->portDefinition.format.video.nStride * 4;
+            exynosOutputPort->portDefinition.nBufferSize = ALIGN(width, 16) * ALIGN(height, 16) * 4;
+            break;
+        default:
+            exynosOutputPort->portDefinition.nBufferSize = ALIGN(width, 16) * ALIGN(height, 16) * 2;
+            break;
+        }
+    }
+
+    FunctionOut();
+
+    return;
+}
+
+void Exynos_Output_SetSupportFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec   = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    if ((pVideoDec == NULL) || (pOutputPort == NULL))
+        return ;
+
+    if (pOutputPort->supportFormat != NULL) {
+        OMX_BOOL ret = OMX_FALSE;
+        int nLastIndex = OUTPUT_PORT_SUPPORTFORMAT_DEFAULT_NUM;
+        int i;
+
+        /* Default supported formats                                                                  */
+        /* Customer wants OMX_COLOR_FormatYUV420SemiPlanar in the default colors format.              */
+        /* But, Google wants OMX_COLOR_FormatYUV420Planar in the default colors format.               */
+        /* Google's Videoeditor uses OMX_COLOR_FormatYUV420Planar(YV12) in the default colors format. */
+        /* Therefore, only when you load the OpenMAX IL component by the customer name,               */
+        /* to change the default OMX_COLOR_FormatYUV420SemiPlanar color format.                       */
+        /* It is determined by case-sensitive.                                                        */
+        if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) != OMX_TRUE) {
+            /* Google GED & S.LSI Component, for video editor*/
+            pOutputPort->supportFormat[0] = OMX_COLOR_FormatYUV420Planar;
+            pOutputPort->supportFormat[1] = OMX_COLOR_FormatYUV420SemiPlanar;
+        } else {
+            /* Customer Component*/
+            pOutputPort->supportFormat[0] = OMX_COLOR_FormatYUV420SemiPlanar;
+            pOutputPort->supportFormat[1] = OMX_COLOR_FormatYUV420Planar;
+        }
+        pOutputPort->supportFormat[2] = OMX_COLOR_Format32bitARGB8888;
+
+        /* add extra formats, if It is supported by H/W. (CSC doesn't exist) */
+        /* OMX_SEC_COLOR_FormatNV12Tiled */
+        ret = pVideoDec->exynos_codec_checkFormatSupport(pExynosComponent,
+                                            (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled);
+        if (ret == OMX_TRUE)
+            pOutputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
+
+        /* OMX_SEC_COLOR_FormatYVU420Planar */
+        ret = pVideoDec->exynos_codec_checkFormatSupport(pExynosComponent,
+                                            (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar);
+        if (ret == OMX_TRUE)
+            pOutputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar;
+
+        /* OMX_SEC_COLOR_FormatNV21Linear */
+        ret = pVideoDec->exynos_codec_checkFormatSupport(pExynosComponent, (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear);
+        if (ret == OMX_TRUE)
+            pOutputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear;
+
+        for (i = 0; i < nLastIndex; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] Supported Format[%d] : 0x%x",
+                                                pExynosComponent, __FUNCTION__, i, pOutputPort->supportFormat[i]);
+        }
+
+        pOutputPort->supportFormat[nLastIndex] = OMX_COLOR_FormatUnused;
+    }
+
+    return ;
+}
+
+void Exynos_Free_CodecBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    CODEC_DEC_BUFFER               **ppCodecBuffer      = NULL;
+
+    int nBufferCnt = 0, nPlaneCnt = 0;
+    int i, j;
+
+    FunctionIn();
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
+        nBufferCnt = MFC_INPUT_BUFFER_NUM_MAX;
+    } else {
+        ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
+        nBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
+    }
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+    for (i = 0; i < nBufferCnt; i++) {
+        if (ppCodecBuffer[i] != NULL) {
+            for (j = 0; j < nPlaneCnt; j++) {
+                if (ppCodecBuffer[i]->pVirAddr[j] != NULL) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] %s codec buffer[%d][%d] : %d",
+                                                pExynosComponent, __FUNCTION__,
+                                                (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                                i, j, ppCodecBuffer[i]->fd[j]);
+                    Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
+                }
+            }
+
+            Exynos_OSAL_Free(ppCodecBuffer[i]);
+            ppCodecBuffer[i] = NULL;
+        }
+    }
+
+    FunctionOut();
+}
+
+OMX_ERRORTYPE Exynos_Allocate_CodecBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex,
+    int                  nBufferCnt,
+    unsigned int         nAllocLen[MAX_BUFFER_PLANE])
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    MEMORY_TYPE                      eMemoryType        = CACHED_MEMORY;
+    CODEC_DEC_BUFFER               **ppCodecBuffer      = NULL;
+
+    int nPlaneCnt = 0;
+    int i, j;
+
+    FunctionIn();
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
+    } else {
+        ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
+#ifdef USE_CSC_HW
+        eMemoryType = NORMAL_MEMORY;
+#endif
+    }
+    nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        eMemoryType = SECURE_MEMORY;
+
+    for (i = 0; i < nBufferCnt; i++) {
+        ppCodecBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
+        if (ppCodecBuffer[i] == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+        Exynos_OSAL_Memset(ppCodecBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
+
+        for (j = 0; j < nPlaneCnt; j++) {
+            ppCodecBuffer[i]->pVirAddr[j] =
+                (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[j], eMemoryType);
+            if (ppCodecBuffer[i]->pVirAddr[j] == NULL) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Alloc for %s codec buffer",
+                                            pExynosComponent, __FUNCTION__,
+                                            (nPortIndex == INPUT_PORT_INDEX)? "input":"output");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+
+            ppCodecBuffer[i]->fd[j] =
+                Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
+            ppCodecBuffer[i]->bufferSize[j] = nAllocLen[j];
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s codec buffer[%d][%d] : %d",
+                                        pExynosComponent, __FUNCTION__,
+                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                        i, j, ppCodecBuffer[i]->fd[j]);
+        }
+
+        ppCodecBuffer[i]->dataSize = 0;
+    }
+
+    FunctionOut();
+
+    return OMX_ErrorNone;
+
+EXIT:
+    Exynos_Free_CodecBuffers(pOMXComponent, nPortIndex);
+
+    FunctionOut();
+
+    return ret;
+}
+
+void Exynos_SetReorderTimestamp(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_U32                     *nIndex,
+    OMX_TICKS                    timeStamp,
+    OMX_U32                      nFlags) {
+
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) || (nIndex == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* find a empty slot */
+    for (i = 0; i < MAX_TIMESTAMP; i++) {
+        if (pExynosComponent->bTimestampSlotUsed[*nIndex] == OMX_FALSE)
+            break;
+
+        (*nIndex)++;
+        (*nIndex) %= MAX_TIMESTAMP;
+    }
+
+    if (i >= MAX_TIMESTAMP)
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Can not find empty slot of timestamp. Timestamp slot is full.",
+                                            pExynosComponent, __FUNCTION__);
+
+    pExynosComponent->timeStamp[*nIndex]          = timeStamp;
+    pExynosComponent->nFlags[*nIndex]             = nFlags;
+    pExynosComponent->bTimestampSlotUsed[*nIndex] = OMX_TRUE;
+
+EXIT:
+    FunctionOut();
+
+    return;
+}
+
+void Exynos_GetReorderTimestamp(
+    EXYNOS_OMX_BASECOMPONENT            *pExynosComponent,
+    EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP  *sCurrentTimestamp,
+    OMX_S32                              nFrameIndex,
+    OMX_S32                              eFrameType) {
+
+    EXYNOS_OMX_BASEPORT         *pExynosOutputPort  = NULL;
+    int i = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) || (sCurrentTimestamp == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    Exynos_OSAL_Memset(sCurrentTimestamp, 0, sizeof(EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP));
+    sCurrentTimestamp->timeStamp = DEFAULT_TIMESTAMP_VAL;
+
+    for (i = 0; i < MAX_TIMESTAMP; i++) {
+        /* NOTE: In case of CODECCONFIG, no return any frame */
+        if ((pExynosComponent->bTimestampSlotUsed[i] == OMX_TRUE) &&
+            (pExynosComponent->nFlags[i] != (OMX_BUFFERFLAG_CODECCONFIG | OMX_BUFFERFLAG_ENDOFFRAME))) {
+
+            /* NOTE: In case of EOS, timestamp is not valid */
+            if ((sCurrentTimestamp->timeStamp == DEFAULT_TIMESTAMP_VAL) ||
+                ((sCurrentTimestamp->timeStamp > pExynosComponent->timeStamp[i]) &&
+                    (((pExynosComponent->nFlags[i] & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) ||
+                     (pExynosComponent->bBehaviorEOS == OMX_TRUE))) ||
+                ((sCurrentTimestamp->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+                sCurrentTimestamp->timeStamp = pExynosComponent->timeStamp[i];
+                sCurrentTimestamp->nFlags    = pExynosComponent->nFlags[i];
+                sCurrentTimestamp->nIndex    = i;
+            }
+        }
+    }
+
+    if (sCurrentTimestamp->timeStamp == DEFAULT_TIMESTAMP_VAL)
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] could not find a valid timestamp", pExynosComponent, __FUNCTION__);
+
+    /* PTS : all index is same as tag */
+    /* DTS : only in case of I-Frame, the index is same as tag */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] disp_pic_frame_type: %d", pExynosComponent, __FUNCTION__, eFrameType);
+    if ((ExynosVideoFrameType)eFrameType & VIDEO_FRAME_I) {
+        /* Timestamp is weird */
+        if (sCurrentTimestamp->nIndex != nFrameIndex) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Timestamp is not same in spite of I-Frame", pExynosComponent, __FUNCTION__);
+
+            /* trust a tag index returned from D/D */
+            sCurrentTimestamp->timeStamp = pExynosComponent->timeStamp[nFrameIndex];
+            sCurrentTimestamp->nFlags    = pExynosComponent->nFlags[nFrameIndex];
+            sCurrentTimestamp->nIndex    = nFrameIndex;
+
+            /* delete past timestamps */
+            for(i = 0; i < MAX_TIMESTAMP; i++) {
+                if ((pExynosComponent->bTimestampSlotUsed[i] == OMX_TRUE) &&
+                    ((sCurrentTimestamp->timeStamp > pExynosComponent->timeStamp[i]) &&
+                        ((pExynosComponent->nFlags[i] & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS))) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] clear an past timestamp %lld us (%.2f secs)",
+                                                            pExynosComponent, __FUNCTION__,
+                                                            pExynosComponent->timeStamp[i], (double)(pExynosComponent->timeStamp[i] / 1E6));
+                    pExynosComponent->nFlags[i]             = 0x00;
+                    pExynosComponent->bTimestampSlotUsed[i] = OMX_FALSE;
+                }
+
+                if ((pExynosComponent->bTimestampSlotUsed[i] == OMX_FALSE) &&
+                    (sCurrentTimestamp->timeStamp < pExynosComponent->timeStamp[i])) {
+                    pExynosComponent->bTimestampSlotUsed[i] = OMX_TRUE;
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] revive an past timestamp %lld us (%.2f secs) by I-frame sync",
+                                                            pExynosComponent, __FUNCTION__,
+                                                            pExynosComponent->timeStamp[i], (double)(pExynosComponent->timeStamp[i] / 1E6));
+                }
+            }
+        }
+
+        if (sCurrentTimestamp->timeStamp == DEFAULT_TIMESTAMP_VAL)
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] the index of frame(%d) about I-frame is wrong",
+                                                pExynosComponent, __FUNCTION__, nFrameIndex);
+
+        sCurrentTimestamp->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+    }
+
+    if (eFrameType & VIDEO_FRAME_CORRUPT)
+        sCurrentTimestamp->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+
+    if (sCurrentTimestamp->timeStamp != DEFAULT_TIMESTAMP_VAL) {
+        if (pExynosOutputPort->latestTimeStamp <= sCurrentTimestamp->timeStamp) {
+            pExynosOutputPort->latestTimeStamp = sCurrentTimestamp->timeStamp;
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] timestamp(%lld) is smaller than latest timeStamp(%lld), uses latestTimeStamp",
+                                pExynosComponent, __FUNCTION__,
+                                sCurrentTimestamp->timeStamp, pExynosOutputPort->latestTimeStamp);
+            sCurrentTimestamp->timeStamp = pExynosOutputPort->latestTimeStamp;
+        }
+    } else {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] can't find a valid timestamp, uses latestTimeStamp(%lld)",
+                                pExynosComponent, __FUNCTION__, pExynosOutputPort->latestTimeStamp);
+        sCurrentTimestamp->timeStamp = pExynosOutputPort->latestTimeStamp;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return;
+}
+
+OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
+{
+    OMX_BOOL ret = OMX_FALSE;
+
+    if ((pExynosComponent == NULL) ||
+        (pExynosComponent->pExynosPort == NULL))
+        return OMX_FALSE;
+
+    if ((pExynosComponent->currentState == OMX_StateExecuting) &&
+        ((pExynosComponent->pExynosPort[nPortIndex].portState == EXYNOS_OMX_PortStateIdle) ||
+         (pExynosComponent->pExynosPort[nPortIndex].portState == EXYNOS_OMX_PortStateDisabling)) &&
+        (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+        (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
+        ret = OMX_TRUE;
+    } else {
+        ret = OMX_FALSE;
+    }
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT           *pInputPort        = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort       = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    /* Input port */
+    pInputPort->portDefinition.format.video.nFrameWidth             = DEFAULT_FRAME_WIDTH;
+    pInputPort->portDefinition.format.video.nFrameHeight            = DEFAULT_FRAME_HEIGHT;
+    pInputPort->portDefinition.format.video.nStride                 = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pInputPort->portDefinition.format.video.nSliceHeight            = 0;
+    pInputPort->portDefinition.format.video.pNativeRender           = 0;
+    pInputPort->portDefinition.format.video.bFlagErrorConcealment   = OMX_FALSE;
+    pInputPort->portDefinition.format.video.eColorFormat            = OMX_COLOR_FormatUnused;
+
+    pInputPort->portDefinition.nBufferSize  = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    pInputPort->portDefinition.bEnabled     = OMX_TRUE;
+
+    pInputPort->bufferProcessType   = BUFFER_SHARE;
+    pOutputPort->eMetaDataType      = METADATA_TYPE_DISABLED;
+
+    pInputPort->portWayType         = WAY2_PORT;
+    Exynos_SetPlaneToPort(pInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+
+    /* Output port */
+    pOutputPort->portDefinition.format.video.nFrameWidth            = DEFAULT_FRAME_WIDTH;
+    pOutputPort->portDefinition.format.video.nFrameHeight           = DEFAULT_FRAME_HEIGHT;
+    pOutputPort->portDefinition.format.video.nStride                = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pOutputPort->portDefinition.format.video.nSliceHeight           = 0;
+    pOutputPort->portDefinition.format.video.pNativeRender          = 0;
+    pOutputPort->portDefinition.format.video.bFlagErrorConcealment  = OMX_FALSE;
+    pOutputPort->portDefinition.format.video.eColorFormat           = OMX_COLOR_FormatYUV420Planar;
+
+    pOutputPort->portDefinition.nBufferCountActual  = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pOutputPort->portDefinition.nBufferCountMin     = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pOutputPort->portDefinition.nBufferSize  = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pOutputPort->portDefinition.bEnabled     = OMX_TRUE;
+
+    pOutputPort->bufferProcessType  = BUFFER_COPY;
+    pOutputPort->eMetaDataType      = METADATA_TYPE_DISABLED;
+
+    pOutputPort->portWayType        = WAY2_PORT;
+    pOutputPort->latestTimeStamp    = DEFAULT_TIMESTAMP_VAL;
+    Exynos_SetPlaneToPort(pOutputPort, Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420Planar, pOutputPort->ePlaneType));
+
+    pOutputPort->cropRectangle.nTop     = 0;
+    pOutputPort->cropRectangle.nLeft    = 0;
+    pOutputPort->cropRectangle.nWidth   = DEFAULT_FRAME_WIDTH;
+    pOutputPort->cropRectangle.nHeight  = DEFAULT_FRAME_HEIGHT;
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_CodecBufferToData(
+    CODEC_DEC_BUFFER    *pCodecBuffer,
+    EXYNOS_OMX_DATA     *pData,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    int i;
+
+    if (nPortIndex > OUTPUT_PORT_INDEX) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    pData->allocSize     = 0;
+    pData->usedDataLen   = 0;
+    pData->nFlags        = 0;
+    pData->timeStamp     = 0;
+    pData->pPrivate      = pCodecBuffer;
+    pData->bufferHeader  = NULL;
+
+    for (i = 0; i < MAX_BUFFER_PLANE; i++) {
+        pData->buffer.addr[i]   = pCodecBuffer->pVirAddr[i];
+        pData->buffer.fd[i]     = pCodecBuffer->fd[i];
+
+        pData->allocSize += pCodecBuffer->bufferSize[i];
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        pData->dataLen       = pCodecBuffer->dataSize;
+        pData->remainDataLen = pCodecBuffer->dataSize;
+    } else {
+        pData->dataLen       = 0;
+        pData->remainDataLen = 0;
+    }
+
+EXIT:
+    return ret;
+}
+
+void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
+{
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *exynosOMXPort  = &pExynosComponent->pExynosPort[nPortIndex];
+
+    FunctionIn();
+
+    if (((pExynosComponent->currentState == OMX_StatePause) ||
+         (pExynosComponent->currentState == OMX_StateIdle) ||
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) ||
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) &&
+        (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) &&
+        (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port -> pause : state(0x%x), transient state(0x%x)",
+                                        pExynosComponent, __FUNCTION__,
+                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                        pExynosComponent->currentState, pExynosComponent->transientState);
+        Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port -> resume : state(0x%x), transient state(0x%x)",
+                                        pExynosComponent, __FUNCTION__,
+                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                        pExynosComponent->currentState, pExynosComponent->transientState);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+        Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return;
+}
+
+OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_BOOL                       ret              = OMX_FALSE;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort      = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+    EXYNOS_OMX_DATABUFFER         *pOutputUseBuffer = &(pOutputPort->way.port2WayDataBuffer.outputDataBuffer);
+    DECODE_CODEC_EXTRA_BUFFERINFO *pExtBufferInfo   = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+    OMX_COLOR_FORMATTYPE           eColorFormat     = pOutputPort->portDefinition.format.video.eColorFormat;
+
+    void *pOutputBuf                = (void *)pOutputUseBuffer->bufferHeader->pBuffer;
+    void *pSrcBuf[MAX_BUFFER_PLANE] = { NULL, };
+    void *pDstBuf[MAX_BUFFER_PLANE] = { NULL, };
+
+    CSC_MEMTYPE     csc_memType       = CSC_MEMORY_USERPTR;
+    CSC_METHOD      csc_method        = CSC_METHOD_SW;
+    CSC_ERRORCODE   csc_ret           = CSC_ErrorNone;
+    unsigned int    csc_src_cacheable = 1;
+    unsigned int    csc_dst_cacheable = 1;
+
+    IMG_INFO srcImgInfo, dstImgInfo;
+
+    FunctionIn();
+
+    /* choose csc method */
+    csc_get_method(pVideoDec->csc_handle, &csc_method);
+    if (csc_method == CSC_METHOD_SW) {
+        if (pVideoDec->exynos_codec_checkFormatSupport(pExynosComponent, eColorFormat) == OMX_TRUE) {
+            /* only remove stride value */
+            csc_memType = CSC_MEMORY_MFC;
+        }
+    } else {
+        csc_memType = CSC_MEMORY_DMABUF;
+        csc_src_cacheable = 0;
+        csc_dst_cacheable = 0;
+    }
+
+    /******************/
+    /* get image info */
+    /******************/
+    /* 1. SRC : MFC OUTPUT */
+    srcImgInfo.nFrameWidth  = pExtBufferInfo->imageStride;
+    srcImgInfo.nFrameHeight = pExtBufferInfo->imageHeight;
+    srcImgInfo.nImageWidth  = pExtBufferInfo->imageWidth;
+    srcImgInfo.nImageHeight = pExtBufferInfo->imageHeight;
+
+    /* read original image fully except padding data */
+    srcImgInfo.nLeft   = 0;
+    srcImgInfo.nTop    = 0;
+    srcImgInfo.nWidth  = pExtBufferInfo->imageWidth;
+    srcImgInfo.nHeight = pExtBufferInfo->imageHeight;
+
+    /* 2. DST : OMX OUTPUT */
+    dstImgInfo.nFrameWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;  // pExtBufferInfo->imageWidth??
+    dstImgInfo.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameHeight;  // pExtBufferInfo->imageHeight??
+    dstImgInfo.nImageWidth  = pExtBufferInfo->imageWidth;
+    dstImgInfo.nImageHeight = pExtBufferInfo->imageHeight;
+
+    /* write image fully */
+    dstImgInfo.nLeft        = 0;
+    dstImgInfo.nTop         = 0;
+    dstImgInfo.nWidth       = pExtBufferInfo->imageWidth;
+    dstImgInfo.nHeight      = pExtBufferInfo->imageHeight;
+
+    /*******************/
+    /* get buffer info */
+    /*******************/
+    /* 1. SRC : MFC OUTPUT */
+    if (csc_method == CSC_METHOD_HW) {
+        pSrcBuf[0] = (void *)pDstOutputData->buffer.fd[0];
+        pSrcBuf[1] = (void *)pDstOutputData->buffer.fd[1];
+        pSrcBuf[2] = (void *)pDstOutputData->buffer.fd[2];
+    } else {
+        if (pOutputPort->ePlaneType == PLANE_SINGLE) {
+            /* single-FD. only Y addr is valid */
+            int nPlaneCnt = Exynos_OSAL_GetPlaneCount(pExtBufferInfo->colorFormat, PLANE_MULTIPLE);
+
+            pSrcBuf[0] = pDstOutputData->buffer.addr[0];
+
+            switch (pVideoDec->eDataType) {
+            case DATA_TYPE_10BIT:
+                if (nPlaneCnt == 2) {  /* Semi-Planar : interleaved */
+                    pSrcBuf[1] = (void *)(((char *)pSrcBuf[0]) + GET_UV_OFFSET((srcImgInfo.nImageWidth * 2), srcImgInfo.nImageHeight));
+                } else if (nPlaneCnt == 3) {  /* Planar */
+                    pSrcBuf[1] = (void *)(((char *)pSrcBuf[0]) + GET_CB_OFFSET((srcImgInfo.nImageWidth * 2), srcImgInfo.nImageHeight));
+                    pSrcBuf[2] = (void *)(((char *)pSrcBuf[0]) + GET_CR_OFFSET((srcImgInfo.nImageWidth * 2), srcImgInfo.nImageHeight));
+                }
+                break;
+            case DATA_TYPE_8BIT_WITH_2BIT:
+                if (nPlaneCnt == 2) {  /* Semi-Planar : interleaved */
+                    pSrcBuf[1] = (void *)(((char *)pSrcBuf[0]) + GET_10B_UV_OFFSET(srcImgInfo.nImageWidth, srcImgInfo.nImageHeight));
+                } else if (nPlaneCnt == 3) {  /* Planar */
+                    pSrcBuf[1] = (void *)(((char *)pSrcBuf[0]) + GET_10B_CB_OFFSET(srcImgInfo.nImageWidth, srcImgInfo.nImageHeight));
+                    pSrcBuf[2] = (void *)(((char *)pSrcBuf[0]) + GET_10B_CR_OFFSET(srcImgInfo.nImageWidth, srcImgInfo.nImageHeight));
+                }
+                break;
+            default:
+                if (nPlaneCnt == 2) {  /* Semi-Planar : interleaved */
+                    pSrcBuf[1] = (void *)(((char *)pSrcBuf[0]) + GET_UV_OFFSET(srcImgInfo.nImageWidth, srcImgInfo.nImageHeight));
+                } else if (nPlaneCnt == 3) {  /* Planar */
+                    pSrcBuf[1] = (void *)(((char *)pSrcBuf[0]) + GET_CB_OFFSET(srcImgInfo.nImageWidth, srcImgInfo.nImageHeight));
+                    pSrcBuf[2] = (void *)(((char *)pSrcBuf[0]) + GET_CR_OFFSET(srcImgInfo.nImageWidth, srcImgInfo.nImageHeight));
+                }
+                break;
+            }
+        } else {
+            /* multi-FD */
+            pSrcBuf[0] = pDstOutputData->buffer.addr[0];
+            pSrcBuf[1] = pDstOutputData->buffer.addr[1];
+            pSrcBuf[2] = pDstOutputData->buffer.addr[2];
+        }
+    }
+
+    /* 2. DST : OMX OUTPUT */
+    if (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+        /* 1. meta data is enabled (surface buffer)
+         *    1) format is not supported at HW codec
+         *       needs CSC(Color-Space-Conversion).
+         */
+        if (pOutputPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK) {
+            /* graphic buffer */
+            EXYNOS_OMX_MULTIPLANE_BUFFER bufferInfo;
+
+            OMX_ERRORTYPE         err = OMX_ErrorNone;
+            EXYNOS_OMX_LOCK_RANGE range;
+            OMX_U32               stride = 0;
+
+            range.nWidth        = dstImgInfo.nFrameWidth;
+            range.nHeight       = dstImgInfo.nFrameHeight;
+            range.eColorFormat  = eColorFormat;
+
+            err = Exynos_OSAL_LockMetaData(pOutputBuf, range, &stride, &bufferInfo, pOutputPort->eMetaDataType);
+            if (err != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to Exynos_OSAL_LockMetaData (err:0x%x)",
+                                                    pExynosComponent, __FUNCTION__, err);
+                ret = OMX_FALSE;
+                goto EXIT;
+            }
+
+            dstImgInfo.nFrameWidth = stride;
+
+            if (csc_method == CSC_METHOD_HW) {
+                pDstBuf[0]  = (void *)bufferInfo.fd[0];
+                pDstBuf[1]  = (void *)bufferInfo.fd[1];
+                pDstBuf[2]  = (void *)bufferInfo.fd[2];
+            } else {
+                pDstBuf[0]  = (void *)bufferInfo.addr[0];
+                pDstBuf[1]  = (void *)bufferInfo.addr[1];
+                pDstBuf[2]  = (void *)bufferInfo.addr[2];
+            }
+        } else {
+            /*************/
+            /*    TBD    */
+            /*************/
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: OMX_ErrorNotImplemented(%d)", pExynosComponent, __FUNCTION__, __LINE__);
+            /* OMX_ErrorNotImplemented */
+            ret = OMX_FALSE;
+            goto EXIT;
+        }
+    } else {
+        /* 2. meta data is not enabled (user application format)
+         *    1) user application couldn't handle non-continuous data
+         *    2) format is not supported at HW codec
+         *       needs CSC(Color-Space-Conversion).
+         */
+
+        if (csc_method == CSC_METHOD_HW) {
+            pDstBuf[0] = (void *)Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf);
+            pDstBuf[1] = NULL;
+            pDstBuf[2] = NULL;
+        } else {
+            unsigned int nAllocLen[MAX_BUFFER_PLANE] = { 0, 0, 0 };
+            unsigned int nDataLen[MAX_BUFFER_PLANE]  = { 0, 0, 0 };
+
+            Exynos_OSAL_GetPlaneSize(eColorFormat, PLANE_SINGLE_USER, dstImgInfo.nFrameWidth, dstImgInfo.nFrameHeight, nDataLen, nAllocLen);
+
+            pDstBuf[0]  = (void *)((char *)pOutputBuf);
+            pDstBuf[1]  = (void *)((char *)pOutputBuf + nDataLen[0]);
+            pDstBuf[2]  = (void *)((char *)pOutputBuf + nDataLen[0] + nDataLen[1]);
+        }
+    }
+
+    /**************************/
+    /* [CSC] setup image info */
+    /**************************/
+    if (pVideoDec->csc_set_format == OMX_FALSE) {
+        /********************/
+        /* get color format */
+        /********************/
+        unsigned int csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat(pExtBufferInfo->colorFormat, pOutputPort->ePlaneType);
+        unsigned int csc_dst_color_format = Exynos_OSAL_OMX2HALPixelFormat(eColorFormat, PLANE_SINGLE_USER);
+
+        if (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED)
+            csc_dst_color_format = Exynos_OSAL_OMX2HALPixelFormat(eColorFormat, pOutputPort->ePlaneType);
+
+        csc_set_src_format(
+            pVideoDec->csc_handle,   /* handle */
+            srcImgInfo.nFrameWidth,  /* width */
+            srcImgInfo.nFrameHeight, /* height */
+            srcImgInfo.nLeft,        /* crop_left */
+            srcImgInfo.nTop,         /* crop_top */
+            srcImgInfo.nWidth,       /* crop_width */
+            srcImgInfo.nHeight,      /* crop_height */
+            csc_src_color_format,    /* color_format */
+            csc_src_cacheable);      /* cacheable */
+
+        csc_set_dst_format(
+            pVideoDec->csc_handle,   /* handle */
+            dstImgInfo.nFrameWidth,  /* width */
+            dstImgInfo.nFrameHeight, /* height */
+            dstImgInfo.nLeft,        /* crop_left */
+            dstImgInfo.nTop,         /* crop_top */
+            dstImgInfo.nWidth,       /* crop_width */
+            dstImgInfo.nHeight,      /* crop_height */
+            csc_dst_color_format,    /* color_format */
+            csc_dst_cacheable);      /* cacheable */
+
+        csc_set_eq_property(
+            pVideoDec->csc_handle,         /* handle */
+            CSC_EQ_MODE_USER,              /* user select */
+            CSC_EQ_RANGE_NARROW,           /* narrow */
+            CSC_EQ_COLORSPACE_SMPTE170M);  /* bt.601 */
+
+        pVideoDec->csc_set_format = OMX_TRUE;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s CSC(%x) / [SRC] resol(%dx%d), rect(%d/%d/%d/%d), format(0x%x) -> [DST] resol(%dx%d), rect(%d/%d/%d/%d), format(0x%x)",
+                                               pExynosComponent, __FUNCTION__,
+                                               (csc_method == CSC_METHOD_SW)? "SW":"HW", csc_memType,
+                                               srcImgInfo.nFrameWidth, srcImgInfo.nFrameHeight,
+                                               srcImgInfo.nLeft, srcImgInfo.nTop, srcImgInfo.nWidth, srcImgInfo.nHeight, csc_src_color_format,
+                                               dstImgInfo.nFrameWidth, dstImgInfo.nFrameHeight,
+                                               dstImgInfo.nLeft, dstImgInfo.nTop, dstImgInfo.nWidth, dstImgInfo.nHeight, csc_dst_color_format);
+    }
+
+    /***************************/
+    /* [CSC] setup buffer info */
+    /***************************/
+    csc_set_src_buffer(
+        pVideoDec->csc_handle,  /* handle */
+        pSrcBuf,
+        csc_memType);
+    csc_set_dst_buffer(
+        pVideoDec->csc_handle,  /* handle */
+        pDstBuf,
+        csc_memType);
+
+    /*****************/
+    /* [CSC] convert */
+    /*****************/
+    csc_ret = csc_convert(pVideoDec->csc_handle);
+    ret = (csc_ret != CSC_ErrorNone)? OMX_FALSE:OMX_TRUE;
+
+    if (pOutputPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK)
+        Exynos_OSAL_UnlockMetaData(pOutputBuf, pOutputPort->eMetaDataType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
+{
+    OMX_BOOL                         ret                = OMX_FALSE;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *exynosInputPort    = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER           *inputUseBuffer     = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
+
+    OMX_BYTE pInputStream = NULL;
+    OMX_U32 copySize = 0;
+
+    FunctionIn();
+
+    if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+        if ((srcInputData->buffer.addr[0] == NULL) ||
+            (srcInputData->pPrivate == NULL)) {
+            ret = OMX_FALSE;
+            goto EXIT;
+        }
+    }
+
+    if (inputUseBuffer->dataValid == OMX_TRUE) {
+        if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_Shared_BufferToData(exynosInputPort, inputUseBuffer, srcInputData);
+
+            if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) {
+                unsigned long ionFD = 0;
+                OMX_PTR dataBuffer = NULL;
+
+                if (exynosInputPort->eMetaDataType == METADATA_TYPE_HANDLE) {
+                    if (srcInputData->buffer.fd[0] == 0) {
+                        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] FD is invalid at %p",
+                                                         pExynosComponent, __FUNCTION__, inputUseBuffer->bufferHeader);
+                        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+                        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                                pExynosComponent->callbackData,
+                                                                OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                        ret = OMX_FALSE;
+                        goto EXIT;
+                    }
+
+                    ionFD = srcInputData->buffer.fd[0];
+                } else {
+                    /* backward compatibility */
+                    ionFD = (unsigned long)srcInputData->buffer.addr[0];
+                }
+
+                dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, ionFD);
+                if (dataBuffer == NULL) {
+                    ret = OMX_FALSE;
+                    goto EXIT;
+                }
+
+                srcInputData->buffer.fd[0]   = ionFD;
+                srcInputData->buffer.addr[0] = dataBuffer;
+            }
+
+            if (exynosInputPort->eMetaDataType == METADATA_TYPE_DISABLED) {
+                srcInputData->buffer.fd[0] =
+                    Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
+                                srcInputData->buffer.addr[0]);
+            }
+
+            /* reset dataBuffer */
+            Exynos_ResetDataBuffer(inputUseBuffer);
+
+            ret = OMX_TRUE;
+        } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+            pInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
+            copySize = inputUseBuffer->remainDataLen;
+
+            if (((srcInputData->allocSize) - (srcInputData->dataLen)) < copySize) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] codec buffer's remaining space(%d) is smaller than input data(%d)",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    ((srcInputData->allocSize) - (srcInputData->dataLen)), copySize);
+
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+                pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                        pExynosComponent->callbackData,
+                                                        OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                ret = OMX_FALSE;
+                goto EXIT;
+            }
+
+            if (copySize > 0) {
+                Exynos_OSAL_Memcpy((OMX_PTR)((char *)srcInputData->buffer.addr[0] + srcInputData->dataLen),
+                                   pInputStream, copySize);
+            }
+
+            inputUseBuffer->dataLen         -= copySize;
+            inputUseBuffer->remainDataLen   -= copySize;
+            inputUseBuffer->usedDataLen     += copySize;
+
+            srcInputData->dataLen           += copySize;
+            srcInputData->remainDataLen     += copySize;
+
+            srcInputData->timeStamp     = inputUseBuffer->timeStamp;
+            srcInputData->nFlags        = inputUseBuffer->nFlags;
+            srcInputData->bufferHeader  = inputUseBuffer->bufferHeader;
+
+            /* return OMX buffer and reset dataBuffer */
+            Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
+
+            ret = OMX_TRUE;
+        }
+
+        if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+            if (srcInputData->dataLen != 0) {
+                pExynosComponent->bBehaviorEOS = OMX_TRUE;
+                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] behavior EOS frame", pExynosComponent, __FUNCTION__);
+            }
+        }
+
+        if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) &&
+            ((srcInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) {
+            EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+            pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
+            pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
+            pOutputPort->latestTimeStamp = srcInputData->timeStamp;  // for reordering timestamp mode
+            pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
+            pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame timestamp after seeking %lld us (%.2f secs)",
+                            pExynosComponent, __FUNCTION__, srcInputData->timeStamp, (double)(srcInputData->timeStamp / 1E6));
+        }
+    }
+
+EXIT:
+
+    if (ret != OMX_TRUE) {
+        /* return OMX buffer and reset dataBuffer */
+        Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
+{
+    OMX_BOOL                   ret              = OMX_FALSE;
+    EXYNOS_OMX_BASECOMPONENT  *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT       *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER     *outputUseBuffer  = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+
+    FunctionIn();
+
+    if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_Shared_DataToBuffer(exynosOutputPort, outputUseBuffer, dstOutputData) == OMX_ErrorNone) {
+            outputUseBuffer->dataValid = OMX_TRUE;
+        } else {
+            ret = OMX_FALSE;
+            goto EXIT;
+        }
+    }
+
+    if (outputUseBuffer->dataValid == OMX_TRUE) {
+        if ((pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) &&
+            ((dstOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
+            unsigned int discardFlags = (OMX_BUFFERFLAG_SYNCFRAME | OMX_BUFFERFLAG_DATACORRUPT | OMX_BUFFERFLAG_ENDOFFRAME);
+
+            if ((pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp) &&
+                ((pExynosComponent->checkTimeStamp.nStartFlags & ~discardFlags) ==
+                 (dstOutputData->nFlags & ~discardFlags))) {
+                pExynosComponent->checkTimeStamp.startTimeStamp = RESET_TIMESTAMP_VAL;
+                pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
+                pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+                pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
+            } else {
+                if (pExynosComponent->checkTimeStamp.startTimeStamp < dstOutputData->timeStamp) {
+                    pExynosComponent->checkTimeStamp.startTimeStamp = RESET_TIMESTAMP_VAL;
+                    pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
+                    pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+                    pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
+                } else {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] drop frame after seeking(in: %lld vs out: %lld)",
+                                                            pExynosComponent, __FUNCTION__,
+                                                            pExynosComponent->checkTimeStamp.startTimeStamp, dstOutputData->timeStamp);
+                    if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
+                        Exynos_OMX_FillThisBufferAgain(pOMXComponent, outputUseBuffer->bufferHeader);
+
+                    ret = OMX_TRUE;
+                    goto EXIT;
+                }
+            }
+        } else if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
+            ret = OMX_TRUE;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] not set check timestamp after seeking", pExynosComponent, __FUNCTION__);
+
+            if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
+                Exynos_OMX_FillThisBufferAgain(pOMXComponent, outputUseBuffer->bufferHeader);
+
+            goto EXIT;
+        }
+
+        if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
+            if (exynosOutputPort->eMetaDataType & METADATA_TYPE_DATA)
+                dstOutputData->remainDataLen = outputUseBuffer->allocSize;
+
+            if (((exynosOutputPort->eMetaDataType & METADATA_TYPE_DATA) ||
+                 (dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen))) &&
+                (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+
+                if (dstOutputData->remainDataLen > 0) {
+                    ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData);
+                } else {
+                    ret = OMX_TRUE;
+                }
+
+                if (ret == OMX_TRUE) {
+                    outputUseBuffer->dataLen       += dstOutputData->remainDataLen;
+                    outputUseBuffer->remainDataLen += dstOutputData->remainDataLen;
+                    outputUseBuffer->nFlags         = dstOutputData->nFlags;
+                    outputUseBuffer->timeStamp      = dstOutputData->timeStamp;
+
+                    if ((outputUseBuffer->remainDataLen > 0) ||
+                        (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) ||
+                        (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+                        Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
+                    }
+                } else {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to CSC", pExynosComponent, __FUNCTION__);
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+                    pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                            pExynosComponent->callbackData,
+                                                            OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                    ret = OMX_FALSE;
+                }
+            } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
+                outputUseBuffer->dataLen = 0;
+                outputUseBuffer->remainDataLen = 0;
+                outputUseBuffer->nFlags = dstOutputData->nFlags;
+                outputUseBuffer->timeStamp = dstOutputData->timeStamp;
+                Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
+            } else {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] codec buffer's remaining space(%d) is smaller than output data(%d)",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    (outputUseBuffer->allocSize - outputUseBuffer->dataLen), dstOutputData->remainDataLen);
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+
+                pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                        pExynosComponent->callbackData,
+                                                        OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                ret = OMX_FALSE;
+            }
+        } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+            if ((outputUseBuffer->remainDataLen > 0) ||
+                (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) ||
+                (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+                Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
+            } else {
+                Exynos_OMX_FillThisBufferAgain(pOMXComponent, outputUseBuffer->bufferHeader);
+                Exynos_ResetDataBuffer(outputUseBuffer);
+            }
+        }
+    } else {
+        ret = OMX_FALSE;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *exynosInputPort    = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *exynosOutputPort   = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER           *srcInputUseBuffer  = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
+    EXYNOS_OMX_DATA                 *pSrcInputData      = &exynosInputPort->processData;
+
+    OMX_BOOL bCheckInputData = OMX_FALSE;
+
+    FunctionIn();
+
+    while (!pVideoDec->bExitBufferProcessThread) {
+        Exynos_OSAL_SleepMillisec(0);
+        Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
+        if ((exynosInputPort->semWaitPortEnable[INPUT_WAY_INDEX] != NULL) &&
+            (!CHECK_PORT_ENABLED(exynosInputPort))) {
+            /* sema will be posted at PortEnable */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> wait(port enable)", pExynosComponent, __FUNCTION__);
+            Exynos_OSAL_SemaphoreWait(exynosInputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> post(port enable)", pExynosComponent, __FUNCTION__);
+            continue;
+        }
+
+        while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
+               (!pVideoDec->bExitBufferProcessThread)) {
+            Exynos_OSAL_SleepMillisec(0);
+
+            if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort)) ||
+                (exynosOutputPort->exceptionFlag == INVALID_STATE))
+                break;
+
+            if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorInputDataDecodeYet) ||
+                ((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorNoneSrcSetupFinish)) {
+                if (exynosOutputPort->exceptionFlag != GENERAL_STATE)
+                    break;
+            }
+
+            Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
+            if ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) {
+                if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+                    OMX_PTR codecBuffer;
+                    if ((pSrcInputData->buffer.addr[0] == NULL) ||
+                        (pSrcInputData->pPrivate == NULL)) {
+                        Exynos_CodecBufferDeQueue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
+                        if (pVideoDec->bExitBufferProcessThread) {
+                            Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                            goto EXIT;
+                        }
+
+                        if (codecBuffer != NULL) {
+                            Exynos_CodecBufferToData(codecBuffer, pSrcInputData, INPUT_PORT_INDEX);
+                        }
+                        Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                        break;
+                    }
+                }
+
+                if (srcInputUseBuffer->dataValid == OMX_TRUE) {
+                    bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
+                } else {
+                    bCheckInputData = OMX_FALSE;
+                }
+
+                if ((bCheckInputData == OMX_FALSE) &&
+                    (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
+                    ret = Exynos_InputBufferGetQueue(pExynosComponent);
+                    if (pVideoDec->bExitBufferProcessThread) {
+                        Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                        goto EXIT;
+                    }
+
+                    Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                    break;
+                }
+
+                if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
+                    Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                    break;
+                }
+            }
+
+            /* if input flush is occured before obtaining bufferMutex,
+             * bufferHeader can be NULL.
+             */
+            if (pSrcInputData->bufferHeader == NULL) {
+                ret = OMX_ErrorNone;
+                Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                break;
+            }
+
+            ret = pVideoDec->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
+            if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedFrame) ||
+                ((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader)) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input data is weird(0x%x)",
+                                                        pExynosComponent, __FUNCTION__, ret);
+                if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+                    OMX_PTR codecBuffer;
+                    codecBuffer = pSrcInputData->pPrivate;
+                    if (codecBuffer != NULL)
+                        Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
+                }
+
+                if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
+                    Exynos_OMX_InputBufferReturn(pOMXComponent, pSrcInputData->bufferHeader);
+                }
+            }
+
+            if ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) {
+                Exynos_ResetCodecData(pSrcInputData);
+            }
+
+            Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+
+            if ((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCodecInit)
+                pVideoDec->bExitBufferProcessThread = OMX_TRUE;
+        }
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE          ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT      *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER    *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
+    EXYNOS_OMX_DATA           srcOutputData;
+
+    FunctionIn();
+
+    Exynos_ResetCodecData(&srcOutputData);
+
+    while (!pVideoDec->bExitBufferProcessThread) {
+        Exynos_OSAL_SleepMillisec(0);
+        if ((exynosInputPort->semWaitPortEnable[OUTPUT_WAY_INDEX] != NULL) &&
+            (!CHECK_PORT_ENABLED(exynosInputPort))) {
+            /* sema will be posted at PortEnable */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> wait(port enable)", pExynosComponent, __FUNCTION__);
+            Exynos_OSAL_SemaphoreWait(exynosInputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> post(port enable)", pExynosComponent, __FUNCTION__);
+            continue;
+        }
+
+        while (!pVideoDec->bExitBufferProcessThread) {
+            if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+                if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
+                    break;
+            }
+            Exynos_OSAL_SleepMillisec(0);
+
+            if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
+                break;
+
+            Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
+            ret = pVideoDec->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
+
+            if (ret == OMX_ErrorNone) {
+                if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+                    OMX_PTR codecBuffer;
+                    codecBuffer = srcOutputData.pPrivate;
+                    if (codecBuffer != NULL)
+                        Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
+                }
+                if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
+                    Exynos_Shared_DataToBuffer(exynosInputPort, srcOutputUseBuffer, &srcOutputData);
+                    Exynos_InputBufferReturn(pOMXComponent, srcOutputUseBuffer);
+                }
+                Exynos_ResetCodecData(&srcOutputData);
+            }
+            Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
+        }
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE          ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER    *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
+    EXYNOS_OMX_DATA           dstInputData;
+
+    FunctionIn();
+
+    Exynos_ResetCodecData(&dstInputData);
+
+    while (!pVideoDec->bExitBufferProcessThread) {
+        Exynos_OSAL_SleepMillisec(0);
+        if ((exynosOutputPort->semWaitPortEnable[INPUT_WAY_INDEX] != NULL) &&
+            (!CHECK_PORT_ENABLED(exynosOutputPort))) {
+            /* sema will be posted at PortEnable */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> wait(port enable)", pExynosComponent, __FUNCTION__);
+            Exynos_OSAL_SemaphoreWait(exynosOutputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> post(port enable)", pExynosComponent, __FUNCTION__);
+            continue;
+        }
+
+        while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
+               (!pVideoDec->bExitBufferProcessThread)) {
+            Exynos_OSAL_SleepMillisec(0);
+
+            if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
+                (exynosOutputPort->exceptionFlag != GENERAL_STATE))
+                break;
+
+            Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
+            if ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorOutputBufferUseYet) {
+                if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
+                    CODEC_DEC_BUFFER *pCodecBuffer = NULL;
+                    ret = Exynos_CodecBufferDeQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR *)&pCodecBuffer);
+                    if (pVideoDec->bExitBufferProcessThread) {
+                        Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                        goto EXIT;
+                    }
+
+                    if (ret != OMX_ErrorNone) {
+                        Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                        break;
+                    }
+                    Exynos_CodecBufferToData(pCodecBuffer, &dstInputData, OUTPUT_PORT_INDEX);
+                }
+
+                if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+                    if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
+                        (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+                        ret = Exynos_OutputBufferGetQueue(pExynosComponent);
+                        if (pVideoDec->bExitBufferProcessThread) {
+                            Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                            goto EXIT;
+                        }
+
+                        if (ret != OMX_ErrorNone) {
+                            Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                            break;
+                        }
+
+                        ret = Exynos_Shared_BufferToData(exynosOutputPort, dstInputUseBuffer, &dstInputData);
+                        if (ret != OMX_ErrorNone) {
+                            dstInputUseBuffer->dataValid = OMX_FALSE;
+                            Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                            break;
+                        }
+#ifdef USE_ANDROID
+                        if ((exynosOutputPort->eMetaDataType == METADATA_TYPE_GRAPHIC) ||
+                            (exynosOutputPort->eMetaDataType == METADATA_TYPE_GRAPHIC_HANDLE)) {
+                            Exynos_OSAL_RefCount_Increase(pVideoDec->hRefHandle,
+                                                          dstInputData.bufferHeader->pBuffer,
+                                                          exynosOutputPort);
+                        }
+#endif
+                        Exynos_ResetDataBuffer(dstInputUseBuffer);
+                    }
+                }
+
+                if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
+                    Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                    break;
+                }
+            }
+
+            ret = pVideoDec->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
+            if ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorOutputBufferUseYet) {
+                Exynos_ResetCodecData(&dstInputData);
+            }
+            Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+        }
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE          ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER    *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+    EXYNOS_OMX_DATA          *pDstOutputData = &exynosOutputPort->processData;
+
+    FunctionIn();
+
+    while (!pVideoDec->bExitBufferProcessThread) {
+        Exynos_OSAL_SleepMillisec(0);
+        Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
+        if ((exynosOutputPort->semWaitPortEnable[OUTPUT_WAY_INDEX] != NULL) &&
+            (!CHECK_PORT_ENABLED(exynosOutputPort))) {
+            /* sema will be posted at PortEnable */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> wait(port enable)", pExynosComponent, __FUNCTION__);
+            Exynos_OSAL_SemaphoreWait(exynosOutputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> post(port enable)", pExynosComponent, __FUNCTION__);
+            continue;
+        }
+
+        while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
+               (!pVideoDec->bExitBufferProcessThread)) {
+            Exynos_OSAL_SleepMillisec(0);
+
+            if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
+                break;
+
+            Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
+            if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
+                if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
+                    (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+                    ret = Exynos_OutputBufferGetQueue(pExynosComponent);
+                    if (pVideoDec->bExitBufferProcessThread) {
+                        Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
+                        goto EXIT;
+                    }
+
+                    if (ret != OMX_ErrorNone) {
+                        Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
+                        break;
+                    }
+                }
+            }
+
+            if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
+                (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
+                ret = pVideoDec->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
+
+            if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
+                (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
+#ifdef USE_ANDROID
+                if (exynosOutputPort->bufferProcessType == BUFFER_SHARE) {
+                    DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
+                    int i;
+
+                    pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+                    for (i = 0; i < VIDEO_BUFFER_MAX_NUM; i++) {
+                        if (pBufferInfo->PDSB.dpbFD[i].fd > 0) {
+                            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] decRefCnt-FD:%llu",
+                                                                        pExynosComponent, __FUNCTION__, pBufferInfo->PDSB.dpbFD[i].fd);
+                            Exynos_OSAL_RefCount_Decrease(pVideoDec->hRefHandle, pBufferInfo->PDSB.dpbFD[i].fd);
+                        } else {
+                            break;
+                        }
+                    }
+                }
+#endif
+                Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
+            }
+
+            if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
+                if (pDstOutputData->pPrivate != NULL) {
+                    Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pDstOutputData->pPrivate);
+                    pDstOutputData->pPrivate = NULL;
+                }
+            }
+
+            /* reset outputData */
+            Exynos_ResetCodecData(pDstOutputData);
+            Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
+        }
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorNone;
+    OMX_COMPONENTTYPE   *pOMXComponent  = NULL;
+
+    FunctionIn();
+
+    if (threadData == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
+
+    Exynos_OSAL_ThreadExit(NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorNone;
+    OMX_COMPONENTTYPE   *pOMXComponent  = NULL;
+
+    FunctionIn();
+
+    if (threadData == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
+
+    Exynos_OSAL_ThreadExit(NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorNone;
+    OMX_COMPONENTTYPE   *pOMXComponent  = NULL;
+
+    FunctionIn();
+
+    if (threadData == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    Exynos_OMX_DstInputBufferProcess(pOMXComponent);
+
+    Exynos_OSAL_ThreadExit(NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorNone;
+    OMX_COMPONENTTYPE   *pOMXComponent  = NULL;
+
+    FunctionIn();
+
+    if (threadData == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
+
+    Exynos_OSAL_ThreadExit(NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    FunctionIn();
+
+    pVideoDec->bExitBufferProcessThread = OMX_FALSE;
+
+    ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstOutputThread,
+                 Exynos_OMX_DstOutputProcessThread,
+                 pOMXComponent);
+    if (ret == OMX_ErrorNone)
+        ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcOutputThread,
+                     Exynos_OMX_SrcOutputProcessThread,
+                     pOMXComponent);
+    if (ret == OMX_ErrorNone)
+        ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstInputThread,
+                     Exynos_OMX_DstInputProcessThread,
+                     pOMXComponent);
+    if (ret == OMX_ErrorNone)
+        ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcInputThread,
+                     Exynos_OMX_SrcInputProcessThread,
+                     pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    OMX_S32 countValue = 0;
+
+    FunctionIn();
+
+    pVideoDec->bExitBufferProcessThread = OMX_TRUE;
+
+    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
+    if (countValue == 0)
+        Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
+    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
+    if (countValue == 0)
+        Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
+
+    /* srcInput */
+    Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
+    Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX]);
+    Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcInputThread);
+    pVideoDec->hSrcInputThread = NULL;
+    Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX], 0);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] src input thread is terminated", pExynosComponent, __FUNCTION__);
+
+    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
+    if (countValue == 0)
+        Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
+    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
+    if (countValue == 0)
+        Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
+    pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    /* dstInput */
+    Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
+    Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX]);
+    Exynos_OSAL_ThreadTerminate(pVideoDec->hDstInputThread);
+    pVideoDec->hDstInputThread = NULL;
+    Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX], 0);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] dst input thread is terminated", pExynosComponent, __FUNCTION__);
+
+    /* srcOutput */
+    pVideoDec->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
+    pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
+
+    Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
+    Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX]);
+    Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcOutputThread);
+    pVideoDec->hSrcOutputThread = NULL;
+    Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX], 0);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] src output thread is terminated", pExynosComponent, __FUNCTION__);
+
+    /* dstOutput */
+    pVideoDec->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
+    pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
+    Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX]);
+    Exynos_OSAL_ThreadTerminate(pVideoDec->hDstOutputThread);
+    pVideoDec->hDstOutputThread = NULL;
+    Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX], 0);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] dst output thread is terminated", pExynosComponent, __FUNCTION__);
+
+    pExynosComponent->checkTimeStamp.needSetStartTimeStamp      = OMX_FALSE;
+    pExynosComponent->checkTimeStamp.needCheckStartTimeStamp    = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    DECODE_CODEC_EXTRA_BUFFERINFO   *pBufferInfo        = NULL;
+
+    int i = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to BaseComponent_Constructor", __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Port_Constructor(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Port_Constructor", __FUNCTION__);
+        Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    pVideoDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
+    if (pVideoDec == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_Port_Destructor(pOMXComponent);
+        Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Memset(pVideoDec, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
+    pVideoDec->bForceHeaderParsing      = OMX_FALSE;
+    pVideoDec->bReconfigDPB             = OMX_FALSE;
+    pVideoDec->bDTSMode                 = OMX_FALSE;
+    pVideoDec->bReorderMode             = OMX_FALSE;
+    pVideoDec->eDataType                = DATA_TYPE_8BIT;
+    pVideoDec->bQosChanged              = OMX_FALSE;
+    pVideoDec->nQosRatio                = 0;
+    pVideoDec->bThumbnailMode           = OMX_FALSE;
+    pVideoDec->bSearchBlackBarChanged   = OMX_FALSE;
+    pVideoDec->bSearchBlackBar          = OMX_FALSE;
+    pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec;
+
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->supportFormat = Exynos_OSAL_Malloc(sizeof(OMX_COLOR_FORMATTYPE) * INPUT_PORT_SUPPORTFORMAT_NUM_MAX);
+    if (pExynosPort->supportFormat == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosPort->supportFormat, 0, (sizeof(OMX_COLOR_FORMATTYPE) * INPUT_PORT_SUPPORTFORMAT_NUM_MAX));
+
+    pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferCountMin = MIN_VIDEO_INPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferSize = 0;
+    pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
+
+    pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
+    if (pExynosPort->portDefinition.format.video.cMIMEType == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+    pExynosPort->portDefinition.format.video.nFrameWidth = 0;
+    pExynosPort->portDefinition.format.video.nFrameHeight= 0;
+    pExynosPort->portDefinition.format.video.nStride = 0;
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.format.video.nBitrate = 64000;
+    pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->supportFormat = Exynos_OSAL_Malloc(sizeof(OMX_COLOR_FORMATTYPE) * OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX);
+    if (pExynosPort->supportFormat == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosPort->supportFormat, 0, (sizeof(OMX_COLOR_FORMATTYPE) * OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX));
+
+    pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
+
+    pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
+    if (pExynosPort->portDefinition.format.video.cMIMEType == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+    pExynosPort->portDefinition.format.video.nFrameWidth = 0;
+    pExynosPort->portDefinition.format.video.nFrameHeight= 0;
+    pExynosPort->portDefinition.format.video.nStride = 0;
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.format.video.nBitrate = 64000;
+    pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
+
+    pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO));
+    if (pExynosPort->processData.extInfo == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(((char *)pExynosPort->processData.extInfo), 0, sizeof(DECODE_CODEC_EXTRA_BUFFERINFO));
+    pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)(pExynosPort->processData.extInfo);
+    for (i = 0; i < VIDEO_BUFFER_MAX_NUM; i++) {
+        pBufferInfo->PDSB.dpbFD[i].fd  = 0;
+        pBufferInfo->PDSB.dpbFD[i].fd1 = 0;
+        pBufferInfo->PDSB.dpbFD[i].fd2 = 0;
+    }
+
+    pOMXComponent->UseBuffer              = &Exynos_OMX_UseBuffer;
+    pOMXComponent->AllocateBuffer         = &Exynos_OMX_AllocateBuffer;
+    pOMXComponent->FreeBuffer             = &Exynos_OMX_FreeBuffer;
+
+#ifdef TUNNELING_SUPPORT
+    pOMXComponent->ComponentTunnelRequest           = &Exynos_OMX_ComponentTunnelRequest;
+    pExynosComponent->exynos_AllocateTunnelBuffer   = &Exynos_OMX_AllocateTunnelBuffer;
+    pExynosComponent->exynos_FreeTunnelBuffer       = &Exynos_OMX_FreeTunnelBuffer;
+#endif
+
+    pExynosComponent->exynos_BufferProcessCreate    = &Exynos_OMX_BufferProcess_Create;
+    pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
+    pExynosComponent->exynos_BufferFlush          = &Exynos_OMX_BufferFlush;
+
+#ifdef USE_ANDROID
+    pVideoDec->hRefHandle = Exynos_OSAL_RefCount_Create();
+#endif
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE          ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+    int                    i = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_RefCount_Terminate(pVideoDec->hRefHandle);
+#endif
+
+    Exynos_OSAL_Free(pVideoDec);
+    pExynosComponent->hComponentHandle = pVideoDec = NULL;
+
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    if (pExynosPort->processData.extInfo != NULL) {
+        Exynos_OSAL_Free(pExynosPort->processData.extInfo);
+        pExynosPort->processData.extInfo = NULL;
+    }
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        pExynosPort = &pExynosComponent->pExynosPort[i];
+        Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
+        pExynosPort->portDefinition.format.video.cMIMEType = NULL;
+
+        Exynos_OSAL_Free(pExynosPort->supportFormat);
+        pExynosPort->supportFormat = NULL;
+    }
+
+    ret = Exynos_OMX_Port_Destructor(pOMXComponent);
+
+    ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/dec/Exynos_OMX_Vdec.h b/openmax/component/video/dec/Exynos_OMX_Vdec.h
new file mode 100755 (executable)
index 0000000..df75761
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Vdec.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              HyeYeon Chung (hyeon.chung@samsung.com)
+ *              Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_VIDEO_DECODE
+#define EXYNOS_OMX_VIDEO_DECODE
+
+#include "OMX_Component.h"
+#include "Exynos_OMX_Def.h"
+#include "Exynos_OSAL_Queue.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "ExynosVideoApi.h"
+
+#define MAX_VIDEO_INPUTBUFFER_NUM           5
+#define MIN_VIDEO_INPUTBUFFER_NUM           2
+#define MAX_VIDEO_OUTPUTBUFFER_NUM          4
+
+#define MAX_FRAME_WIDTH                 1920
+#define MAX_FRAME_HEIGHT                1080
+
+#define DEFAULT_VIDEO_INPUT_BUFFER_SIZE    (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT) * 2
+#define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE   (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3) / 2
+
+#define MFC_INPUT_BUFFER_NUM_MAX            3
+
+/* min size of input buffer for DRC */
+#define DEFAULT_VIDEO_MIN_INPUT_BUFFER_SIZE     (1024 * 1024 * 3 / 2)  /* 1.5MB */
+
+/* input buffer size for custom component */
+#define CUSTOM_DEFAULT_VIDEO_INPUT_BUFFER_SIZE     (1024 * 1024 * 3 / 2)  /* 1.5MB */
+#define CUSTOM_FHD_VIDEO_INPUT_BUFFER_SIZE         (1920 * 1088 * 3 / 2)
+#define CUSTOM_UHD_VIDEO_INPUT_BUFFER_SIZE         (1024 * 1024 * 6)      /* 6MB */
+
+#define MFC_OUTPUT_BUFFER_NUM_MAX           16 * 2
+#define DEFAULT_MFC_OUTPUT_YBUFFER_SIZE     MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT
+#define DEFAULT_MFC_OUTPUT_CBUFFER_SIZE     MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 2
+
+#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX         1
+#define OUTPUT_PORT_SUPPORTFORMAT_DEFAULT_NUM    3  /* I420P, NV12, RGBA */
+#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX        (OUTPUT_PORT_SUPPORTFORMAT_DEFAULT_NUM + 4)  /* NV12T, YV12, NV21, UNUSED */
+
+#define EXTRA_DPB_NUM                       5
+
+#define MFC_DEFAULT_INPUT_BUFFER_PLANE      1
+#define MFC_DEFAULT_OUTPUT_BUFFER_PLANE     2
+
+#define MAX_INPUTBUFFER_NUM_DYNAMIC         0 /* Dynamic number of metadata buffer */
+#define MAX_OUTPUTBUFFER_NUM_DYNAMIC        0 /* Dynamic number of metadata buffer */
+
+#define MAX_SECURE_INPUT_BUFFER_SIZE        ((3 * 1024 * 1024) / 2) /* 1.5MB */
+
+#define DEC_BLOCKS_PER_SECOND               979200 /* remove it and have to read a capability at media_codecs.xml */
+
+typedef struct
+{
+    void *pAddrY;
+    void *pAddrC;
+} CODEC_DEC_ADDR_INFO;
+
+typedef struct _BYPASS_BUFFER_INFO
+{
+    OMX_U32   nFlags;
+    OMX_TICKS timeStamp;
+} BYPASS_BUFFER_INFO;
+
+typedef struct _CODEC_DEC_BUFFER
+{
+    void            *pVirAddr[MAX_BUFFER_PLANE];   /* virtual address   */
+    unsigned int     bufferSize[MAX_BUFFER_PLANE]; /* buffer alloc size */
+    unsigned long    fd[MAX_BUFFER_PLANE];         /* buffer FD */
+    int              dataSize;                     /* total data length */
+} CODEC_DEC_BUFFER;
+
+typedef struct _DECODE_CODEC_EXTRA_BUFFERINFO
+{
+    OMX_U32                imageWidth;  /* original info of contents */
+    OMX_U32                imageHeight; /* original info of contents */
+    OMX_U32                imageStride; /* the size applibed H/W alignment. it is including padding data */
+    OMX_CONFIG_RECTTYPE    cropRect;    /* original info of contents */
+    OMX_COLOR_FORMATTYPE   colorFormat;
+    PrivateDataShareBuffer PDSB;
+} DECODE_CODEC_EXTRA_BUFFERINFO;
+
+typedef struct _EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP
+{
+    OMX_S32   nIndex;
+    OMX_TICKS timeStamp;
+    OMX_U32   nFlags;
+} EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP;
+
+typedef enum _EXYNOS_OMX_DATA_TYPE {
+    DATA_TYPE_8BIT           = 0x00,
+    DATA_TYPE_10BIT          = 0x01,
+    DATA_TYPE_8BIT_WITH_2BIT = 0x11,
+} EXYNOS_OMX_DATA_TYPE;
+
+typedef struct _EXYNOS_OMX_VIDEODEC_COMPONENT
+{
+    OMX_HANDLETYPE          hCodecHandle;
+    OMX_BOOL                bDiscardCSDError;          /* if it is true, discard a error event in CorruptedHeader case */
+    OMX_BOOL                bForceHeaderParsing;
+    OMX_BOOL                bThumbnailMode;
+    OMX_BOOL                bDTSMode;                  /* true:Decoding Time Stamp, false:Presentation Time Stamp */
+    OMX_BOOL                bReorderMode;              /* true:use Time Stamp reordering, don't care about a mode like as PTS or DTS */
+    EXYNOS_OMX_DATA_TYPE    eDataType;
+    OMX_BOOL                bQosChanged;
+    OMX_U32                 nQosRatio;
+    OMX_BOOL                bSearchBlackBarChanged;    /* true: Notify BlackBar searching option(en/disable) was changed */
+    OMX_BOOL                bSearchBlackBar;           /* true: BlackBar searching enable, false: disable */
+    OMX_CONFIG_RECTTYPE     blackBarCropRect;
+    OMX_U32                 nMinInBufSize;             /* required min size of input buffer for DRC */
+    CODEC_DEC_BUFFER       *pMFCDecInputBuffer[MFC_INPUT_BUFFER_NUM_MAX];
+    CODEC_DEC_BUFFER       *pMFCDecOutputBuffer[MFC_OUTPUT_BUFFER_NUM_MAX];
+
+    /* Buffer Process */
+    OMX_BOOL       bExitBufferProcessThread;
+    OMX_HANDLETYPE hSrcInputThread;
+    OMX_HANDLETYPE hSrcOutputThread;
+    OMX_HANDLETYPE hDstInputThread;
+    OMX_HANDLETYPE hDstOutputThread;
+
+    /* Shared Memory Handle */
+    OMX_HANDLETYPE hSharedMemory;
+
+    /* For Reconfiguration DPB */
+    OMX_BOOL bReconfigDPB;
+
+    /* For Ref Cnt handling about graphic buffer */
+    OMX_HANDLETYPE hRefHandle;
+
+    /* CSC handle */
+    OMX_PTR csc_handle;
+    OMX_U32 csc_set_format;
+
+    OMX_ERRORTYPE (*exynos_codec_srcInputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData);
+    OMX_ERRORTYPE (*exynos_codec_srcOutputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData);
+    OMX_ERRORTYPE (*exynos_codec_dstInputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pOutputData);
+    OMX_ERRORTYPE (*exynos_codec_dstOutputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pOutputData);
+
+    OMX_ERRORTYPE (*exynos_codec_start)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex);
+    OMX_ERRORTYPE (*exynos_codec_stop)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex);
+    OMX_ERRORTYPE (*exynos_codec_bufferProcessRun)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex);
+    OMX_ERRORTYPE (*exynos_codec_enqueueAllBuffer)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex);
+
+    OMX_ERRORTYPE (*exynos_codec_getCodecOutputPrivateData) (OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[]);
+
+    OMX_ERRORTYPE (*exynos_codec_reconfigAllBuffers) (OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex);
+    OMX_BOOL      (*exynos_codec_checkFormatSupport)(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_COLOR_FORMATTYPE eColorFormat);
+    OMX_ERRORTYPE (*exynos_codec_checkResolutionChange)(OMX_COMPONENTTYPE *pOMXComponent);
+} EXYNOS_OMX_VIDEODEC_COMPONENT;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent);
+void Exynos_Output_SetSupportFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+void Exynos_SetReorderTimestamp(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 *nIndex, OMX_TICKS timeStamp, OMX_U32 nFlags);
+void Exynos_GetReorderTimestamp(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP *sCurrentTimestamp, OMX_S32 nFrameIndex, OMX_S32 eFrameType);
+OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex);
+OMX_ERRORTYPE Exynos_CodecBufferToData(CODEC_DEC_BUFFER *codecBuffer, EXYNOS_OMX_DATA *pData, OMX_U32 nPortIndex);
+OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData);
+OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_Allocate_CodecBuffers(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex, int nBufferCnt, unsigned int nAllocSize[MAX_BUFFER_PLANE]);
+void Exynos_Free_CodecBuffers(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex);
+OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/Exynos_OMX_VdecControl.c b/openmax/component/video/dec/Exynos_OMX_VdecControl.c
new file mode 100755 (executable)
index 0000000..b61d068
--- /dev/null
@@ -0,0 +1,2374 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_VdecControl.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.5.0
+ * @history
+ *   2012.02.20 : Create
+ *   2017.08.03 : Change event handling
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OMX_Vdec.h"
+#include "Exynos_OMX_VdecControl.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OSAL_Thread.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_SharedMemory.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+#include "ExynosVideoApi.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VIDEO_DECCONTROL"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+OMX_ERRORTYPE Exynos_OMX_UseBuffer(
+    OMX_IN OMX_HANDLETYPE            hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32                   nPortIndex,
+    OMX_IN OMX_PTR                   pAppPrivate,
+    OMX_IN OMX_U32                   nSizeBytes,
+    OMX_IN OMX_U8                   *pBuffer)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT         *pExynosPort        = NULL;
+    OMX_BUFFERHEADERTYPE        *temp_bufferHeader  = NULL;
+
+    OMX_U32 i = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid parameter(0x%x)", pExynosComponent, __FUNCTION__, nPortIndex);
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    if (pExynosPort->portState != EXYNOS_OMX_PortStateEnabling) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] %s port : invalid state : comp state(0x%x), port state(0x%x), enabled(0x%x)",
+                        pExynosComponent, __FUNCTION__,
+                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                        pExynosComponent->currentState, pExynosPort->portState, pExynosPort->portDefinition.bEnabled);
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    if (CHECK_PORT_TUNNELED(pExynosPort) &&
+        CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (temp_bufferHeader == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
+
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
+            pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader;
+            pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED);
+            INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE);
+
+            temp_bufferHeader->pBuffer        = pBuffer;
+            temp_bufferHeader->nAllocLen      = nSizeBytes;
+            temp_bufferHeader->pAppPrivate    = pAppPrivate;
+
+            if (nPortIndex == INPUT_PORT_INDEX)
+                temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX;
+            else
+                temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX;
+
+            pExynosPort->assignedBufferNum++;
+
+            *ppBufferHdr = temp_bufferHeader;
+
+            if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+                pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+
+                if ((pExynosComponent->currentState == OMX_StateLoaded) &&
+                    (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle)) {
+                    if (CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]) &&
+                        CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX])) {
+                        Exynos_OMX_SendEventCommand(pExynosComponent, EVENT_CMD_STATE_TO_IDLE_STATE, NULL);
+                    }
+                } else if ((!CHECK_PORT_ENABLED(pExynosPort)) &&
+                           (pExynosPort->portState == EXYNOS_OMX_PortStateEnabling)) {
+                    Exynos_OMX_SendEventCommand(pExynosComponent,
+                                                ((nPortIndex == INPUT_PORT_INDEX)? EVENT_CMD_ENABLE_INPUT_PORT:EVENT_CMD_ENABLE_OUTPUT_PORT),
+                                                NULL);
+                }
+            }
+
+            ret = OMX_ErrorNone;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port: buffer header(%p), size(%d)",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                                    (*ppBufferHdr), nSizeBytes);
+            goto EXIT;
+        }
+    }
+
+    Exynos_OSAL_Free(temp_bufferHeader);
+    ret = OMX_ErrorInsufficientResources;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AllocateBuffer(
+    OMX_IN OMX_HANDLETYPE            hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
+    OMX_IN OMX_U32                   nPortIndex,
+    OMX_IN OMX_PTR                   pAppPrivate,
+    OMX_IN OMX_U32                   nSizeBytes)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    OMX_BUFFERHEADERTYPE            *temp_bufferHeader  = NULL;
+    OMX_U8                          *temp_buffer        = NULL;
+    unsigned long                    temp_buffer_fd     = -1;
+    MEMORY_TYPE                      mem_type           = NORMAL_MEMORY;
+
+    OMX_U32 i = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid parameter(0x%x)", pExynosComponent, __FUNCTION__, nPortIndex);
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    if (pExynosPort->portState != EXYNOS_OMX_PortStateEnabling) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] %s port : invalid state : comp state(0x%x), port state(0x%x), enabled(0x%x)",
+                        pExynosComponent, __FUNCTION__,
+                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                        pExynosComponent->currentState, pExynosPort->portState, pExynosPort->portDefinition.bEnabled);
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    if (CHECK_PORT_TUNNELED(pExynosPort) &&
+        CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) &&
+        (nPortIndex == INPUT_PORT_INDEX))
+        mem_type |= SECURE_MEMORY;
+
+    if (!((nPortIndex == OUTPUT_PORT_INDEX) &&
+          (pExynosPort->bufferProcessType & BUFFER_SHARE)))
+        mem_type |= CACHED_MEMORY;
+
+    if (pExynosPort->bNeedContigMem == OMX_TRUE)
+        mem_type |= CONTIG_MEMORY;
+
+    if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) &&
+        (nPortIndex == INPUT_PORT_INDEX) &&
+        (pExynosPort->eMetaDataType == METADATA_TYPE_HANDLE)) {  /* for DRM input : metadata */
+        temp_buffer = Exynos_OSAL_AllocMetaDataBuffer(pVideoDec->hSharedMemory,
+                                                      pExynosPort->eMetaDataType,
+                                                      nSizeBytes,
+                                                      mem_type);
+        if (temp_buffer == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Alloc", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    } else {
+        temp_buffer = Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nSizeBytes, mem_type);
+        if (temp_buffer == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Alloc", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        temp_buffer_fd = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, temp_buffer);
+    }
+
+    temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (temp_bufferHeader == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
+
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
+            pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader;
+            pExynosPort->extendBufferHeader[i].buf_fd[0] = temp_buffer_fd;
+            pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED);
+            INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE);
+
+            if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) &&
+                (pExynosPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
+                /* backward compatibility */
+                temp_bufferHeader->pBuffer = (void *)temp_buffer_fd;
+            } else {
+                temp_bufferHeader->pBuffer = temp_buffer;
+            }
+
+            temp_bufferHeader->nAllocLen      = nSizeBytes;
+            temp_bufferHeader->pAppPrivate    = pAppPrivate;
+
+            if (nPortIndex == INPUT_PORT_INDEX)
+                temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX;
+            else
+                temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX;
+
+            pExynosPort->assignedBufferNum++;
+
+            *ppBuffer = temp_bufferHeader;
+
+            if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+                pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+
+                if ((pExynosComponent->currentState == OMX_StateLoaded) &&
+                    (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle)) {
+                    if (CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]) &&
+                        CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX])) {
+                        Exynos_OMX_SendEventCommand(pExynosComponent, EVENT_CMD_STATE_TO_IDLE_STATE, NULL);
+                    }
+                } else if((!CHECK_PORT_ENABLED(pExynosPort)) &&
+                          (pExynosPort->portState == EXYNOS_OMX_PortStateEnabling)) {
+                    Exynos_OMX_SendEventCommand(pExynosComponent,
+                                                ((nPortIndex == INPUT_PORT_INDEX)? EVENT_CMD_ENABLE_INPUT_PORT:EVENT_CMD_ENABLE_OUTPUT_PORT),
+                                                NULL);
+                }
+            }
+
+            ret = OMX_ErrorNone;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port: buffer header(%p), size(%d)",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                                    (*ppBuffer), nSizeBytes);
+            goto EXIT;
+        }
+    }
+
+    ret = OMX_ErrorInsufficientResources;
+
+EXIT:
+    if (ret == OMX_ErrorInsufficientResources) {
+        if (temp_bufferHeader != NULL)
+            Exynos_OSAL_Free(temp_bufferHeader);
+
+        if (temp_buffer != NULL) {
+            if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) &&
+                (nPortIndex == INPUT_PORT_INDEX) &&
+                (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+                Exynos_OSAL_FreeMetaDataBuffer(pVideoDec->hSharedMemory, pExynosPort->eMetaDataType, temp_buffer);
+            } else if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) &&
+                       (pExynosPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
+                OMX_PTR mapBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, temp_buffer_fd);
+
+                Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, temp_buffer);
+            } else {
+                Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, temp_buffer);
+            }
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FreeBuffer(
+    OMX_IN OMX_HANDLETYPE        hComponent,
+    OMX_IN OMX_U32               nPortIndex,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    OMX_BUFFERHEADERTYPE            *pOMXBufferHdr      = NULL;
+
+    OMX_U32 i = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid parameter(0x%x)", pExynosComponent, __FUNCTION__, nPortIndex);
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    if ((pExynosPort->portState != EXYNOS_OMX_PortStateDisabling) &&
+        (pExynosPort->portState != EXYNOS_OMX_PortStateFlushingForDisable) &&
+        (pExynosPort->portState != EXYNOS_OMX_PortStateInvalid)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] %s port : invalid state : comp state(0x%x), port state(0x%x), enabled(0x%x)",
+                        pExynosComponent, __FUNCTION__,
+                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                        pExynosComponent->currentState, pExynosPort->portState, pExynosPort->portDefinition.bEnabled);
+        ret = OMX_ErrorIncorrectStateOperation;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+
+        (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent,
+                        pExynosComponent->callbackData,
+                        (OMX_U32)OMX_EventError,
+                        (OMX_U32)OMX_ErrorPortUnpopulated,
+                        nPortIndex, NULL);
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    if (CHECK_PORT_TUNNELED(pExynosPort) &&
+        CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    for (i = 0; i < MAX_BUFFER_NUM; i++) {
+        if (((pExynosPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) &&
+            (pExynosPort->extendBufferHeader[i].OMXBufferHeader != NULL)) {
+            pOMXBufferHdr = pExynosPort->extendBufferHeader[i].OMXBufferHeader;
+
+            if (pOMXBufferHdr->pBuffer == pBufferHdr->pBuffer) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port: buffer header(%p)",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                                        pOMXBufferHdr);
+                if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) {
+                    if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) &&
+                        (nPortIndex == INPUT_PORT_INDEX) &&
+                        (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+                        Exynos_OSAL_FreeMetaDataBuffer(pVideoDec->hSharedMemory,
+                                                       pExynosPort->eMetaDataType,
+                                                       pOMXBufferHdr->pBuffer);
+                    } else if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) &&
+                               (pExynosPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
+                        unsigned long ionFD = (unsigned long)pOMXBufferHdr->pBuffer;
+
+                        OMX_PTR mapBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, ionFD);
+                        Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, mapBuffer);
+                    } else {
+                        Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pOMXBufferHdr->pBuffer);
+                    }
+
+                    pOMXBufferHdr->pBuffer = NULL;
+                    pBufferHdr->pBuffer = NULL;
+                } else if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) {
+                    ; /* None*/
+                }
+
+                pExynosPort->assignedBufferNum--;
+
+                if (pExynosPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) {
+                    Exynos_OSAL_Free(pOMXBufferHdr);
+                    pExynosPort->extendBufferHeader[i].OMXBufferHeader  = NULL;
+                    pExynosPort->extendBufferHeader[i].bBufferInOMX     = OMX_FALSE;
+                    pBufferHdr = NULL;
+                }
+
+                pExynosPort->bufferStateAllocate[i] = BUFFER_STATE_FREE;
+                ret = OMX_ErrorNone;
+                goto EXIT;
+            }
+        }
+    }
+
+EXIT:
+    if (ret == OMX_ErrorNone) {
+        if (pExynosPort->assignedBufferNum < (OMX_S32)pExynosPort->portDefinition.nBufferCountActual)
+            pExynosPort->portDefinition.bPopulated = OMX_FALSE;
+
+        if (pExynosPort->assignedBufferNum == 0) {
+            if ((pExynosComponent->currentState == OMX_StateIdle) &&
+                (pExynosComponent->transientState == EXYNOS_OMX_TransStateIdleToLoaded)) {
+                if (!CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]) &&
+                    !CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX])) {
+                    Exynos_OMX_SendEventCommand(pExynosComponent, EVENT_CMD_STATE_TO_LOAD_STATE, NULL);
+                }
+            } else if((CHECK_PORT_ENABLED(pExynosPort)) &&
+                      (pExynosPort->portState == EXYNOS_OMX_PortStateDisabling)) {
+                Exynos_OMX_SendEventCommand(pExynosComponent,
+                                            ((nPortIndex == INPUT_PORT_INDEX)? EVENT_CMD_DISABLE_INPUT_PORT:EVENT_CMD_DISABLE_OUTPUT_PORT),
+                                            NULL);
+            }
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+#ifdef TUNNELING_SUPPORT
+OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                 ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT          *pExynosPort       = NULL;
+    OMX_BUFFERHEADERTYPE         *temp_bufferHeader = NULL;
+    OMX_U8                       *temp_buffer       = NULL;
+    OMX_U32                       bufferSize        = 0;
+    OMX_PARAM_PORTDEFINITIONTYPE  portDefinition;
+
+    ret = OMX_ErrorTunnelingUnsupported;
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FreeTunnelBuffer(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE            ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT     *pExynosPort        = NULL;
+    OMX_BUFFERHEADERTYPE    *temp_bufferHeader  = NULL;
+    OMX_U8                  *temp_buffer        = NULL;
+    OMX_U32                  bufferSize         = 0;
+
+    ret = OMX_ErrorTunnelingUnsupported;
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentTunnelRequest(
+    OMX_IN OMX_HANDLETYPE hComp,
+    OMX_IN OMX_U32        nPort,
+    OMX_IN OMX_HANDLETYPE hTunneledComp,
+    OMX_IN OMX_U32        nTunneledPort,
+    OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    ret = OMX_ErrorTunnelingUnsupported;
+EXIT:
+    return ret;
+}
+#endif
+
+OMX_ERRORTYPE Exynos_OMX_GetFlushBuffer(EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_DATABUFFER *pDataBuffer[])
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    *pDataBuffer = NULL;
+
+    if (pExynosPort->portWayType == WAY1_PORT) {
+        *pDataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer;
+    } else if (pExynosPort->portWayType == WAY2_PORT) {
+            pDataBuffer[0] = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
+            pDataBuffer[1] = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer);
+    }
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    OMX_BUFFERHEADERTYPE            *bufferHeader       = NULL;
+    EXYNOS_OMX_DATABUFFER           *pDataPortBuffer[2] = {NULL, NULL};
+    EXYNOS_OMX_MESSAGE              *message            = NULL;
+
+    OMX_S32 semValue = 0;
+    int i = 0;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if ((portIndex < 0) ||
+        (portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+
+    while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
+        Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &semValue);
+        if (semValue == 0)
+            Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[portIndex].bufferSemID);
+
+        Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[portIndex].bufferSemID);
+        message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+        if ((message != NULL) &&
+            (message->type != EXYNOS_OMX_CommandFakeBuffer)) {
+            bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData;
+            bufferHeader->nFilledLen = 0;
+
+            if (portIndex == OUTPUT_PORT_INDEX)
+                Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader);
+            else if (portIndex == INPUT_PORT_INDEX)
+                Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader);
+        }
+
+        Exynos_OSAL_Free(message);
+        message = NULL;
+    }
+
+    Exynos_OMX_GetFlushBuffer(pExynosPort, pDataPortBuffer);
+    if (portIndex == INPUT_PORT_INDEX) {
+        if (pDataPortBuffer[0]->dataValid == OMX_TRUE)
+            Exynos_InputBufferReturn(pOMXComponent, pDataPortBuffer[0]);
+        if (pDataPortBuffer[1]->dataValid == OMX_TRUE)
+            Exynos_InputBufferReturn(pOMXComponent, pDataPortBuffer[1]);
+    } else if (portIndex == OUTPUT_PORT_INDEX) {
+        if (pDataPortBuffer[0]->dataValid == OMX_TRUE)
+            Exynos_OutputBufferReturn(pOMXComponent, pDataPortBuffer[0]);
+        if (pDataPortBuffer[1]->dataValid == OMX_TRUE)
+            Exynos_OutputBufferReturn(pOMXComponent, pDataPortBuffer[1]);
+    }
+
+    if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+        if (pExynosPort->processData.bufferHeader != NULL) {
+            if (portIndex == INPUT_PORT_INDEX) {
+                Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader);
+            } else if (portIndex == OUTPUT_PORT_INDEX) {
+                if (pExynosPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK)
+                    Exynos_OSAL_UnlockMetaData(pExynosPort->processData.bufferHeader->pBuffer, pExynosPort->eMetaDataType);
+
+                Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader);
+            }
+        }
+        Exynos_ResetCodecData(&pExynosPort->processData);
+
+        for (i = 0; i < MAX_BUFFER_NUM; i++) {
+            if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_TRUE) {
+                if (portIndex == OUTPUT_PORT_INDEX) {
+                    if (pExynosPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK)
+                        Exynos_OSAL_UnlockMetaData(pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer, pExynosPort->eMetaDataType);
+
+                    Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->extendBufferHeader[i].OMXBufferHeader);
+                } else if (portIndex == INPUT_PORT_INDEX) {
+                    Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->extendBufferHeader[i].OMXBufferHeader);
+                }
+            }
+        }
+    }
+
+#ifdef USE_ANDROID
+    if ((pExynosPort->bufferProcessType == BUFFER_SHARE) &&
+        (portIndex == OUTPUT_PORT_INDEX))
+        Exynos_OSAL_RefCount_Reset(pVideoDec->hRefHandle);
+#endif
+
+    if (pExynosPort->bufferSemID != NULL) {
+        while (1) {
+            OMX_S32 cnt = 0;
+            Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &cnt);
+            if (cnt == 0)
+                break;
+            else if (cnt > 0)
+                Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+            else if (cnt < 0)
+                Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    Exynos_OSAL_ResetQueue(&pExynosPort->bufferQ);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+
+OMX_ERRORTYPE Exynos_OMX_ForceHeaderParsing(
+    OMX_COMPONENTTYPE       *pOMXComponent,
+    EXYNOS_OMX_DATABUFFER   *pSrcDataBuffer,
+    EXYNOS_OMX_DATA         *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    OMX_PTR  pCodecBuffer   = NULL;
+    OMX_S32  nBufferCnt     = 0;
+    OMX_BOOL bSubmitCSD     = OMX_FALSE;
+
+    FunctionIn();
+
+    pVideoDec->bForceHeaderParsing = OMX_TRUE;
+
+    /* get a count of queued buffer */
+    nBufferCnt = Exynos_OSAL_GetElemNum(&pInputPort->bufferQ);
+
+    /* it is possible that input way has valid info,
+     * it means that Exynos_Preprocessor_InputData is not handled yet.
+     * so, do-while loop is used.
+     */
+    do {
+        if (pSrcDataBuffer->dataValid == OMX_TRUE) {
+            if (!(pSrcDataBuffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
+                /* if does not have CSD flag, think of that all CSDs were already parsed */
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] no more CSD buffer", pExynosComponent, __FUNCTION__);
+                break;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] has CSD buffer(%p), remains(%d)",
+                                    pExynosComponent, __FUNCTION__, pSrcDataBuffer->bufferHeader, nBufferCnt);
+
+            /* for BUFFER_COPY mode, get a codec buffer */
+            if ((pInputPort->bufferProcessType & BUFFER_COPY) &&
+                ((pSrcInputData->buffer.addr[0] == NULL) ||
+                 (pSrcInputData->pPrivate == NULL))) {
+                Exynos_CodecBufferDeQueue(pExynosComponent, INPUT_PORT_INDEX, &pCodecBuffer);
+                if (pCodecBuffer == NULL) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] can't find a valid codec buffer", pExynosComponent, __FUNCTION__);
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+
+                Exynos_CodecBufferToData(pCodecBuffer, pSrcInputData, INPUT_PORT_INDEX);
+            }
+
+            if (Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData) == OMX_TRUE) {
+                ret = pVideoDec->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
+                switch ((int)ret) {
+                case OMX_ErrorNone:
+                {
+                    bSubmitCSD = OMX_TRUE;
+                }
+                    break;
+                case OMX_ErrorCorruptedFrame:
+                case OMX_ErrorCorruptedHeader:
+                case OMX_ErrorInputDataDecodeYet:  /* no need re-input scheme */
+                {
+                    /* discard current buffer */
+                    if (pInputPort->bufferProcessType & BUFFER_COPY)
+                        Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pSrcInputData->pPrivate);
+
+                    if (pInputPort->bufferProcessType & BUFFER_SHARE)
+                        Exynos_OMX_InputBufferReturn(pOMXComponent, pSrcInputData->bufferHeader);
+                }
+                    break;
+                case OMX_ErrorNeedNextHeaderInfo:
+                case OMX_ErrorNoneSrcSetupFinish:
+                {
+                    /* no need to process anything */
+                }
+                    break;
+                default:
+                {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] error is occurred at pre-processing(0x%x)",
+                                                        pExynosComponent, __FUNCTION__, ret);
+                    goto EXIT;
+                }
+                    break;
+                }
+            } else {
+                if (pInputPort->bufferProcessType & BUFFER_COPY)
+                    Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pSrcInputData->pPrivate);
+            }
+
+            /* info cleanup */
+            Exynos_ResetDataBuffer(pSrcDataBuffer);
+            Exynos_ResetCodecData(pSrcInputData);
+        }
+
+        if (nBufferCnt > 0) {
+            nBufferCnt--;
+
+            /* get a buffer from port */
+            ret = Exynos_InputBufferGetQueue(pExynosComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Failed to InputBufferGetQueue", pExynosComponent, __FUNCTION__);
+                break;
+            }
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] no more buffer", pExynosComponent, __FUNCTION__);
+            break;
+        }
+    } while (1);
+
+EXIT:
+    pVideoDec->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
+
+    if (bSubmitCSD == OMX_TRUE) {
+        ret = pVideoDec->exynos_codec_checkResolutionChange(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] error is occurred at resolution check(0x%x)",
+                                              pExynosComponent, __FUNCTION__, ret);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                       pExynosComponent->callbackData,
+                                                       OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+    pVideoDec->bForceHeaderParsing = OMX_FALSE;
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BufferFlush(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_S32             nPortIndex,
+    OMX_BOOL            bEvent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    EXYNOS_OMX_DATABUFFER           *flushPortBuffer[2] = {NULL, NULL};
+    EXYNOS_OMX_PORT_STATETYPE        ePortState         = EXYNOS_OMX_PortStateInvalid;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if ((nPortIndex < 0) ||
+        (nPortIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+    ePortState  = pExynosPort->portState;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] OMX_CommandFlush start, port:%d, event:%d",
+                                    pExynosComponent, __FUNCTION__, nPortIndex, bEvent);
+
+    Exynos_OSAL_SignalSet(pExynosPort->pauseEvent);
+
+    Exynos_OMX_GetFlushBuffer(pExynosPort, flushPortBuffer);
+    if (flushPortBuffer[0] == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pExynosPort->bufferProcessType & BUFFER_COPY)
+        Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID);
+
+    if (pExynosPort->bufferSemID != NULL) {
+        while (1) {
+            OMX_S32 cnt = 0;
+            Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &cnt);
+            if (cnt > 0)
+                break;
+            else
+                Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, nPortIndex);
+    Exynos_OSAL_MutexLock(flushPortBuffer[0]->bufferMutex);
+
+    pVideoDec->exynos_codec_stop(pOMXComponent, nPortIndex);
+
+    if (flushPortBuffer[1] != NULL)
+        Exynos_OSAL_MutexLock(flushPortBuffer[1]->bufferMutex);
+
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) {
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            /* try to find a CSD buffer and parse it */
+            Exynos_OMX_ForceHeaderParsing(pOMXComponent, flushPortBuffer[0], &(pExynosPort->processData));
+        }
+    }
+
+    ret = Exynos_OMX_FlushPort(pOMXComponent, nPortIndex);
+
+    if ((ePortState == EXYNOS_OMX_PortStateFlushingForDisable) &&
+        (pVideoDec->bReconfigDPB == OMX_TRUE)) {
+        ret = pVideoDec->exynos_codec_reconfigAllBuffers(pOMXComponent, nPortIndex);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+    } else if (pExynosComponent->pExynosPort[nPortIndex].bufferProcessType & BUFFER_COPY) {
+        pVideoDec->exynos_codec_enqueueAllBuffer(pOMXComponent, nPortIndex);
+    }
+
+    Exynos_ResetCodecData(&pExynosPort->processData);
+
+    if (ret == OMX_ErrorNone) {
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE;
+            pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
+            Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, OMX_FALSE, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+            INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+            Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+            pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+            pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+            pExynosComponent->bBehaviorEOS = OMX_FALSE;
+            pExynosComponent->reInputData = OMX_FALSE;
+
+            pVideoDec->exynos_codec_start(pOMXComponent, nPortIndex);
+        } else {
+            if (pVideoDec->bReconfigDPB != OMX_TRUE)
+                pVideoDec->exynos_codec_start(pOMXComponent, nPortIndex);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_CountReset(pExynosPort->hBufferCount);
+#endif
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] OMX_CommandFlush end, port:%d, event:%d",
+                                        pExynosComponent, __FUNCTION__, nPortIndex, bEvent);
+
+EXIT:
+    if (flushPortBuffer[1] != NULL)
+        Exynos_OSAL_MutexUnlock(flushPortBuffer[1]->bufferMutex);
+
+    if (flushPortBuffer[0] != NULL)
+        Exynos_OSAL_MutexUnlock(flushPortBuffer[0]->bufferMutex);
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_InputBufferReturn(
+    OMX_COMPONENTTYPE       *pOMXComponent,
+    EXYNOS_OMX_DATABUFFER   *pDataBuffer)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT         *pInputPort         = NULL;
+    OMX_BUFFERHEADERTYPE        *pBufferHdr         = NULL;
+
+    FunctionIn();
+
+    if ((pOMXComponent == NULL) ||
+        (pDataBuffer == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pInputPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]);
+
+    pBufferHdr = pDataBuffer->bufferHeader;
+
+    if (pBufferHdr != NULL) {
+        if (pInputPort->markType.hMarkTargetComponent != NULL) {
+            pBufferHdr->hMarkTargetComponent            = pInputPort->markType.hMarkTargetComponent;
+            pBufferHdr->pMarkData                       = pInputPort->markType.pMarkData;
+            pInputPort->markType.hMarkTargetComponent   = NULL;
+            pInputPort->markType.pMarkData              = NULL;
+        }
+
+        if (pBufferHdr->hMarkTargetComponent != NULL) {
+            if (pBufferHdr->hMarkTargetComponent == pOMXComponent) {
+                pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                pExynosComponent->callbackData,
+                                OMX_EventMark,
+                                0, 0, pBufferHdr->pMarkData);
+            } else {
+                pExynosComponent->propagateMarkType.hMarkTargetComponent    = pBufferHdr->hMarkTargetComponent;
+                pExynosComponent->propagateMarkType.pMarkData               = pBufferHdr->pMarkData;
+            }
+        }
+
+        pBufferHdr->nFilledLen  = 0;
+        pBufferHdr->nOffset     = 0;
+
+        Exynos_OMX_InputBufferReturn(pOMXComponent, pBufferHdr);
+    }
+
+    /* reset dataBuffer */
+    Exynos_ResetDataBuffer(pDataBuffer);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_InputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorUndefined;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort    = NULL;
+    EXYNOS_OMX_MESSAGE              *message        = NULL;
+    EXYNOS_OMX_DATABUFFER           *inputUseBuffer = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec      = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pExynosPort    = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    inputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
+
+    if (pExynosComponent->currentState != OMX_StateExecuting) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    } else if (((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+                (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) ||
+               (pVideoDec->bForceHeaderParsing == OMX_TRUE)) {
+        if (pVideoDec->bForceHeaderParsing != OMX_TRUE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> wait(bufferSemID)",
+                                                        pExynosComponent, __FUNCTION__);
+            Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> post(bufferSemID)",
+                                                        pExynosComponent, __FUNCTION__);
+        }
+
+        if (inputUseBuffer->dataValid != OMX_TRUE) {
+            message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+            if (message == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+            if (message->type == EXYNOS_OMX_CommandFakeBuffer) {
+                Exynos_OSAL_Free(message);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecFlush;
+                goto EXIT;
+            }
+
+            inputUseBuffer->bufferHeader  = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
+            inputUseBuffer->allocSize     = inputUseBuffer->bufferHeader->nAllocLen;
+            inputUseBuffer->dataLen       = inputUseBuffer->bufferHeader->nFilledLen;
+            inputUseBuffer->remainDataLen = inputUseBuffer->dataLen;
+            inputUseBuffer->usedDataLen   = 0;
+            inputUseBuffer->dataValid     = OMX_TRUE;
+            inputUseBuffer->nFlags        = inputUseBuffer->bufferHeader->nFlags;
+            inputUseBuffer->timeStamp     = inputUseBuffer->bufferHeader->nTimeStamp;
+
+            Exynos_OSAL_Free(message);
+
+            if (inputUseBuffer->allocSize < inputUseBuffer->dataLen) {
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] buffer size(%d) is smaller than dataLen(%d)",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    inputUseBuffer->allocSize, inputUseBuffer->dataLen);
+            }
+        }
+
+        ret = OMX_ErrorNone;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OutputBufferReturn(
+    OMX_COMPONENTTYPE       *pOMXComponent,
+    EXYNOS_OMX_DATABUFFER   *pDataBuffer)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT         *pOutputPort        = NULL;
+    OMX_BUFFERHEADERTYPE        *pBufferHdr         = pDataBuffer->bufferHeader;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pOutputPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+
+    if (pBufferHdr != NULL) {
+        pBufferHdr->nFilledLen = pDataBuffer->remainDataLen;
+        pBufferHdr->nOffset    = 0;
+        pBufferHdr->nFlags     = pDataBuffer->nFlags;
+        pBufferHdr->nTimeStamp = pDataBuffer->timeStamp;
+
+        if ((pOutputPort->eMetaDataType & METADATA_TYPE_DATA) &&
+            (pBufferHdr->nFilledLen > 0))
+            pBufferHdr->nFilledLen = pBufferHdr->nAllocLen;
+
+        if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) {
+            pBufferHdr->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent;
+            pBufferHdr->pMarkData            = pExynosComponent->propagateMarkType.pMarkData;
+
+            pExynosComponent->propagateMarkType.hMarkTargetComponent    = NULL;
+            pExynosComponent->propagateMarkType.pMarkData               = NULL;
+        }
+
+        if ((pBufferHdr->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] send event(OMX_EventBufferFlag)",
+                                                pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                            pExynosComponent->callbackData,
+                            OMX_EventBufferFlag,
+                            OUTPUT_PORT_INDEX,
+                            pBufferHdr->nFlags, NULL);
+        }
+
+        Exynos_OMX_OutputBufferReturn(pOMXComponent, pBufferHdr);
+    }
+
+    /* reset dataBuffer */
+    Exynos_ResetDataBuffer(pDataBuffer);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OutputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE          ret              = OMX_ErrorUndefined;
+    EXYNOS_OMX_BASEPORT   *pExynosPort      = NULL;
+    EXYNOS_OMX_MESSAGE    *message          = NULL;
+    EXYNOS_OMX_DATABUFFER *outputUseBuffer  = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+
+    if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+        outputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer);
+    } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+        outputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
+    } else {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->currentState != OMX_StateExecuting) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+               (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> wait(bufferSemID)",
+                                                    pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> post(bufferSemID)",
+                                                    pExynosComponent, __FUNCTION__);
+        if (outputUseBuffer->dataValid != OMX_TRUE) {
+            message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+            if (message == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+            if (message->type == EXYNOS_OMX_CommandFakeBuffer) {
+                Exynos_OSAL_Free(message);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecFlush;
+                goto EXIT;
+            }
+
+            outputUseBuffer->bufferHeader  = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
+            outputUseBuffer->allocSize     = outputUseBuffer->bufferHeader->nAllocLen;
+            outputUseBuffer->dataLen       = 0; //dataBuffer->bufferHeader->nFilledLen;
+            outputUseBuffer->remainDataLen = outputUseBuffer->dataLen;
+            outputUseBuffer->usedDataLen   = 0; //dataBuffer->bufferHeader->nOffset;
+            outputUseBuffer->dataValid     = OMX_TRUE;
+            /* dataBuffer->nFlags             = dataBuffer->bufferHeader->nFlags; */
+            /* dataBuffer->nTimeStamp         = dataBuffer->bufferHeader->nTimeStamp; */
+/*
+            if (pExynosPort->bufferProcessType & BUFFER_SHARE)
+                outputUseBuffer->pPrivate      = outputUseBuffer->bufferHeader->pOutputPortPrivate;
+            else if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+                pExynosPort->processData.dataBuffer = outputUseBuffer->bufferHeader->pBuffer;
+                pExynosPort->processData.allocSize  = outputUseBuffer->bufferHeader->nAllocLen;
+            }
+*/
+            Exynos_OSAL_Free(message);
+        }
+
+        ret = OMX_ErrorNone;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+
+}
+
+OMX_BUFFERHEADERTYPE *Exynos_OutputBufferGetQueue_Direct(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_BUFFERHEADERTYPE  *retBuffer    = NULL;
+    EXYNOS_OMX_BASEPORT   *pExynosPort  = NULL;
+    EXYNOS_OMX_MESSAGE    *message      = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        retBuffer = NULL;
+        goto EXIT;
+    }
+    pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+
+    if (pExynosComponent->currentState != OMX_StateExecuting) {
+        retBuffer = NULL;
+        goto EXIT;
+    } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+               (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> wait(bufferSemID)",
+                                                    pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> post(bufferSemID)",
+                                                    pExynosComponent, __FUNCTION__);
+
+        message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+        if (message == NULL) {
+            retBuffer = NULL;
+            goto EXIT;
+        }
+
+        if (message->type == EXYNOS_OMX_CommandFakeBuffer) {
+            Exynos_OSAL_Free(message);
+            retBuffer = NULL;
+            goto EXIT;
+        }
+
+        retBuffer  = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
+        Exynos_OSAL_Free(message);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return retBuffer;
+}
+
+OMX_ERRORTYPE Exynos_CodecBufferEnQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex, OMX_PTR data)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT *pExynosPort    = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (PortIndex >= pExynosComponent->portParam.nPorts) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &(pExynosComponent->pExynosPort[PortIndex]);
+
+    if (data == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_Queue(&pExynosPort->codecBufferQ, (void *)data);
+    if (ret != 0) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+    Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_CodecBufferDeQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex, OMX_PTR *data)
+{
+    OMX_ERRORTYPE          ret         = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT   *pExynosPort = NULL;
+    OMX_PTR                tempData    = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (PortIndex >= pExynosComponent->portParam.nPorts) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &(pExynosComponent->pExynosPort[PortIndex]);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port -> wait(codecSemID)",
+                                                pExynosComponent, __FUNCTION__,
+                                                (PortIndex == INPUT_PORT_INDEX)? "input":"output");
+    Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port -> wait(codecSemID)",
+                                                pExynosComponent, __FUNCTION__,
+                                                (PortIndex == INPUT_PORT_INDEX)? "input":"output");
+
+    tempData = (OMX_PTR)Exynos_OSAL_Dequeue(&pExynosPort->codecBufferQ);
+    if (tempData == NULL) {
+        *data = NULL;
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+    *data = tempData;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_CodecBufferReset(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT *pExynosPort    = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (PortIndex >= pExynosComponent->portParam.nPorts) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &(pExynosComponent->pExynosPort[PortIndex]);
+
+    ret = Exynos_OSAL_ResetQueue(&pExynosPort->codecBufferQ);
+    if (ret != 0) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+    while (1) {
+        OMX_S32 cnt = 0;
+        Exynos_OSAL_Get_SemaphoreCount(pExynosPort->codecSemID, &cnt);
+        if (cnt > 0)
+            Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID);
+        else
+            break;
+    }
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     ComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (ComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoInit:
+    {
+        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        portParam->nPorts           = pExynosComponent->portParam.nPorts;
+        portParam->nStartPortNumber = pExynosComponent->portParam.nStartPortNumber;
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+        OMX_U32                         nPortIndex  = pPortFormat->nPortIndex;
+        OMX_U32                         nIndex      = pPortFormat->nIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE   *pPortDef    = NULL;
+
+        OMX_BOOL bFormatSupport = OMX_FALSE;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((nPortIndex >= pExynosComponent->portParam.nPorts)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            if (nIndex > (INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1)) {
+                ret = OMX_ErrorNoMore;
+                goto EXIT;
+            }
+
+            pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+            pPortDef    = &pExynosPort->portDefinition;
+
+            pPortFormat->eCompressionFormat = pPortDef->format.video.eCompressionFormat;
+            pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
+            pPortFormat->eColorFormat       = pPortDef->format.video.eColorFormat;
+        } else if (nPortIndex == OUTPUT_PORT_INDEX) {
+            if (nIndex > (OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1)) {
+                ret = OMX_ErrorNoMore;
+                goto EXIT;
+            }
+
+            pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+            pPortDef    = &pExynosPort->portDefinition;
+            pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+            pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
+
+            if (pExynosPort->eMetaDataType == METADATA_TYPE_DISABLED) {
+                if (pExynosPort->supportFormat[nIndex] == OMX_COLOR_FormatUnused) {
+                    ret = OMX_ErrorNoMore;
+                    goto EXIT;
+                }
+                pPortFormat->eColorFormat = pExynosPort->supportFormat[nIndex];
+            } else {
+                if (nIndex > 0) {
+                    ret = OMX_ErrorNoMore;
+                    goto EXIT;
+                }
+
+                bFormatSupport = pVideoDec->exynos_codec_checkFormatSupport(pExynosComponent, (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled);
+#ifdef USE_ANDROID
+                if (bFormatSupport == OMX_TRUE)
+                    pPortFormat->eColorFormat = Exynos_OSAL_OMX2HALPixelFormat((OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled, pExynosPort->ePlaneType);
+                else
+                    pPortFormat->eColorFormat = Exynos_OSAL_OMX2HALPixelFormat(OMX_COLOR_FormatYUV420SemiPlanar, pExynosPort->ePlaneType);
+#else
+                if (bFormatSupport == OMX_TRUE)
+                    pPortFormat->eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
+                else
+                    pPortFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+#endif
+            }
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamDescribeColorFormat:
+    case OMX_IndexParamGetAndroidNativeBuffer:
+    {
+        ret = Exynos_OSAL_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
+    }
+        break;
+#endif
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+        OMX_U32                       nPortIndex     = portDefinition->nPortIndex;
+
+        ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+#ifdef USE_ANDROID
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if ((pExynosPort->eMetaDataType == METADATA_TYPE_GRAPHIC) ||
+            (pExynosPort->eMetaDataType == METADATA_TYPE_GRAPHIC_HANDLE)) {
+            switch (pVideoDec->eDataType) {
+            case DATA_TYPE_8BIT_WITH_2BIT:
+                portDefinition->format.video.eColorFormat =
+                    (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HALPixelFormat((OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatS10bitYUV420SemiPlanar,
+                                                    pExynosPort->ePlaneType);
+                break;
+            case DATA_TYPE_10BIT:
+                portDefinition->format.video.eColorFormat =
+                    (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HALPixelFormat((OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_Format10bitYUV420SemiPlanar,
+                                                    pExynosPort->ePlaneType);
+                break;
+            default:
+                portDefinition->format.video.eColorFormat =
+                    (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HALPixelFormat(portDefinition->format.video.eColorFormat, pExynosPort->ePlaneType);
+                break;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] portDefinition->format.video.eColorFormat: 0x%x",
+                                                    pExynosComponent, __FUNCTION__, portDefinition->format.video.eColorFormat);
+        }
+#endif
+        ret = Exynos_OSAL_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+    }
+        break;
+    case OMX_IndexVendorNeedContigMemory:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE  *pPortMemType    = (EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *)ComponentParameterStructure;
+        OMX_U32                              nPortIndex      = pPortMemType->nPortIndex;
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortMemType, sizeof(EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        pPortMemType->bNeedContigMem = pExynosPort->bNeedContigMem;
+    }
+        break;
+    case OMX_IndexExynosParamCorruptedHeader:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_CORRUPTEDHEADER  *pCorruptedHeader = (EXYNOS_OMX_VIDEO_PARAM_CORRUPTEDHEADER *)ComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pCorruptedHeader, sizeof(EXYNOS_OMX_VIDEO_PARAM_CORRUPTEDHEADER));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pCorruptedHeader->bDiscardEvent = pVideoDec->bDiscardCSDError;
+    }
+        break;
+    default:
+    {
+        ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
+    }
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        ComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (ComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+        OMX_U32                         nPortIndex  = pPortFormat->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE   *pPortDef    = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((nPortIndex >= pExynosComponent->portParam.nPorts)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            pPortDef = &pExynosPort->portDefinition;
+
+            pPortDef->format.video.eColorFormat       = pPortFormat->eColorFormat;
+            pPortDef->format.video.eCompressionFormat = pPortFormat->eCompressionFormat;
+            pPortDef->format.video.xFramerate         = pPortFormat->xFramerate;
+#ifdef USE_ANDROID
+            if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+                (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+                pPortDef->format.video.eColorFormat = Exynos_OSAL_HAL2OMXColorFormat(pPortFormat->eColorFormat);
+            }
+#endif
+            Exynos_UpdateFrameSize(pOMXComponent);
+        }
+    }
+        break;
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE  *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+        OMX_U32                        portIndex       = pPortDefinition->nPortIndex;
+        OMX_U32 size;
+        OMX_U32 realWidth, realHeight;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        if (portIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+        if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+#ifdef USE_ANDROID
+        /* to prevent a over-allocation about reserved memory */
+        if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) &&
+            (portIndex == OUTPUT_PORT_INDEX)) {
+            int nDisExtBufCnt = Exynos_OSAL_GetDisplayExtraBufferCount();
+
+            if (pPortDefinition->nBufferCountActual > (pExynosPort->portDefinition.nBufferCountMin + nDisExtBufCnt)) {
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+            }
+        }
+#endif
+
+        Exynos_OSAL_Memcpy(((char *)&pExynosPort->portDefinition) + nOffset,
+                           ((char *)pPortDefinition) + nOffset,
+                           pPortDefinition->nSize - nOffset);
+
+#ifdef USE_ANDROID // Modified by Google engineer
+        /* should not affect the format since in ANB case, the caller
+                * is providing us a HAL format */
+        if ((pExynosPort->eMetaDataType == METADATA_TYPE_GRAPHIC) ||
+            (pExynosPort->eMetaDataType == METADATA_TYPE_GRAPHIC_HANDLE)) {
+            pExynosPort->portDefinition.format.video.eColorFormat =
+                Exynos_OSAL_HAL2OMXColorFormat(pExynosPort->portDefinition.format.video.eColorFormat);
+        }
+#endif
+
+        realWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
+        realHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
+        size = (ALIGN(realWidth, 16) * ALIGN(realHeight, 16) * 3) / 2;
+        pExynosPort->portDefinition.format.video.nStride = realWidth;
+        pExynosPort->portDefinition.format.video.nSliceHeight = realHeight;
+        pExynosPort->portDefinition.nBufferSize = (size > pExynosPort->portDefinition.nBufferSize) ? size : pExynosPort->portDefinition.nBufferSize;
+
+        if (portIndex == INPUT_PORT_INDEX) {
+            if (pExynosPort->portDefinition.nBufferSize < pVideoDec->nMinInBufSize)
+                pExynosPort->portDefinition.nBufferSize = pVideoDec->nMinInBufSize;
+
+            if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) {
+                if (pExynosPort->portDefinition.nBufferSize > CUSTOM_FHD_VIDEO_INPUT_BUFFER_SIZE) {
+                    pExynosPort->portDefinition.nBufferSize = (CUSTOM_UHD_VIDEO_INPUT_BUFFER_SIZE > pExynosPort->portDefinition.nBufferSize) ?
+                                                               CUSTOM_UHD_VIDEO_INPUT_BUFFER_SIZE : (pExynosPort->portDefinition.nBufferSize / 2);
+                } else {
+                    pExynosPort->portDefinition.nBufferSize = CUSTOM_DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+                }
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] the size of input buffer is %d",
+                                                pExynosComponent, __FUNCTION__, pExynosPort->portDefinition.nBufferSize);
+
+            Exynos_UpdateFrameSize(pOMXComponent);
+        }
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamEnableAndroidBuffers:
+    case OMX_IndexParamAllocateNativeHandle:
+#endif
+    // Porting exynos 9110, code from SM-R765(7270) 
+    case OMX_IndexParamStoreMetaDataBuffer:
+    {
+        ret = Exynos_OSAL_SetParameter(hComponent, nIndex, ComponentParameterStructure);
+    }
+        break;
+    case OMX_IndexVendorNeedContigMemory:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE  *pPortMemType    = (EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *)ComponentParameterStructure;
+        OMX_U32                              nPortIndex      = pPortMemType->nPortIndex;
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortMemType, sizeof(EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        pExynosPort->bNeedContigMem = pPortMemType->bNeedContigMem;
+    }
+        break;
+    case OMX_IndexVendorSetDTSMode:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_DTSMODE  *pDTSParam  = (EXYNOS_OMX_VIDEO_PARAM_DTSMODE *)ComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDTSParam, sizeof(EXYNOS_OMX_VIDEO_PARAM_DTSMODE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pVideoDec->bDTSMode = pDTSParam->bDTSMode;
+    }
+        break;
+    case OMX_IndexParamEnableThumbnailMode:
+    {
+        EXYNOS_OMX_VIDEO_THUMBNAILMODE  *pThumbnailMode = (EXYNOS_OMX_VIDEO_THUMBNAILMODE *)ComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pThumbnailMode, sizeof(EXYNOS_OMX_VIDEO_THUMBNAILMODE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pVideoDec->bThumbnailMode = pThumbnailMode->bEnable;
+        if (pVideoDec->bThumbnailMode == OMX_TRUE) {
+            EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+            pExynosOutputPort->portDefinition.nBufferCountMin    = 1;
+            pExynosOutputPort->portDefinition.nBufferCountActual = 1;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexExynosParamCorruptedHeader:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_CORRUPTEDHEADER  *pCorruptedHeader   = (EXYNOS_OMX_VIDEO_PARAM_CORRUPTEDHEADER *)ComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pCorruptedHeader, sizeof(EXYNOS_OMX_VIDEO_PARAM_CORRUPTEDHEADER));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pVideoDec->bDiscardCSDError = pCorruptedHeader->bDiscardEvent;
+        ret = OMX_ErrorNone;
+    }
+        break;
+    default:
+    {
+        ret = Exynos_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure);
+    }
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexVendorGetBufferFD:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO *pBufferInfo = (EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pBufferInfo, sizeof(EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pBufferInfo->fd = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pBufferInfo->pVirAddr);
+    }
+        break;
+    case OMX_IndexExynosConfigPTSMode: /* MSRND */
+    {
+        *((OMX_BOOL *)pComponentConfigStructure) = (pVideoDec->bDTSMode == OMX_TRUE)? OMX_FALSE:OMX_TRUE;
+    }
+        break;
+    case OMX_IndexConfigBlackBarCrop:
+    {
+        OMX_CONFIG_RECTTYPE *pBlackBarCropRect = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pBlackBarCropRect, sizeof(OMX_CONFIG_RECTTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pBlackBarCropRect->nPortIndex != OUTPUT_PORT_INDEX) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] This config is vaild at Output port only", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Memcpy(pBlackBarCropRect, &pVideoDec->blackBarCropRect, sizeof(OMX_CONFIG_RECTTYPE));
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexConfigVideoColorAspects:
+    {
+        ret = Exynos_OSAL_GetConfig(hComponent, nIndex, pComponentConfigStructure);
+    }
+        break;
+    case OMX_IndexConfigAndroidVendorExtension:
+    {
+        ret = Exynos_OSAL_GetVendorExt(hComponent, pComponentConfigStructure);
+    }
+        break;
+#endif
+    default:
+        ret = Exynos_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigOperatingRate:  /* since M version */
+    {
+        OMX_PARAM_U32TYPE *pConfigRate = (OMX_PARAM_U32TYPE *)pComponentConfigStructure;
+        OMX_U32            xFramerate  = 0;
+
+        ret = Exynos_OMX_Check_SizeVersion(pConfigRate, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        xFramerate = pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.xFramerate;
+        if ((xFramerate >> 16) == 0) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] : xFramerate is zero. can't calculate QosRatio",
+                                                    pExynosComponent, __FUNCTION__);
+            pVideoDec->nQosRatio = 100;
+        } else {
+            pVideoDec->nQosRatio = (OMX_U32)((pConfigRate->nU32 / (double)xFramerate) * 100);
+        }
+
+        pVideoDec->bQosChanged = OMX_TRUE;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] operating rate(%.1lf) / frame rate(%.1lf) / ratio(%d)", pExynosComponent, __FUNCTION__,
+                                                pConfigRate->nU32 / (double)65536, xFramerate / (double)65536, pVideoDec->nQosRatio);
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexExynosConfigPTSMode: /* MSRND */
+    {
+        pVideoDec->bDTSMode = ((*((OMX_BOOL *)pComponentConfigStructure)) == OMX_TRUE)? OMX_FALSE:OMX_TRUE;
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexConfigSearchBlackBar:
+    {
+        OMX_CONFIG_BOOLEANTYPE *pConfigSearchBlackBar = (OMX_CONFIG_BOOLEANTYPE *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pConfigSearchBlackBar, sizeof(OMX_CONFIG_BOOLEANTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pVideoDec->bSearchBlackBar        = pConfigSearchBlackBar->bEnabled;
+        pVideoDec->bSearchBlackBarChanged = OMX_TRUE;
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexConfigVideoColorAspects:
+    {
+        ret = Exynos_OSAL_SetConfig(hComponent, nIndex, pComponentConfigStructure);
+    }
+        break;
+    case OMX_IndexConfigAndroidVendorExtension:
+    {
+        ret = Exynos_OSAL_SetVendorExt(hComponent, pComponentConfigStructure);
+    }
+        break;
+#endif
+    default:
+        ret = Exynos_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetExtensionIndex(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE *pIndexType)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] pOMXComponent->pComponentPrivate is NULL", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_NEED_CONTIG_MEMORY) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorNeedContigMemory;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_GET_BUFFER_FD) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorGetBufferFD;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_SET_DTS_MODE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorSetDTSMode;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamEnableThumbnailMode;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_BLACK_BAR_CROP_INFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigBlackBarCrop;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_SEARCH_BLACK_BAR) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigSearchBlackBar;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_GET_ANB) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamGetAndroidNativeBuffer;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_ANB) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamEnableAndroidBuffers;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ALLOCATE_NATIVE_HANDLE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamAllocateNativeHandle;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_DESCRIBE_COLOR_FORMAT) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamDescribeColorFormat;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_COLOR_ASPECTS_INFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigVideoColorAspects;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+#endif
+
+    // Porting exynos 9110, code from SM-R765(7270)
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamStoreMetaDataBuffer;
+        goto EXIT;
+    }
+
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) {
+        if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_CONFIG_PTS_MODE) == 0) {
+            *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosConfigPTSMode;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_CORRUPTEDHEADER) == 0) {
+            *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamCorruptedHeader;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Shared_BufferToData(
+    EXYNOS_OMX_BASEPORT     *pExynosPort,
+    EXYNOS_OMX_DATABUFFER   *pUseBuffer,
+    EXYNOS_OMX_DATA         *pData)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((pExynosPort == NULL) ||
+        (pUseBuffer == NULL) ||
+        (pData == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if ((pUseBuffer->bufferHeader == NULL) ||
+        (pUseBuffer->bufferHeader->pBuffer == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pExynosPort->exceptionFlag != GENERAL_STATE) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if (pExynosPort->eMetaDataType == METADATA_TYPE_DISABLED) {
+        pData->buffer.addr[0] = pUseBuffer->bufferHeader->pBuffer;
+    } else {
+        /* metadata type */
+        EXYNOS_OMX_MULTIPLANE_BUFFER bufferInfo;
+
+        if (pExynosPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK) {
+            EXYNOS_OMX_LOCK_RANGE range;
+            OMX_U32 stride;
+
+            range.nWidth        = pExynosPort->portDefinition.format.video.nFrameWidth;
+            range.nHeight       = pExynosPort->portDefinition.format.video.nFrameHeight;
+            range.eColorFormat  = pExynosPort->portDefinition.format.video.eColorFormat;
+            stride              = range.nWidth;
+
+            ret = Exynos_OSAL_LockMetaData(pUseBuffer->bufferHeader->pBuffer,
+                                           range,
+                                           &stride, &bufferInfo,
+                                           pExynosPort->eMetaDataType);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s]: Failed to Exynos_OSAL_LockMetaData (err:0x%x)",
+                                    __FUNCTION__, ret);
+                goto EXIT;
+            }
+        } else {
+            ret = Exynos_OSAL_GetInfoFromMetaData(pUseBuffer->bufferHeader->pBuffer,
+                                                    &bufferInfo, pExynosPort->eMetaDataType);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s]: Failed to Exynos_OSAL_GetInfoFromMetaData (err:0x%x)",
+                                    __FUNCTION__, ret);
+                goto EXIT;
+            }
+        }
+
+        pData->buffer.addr[0] = bufferInfo.addr[0];
+        pData->buffer.addr[1] = bufferInfo.addr[1];
+        pData->buffer.addr[2] = bufferInfo.addr[2];
+
+        pData->buffer.fd[0] = bufferInfo.fd[0];
+        pData->buffer.fd[1] = bufferInfo.fd[1];
+        pData->buffer.fd[2] = bufferInfo.fd[2];
+    }
+
+    pData->allocSize     = pUseBuffer->allocSize;
+    pData->dataLen       = pUseBuffer->dataLen;
+    pData->usedDataLen   = pUseBuffer->usedDataLen;
+    pData->remainDataLen = pUseBuffer->remainDataLen;
+    pData->timeStamp     = pUseBuffer->timeStamp;
+    pData->nFlags        = pUseBuffer->nFlags;
+    pData->pPrivate      = pUseBuffer->pPrivate;
+    pData->bufferHeader  = pUseBuffer->bufferHeader;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Shared_DataToBuffer(
+    EXYNOS_OMX_BASEPORT     *pExynosPort,
+    EXYNOS_OMX_DATABUFFER   *pUseBuffer,
+    EXYNOS_OMX_DATA         *pData)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((pExynosPort == NULL) ||
+        (pUseBuffer == NULL) ||
+        (pData == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if ((pData->bufferHeader == NULL) ||
+        (pData->bufferHeader->pBuffer == NULL)) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    pUseBuffer->bufferHeader          = pData->bufferHeader;
+    pUseBuffer->allocSize             = pData->allocSize;
+    pUseBuffer->dataLen               = pData->dataLen;
+    pUseBuffer->usedDataLen           = pData->usedDataLen;
+    pUseBuffer->remainDataLen         = pData->remainDataLen;
+    pUseBuffer->timeStamp             = pData->timeStamp;
+    pUseBuffer->nFlags                = pData->nFlags;
+    pUseBuffer->pPrivate              = pData->pPrivate;
+
+    if (pExynosPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK)
+        Exynos_OSAL_UnlockMetaData(pUseBuffer->bufferHeader->pBuffer, pExynosPort->eMetaDataType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/dec/Exynos_OMX_VdecControl.h b/openmax/component/video/dec/Exynos_OMX_VdecControl.h
new file mode 100755 (executable)
index 0000000..e5f22a3
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_VdecControl.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.5.0
+ * @history
+ *   2012.02.20 : Create
+ *   2017.08.03 : Change event handling
+ */
+
+#ifndef EXYNOS_OMX_VIDEO_DECODECONTROL
+#define EXYNOS_OMX_VIDEO_DECODECONTROL
+
+#include "OMX_Component.h"
+#include "Exynos_OMX_Def.h"
+#include "Exynos_OSAL_Queue.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Basecomponent.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_ERRORTYPE Exynos_OMX_UseBuffer(
+    OMX_IN OMX_HANDLETYPE            hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32                   nPortIndex,
+    OMX_IN OMX_PTR                   pAppPrivate,
+    OMX_IN OMX_U32                   nSizeBytes,
+    OMX_IN OMX_U8                   *pBuffer);
+OMX_ERRORTYPE Exynos_OMX_AllocateBuffer(
+    OMX_IN OMX_HANDLETYPE            hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
+    OMX_IN OMX_U32                   nPortIndex,
+    OMX_IN OMX_PTR                   pAppPrivate,
+    OMX_IN OMX_U32                   nSizeBytes);
+OMX_ERRORTYPE Exynos_OMX_FreeBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_U32        nPortIndex,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr);
+
+#ifdef TUNNELING_SUPPORT
+OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer(
+    EXYNOS_OMX_BASEPORT *pOMXBasePort,
+    OMX_U32           nPortIndex);
+OMX_ERRORTYPE Exynos_OMX_FreeTunnelBuffer(
+    EXYNOS_OMX_BASEPORT *pOMXBasePort,
+    OMX_U32           nPortIndex);
+OMX_ERRORTYPE Exynos_OMX_ComponentTunnelRequest(
+    OMX_IN  OMX_HANDLETYPE hComp,
+    OMX_IN OMX_U32         nPort,
+    OMX_IN OMX_HANDLETYPE  hTunneledComp,
+    OMX_IN OMX_U32         nTunneledPort,
+    OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup);
+#endif
+
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     ComponentParameterStructure);
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        ComponentParameterStructure);
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex,
+    OMX_PTR pComponentConfigStructure);
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex,
+    OMX_PTR pComponentConfigStructure);
+OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetExtensionIndex(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE *pIndexType);
+
+OMX_ERRORTYPE Exynos_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *pDataBuffer);
+OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *pDataBuffer);
+OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent);
+
+OMX_BUFFERHEADERTYPE *Exynos_OutputBufferGetQueue_Direct(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+OMX_ERRORTYPE Exynos_InputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+OMX_ERRORTYPE Exynos_OutputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+
+OMX_ERRORTYPE Exynos_CodecBufferEnQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex, OMX_PTR data);
+OMX_ERRORTYPE Exynos_CodecBufferDeQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex, OMX_PTR *data);
+OMX_ERRORTYPE Exynos_CodecBufferReset(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex);
+
+OMX_ERRORTYPE Exynos_Shared_BufferToData(EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData);
+OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/openmax/component/video/dec/Makefile.am b/openmax/component/video/dec/Makefile.am
new file mode 100755 (executable)
index 0000000..fb79a34
--- /dev/null
@@ -0,0 +1,19 @@
+SUBDIRS = . h264 hevc mpeg4 mpeg2 vc1 vp8
+
+lib_LTLIBRARIES = libExynosOMX_Vdec.la
+
+libExynosOMX_Vdec_la_SOURCES = Exynos_OMX_Vdec.c \
+                               Exynos_OMX_VdecControl.c
+
+libExynosOMX_Vdec_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                              $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la
+
+libExynosOMX_Vdec_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                              -I$(top_srcdir)/openmax/include/exynos \
+                              -I$(top_srcdir)/openmax/osal \
+                              -I$(top_srcdir)/openmax/core \
+                              -I$(top_srcdir)/openmax/component/common \
+                              -I$(top_srcdir)/exynos/libvideocodec/include
+
+libExynosOMX_Vdec_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
+libExynosOMX_Vdec_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable
diff --git a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.c
new file mode 100755 (executable)
index 0000000..d1f49a2
--- /dev/null
@@ -0,0 +1,3556 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_H264dec.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Vdec.h"
+#include "Exynos_OMX_VdecControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "Exynos_OMX_H264dec.h"
+#include "ExynosVideoApi.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+#ifdef USE_ANDROID
+#include "VendorVideoAPI.h"
+#endif
+
+#ifdef USE_SKYPE_HD
+#include "Exynos_OSAL_SkypeHD.h"
+#endif
+
+/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
+/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_H264_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec       = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pH264Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Dec->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileBaseline;
+    pH264Dec->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileMain;
+    pH264Dec->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileHigh;
+    pH264Dec->hMFCH264Handle.profiles[nProfileCnt++] = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedBaseline;
+    pH264Dec->hMFCH264Handle.profiles[nProfileCnt++] = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedHigh;
+    pH264Dec->hMFCH264Handle.nProfileCnt = nProfileCnt;
+
+    switch (pH264Dec->hMFCH264Handle.videoInstInfo.HwVersion) {
+    case MFC_1220:
+    case MFC_120:
+    case MFC_110:
+    case MFC_100:
+    case MFC_101:
+        pH264Dec->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel52;
+        break;
+    case MFC_80:
+    case MFC_90:
+    case MFC_1010:
+    case MFC_1120:
+        pH264Dec->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel51;
+        break;
+    case MFC_61:
+    case MFC_65:
+    case MFC_72:
+    case MFC_723:
+    case MFC_77:
+    case MFC_1011:
+        pH264Dec->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel42;
+        break;
+    case MFC_51:
+    case MFC_78:
+    case MFC_78D:
+    case MFC_92:
+    case MFC_1020:
+    case MFC_1021:
+    default:
+        pH264Dec->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel4;
+        break;
+    }
+
+EXIT:
+
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec       = NULL;
+
+    int nLevelCnt = 0;
+    OMX_U32 nMaxIndex = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pH264Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pH264Dec->hMFCH264Handle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pH264Dec->hMFCH264Handle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pH264Dec->hMFCH264Handle.maxLevel;
+#else
+    while ((pH264Dec->hMFCH264Handle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+
+    if ((pH264Dec->hMFCH264Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                        pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pH264Dec->hMFCH264Handle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pH264Dec->hMFCH264Handle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] supported profile(%x), level(%x)",
+                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec  = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec   = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pH264Dec == NULL)
+        goto EXIT;
+
+    while ((pH264Dec->hMFCH264Handle.maxLevel >> nLevelCnt++) > 0);
+
+    if ((pH264Dec->hMFCH264Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pH264Dec->hMFCH264Handle.nProfileCnt; i++) {
+        if (pH264Dec->hMFCH264Handle.profiles[i] == pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    while (nLevelCnt >= 0) {
+        if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+            bLevelSupport = OMX_TRUE;
+            break;
+        }
+
+        nLevelCnt--;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    FunctionOut();
+
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
+{
+    OMX_ERRORTYPE       ret          = OMX_ErrorNone;
+    ExynosVideoBuffer  *pCodecBuffer = NULL;
+
+    if (codecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
+
+    if (addr != NULL) {
+        addr[0] = pCodecBuffer->planes[0].addr;
+        addr[1] = pCodecBuffer->planes[1].addr;
+        addr[2] = pCodecBuffer->planes[2].addr;
+    }
+
+    if (size != NULL) {
+        size[0] = pCodecBuffer->planes[0].allocSize;
+        size[1] = pCodecBuffer->planes[1].allocSize;
+        size[2] = pCodecBuffer->planes[2].allocSize;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_BOOL Check_H264_StartCode(
+    OMX_U8 *pInputStream,
+    OMX_U32 streamSize)
+{
+    OMX_BOOL ret = OMX_FALSE;
+
+    FunctionIn();
+
+    if (streamSize < 4) {
+        ret = OMX_FALSE;
+        goto EXIT;
+    }
+
+    if ((pInputStream[0] == 0x00) &&
+        (pInputStream[1] == 0x00) &&
+        (pInputStream[2] == 0x00) &&
+        (pInputStream[3] != 0x00) &&
+        ((pInputStream[4] & 0x1F) != 0xB) &&  // F/W constraint : in case of EOS data, can't return a buffer
+        ((pInputStream[3] >> 3) == 0x00)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] NaluType : %d, 0x%x, 0x%x, 0x%x", __FUNCTION__,
+                                            (pInputStream[4] & 0x1F), pInputStream[3], pInputStream[4], pInputStream[5]);
+        ret = OMX_TRUE;
+    } else if ((pInputStream[0] == 0x00) &&
+               (pInputStream[1] == 0x00) &&
+               (pInputStream[2] != 0x00) &&
+               ((pInputStream[3] & 0x1F) != 0xB) &&  // F/W constraint : in case of EOS data, can't return a buffer
+               ((pInputStream[2] >> 3) == 0x00)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] NaluType : %d, 0x%x, 0x%x, 0x%x", __FUNCTION__,
+                                            (pInputStream[3] & 0x1F), pInputStream[2], pInputStream[3], pInputStream[4]);
+        ret = OMX_TRUE;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec       = NULL;
+    EXYNOS_OMX_BASEPORT             *pOutputPort    = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pH264Dec == NULL)
+        goto EXIT;
+    pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pOutputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pH264Dec->hMFCH264Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pH264Dec->hMFCH264Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecOpen(EXYNOS_H264DEC_HANDLE *pH264Dec, ExynosVideoInstInfo *pVideoInstInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pH264Dec == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pDecOps    = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
+    pInbufOps  = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+    pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+
+    if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pH264Dec->hMFCH264Handle.pDecOps    = pDecOps;
+    pH264Dec->hMFCH264Handle.pInbufOps  = pInbufOps;
+    pH264Dec->hMFCH264Handle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pDecOps->nSize    = sizeof(ExynosVideoDecOps);
+    pInbufOps->nSize  = sizeof(ExynosVideoDecBufferOps);
+    pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
+
+    if (Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for decoder ops */
+    if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
+        (pDecOps->Get_ActualBufferCount == NULL) ||
+#ifdef USE_S3D_SUPPORT
+        (pDecOps->Enable_SEIParsing == NULL) || (pDecOps->Get_FramePackingInfo == NULL) ||
+#endif
+        (pDecOps->Set_FrameTag == NULL) || (pDecOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pH264Dec->hMFCH264Handle.hMFCHandle = pH264Dec->hMFCH264Handle.pDecOps->Init(pVideoInstInfo);
+    if (pH264Dec->hMFCH264Handle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+#ifdef USE_S3D_SUPPORT
+    /* S3D: Enable SEI parsing to check Frame Packing */
+    if (pDecOps->Enable_SEIParsing(pH264Dec->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Enable SEI Parsing", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+#endif
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pDecOps != NULL) {
+            Exynos_OSAL_Free(pDecOps);
+            pH264Dec->hMFCH264Handle.pDecOps = NULL;
+        }
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pH264Dec->hMFCH264Handle.pInbufOps = NULL;
+        }
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pH264Dec->hMFCH264Handle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecClose(EXYNOS_H264DEC_HANDLE *pH264Dec)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pH264Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
+    pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
+    pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
+    pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pDecOps->Finalize(hMFCHandle);
+        pH264Dec->hMFCH264Handle.hMFCHandle = NULL;
+        pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
+        pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pH264Dec->hMFCH264Handle.pOutbufOps = NULL;
+    }
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pH264Dec->hMFCH264Handle.pInbufOps = NULL;
+    }
+    if (pDecOps != NULL) {
+        Exynos_OSAL_Free(pDecOps);
+        pH264Dec->hMFCH264Handle.pDecOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pH264Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
+    pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
+    pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_TRUE)) {
+        pInbufOps->Run(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE)) {
+        pOutbufOps->Run(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pH264Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
+    pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
+    pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) {
+        pInbufOps->Stop(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) {
+        EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+        pOutbufOps->Stop(hMFCHandle);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE)
+            pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pH264Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pH264Dec->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pH264Dec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pH264Dec->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pH264Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pH264Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pH264Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecReconfigAllBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = &pExynosComponent->pExynosPort[nPortIndex];
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pH264Dec->hMFCH264Handle.hMFCHandle;
+    ExynosVideoDecBufferOps         *pBufferOps         = NULL;
+
+    FunctionIn();
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pH264Dec->bSourceStart == OMX_TRUE)) {
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pH264Dec->bDestinationStart == OMX_TRUE)) {
+        pBufferOps  = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+        if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+            /**********************************/
+            /* Codec Buffer Free & Unregister */
+            /**********************************/
+            Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+            Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
+
+            /******************************************************/
+            /* V4L2 Destnation Setup for DPB Buffer Number Change */
+            /******************************************************/
+            ret = H264CodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to H264CodecDstSetup(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+        } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+            /***************************/
+            /* Codec Buffer Unregister */
+            /***************************/
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
+        }
+    } else {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec         = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle       = pH264Dec->hMFCH264Handle.hMFCHandle;
+
+    int i;
+
+    ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecInputBuffer[i]->fd[0], pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < pH264Dec->hMFCH264Handle.maxDPBNum; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecOutputBuffer[i]->fd[0], pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+        }
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+#ifdef USE_S3D_SUPPORT
+OMX_BOOL H264CodecCheckFramePacking(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+    ExynosVideoDecOps             *pDecOps           = pH264Dec->hMFCH264Handle.pDecOps;
+    ExynosVideoFramePacking        framePacking;
+    void                          *hMFCHandle        = pH264Dec->hMFCH264Handle.hMFCHandle;
+    OMX_BOOL                       ret               = OMX_FALSE;
+
+    FunctionIn();
+
+    /* Get Frame packing information*/
+    if (pDecOps->Get_FramePackingInfo(pH264Dec->hMFCH264Handle.hMFCHandle, &framePacking) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Get Frame Packing Information", pExynosComponent, __FUNCTION__);
+        ret = OMX_FALSE;
+        goto EXIT;
+    }
+
+    if (framePacking.available) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] arrangement ID: 0x%08x",
+                                            pExynosComponent, __FUNCTION__, framePacking.arrangement_id);
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] arrangement_type: %d",
+                                            pExynosComponent, __FUNCTION__, framePacking.arrangement_type);
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] content_interpretation_type: %d",
+                                            pExynosComponent, __FUNCTION__, framePacking.content_interpretation_type);
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] current_frame_is_frame0_flag: %d",
+                                            pExynosComponent, __FUNCTION__, framePacking.current_frame_is_frame0_flag);
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] spatial_flipping_flag: %d",
+                                            pExynosComponent, __FUNCTION__, framePacking.spatial_flipping_flag);
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] fr0X:%d fr0Y:%d fr0X:%d fr0Y:%d",
+                                            pExynosComponent, __FUNCTION__, framePacking.frame0_grid_pos_x,
+                                            framePacking.frame0_grid_pos_y, framePacking.frame1_grid_pos_x, framePacking.frame1_grid_pos_y);
+
+        pH264Dec->hMFCH264Handle.S3DFPArgmtType = (EXYNOS_OMX_FPARGMT_TYPE) framePacking.arrangement_type;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventS3DInformation)",
+                                                pExynosComponent, __FUNCTION__);
+        /** Send Port Settings changed call back - output color format change */
+        (*(pExynosComponent->pCallbacks->EventHandler))
+              (pOMXComponent,
+               pExynosComponent->callbackData,
+               (OMX_EVENTTYPE)OMX_EventS3DInformation,              /* The command was completed */
+               OMX_TRUE,                                            /* S3D is enabled */
+               (OMX_S32)pH264Dec->hMFCH264Handle.S3DFPArgmtType,    /* S3D FPArgmtType */
+               NULL);
+
+        Exynos_OSAL_SleepMillisec(0);
+    } else {
+        pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_NONE;
+    }
+
+    ret = OMX_TRUE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+#endif
+
+#ifdef USE_ANDROID
+void H264CodecUpdateHdrInfo(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    ExynosVideoMeta     *pMeta)
+{
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort       = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pInputPort        = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    void                          *hMFCHandle        = pH264Dec->hMFCH264Handle.hMFCHandle;
+
+    ExynosVideoDecOps  *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
+    ExynosVideoHdrInfo  sHdrInfo;
+
+    if (pDecOps->Get_HDRInfo(hMFCHandle, &sHdrInfo) == VIDEO_ERROR_NONE) {
+        /* update bitstream's info to input port */
+        EXYNOS_OMX_VIDEO_HDRSTATICINFO   *pHDRStaticInfo = &(pOutputPort->HDRStaticInfo);
+        EXYNOS_OMX_VIDEO_COLORASPECTS    *pColorAspects  = &(pInputPort->ColorAspects);
+
+        /* save info to vendor path for renderer */
+        ExynosType1         *pMetaHDR = &(pMeta->data.dec.sHdrStaticInfo.sType1);
+        ExynosColorAspects  *pMetaCA  = &(pMeta->data.dec.sColorAspects);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eType(0x%x) is changed", pExynosComponent, __FUNCTION__, sHdrInfo.eChangedType);
+
+        /* color aspects */
+        if (sHdrInfo.eValidType & (HDR_INFO_COLOR_ASPECTS | HDR_INFO_RANGE)) {
+            /* HDR_INFO_COLOR_ASPECTS (8) */
+            pMetaCA->mMatrixCoeffs = pColorAspects->nCoeffType      = sHdrInfo.sColorAspects.eCoeffType;
+            pMetaCA->mPrimaries    = pColorAspects->nPrimaryType    = sHdrInfo.sColorAspects.ePrimariesType;
+            pMetaCA->mTransfer     = pColorAspects->nTransferType   = sHdrInfo.sColorAspects.eTransferType;
+
+            /* HDR_INFO_RANGE (16) */
+            pMetaCA->mRange        = pColorAspects->nRangeType      = sHdrInfo.sColorAspects.eRangeType;
+
+            //pMeta->eType |= VIDEO_INFO_TYPE_COLOR_ASPECTS;
+        }
+
+        /* hdr static info */
+        if (sHdrInfo.eValidType & (HDR_INFO_LIGHT | HDR_INFO_LUMINANCE)) {
+            /* HDR_INFO_LIGHT (1) */
+            pMetaHDR->mMaxFrameAverageLightLevel = pHDRStaticInfo->nMaxPicAverageLight  = sHdrInfo.sHdrStatic.max_pic_average_light;
+            pMetaHDR->mMaxContentLightLevel      = pHDRStaticInfo->nMaxContentLight     = sHdrInfo.sHdrStatic.max_content_light;
+
+            /* HDR_INFO_LUMINANCE (2) */
+            pMetaHDR->mMaxDisplayLuminance       = pHDRStaticInfo->nMaxDisplayLuminance = sHdrInfo.sHdrStatic.max_display_luminance;
+            pMetaHDR->mMinDisplayLuminance       = pHDRStaticInfo->nMinDisplayLuminance = sHdrInfo.sHdrStatic.min_display_luminance;
+
+            pMetaHDR->mR.x = pHDRStaticInfo->red.x  = sHdrInfo.sHdrStatic.red.x;
+            pMetaHDR->mR.y = pHDRStaticInfo->red.y  = sHdrInfo.sHdrStatic.red.y;
+
+            pMetaHDR->mG.x = pHDRStaticInfo->green.x = sHdrInfo.sHdrStatic.green.x;
+            pMetaHDR->mG.y = pHDRStaticInfo->green.y = sHdrInfo.sHdrStatic.green.y;
+
+            pMetaHDR->mB.x = pHDRStaticInfo->blue.x  = sHdrInfo.sHdrStatic.blue.x;
+            pMetaHDR->mB.y = pHDRStaticInfo->blue.y  = sHdrInfo.sHdrStatic.blue.y;
+
+            pMetaHDR->mW.x = pHDRStaticInfo->white.x = sHdrInfo.sHdrStatic.white.x;
+            pMetaHDR->mW.y = pHDRStaticInfo->white.y = sHdrInfo.sHdrStatic.white.y;
+
+            pMeta->eType |= VIDEO_INFO_TYPE_HDR_STATIC;
+        }
+
+        /* if both have changed, should send an event once */
+        if (sHdrInfo.eChangedType & (HDR_INFO_COLOR_ASPECTS | HDR_INFO_RANGE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_IndexConfigVideoColorAspects)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 OMX_IndexConfigVideoColorAspects,
+                 NULL);
+        }
+#if 0  /* OMX_IndexConfigVideoHdrStaticInfo is not supported yet */
+          else if (sHdrInfo.eChangedType & (HDR_INFO_LIGHT | HDR_INFO_LUMINANCE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_IndexConfigVideoHdrStaticInfo)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 OMX_IndexConfigVideoHdrStaticInfo,
+                 NULL);
+        }
+#endif // Porting exynos 9110, Error fix
+    }
+
+EXIT:
+    return;
+}
+#endif // USE_ANDROID
+
+OMX_ERRORTYPE H264CodecUpdateBlackBarCrop(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec             = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pH264Dec->hMFCH264Handle.hMFCHandle;
+    OMX_CONFIG_RECTTYPE           *pBlackBarCropRect    = &pVideoDec->blackBarCropRect;
+
+    ExynosVideoDecBufferOps  *pOutbufOps  = pH264Dec->hMFCH264Handle.pOutbufOps;
+    ExynosVideoRect           CropRect;
+
+    FunctionIn();
+
+    Exynos_OSAL_Memset(&CropRect, 0, sizeof(ExynosVideoRect));
+    if (pOutbufOps->Get_BlackBarCrop(hMFCHandle, &CropRect) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get crop info", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pBlackBarCropRect->nLeft   = CropRect.nLeft;
+    pBlackBarCropRect->nTop    = CropRect.nTop;
+    pBlackBarCropRect->nWidth  = CropRect.nWidth;
+    pBlackBarCropRect->nHeight = CropRect.nHeight;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Black Bar Info: LEFT(%d) TOP(%d) WIDTH(%d) HEIGHT(%d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pBlackBarCropRect->nLeft, pBlackBarCropRect->nTop,
+                                        pBlackBarCropRect->nWidth, pBlackBarCropRect->nHeight);
+
+    /** Send Port Settings changed call back **/
+    (*(pExynosComponent->pCallbacks->EventHandler))
+        (pOMXComponent,
+         pExynosComponent->callbackData,
+         OMX_EventPortSettingsChanged, /* The command was completed */
+         OMX_DirOutput, /* This is the port index */
+         (OMX_INDEXTYPE)OMX_IndexConfigBlackBarCrop,
+         NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecCheckResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pH264Dec->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_EXCEPTION_STATE     eOutputExcepState  = pOutputPort->exceptionFlag;
+
+    ExynosVideoDecOps             *pDecOps            = pH264Dec->hMFCH264Handle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pH264Dec->hMFCH264Handle.pOutbufOps;
+    ExynosVideoGeometry            codecOutbufConf;
+
+    OMX_CONFIG_RECTTYPE          *pCropRectangle        = &(pOutputPort->cropRectangle);
+    OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition  = &(pInputPort->portDefinition);
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = &(pOutputPort->portDefinition);
+
+    int maxDPBNum = 0;
+
+    FunctionIn();
+
+    /* get geometry */
+    Exynos_OSAL_Memset(&codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry");
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        maxDPBNum += EXTRA_DPB_NUM;
+
+    pCropRectangle->nTop     = codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = codecOutbufConf.cropRect.nHeight;
+
+    /* resolution is changed */
+    if ((codecOutbufConf.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
+        (codecOutbufConf.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight) ||
+        (codecOutbufConf.nStride != pH264Dec->hMFCH264Handle.codecOutbufConf.nStride) ||
+#if 0  // TODO: check posibility
+        (codecOutbufConf.eColorFormat != pH264Dec->hMFCH264Handle.codecOutbufConf.eColorFormat) ||
+        (codecOutbufConf.eFilledDataType != pH264Dec->hMFCH264Handle.codecOutbufConf.eFilledDataType) ||
+#endif
+        (maxDPBNum != pH264Dec->hMFCH264Handle.maxDPBNum)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
+                            pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight,
+                            codecOutbufConf.nFrameWidth,
+                            codecOutbufConf.nFrameHeight);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] DPB(%d), FORMAT(0x%x), TYPE(0x%x) -> DPB(%d), FORMAT(0x%x), TYPE(0x%x)",
+                            pExynosComponent, __FUNCTION__,
+                            pH264Dec->hMFCH264Handle.maxDPBNum,
+                            pH264Dec->hMFCH264Handle.codecOutbufConf.eColorFormat,
+                            pH264Dec->hMFCH264Handle.codecOutbufConf.eFilledDataType,
+                            maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType);
+
+        pInputPortDefinition->format.video.nFrameWidth     = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight    = codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride         = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight    = codecOutbufConf.nFrameHeight;
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            pOutputPortDefinition->nBufferCountActual  = maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin     = maxDPBNum;
+        }
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        if (eOutputExcepState == GENERAL_STATE) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* crop info of contents is changed */
+    if ((codecOutbufConf.cropRect.nTop != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nTop) ||
+        (codecOutbufConf.cropRect.nLeft != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nLeft) ||
+        (codecOutbufConf.cropRect.nWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth) ||
+        (codecOutbufConf.cropRect.nHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth,
+                            pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight,
+                            codecOutbufConf.cropRect.nWidth,
+                            codecOutbufConf.cropRect.nHeight);
+
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    Exynos_OSAL_Memcpy(&pH264Dec->hMFCH264Handle.codecOutbufConf, &codecOutbufConf, sizeof(codecOutbufConf));
+    pH264Dec->hMFCH264Handle.maxDPBNum = maxDPBNum;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecUpdateResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pH264Dec->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    ExynosVideoDecOps             *pDecOps            = pH264Dec->hMFCH264Handle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+    OMX_CONFIG_RECTTYPE          *pCropRectangle        = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition  = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = NULL;
+
+    FunctionIn();
+
+    /* get geometry for output */
+    Exynos_OSAL_Memset(&pH264Dec->hMFCH264Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &pH264Dec->hMFCH264Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get geometry about output", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedHeader;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    pH264Dec->hMFCH264Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        pH264Dec->hMFCH264Handle.maxDPBNum += EXTRA_DPB_NUM;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] maxDPBNum: %d", pExynosComponent, __FUNCTION__, pH264Dec->hMFCH264Handle.maxDPBNum);
+
+    /* get interlace info */
+    if (pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE)
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] contents is interlaced type", pExynosComponent, __FUNCTION__);
+
+    pCropRectangle          = &(pOutputPort->cropRectangle);
+    pInputPortDefinition    = &(pInputPort->portDefinition);
+    pOutputPortDefinition   = &(pOutputPort->portDefinition);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] past info: width(%d) height(%d)",
+                                            pExynosComponent, __FUNCTION__,
+                                            pInputPortDefinition->format.video.nFrameWidth,
+                                            pInputPortDefinition->format.video.nFrameHeight);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] resolution info: width(%d / %d), height(%d / %d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
+                                        pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth,
+                                        pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight,
+                                        pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight);
+
+    pCropRectangle->nTop     = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth     = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight    = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride         = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight    = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
+#if 0
+            /* don't need to change */
+            pOutputPortDefinition->nBufferCountActual  = pOutputPort->portDefinition.nBufferCountActual;
+            pOutputPortDefinition->nBufferCountMin     = pOutputPort->portDefinition.nBufferCountMin;
+#endif
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight) ||
+            ((OMX_S32)pOutputPortDefinition->nBufferCountActual != pH264Dec->hMFCH264Handle.maxDPBNum)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth     = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight    = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride         = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight    = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
+
+            pOutputPortDefinition->nBufferCountActual  = pH264Dec->hMFCH264Handle.maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin     = pH264Dec->hMFCH264Handle.maxDPBNum;
+
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* contents has crop info */
+    if ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth) ||
+        (pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight)) {
+        pInputPortDefinition->format.video.nFrameWidth     = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight    = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride         = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight    = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged) with crop",
+                                                pExynosComponent, __FUNCTION__);
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pH264Dec->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+    OMX_COLOR_FORMATTYPE           eOutputFormat     = pExynosOutputPort->portDefinition.format.video.eColorFormat;
+
+    EXYNOS_OMX_VIDEO_HDRSTATICINFO  *pHDRStaticInfo  = &(pExynosOutputPort->HDRStaticInfo);
+    EXYNOS_OMX_VIDEO_COLORASPECTS   *pFWCA           = &(pExynosOutputPort->ColorAspects);
+    EXYNOS_OMX_VIDEO_COLORASPECTS   *pBSCA           = &(pExynosInputPort->ColorAspects);
+
+    ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+
+    OMX_U32  nInBufferCnt   = 0;
+    OMX_BOOL bSupportFormat = OMX_FALSE;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pH264Dec->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pH264Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pH264Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pVideoDec->bThumbnailMode == OMX_TRUE)
+        pDecOps->Set_IFrameDecoding(hMFCHandle);
+    else if ((IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) &&
+             (pH264Dec->hMFCH264Handle.nDisplayDelay <= MAX_H264_DISPLAYDELAY_VALIDNUM)) {
+        pDecOps->Set_DisplayDelay(hMFCHandle, (int)pH264Dec->hMFCH264Handle.nDisplayDelay);
+    }
+
+#ifdef USE_SKYPE_HD
+    if (pH264Dec->hMFCH264Handle.bLowLatency == OMX_TRUE)
+        pDecOps->Set_DisplayDelay(hMFCHandle, 0);
+#endif
+
+    if ((pDecOps->Enable_DTSMode != NULL) &&
+        (pVideoDec->bDTSMode == OMX_TRUE))
+        pDecOps->Enable_DTSMode(hMFCHandle);
+
+    /* input buffer info */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eCompressionFormat = VIDEO_CODING_AVC;
+    pInbufOps->Set_Shareable(hMFCHandle);
+
+    nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        /* OMX buffer is not used directly : CODEC buffer */
+        nAllocLen[0] = pSrcInputData->allocSize;
+    }
+
+    bufferConf.nSizeImage = nAllocLen[0];
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+    nInBufferCnt = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    /* should be done before prepare input buffer */
+    if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set output geometry */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+    bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] omx format(0x%x) is %s by h/w",
+                                            pExynosComponent, __FUNCTION__, eOutputFormat,
+                                            (bSupportFormat == OMX_TRUE)? "supported":"not supported");
+    if (bSupportFormat == OMX_TRUE) {  /* supported by H/W */
+        bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eOutputFormat, pExynosOutputPort->ePlaneType);
+        Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pExynosOutputPort->ePlaneType));
+    } else {
+        OMX_COLOR_FORMATTYPE eCheckFormat = OMX_SEC_COLOR_FormatNV12Tiled;
+        bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        if (bSupportFormat != OMX_TRUE) {
+            eCheckFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+            bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        }
+        if (bSupportFormat == OMX_TRUE) {  /* supported by CSC(NV12T/NV12 -> format) */
+            bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eCheckFormat, pExynosOutputPort->ePlaneType);
+            Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eCheckFormat, pExynosOutputPort->ePlaneType));
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not support this format (0x%x)", pExynosComponent, __FUNCTION__, eOutputFormat);
+            ret = OMX_ErrorNotImplemented;
+            pInbufOps->Cleanup_Buffer(hMFCHandle);
+            goto EXIT;
+        }
+    }
+
+    pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output video format is 0x%x",
+                                            pExynosComponent, __FUNCTION__, bufferConf.eColorFormat);
+
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    /* input buffer enqueue for header parsing */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+
+    if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pSrcInputData->buffer.addr,
+                            (unsigned long *)pSrcInputData->buffer.fd,
+                            nAllocLen,
+                            nDataLen,
+                            Exynos_GetPlaneFromPort(pExynosInputPort),
+                            pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enqueue input buffer for header parsing", pExynosComponent, __FUNCTION__);
+//        ret = OMX_ErrorInsufficientResources;
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
+
+    /* start header parsing */
+    if (H264CodecStart(pOMXComponent, INPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run input buffer for header parsing", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    ret = H264CodecUpdateResolution(pOMXComponent);
+    if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+        (pExynosComponent->codecType != HW_VIDEO_DEC_SECURE_CODEC) &&
+        (oneFrameSize >= 8)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...", pExynosComponent, __FUNCTION__,
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0])    , *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 1),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 2), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 3),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 4), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 5),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 6), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 7));
+    }
+
+    if (ret != OMX_ErrorNone) {
+        H264CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_SleepMillisec(0);
+    ret = (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] first frame will be re-pushed to input", pExynosComponent, __FUNCTION__);
+
+    H264CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec             = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pH264Dec->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort    = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nOutbufs, nPlaneCnt;
+
+    FunctionIn();
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++)
+        nAllocLen[i] = pH264Dec->hMFCH264Handle.codecOutbufConf.nAlignPlaneSize[i];
+
+    H264CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    /* for adaptive playback */
+    if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enable Dynamic DPB", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare output buffer */
+        if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        /* get dpb count */
+        nOutbufs = pH264Dec->hMFCH264Handle.maxDPBNum;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        /* Enqueue output buffer */
+        for (i = 0; i < nOutbufs; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+                            (unsigned long *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+                            pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+                            nDataLen,
+                            nPlaneCnt,
+                            NULL);
+        }
+
+        pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* get dpb count */
+        nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+        if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pExynosOutputPort->eMetaDataType == METADATA_TYPE_DISABLED) {
+            /*************/
+            /*    TBD    */
+            /*************/
+            /* data buffer : user buffer
+             * H/W can't accept user buffer directly
+             */
+            ret = OMX_ErrorNotImplemented;
+            goto EXIT;
+        }
+
+        pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
+    }
+
+    if (H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoAvc:
+    {
+        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcAVCComponent = &pH264Dec->AVCComponent[pDstAVCComponent->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstAVCComponent) + nOffset,
+                           ((char *)pSrcAVCComponent) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_AVCTYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCTYPE          *pSrcAVCComponent = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcAVCComponent = &pH264Dec->AVCComponent[pDstProfileLevel->nPortIndex];
+
+        pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile;
+        pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX];
+        pDstErrorCorrectionType->bEnableHEC              = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync           = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing   = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC             = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexExynosParamDisplayDelay:  /* MSRND */
+    {
+        OMX_PARAM_U32TYPE       *pDisplayDelay  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+        EXYNOS_H264DEC_HANDLE   *pH264Dec       = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDisplayDelay, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+
+        if (pDisplayDelay->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+        pDisplayDelay->nU32 = pH264Dec->hMFCH264Handle.nDisplayDelay;
+    }
+        break;
+    case OMX_IndexExynosParamReorderMode:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *pReorderParam = (EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pReorderParam, sizeof(EXYNOS_OMX_VIDEO_PARAM_REORDERMODE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pReorderParam->bReorderMode = pVideoDec->bReorderMode;
+    }
+        break;
+    default:
+#ifdef USE_SKYPE_HD
+        ret = Exynos_H264Dec_GetParameter_SkypeHD(hComponent, nParamIndex, pComponentParameterStructure);
+        if (ret != OMX_ErrorNone)
+#endif
+            ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Dec  = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoAvc:
+    {
+        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
+        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstAVCComponent = &pH264Dec->AVCComponent[pSrcAVCComponent->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstAVCComponent) + nOffset,
+                           ((char *)pSrcAVCComponent) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_AVCTYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE)) {
+            pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCTYPE          *pDstAVCComponent = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstAVCComponent = &pH264Dec->AVCComponent[pSrcProfileLevel->nPortIndex];
+
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile;
+        pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX];
+        pDstErrorCorrectionType->bEnableHEC              = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync           = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing   = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC             = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexExynosParamDisplayDelay:  /* MSRND */
+    {
+        OMX_PARAM_U32TYPE       *pDisplayDelay  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+        EXYNOS_H264DEC_HANDLE   *pH264Dec       = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDisplayDelay, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+
+        if (pDisplayDelay->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+        if (pDisplayDelay->nU32 > MAX_H264_DISPLAYDELAY_VALIDNUM) {
+            ret = OMX_ErrorBadParameter;
+            break;
+        }
+
+        pH264Dec->hMFCH264Handle.nDisplayDelay = pDisplayDelay->nU32;
+    }
+        break;
+    case OMX_IndexExynosParamReorderMode:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *pReorderParam = (EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pReorderParam, sizeof(EXYNOS_OMX_VIDEO_PARAM_REORDERMODE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pVideoDec->bReorderMode = pReorderParam->bReorderMode;
+    }
+        break;
+    default:
+#ifdef USE_SKYPE_HD
+        ret = Exynos_H264Dec_SetParameter_SkypeHD(hComponent, nIndex, pComponentParameterStructure);
+        if (ret != OMX_ErrorNone)
+#endif
+            ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_GetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigCommonOutputCrop:
+    {
+        EXYNOS_OMX_BASEPORT *pExynosPort  = NULL;
+        OMX_CONFIG_RECTTYPE *pSrcRectType = NULL;
+        OMX_CONFIG_RECTTYPE *pDstRectType = NULL;
+
+        if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
+            ret = OMX_ErrorNotReady;
+            break;
+        }
+
+        pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
+
+        if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) &&
+            (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex];
+
+        pSrcRectType = &(pExynosPort->cropRectangle);
+
+        pDstRectType->nTop = pSrcRectType->nTop;
+        pDstRectType->nLeft = pSrcRectType->nLeft;
+        pDstRectType->nHeight = pSrcRectType->nHeight;
+        pDstRectType->nWidth = pSrcRectType->nWidth;
+    }
+        break;
+#ifdef USE_S3D_SUPPORT
+    case OMX_IndexVendorS3DMode:
+    {
+        OMX_U32                *pS3DMode = NULL;
+
+        pS3DMode = (OMX_U32 *)pComponentConfigStructure;
+        *pS3DMode = (OMX_U32) pH264Dec->hMFCH264Handle.S3DFPArgmtType;
+    }
+        break;
+#endif
+    case OMX_IndexExynosConfigDisplayDelay:  /* MSRND */
+    {
+        (*((OMX_U32 *)pComponentConfigStructure)) = pH264Dec->hMFCH264Handle.nDisplayDelay;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexExynosConfigDisplayDelay:  /* MSRND */
+    {
+        OMX_U32 nDisplayDelay = (*((OMX_U32 *)pComponentConfigStructure));
+
+        if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_TRUE) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            break;
+        }
+
+        if (nDisplayDelay > MAX_H264_DISPLAYDELAY_VALIDNUM) {
+            ret = OMX_ErrorBadParameter;
+            break;
+        }
+
+        pH264Dec->hMFCH264Handle.nDisplayDelay = nDisplayDelay;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_GetExtensionIndex(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE *pIndexType)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] pOMXComponent->pComponentPrivate is NULL", __FUNCTION__);
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+#ifdef USE_S3D_SUPPORT
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_GET_S3D) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorS3DMode;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+#endif
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_REORDER_MODE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamReorderMode;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) {
+        if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_CONFIG_DISPLAY_DELAY) == 0) {
+            *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosConfigDisplayDelay;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_DISPLAY_DELAY) == 0) {
+            *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamDisplayDelay;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_ComponentRoleEnum(
+    OMX_HANDLETYPE hComponent,
+    OMX_U8        *cRole,
+    OMX_U32        nIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) || (cRole == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorNoMore;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    ExynosVideoInstInfo *pVideoInstInfo = &(pH264Dec->hMFCH264Handle.videoInstInfo);
+
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+    int i;
+
+    FunctionIn();
+
+    pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
+    pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    pVideoDec->bDiscardCSDError = OMX_FALSE;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                             pExynosInputPort->portDefinition.format.video.nBitrate,
+                                                                                             pExynosInputPort->portDefinition.format.video.xFramerate);
+    pVideoInstInfo->nSize       = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth      = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight     = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate    = pExynosInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate  = pExynosInputPort->portDefinition.format.video.xFramerate;
+
+    /* H.264 Codec Open */
+    ret = H264CodecOpen(pH264Dec, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+        nAllocLen[0] = ALIGN(pExynosInputPort->portDefinition.format.video.nFrameWidth *
+                             pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+        if (nAllocLen[0] < pVideoDec->nMinInBufSize)
+            nAllocLen[0] = pVideoDec->nMinInBufSize;
+
+        Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_SetPlaneToPort(pExynosOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pH264Dec->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pH264Dec->hSourceStartEvent);
+    pH264Dec->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pH264Dec->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pH264Dec->hDestinationOutStartEvent);
+
+    Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pH264Dec->hMFCH264Handle.indexTimestamp = 0;
+    pH264Dec->hMFCH264Handle.outputIndexTimestamp = 0;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pH264Dec->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) {
+        pVideoDec->csc_handle = csc_init(CSC_METHOD_HW);
+        csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2);
+        csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_MODE_DRM, 1);
+    } else {
+        pVideoDec->csc_handle = csc_init(csc_method);
+    }
+
+    if (pVideoDec->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    pVideoDec->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    FunctionIn();
+
+    if (pVideoDec->csc_handle != NULL) {
+        csc_deinit(pVideoDec->csc_handle);
+        pVideoDec->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pH264Dec->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pH264Dec->hDestinationInStartEvent);
+    pH264Dec->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pH264Dec->hDestinationOutStartEvent);
+    pH264Dec->hDestinationOutStartEvent = NULL;
+    pH264Dec->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pH264Dec->hSourceStartEvent);
+    pH264Dec->hSourceStartEvent = NULL;
+    pH264Dec->bSourceStart = OMX_FALSE;
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
+        pExynosOutputPort->codecSemID = NULL;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
+        pExynosInputPort->codecSemID = NULL;
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+    H264CodecClose(pH264Dec);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pH264Dec->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    OMX_U32 oneFrameSize = pSrcInputData->dataLen;
+
+    ExynosVideoDecOps       *pDecOps     = pH264Dec->hMFCH264Handle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps   = pH264Dec->hMFCH264Handle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+
+    OMX_BOOL bInStartCode = OMX_FALSE;
+
+    FunctionIn();
+
+    if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (pH264Dec->bDestinationStart == OMX_FALSE) &&
+        (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+        ret = H264CodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to H264CodecDstSetup(0x%x)",
+                                            pExynosComponent, __FUNCTION__, ret);
+            goto EXIT;
+        }
+    }
+
+    if (((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) ||
+            ((bInStartCode = Check_H264_StartCode(pSrcInputData->buffer.addr[0], oneFrameSize)) == OMX_TRUE)) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+
+        if (pVideoDec->bReorderMode == OMX_FALSE) {
+            /* next slot will be used like as circular queue */
+            pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
+            pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp]    = pSrcInputData->nFlags;
+        } else {  /* MSRND */
+            Exynos_SetReorderTimestamp(pExynosComponent, &(pH264Dec->hMFCH264Handle.indexTimestamp), pSrcInputData->timeStamp, pSrcInputData->nFlags);
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), dataLen(%d), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, oneFrameSize, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pH264Dec->hMFCH264Handle.indexTimestamp);
+
+        pDecOps->Set_FrameTag(hMFCHandle, pH264Dec->hMFCH264Handle.indexTimestamp);
+        pH264Dec->hMFCH264Handle.indexTimestamp++;
+        pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
+
+        if ((pVideoDec->bQosChanged == OMX_TRUE) &&
+            (pDecOps->Set_QosRatio != NULL)) {
+            pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
+            pVideoDec->bQosChanged = OMX_FALSE;
+        }
+
+        if (pVideoDec->bSearchBlackBarChanged == OMX_TRUE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] BlackBar searching mode : %s",
+                                            pExynosComponent, __FUNCTION__,
+                                            (pVideoDec->bSearchBlackBar == OMX_TRUE) ? "enable" : "disable");
+            pDecOps->Set_SearchBlackBar(hMFCHandle, (ExynosVideoBoolType)pVideoDec->bSearchBlackBar);
+            pVideoDec->bSearchBlackBarChanged = OMX_FALSE;
+        }
+
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        /* queue work for input buffer */
+        nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+        if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        } else {
+            nAllocLen[0] = pSrcInputData->allocSize;
+
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        }
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pSrcInputData->buffer.addr,
+                                (unsigned long *)pSrcInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pExynosInputPort),
+                                pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            goto EXIT;
+        }
+
+        H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+
+        if (pH264Dec->bSourceStart == OMX_FALSE) {
+            pH264Dec->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pH264Dec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
+            (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE)) {
+            pH264Dec->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pH264Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pH264Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    } else if (bInStartCode == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] can't find a start code", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedFrame;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pH264Dec->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pInbufOps      = pH264Dec->hMFCH264Handle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->allocSize  = 0;
+        pSrcOutputData->pPrivate = NULL;
+    } else {
+        pSrcOutputData->buffer.addr[0]  = pVideoBuffer->planes[0].addr;
+        pSrcOutputData->buffer.fd[0]    = pVideoBuffer->planes[0].fd;
+        pSrcOutputData->allocSize       = pVideoBuffer->planes[0].allocSize;
+
+        if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] == pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
+                    pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pExynosInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pH264Dec->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pOutbufOps  = pH264Dec->hMFCH264Handle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++) {
+        nAllocLen[i] = pH264Dec->hMFCH264Handle.codecOutbufConf.nAlignPlaneSize[i];
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] ADDR[%d]: 0x%x, size[%d]: %d", pExynosComponent, __FUNCTION__,
+                                        i, pDstInputData->buffer.addr[i], i, nAllocLen[i]);
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                nPlaneCnt,
+                                pDstInputData->bufferHeader);
+
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+        }
+
+        goto EXIT;
+    }
+
+    H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pH264Dec->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+    DECODE_CODEC_EXTRA_BUFFERINFO   *pBufferInfo        = NULL;
+
+    ExynosVideoDecOps           *pDecOps        = pH264Dec->hMFCH264Handle.pDecOps;
+    ExynosVideoDecBufferOps     *pOutbufOps     = pH264Dec->hMFCH264Handle.pOutbufOps;
+    ExynosVideoBuffer           *pVideoBuffer   = NULL;
+    ExynosVideoBuffer            videoBuffer;
+    ExynosVideoFrameStatusType   displayStatus  = VIDEO_FRAME_STATUS_UNKNOWN;
+    ExynosVideoGeometry         *bufferGeometry = NULL;
+    ExynosVideoErrorType         codecReturn    = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+
+    OMX_S32 indexTimestamp = 0;
+    int plane, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pH264Dec->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    while (1) {
+        Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer));
+
+        codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+        if (codecReturn == VIDEO_ERROR_NONE) {
+            pVideoBuffer = &videoBuffer;
+        } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO) at ExtensionDequeue", pExynosComponent, __FUNCTION__);
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorHardware;
+            goto EXIT;
+        } else {
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        displayStatus = pVideoBuffer->displayStatus;
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus: 0x%x", pExynosComponent, __FUNCTION__, displayStatus);
+
+        if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
+            (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+            (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D) ||
+            (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+            (CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+            ret = OMX_ErrorNone;
+            break;
+        }
+    }
+
+#ifdef USE_S3D_SUPPORT
+    /* Check Whether frame packing information is available */
+    if ((pH264Dec->hMFCH264Handle.S3DFPArgmtType == OMX_SEC_FPARGMT_INVALID) &&
+        (pVideoDec->bThumbnailMode == OMX_FALSE) &&
+        ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
+         (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
+         (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D))) {
+        if (H264CodecCheckFramePacking(pOMXComponent) != OMX_TRUE) {
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            goto EXIT;
+        }
+    }
+#endif
+
+    if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+        ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+         (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D))) {
+        if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+            pOutputPort->exceptionFlag = NEED_PORT_FLUSH;
+            pVideoDec->bReconfigDPB = OMX_TRUE;
+            H264CodecUpdateResolution(pOMXComponent);
+            pVideoDec->csc_set_format = OMX_FALSE;
+#ifdef USE_S3D_SUPPORT
+            pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_INVALID;
+#endif
+        }
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pH264Dec->hMFCH264Handle.outputIndexTimestamp++;
+    pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+    pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
+    nPlaneCnt = Exynos_GetPlaneFromPort(pOutputPort);
+    for (plane = 0; plane < nPlaneCnt; plane++) {
+        pDstOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+        pDstOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+        pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        pDstOutputData->dataLen   += pVideoBuffer->planes[plane].dataSize;
+
+        nDataLen[plane]            = pVideoBuffer->planes[plane].dataSize;
+    }
+    pDstOutputData->usedDataLen = 0;
+    pDstOutputData->pPrivate = pVideoBuffer;
+
+    pBufferInfo     = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+    bufferGeometry  = &pH264Dec->hMFCH264Handle.codecOutbufConf;
+    pBufferInfo->imageWidth       = bufferGeometry->nFrameWidth;
+    pBufferInfo->imageHeight      = bufferGeometry->nFrameHeight;
+    pBufferInfo->imageStride      = bufferGeometry->nStride;
+    pBufferInfo->cropRect.nLeft   = bufferGeometry->cropRect.nLeft;
+    pBufferInfo->cropRect.nTop    = bufferGeometry->cropRect.nTop;
+    pBufferInfo->cropRect.nWidth  = bufferGeometry->cropRect.nWidth;
+    pBufferInfo->cropRect.nHeight = bufferGeometry->cropRect.nHeight;
+    pBufferInfo->colorFormat      = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+    Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            goto EXIT;
+        }
+
+        /* calculate each plane info for the application */
+        Exynos_OSAL_GetPlaneSize(pOutputPort->portDefinition.format.video.eColorFormat,
+                                 PLANE_SINGLE, pOutputPort->portDefinition.format.video.nFrameWidth,
+                                 pOutputPort->portDefinition.format.video.nFrameHeight,
+                                 nDataLen, nAllocLen);
+
+        pDstOutputData->allocSize = nAllocLen[0] + nAllocLen[1] + nAllocLen[2];
+        pDstOutputData->dataLen   = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+#ifdef USE_ANDROID
+    /* get interlace frame info and HDR info */
+    if ((pOutputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pVideoBuffer->planes[2].addr != NULL)) {
+        ExynosVideoMeta *pMeta = (ExynosVideoMeta *)pVideoBuffer->planes[2].addr;
+
+        pMeta->eType = VIDEO_INFO_TYPE_INVALID;
+
+        if (pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] interlace type = %x", pExynosComponent, __FUNCTION__, pVideoBuffer->interlacedType);
+            pMeta->eType |= VIDEO_INFO_TYPE_INTERLACED;
+            pMeta->data.dec.nInterlacedType = pVideoBuffer->interlacedType;
+        }
+
+        if (pVideoBuffer->frameType & VIDEO_FRAME_WITH_HDR_INFO)
+            H264CodecUpdateHdrInfo(pOMXComponent, pMeta);
+    }
+#endif
+
+    indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+    if (pVideoDec->bReorderMode == OMX_FALSE) {
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
+                (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
+                if (indexTimestamp == INDEX_AFTER_EOS) {
+                    pDstOutputData->timeStamp = 0x00;
+                    pDstOutputData->nFlags = 0x00;
+                } else {
+                    pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
+                    pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] missing out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+                }
+            } else {
+                pDstOutputData->timeStamp = 0x00;
+                pDstOutputData->nFlags = 0x00;
+            }
+        } else {
+            /* For timestamp correction. if mfc support frametype detect */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] disp_pic_frame_type: %d", pExynosComponent, __FUNCTION__, pVideoBuffer->frameType);
+
+            /* NEED TIMESTAMP REORDER */
+            if (pVideoDec->bDTSMode == OMX_TRUE) {
+                if ((pVideoBuffer->frameType & VIDEO_FRAME_I) ||
+                    ((pVideoBuffer->frameType & VIDEO_FRAME_OTHERS) &&
+                        ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
+                    (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
+                    pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp;
+                else
+                    indexTimestamp = pH264Dec->hMFCH264Handle.outputIndexTimestamp;
+            }
+
+            pDstOutputData->timeStamp   = pExynosComponent->timeStamp[indexTimestamp];
+            pDstOutputData->nFlags      = pExynosComponent->nFlags[indexTimestamp] | OMX_BUFFERFLAG_ENDOFFRAME;
+
+            if (pVideoBuffer->frameType & VIDEO_FRAME_I)
+                pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+            if (pVideoBuffer->frameType & VIDEO_FRAME_CORRUPT)
+                pDstOutputData->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                                    pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                                    indexTimestamp);
+    } else {  /* MSRND */
+        EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP sCurrentTimestamp;
+
+        Exynos_GetReorderTimestamp(pExynosComponent, &sCurrentTimestamp, indexTimestamp, pVideoBuffer->frameType);
+
+        pDstOutputData->timeStamp   = sCurrentTimestamp.timeStamp;
+        pDstOutputData->nFlags      = sCurrentTimestamp.nFlags | OMX_BUFFERFLAG_ENDOFFRAME;
+
+        pExynosComponent->nFlags[sCurrentTimestamp.nIndex]               = 0x00;
+        pExynosComponent->bTimestampSlotUsed[sCurrentTimestamp.nIndex]   = OMX_FALSE;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), reordered tag: %d, original tag: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                                    pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                                    sCurrentTimestamp.nIndex,
+                                                    indexTimestamp);
+    }
+
+    if (pVideoBuffer->frameType & VIDEO_FRAME_WITH_BLACK_BAR) {
+        if (H264CodecUpdateBlackBarCrop(pOMXComponent) != OMX_ErrorNone)
+            goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+        (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+    }
+
+    if (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) {
+        pDstOutputData->remainDataLen = 0;
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            if (indexTimestamp != INDEX_AFTER_EOS)
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] tag(%d) is wrong", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+            pDstOutputData->timeStamp   = 0x00;
+            pDstOutputData->nFlags      = 0x00;
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) ||
+            (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+            pExynosComponent->nFlags[indexTimestamp] &= (~OMX_BUFFERFLAG_EOS);
+        }
+    } else if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        pDstOutputData->remainDataLen = 0;
+
+        if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
+            pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+            if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+                pExynosComponent->bBehaviorEOS = OMX_FALSE;
+            } else {
+                pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+                pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+            }
+        }
+    } else {
+        pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_H264Dec_SrcIn(pOMXComponent, pSrcInputData);
+    if ((ret != OMX_ErrorNone) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorCorruptedFrame)) {
+
+        if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+            (pVideoDec->bDiscardCSDError == OMX_TRUE)) {
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+    if ((pH264Dec->bSourceStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
+        Exynos_OSAL_SignalWait(pH264Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pH264Dec->hSourceStartEvent);
+    }
+
+    ret = Exynos_H264Dec_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        if (pExynosComponent->currentState == OMX_StatePause)
+            ret = (OMX_ERRORTYPE)OMX_ErrorOutputBufferUseYet;
+        else
+            ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pH264Dec->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pH264Dec->hDestinationInStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pH264Dec->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pH264Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+            (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+            ret = H264CodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to H264CodecDstSetup(0x%x)", pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+            Exynos_OSAL_SignalSet(pH264Dec->hDestinationOutStartEvent);
+        }
+    }
+
+    if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_H264Dec_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                    pExynosComponent->callbackData,
+                                                    OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (((pH264Dec->bDestinationStart == OMX_FALSE) ||
+         (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE)) &&
+        (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pH264Dec->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pH264Dec->hDestinationOutStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pH264Dec->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pH264Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_H264Dec_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = NULL;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec         = NULL;
+    OMX_BOOL                       bSecureMode      = OMX_FALSE;
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) || (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DEC, componentName) == 0) {
+        bSecureMode = OMX_FALSE;
+    } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DRM_DEC, componentName) == 0) {
+        bSecureMode = OMX_TRUE;
+    } else {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = (bSecureMode == OMX_TRUE)? HW_VIDEO_DEC_SECURE_CODEC:HW_VIDEO_DEC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pH264Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264DEC_HANDLE));
+    if (pH264Dec == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pH264Dec, 0, sizeof(EXYNOS_H264DEC_HANDLE));
+
+    pVideoDec               = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pH264Dec;
+
+    Exynos_OSAL_Strcpy(pExynosComponent->componentName, componentName);
+
+#ifdef USE_S3D_SUPPORT
+    pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_INVALID;
+#endif
+    pH264Dec->hMFCH264Handle.nDisplayDelay = MAX_H264_DISPLAYDELAY_VALIDNUM + 1;
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE)
+        pExynosPort->portDefinition.nBufferSize = CUSTOM_DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+
+    pVideoDec->nMinInBufSize = DEFAULT_VIDEO_MIN_INPUT_BUFFER_SIZE;  /* for DRC */
+
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+#ifdef USE_SINGLE_PLANE_IN_DRM
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        pExynosPort->ePlaneType = PLANE_SINGLE;
+#endif
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pH264Dec->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
+        pH264Dec->AVCComponent[i].nPortIndex = i;
+        pH264Dec->AVCComponent[i].eProfile   = OMX_VIDEO_AVCProfileBaseline;
+        pH264Dec->AVCComponent[i].eLevel     = OMX_VIDEO_AVCLevel4;
+    }
+
+    pOMXComponent->GetParameter      = &Exynos_H264Dec_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_H264Dec_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_H264Dec_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_H264Dec_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_H264Dec_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_H264Dec_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_H264Dec_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Dec_Terminate;
+
+    pVideoDec->exynos_codec_srcInputProcess  = &Exynos_H264Dec_srcInputBufferProcess;
+    pVideoDec->exynos_codec_srcOutputProcess = &Exynos_H264Dec_srcOutputBufferProcess;
+    pVideoDec->exynos_codec_dstInputProcess  = &Exynos_H264Dec_dstInputBufferProcess;
+    pVideoDec->exynos_codec_dstOutputProcess = &Exynos_H264Dec_dstOutputBufferProcess;
+
+    pVideoDec->exynos_codec_start            = &H264CodecStart;
+    pVideoDec->exynos_codec_stop             = &H264CodecStop;
+    pVideoDec->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun;
+    pVideoDec->exynos_codec_enqueueAllBuffer = &H264CodecEnQueueAllBuffer;
+
+    pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+    pVideoDec->exynos_codec_reconfigAllBuffers        = &H264CodecReconfigAllBuffers;
+
+    pVideoDec->exynos_codec_checkFormatSupport      = &CheckFormatHWSupport;
+    pVideoDec->exynos_codec_checkResolutionChange   = &H264CodecCheckResolution;
+
+    pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoDec->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pH264Dec);
+        pH264Dec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pH264Dec->hMFCH264Handle.videoInstInfo.eCodecType = VIDEO_CODING_AVC;
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        pH264Dec->hMFCH264Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pH264Dec->hMFCH264Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pH264Dec->hMFCH264Handle.videoInstInfo), VIDEO_TRUE /* dec */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pH264Dec);
+        pH264Dec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for dec skype(%d)", pExynosComponent, __FUNCTION__,
+            (pH264Dec->hMFCH264Handle.videoInstInfo.supportInfo.dec.bSkypeSupport));
+
+    Exynos_Output_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+#ifdef USE_ANDROID
+#ifdef USE_SKYPE_HD
+    Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-caps-vt-driver-version", (OMX_INDEXTYPE)OMX_IndexSkypeParamDriverVersion);
+    Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-dec-low-latency", (OMX_INDEXTYPE)OMX_IndexSkypeParamLowLatency);
+#endif
+#endif
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = NULL;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec         = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent       = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent    = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoDec           = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pH264Dec != NULL) {
+        Exynos_OSAL_Free(pH264Dec);
+        pH264Dec = pVideoDec->hCodecHandle = NULL;
+    }
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_DelVendorExts(hComponent);
+#endif
+
+    ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/dec/h264/Exynos_OMX_H264dec.h b/openmax/component/video/dec/h264/Exynos_OMX_H264dec.h
new file mode 100755 (executable)
index 0000000..9745e94
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file    Exynos_OMX_H264dec.h
+ * @brief
+ * @author    SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_H264_DEC_COMPONENT
+#define EXYNOS_OMX_H264_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+#include "ExynosVideoApi.h"
+#include "library_register.h"
+
+
+typedef struct _EXYNOS_MFC_H264DEC_HANDLE
+{
+    OMX_HANDLETYPE             hMFCHandle;
+    OMX_U32                    indexTimestamp;
+    OMX_U32                    outputIndexTimestamp;
+    OMX_BOOL                   bConfiguredMFCSrc;
+    OMX_BOOL                   bConfiguredMFCDst;
+    OMX_S32                    maxDPBNum;
+
+    /* for custom component(MSRND) */
+    #define MAX_H264_DISPLAYDELAY_VALIDNUM 8
+    OMX_U32                    nDisplayDelay;
+
+    /* skype */
+    OMX_BOOL bLowLatency;
+
+#ifdef USE_S3D_SUPPORT
+    EXYNOS_OMX_FPARGMT_TYPE    S3DFPArgmtType;
+#endif
+
+    ExynosVideoColorFormatType MFCOutputColorType;
+    ExynosVideoDecOps         *pDecOps;
+    ExynosVideoDecBufferOps   *pInbufOps;
+    ExynosVideoDecBufferOps   *pOutbufOps;
+    ExynosVideoGeometry        codecOutbufConf;
+    ExynosVideoInstInfo        videoInstInfo;
+
+    #define MAX_PROFILE_NUM 5
+    OMX_VIDEO_AVCPROFILETYPE   profiles[MAX_PROFILE_NUM];
+    OMX_S32                    nProfileCnt;
+    OMX_VIDEO_AVCLEVELTYPE     maxLevel;
+} EXYNOS_MFC_H264DEC_HANDLE;
+
+typedef struct _EXYNOS_H264DEC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_AVCTYPE AVCComponent[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+
+    /* EXYNOS MFC Codec specific */
+    EXYNOS_MFC_H264DEC_HANDLE hMFCH264Handle;
+
+    OMX_BOOL bSourceStart;
+    OMX_BOOL bDestinationStart;
+    OMX_HANDLETYPE hSourceStartEvent;
+    OMX_HANDLETYPE hDestinationInStartEvent;
+    OMX_HANDLETYPE hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE bypassBufferInfoQ;
+} EXYNOS_H264DEC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName);
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/h264/Makefile.am b/openmax/component/video/dec/h264/Makefile.am
new file mode 100755 (executable)
index 0000000..81e6951
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libOMX.Exynos.AVC.Decoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_AVC_Decoder_la_SOURCES = Exynos_OMX_H264dec.c \
+                                       library_register.c
+
+libOMX_Exynos_AVC_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                      $(top_builddir)/openmax/component/video/dec/libExynosOMX_Vdec.la \
+                                      $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+libOMX_Exynos_AVC_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                      -I$(top_srcdir)/openmax/include/exynos \
+                                      -I$(top_srcdir)/openmax/osal \
+                                      -I$(top_srcdir)/openmax/core \
+                                      -I$(top_srcdir)/openmax/component/common \
+                                      -I$(top_srcdir)/openmax/component/video/dec \
+                                      -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_AVC_Decoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
+libOMX_Exynos_AVC_Decoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable
+
+libOMX_Exynos_AVC_Decoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/dec/h264/library_register.c b/openmax/component/video/dec/h264/library_register.c
new file mode 100755 (executable)
index 0000000..7fe26e8
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file    library_register.c
+ * @brief
+ * @author    SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+#include "Exynos_OSAL_Log.h"
+
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents)
+{
+    FunctionIn();
+
+    if (exynosComponents == NULL)
+        goto EXIT;
+
+    /* component 1 - video decoder H.264 */
+    Exynos_OSAL_Strcpy(exynosComponents[0]->componentName, EXYNOS_OMX_COMPONENT_H264_DEC);
+    Exynos_OSAL_Strcpy(exynosComponents[0]->roles[0], EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
+    exynosComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+    /* component 2 - video decoder H.264 for DRM */
+    Exynos_OSAL_Strcpy(exynosComponents[1]->componentName, EXYNOS_OMX_COMPONENT_H264_DRM_DEC);
+    Exynos_OSAL_Strcpy(exynosComponents[1]->roles[0], EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
+    exynosComponents[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
diff --git a/openmax/component/video/dec/h264/library_register.h b/openmax/component/video/dec/h264/library_register.h
new file mode 100755 (executable)
index 0000000..48f3f44
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_H264_REG
+#define EXYNOS_OMX_H264_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM       2
+#define MAX_COMPONENT_ROLE_NUM  1
+
+/* H.264 */
+#ifndef USE_CUSTOM_COMPONENT_SUPPORT
+#define EXYNOS_OMX_COMPONENT_H264_DEC            "OMX.Exynos.AVC.Decoder"
+#define EXYNOS_OMX_COMPONENT_H264_DRM_DEC        "OMX.Exynos.AVC.Decoder.secure"
+#else
+#define EXYNOS_OMX_COMPONENT_H264_DEC            "OMX.Exynos.avc.dec"
+#define EXYNOS_OMX_COMPONENT_H264_DRM_DEC        "OMX.Exynos.avc.dec.secure"
+#endif
+
+#define EXYNOS_OMX_COMPONENT_H264_DEC_ROLE       "video_decoder.avc"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
diff --git a/openmax/component/video/dec/hevc/Exynos_OMX_HEVCdec.c b/openmax/component/video/dec/hevc/Exynos_OMX_HEVCdec.c
new file mode 100755 (executable)
index 0000000..f5ced49
--- /dev/null
@@ -0,0 +1,3620 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_HEVCdec.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2013.07.26 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Vdec.h"
+#include "Exynos_OMX_VdecControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_HEVCdec.h"
+#include "ExynosVideoApi.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+#ifdef USE_ANDROID
+#include "VendorVideoAPI.h"
+#endif
+
+/* To use CSC_METHOD_HW in EXYNOS OMX */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_HEVC_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec       = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pHevcDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcDec->hMFCHevcHandle.profiles[nProfileCnt++] = OMX_VIDEO_HEVCProfileMain;
+    pHevcDec->hMFCHevcHandle.nProfileCnt = nProfileCnt;
+
+    switch (pHevcDec->hMFCHevcHandle.videoInstInfo.HwVersion) {
+    case MFC_1220:
+    case MFC_120:
+    case MFC_110:
+        pHevcDec->hMFCHevcHandle.profiles[nProfileCnt++] = OMX_VIDEO_HEVCProfileMain10;
+        pHevcDec->hMFCHevcHandle.profiles[nProfileCnt++] = OMX_VIDEO_HEVCProfileMain10HDR10;
+        pHevcDec->hMFCHevcHandle.nProfileCnt = nProfileCnt;
+
+        pHevcDec->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel6;
+        break;
+    case MFC_100:
+        pHevcDec->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel51;
+        break;
+    case MFC_101:
+        pHevcDec->hMFCHevcHandle.profiles[nProfileCnt++] = OMX_VIDEO_HEVCProfileMain10;
+        pHevcDec->hMFCHevcHandle.profiles[nProfileCnt++] = OMX_VIDEO_HEVCProfileMain10HDR10;
+        pHevcDec->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel51;
+        break;
+    case HEVC_10:
+    case MFC_90:
+    case MFC_1010:
+    case MFC_1120:
+        pHevcDec->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel5;
+        break;
+    case MFC_1011:
+    case MFC_1020:
+        pHevcDec->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel41;
+        break;
+    case MFC_92:
+    case MFC_1021:
+    default:
+        pHevcDec->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel4;
+        break;
+    }
+
+EXIT:
+
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec       = NULL;
+
+    int nLevelCnt = 0;
+    OMX_U32 nMaxIndex = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pHevcDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pHevcDec->hMFCHevcHandle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pHevcDec->hMFCHevcHandle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pHevcDec->hMFCHevcHandle.maxLevel;
+#else
+    while ((pHevcDec->hMFCHevcHandle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+
+    if ((pHevcDec->hMFCHevcHandle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                        pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pHevcDec->hMFCHevcHandle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pHevcDec->hMFCHevcHandle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] supported profile(%x), level(%x)",
+                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec  = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec   = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pHevcDec == NULL)
+        goto EXIT;
+
+    while ((pHevcDec->hMFCHevcHandle.maxLevel >> nLevelCnt++) > 0);
+
+    if ((pHevcDec->hMFCHevcHandle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pHevcDec->hMFCHevcHandle.nProfileCnt; i++) {
+        if (pHevcDec->hMFCHevcHandle.profiles[i] == pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    while (nLevelCnt >= 0) {
+        if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+            bLevelSupport = OMX_TRUE;
+            break;
+        }
+
+        nLevelCnt--;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    FunctionOut();
+
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_ERRORTYPE GetCodecOutputPrivateData(
+    OMX_PTR     codecBuffer,
+    OMX_PTR     addr[],
+    OMX_U32     size[])
+{
+    OMX_ERRORTYPE       ret             = OMX_ErrorNone;
+    ExynosVideoBuffer  *pCodecBuffer    = NULL;
+
+    if (codecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
+
+    if (addr != NULL) {
+        addr[0] = pCodecBuffer->planes[0].addr;
+        addr[1] = pCodecBuffer->planes[1].addr;
+        addr[2] = pCodecBuffer->planes[2].addr;
+    }
+
+    if (size != NULL) {
+        size[0] = pCodecBuffer->planes[0].allocSize;
+        size[1] = pCodecBuffer->planes[1].allocSize;
+        size[2] = pCodecBuffer->planes[2].allocSize;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_BOOL Check_HEVC_StartCode(
+    OMX_U8     *pInputStream,
+    OMX_U32     streamSize)
+{
+    OMX_BOOL ret = OMX_FALSE;
+
+    FunctionIn();
+
+    if (streamSize < 4) {
+        ret = OMX_FALSE;
+        goto EXIT;
+    }
+
+    if ((pInputStream[0] == 0x00) &&
+        (pInputStream[1] == 0x00) &&
+        (pInputStream[2] == 0x01))
+        ret = OMX_TRUE;
+
+    if ((pInputStream[0] == 0x00) &&
+        (pInputStream[1] == 0x00) &&
+        (pInputStream[2] == 0x00) &&
+        (pInputStream[3] == 0x01))
+        ret = OMX_TRUE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec       = NULL;
+    EXYNOS_OMX_BASEPORT             *pOutputPort    = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pHevcDec == NULL)
+        goto EXIT;
+    pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pOutputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pHevcDec->hMFCHevcHandle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pHevcDec->hMFCHevcHandle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+
+    return ret;
+}
+
+OMX_ERRORTYPE HevcCodecOpen(
+    EXYNOS_HEVCDEC_HANDLE *pHevcDec,
+    ExynosVideoInstInfo   *pVideoInstInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pHevcDec == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pDecOps    = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
+    pInbufOps  = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+    pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+
+    if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pHevcDec->hMFCHevcHandle.pDecOps    = pDecOps;
+    pHevcDec->hMFCHevcHandle.pInbufOps  = pInbufOps;
+    pHevcDec->hMFCHevcHandle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pDecOps->nSize    = sizeof(ExynosVideoDecOps);
+    pInbufOps->nSize  = sizeof(ExynosVideoDecBufferOps);
+    pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
+
+    if (Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for decoder ops */
+    if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
+        (pDecOps->Get_ActualBufferCount == NULL) ||
+#ifdef USE_S3D_SUPPORT
+        (pDecOps->Enable_SEIParsing == NULL) || (pDecOps->Get_FramePackingInfo == NULL) ||
+#endif
+        (pDecOps->Set_FrameTag == NULL) || (pDecOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pHevcDec->hMFCHevcHandle.hMFCHandle = pHevcDec->hMFCHevcHandle.pDecOps->Init(pVideoInstInfo);
+
+    if (pHevcDec->hMFCHevcHandle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+#ifdef USE_S3D_SUPPORT
+    /* S3D: Enable SEI parsing to check Frame Packing */
+    if (pDecOps->Enable_SEIParsing(pHevcDec->hMFCHevcHandle.hMFCHandle) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Enable SEI Parsing", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+#endif
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pDecOps != NULL) {
+            Exynos_OSAL_Free(pDecOps);
+            pHevcDec->hMFCHevcHandle.pDecOps = NULL;
+        }
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pHevcDec->hMFCHevcHandle.pInbufOps = NULL;
+        }
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pHevcDec->hMFCHevcHandle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HevcCodecClose(EXYNOS_HEVCDEC_HANDLE *pHevcDec)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pHevcDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    pDecOps    = pHevcDec->hMFCHevcHandle.pDecOps;
+    pInbufOps  = pHevcDec->hMFCHevcHandle.pInbufOps;
+    pOutbufOps = pHevcDec->hMFCHevcHandle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pDecOps->Finalize(hMFCHandle);
+        pHevcDec->hMFCHevcHandle.hMFCHandle = NULL;
+        pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc = OMX_FALSE;
+        pHevcDec->hMFCHevcHandle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pHevcDec->hMFCHevcHandle.pOutbufOps = NULL;
+    }
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pHevcDec->hMFCHevcHandle.pInbufOps = NULL;
+    }
+    if (pDecOps != NULL) {
+        Exynos_OSAL_Free(pDecOps);
+        pHevcDec->hMFCHevcHandle.pDecOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HevcCodecStart(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_U32             nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec           = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pHevcDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    pInbufOps  = pHevcDec->hMFCHevcHandle.pInbufOps;
+    pOutbufOps = pHevcDec->hMFCHevcHandle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc == OMX_TRUE)) {
+        pInbufOps->Run(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pHevcDec->hMFCHevcHandle.bConfiguredMFCDst == OMX_TRUE)) {
+        pOutbufOps->Run(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HevcCodecStop(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_U32             nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec           = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pHevcDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    pInbufOps  = pHevcDec->hMFCHevcHandle.pInbufOps;
+    pOutbufOps = pHevcDec->hMFCHevcHandle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) {
+        pInbufOps->Stop(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) {
+        EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+        pOutbufOps->Stop(hMFCHandle);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE)
+            pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HevcCodecOutputBufferProcessRun(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_U32             nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec           = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pHevcDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pHevcDec->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pHevcDec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pHevcDec->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pHevcDec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pHevcDec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pHevcDec->hMFCHevcHandle.bConfiguredMFCDst == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pHevcDec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HevcCodecReconfigAllBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = &pExynosComponent->pExynosPort[nPortIndex];
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec           = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    ExynosVideoDecBufferOps         *pBufferOps         = NULL;
+
+    FunctionIn();
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pHevcDec->bSourceStart == OMX_TRUE)) {
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pHevcDec->bDestinationStart == OMX_TRUE)) {
+        pBufferOps  = pHevcDec->hMFCHevcHandle.pOutbufOps;
+
+        if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+            /**********************************/
+            /* Codec Buffer Free & Unregister */
+            /**********************************/
+            Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+            Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pHevcDec->hMFCHevcHandle.bConfiguredMFCDst = OMX_FALSE;
+
+            /******************************************************/
+            /* V4L2 Destnation Setup for DPB Buffer Number Change */
+            /******************************************************/
+            ret = HevcCodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to HevcCodecDstSetup(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+        } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+            /***************************/
+            /* Codec Buffer Unregister */
+            /***************************/
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pHevcDec->hMFCHevcHandle.bConfiguredMFCDst = OMX_FALSE;
+        }
+    } else {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HevcCodecEnQueueAllBuffer(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_U32             nPortIndex)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec          = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    int i;
+
+    ExynosVideoDecBufferOps *pInbufOps  = pHevcDec->hMFCHevcHandle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pHevcDec->hMFCHevcHandle.pOutbufOps;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecInputBuffer[i]->fd[0], pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pHevcDec->hMFCHevcHandle.bConfiguredMFCDst == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < pHevcDec->hMFCHevcHandle.maxDPBNum; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecOutputBuffer[i]->fd[0], pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+        }
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+#ifdef USE_S3D_SUPPORT
+OMX_BOOL HevcCodecCheckFramePacking(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec          = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+    ExynosVideoDecOps             *pDecOps           = pHevcDec->hMFCHevcHandle.pDecOps;
+    ExynosVideoFramePacking        framePacking;
+    void                          *hMFCHandle        = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    OMX_BOOL                       ret               = OMX_FALSE;
+
+    FunctionIn();
+
+    /* Get Frame packing information*/
+    if (pDecOps->Get_FramePackingInfo(pHevcDec->hMFCHevcHandle.hMFCHandle, &framePacking) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Get Frame Packing Information", pExynosComponent, __FUNCTION__);
+        ret = OMX_FALSE;
+        goto EXIT;
+    }
+
+    if (framePacking.available) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] arrangement ID: 0x%08x",
+                                            pExynosComponent, __FUNCTION__, framePacking.arrangement_id);
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] arrangement_type: %d",
+                                            pExynosComponent, __FUNCTION__, framePacking.arrangement_type);
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] content_interpretation_type: %d",
+                                            pExynosComponent, __FUNCTION__, framePacking.content_interpretation_type);
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] current_frame_is_frame0_flag: %d",
+                                            pExynosComponent, __FUNCTION__, framePacking.current_frame_is_frame0_flag);
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] spatial_flipping_flag: %d",
+                                            pExynosComponent, __FUNCTION__, framePacking.spatial_flipping_flag);
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] fr0X:%d fr0Y:%d fr0X:%d fr0Y:%d",
+                                            pExynosComponent, __FUNCTION__, framePacking.frame0_grid_pos_x,
+                                            framePacking.frame0_grid_pos_y, framePacking.frame1_grid_pos_x, framePacking.frame1_grid_pos_y);
+
+        pHevcDec->hMFCHevcHandle.S3DFPArgmtType = (EXYNOS_OMX_FPARGMT_TYPE) framePacking.arrangement_type;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventS3DInformation)",
+                                                pExynosComponent, __FUNCTION__);
+        /** Send Port Settings changed call back - output color format change */
+        (*(pExynosComponent->pCallbacks->EventHandler))
+              (pOMXComponent,
+               pExynosComponent->callbackData,
+               (OMX_EVENTTYPE)OMX_EventS3DInformation,              /* The command was completed */
+               OMX_TRUE,                                            /* S3D is enabled */
+               (OMX_S32)pHevcDec->hMFCHevcHandle.S3DFPArgmtType,    /* S3D FPArgmtType */
+               NULL);
+
+        Exynos_OSAL_SleepMillisec(0);
+    } else {
+        pHevcDec->hMFCHevcHandle.S3DFPArgmtType = OMX_SEC_FPARGMT_NONE;
+    }
+
+    ret = OMX_TRUE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+#endif
+
+#ifdef USE_ANDROID
+void HevcCodecUpdateHdrInfo(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    ExynosVideoMeta     *pMeta)
+{
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec          = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort       = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pInputPort        = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    void                          *hMFCHandle        = pHevcDec->hMFCHevcHandle.hMFCHandle;
+
+    ExynosVideoDecOps  *pDecOps = pHevcDec->hMFCHevcHandle.pDecOps;
+    ExynosVideoHdrInfo  sHdrInfo;
+
+    if (pDecOps->Get_HDRInfo(hMFCHandle, &sHdrInfo) == VIDEO_ERROR_NONE) {
+        /* update bitstream's info to input port */
+        EXYNOS_OMX_VIDEO_HDRSTATICINFO   *pHDRStaticInfo = &(pOutputPort->HDRStaticInfo);
+        EXYNOS_OMX_VIDEO_COLORASPECTS    *pColorAspects  = &(pInputPort->ColorAspects);
+
+        /* save info to vendor path for renderer */
+        ExynosType1         *pMetaHDR = &(pMeta->data.dec.sHdrStaticInfo.sType1);
+        ExynosColorAspects  *pMetaCA  = &(pMeta->data.dec.sColorAspects);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eType(0x%x) is changed", pExynosComponent, __FUNCTION__, sHdrInfo.eChangedType);
+
+        /* color aspects */
+        if (sHdrInfo.eValidType & (HDR_INFO_COLOR_ASPECTS | HDR_INFO_RANGE)) {
+            /* HDR_INFO_COLOR_ASPECTS (8) */
+            pMetaCA->mMatrixCoeffs = pColorAspects->nCoeffType      = sHdrInfo.sColorAspects.eCoeffType;
+            pMetaCA->mPrimaries    = pColorAspects->nPrimaryType    = sHdrInfo.sColorAspects.ePrimariesType;
+            pMetaCA->mTransfer     = pColorAspects->nTransferType   = sHdrInfo.sColorAspects.eTransferType;
+
+            /* HDR_INFO_RANGE (16) */
+            pMetaCA->mRange        = pColorAspects->nRangeType      = sHdrInfo.sColorAspects.eRangeType;
+
+            //pMeta->eType |= VIDEO_INFO_TYPE_COLOR_ASPECTS;
+        }
+
+        /* hdr static info */
+        if (sHdrInfo.eValidType & (HDR_INFO_LIGHT | HDR_INFO_LUMINANCE)) {
+            /* HDR_INFO_LIGHT (1) */
+            pMetaHDR->mMaxFrameAverageLightLevel = pHDRStaticInfo->nMaxPicAverageLight  = sHdrInfo.sHdrStatic.max_pic_average_light;
+            pMetaHDR->mMaxContentLightLevel      = pHDRStaticInfo->nMaxContentLight     = sHdrInfo.sHdrStatic.max_content_light;
+
+            /* HDR_INFO_LUMINANCE (2) */
+            pMetaHDR->mMaxDisplayLuminance       = pHDRStaticInfo->nMaxDisplayLuminance = sHdrInfo.sHdrStatic.max_display_luminance;
+            pMetaHDR->mMinDisplayLuminance       = pHDRStaticInfo->nMinDisplayLuminance = sHdrInfo.sHdrStatic.min_display_luminance;
+
+            pMetaHDR->mR.x = pHDRStaticInfo->red.x  = sHdrInfo.sHdrStatic.red.x;
+            pMetaHDR->mR.y = pHDRStaticInfo->red.y  = sHdrInfo.sHdrStatic.red.y;
+
+            pMetaHDR->mG.x = pHDRStaticInfo->green.x = sHdrInfo.sHdrStatic.green.x;
+            pMetaHDR->mG.y = pHDRStaticInfo->green.y = sHdrInfo.sHdrStatic.green.y;
+
+            pMetaHDR->mB.x = pHDRStaticInfo->blue.x  = sHdrInfo.sHdrStatic.blue.x;
+            pMetaHDR->mB.y = pHDRStaticInfo->blue.y  = sHdrInfo.sHdrStatic.blue.y;
+
+            pMetaHDR->mW.x = pHDRStaticInfo->white.x = sHdrInfo.sHdrStatic.white.x;
+            pMetaHDR->mW.y = pHDRStaticInfo->white.y = sHdrInfo.sHdrStatic.white.y;
+
+            pMeta->eType |= VIDEO_INFO_TYPE_HDR_STATIC;
+        }
+
+        /* if both have changed, should send an event once */
+        if (sHdrInfo.eChangedType & (HDR_INFO_COLOR_ASPECTS | HDR_INFO_RANGE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_IndexConfigVideoColorAspects)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 OMX_IndexConfigVideoColorAspects,
+                 NULL);
+        } else if (sHdrInfo.eChangedType & (HDR_INFO_LIGHT | HDR_INFO_LUMINANCE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_IndexConfigVideoHdrStaticInfo)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 OMX_IndexConfigVideoHdrStaticInfo,
+                 NULL);
+        }
+    }
+
+EXIT:
+
+    return;
+}
+#endif // USE_ANDROID
+
+OMX_ERRORTYPE HevcCodecUpdateBlackBarCrop(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec             = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    OMX_CONFIG_RECTTYPE           *pBlackBarCropRect    = &pVideoDec->blackBarCropRect;
+
+    ExynosVideoDecBufferOps  *pOutbufOps  = pHevcDec->hMFCHevcHandle.pOutbufOps;
+    ExynosVideoRect           CropRect;
+
+    FunctionIn();
+
+    Exynos_OSAL_Memset(&CropRect, 0, sizeof(ExynosVideoRect));
+    if (pOutbufOps->Get_BlackBarCrop(hMFCHandle, &CropRect) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get crop info", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pBlackBarCropRect->nLeft   = CropRect.nLeft;
+    pBlackBarCropRect->nTop    = CropRect.nTop;
+    pBlackBarCropRect->nWidth  = CropRect.nWidth;
+    pBlackBarCropRect->nHeight = CropRect.nHeight;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Black Bar Info: LEFT(%d) TOP(%d) WIDTH(%d) HEIGHT(%d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pBlackBarCropRect->nLeft, pBlackBarCropRect->nTop,
+                                        pBlackBarCropRect->nWidth, pBlackBarCropRect->nHeight);
+
+    /** Send Port Settings changed call back **/
+    (*(pExynosComponent->pCallbacks->EventHandler))
+        (pOMXComponent,
+         pExynosComponent->callbackData,
+         OMX_EventPortSettingsChanged, /* The command was completed */
+         OMX_DirOutput, /* This is the port index */
+         (OMX_INDEXTYPE)OMX_IndexConfigBlackBarCrop,
+         NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HevcCodecCheckResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec           = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_EXCEPTION_STATE     eOutputExcepState  = pOutputPort->exceptionFlag;
+
+    ExynosVideoDecOps             *pDecOps            = pHevcDec->hMFCHevcHandle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pHevcDec->hMFCHevcHandle.pOutbufOps;
+    ExynosVideoGeometry            codecOutbufConf;
+
+    OMX_CONFIG_RECTTYPE          *pCropRectangle        = &(pOutputPort->cropRectangle);
+    OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition  = &(pInputPort->portDefinition);
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = &(pOutputPort->portDefinition);
+
+    int maxDPBNum = 0;
+
+    FunctionIn();
+
+    /* get geometry for output */
+    Exynos_OSAL_Memset(&codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry");
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        maxDPBNum += EXTRA_DPB_NUM;
+
+    pCropRectangle->nTop     = codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = codecOutbufConf.cropRect.nHeight;
+
+    /* resolution is changed */
+    if ((codecOutbufConf.nFrameWidth != pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth) ||
+        (codecOutbufConf.nFrameHeight != pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight) ||
+        (codecOutbufConf.nStride != pHevcDec->hMFCHevcHandle.codecOutbufConf.nStride) ||
+#if 0  // TODO: check posibility
+        (codecOutbufConf.eColorFormat != pHevcDec->hMFCHevcHandle.codecOutbufConf.eColorFormat) ||
+        (codecOutbufConf.eFilledDataType != pHevcDec->hMFCHevcHandle.codecOutbufConf.eFilledDataType) ||
+#endif
+        (maxDPBNum != pHevcDec->hMFCHevcHandle.maxDPBNum)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth,
+                            pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight,
+                            codecOutbufConf.nFrameWidth,
+                            codecOutbufConf.nFrameHeight);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] DPB(%d), FORMAT(0x%x), TYPE(0x%x) -> DPB(%d), FORMAT(0x%x), TYPE(0x%x)",
+                            pExynosComponent, __FUNCTION__,
+                            pHevcDec->hMFCHevcHandle.maxDPBNum,
+                            pHevcDec->hMFCHevcHandle.codecOutbufConf.eColorFormat,
+                            pHevcDec->hMFCHevcHandle.codecOutbufConf.eFilledDataType,
+                            maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType);
+
+        pInputPortDefinition->format.video.nFrameWidth     = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight    = codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride         = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight    = codecOutbufConf.nFrameHeight;
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            pOutputPortDefinition->nBufferCountActual  = maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin     = maxDPBNum;
+        }
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        if (eOutputExcepState == GENERAL_STATE) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* crop info of contents is changed */
+    if ((codecOutbufConf.cropRect.nTop != pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nTop) ||
+        (codecOutbufConf.cropRect.nLeft != pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nLeft) ||
+        (codecOutbufConf.cropRect.nWidth != pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nWidth) ||
+        (codecOutbufConf.cropRect.nHeight != pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nHeight)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nWidth,
+                            pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nHeight,
+                            codecOutbufConf.cropRect.nWidth,
+                            codecOutbufConf.cropRect.nHeight);
+
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    Exynos_OSAL_Memcpy(&pHevcDec->hMFCHevcHandle.codecOutbufConf, &codecOutbufConf, sizeof(codecOutbufConf));
+    pHevcDec->hMFCHevcHandle.maxDPBNum = maxDPBNum;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HevcCodecUpdateResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec           = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    ExynosVideoDecOps             *pDecOps            = pHevcDec->hMFCHevcHandle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pHevcDec->hMFCHevcHandle.pOutbufOps;
+    ExynosVideoErrorType           codecRet           = VIDEO_ERROR_NONE;
+
+    OMX_CONFIG_RECTTYPE          *pCropRectangle        = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition  = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = NULL;
+
+    FunctionIn();
+
+    /* get geometry for output */
+    Exynos_OSAL_Memset(&pHevcDec->hMFCHevcHandle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    codecRet = pOutbufOps->Get_Geometry(hMFCHandle, &pHevcDec->hMFCHevcHandle.codecOutbufConf);
+    if (codecRet ==  VIDEO_ERROR_HEADERINFO) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] parsed header info has only VPS", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorNeedNextHeaderInfo;
+        goto EXIT;
+    } else if (codecRet != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get geometry about output", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedHeader;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    pHevcDec->hMFCHevcHandle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        pHevcDec->hMFCHevcHandle.maxDPBNum += EXTRA_DPB_NUM;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] maxDPBNum: %d", pExynosComponent, __FUNCTION__, pHevcDec->hMFCHevcHandle.maxDPBNum);
+
+    pCropRectangle          = &(pOutputPort->cropRectangle);
+    pInputPortDefinition    = &(pInputPort->portDefinition);
+    pOutputPortDefinition   = &(pOutputPort->portDefinition);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] past info: width(%d) height(%d)",
+                                            pExynosComponent, __FUNCTION__,
+                                            pInputPortDefinition->format.video.nFrameWidth,
+                                            pInputPortDefinition->format.video.nFrameHeight);
+
+    if (pHevcDec->hMFCHevcHandle.codecOutbufConf.eFilledDataType & DATA_10BIT) {
+        if (pHevcDec->hMFCHevcHandle.MFCOutputColorType != pHevcDec->hMFCHevcHandle.codecOutbufConf.eColorFormat) {
+            OMX_COLOR_FORMATTYPE eOutputFormat = Exynos_OSAL_Video2OMXFormat(pHevcDec->hMFCHevcHandle.codecOutbufConf.eColorFormat);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] The format(%x) is changed to %x by H/W Codec",
+                                        pExynosComponent, __FUNCTION__,
+                                        pHevcDec->hMFCHevcHandle.MFCOutputColorType,
+                                        pHevcDec->hMFCHevcHandle.codecOutbufConf.eColorFormat);
+
+            pHevcDec->hMFCHevcHandle.MFCOutputColorType = pHevcDec->hMFCHevcHandle.codecOutbufConf.eColorFormat;
+            Exynos_SetPlaneToPort(pOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pOutputPort->ePlaneType));
+        }
+
+        if (pHevcDec->hMFCHevcHandle.codecOutbufConf.eFilledDataType == DATA_8BIT_WITH_2BIT)
+            pVideoDec->eDataType = DATA_TYPE_8BIT_WITH_2BIT;
+        else
+            pVideoDec->eDataType = DATA_TYPE_10BIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] resolution info: width(%d / %d), height(%d / %d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth,
+                                        pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nWidth,
+                                        pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight,
+                                        pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nHeight);
+
+    pCropRectangle->nTop     = pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nHeight;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pVideoDec->eDataType & DATA_TYPE_10BIT) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth   = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight  = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride       = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight  = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight;
+#if 0
+            /* don't need to change */
+            pOutputPortDefinition->nBufferCountActual  = pOutputPort->portDefinition.nBufferCountActual;
+            pOutputPortDefinition->nBufferCountMin     = pOutputPort->portDefinition.nBufferCountMin;
+#endif
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pVideoDec->eDataType & DATA_TYPE_10BIT) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight) ||
+            ((OMX_S32)pOutputPortDefinition->nBufferCountActual != pHevcDec->hMFCHevcHandle.maxDPBNum)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth   = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight  = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride       = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight  = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight;
+
+            pOutputPortDefinition->nBufferCountActual    = pHevcDec->hMFCHevcHandle.maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin       = pHevcDec->hMFCHevcHandle.maxDPBNum;
+
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* contents has crop info */
+    if ((pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth != pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nWidth) ||
+        (pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight != pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nHeight)) {
+        pInputPortDefinition->format.video.nFrameWidth     = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight    = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride         = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight    = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight;
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged) with crop",
+                                                pExynosComponent, __FUNCTION__);
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+        INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+        Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HevcCodecSrcSetup(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec          = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+    OMX_COLOR_FORMATTYPE           eOutputFormat     = pExynosOutputPort->portDefinition.format.video.eColorFormat;
+
+    EXYNOS_OMX_VIDEO_HDRSTATICINFO  *pHDRStaticInfo  = &(pExynosOutputPort->HDRStaticInfo);
+    EXYNOS_OMX_VIDEO_COLORASPECTS   *pFWCA           = &(pExynosOutputPort->ColorAspects);
+    EXYNOS_OMX_VIDEO_COLORASPECTS   *pBSCA           = &(pExynosInputPort->ColorAspects);
+
+    ExynosVideoDecOps       *pDecOps    = pHevcDec->hMFCHevcHandle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps  = pHevcDec->hMFCHevcHandle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pHevcDec->hMFCHevcHandle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_U32  nInBufferCnt   = 0;
+    OMX_BOOL bSupportFormat = OMX_FALSE;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pHevcDec->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pHevcDec->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pHevcDec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pVideoDec->bThumbnailMode == OMX_TRUE)
+        pDecOps->Set_IFrameDecoding(hMFCHandle);
+    else if ((IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) &&
+             (pHevcDec->hMFCHevcHandle.nDisplayDelay <= MAX_HEVC_DISPLAYDELAY_VALIDNUM)) {
+        pDecOps->Set_DisplayDelay(hMFCHandle, (int)pHevcDec->hMFCHevcHandle.nDisplayDelay);
+    }
+
+    if ((pDecOps->Enable_DTSMode != NULL) &&
+        (pVideoDec->bDTSMode == OMX_TRUE))
+        pDecOps->Enable_DTSMode(hMFCHandle);
+
+    /* input buffer info */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eCompressionFormat = VIDEO_CODING_HEVC;
+    pInbufOps->Set_Shareable(hMFCHandle);
+
+
+    nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        /* OMX buffer is not used directly : CODEC buffer */
+        nAllocLen[0] = pSrcInputData->allocSize;
+    }
+
+    bufferConf.nSizeImage = nAllocLen[0];
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+    nInBufferCnt = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    /* should be done before prepare input buffer */
+    if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set output geometry */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+    bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] omx format(0x%x) is %s by h/w",
+                                            pExynosComponent, __FUNCTION__, eOutputFormat,
+                                            (bSupportFormat == OMX_TRUE)? "supported":"not supported");
+    if (bSupportFormat == OMX_TRUE) {  /* supported by H/W */
+        bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eOutputFormat, pExynosOutputPort->ePlaneType);
+        Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pExynosOutputPort->ePlaneType));
+    } else {
+        OMX_COLOR_FORMATTYPE eCheckFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+        bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+
+        if (bSupportFormat == OMX_TRUE) {  /* supported by CSC(NV12 -> format) */
+            bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eCheckFormat, pExynosOutputPort->ePlaneType);
+            Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eCheckFormat, pExynosOutputPort->ePlaneType));
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not support this format (0x%x)", pExynosComponent, __FUNCTION__, eOutputFormat);
+            ret = OMX_ErrorNotImplemented;
+            pInbufOps->Cleanup_Buffer(hMFCHandle);
+            goto EXIT;
+        }
+    }
+
+    pHevcDec->hMFCHevcHandle.MFCOutputColorType = bufferConf.eColorFormat;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output video format is 0x%x",
+                                            pExynosComponent, __FUNCTION__, bufferConf.eColorFormat);
+
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    if (pVideoDec->bReorderMode == OMX_TRUE)
+        Exynos_SetReorderTimestamp(pExynosComponent, &(pHevcDec->hMFCHevcHandle.indexTimestamp), pSrcInputData->timeStamp, pSrcInputData->nFlags);
+
+    /* input buffer enqueue for header parsing */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+
+    if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pSrcInputData->buffer.addr,
+                            (unsigned long *)pSrcInputData->buffer.fd,
+                            nAllocLen,
+                            nDataLen,
+                            Exynos_GetPlaneFromPort(pExynosInputPort),
+                            pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enqueue input buffer for header parsing", pExynosComponent, __FUNCTION__);
+//        ret = OMX_ErrorInsufficientResources;
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc = OMX_TRUE;
+
+    /* start header parsing */
+    if (HevcCodecStart(pOMXComponent, INPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run input buffer for header parsing", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    ret = HevcCodecUpdateResolution(pOMXComponent);
+    if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+        (pExynosComponent->codecType != HW_VIDEO_DEC_SECURE_CODEC) &&
+        (oneFrameSize >= 8)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...", pExynosComponent, __FUNCTION__,
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0])    , *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 1),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 2), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 3),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 4), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 5),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 6), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 7));
+    }
+
+    if (ret != OMX_ErrorNone) {
+        HevcCodecStop(pOMXComponent, INPUT_PORT_INDEX);
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc = OMX_FALSE;
+
+        if ((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorNeedNextHeaderInfo) {
+            if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+                EXYNOS_OMX_DATABUFFER directReturnUseBuffer;
+                Exynos_Shared_DataToBuffer(pExynosInputPort, &directReturnUseBuffer, pSrcInputData);
+                Exynos_InputBufferReturn(pOMXComponent, &directReturnUseBuffer);
+            } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+                OMX_PTR codecBuffer;
+                codecBuffer = pSrcInputData->pPrivate;
+                if (codecBuffer != NULL)
+                    Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
+            }
+        }
+
+        goto EXIT;
+    }
+
+    Exynos_OSAL_SleepMillisec(0);
+    /*  disable header info re-input scheme
+      ret = OMX_ErrorInputDataDecodeYet;
+      HevcCodecStop(pOMXComponent, INPUT_PORT_INDEX);
+    */
+    ret = (OMX_ERRORTYPE)OMX_ErrorNoneSrcSetupFinish;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HevcCodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec             = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort    = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecOps           *pDecOps    = pHevcDec->hMFCHevcHandle.pDecOps;
+    ExynosVideoDecBufferOps     *pOutbufOps = pHevcDec->hMFCHevcHandle.pOutbufOps;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nOutbufs, nPlaneCnt;
+
+    FunctionIn();
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++)
+        nAllocLen[i] = pHevcDec->hMFCHevcHandle.codecOutbufConf.nAlignPlaneSize[i];
+
+    HevcCodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    /* for adaptive playback */
+    if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enable Dynamic DPB", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare output buffer */
+        if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        /* get dpb count */
+        nOutbufs = pHevcDec->hMFCHevcHandle.maxDPBNum;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        /* Enqueue output buffer */
+        for (i = 0; i < nOutbufs; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+                            (unsigned long *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+                            pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+                            nDataLen,
+                            nPlaneCnt,
+                            NULL);
+        }
+
+        pHevcDec->hMFCHevcHandle.bConfiguredMFCDst = OMX_TRUE;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* get dpb count */
+        nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+        if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pExynosOutputPort->eMetaDataType == METADATA_TYPE_DISABLED) {
+            /*************/
+            /*    TBD    */
+            /*************/
+            /* data buffer : user buffer
+             * H/W can't accept user buffer directly
+             */
+            ret = OMX_ErrorNotImplemented;
+            goto EXIT;
+        }
+
+        pHevcDec->hMFCHevcHandle.bConfiguredMFCDst = OMX_TRUE;
+    }
+
+    if (HevcCodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoHevc:
+    {
+        OMX_VIDEO_PARAM_HEVCTYPE *pDstHevcComponent = (OMX_VIDEO_PARAM_HEVCTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_HEVCTYPE *pSrcHevcComponent = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstHevcComponent, sizeof(OMX_VIDEO_PARAM_HEVCTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstHevcComponent->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcHevcComponent = &pHevcDec->HevcComponent[pDstHevcComponent->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstHevcComponent) + nOffset,
+                           ((char *)pSrcHevcComponent) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_HEVCTYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_HEVC_DEC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel  = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_HEVCTYPE         *pSrcHevcComponent = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcHevcComponent = &pHevcDec->HevcComponent[pDstProfileLevel->nPortIndex];
+
+        pDstProfileLevel->eProfile = pSrcHevcComponent->eProfile;
+        pDstProfileLevel->eLevel = pSrcHevcComponent->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pHevcDec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC                 = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync              = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing      = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning    = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC                = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexExynosParamDisplayDelay:  /* MSRND */
+    {
+        OMX_PARAM_U32TYPE       *pDisplayDelay  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+        EXYNOS_HEVCDEC_HANDLE   *pHevcDec       = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDisplayDelay, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+
+        if (pDisplayDelay->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+        pDisplayDelay->nU32 = pHevcDec->hMFCHevcHandle.nDisplayDelay;
+    }
+        break;
+    case OMX_IndexExynosParamReorderMode:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *pReorderParam = (EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pReorderParam, sizeof(EXYNOS_OMX_VIDEO_PARAM_REORDERMODE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pReorderParam->bReorderMode = pVideoDec->bReorderMode;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoHevc:
+    {
+        OMX_VIDEO_PARAM_HEVCTYPE *pDstHevcComponent = NULL;
+        OMX_VIDEO_PARAM_HEVCTYPE *pSrcHevcComponent = (OMX_VIDEO_PARAM_HEVCTYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcHevcComponent, sizeof(OMX_VIDEO_PARAM_HEVCTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcHevcComponent->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstHevcComponent = &pHevcDec->HevcComponent[pSrcHevcComponent->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstHevcComponent) + nOffset,
+                           ((char *)pSrcHevcComponent) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_HEVCTYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_HEVC_DEC_ROLE)) {
+            pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)OMX_VIDEO_CodingHEVC;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel  = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_HEVCTYPE         *pDstHevcComponent = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstHevcComponent = &pHevcDec->HevcComponent[pSrcProfileLevel->nPortIndex];
+
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pDstHevcComponent->eProfile = pSrcProfileLevel->eProfile;
+        pDstHevcComponent->eLevel   = pSrcProfileLevel->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pHevcDec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC                 = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync              = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing      = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning    = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC                = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexExynosParamDisplayDelay:  /* MSRND */
+    {
+        OMX_PARAM_U32TYPE       *pDisplayDelay  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+        EXYNOS_HEVCDEC_HANDLE   *pHevcDec       = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDisplayDelay, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+
+        if (pDisplayDelay->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+        if (pDisplayDelay->nU32 > MAX_HEVC_DISPLAYDELAY_VALIDNUM) {
+            ret = OMX_ErrorBadParameter;
+            break;
+        }
+
+        pHevcDec->hMFCHevcHandle.nDisplayDelay = pDisplayDelay->nU32;
+    }
+        break;
+    case OMX_IndexExynosParamReorderMode:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *pReorderParam = (EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pReorderParam, sizeof(EXYNOS_OMX_VIDEO_PARAM_REORDERMODE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pVideoDec->bReorderMode = pReorderParam->bReorderMode;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_GetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigCommonOutputCrop:
+    {
+        EXYNOS_OMX_BASEPORT *pExynosPort  = NULL;
+        OMX_CONFIG_RECTTYPE *pSrcRectType = NULL;
+        OMX_CONFIG_RECTTYPE *pDstRectType = NULL;
+
+        if (pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc == OMX_FALSE) {
+            ret = OMX_ErrorNotReady;
+            break;
+        }
+
+        pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
+
+        if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) &&
+            (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex];
+
+        pSrcRectType = &(pExynosPort->cropRectangle);
+
+        pDstRectType->nTop    = pSrcRectType->nTop;
+        pDstRectType->nLeft   = pSrcRectType->nLeft;
+        pDstRectType->nHeight = pSrcRectType->nHeight;
+        pDstRectType->nWidth  = pSrcRectType->nWidth;
+    }
+        break;
+#ifdef USE_S3D_SUPPORT
+    case OMX_IndexVendorS3DMode:
+    {
+        OMX_U32 *pS3DMode = NULL;
+
+        pS3DMode = (OMX_U32 *)pComponentConfigStructure;
+        *pS3DMode = (OMX_U32) pHevcDec->hMFCHevcHandle.S3DFPArgmtType;
+    }
+        break;
+#endif
+    case OMX_IndexExynosConfigDisplayDelay:  /* MSRND */
+    {
+        (*((OMX_U32 *)pComponentConfigStructure)) = pHevcDec->hMFCHevcHandle.nDisplayDelay;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexConfigVideoHdrStaticInfo:
+    {
+        ret = Exynos_OSAL_GetConfig(hComponent, nIndex, pComponentConfigStructure);
+    }
+        break;
+#endif
+    default:
+        ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexExynosConfigDisplayDelay:  /* MSRND */
+    {
+        OMX_U32 nDisplayDelay = (*((OMX_U32 *)pComponentConfigStructure));
+
+        if (pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc == OMX_TRUE) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            break;
+        }
+
+        if (nDisplayDelay > MAX_HEVC_DISPLAYDELAY_VALIDNUM) {
+            ret = OMX_ErrorBadParameter;
+            break;
+        }
+
+        pHevcDec->hMFCHevcHandle.nDisplayDelay = nDisplayDelay;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexConfigVideoHdrStaticInfo:
+    {
+        ret = Exynos_OSAL_SetConfig(hComponent, nIndex, pComponentConfigStructure);
+    }
+        break;
+#endif
+    default:
+        ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_GetExtensionIndex(
+    OMX_IN  OMX_HANDLETYPE  hComponent,
+    OMX_IN  OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE  *pIndexType)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+
+#ifdef USE_S3D_SUPPORT
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_GET_S3D) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorS3DMode;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+#endif
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_REORDER_MODE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamReorderMode;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_HDR_STATIC_INFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigVideoHdrStaticInfo;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+#endif
+
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) {
+        if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_CONFIG_DISPLAY_DELAY) == 0) {
+            *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosConfigDisplayDelay;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_DISPLAY_DELAY) == 0) {
+            *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamDisplayDelay;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_ComponentRoleEnum(
+    OMX_HANDLETYPE hComponent,
+    OMX_U8        *cRole,
+    OMX_U32        nIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) || (cRole == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_HEVC_DEC_ROLE);
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorNoMore;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_HevcDec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec          = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    ExynosVideoInstInfo *pVideoInstInfo = &(pHevcDec->hMFCHevcHandle.videoInstInfo);
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+    int i;
+
+    FunctionIn();
+
+    pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc = OMX_FALSE;
+    pHevcDec->hMFCHevcHandle.bConfiguredMFCDst = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    pVideoDec->bDiscardCSDError = OMX_FALSE;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                             pExynosInputPort->portDefinition.format.video.nBitrate,
+                                                                                             pExynosInputPort->portDefinition.format.video.xFramerate);
+    pVideoInstInfo->nSize         = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth        = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight       = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate      = pExynosInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate    = pExynosInputPort->portDefinition.format.video.xFramerate;
+
+    /* HEVC Codec Open */
+    ret = HevcCodecOpen(pHevcDec, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+        nAllocLen[0] = ALIGN(pExynosInputPort->portDefinition.format.video.nFrameWidth *
+                             pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+        if (nAllocLen[0] < pVideoDec->nMinInBufSize)
+            nAllocLen[0] = pVideoDec->nMinInBufSize;
+
+        Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_SetPlaneToPort(pExynosOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pHevcDec->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pHevcDec->hSourceStartEvent);
+    pHevcDec->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pHevcDec->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pHevcDec->hDestinationOutStartEvent);
+
+    Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pHevcDec->hMFCHevcHandle.indexTimestamp = 0;
+    pHevcDec->hMFCHevcHandle.outputIndexTimestamp = 0;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pHevcDec->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) {
+        pVideoDec->csc_handle = csc_init(CSC_METHOD_HW);
+        csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2);
+        csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_MODE_DRM, 1);
+    } else {
+        pVideoDec->csc_handle = csc_init(csc_method);
+    }
+
+    if (pVideoDec->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    pVideoDec->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_HevcDec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec           = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    FunctionIn();
+
+    if (pVideoDec->csc_handle != NULL) {
+        csc_deinit(pVideoDec->csc_handle);
+        pVideoDec->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pHevcDec->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pHevcDec->hDestinationInStartEvent);
+    pHevcDec->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pHevcDec->hDestinationOutStartEvent);
+    pHevcDec->hDestinationOutStartEvent = NULL;
+    pHevcDec->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pHevcDec->hSourceStartEvent);
+    pHevcDec->hSourceStartEvent = NULL;
+    pHevcDec->bSourceStart = OMX_FALSE;
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
+        pExynosOutputPort->codecSemID = NULL;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
+        pExynosInputPort->codecSemID = NULL;
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+    HevcCodecClose(pHevcDec);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_SrcIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec          = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+
+    ExynosVideoDecOps       *pDecOps     = pHevcDec->hMFCHevcHandle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps   = pHevcDec->hMFCHevcHandle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_BOOL bInStartCode = OMX_FALSE;
+
+    FunctionIn();
+
+    if (pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = HevcCodecSrcSetup(pOMXComponent, pSrcInputData);
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (pHevcDec->bDestinationStart == OMX_FALSE) &&
+        (pHevcDec->hMFCHevcHandle.bConfiguredMFCDst == OMX_FALSE)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+        ret = HevcCodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to HevcCodecDstSetup(0x%x)",
+                                            pExynosComponent, __FUNCTION__, ret);
+            goto EXIT;
+        }
+    }
+
+    if (((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) ||
+           ((bInStartCode = Check_HEVC_StartCode(pSrcInputData->buffer.addr[0], oneFrameSize)) == OMX_TRUE)) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+        if (pVideoDec->bReorderMode == OMX_FALSE) {
+            /* next slot will be used like as circular queue */
+            pExynosComponent->timeStamp[pHevcDec->hMFCHevcHandle.indexTimestamp] = pSrcInputData->timeStamp;
+            pExynosComponent->nFlags[pHevcDec->hMFCHevcHandle.indexTimestamp]    = pSrcInputData->nFlags;
+        } else {  /* MSRND */
+            Exynos_SetReorderTimestamp(pExynosComponent, &(pHevcDec->hMFCHevcHandle.indexTimestamp), pSrcInputData->timeStamp, pSrcInputData->nFlags);
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), dataLen(%d), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, oneFrameSize, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pHevcDec->hMFCHevcHandle.indexTimestamp);
+
+        pDecOps->Set_FrameTag(hMFCHandle, pHevcDec->hMFCHevcHandle.indexTimestamp);
+        pHevcDec->hMFCHevcHandle.indexTimestamp++;
+        pHevcDec->hMFCHevcHandle.indexTimestamp %= MAX_TIMESTAMP;
+
+        if ((pVideoDec->bQosChanged == OMX_TRUE) &&
+            (pDecOps->Set_QosRatio != NULL)) {
+            pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
+            pVideoDec->bQosChanged = OMX_FALSE;
+        }
+
+         if (pVideoDec->bSearchBlackBarChanged == OMX_TRUE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] BlackBar searching mode : %s",
+                                            pExynosComponent, __FUNCTION__,
+                                            (pVideoDec->bSearchBlackBar == OMX_TRUE) ? "enable" : "disable");
+            pDecOps->Set_SearchBlackBar(hMFCHandle, (ExynosVideoBoolType)pVideoDec->bSearchBlackBar);
+            pVideoDec->bSearchBlackBarChanged = OMX_FALSE;
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        /* queue work for input buffer */
+        nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+        if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        } else {
+            nAllocLen[0] = pSrcInputData->allocSize;
+
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        }
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pSrcInputData->buffer.addr,
+                                (unsigned long *)pSrcInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pExynosInputPort),
+                                pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            goto EXIT;
+        }
+
+        HevcCodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        if (pHevcDec->bSourceStart == OMX_FALSE) {
+            pHevcDec->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pHevcDec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        if ((pHevcDec->bDestinationStart == OMX_FALSE) &&
+            (pHevcDec->hMFCHevcHandle.bConfiguredMFCDst == OMX_TRUE)) {
+            pHevcDec->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pHevcDec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pHevcDec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    } else if (bInStartCode == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] can't find a start code", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedFrame;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_SrcOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec         = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle       = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pInbufOps      = pHevcDec->hMFCHevcHandle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->allocSize  = 0;
+        pSrcOutputData->pPrivate = NULL;
+    } else {
+        pSrcOutputData->buffer.addr[0] = pVideoBuffer->planes[0].addr;
+        pSrcOutputData->buffer.fd[0] = pVideoBuffer->planes[0].fd;
+        pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
+
+        if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] ==
+                        pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
+                    pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pExynosInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_DstIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec           = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pOutbufOps  = pHevcDec->hMFCHevcHandle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++) {
+        nAllocLen[i] = pHevcDec->hMFCHevcHandle.codecOutbufConf.nAlignPlaneSize[i];
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] ADDR[%d]: 0x%x, size[%d]: %d", pExynosComponent, __FUNCTION__,
+                                        i, pDstInputData->buffer.addr[i], i, nAllocLen[i]);
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                nPlaneCnt,
+                                pDstInputData->bufferHeader);
+
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+        }
+
+        goto EXIT;
+    }
+
+    HevcCodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_DstOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE         *pHevcDec          = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pHevcDec->hMFCHevcHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort       = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo       = NULL;
+
+    ExynosVideoDecOps           *pDecOps        = pHevcDec->hMFCHevcHandle.pDecOps;
+    ExynosVideoDecBufferOps     *pOutbufOps     = pHevcDec->hMFCHevcHandle.pOutbufOps;
+    ExynosVideoBuffer           *pVideoBuffer   = NULL;
+    ExynosVideoBuffer            videoBuffer;
+    ExynosVideoFrameStatusType   displayStatus  = VIDEO_FRAME_STATUS_UNKNOWN;
+    ExynosVideoGeometry         *bufferGeometry = NULL;
+    ExynosVideoErrorType         codecReturn    = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+
+    OMX_S32 indexTimestamp = 0;
+    int plane, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pHevcDec->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    while (1) {
+        Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer));
+
+        codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+        if (codecReturn == VIDEO_ERROR_NONE) {
+            pVideoBuffer = &videoBuffer;
+        } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO) at ExtensionDequeue", pExynosComponent, __FUNCTION__);
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorHardware;
+            goto EXIT;
+        } else {
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        displayStatus = pVideoBuffer->displayStatus;
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus: 0x%x", pExynosComponent, __FUNCTION__, displayStatus);
+
+        if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
+            (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+            (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D) ||
+            (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+            (CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+            ret = OMX_ErrorNone;
+            break;
+        }
+    }
+
+#ifdef USE_S3D_SUPPORT
+    /* Check Whether frame packing information is available */
+    if ((pHevcDec->hMFCHevcHandle.S3DFPArgmtType == OMX_SEC_FPARGMT_INVALID) &&
+        (pVideoDec->bThumbnailMode == OMX_FALSE) &&
+        ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
+         (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
+         (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D))) {
+        if (HevcCodecCheckFramePacking(pOMXComponent) != OMX_TRUE) {
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            goto EXIT;
+        }
+    }
+#endif
+
+    if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+        ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+         (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D))) {
+        if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+            pOutputPort->exceptionFlag = NEED_PORT_FLUSH;
+            pVideoDec->bReconfigDPB = OMX_TRUE;
+            HevcCodecUpdateResolution(pOMXComponent);
+            pVideoDec->csc_set_format = OMX_FALSE;
+#ifdef USE_S3D_SUPPORT
+            pHevcDec->hMFCHevcHandle.S3DFPArgmtType = OMX_SEC_FPARGMT_INVALID;
+#endif
+        }
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pHevcDec->hMFCHevcHandle.outputIndexTimestamp++;
+    pHevcDec->hMFCHevcHandle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+    pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
+    nPlaneCnt = Exynos_GetPlaneFromPort(pOutputPort);
+    for (plane = 0; plane < nPlaneCnt; plane++) {
+        pDstOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+        pDstOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+        pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        pDstOutputData->dataLen   += pVideoBuffer->planes[plane].dataSize;
+        nDataLen[plane]            = pVideoBuffer->planes[plane].dataSize;
+    }
+    pDstOutputData->usedDataLen = 0;
+    pDstOutputData->pPrivate = pVideoBuffer;
+
+    pBufferInfo     = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+    bufferGeometry  = &pHevcDec->hMFCHevcHandle.codecOutbufConf;
+    pBufferInfo->imageWidth       = bufferGeometry->nFrameWidth;
+    pBufferInfo->imageHeight      = bufferGeometry->nFrameHeight;
+    pBufferInfo->imageStride      = bufferGeometry->nStride;
+    pBufferInfo->cropRect.nLeft   = bufferGeometry->cropRect.nLeft;
+    pBufferInfo->cropRect.nTop    = bufferGeometry->cropRect.nTop;
+    pBufferInfo->cropRect.nWidth  = bufferGeometry->cropRect.nWidth;
+    pBufferInfo->cropRect.nHeight = bufferGeometry->cropRect.nHeight;
+    pBufferInfo->colorFormat      = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+    Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            goto EXIT;
+        }
+
+        /* calculate each plane info for the application */
+        Exynos_OSAL_GetPlaneSize(pOutputPort->portDefinition.format.video.eColorFormat,
+                                 PLANE_SINGLE, pOutputPort->portDefinition.format.video.nFrameWidth,
+                                 pOutputPort->portDefinition.format.video.nFrameHeight,
+                                 nDataLen, nAllocLen);
+
+        pDstOutputData->allocSize = nAllocLen[0] + nAllocLen[1] + nAllocLen[2];
+        pDstOutputData->dataLen   = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+#ifdef USE_ANDROID
+    /* get HDR info */
+    if ((pOutputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pVideoBuffer->planes[2].addr != NULL)) {
+        ExynosVideoMeta *pMeta = (ExynosVideoMeta *)pVideoBuffer->planes[2].addr;
+
+        pMeta->eType = VIDEO_INFO_TYPE_INVALID;
+
+        if (pVideoBuffer->frameType & VIDEO_FRAME_WITH_HDR_INFO)
+            HevcCodecUpdateHdrInfo(pOMXComponent, pMeta);
+    }
+#endif
+
+    indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+    if (pVideoDec->bReorderMode == OMX_FALSE) {
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
+                (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
+                if (indexTimestamp == INDEX_AFTER_EOS) {
+                    pDstOutputData->timeStamp = 0x00;
+                    pDstOutputData->nFlags = 0x00;
+                } else {
+                    pDstOutputData->timeStamp = pExynosComponent->timeStamp[pHevcDec->hMFCHevcHandle.outputIndexTimestamp];
+                    pDstOutputData->nFlags = pExynosComponent->nFlags[pHevcDec->hMFCHevcHandle.outputIndexTimestamp];
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] missing out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+                }
+            } else {
+                pDstOutputData->timeStamp = 0x00;
+                pDstOutputData->nFlags = 0x00;
+            }
+        } else {
+            /* For timestamp correction. if mfc support frametype detect */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] disp_pic_frame_type: %d", pExynosComponent, __FUNCTION__, pVideoBuffer->frameType);
+
+            /* NEED TIMESTAMP REORDER */
+            if (pVideoDec->bDTSMode == OMX_TRUE) {
+                if ((pVideoBuffer->frameType & VIDEO_FRAME_I) ||
+                    ((pVideoBuffer->frameType & VIDEO_FRAME_OTHERS) &&
+                        ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
+                    (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
+                   pHevcDec->hMFCHevcHandle.outputIndexTimestamp = indexTimestamp;
+                else
+                   indexTimestamp = pHevcDec->hMFCHevcHandle.outputIndexTimestamp;
+            }
+
+            pDstOutputData->timeStamp   = pExynosComponent->timeStamp[indexTimestamp];
+            pDstOutputData->nFlags      = pExynosComponent->nFlags[indexTimestamp] | OMX_BUFFERFLAG_ENDOFFRAME;
+
+            if (pVideoBuffer->frameType & VIDEO_FRAME_I)
+                pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+            if (pVideoBuffer->frameType & VIDEO_FRAME_CORRUPT)
+                pDstOutputData->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                                    pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                                    indexTimestamp);
+    } else {  /* MSRND */
+        EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP sCurrentTimestamp;
+
+        Exynos_GetReorderTimestamp(pExynosComponent, &sCurrentTimestamp, indexTimestamp, pVideoBuffer->frameType);
+
+        pDstOutputData->timeStamp   = sCurrentTimestamp.timeStamp;
+        pDstOutputData->nFlags      = sCurrentTimestamp.nFlags | OMX_BUFFERFLAG_ENDOFFRAME;
+
+        pExynosComponent->nFlags[sCurrentTimestamp.nIndex]               = 0x00;
+        pExynosComponent->bTimestampSlotUsed[sCurrentTimestamp.nIndex]   = OMX_FALSE;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), reordered tag: %d, original tag: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                                    pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                                    sCurrentTimestamp.nIndex,
+                                                    indexTimestamp);
+    }
+
+    if (pVideoBuffer->frameType & VIDEO_FRAME_WITH_BLACK_BAR) {
+        if (HevcCodecUpdateBlackBarCrop(pOMXComponent) != OMX_ErrorNone)
+            goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) != OMX_TRUE) {
+        if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+            (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+        }
+    }
+
+    if (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) {
+        pDstOutputData->remainDataLen = 0;
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            if (indexTimestamp != INDEX_AFTER_EOS)
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] tag(%d) is wrong", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+            pDstOutputData->timeStamp   = 0x00;
+            pDstOutputData->nFlags      = 0x00;
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) ||
+            (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+            pExynosComponent->nFlags[indexTimestamp] &= (~OMX_BUFFERFLAG_EOS);
+        }
+    } else if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        pDstOutputData->remainDataLen = 0;
+
+        if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
+            pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+
+            if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) != OMX_TRUE) {
+                if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+                    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+                } else {
+                    pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+                    pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+                }
+            } else {
+                pExynosComponent->bBehaviorEOS = OMX_FALSE;
+            }
+        }
+    } else {
+        pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_srcInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_HevcDec_SrcIn(pOMXComponent, pSrcInputData);
+    if ((ret != OMX_ErrorNone) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorNeedNextHeaderInfo) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorNoneSrcSetupFinish) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorCorruptedFrame)) {
+
+        if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+            (pVideoDec->bDiscardCSDError == OMX_TRUE)) {
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_srcOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec           = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+    if ((pHevcDec->bSourceStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
+        Exynos_OSAL_SignalWait(pHevcDec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pHevcDec->hSourceStartEvent);
+    }
+
+    ret = Exynos_HevcDec_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_dstInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec          = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        if (pExynosComponent->currentState == OMX_StatePause)
+            ret = (OMX_ERRORTYPE)OMX_ErrorOutputBufferUseYet;
+        else
+            ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pHevcDec->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pHevcDec->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pHevcDec->hDestinationInStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pHevcDec->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pHevcDec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+            (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+            ret = HevcCodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to HevcCodecDstSetup(0x%x)", pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+            Exynos_OSAL_SignalSet(pHevcDec->hDestinationOutStartEvent);
+        }
+    }
+
+    if (pHevcDec->hMFCHevcHandle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_HevcDec_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HevcDec_dstOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec          = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (((pHevcDec->bDestinationStart == OMX_FALSE) ||
+         (pHevcDec->hMFCHevcHandle.bConfiguredMFCDst == OMX_FALSE)) &&
+        (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pHevcDec->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pHevcDec->hDestinationOutStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pHevcDec->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pHevcDec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_HevcDec_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE  hComponent,
+    OMX_STRING      componentName)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec           = NULL;
+    OMX_BOOL                         bSecureMode        = OMX_FALSE;
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) || (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_HEVC_DEC, componentName) == 0) {
+        bSecureMode = OMX_FALSE;
+    } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_HEVC_DRM_DEC, componentName) == 0) {
+        bSecureMode = OMX_TRUE;
+    } else {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = (bSecureMode == OMX_TRUE)? HW_VIDEO_DEC_SECURE_CODEC:HW_VIDEO_DEC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pHevcDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_HEVCDEC_HANDLE));
+    if (pHevcDec == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pHevcDec, 0, sizeof(EXYNOS_HEVCDEC_HANDLE));
+    pVideoDec               = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pHevcDec;
+    pHevcDec->hMFCHevcHandle.nDisplayDelay = MAX_HEVC_DISPLAYDELAY_VALIDNUM + 1;
+
+    Exynos_OSAL_Strcpy(pExynosComponent->componentName, componentName);
+
+#ifdef USE_S3D_SUPPORT
+    pHevcDec->hMFCHevcHandle.S3DFPArgmtType = OMX_SEC_FPARGMT_INVALID;
+#endif
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth  = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride      = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE)
+        pExynosPort->portDefinition.nBufferSize = CUSTOM_DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+
+    pVideoDec->nMinInBufSize = DEFAULT_VIDEO_MIN_INPUT_BUFFER_SIZE;  /* for DRC */
+
+    pExynosPort->portDefinition.format.video.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)OMX_VIDEO_CodingHEVC;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/hevc");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth  = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride      = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+#ifdef USE_SINGLE_PLANE_IN_DRM
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        pExynosPort->ePlaneType = PLANE_SINGLE;
+#endif
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pHevcDec->HevcComponent[i], OMX_VIDEO_PARAM_HEVCTYPE);
+        pHevcDec->HevcComponent[i].nPortIndex = i;
+        pHevcDec->HevcComponent[i].eProfile   = OMX_VIDEO_HEVCProfileMain;
+        pHevcDec->HevcComponent[i].eLevel     = OMX_VIDEO_HEVCMainTierLevel5;
+    }
+
+    pOMXComponent->GetParameter      = &Exynos_HevcDec_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_HevcDec_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_HevcDec_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_HevcDec_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_HevcDec_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_HevcDec_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_HevcDec_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_HevcDec_Terminate;
+
+    pVideoDec->exynos_codec_srcInputProcess  = &Exynos_HevcDec_srcInputBufferProcess;
+    pVideoDec->exynos_codec_srcOutputProcess = &Exynos_HevcDec_srcOutputBufferProcess;
+    pVideoDec->exynos_codec_dstInputProcess  = &Exynos_HevcDec_dstInputBufferProcess;
+    pVideoDec->exynos_codec_dstOutputProcess = &Exynos_HevcDec_dstOutputBufferProcess;
+
+    pVideoDec->exynos_codec_start            = &HevcCodecStart;
+    pVideoDec->exynos_codec_stop             = &HevcCodecStop;
+    pVideoDec->exynos_codec_bufferProcessRun = &HevcCodecOutputBufferProcessRun;
+    pVideoDec->exynos_codec_enqueueAllBuffer = &HevcCodecEnQueueAllBuffer;
+
+    pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+    pVideoDec->exynos_codec_reconfigAllBuffers        = &HevcCodecReconfigAllBuffers;
+
+    pVideoDec->exynos_codec_checkFormatSupport      = &CheckFormatHWSupport;
+    pVideoDec->exynos_codec_checkResolutionChange   = &HevcCodecCheckResolution;
+
+    pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoDec->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pHevcDec);
+        pHevcDec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pHevcDec->hMFCHevcHandle.videoInstInfo.eCodecType = VIDEO_CODING_HEVC;
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        pHevcDec->hMFCHevcHandle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pHevcDec->hMFCHevcHandle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pHevcDec->hMFCHevcHandle.videoInstInfo), VIDEO_TRUE /* dec */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pHevcDec);
+        pHevcDec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for dec skype(%d)", pExynosComponent, __FUNCTION__,
+            (pHevcDec->hMFCHevcHandle.videoInstInfo.supportInfo.dec.bSkypeSupport));
+
+    Exynos_Output_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
+    OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_HEVCDEC_HANDLE           *pHevcDec           = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent    = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pHevcDec != NULL) {
+        Exynos_OSAL_Free(pHevcDec);
+        pHevcDec = pVideoDec->hCodecHandle = NULL;
+    }
+
+    ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/dec/hevc/Exynos_OMX_HEVCdec.h b/openmax/component/video/dec/hevc/Exynos_OMX_HEVCdec.h
new file mode 100755 (executable)
index 0000000..9757b35
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_HEVCdec.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2013.07.26 : Create
+ */
+
+#ifndef EXYNOS_OMX_HEVC_DEC_COMPONENT
+#define EXYNOS_OMX_HEVC_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+#include "ExynosVideoApi.h"
+
+
+typedef struct _EXYNOS_MFC_HEVCDEC_HANDLE
+{
+    OMX_HANDLETYPE             hMFCHandle;
+    OMX_U32                    indexTimestamp;
+    OMX_U32                    outputIndexTimestamp;
+    OMX_BOOL                   bConfiguredMFCSrc;
+    OMX_BOOL                   bConfiguredMFCDst;
+    OMX_S32                    maxDPBNum;
+
+    /* for custom component(MSRND) */
+    #define MAX_HEVC_DISPLAYDELAY_VALIDNUM 8
+    OMX_U32                    nDisplayDelay;
+
+#ifdef USE_S3D_SUPPORT
+    EXYNOS_OMX_FPARGMT_TYPE    S3DFPArgmtType;
+#endif
+
+    ExynosVideoColorFormatType MFCOutputColorType;
+    ExynosVideoDecOps         *pDecOps;
+    ExynosVideoDecBufferOps   *pInbufOps;
+    ExynosVideoDecBufferOps   *pOutbufOps;
+    ExynosVideoGeometry        codecOutbufConf;
+    ExynosVideoInstInfo        videoInstInfo;
+
+    #define MAX_PROFILE_NUM 3
+    OMX_VIDEO_HEVCPROFILETYPE   profiles[MAX_PROFILE_NUM];
+    OMX_S32                     nProfileCnt;
+    OMX_VIDEO_HEVCLEVELTYPE     maxLevel;
+} EXYNOS_MFC_HEVCDEC_HANDLE;
+
+typedef struct _EXYNOS_HEVCDEC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_HEVCTYPE HevcComponent[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+
+    /* EXYNOS MFC Codec specific */
+    EXYNOS_MFC_HEVCDEC_HANDLE            hMFCHevcHandle;
+
+    OMX_BOOL bSourceStart;
+    OMX_BOOL bDestinationStart;
+    OMX_HANDLETYPE hSourceStartEvent;
+    OMX_HANDLETYPE hDestinationInStartEvent;
+    OMX_HANDLETYPE hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE bypassBufferInfoQ;
+} EXYNOS_HEVCDEC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName);
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE HevcCodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/hevc/Makefile.am b/openmax/component/video/dec/hevc/Makefile.am
new file mode 100755 (executable)
index 0000000..3e17b31
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libOMX.Exynos.HEVC.Decoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_HEVC_Decoder_la_SOURCES = Exynos_OMX_HEVCdec.c \
+                                        library_register.c
+
+libOMX_Exynos_HEVC_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                       $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                       $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                       $(top_builddir)/openmax/component/video/dec/libExynosOMX_Vdec.la \
+                                       $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+libOMX_Exynos_HEVC_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                       -I$(top_srcdir)/openmax/include/exynos \
+                                       -I$(top_srcdir)/openmax/osal \
+                                       -I$(top_srcdir)/openmax/core \
+                                       -I$(top_srcdir)/openmax/component/common \
+                                       -I$(top_srcdir)/openmax/component/video/dec \
+                                       -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_HEVC_Decoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
+libOMX_Exynos_HEVC_Decoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable
+
+libOMX_Exynos_HEVC_Decoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/dec/hevc/library_register.c b/openmax/component/video/dec/hevc/library_register.c
new file mode 100755 (executable)
index 0000000..b2fe0ea
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       library_register.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2013.07.26 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_HEVC_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(
+    ExynosRegisterComponentType **ppExynosComponent)
+{
+    FunctionIn();
+
+    if (ppExynosComponent == NULL)
+        goto EXIT;
+
+    /* component 1 - video decoder HEVC */
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_HEVC_DEC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_HEVC_DEC_ROLE);
+    ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+    /* component 2 - video decoder HEVC for DRM */
+    Exynos_OSAL_Strcpy(ppExynosComponent[1]->componentName, EXYNOS_OMX_COMPONENT_HEVC_DRM_DEC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[1]->roles[0], EXYNOS_OMX_COMPONENT_HEVC_DEC_ROLE);
+    ppExynosComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
diff --git a/openmax/component/video/dec/hevc/library_register.h b/openmax/component/video/dec/hevc/library_register.h
new file mode 100755 (executable)
index 0000000..5e3fed0
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2013.07.26 : Create
+ */
+
+#ifndef EXYNOS_OMX_HEVC_DEC_REG
+#define EXYNOS_OMX_HEVC_DEC_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM       2
+#define MAX_COMPONENT_ROLE_NUM  1
+
+/* HEVC */
+#ifndef USE_CUSTOM_COMPONENT_SUPPORT
+#define EXYNOS_OMX_COMPONENT_HEVC_DEC            "OMX.Exynos.HEVC.Decoder"
+#define EXYNOS_OMX_COMPONENT_HEVC_DRM_DEC        "OMX.Exynos.HEVC.Decoder.secure"
+#else
+#define EXYNOS_OMX_COMPONENT_HEVC_DEC            "OMX.Exynos.hevc.dec"
+#define EXYNOS_OMX_COMPONENT_HEVC_DRM_DEC        "OMX.Exynos.hevc.dec.secure"
+#endif
+
+#define EXYNOS_OMX_COMPONENT_HEVC_DEC_ROLE   "video_decoder.hevc"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.c
new file mode 100755 (executable)
index 0000000..4751b20
--- /dev/null
@@ -0,0 +1,3105 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Mpeg2dec.c
+ * @brief
+ * @author      Satish Kumar Reddy (palli.satish@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.07.10 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Vdec.h"
+#include "Exynos_OMX_VdecControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Mpeg2dec.h"
+#include "ExynosVideoApi.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+
+#ifdef USE_ANDROID
+#include "VendorVideoAPI.h"
+#endif
+
+/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
+/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_MPEG2_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec      = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg2Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg2Dec->hMFCMpeg2Handle.profiles[nProfileCnt++] = OMX_VIDEO_MPEG2ProfileSimple;
+    pMpeg2Dec->hMFCMpeg2Handle.profiles[nProfileCnt++] = OMX_VIDEO_MPEG2ProfileMain;
+    pMpeg2Dec->hMFCMpeg2Handle.nProfileCnt = nProfileCnt;
+    pMpeg2Dec->hMFCMpeg2Handle.maxLevel = OMX_VIDEO_MPEG2LevelHL;
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_MPEG2DEC_HANDLE           *pMpeg2Dec       = NULL;
+
+    int nLevelCnt = 0;
+    OMX_U32 nMaxIndex = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg2Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pMpeg2Dec->hMFCMpeg2Handle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pMpeg2Dec->hMFCMpeg2Handle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pMpeg2Dec->hMFCMpeg2Handle.maxLevel;
+#else
+    while ((pMpeg2Dec->hMFCMpeg2Handle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+    nLevelCnt += 1;  /* OMX_VIDEO_MPEG2LevelLL : 0 */
+
+    if ((pMpeg2Dec->hMFCMpeg2Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                        pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pMpeg2Dec->hMFCMpeg2Handle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pMpeg2Dec->hMFCMpeg2Handle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] supported profile(%x), level(%x)",
+                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec  = NULL;
+    EXYNOS_MPEG2DEC_HANDLE           *pMpeg2Dec   = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg2Dec == NULL)
+        goto EXIT;
+
+    while ((pMpeg2Dec->hMFCMpeg2Handle.maxLevel >> nLevelCnt++) > 0);
+    nLevelCnt += 1;  /* OMX_VIDEO_MPEG2LevelLL : 0 */
+
+    if ((pMpeg2Dec->hMFCMpeg2Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pMpeg2Dec->hMFCMpeg2Handle.nProfileCnt; i++) {
+        if (pMpeg2Dec->hMFCMpeg2Handle.profiles[i] == pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    if (pProfileLevelType->eLevel == OMX_VIDEO_MPEG2LevelLL) {
+        bLevelSupport = OMX_TRUE;
+    } else {
+        nLevelCnt--;
+        while (nLevelCnt >= 0) {
+            if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+                bLevelSupport = OMX_TRUE;
+                break;
+            }
+
+            nLevelCnt--;
+        }
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    FunctionOut();
+
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
+{
+    OMX_ERRORTYPE       ret          = OMX_ErrorNone;
+    ExynosVideoBuffer  *pCodecBuffer = NULL;
+
+    if (codecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
+
+    if (addr != NULL) {
+        addr[0] = pCodecBuffer->planes[0].addr;
+        addr[1] = pCodecBuffer->planes[1].addr;
+        addr[2] = pCodecBuffer->planes[2].addr;
+    }
+
+    if (size != NULL) {
+        size[0] = pCodecBuffer->planes[0].allocSize;
+        size[1] = pCodecBuffer->planes[1].allocSize;
+        size[2] = pCodecBuffer->planes[2].allocSize;
+    }
+
+EXIT:
+
+    return ret;
+}
+
+static OMX_BOOL Check_Mpeg2_StartCode(
+    OMX_U8     *pInputStream,
+    OMX_U32     streamSize)
+{
+    OMX_BOOL ret = OMX_FALSE;
+
+    FunctionIn();
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] streamSize: %d", __FUNCTION__, streamSize);
+
+    if (streamSize < 3) {
+        ret = OMX_FALSE;
+        goto EXIT;
+    }
+
+    /* Frame  Start code*/
+    if (pInputStream[0] != 0x00 || pInputStream[1] != 0x00 || pInputStream[2]!=0x01) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mpeg2 Frame Start Code not Found", __FUNCTION__);
+        ret = OMX_FALSE;
+        goto EXIT;
+    }
+
+    ret = OMX_TRUE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec      = NULL;
+    EXYNOS_OMX_BASEPORT             *pOutputPort    = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg2Dec == NULL)
+        goto EXIT;
+    pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pOutputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecOpen(EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec, ExynosVideoInstInfo *pVideoInstInfo)
+{
+    OMX_ERRORTYPE           ret = OMX_ErrorNone;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pMpeg2Dec == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pDecOps    = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
+    pInbufOps  = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+    pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+
+    if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pMpeg2Dec->hMFCMpeg2Handle.pDecOps    = pDecOps;
+    pMpeg2Dec->hMFCMpeg2Handle.pInbufOps  = pInbufOps;
+    pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pDecOps->nSize    = sizeof(ExynosVideoDecOps);
+    pInbufOps->nSize  = sizeof(ExynosVideoDecBufferOps);
+    pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
+
+    if (Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for decoder ops */
+    if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
+        (pDecOps->Get_ActualBufferCount == NULL) ||
+        (pDecOps->Set_FrameTag == NULL) || (pDecOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.pDecOps->Init(pVideoInstInfo);
+    if (pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pDecOps != NULL) {
+            Exynos_OSAL_Free(pDecOps);
+            pMpeg2Dec->hMFCMpeg2Handle.pDecOps = NULL;
+        }
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pMpeg2Dec->hMFCMpeg2Handle.pInbufOps = NULL;
+        }
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecClose(EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec)
+{
+    OMX_ERRORTYPE            ret = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pMpeg2Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+    pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+    pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pDecOps->Finalize(hMFCHandle);
+        pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle = NULL;
+        pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc = OMX_FALSE;
+        pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps = NULL;
+    }
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pMpeg2Dec->hMFCMpeg2Handle.pInbufOps = NULL;
+    }
+    if (pDecOps != NULL) {
+        Exynos_OSAL_Free(pDecOps);
+        pMpeg2Dec->hMFCMpeg2Handle.pDecOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg2Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+    pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc == OMX_TRUE)) {
+        pInbufOps->Run(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_TRUE)) {
+        pOutbufOps->Run(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg2Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+    pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) {
+        pInbufOps->Stop(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) {
+        EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+        pOutbufOps->Stop(hMFCHandle);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE)
+            pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg2Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pMpeg2Dec->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pMpeg2Dec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pMpeg2Dec->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecReconfigAllBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = &pExynosComponent->pExynosPort[nPortIndex];
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    ExynosVideoDecBufferOps         *pBufferOps         = NULL;
+
+    FunctionIn();
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pMpeg2Dec->bSourceStart == OMX_TRUE)) {
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pMpeg2Dec->bDestinationStart == OMX_TRUE)) {
+        pBufferOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+
+        if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+            /**********************************/
+            /* Codec Buffer Free & Unregister */
+            /**********************************/
+            Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+            Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_FALSE;
+
+            /******************************************************/
+            /* V4L2 Destnation Setup for DPB Buffer Number Change */
+            /******************************************************/
+            ret = Mpeg2CodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to Mpeg2CodecDstSetup(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+        } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+            /***************************/
+            /* Codec Buffer Unregister */
+            /***************************/
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_FALSE;
+        }
+    } else {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+
+    ExynosVideoDecBufferOps *pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+
+    int i;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecInputBuffer[i]->fd[0], pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecOutputBuffer[i]->fd[0], pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+        }
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecUpdateBlackBarCrop(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE        *pMpeg2Dec            = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    OMX_CONFIG_RECTTYPE           *pBlackBarCropRect    = &pVideoDec->blackBarCropRect;
+
+    ExynosVideoDecBufferOps  *pOutbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+    ExynosVideoRect           CropRect;
+
+    FunctionIn();
+
+    Exynos_OSAL_Memset(&CropRect, 0, sizeof(ExynosVideoRect));
+    if (pOutbufOps->Get_BlackBarCrop(hMFCHandle, &CropRect) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get crop info", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pBlackBarCropRect->nLeft   = CropRect.nLeft;
+    pBlackBarCropRect->nTop    = CropRect.nTop;
+    pBlackBarCropRect->nWidth  = CropRect.nWidth;
+    pBlackBarCropRect->nHeight = CropRect.nHeight;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Black Bar Info: LEFT(%d) TOP(%d) WIDTH(%d) HEIGHT(%d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pBlackBarCropRect->nLeft, pBlackBarCropRect->nTop,
+                                        pBlackBarCropRect->nWidth, pBlackBarCropRect->nHeight);
+
+    /** Send Port Settings changed call back **/
+    (*(pExynosComponent->pCallbacks->EventHandler))
+        (pOMXComponent,
+         pExynosComponent->callbackData,
+         OMX_EventPortSettingsChanged, /* The command was completed */
+         OMX_DirOutput, /* This is the port index */
+         (OMX_INDEXTYPE)OMX_IndexConfigBlackBarCrop,
+         NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecCheckResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE        *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_EXCEPTION_STATE     eOutputExcepState  = pOutputPort->exceptionFlag;
+
+    ExynosVideoDecOps             *pDecOps            = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+    ExynosVideoGeometry            codecOutbufConf;
+
+    OMX_CONFIG_RECTTYPE          *pCropRectangle        = &(pOutputPort->cropRectangle);
+    OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition  = &(pInputPort->portDefinition);
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = &(pOutputPort->portDefinition);
+
+    int maxDPBNum = 0;
+
+    FunctionIn();
+
+    /* get geometry */
+    Exynos_OSAL_Memset(&codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry");
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        maxDPBNum += EXTRA_DPB_NUM;
+
+    pCropRectangle->nTop     = codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = codecOutbufConf.cropRect.nHeight;
+
+    /* resolution is changed */
+    if ((codecOutbufConf.nFrameWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth) ||
+        (codecOutbufConf.nFrameHeight != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight) ||
+        (codecOutbufConf.nStride != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nStride) ||
+#if 0  // TODO: check posibility
+        (codecOutbufConf.eColorFormat != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.eColorFormat) ||
+        (codecOutbufConf.eFilledDataType != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.eFilledDataType) ||
+#endif
+        (maxDPBNum != pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth,
+                            pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight,
+                            codecOutbufConf.nFrameWidth,
+                            codecOutbufConf.nFrameHeight);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] DPB(%d), FORMAT(0x%x), TYPE(0x%x) -> DPB(%d), FORMAT(0x%x), TYPE(0x%x)",
+                            pExynosComponent, __FUNCTION__,
+                            pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum,
+                            pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.eColorFormat,
+                            pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.eFilledDataType,
+                            maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType);
+
+        pInputPortDefinition->format.video.nFrameWidth     = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight    = codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride         = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight    = codecOutbufConf.nFrameHeight;
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            pOutputPortDefinition->nBufferCountActual  = maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin     = maxDPBNum;
+        }
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        if (eOutputExcepState == GENERAL_STATE) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* crop info of contents is changed */
+    if ((codecOutbufConf.cropRect.nTop != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nTop) ||
+        (codecOutbufConf.cropRect.nLeft != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nLeft) ||
+        (codecOutbufConf.cropRect.nWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nWidth) ||
+        (codecOutbufConf.cropRect.nHeight != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nHeight)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nWidth,
+                            pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nHeight,
+                            codecOutbufConf.cropRect.nWidth,
+                            codecOutbufConf.cropRect.nHeight);
+
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    Exynos_OSAL_Memcpy(&pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf, &codecOutbufConf, sizeof(codecOutbufConf));
+    pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum = maxDPBNum;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecUpdateResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE        *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    ExynosVideoDecOps             *pDecOps            = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+
+    OMX_CONFIG_RECTTYPE             *pCropRectangle         = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE    *pInputPortDefinition   = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE    *pOutputPortDefinition  = NULL;
+
+    FunctionIn();
+
+    /* get geometry for output */
+    Exynos_OSAL_Memset(&pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get geometry about output", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedHeader;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum += EXTRA_DPB_NUM;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] maxDPBNum: %d", pExynosComponent, __FUNCTION__, pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum);
+
+    /* get interlace info */
+    if (pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE)
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] contents is interlaced type", pExynosComponent, __FUNCTION__);
+
+    pCropRectangle          = &(pOutputPort->cropRectangle);
+    pInputPortDefinition    = &(pInputPort->portDefinition);
+    pOutputPortDefinition   = &(pOutputPort->portDefinition);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] past info: width(%d) height(%d)",
+                                            pExynosComponent, __FUNCTION__,
+                                            pInputPortDefinition->format.video.nFrameWidth,
+                                            pInputPortDefinition->format.video.nFrameHeight);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] resolution info: width(%d / %d), height(%d / %d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth,
+                                        pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nWidth,
+                                        pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight,
+                                        pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nHeight);
+
+    pCropRectangle->nTop     = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nHeight;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth  = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride      = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight;
+#if 0
+            /* don't need to change */
+            pOutputPortDefinition->nBufferCountActual       = pOutputPort->portDefinition.nBufferCountActual;
+            pOutputPortDefinition->nBufferCountMin          = pOutputPort->portDefinition.nBufferCountMin;
+#endif
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight) ||
+            ((OMX_S32)pOutputPortDefinition->nBufferCountActual != pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth  = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride      = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight;
+
+            pOutputPortDefinition->nBufferCountActual       = pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin          = pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum;
+
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* contents has crop info */
+    if ((pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nWidth) ||
+        (pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nHeight)) {
+        pInputPortDefinition->format.video.nFrameWidth  = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride      = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight;
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged) with crop",
+                                                pExynosComponent, __FUNCTION__);
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE        *pMpeg2Dec         = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+    OMX_COLOR_FORMATTYPE           eOutputFormat     = pExynosOutputPort->portDefinition.format.video.eColorFormat;
+
+    ExynosVideoDecOps       *pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_U32  nInBufferCnt = 0;
+    OMX_BOOL bSupportFormat = OMX_FALSE;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pMpeg2Dec->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pVideoDec->bThumbnailMode == OMX_TRUE)
+        pDecOps->Set_IFrameDecoding(hMFCHandle);
+
+    if ((pDecOps->Enable_DTSMode != NULL) &&
+        (pVideoDec->bDTSMode == OMX_TRUE))
+        pDecOps->Enable_DTSMode(hMFCHandle);
+
+    /* input buffer info */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eCompressionFormat = VIDEO_CODING_MPEG2;
+    pInbufOps->Set_Shareable(hMFCHandle);
+
+    nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        /* OMX buffer is not used directly : CODEC buffer */
+        nAllocLen[0] = pSrcInputData->allocSize;
+    }
+
+    bufferConf.nSizeImage = nAllocLen[0];
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+    nInBufferCnt = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    /* should be done before prepare input buffer */
+    if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set output geometry */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+    bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] omx format(0x%x) is %s by h/w",
+                                            pExynosComponent, __FUNCTION__, eOutputFormat,
+                                            (bSupportFormat == OMX_TRUE)? "supported":"not supported");
+    if (bSupportFormat == OMX_TRUE) {  /* supported by H/W */
+        bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eOutputFormat, pExynosOutputPort->ePlaneType);
+        Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pExynosOutputPort->ePlaneType));
+    } else {
+        OMX_COLOR_FORMATTYPE eCheckFormat = OMX_SEC_COLOR_FormatNV12Tiled;
+        bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        if (bSupportFormat != OMX_TRUE) {
+            eCheckFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+            bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        }
+        if (bSupportFormat == OMX_TRUE) {  /* supported by CSC(NV12T/NV12 -> format) */
+            bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eCheckFormat, pExynosOutputPort->ePlaneType);
+            Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eCheckFormat, pExynosOutputPort->ePlaneType));
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not support this format (0x%x)", pExynosComponent, __FUNCTION__, eOutputFormat);
+            ret = OMX_ErrorNotImplemented;
+            pInbufOps->Cleanup_Buffer(hMFCHandle);
+            goto EXIT;
+        }
+    }
+
+    pMpeg2Dec->hMFCMpeg2Handle.MFCOutputColorType = bufferConf.eColorFormat;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output video format is 0x%x",
+                                            pExynosComponent, __FUNCTION__, bufferConf.eColorFormat);
+
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    /* input buffer enqueue for header parsing */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+
+    if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pSrcInputData->buffer.addr,
+                            (unsigned long *)pSrcInputData->buffer.fd,
+                            nAllocLen,
+                            nDataLen,
+                            Exynos_GetPlaneFromPort(pExynosInputPort),
+                            pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enqueue input buffer for header parsing", pExynosComponent, __FUNCTION__);
+//        ret = OMX_ErrorInsufficientResources;
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc = OMX_TRUE;
+
+    /* start header parsing */
+    if (Mpeg2CodecStart(pOMXComponent, INPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run input buffer for header parsing", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    ret = Mpeg2CodecUpdateResolution(pOMXComponent);
+    if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+        (pExynosComponent->codecType != HW_VIDEO_DEC_SECURE_CODEC) &&
+        (oneFrameSize >= 8)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...", pExynosComponent, __FUNCTION__,
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0])    , *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 1),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 2), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 3),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 4), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 5),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 6), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 7));
+    }
+
+    if (ret != OMX_ErrorNone) {
+        Mpeg2CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_SleepMillisec(0);
+    ret = (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] first frame will be re-pushed to input", pExynosComponent, __FUNCTION__);
+
+    Mpeg2CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE        *pMpeg2Dec            = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort    = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecOps       *pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nOutbufs, nPlaneCnt;
+
+    FunctionIn();
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++)
+        nAllocLen[i] = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nAlignPlaneSize[i];
+
+    Mpeg2CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    /* for adaptive playback */
+    if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enable Dynamic DPB", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare output buffer */
+        if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        /* get dpb count */
+        nOutbufs = pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        /* Enqueue output buffer */
+        for (i = 0; i < nOutbufs; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+                            (unsigned long *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+                            pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+                            nDataLen,
+                            nPlaneCnt,
+                            NULL);
+        }
+
+        pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_TRUE;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* get dpb count */
+        nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+        if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pExynosOutputPort->eMetaDataType == METADATA_TYPE_DISABLED) {
+            /*************/
+            /*    TBD    */
+            /*************/
+            /* data buffer : user buffer
+             * H/W can't accept user buffer directly
+             */
+            ret = OMX_ErrorNotImplemented;
+            goto EXIT;
+        }
+
+        pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_TRUE;
+    }
+
+    if (Mpeg2CodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec         = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg2Dec  = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch (nParamIndex) {
+    case OMX_IndexParamVideoMpeg2:
+    {
+        OMX_VIDEO_PARAM_MPEG2TYPE *pDstMpeg2Param = (OMX_VIDEO_PARAM_MPEG2TYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_MPEG2TYPE *pSrcMpeg2Param = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstMpeg2Param, sizeof(OMX_VIDEO_PARAM_MPEG2TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstMpeg2Param->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcMpeg2Param = &pMpeg2Dec->Mpeg2Component[pDstMpeg2Param->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstMpeg2Param) + nOffset,
+                           ((char *)pSrcMpeg2Param) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_MPEG2TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel   = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_MPEG2TYPE        *pSrcMpeg2Component = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcMpeg2Component = &pMpeg2Dec->Mpeg2Component[pDstProfileLevel->nPortIndex];
+
+        pDstProfileLevel->eProfile = pSrcMpeg2Component->eProfile;
+        pDstProfileLevel->eLevel = pSrcMpeg2Component->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pMpeg2Dec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec         = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch (nIndex) {
+    case OMX_IndexParamVideoMpeg2:
+    {
+        OMX_VIDEO_PARAM_MPEG2TYPE *pDstMpeg2Param = NULL;
+        OMX_VIDEO_PARAM_MPEG2TYPE *pSrcMpeg2Param = (OMX_VIDEO_PARAM_MPEG2TYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcMpeg2Param, sizeof(OMX_VIDEO_PARAM_MPEG2TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcMpeg2Param->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstMpeg2Param = &pMpeg2Dec->Mpeg2Component[pSrcMpeg2Param->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstMpeg2Param) + nOffset,
+                           ((char *)pSrcMpeg2Param) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_MPEG2TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE)) {
+            pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel   = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_MPEG2TYPE        *pDstMpeg2Component = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstMpeg2Component = &pMpeg2Dec->Mpeg2Component[pSrcProfileLevel->nPortIndex];
+
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pDstMpeg2Component->eProfile = pSrcProfileLevel->eProfile;
+        pDstMpeg2Component->eLevel = pSrcProfileLevel->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pMpeg2Dec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_GetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec         = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch (nIndex) {
+    case OMX_IndexConfigCommonOutputCrop:
+    {
+        EXYNOS_OMX_BASEPORT *pExynosPort   = NULL;
+        OMX_CONFIG_RECTTYPE *pSrcRectType  = NULL;
+        OMX_CONFIG_RECTTYPE *pDstRectType  = NULL;
+
+        if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc == OMX_FALSE) {
+            ret = OMX_ErrorNotReady;
+            break;
+        }
+
+        pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
+
+        if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) &&
+            (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex];
+
+        pSrcRectType = &(pExynosPort->cropRectangle);
+
+        pDstRectType->nTop    = pSrcRectType->nTop;
+        pDstRectType->nLeft   = pSrcRectType->nLeft;
+        pDstRectType->nHeight = pSrcRectType->nHeight;
+        pDstRectType->nWidth  = pSrcRectType->nWidth;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec         = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    switch (nIndex) {
+    default:
+        ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_GetExtensionIndex(
+    OMX_IN  OMX_HANDLETYPE   hComponent,
+    OMX_IN  OMX_STRING       cParameterName,
+    OMX_OUT OMX_INDEXTYPE   *pIndexType)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_ComponentRoleEnum(
+    OMX_HANDLETYPE hComponent,
+    OMX_U8        *cRole,
+    OMX_U32        nIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) || (cRole == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE);
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorNoMore;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_Mpeg2Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    ExynosVideoInstInfo *pVideoInstInfo = &(pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo);
+
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+    int i;
+
+    FunctionIn();
+
+    pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc = OMX_FALSE;
+    pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    pVideoDec->bDiscardCSDError = OMX_FALSE;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                             pExynosInputPort->portDefinition.format.video.nBitrate,
+                                                                                             pExynosInputPort->portDefinition.format.video.xFramerate);
+
+    pVideoInstInfo->nSize        = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth       = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight      = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate     = pExynosInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate   = pExynosInputPort->portDefinition.format.video.xFramerate;
+
+    /* Mpeg2 Codec Open */
+    ret = Mpeg2CodecOpen(pMpeg2Dec, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+        nAllocLen[0] = ALIGN(pExynosInputPort->portDefinition.format.video.nFrameWidth *
+                             pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+        if (nAllocLen[0] < pVideoDec->nMinInBufSize)
+            nAllocLen[0] = pVideoDec->nMinInBufSize;
+
+        Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_SetPlaneToPort(pExynosOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pMpeg2Dec->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pMpeg2Dec->hSourceStartEvent);
+    pMpeg2Dec->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pMpeg2Dec->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pMpeg2Dec->hDestinationOutStartEvent);
+
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp = 0;
+    pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp = 0;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pMpeg2Dec->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+    pVideoDec->csc_handle = csc_init(csc_method);
+    if (pVideoDec->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    pVideoDec->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_Mpeg2Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if (pVideoDec->csc_handle != NULL) {
+        csc_deinit(pVideoDec->csc_handle);
+        pVideoDec->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pMpeg2Dec->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pMpeg2Dec->hDestinationInStartEvent);
+    pMpeg2Dec->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pMpeg2Dec->hDestinationOutStartEvent);
+    pMpeg2Dec->hDestinationOutStartEvent = NULL;
+    pMpeg2Dec->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pMpeg2Dec->hSourceStartEvent);
+    pMpeg2Dec->hSourceStartEvent = NULL;
+    pMpeg2Dec->bSourceStart = OMX_FALSE;
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
+        pExynosOutputPort->codecSemID = NULL;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
+        pExynosInputPort->codecSemID = NULL;
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+    Mpeg2CodecClose(pMpeg2Dec);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE        *pMpeg2Dec         = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+
+    ExynosVideoDecOps       *pDecOps     = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps   = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_BOOL bInStartCode = OMX_FALSE;
+
+    FunctionIn();
+
+    if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = Mpeg2CodecSrcSetup(pOMXComponent, pSrcInputData);
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (pMpeg2Dec->bDestinationStart == OMX_FALSE) &&
+        (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_FALSE)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+        ret = Mpeg2CodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Mpeg2CodecDstSetup(0x%x)",
+                                            pExynosComponent, __FUNCTION__, ret);
+            goto EXIT;
+        }
+    }
+
+    if (((bInStartCode = Check_Mpeg2_StartCode(pSrcInputData->buffer.addr[0], oneFrameSize)) == OMX_TRUE) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+        pExynosComponent->timeStamp[pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp] = pSrcInputData->timeStamp;
+        pExynosComponent->nFlags[pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp] = pSrcInputData->nFlags;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), dataLen(%d), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, oneFrameSize, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp);
+        pDecOps->Set_FrameTag(hMFCHandle, pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp);
+        pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp++;
+        pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp %= MAX_TIMESTAMP;
+
+        if ((pVideoDec->bQosChanged == OMX_TRUE) &&
+            (pDecOps->Set_QosRatio != NULL)) {
+            pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
+            pVideoDec->bQosChanged = OMX_FALSE;
+        }
+
+        if (pVideoDec->bSearchBlackBarChanged == OMX_TRUE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] BlackBar searching mode : %s",
+                                            pExynosComponent, __FUNCTION__,
+                                            (pVideoDec->bSearchBlackBar == OMX_TRUE) ? "enable" : "disable");
+            pDecOps->Set_SearchBlackBar(hMFCHandle, (ExynosVideoBoolType)pVideoDec->bSearchBlackBar);
+            pVideoDec->bSearchBlackBarChanged = OMX_FALSE;
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        /* queue work for input buffer */
+        nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+        if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        } else {
+            nAllocLen[0] = pSrcInputData->allocSize;
+
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        }
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pSrcInputData->buffer.addr,
+                                (unsigned long *)pSrcInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pExynosInputPort),
+                                pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            goto EXIT;
+        }
+        Mpeg2CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        if (pMpeg2Dec->bSourceStart == OMX_FALSE) {
+            pMpeg2Dec->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pMpeg2Dec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        if ((pMpeg2Dec->bDestinationStart == OMX_FALSE) &&
+            (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc == OMX_TRUE)) {
+            pMpeg2Dec->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    } else if (bInStartCode == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] can't find a start code", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedFrame;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pInbufOps      = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->allocSize  = 0;
+        pSrcOutputData->pPrivate = NULL;
+    } else {
+        pSrcOutputData->buffer.addr[0] = pVideoBuffer->planes[0].addr;
+        pSrcOutputData->buffer.fd[0] = pVideoBuffer->planes[0].fd;
+        pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
+
+        if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] ==
+                        pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
+                    pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pExynosInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pOutbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++) {
+        nAllocLen[i] = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nAlignPlaneSize[i];
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] ADDR[%d]: 0x%x, size[%d]: %d", pExynosComponent, __FUNCTION__,
+                                        i, pDstInputData->buffer.addr[i], i, nAllocLen[i]);
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                nPlaneCnt,
+                                pDstInputData->bufferHeader);
+
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+        }
+
+        goto EXIT;
+    }
+
+    Mpeg2CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    DECODE_CODEC_EXTRA_BUFFERINFO   *pBufferInfo        = NULL;
+
+    ExynosVideoDecOps           *pDecOps        = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+    ExynosVideoDecBufferOps     *pOutbufOps     = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+    ExynosVideoBuffer           *pVideoBuffer   = NULL;
+    ExynosVideoBuffer            videoBuffer;
+    ExynosVideoFrameStatusType   displayStatus  = VIDEO_FRAME_STATUS_UNKNOWN;
+    ExynosVideoGeometry         *bufferGeometry = NULL;
+    ExynosVideoErrorType         codecReturn    = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+
+    OMX_S32 indexTimestamp = 0;
+    int plane, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pMpeg2Dec->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    while (1) {
+        Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer));
+
+        codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+        if (codecReturn == VIDEO_ERROR_NONE) {
+            pVideoBuffer = &videoBuffer;
+        } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO) at ExtensionDequeue", pExynosComponent, __FUNCTION__);
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorHardware;
+            goto EXIT;
+        } else {
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        displayStatus = pVideoBuffer->displayStatus;
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus: 0x%x", pExynosComponent, __FUNCTION__, displayStatus);
+
+        if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
+            (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+            (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+            (CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+            ret = OMX_ErrorNone;
+            break;
+        }
+    }
+
+   if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+       (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) {
+        if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+            pOutputPort->exceptionFlag = NEED_PORT_FLUSH;
+            pVideoDec->bReconfigDPB = OMX_TRUE;
+            Mpeg2CodecUpdateResolution(pOMXComponent);
+            pVideoDec->csc_set_format = OMX_FALSE;
+        }
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp++;
+    pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+    pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
+    nPlaneCnt = Exynos_GetPlaneFromPort(pOutputPort);
+    for (plane = 0; plane < nPlaneCnt; plane++) {
+        pDstOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+        pDstOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+        pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        pDstOutputData->dataLen   += pVideoBuffer->planes[plane].dataSize;
+        nDataLen[plane]            = pVideoBuffer->planes[plane].dataSize;
+    }
+    pDstOutputData->usedDataLen = 0;
+    pDstOutputData->pPrivate = pVideoBuffer;
+
+    pBufferInfo     = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+    bufferGeometry  = &pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf;
+    pBufferInfo->imageWidth       = bufferGeometry->nFrameWidth;
+    pBufferInfo->imageHeight      = bufferGeometry->nFrameHeight;
+    pBufferInfo->imageStride      = bufferGeometry->nStride;
+    pBufferInfo->cropRect.nLeft   = bufferGeometry->cropRect.nLeft;
+    pBufferInfo->cropRect.nTop    = bufferGeometry->cropRect.nTop;
+    pBufferInfo->cropRect.nWidth  = bufferGeometry->cropRect.nWidth;
+    pBufferInfo->cropRect.nHeight = bufferGeometry->cropRect.nHeight;
+    pBufferInfo->colorFormat      = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+    Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            goto EXIT;
+        }
+
+        /* calculate each plane info for the application */
+        Exynos_OSAL_GetPlaneSize(pOutputPort->portDefinition.format.video.eColorFormat,
+                                 PLANE_SINGLE, pOutputPort->portDefinition.format.video.nFrameWidth,
+                                 pOutputPort->portDefinition.format.video.nFrameHeight,
+                                 nDataLen, nAllocLen);
+
+        pDstOutputData->allocSize = nAllocLen[0] + nAllocLen[1] + nAllocLen[2];
+        pDstOutputData->dataLen   = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+#ifdef USE_ANDROID
+    /* get interlace frame info */
+    if ((pOutputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
+        (pVideoBuffer->planes[2].addr != NULL)) {
+        ExynosVideoMeta *pMeta = (ExynosVideoMeta *)pVideoBuffer->planes[2].addr;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] interlace type = %x", pExynosComponent, __FUNCTION__, pVideoBuffer->interlacedType);
+        pMeta->eType = VIDEO_INFO_TYPE_INTERLACED;
+        pMeta->data.dec.nInterlacedType = pVideoBuffer->interlacedType;
+    }
+#endif
+
+    indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+    if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+        if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
+            (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
+            if (indexTimestamp == INDEX_AFTER_EOS) {
+                pDstOutputData->timeStamp = 0x00;
+                pDstOutputData->nFlags = 0x00;
+            } else {
+                pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp];
+                pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp];
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] missing out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+            }
+        } else {
+            pDstOutputData->timeStamp = 0x00;
+            pDstOutputData->nFlags = 0x00;
+        }
+    } else {
+        /* For timestamp correction. if mfc support frametype detect */
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] disp_pic_frame_type: %d", pExynosComponent, __FUNCTION__, pVideoBuffer->frameType);
+
+        /* NEED TIMESTAMP REORDER */
+        if (pVideoDec->bDTSMode == OMX_TRUE) {
+            if ((pVideoBuffer->frameType & VIDEO_FRAME_I) ||
+                ((pVideoBuffer->frameType & VIDEO_FRAME_OTHERS) &&
+                    ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
+                (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
+                pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp = indexTimestamp;
+            else
+                indexTimestamp = pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp;
+        }
+
+        pDstOutputData->timeStamp   = pExynosComponent->timeStamp[indexTimestamp];
+        pDstOutputData->nFlags      = pExynosComponent->nFlags[indexTimestamp] | OMX_BUFFERFLAG_ENDOFFRAME;
+
+        if (pVideoBuffer->frameType & VIDEO_FRAME_I)
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+        if (pVideoBuffer->frameType & VIDEO_FRAME_CORRUPT)
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+    }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                                    pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                                    indexTimestamp);
+
+        if (pVideoBuffer->frameType & VIDEO_FRAME_WITH_BLACK_BAR) {
+            if (Mpeg2CodecUpdateBlackBarCrop(pOMXComponent) != OMX_ErrorNone)
+                goto EXIT;
+        }
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+        (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+    }
+
+    if (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) {
+        pDstOutputData->remainDataLen = 0;
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            if (indexTimestamp != INDEX_AFTER_EOS)
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] tag(%d) is wrong", pExynosComponent, __FUNCTION__, indexTimestamp);
+            pDstOutputData->timeStamp   = 0x00;
+            pDstOutputData->nFlags      = 0x00;
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) ||
+            (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+            pExynosComponent->nFlags[indexTimestamp] &= (~OMX_BUFFERFLAG_EOS);
+        }
+    } else if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        pDstOutputData->remainDataLen = 0;
+
+        if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
+            pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+
+            if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+                pExynosComponent->bBehaviorEOS = OMX_FALSE;
+            } else {
+                pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+                pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+            }
+        }
+    } else {
+        pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_Mpeg2Dec_SrcIn(pOMXComponent, pSrcInputData);
+    if ((ret != OMX_ErrorNone) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorCorruptedFrame)) {
+
+        if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+            (pVideoDec->bDiscardCSDError == OMX_TRUE)) {
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+    if ((pMpeg2Dec->bSourceStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
+        Exynos_OSAL_SignalWait(pMpeg2Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pMpeg2Dec->hSourceStartEvent);
+    }
+
+    ret = Exynos_Mpeg2Dec_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        if (pExynosComponent->currentState == OMX_StatePause)
+            ret = (OMX_ERRORTYPE)OMX_ErrorOutputBufferUseYet;
+        else
+            ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pMpeg2Dec->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pMpeg2Dec->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pMpeg2Dec->hDestinationInStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pMpeg2Dec->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pMpeg2Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+
+        if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+            (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+            ret = Mpeg2CodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Mpeg2CodecDstSetup(0x%x)", pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+            Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationOutStartEvent);
+        }
+    }
+
+    if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_Mpeg2Dec_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg2Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec          = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (((pMpeg2Dec->bDestinationStart == OMX_FALSE) ||
+         (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_FALSE)) &&
+        (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pMpeg2Dec->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pMpeg2Dec->hDestinationOutStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pMpeg2Dec->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pMpeg2Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_Mpeg2Dec_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE  hComponent,
+    OMX_STRING      componentName)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_MPEG2DEC_HANDLE            *pMpeg2Dec            = NULL;
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) || (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG2_DEC, componentName) != 0) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pMpeg2Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MPEG2DEC_HANDLE));
+    if (pMpeg2Dec == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pMpeg2Dec, 0, sizeof(EXYNOS_MPEG2DEC_HANDLE));
+    pVideoDec               = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pMpeg2Dec;
+
+    Exynos_OSAL_Strcpy(pExynosComponent->componentName, componentName);
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE)
+        pExynosPort->portDefinition.nBufferSize = CUSTOM_DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+
+    pVideoDec->nMinInBufSize = DEFAULT_VIDEO_MIN_INPUT_BUFFER_SIZE;  /* for DRC */
+
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/mpeg2");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    //pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pMpeg2Dec->Mpeg2Component[i], OMX_VIDEO_PARAM_MPEG2TYPE);
+        pMpeg2Dec->Mpeg2Component[i].nPortIndex = i;
+        pMpeg2Dec->Mpeg2Component[i].eProfile = OMX_VIDEO_MPEG2ProfileMain;
+        pMpeg2Dec->Mpeg2Component[i].eLevel = OMX_VIDEO_MPEG2LevelML; /* Check again**** */
+    }
+
+    pOMXComponent->GetParameter      = &Exynos_Mpeg2Dec_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_Mpeg2Dec_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_Mpeg2Dec_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_Mpeg2Dec_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_Mpeg2Dec_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_Mpeg2Dec_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_Mpeg2Dec_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_Mpeg2Dec_Terminate;
+
+    pVideoDec->exynos_codec_srcInputProcess  = &Exynos_Mpeg2Dec_srcInputBufferProcess;
+    pVideoDec->exynos_codec_srcOutputProcess = &Exynos_Mpeg2Dec_srcOutputBufferProcess;
+    pVideoDec->exynos_codec_dstInputProcess  = &Exynos_Mpeg2Dec_dstInputBufferProcess;
+    pVideoDec->exynos_codec_dstOutputProcess = &Exynos_Mpeg2Dec_dstOutputBufferProcess;
+
+    pVideoDec->exynos_codec_start         = &Mpeg2CodecStart;
+    pVideoDec->exynos_codec_stop          = &Mpeg2CodecStop;
+    pVideoDec->exynos_codec_bufferProcessRun = &Mpeg2CodecOutputBufferProcessRun;
+    pVideoDec->exynos_codec_enqueueAllBuffer = &Mpeg2CodecEnQueueAllBuffer;
+
+    pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+    pVideoDec->exynos_codec_reconfigAllBuffers        = &Mpeg2CodecReconfigAllBuffers;
+
+    pVideoDec->exynos_codec_checkFormatSupport      = &CheckFormatHWSupport;
+    pVideoDec->exynos_codec_checkResolutionChange   = &Mpeg2CodecCheckResolution;
+
+    pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoDec->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pMpeg2Dec);
+        pMpeg2Dec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.eCodecType = VIDEO_CODING_MPEG2;
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo), VIDEO_TRUE /* dec */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pMpeg2Dec);
+        pMpeg2Dec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_Output_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
+    OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+    EXYNOS_MPEG2DEC_HANDLE        *pMpeg2Dec            = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent       = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent    = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoDec           = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg2Dec != NULL) {
+        Exynos_OSAL_Free(pMpeg2Dec);
+        pMpeg2Dec = pVideoDec->hCodecHandle = NULL;
+    }
+
+    ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h b/openmax/component/video/dec/mpeg2/Exynos_OMX_Mpeg2dec.h
new file mode 100755 (executable)
index 0000000..1cc72f3
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Mpeg2dec.h
+ * @brief
+ * @author     Satish Kumar Reddy (palli.satish@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2012.07.10 : Create
+ */
+
+#ifndef EXYNOS_OMX_MPEG2_DEC_COMPONENT
+#define EXYNOS_OMX_MPEG2_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+#include "ExynosVideoApi.h"
+
+
+typedef struct _EXYNOS_MFC_MPEG2DEC_HANDLE
+{
+    OMX_HANDLETYPE hMFCHandle;
+    OMX_U32        indexTimestamp;
+    OMX_U32        outputIndexTimestamp;
+    OMX_BOOL       bConfiguredMFCSrc;
+    OMX_BOOL       bConfiguredMFCDst;
+    OMX_S32        maxDPBNum;
+
+    ExynosVideoColorFormatType  MFCOutputColorType;
+    ExynosVideoDecOps          *pDecOps;
+    ExynosVideoDecBufferOps    *pInbufOps;
+    ExynosVideoDecBufferOps    *pOutbufOps;
+    ExynosVideoGeometry         codecOutbufConf;
+    ExynosVideoInstInfo         videoInstInfo;
+
+    #define MAX_PROFILE_NUM 2
+    OMX_VIDEO_MPEG2PROFILETYPE   profiles[MAX_PROFILE_NUM];
+    OMX_S32                      nProfileCnt;
+    OMX_VIDEO_MPEG2LEVELTYPE     maxLevel;
+} EXYNOS_MFC_MPEG2DEC_HANDLE;
+
+typedef struct _EXYNOS_MPEG2DEC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_MPEG2TYPE           Mpeg2Component[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+
+    /* EXYNOS MFC Codec specific */
+    EXYNOS_MFC_MPEG2DEC_HANDLE            hMFCMpeg2Handle;
+
+    OMX_BOOL bSourceStart;
+    OMX_BOOL bDestinationStart;
+    OMX_HANDLETYPE hSourceStartEvent;
+    OMX_HANDLETYPE hDestinationInStartEvent;
+    OMX_HANDLETYPE hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE bypassBufferInfoQ;
+} EXYNOS_MPEG2DEC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE hComponent,
+    OMX_STRING componentName);
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
+    OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Mpeg2CodecDstSetup(
+    OMX_COMPONENTTYPE *pOMXComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/mpeg2/Makefile.am b/openmax/component/video/dec/mpeg2/Makefile.am
new file mode 100755 (executable)
index 0000000..bdf0111
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libOMX.Exynos.MPEG2.Decoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_MPEG2_Decoder_la_SOURCES = Exynos_OMX_Mpeg2dec.c \
+                                         library_register.c
+
+libOMX_Exynos_MPEG2_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                        $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                        $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                        $(top_builddir)/openmax/component/video/dec/libExynosOMX_Vdec.la \
+                                      $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+libOMX_Exynos_MPEG2_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                        -I$(top_srcdir)/openmax/include/exynos \
+                                        -I$(top_srcdir)/openmax/osal \
+                                        -I$(top_srcdir)/openmax/core \
+                                        -I$(top_srcdir)/openmax/component/common \
+                                        -I$(top_srcdir)/openmax/component/video/dec \
+                                      -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_MPEG2_Decoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
+libOMX_Exynos_MPEG2_Decoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable
+
+libOMX_Exynos_MPEG2_Decoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/dec/mpeg2/library_register.c b/openmax/component/video/dec/mpeg2/library_register.c
new file mode 100755 (executable)
index 0000000..65faff5
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       library_register.c
+ * @brief
+ * @author     Satish Kumar Reddy (palli.satish@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2012.07.10 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_MPEG2_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(
+    ExynosRegisterComponentType **ppExynosComponent)
+{
+    FunctionIn();
+
+    if (ppExynosComponent == NULL)
+        goto EXIT;
+
+    /* component 1 - video decoder MPEG2 */
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_MPEG2_DEC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE);
+    ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
diff --git a/openmax/component/video/dec/mpeg2/library_register.h b/openmax/component/video/dec/mpeg2/library_register.h
new file mode 100755 (executable)
index 0000000..99d4d4b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author      Satish Kumar Reddy (palli.satish@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.07.10 : Create
+ */
+
+#ifndef EXYNOS_OMX_MPEG2_DEC_REG
+#define EXYNOS_OMX_MPEG2_DEC_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM       1
+#define MAX_COMPONENT_ROLE_NUM  1
+
+#ifndef USE_CUSTOM_COMPONENT_SUPPORT
+#define EXYNOS_OMX_COMPONENT_MPEG2_DEC        "OMX.Exynos.MPEG2.Decoder"
+#else
+#define EXYNOS_OMX_COMPONENT_MPEG2_DEC        "OMX.Exynos.mpeg2.dec"
+#endif
+
+#define EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE   "video_decoder.mpeg2"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(
+    ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c
new file mode 100755 (executable)
index 0000000..c1cd44b
--- /dev/null
@@ -0,0 +1,3369 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file      Exynos_OMX_Mpeg4dec.c
+ * @brief
+ * @author    Yunji Kim (yunji.kim@samsung.com)
+ * @author    SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version   2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Vdec.h"
+#include "Exynos_OMX_VdecControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Mpeg4dec.h"
+#include "ExynosVideoApi.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+
+#ifdef USE_ANDROID
+#include "VendorVideoAPI.h"
+#endif
+
+/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
+/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_MPEG4_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec      = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg4Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) {
+        pMpeg4Dec->hMFCMpeg4Handle.profiles[nProfileCnt++] = (int)OMX_VIDEO_MPEG4ProfileSimple;
+        pMpeg4Dec->hMFCMpeg4Handle.profiles[nProfileCnt++] = (int)OMX_VIDEO_MPEG4ProfileAdvancedSimple;
+        pMpeg4Dec->hMFCMpeg4Handle.nProfileCnt = nProfileCnt;
+        pMpeg4Dec->hMFCMpeg4Handle.maxLevel = (int)OMX_VIDEO_MPEG4Level5;
+    } else {
+        pMpeg4Dec->hMFCMpeg4Handle.profiles[nProfileCnt++] = (int)OMX_VIDEO_H263ProfileBaseline;
+        pMpeg4Dec->hMFCMpeg4Handle.profiles[nProfileCnt++] = (int)OMX_VIDEO_H263ProfileH320Coding;
+        pMpeg4Dec->hMFCMpeg4Handle.profiles[nProfileCnt++] = (int)OMX_VIDEO_H263ProfileBackwardCompatible;
+        pMpeg4Dec->hMFCMpeg4Handle.profiles[nProfileCnt++] = (int)OMX_VIDEO_H263ProfileISWV2;
+        pMpeg4Dec->hMFCMpeg4Handle.nProfileCnt = nProfileCnt;
+        pMpeg4Dec->hMFCMpeg4Handle.maxLevel = (int)OMX_VIDEO_H263Level70;
+    }
+
+EXIT:
+
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec      = NULL;
+
+    int nLevelCnt = 0;
+    OMX_U32 nMaxIndex = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg4Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pMpeg4Dec->hMFCMpeg4Handle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pMpeg4Dec->hMFCMpeg4Handle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pMpeg4Dec->hMFCMpeg4Handle.maxLevel;
+#else
+    while ((pMpeg4Dec->hMFCMpeg4Handle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+
+    if ((pMpeg4Dec->hMFCMpeg4Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                        pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pMpeg4Dec->hMFCMpeg4Handle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pMpeg4Dec->hMFCMpeg4Handle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] supported profile(%x), level(%x)",
+                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec  = NULL;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec  = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg4Dec == NULL)
+        goto EXIT;
+
+    while ((pMpeg4Dec->hMFCMpeg4Handle.maxLevel >> nLevelCnt++) > 0);
+
+    if ((pMpeg4Dec->hMFCMpeg4Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pMpeg4Dec->hMFCMpeg4Handle.nProfileCnt; i++) {
+        if (pMpeg4Dec->hMFCMpeg4Handle.profiles[i] == (int)pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    while (nLevelCnt >= 0) {
+        if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+            bLevelSupport = OMX_TRUE;
+            break;
+        }
+
+        nLevelCnt--;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    FunctionOut();
+
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
+{
+    OMX_ERRORTYPE       ret          = OMX_ErrorNone;
+    ExynosVideoBuffer  *pCodecBuffer = NULL;
+
+    if (codecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
+
+    if (addr != NULL) {
+        addr[0] = pCodecBuffer->planes[0].addr;
+        addr[1] = pCodecBuffer->planes[1].addr;
+        addr[2] = pCodecBuffer->planes[2].addr;
+    }
+
+    if (size != NULL) {
+        size[0] = pCodecBuffer->planes[0].allocSize;
+        size[1] = pCodecBuffer->planes[1].allocSize;
+        size[2] = pCodecBuffer->planes[2].allocSize;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_BOOL gbFIMV1 = OMX_FALSE;
+
+static OMX_BOOL Check_Stream_StartCode(
+    OMX_U8    *pInputStream,
+    OMX_U32    streamSize,
+    CODEC_TYPE codecType)
+{
+    OMX_BOOL ret = OMX_FALSE;
+
+    FunctionIn();
+
+    switch (codecType) {
+    case CODEC_TYPE_MPEG4:
+        if (gbFIMV1) {
+            ret = OMX_TRUE;
+            goto EXIT;
+        } else {
+            if (streamSize < 3) {
+                ret = OMX_FALSE;
+                goto EXIT;
+            } else if ((pInputStream[0] == 0x00) &&
+                       (pInputStream[1] == 0x00) &&
+                       (pInputStream[2] == 0x01)) {
+                ret = OMX_TRUE;
+            } else {
+                ret = OMX_FALSE;
+                goto EXIT;
+            }
+        }
+        break;
+    case CODEC_TYPE_H263:
+        if (streamSize > 0) {
+            unsigned startCode = 0xFFFFFFFF;
+            unsigned pTypeMask = 0x03;
+            unsigned pType     = 0;
+            OMX_U32  len       = 0;
+            int      readStream;
+            /* Check PSC(Picture Start Code) : 0000 0000 0000 0000 1000 00 */
+            while (((startCode << 8 >> 10) != 0x20) || (pType != 0x02)) {
+                readStream = *(pInputStream + len);
+                startCode = (startCode << 8) | readStream;
+
+                readStream = *(pInputStream + len + 1);
+                pType = readStream & pTypeMask;
+
+                len++;
+                if (len > 0x3)
+                    break;
+            }
+
+            if (len > 0x3) {
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Picture Start Code Missing", __FUNCTION__);
+                ret = OMX_FALSE;
+                goto EXIT;
+            } else {
+                ret = OMX_TRUE;
+            }
+        } else {
+            ret = OMX_FALSE;
+            goto EXIT;
+        }
+        break;
+    default:
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: undefined codec type (%d)", __FUNCTION__, codecType);
+        ret = OMX_FALSE;
+        goto EXIT;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec      = NULL;
+    EXYNOS_OMX_BASEPORT             *pOutputPort    = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg4Dec == NULL)
+        goto EXIT;
+    pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pOutputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecOpen(EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec, ExynosVideoInstInfo *pVideoInstInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pMpeg4Dec == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pDecOps    = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
+    pInbufOps  = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+    pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+
+    if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pMpeg4Dec->hMFCMpeg4Handle.pDecOps    = pDecOps;
+    pMpeg4Dec->hMFCMpeg4Handle.pInbufOps  = pInbufOps;
+    pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pDecOps->nSize    = sizeof(ExynosVideoDecOps);
+    pInbufOps->nSize  = sizeof(ExynosVideoDecBufferOps);
+    pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
+
+    if (Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for decoder ops */
+    if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
+        (pDecOps->Get_ActualBufferCount == NULL) ||
+        (pDecOps->Set_FrameTag == NULL) || (pDecOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.pDecOps->Init(pVideoInstInfo);
+    if (pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pDecOps != NULL) {
+            Exynos_OSAL_Free(pDecOps);
+            pMpeg4Dec->hMFCMpeg4Handle.pDecOps = NULL;
+        }
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pMpeg4Dec->hMFCMpeg4Handle.pInbufOps = NULL;
+        }
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecClose(EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pMpeg4Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    pDecOps    = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+    pInbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+    pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pDecOps->Finalize(hMFCHandle);
+        pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = NULL;
+        pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE;
+        pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps = NULL;
+    }
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pMpeg4Dec->hMFCMpeg4Handle.pInbufOps = NULL;
+    }
+    if (pDecOps != NULL) {
+        Exynos_OSAL_Free(pDecOps);
+        pMpeg4Dec->hMFCMpeg4Handle.pDecOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg4Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    pInbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+    pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc == OMX_TRUE)) {
+        pInbufOps->Run(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE)) {
+        pOutbufOps->Run(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg4Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    pInbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+    pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) {
+        pInbufOps->Stop(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) {
+        EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+        pOutbufOps->Stop(hMFCHandle);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE)
+            pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg4Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pMpeg4Dec->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pMpeg4Dec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pMpeg4Dec->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecReconfigAllBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = &pExynosComponent->pExynosPort[nPortIndex];
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    ExynosVideoDecBufferOps         *pBufferOps         = NULL;
+
+    FunctionIn();
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pMpeg4Dec->bSourceStart == OMX_TRUE)) {
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pMpeg4Dec->bDestinationStart == OMX_TRUE)) {
+        pBufferOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+
+        if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+            /**********************************/
+            /* Codec Buffer Free & Unregister */
+            /**********************************/
+            Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+            Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE;
+
+            /******************************************************/
+            /* V4L2 Destnation Setup for DPB Buffer Number Change */
+            /******************************************************/
+            ret = Mpeg4CodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to MPEG4CodecDstSetup(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+        } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+            /***************************/
+            /* Codec Buffer Unregister */
+            /***************************/
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE;
+        }
+    } else {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+
+    ExynosVideoDecBufferOps *pInbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+
+    int i;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecInputBuffer[i]->fd[0], pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecOutputBuffer[i]->fd[0], pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+        }
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecUpdateBlackBarCrop(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec            = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    OMX_CONFIG_RECTTYPE           *pBlackBarCropRect    = &pVideoDec->blackBarCropRect;
+
+    ExynosVideoDecBufferOps  *pOutbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+    ExynosVideoRect           CropRect;
+
+    FunctionIn();
+
+    Exynos_OSAL_Memset(&CropRect, 0, sizeof(ExynosVideoRect));
+    if (pOutbufOps->Get_BlackBarCrop(hMFCHandle, &CropRect) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get crop info", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pBlackBarCropRect->nLeft   = CropRect.nLeft;
+    pBlackBarCropRect->nTop    = CropRect.nTop;
+    pBlackBarCropRect->nWidth  = CropRect.nWidth;
+    pBlackBarCropRect->nHeight = CropRect.nHeight;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Black Bar Info: LEFT(%d) TOP(%d) WIDTH(%d) HEIGHT(%d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pBlackBarCropRect->nLeft, pBlackBarCropRect->nTop,
+                                        pBlackBarCropRect->nWidth, pBlackBarCropRect->nHeight);
+
+    /** Send Port Settings changed call back **/
+    (*(pExynosComponent->pCallbacks->EventHandler))
+        (pOMXComponent,
+         pExynosComponent->callbackData,
+         OMX_EventPortSettingsChanged, /* The command was completed */
+         OMX_DirOutput, /* This is the port index */
+         (OMX_INDEXTYPE)OMX_IndexConfigBlackBarCrop,
+         NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecCheckResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec          = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_EXCEPTION_STATE     eOutputExcepState  = pOutputPort->exceptionFlag;
+
+    ExynosVideoDecOps             *pDecOps            = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+    ExynosVideoGeometry            codecOutbufConf;
+
+    OMX_CONFIG_RECTTYPE          *pCropRectangle        = &(pOutputPort->cropRectangle);
+    OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition  = &(pInputPort->portDefinition);
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = &(pOutputPort->portDefinition);
+
+    int maxDPBNum = 0;
+
+    FunctionIn();
+
+    /* get geometry */
+    Exynos_OSAL_Memset(&codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry");
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        maxDPBNum += EXTRA_DPB_NUM;
+
+    pCropRectangle->nTop     = codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = codecOutbufConf.cropRect.nHeight;
+
+    /* resolution is changed */
+    if ((codecOutbufConf.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) ||
+        (codecOutbufConf.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight) ||
+        (codecOutbufConf.nStride != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nStride) ||
+#if 0  // TODO: check posibility
+        (codecOutbufConf.eColorFormat != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.eColorFormat) ||
+        (codecOutbufConf.eFilledDataType != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.eFilledDataType) ||
+#endif
+        (maxDPBNum != pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth,
+                            pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight,
+                            codecOutbufConf.nFrameWidth,
+                            codecOutbufConf.nFrameHeight);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] DPB(%d), FORMAT(0x%x), TYPE(0x%x) -> DPB(%d), FORMAT(0x%x), TYPE(0x%x)",
+                            pExynosComponent, __FUNCTION__,
+                            pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum,
+                            pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.eColorFormat,
+                            pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.eFilledDataType,
+                            maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType);
+
+        pInputPortDefinition->format.video.nFrameWidth     = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight    = codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride         = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight    = codecOutbufConf.nFrameHeight;
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            pOutputPortDefinition->nBufferCountActual  = maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin     = maxDPBNum;
+        }
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        if (eOutputExcepState == GENERAL_STATE) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* crop info of contents is changed */
+    if ((codecOutbufConf.cropRect.nTop != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nTop) ||
+        (codecOutbufConf.cropRect.nLeft != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nLeft) ||
+        (codecOutbufConf.cropRect.nWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nWidth) ||
+        (codecOutbufConf.cropRect.nHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nHeight)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nWidth,
+                            pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nHeight,
+                            codecOutbufConf.cropRect.nWidth,
+                            codecOutbufConf.cropRect.nHeight);
+
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    Exynos_OSAL_Memcpy(&pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf, &codecOutbufConf, sizeof(codecOutbufConf));
+    pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum = maxDPBNum;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecUpdateResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec          = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    ExynosVideoDecOps             *pDecOps            = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+
+    OMX_CONFIG_RECTTYPE             *pCropRectangle         = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE    *pInputPortDefinition   = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE    *pOutputPortDefinition  = NULL;
+
+    FunctionIn();
+
+    /* get geometry for output */
+    Exynos_OSAL_Memset(&pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get geometry about output", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedHeader;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum += EXTRA_DPB_NUM;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] maxDPBNum: %d", pExynosComponent, __FUNCTION__, pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum);
+
+    /* get interlace info */
+    if (pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE)
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] contents is interlaced type", pExynosComponent, __FUNCTION__);
+
+    pCropRectangle          = &(pOutputPort->cropRectangle);
+    pInputPortDefinition    = &(pInputPort->portDefinition);
+    pOutputPortDefinition   = &(pOutputPort->portDefinition);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] past info: width(%d) height(%d)",
+                                            pExynosComponent, __FUNCTION__,
+                                            pInputPortDefinition->format.video.nFrameWidth,
+                                            pInputPortDefinition->format.video.nFrameHeight);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] resolution info: width(%d / %d), height(%d / %d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth,
+                                        pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nWidth,
+                                        pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight,
+                                        pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nHeight);
+
+    pCropRectangle->nTop     = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nHeight;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth  = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride      = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight;
+#if 0
+            /* don't need to change */
+            pOutputPortDefinition->nBufferCountActual       = pOutputPort->portDefinition.nBufferCountActual;
+            pOutputPortDefinition->nBufferCountMin          = pOutputPort->portDefinition.nBufferCountMin;
+#endif
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight) ||
+            ((OMX_S32)pOutputPortDefinition->nBufferCountActual != pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth  = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride      = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight;
+
+            pOutputPortDefinition->nBufferCountActual       = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin          = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum;
+
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* contents has crop info */
+    if ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nWidth) ||
+        (pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nHeight)) {
+        pInputPortDefinition->format.video.nFrameWidth  = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride      = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight;
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged) with crop",
+                                                pExynosComponent, __FUNCTION__);
+
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec         = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+    OMX_COLOR_FORMATTYPE           eOutputFormat     = pExynosOutputPort->portDefinition.format.video.eColorFormat;
+
+    ExynosVideoDecOps       *pDecOps    = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_U32  nInBufferCnt   = 0;
+    OMX_BOOL bSupportFormat = OMX_FALSE;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pMpeg4Dec->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pVideoDec->bThumbnailMode == OMX_TRUE)
+        pDecOps->Set_IFrameDecoding(hMFCHandle);
+
+    if ((pDecOps->Enable_DTSMode != NULL) &&
+        (pVideoDec->bDTSMode == OMX_TRUE))
+        pDecOps->Enable_DTSMode(hMFCHandle);
+
+    /* input buffer info */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
+        bufferConf.eCompressionFormat = VIDEO_CODING_MPEG4;
+    else
+        bufferConf.eCompressionFormat = VIDEO_CODING_H263;
+
+    pInbufOps->Set_Shareable(hMFCHandle);
+
+    nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        /* OMX buffer is not used directly : CODEC buffer */
+        nAllocLen[0] = pSrcInputData->allocSize;
+    }
+
+    bufferConf.nSizeImage = nAllocLen[0];
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+    nInBufferCnt = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    /* should be done before prepare input buffer */
+    if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set output geometry */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+    bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] omx format(0x%x) is %s by h/w",
+                                            pExynosComponent, __FUNCTION__, eOutputFormat,
+                                            (bSupportFormat == OMX_TRUE)? "supported":"not supported");
+    if (bSupportFormat == OMX_TRUE) {  /* supported by H/W */
+        bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eOutputFormat, pExynosOutputPort->ePlaneType);
+        Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pExynosOutputPort->ePlaneType));
+    } else {
+        OMX_COLOR_FORMATTYPE eCheckFormat = OMX_SEC_COLOR_FormatNV12Tiled;
+        bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        if (bSupportFormat != OMX_TRUE) {
+            eCheckFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+            bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        }
+        if (bSupportFormat == OMX_TRUE) {  /* supported by CSC(NV12T/NV12 -> format) */
+            bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eCheckFormat, pExynosOutputPort->ePlaneType);
+            Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eCheckFormat, pExynosOutputPort->ePlaneType));
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not support this format (0x%x)", pExynosComponent, __FUNCTION__, eOutputFormat);
+            ret = OMX_ErrorNotImplemented;
+            pInbufOps->Cleanup_Buffer(hMFCHandle);
+            goto EXIT;
+        }
+    }
+
+    pMpeg4Dec->hMFCMpeg4Handle.MFCOutputColorType = bufferConf.eColorFormat;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output video format is 0x%x",
+                                            pExynosComponent, __FUNCTION__, bufferConf.eColorFormat);
+
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    /* input buffer enqueue for header parsing */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+
+    if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pSrcInputData->buffer.addr,
+                            (unsigned long *)pSrcInputData->buffer.fd,
+                            nAllocLen,
+                            nDataLen,
+                            Exynos_GetPlaneFromPort(pExynosInputPort),
+                            pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enqueue input buffer for header parsing", pExynosComponent, __FUNCTION__);
+//        ret = OMX_ErrorInsufficientResources;
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_TRUE;
+
+    /* start header parsing */
+    if (Mpeg4CodecStart(pOMXComponent, INPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run input buffer for header parsing", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    ret = Mpeg4CodecUpdateResolution(pOMXComponent);
+    if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+        (pExynosComponent->codecType != HW_VIDEO_DEC_SECURE_CODEC) &&
+        (oneFrameSize >= 8)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...", pExynosComponent, __FUNCTION__,
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0])    , *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 1),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 2), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 3),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 4), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 5),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 6), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 7));
+    }
+
+    if (ret != OMX_ErrorNone) {
+        Mpeg4CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_SleepMillisec(0);
+    ret = (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] first frame will be re-pushed to input", pExynosComponent, __FUNCTION__);
+
+    Mpeg4CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecOps       *pDecOps    = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nOutbufs, nPlaneCnt;
+
+    FunctionIn();
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++)
+        nAllocLen[i] = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nAlignPlaneSize[i];
+
+    Mpeg4CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    /* for adaptive playback */
+    if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enable Dynamic DPB", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if ((IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) &&
+        (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4))
+        pDecOps->Enable_PackedPB(hMFCHandle);
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare output buffer */
+        if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        /* get dpb count */
+        nOutbufs = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        /* Enqueue output buffer */
+        for (i = 0; i < nOutbufs; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+                            (unsigned long *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+                            pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+                            nDataLen,
+                            nPlaneCnt,
+                            NULL);
+        }
+
+        pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* get dpb count */
+        nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+        if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pExynosOutputPort->eMetaDataType == METADATA_TYPE_DISABLED) {
+            /*************/
+            /*    TBD    */
+            /*************/
+            /* data buffer : user buffer
+             * H/W can't accept user buffer directly
+             */
+            ret = OMX_ErrorNotImplemented;
+            goto EXIT;
+        }
+
+        pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE;
+    }
+
+    if (Mpeg4CodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec         = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg4Dec  = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoMpeg4:
+    {
+        OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstMpeg4Param->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstMpeg4Param->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstMpeg4Param) + nOffset,
+                           ((char *)pSrcMpeg4Param) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_MPEG4TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamVideoH263:
+    {
+        OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstH263Param->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcH263Param = &pMpeg4Dec->h263Component[pDstH263Param->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstH263Param) + nOffset,
+                           ((char *)pSrcH263Param) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_H263TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_S32                      codecType;
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType;
+        if (codecType == CODEC_TYPE_MPEG4)
+            Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE);
+        else
+            Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_MPEG4TYPE        *pSrcMpeg4Param   = NULL;
+        OMX_VIDEO_PARAM_H263TYPE         *pSrcH263Param    = NULL;
+        OMX_S32                           codecType;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType;
+        if (codecType == CODEC_TYPE_MPEG4) {
+            pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstProfileLevel->nPortIndex];
+            pDstProfileLevel->eProfile = pSrcMpeg4Param->eProfile;
+            pDstProfileLevel->eLevel = pSrcMpeg4Param->eLevel;
+        } else {
+            pSrcH263Param = &pMpeg4Dec->h263Component[pDstProfileLevel->nPortIndex];
+            pDstProfileLevel->eProfile = pSrcH263Param->eProfile;
+            pDstProfileLevel->eLevel = pSrcH263Param->eLevel;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexExynosParamReorderMode:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *pReorderParam = (EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pReorderParam, sizeof(EXYNOS_OMX_VIDEO_PARAM_REORDERMODE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pReorderParam->bReorderMode = pVideoDec->bReorderMode;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec         = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg4Dec  = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoMpeg4:
+    {
+        OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL;
+        OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcMpeg4Param->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcMpeg4Param->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstMpeg4Param) + nOffset,
+                           ((char *)pSrcMpeg4Param) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_MPEG4TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamVideoH263:
+    {
+        OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL;
+        OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcH263Param->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstH263Param = &pMpeg4Dec->h263Component[pSrcH263Param->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstH263Param) + nOffset,
+                           ((char *)pSrcH263Param) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_H263TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE)) {
+            pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
+        } else if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE)) {
+            pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_MPEG4TYPE        *pDstMpeg4Param   = NULL;
+        OMX_VIDEO_PARAM_H263TYPE         *pDstH263Param    = NULL;
+        OMX_S32                           codecType;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType;
+        if (codecType == CODEC_TYPE_MPEG4) {
+            /*
+             * To do: Check validity of profile & level parameters
+             */
+
+            pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcProfileLevel->nPortIndex];
+            pDstMpeg4Param->eProfile = pSrcProfileLevel->eProfile;
+            pDstMpeg4Param->eLevel = pSrcProfileLevel->eLevel;
+        } else {
+            /*
+             * To do: Check validity of profile & level parameters
+             */
+
+            pDstH263Param = &pMpeg4Dec->h263Component[pSrcProfileLevel->nPortIndex];
+            pDstH263Param->eProfile = pSrcProfileLevel->eProfile;
+            pDstH263Param->eLevel = pSrcProfileLevel->eLevel;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexExynosParamReorderMode:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *pReorderParam = (EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pReorderParam, sizeof(EXYNOS_OMX_VIDEO_PARAM_REORDERMODE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pVideoDec->bReorderMode = pReorderParam->bReorderMode;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_GetConfig(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec         = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg4Dec  = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch (nIndex) {
+    case OMX_IndexConfigCommonOutputCrop:
+    {
+        EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+        OMX_CONFIG_RECTTYPE *pSrcRectType  = NULL;
+        OMX_CONFIG_RECTTYPE *pDstRectType  = NULL;
+
+        if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc == OMX_FALSE) {
+            ret = OMX_ErrorNotReady;
+            break;
+        }
+
+        pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
+
+        if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) &&
+            (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex];
+
+        pSrcRectType = &(pExynosPort->cropRectangle);
+
+        pDstRectType->nTop    = pSrcRectType->nTop;
+        pDstRectType->nLeft   = pSrcRectType->nLeft;
+        pDstRectType->nHeight = pSrcRectType->nHeight;
+        pDstRectType->nWidth  = pSrcRectType->nWidth;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_SetConfig(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec         = NULL;
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg4Dec  = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    switch (nIndex) {
+    default:
+        ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_GetExtensionIndex(
+    OMX_IN  OMX_HANDLETYPE  hComponent,
+    OMX_IN  OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE  *pIndexType)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_REORDER_MODE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamReorderMode;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_ComponentRoleEnum(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_OUT OMX_U8        *cRole,
+    OMX_IN  OMX_U32        nIndex)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+    OMX_S32                   codecType;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) || (cRole == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid ) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    codecType = ((EXYNOS_MPEG4DEC_HANDLE *)(((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType;
+    if (codecType == CODEC_TYPE_MPEG4)
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE);
+    else
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec         = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    ExynosVideoInstInfo *pVideoInstInfo = &(pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo);
+
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+    int i;
+
+    FunctionIn();
+
+    pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE;
+    pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    pVideoDec->bDiscardCSDError = OMX_FALSE;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                             pExynosInputPort->portDefinition.format.video.nBitrate,
+                                                                                             pExynosInputPort->portDefinition.format.video.xFramerate);
+
+    pVideoInstInfo->nSize        = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth       = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight      = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate     = pExynosInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate   = pExynosInputPort->portDefinition.format.video.xFramerate;
+
+    /* Mpeg4 Codec Open */
+    ret = Mpeg4CodecOpen(pMpeg4Dec, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+        nAllocLen[0] = ALIGN(pExynosInputPort->portDefinition.format.video.nFrameWidth *
+                             pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+        if (nAllocLen[0] < pVideoDec->nMinInBufSize)
+            nAllocLen[0] = pVideoDec->nMinInBufSize;
+
+        Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_SetPlaneToPort(pExynosOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pMpeg4Dec->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pMpeg4Dec->hSourceStartEvent);
+    pMpeg4Dec->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pMpeg4Dec->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pMpeg4Dec->hDestinationOutStartEvent);
+
+    Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp = 0;
+    pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = 0;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pMpeg4Dec->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) {
+        pVideoDec->csc_handle = csc_init(CSC_METHOD_HW);
+        csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2);
+        csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_MODE_DRM, 1);
+    } else {
+        pVideoDec->csc_handle = csc_init(csc_method);
+    }
+
+    if (pVideoDec->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    pVideoDec->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_Mpeg4Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if (pVideoDec->csc_handle != NULL) {
+        csc_deinit(pVideoDec->csc_handle);
+        pVideoDec->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pMpeg4Dec->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pMpeg4Dec->hDestinationInStartEvent);
+    pMpeg4Dec->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pMpeg4Dec->hDestinationOutStartEvent);
+    pMpeg4Dec->hDestinationOutStartEvent = NULL;
+    pMpeg4Dec->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pMpeg4Dec->hSourceStartEvent);
+    pMpeg4Dec->hSourceStartEvent = NULL;
+    pMpeg4Dec->bSourceStart = OMX_FALSE;
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
+        pExynosOutputPort->codecSemID = NULL;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
+        pExynosInputPort->codecSemID = NULL;
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+    Mpeg4CodecClose(pMpeg4Dec);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec         = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+
+    ExynosVideoDecOps       *pDecOps     = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps   = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_BOOL bInStartCode = OMX_FALSE;
+
+    FunctionIn();
+
+    if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = Mpeg4CodecSrcSetup(pOMXComponent, pSrcInputData);
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (pMpeg4Dec->bDestinationStart == OMX_FALSE) &&
+        (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+        ret = Mpeg4CodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to MPEG4CodecDstSetup(0x%x)",
+                                            pExynosComponent, __FUNCTION__, ret);
+            goto EXIT;
+        }
+    }
+
+    if (((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) ||
+        ((bInStartCode = Check_Stream_StartCode(pSrcInputData->buffer.addr[0], oneFrameSize, pMpeg4Dec->hMFCMpeg4Handle.codecType)) == OMX_TRUE)) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+
+        if (pVideoDec->bReorderMode == OMX_FALSE) {
+            /* next slot will be used like as circular queue */
+            pExynosComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->timeStamp;
+            pExynosComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp]    = pSrcInputData->nFlags;
+        } else {  /* MSRND */
+            Exynos_SetReorderTimestamp(pExynosComponent, &(pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp), pSrcInputData->timeStamp, pSrcInputData->nFlags);
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), dataLen(%d), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, oneFrameSize, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp);
+
+        pDecOps->Set_FrameTag(hMFCHandle, pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp);
+        pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++;
+        pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP;
+
+        if ((pVideoDec->bQosChanged == OMX_TRUE) &&
+            (pDecOps->Set_QosRatio != NULL)) {
+            pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
+            pVideoDec->bQosChanged = OMX_FALSE;
+        }
+
+        if (pVideoDec->bSearchBlackBarChanged == OMX_TRUE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] BlackBar searching mode : %s",
+                                            pExynosComponent, __FUNCTION__,
+                                            (pVideoDec->bSearchBlackBar == OMX_TRUE) ? "enable" : "disable");
+            pDecOps->Set_SearchBlackBar(hMFCHandle, (ExynosVideoBoolType)pVideoDec->bSearchBlackBar);
+            pVideoDec->bSearchBlackBarChanged = OMX_FALSE;
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        /* queue work for input buffer */
+        nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+        if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        } else {
+            nAllocLen[0] = pSrcInputData->allocSize;
+
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        }
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pSrcInputData->buffer.addr,
+                                (unsigned long *)pSrcInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pExynosInputPort),
+                                pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            goto EXIT;
+        }
+        Mpeg4CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        if (pMpeg4Dec->bSourceStart == OMX_FALSE) {
+            pMpeg4Dec->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pMpeg4Dec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        if ((pMpeg4Dec->bDestinationStart == OMX_FALSE) &&
+            (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE)) {
+            pMpeg4Dec->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    } else if (bInStartCode == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] can't find a start code", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedFrame;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pInbufOps      = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->allocSize  = 0;
+        pSrcOutputData->pPrivate = NULL;
+    } else {
+        pSrcOutputData->buffer.addr[0] = pVideoBuffer->planes[0].addr;
+        pSrcOutputData->buffer.fd[0] = pVideoBuffer->planes[0].fd;
+        pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
+
+        if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] ==
+                        pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
+                    pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pExynosInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pOutbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++) {
+        nAllocLen[i] = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nAlignPlaneSize[i];
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] ADDR[%d]: 0x%x, size[%d]: %d", pExynosComponent, __FUNCTION__,
+                                        i, pDstInputData->buffer.addr[i], i, nAllocLen[i]);
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                nPlaneCnt,
+                                pDstInputData->bufferHeader);
+
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+        }
+
+        goto EXIT;
+    }
+
+    Mpeg4CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    DECODE_CODEC_EXTRA_BUFFERINFO   *pBufferInfo        = NULL;
+
+    ExynosVideoDecOps           *pDecOps        = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+    ExynosVideoDecBufferOps     *pOutbufOps     = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+    ExynosVideoBuffer           *pVideoBuffer   = NULL;
+    ExynosVideoBuffer            videoBuffer;
+    ExynosVideoFrameStatusType   displayStatus  = VIDEO_FRAME_STATUS_UNKNOWN;
+    ExynosVideoGeometry         *bufferGeometry = NULL;
+    ExynosVideoErrorType         codecReturn    = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+
+    OMX_S32 indexTimestamp = 0;
+    int plane, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pMpeg4Dec->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    while (1) {
+        Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer));
+
+        codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+        if (codecReturn == VIDEO_ERROR_NONE) {
+            pVideoBuffer = &videoBuffer;
+        } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO) at ExtensionDequeue", pExynosComponent, __FUNCTION__);
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorHardware;
+            goto EXIT;
+        } else {
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        displayStatus = pVideoBuffer->displayStatus;
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus: 0x%x", pExynosComponent, __FUNCTION__, displayStatus);
+
+        if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
+            (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+            (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+            (CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+            ret = OMX_ErrorNone;
+            break;
+        }
+    }
+
+    if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+        (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) {
+        if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+            pOutputPort->exceptionFlag = NEED_PORT_FLUSH;
+            pVideoDec->bReconfigDPB = OMX_TRUE;
+            Mpeg4CodecUpdateResolution(pOMXComponent);
+            pVideoDec->csc_set_format = OMX_FALSE;
+        }
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) {
+        pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp++;
+        pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+    }
+
+    pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
+    nPlaneCnt = Exynos_GetPlaneFromPort(pOutputPort);
+    for (plane = 0; plane < nPlaneCnt; plane++) {
+        pDstOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+        pDstOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+        pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        pDstOutputData->dataLen   += pVideoBuffer->planes[plane].dataSize;
+        nDataLen[plane]            = pVideoBuffer->planes[plane].dataSize;
+    }
+    pDstOutputData->usedDataLen = 0;
+    pDstOutputData->pPrivate = pVideoBuffer;
+
+    pBufferInfo     = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+    bufferGeometry  = &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf;
+    pBufferInfo->imageWidth       = bufferGeometry->nFrameWidth;
+    pBufferInfo->imageHeight      = bufferGeometry->nFrameHeight;
+    pBufferInfo->imageStride      = bufferGeometry->nStride;
+    pBufferInfo->cropRect.nLeft   = bufferGeometry->cropRect.nLeft;
+    pBufferInfo->cropRect.nTop    = bufferGeometry->cropRect.nTop;
+    pBufferInfo->cropRect.nWidth  = bufferGeometry->cropRect.nWidth;
+    pBufferInfo->cropRect.nHeight = bufferGeometry->cropRect.nHeight;
+    pBufferInfo->colorFormat      = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+    Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            goto EXIT;
+        }
+
+        /* calculate each plane info for the application */
+        Exynos_OSAL_GetPlaneSize(pOutputPort->portDefinition.format.video.eColorFormat,
+                                 PLANE_SINGLE, pOutputPort->portDefinition.format.video.nFrameWidth,
+                                 pOutputPort->portDefinition.format.video.nFrameHeight,
+                                 nDataLen, nAllocLen);
+
+        pDstOutputData->allocSize = nAllocLen[0] + nAllocLen[1] + nAllocLen[2];
+        pDstOutputData->dataLen   = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+#ifdef USE_ANDROID
+    /* get interlace frame info */
+    if ((pOutputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
+        (pVideoBuffer->planes[2].addr != NULL)) {
+        ExynosVideoMeta *pMeta = (ExynosVideoMeta *)pVideoBuffer->planes[2].addr;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] interlace type = %x", pExynosComponent, __FUNCTION__, pVideoBuffer->interlacedType);
+        pMeta->eType = VIDEO_INFO_TYPE_INTERLACED;
+        pMeta->data.dec.nInterlacedType = pVideoBuffer->interlacedType;
+    }
+#endif
+
+    indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+    if (pVideoDec->bReorderMode == OMX_FALSE) {
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
+                (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
+                if (indexTimestamp == INDEX_AFTER_EOS) {
+                    pDstOutputData->timeStamp = 0x00;
+                    pDstOutputData->nFlags = 0x00;
+                } else {
+                    pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp];
+                    pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp];
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] missing out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+                }
+            } else {
+                pDstOutputData->timeStamp = 0x00;
+                pDstOutputData->nFlags = 0x00;
+            }
+        } else {
+            /* For timestamp correction. if mfc support frametype detect */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] disp_pic_frame_type: %d", pExynosComponent, __FUNCTION__, pVideoBuffer->frameType);
+
+            /* NEED TIMESTAMP REORDER */
+            if (pVideoDec->bDTSMode == OMX_TRUE) {
+                if ((pVideoBuffer->frameType & VIDEO_FRAME_I) ||
+                    ((pVideoBuffer->frameType & VIDEO_FRAME_OTHERS) &&
+                        ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
+                    (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
+                    pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = indexTimestamp;
+                else
+                    indexTimestamp = pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp;
+            }
+
+            pDstOutputData->timeStamp   = pExynosComponent->timeStamp[indexTimestamp];
+            pDstOutputData->nFlags      = pExynosComponent->nFlags[indexTimestamp] | OMX_BUFFERFLAG_ENDOFFRAME;
+
+            if (pVideoBuffer->frameType & VIDEO_FRAME_I)
+                pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+            if (pVideoBuffer->frameType & VIDEO_FRAME_CORRUPT)
+                pDstOutputData->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                                    pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                                    indexTimestamp);
+    } else {  /* MSRND */
+        EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP sCurrentTimestamp;
+
+        Exynos_GetReorderTimestamp(pExynosComponent, &sCurrentTimestamp, indexTimestamp, pVideoBuffer->frameType);
+
+        pDstOutputData->timeStamp   = sCurrentTimestamp.timeStamp;
+        pDstOutputData->nFlags      = sCurrentTimestamp.nFlags | OMX_BUFFERFLAG_ENDOFFRAME;
+
+        pExynosComponent->nFlags[sCurrentTimestamp.nIndex]               = 0x00;
+        pExynosComponent->bTimestampSlotUsed[sCurrentTimestamp.nIndex]   = OMX_FALSE;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), reordered tag: %d, original tag: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                                    pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                                    sCurrentTimestamp.nIndex,
+                                                    indexTimestamp);
+    }
+
+    if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_H263) {
+        pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp++;
+        pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+    }
+
+    if (pVideoBuffer->frameType & VIDEO_FRAME_WITH_BLACK_BAR) {
+        if (Mpeg4CodecUpdateBlackBarCrop(pOMXComponent) != OMX_ErrorNone)
+            goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+        (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+    }
+
+    if (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) {
+        pDstOutputData->remainDataLen = 0;
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            if (indexTimestamp != INDEX_AFTER_EOS)
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] tag(%d) is wrong", pExynosComponent, __FUNCTION__, indexTimestamp);
+            pDstOutputData->timeStamp   = 0x00;
+            pDstOutputData->nFlags      = 0x00;
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) ||
+            (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+            pExynosComponent->nFlags[indexTimestamp] &= (~OMX_BUFFERFLAG_EOS);
+        }
+    } else if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        pDstOutputData->remainDataLen = 0;
+
+        if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
+            pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+
+            if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+                pExynosComponent->bBehaviorEOS = OMX_FALSE;
+            } else {
+                pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+                pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+            }
+        }
+    } else {
+        pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_Mpeg4Dec_SrcIn(pOMXComponent, pSrcInputData);
+    if ((ret != OMX_ErrorNone) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorCorruptedFrame)) {
+
+        if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+            (pVideoDec->bDiscardCSDError == OMX_TRUE)) {
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+    if ((pMpeg4Dec->bSourceStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
+        Exynos_OSAL_SignalWait(pMpeg4Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pMpeg4Dec->hSourceStartEvent);
+    }
+
+    ret = Exynos_Mpeg4Dec_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        if (pExynosComponent->currentState == OMX_StatePause)
+            ret = (OMX_ERRORTYPE)OMX_ErrorOutputBufferUseYet;
+        else
+            ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pMpeg4Dec->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationInStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pMpeg4Dec->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pMpeg4Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+            (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+            ret = Mpeg4CodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to MPEG4CodecDstSetup(0x%x)", pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+            Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationOutStartEvent);
+        }
+    }
+
+    if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_Mpeg4Dec_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4DEC_HANDLE          *pMpeg4Dec          = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (((pMpeg4Dec->bDestinationStart == OMX_FALSE) ||
+         (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE)) &&
+        (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationOutStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pMpeg4Dec->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pMpeg4Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_Mpeg4Dec_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = NULL;
+    EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec        = NULL;
+    OMX_BOOL                       bSecureMode      = OMX_FALSE;
+    int i = 0;
+    OMX_S32 codecType = -1;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) || (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG4_DEC, componentName) == 0) {
+        codecType = CODEC_TYPE_MPEG4;
+        bSecureMode = OMX_FALSE;
+    } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H263_DEC, componentName) == 0) {
+        codecType = CODEC_TYPE_H263;
+        bSecureMode = OMX_FALSE;
+    } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG4_DRM_DEC, componentName) == 0) {
+        codecType = CODEC_TYPE_MPEG4;
+        bSecureMode = OMX_TRUE;
+    } else {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = (bSecureMode == OMX_TRUE)? HW_VIDEO_DEC_SECURE_CODEC:HW_VIDEO_DEC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pMpeg4Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MPEG4DEC_HANDLE));
+    if (pMpeg4Dec == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pMpeg4Dec, 0, sizeof(EXYNOS_MPEG4DEC_HANDLE));
+    pVideoDec               = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Dec;
+    pMpeg4Dec->hMFCMpeg4Handle.codecType = codecType;
+    Exynos_OSAL_Strcpy(pExynosComponent->componentName, componentName);
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE)
+        pExynosPort->portDefinition.nBufferSize = CUSTOM_DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+
+    pVideoDec->nMinInBufSize = DEFAULT_VIDEO_MIN_INPUT_BUFFER_SIZE;  /* for DRC */
+
+    if (codecType == CODEC_TYPE_MPEG4) {
+        pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
+        Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+        Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/mpeg4");
+    } else {
+        pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
+        Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+        Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/h263");
+    }
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+#ifdef USE_SINGLE_PLANE_IN_DRM
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        pExynosPort->ePlaneType = PLANE_SINGLE;
+#endif
+
+    if (codecType == CODEC_TYPE_MPEG4) {
+        for(i = 0; i < ALL_PORT_NUM; i++) {
+            INIT_SET_SIZE_VERSION(&pMpeg4Dec->mpeg4Component[i], OMX_VIDEO_PARAM_MPEG4TYPE);
+            pMpeg4Dec->mpeg4Component[i].nPortIndex = i;
+            pMpeg4Dec->mpeg4Component[i].eProfile   = OMX_VIDEO_MPEG4ProfileSimple;
+            pMpeg4Dec->mpeg4Component[i].eLevel     = OMX_VIDEO_MPEG4Level3;
+        }
+    } else {
+        for(i = 0; i < ALL_PORT_NUM; i++) {
+            INIT_SET_SIZE_VERSION(&pMpeg4Dec->h263Component[i], OMX_VIDEO_PARAM_H263TYPE);
+            pMpeg4Dec->h263Component[i].nPortIndex = i;
+            pMpeg4Dec->h263Component[i].eProfile   = OMX_VIDEO_H263ProfileBaseline | OMX_VIDEO_H263ProfileISWV2;
+            pMpeg4Dec->h263Component[i].eLevel     = OMX_VIDEO_H263Level45;
+        }
+    }
+
+    pOMXComponent->GetParameter      = &Exynos_Mpeg4Dec_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_Mpeg4Dec_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_Mpeg4Dec_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_Mpeg4Dec_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_Mpeg4Dec_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_Mpeg4Dec_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_Mpeg4Dec_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_Mpeg4Dec_Terminate;
+
+    pVideoDec->exynos_codec_srcInputProcess  = &Exynos_Mpeg4Dec_srcInputBufferProcess;
+    pVideoDec->exynos_codec_srcOutputProcess = &Exynos_Mpeg4Dec_srcOutputBufferProcess;
+    pVideoDec->exynos_codec_dstInputProcess  = &Exynos_Mpeg4Dec_dstInputBufferProcess;
+    pVideoDec->exynos_codec_dstOutputProcess = &Exynos_Mpeg4Dec_dstOutputBufferProcess;
+
+    pVideoDec->exynos_codec_start            = &Mpeg4CodecStart;
+    pVideoDec->exynos_codec_stop             = &Mpeg4CodecStop;
+    pVideoDec->exynos_codec_bufferProcessRun = &Mpeg4CodecOutputBufferProcessRun;
+    pVideoDec->exynos_codec_enqueueAllBuffer = &Mpeg4CodecEnQueueAllBuffer;
+
+    pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+    pVideoDec->exynos_codec_reconfigAllBuffers        = &Mpeg4CodecReconfigAllBuffers;
+
+    pVideoDec->exynos_codec_checkFormatSupport      = &CheckFormatHWSupport;
+    pVideoDec->exynos_codec_checkResolutionChange   = &Mpeg4CodecCheckResolution;
+
+    pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoDec->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pMpeg4Dec);
+        pMpeg4Dec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
+        pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.eCodecType = VIDEO_CODING_MPEG4;
+    else
+        pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.eCodecType = VIDEO_CODING_H263;
+
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo), VIDEO_TRUE /* dec */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pMpeg4Dec);
+        pMpeg4Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+        pMpeg4Dec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_Output_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE            ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE       *pOMXComponent = NULL;
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+    EXYNOS_MPEG4DEC_HANDLE      *pMpeg4Dec = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent       = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent    = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoDec           = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pMpeg4Dec != NULL) {
+        Exynos_OSAL_Free(pMpeg4Dec);
+        pMpeg4Dec = pVideoDec->hCodecHandle = NULL;
+    }
+
+    ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h b/openmax/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.h
new file mode 100755 (executable)
index 0000000..ab40aec
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Mpeg4dec.h
+ * @brief
+ * @author      Yunji Kim (yunji.kim@samsung.com)
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_MPEG4_DEC_COMPONENT
+#define EXYNOS_OMX_MPEG4_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+#include "ExynosVideoApi.h"
+
+
+typedef enum _CODEC_TYPE
+{
+    CODEC_TYPE_H263,
+    CODEC_TYPE_MPEG4
+} CODEC_TYPE;
+
+/*
+ * This structure is the same as BitmapInfoHhr struct in pv_avifile_typedefs.h file
+ */
+typedef struct _BitmapInfoHhr
+{
+    OMX_U32    BiSize;
+    OMX_U32    BiWidth;
+    OMX_U32    BiHeight;
+    OMX_U16    BiPlanes;
+    OMX_U16    BiBitCount;
+    OMX_U32    BiCompression;
+    OMX_U32    BiSizeImage;
+    OMX_U32    BiXPelsPerMeter;
+    OMX_U32    BiYPelsPerMeter;
+    OMX_U32    BiClrUsed;
+    OMX_U32    BiClrImportant;
+} BitmapInfoHhr;
+
+typedef struct _EXYNOS_MFC_MPEG4DEC_HANDLE
+{
+    OMX_HANDLETYPE             hMFCHandle;
+    OMX_U32                    indexTimestamp;
+    OMX_U32                    outputIndexTimestamp;
+    OMX_BOOL                   bConfiguredMFCSrc;
+    OMX_BOOL                   bConfiguredMFCDst;
+    OMX_S32                    maxDPBNum;
+    CODEC_TYPE                 codecType;
+
+    ExynosVideoColorFormatType MFCOutputColorType;
+    ExynosVideoDecOps         *pDecOps;
+    ExynosVideoDecBufferOps   *pInbufOps;
+    ExynosVideoDecBufferOps   *pOutbufOps;
+    ExynosVideoGeometry        codecOutbufConf;
+    ExynosVideoInstInfo        videoInstInfo;
+
+    #define MAX_PROFILE_NUM 4
+    OMX_S32 profiles[MAX_PROFILE_NUM];
+    OMX_S32 nProfileCnt;
+    OMX_S32 maxLevel;
+} EXYNOS_MFC_MPEG4DEC_HANDLE;
+
+typedef struct _EXYNOS_MPEG4DEC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_H263TYPE            h263Component[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_MPEG4TYPE           mpeg4Component[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+
+    /* EXYNOS MFC Codec specific */
+    EXYNOS_MFC_MPEG4DEC_HANDLE          hMFCMpeg4Handle;
+
+    OMX_BOOL bSourceStart;
+    OMX_BOOL bDestinationStart;
+    OMX_HANDLETYPE hSourceStartEvent;
+    OMX_HANDLETYPE hDestinationInStartEvent;
+    OMX_HANDLETYPE hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE bypassBufferInfoQ;
+} EXYNOS_MPEG4DEC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE hComponent,
+    OMX_STRING componentName);
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
+    OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Mpeg4CodecDstSetup(
+    OMX_COMPONENTTYPE *pOMXComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/mpeg4/Makefile.am b/openmax/component/video/dec/mpeg4/Makefile.am
new file mode 100755 (executable)
index 0000000..8370caa
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libOMX.Exynos.MPEG4.Decoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_MPEG4_Decoder_la_SOURCES = Exynos_OMX_Mpeg4dec.c \
+                                         library_register.c
+
+libOMX_Exynos_MPEG4_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                        $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                        $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                        $(top_builddir)/openmax/component/video/dec/libExynosOMX_Vdec.la \
+                                      $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+libOMX_Exynos_MPEG4_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                        -I$(top_srcdir)/openmax/include/exynos \
+                                        -I$(top_srcdir)/openmax/osal \
+                                        -I$(top_srcdir)/openmax/core \
+                                        -I$(top_srcdir)/openmax/component/common \
+                                        -I$(top_srcdir)/openmax/component/video/dec \
+                                      -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_MPEG4_Decoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
+libOMX_Exynos_MPEG4_Decoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable
+
+libOMX_Exynos_MPEG4_Decoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/dec/mpeg4/library_register.c b/openmax/component/video/dec/mpeg4/library_register.c
new file mode 100755 (executable)
index 0000000..e55c680
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.c
+ * @brief
+ * @author      Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_MPEG4_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(
+    ExynosRegisterComponentType **ppExynosComponent)
+{
+    FunctionIn();
+
+    if (ppExynosComponent == NULL)
+        goto EXIT;
+
+    /* component 1 - video decoder MPEG4 */
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_MPEG4_DEC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE);
+    ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+    /* component 2 - video decoder MPEG4 for DRM*/
+    Exynos_OSAL_Strcpy(ppExynosComponent[1]->componentName, EXYNOS_OMX_COMPONENT_MPEG4_DRM_DEC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[1]->roles[0], EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE);
+    ppExynosComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+    /* component 3 - video decoder H.263 */
+    Exynos_OSAL_Strcpy(ppExynosComponent[2]->componentName, EXYNOS_OMX_COMPONENT_H263_DEC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[2]->roles[0], EXYNOS_OMX_COMPONENT_H263_DEC_ROLE);
+    ppExynosComponent[2]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
diff --git a/openmax/component/video/dec/mpeg4/library_register.h b/openmax/component/video/dec/mpeg4/library_register.h
new file mode 100755 (executable)
index 0000000..ed95a44
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author      Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_MPEG4_DEC_REG
+#define EXYNOS_OMX_MPEG4_DEC_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM         3
+#define MAX_COMPONENT_ROLE_NUM    1
+
+/* MPEG4 */
+#ifndef USE_CUSTOM_COMPONENT_SUPPORT
+#define EXYNOS_OMX_COMPONENT_MPEG4_DEC            "OMX.Exynos.MPEG4.Decoder"
+#define EXYNOS_OMX_COMPONENT_MPEG4_DRM_DEC        "OMX.Exynos.MPEG4.Decoder.secure"
+#else
+#define EXYNOS_OMX_COMPONENT_MPEG4_DEC            "OMX.Exynos.mpeg4.dec"
+#define EXYNOS_OMX_COMPONENT_MPEG4_DRM_DEC        "OMX.Exynos.mpeg4.dec.secure"
+#endif
+
+#define EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE       "video_decoder.mpeg4"
+
+
+/* H.263 */
+#ifndef USE_CUSTOM_COMPONENT_SUPPORT
+#define EXYNOS_OMX_COMPONENT_H263_DEC         "OMX.Exynos.H263.Decoder"
+#else
+#define EXYNOS_OMX_COMPONENT_H263_DEC         "OMX.Exynos.h263.dec"
+#endif
+
+#define EXYNOS_OMX_COMPONENT_H263_DEC_ROLE    "video_decoder.h263"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(
+    ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.c b/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.c
new file mode 100755 (executable)
index 0000000..e28be27
--- /dev/null
@@ -0,0 +1,3374 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Wmvdec.c
+ * @brief
+ * @author      HyeYeon Chung (hyeon.chung@samsung.com)
+ * @author      Satish Kumar Reddy (palli.satish@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.07.10 : Create
+ *              : Support WMV3 (Vc-1 Simple/Main Profile)
+ *              : Support WMvC1 (Vc-1 Advanced Profile)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Vdec.h"
+#include "Exynos_OMX_VdecControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Wmvdec.h"
+#include "ExynosVideoApi.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+
+#ifdef USE_ANDROID
+#include "VendorVideoAPI.h"
+#endif
+
+/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
+/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_WMV_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+#define SL_META_LEN 36 /* sequence layer metadata length in bytes */
+
+/* Enable or disable "WMV3_ADDITIONAL_START_CODE" based on MFC F/W's need */
+//#define WMV3_ADDITIONAL_START_CODE
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec        = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pWmvDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pWmvDec->hMFCWmvHandle.profiles[nProfileCnt]   = OMX_VIDEO_VC1ProfileSimple;
+    pWmvDec->hMFCWmvHandle.maxLevel[nProfileCnt++] = OMX_VIDEO_VC1LevelMedium;
+
+    pWmvDec->hMFCWmvHandle.profiles[nProfileCnt]   = OMX_VIDEO_VC1ProfileMain;
+    pWmvDec->hMFCWmvHandle.maxLevel[nProfileCnt++] = OMX_VIDEO_VC1LevelHigh;
+
+    pWmvDec->hMFCWmvHandle.profiles[nProfileCnt]   = OMX_VIDEO_VC1ProfileAdvanced;
+    pWmvDec->hMFCWmvHandle.maxLevel[nProfileCnt++] = OMX_VIDEO_VC1Level4;
+
+    pWmvDec->hMFCWmvHandle.nProfileCnt = nProfileCnt;
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec        = NULL;
+
+    OMX_U32 nLevelCnt = 0;
+    OMX_U32 nMaxIndex = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pWmvDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pWmvDec->hMFCWmvHandle.nProfileCnt; i++)
+        nMaxIndex += pWmvDec->hMFCWmvHandle.maxLevel[i];
+
+    if ((pWmvDec->hMFCWmvHandle.nProfileCnt == 0) ||
+        (nMaxIndex == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                        pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pWmvDec->hMFCWmvHandle.nProfileCnt; i++) {
+        if (pProfileLevelType->nProfileIndex < (nLevelCnt + pWmvDec->hMFCWmvHandle.maxLevel[i])) {
+            pProfileLevelType->eProfile = pWmvDec->hMFCWmvHandle.profiles[i];
+            pProfileLevelType->eLevel   = (OMX_U32)(pProfileLevelType->nProfileIndex - nLevelCnt);
+            break;
+        }
+
+        nLevelCnt += pWmvDec->hMFCWmvHandle.maxLevel[i];
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] supported profile(%x), level(%x)",
+                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_BOOL                         ret        = OMX_FALSE;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec  = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec    = NULL;
+
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pWmvDec == NULL)
+        goto EXIT;
+
+    if (pWmvDec->hMFCWmvHandle.nProfileCnt == 0) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pWmvDec->hMFCWmvHandle.nProfileCnt; i++) {
+        if ((pWmvDec->hMFCWmvHandle.profiles[i] == pProfileLevelType->eProfile) &&
+            (pWmvDec->hMFCWmvHandle.maxLevel[i] >= pProfileLevelType->eLevel)) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (ret == OMX_TRUE)? "":"not ");
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
+{
+    OMX_ERRORTYPE       ret          = OMX_ErrorNone;
+    ExynosVideoBuffer  *pCodecBuffer = NULL;
+
+    if (codecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
+
+    if (addr != NULL) {
+        addr[0] = pCodecBuffer->planes[0].addr;
+        addr[1] = pCodecBuffer->planes[1].addr;
+        addr[2] = pCodecBuffer->planes[2].addr;
+    }
+
+    if (size != NULL) {
+        size[0] = pCodecBuffer->planes[0].allocSize;
+        size[1] = pCodecBuffer->planes[1].allocSize;
+        size[2] = pCodecBuffer->planes[2].allocSize;
+    }
+
+EXIT:
+    return ret;
+}
+
+static WMV_FORMAT getFormatType(
+    OMX_U8 *pInputStream)
+{
+    WMV_FORMAT  ret          = WMV_FORMAT_UNKNOWN;
+    OMX_BYTE    pCheckBuffer = (OMX_BYTE)pInputStream;
+
+    if (pInputStream == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] pInputStream is null", __FUNCTION__);
+        return ret;
+    }
+
+    if ((pCheckBuffer[3] == 0xC5) &&
+        (pCheckBuffer[4] == 0x04)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%s] WMV_FORMAT_WMV3", __FUNCTION__);
+        ret = WMV_FORMAT_WMV3;
+    } else if (((pCheckBuffer[3] == 0x01) &&
+                    (pCheckBuffer[4] == 0x0F)) ||
+               ((pCheckBuffer[2] == 0x01) &&
+                    (pCheckBuffer[3] == 0x0F))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%s] WMV_FORMAT_VC1", __FUNCTION__);
+        ret = WMV_FORMAT_VC1;
+    } else {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] WMV_FORMAT_UNKNOWN", __FUNCTION__);
+    }
+
+    return ret;
+}
+
+static OMX_BOOL Check_Stream_PrefixCode(
+    OMX_U8    *pInputStream,
+    OMX_U32    streamSize,
+    WMV_FORMAT wmvFormat)
+{
+    switch (wmvFormat) {
+    case WMV_FORMAT_WMV3:
+#ifdef WMV3_ADDITIONAL_START_CODE
+        return OMX_FALSE;
+#else
+        if (streamSize > 0)
+            return OMX_TRUE;
+        else
+            return OMX_FALSE;
+#endif
+        break;
+    case WMV_FORMAT_VC1:
+        /* TODO : for comformanc test based on common buffer scheme w/o parser */
+        if (streamSize < 3) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] streamSize is too small (%d)", __FUNCTION__, streamSize);
+            return OMX_FALSE;
+        } else if ((pInputStream[0] == 0x00) &&
+                   (pInputStream[1] == 0x00) &&
+                   (pInputStream[2] == 0x01)) {
+            return OMX_TRUE;
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] Cannot find prefix", __FUNCTION__);
+            return OMX_FALSE;
+        }
+        break;
+
+    default:
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] undefined wmvFormat (%d)", __FUNCTION__, wmvFormat);
+        return OMX_FALSE;
+        break;
+    }
+}
+
+OMX_BOOL Make_Stream_MetaData(
+     OMX_U8        *pInputStream,
+     OMX_U32       *pStreamSize,
+     WMV_FORMAT     wmvFormat)
+{
+    OMX_BOOL ret      = OMX_FALSE;
+    OMX_BYTE pCurrBuf = pInputStream;
+    switch ((int)wmvFormat) {
+    case WMV_FORMAT_WMV3:
+        if ((*pStreamSize) >= SL_META_LEN) {
+            (*pStreamSize) = SL_META_LEN;
+            ret = OMX_TRUE;
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] *pStreamSize is too small to contain metadata(%d)", __FUNCTION__, *pStreamSize);
+            ret = OMX_FALSE;
+        }
+        break;
+    case WMV_FORMAT_VC1:
+        if ((pInputStream[1] == 0x00) &&
+            (pInputStream[2] == 0x00) &&
+            (pInputStream[3] == 0x01) &&
+            (pInputStream[4] == 0x0F)) {
+            Exynos_OSAL_Memmove(pCurrBuf, pInputStream + 1, (*pStreamSize) - 1);
+            (*pStreamSize) -= 1;
+            ret = OMX_TRUE;
+        } else if ((pInputStream[0] == 0x00) &&
+                   (pInputStream[1] == 0x00) &&
+                   (pInputStream[2] == 0x01) &&
+                   (pInputStream[3] == 0x0F) &&
+                   ((*pStreamSize) >= 1)) {
+            ret = OMX_TRUE;
+        }
+        break;
+    default:
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] It is not necessary to make bitstream metadata for wmvFormat (%d)", __FUNCTION__, (int)wmvFormat);
+        ret = OMX_FALSE;
+        break;
+    }
+
+    return ret;
+}
+
+static OMX_BOOL Make_Stream_StartCode(
+    OMX_U8          *pInputStream,
+    OMX_U32         *pStreamSize,
+    WMV_FORMAT       wmvFormat)
+{
+    OMX_BOOL ret             = OMX_FALSE;
+    OMX_U8   vc1StartCode[4] = {0x00, 0x00, 0x01, 0x0d};
+
+#ifdef WMV3_ADDITIONAL_START_CODE
+     /* first 4 bytes : size of Frame, second 4 bytes : present Time stamp */
+    OMX_U8  wmvStartCode[8] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
+#endif
+
+    switch ((int)wmvFormat) {
+    case WMV_FORMAT_WMV3:
+#ifdef WMV3_ADDITIONAL_START_CODE
+        Exynos_OSAL_Memmove(pInputStream + 8, pInputStream, (*pStreamSize));
+        Exynos_OSAL_Memcpy(pInputStream, wmvStartCode, 8);
+        (*pStreamSize) += 8;
+#endif
+        ret = OMX_TRUE;
+        break;
+    case WMV_FORMAT_VC1:
+        /* Should find better way to shift data */
+        Exynos_OSAL_Memmove(pInputStream + 4, pInputStream, (*pStreamSize));
+        Exynos_OSAL_Memcpy(pInputStream, vc1StartCode, 4);
+        (*pStreamSize) += 4;
+        ret = OMX_TRUE;
+        break;
+    default:
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] undefined wmvFormat (%d)", __FUNCTION__, wmvFormat);
+        ret = OMX_FALSE;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec        = NULL;
+    EXYNOS_OMX_BASEPORT             *pOutputPort    = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pWmvDec == NULL)
+        goto EXIT;
+    pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pOutputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pWmvDec->hMFCWmvHandle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pWmvDec->hMFCWmvHandle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecOpen(EXYNOS_WMVDEC_HANDLE *pWmvDec, ExynosVideoInstInfo *pVideoInstInfo)
+{
+    OMX_ERRORTYPE           ret = OMX_ErrorNone;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pWmvDec == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pDecOps    = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
+    pInbufOps  = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+    pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+
+    if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pWmvDec->hMFCWmvHandle.pDecOps    = pDecOps;
+    pWmvDec->hMFCWmvHandle.pInbufOps  = pInbufOps;
+    pWmvDec->hMFCWmvHandle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pDecOps->nSize    = sizeof(ExynosVideoDecOps);
+    pInbufOps->nSize  = sizeof(ExynosVideoDecBufferOps);
+    pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
+
+    if (Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for decoder ops */
+    if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
+        (pDecOps->Get_ActualBufferCount == NULL) ||
+        (pDecOps->Set_FrameTag == NULL) || (pDecOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pWmvDec->hMFCWmvHandle.hMFCHandle = pWmvDec->hMFCWmvHandle.pDecOps->Init(pVideoInstInfo);
+    if (pWmvDec->hMFCWmvHandle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pDecOps != NULL) {
+            Exynos_OSAL_Free(pDecOps);
+            pWmvDec->hMFCWmvHandle.pDecOps = NULL;
+        }
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pWmvDec->hMFCWmvHandle.pInbufOps = NULL;
+        }
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pWmvDec->hMFCWmvHandle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecClose(EXYNOS_WMVDEC_HANDLE *pWmvDec)
+{
+    OMX_ERRORTYPE            ret = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pWmvDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
+    pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
+    pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pDecOps->Finalize(hMFCHandle);
+        pWmvDec->hMFCWmvHandle.hMFCHandle = NULL;
+        pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_FALSE;
+        pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pWmvDec->hMFCWmvHandle.pOutbufOps = NULL;
+    }
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pWmvDec->hMFCWmvHandle.pInbufOps = NULL;
+    }
+    if (pDecOps != NULL) {
+        Exynos_OSAL_Free(pDecOps);
+        pWmvDec->hMFCWmvHandle.pDecOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pWmvDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
+    pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc == OMX_TRUE)) {
+        pInbufOps->Run(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_TRUE)) {
+        pOutbufOps->Run(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pWmvDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
+    pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) {
+        pInbufOps->Stop(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) {
+        EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+        pOutbufOps->Stop(hMFCHandle);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE)
+            pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pWmvDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pWmvDec->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pWmvDec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pWmvDec->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pWmvDec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pWmvDec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pWmvDec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecReconfigAllBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = &pExynosComponent->pExynosPort[nPortIndex];
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    ExynosVideoDecBufferOps         *pBufferOps         = NULL;
+
+    FunctionIn();
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pWmvDec->bSourceStart == OMX_TRUE)) {
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pWmvDec->bDestinationStart == OMX_TRUE)) {
+        pBufferOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+
+        if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+            /**********************************/
+            /* Codec Buffer Free & Unregister */
+            /**********************************/
+            Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+            Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_FALSE;
+
+            /******************************************************/
+            /* V4L2 Destnation Setup for DPB Buffer Number Change */
+            /******************************************************/
+            ret = WmvCodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to WmvCodecDstSetup(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+        } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+            /***************************/
+            /* Codec Buffer Unregister */
+            /***************************/
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_FALSE;
+        }
+    } else {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE          *pWmvDec          = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle       = pWmvDec->hMFCWmvHandle.hMFCHandle;
+
+    ExynosVideoDecBufferOps *pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+
+    int i;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecInputBuffer[i]->fd[0], pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < pWmvDec->hMFCWmvHandle.maxDPBNum; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecOutputBuffer[i]->fd[0], pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+        }
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecUpdateBlackBarCrop(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE          *pWmvDec              = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    OMX_CONFIG_RECTTYPE           *pBlackBarCropRect    = &pVideoDec->blackBarCropRect;
+
+    ExynosVideoDecBufferOps  *pOutbufOps  = pWmvDec->hMFCWmvHandle.pOutbufOps;
+    ExynosVideoRect           CropRect;
+
+    FunctionIn();
+
+    Exynos_OSAL_Memset(&CropRect, 0, sizeof(ExynosVideoRect));
+    if (pOutbufOps->Get_BlackBarCrop(hMFCHandle, &CropRect) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get crop info", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pBlackBarCropRect->nLeft   = CropRect.nLeft;
+    pBlackBarCropRect->nTop    = CropRect.nTop;
+    pBlackBarCropRect->nWidth  = CropRect.nWidth;
+    pBlackBarCropRect->nHeight = CropRect.nHeight;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Black Bar Info: LEFT(%d) TOP(%d) WIDTH(%d) HEIGHT(%d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pBlackBarCropRect->nLeft, pBlackBarCropRect->nTop,
+                                        pBlackBarCropRect->nWidth, pBlackBarCropRect->nHeight);
+
+    /** Send Port Settings changed call back **/
+    (*(pExynosComponent->pCallbacks->EventHandler))
+        (pOMXComponent,
+         pExynosComponent->callbackData,
+         OMX_EventPortSettingsChanged, /* The command was completed */
+         OMX_DirOutput, /* This is the port index */
+         (OMX_INDEXTYPE)OMX_IndexConfigBlackBarCrop,
+         NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecCheckResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE          *pWmvDec            = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_EXCEPTION_STATE     eOutputExcepState  = pOutputPort->exceptionFlag;
+
+    ExynosVideoDecOps             *pDecOps            = pWmvDec->hMFCWmvHandle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pWmvDec->hMFCWmvHandle.pOutbufOps;
+    ExynosVideoGeometry            codecOutbufConf;
+
+    OMX_CONFIG_RECTTYPE          *pCropRectangle        = &(pOutputPort->cropRectangle);
+    OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition  = &(pInputPort->portDefinition);
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = &(pOutputPort->portDefinition);
+
+    int maxDPBNum = 0;
+
+    FunctionIn();
+
+    /* get geometry */
+    Exynos_OSAL_Memset(&codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry");
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        maxDPBNum += EXTRA_DPB_NUM;
+
+    pCropRectangle->nTop     = codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = codecOutbufConf.cropRect.nHeight;
+
+    /* resolution is changed */
+    if ((codecOutbufConf.nFrameWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth) ||
+        (codecOutbufConf.nFrameHeight != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight) ||
+        (codecOutbufConf.nStride != pWmvDec->hMFCWmvHandle.codecOutbufConf.nStride) ||
+#if 0  // TODO: check posibility
+        (codecOutbufConf.eColorFormat != pWmvDec->hMFCWmvHandle.codecOutbufConf.eColorFormat) ||
+        (codecOutbufConf.eFilledDataType != pWmvDec->hMFCWmvHandle.codecOutbufConf.eFilledDataType) ||
+#endif
+        (maxDPBNum != pWmvDec->hMFCWmvHandle.maxDPBNum)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth,
+                            pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight,
+                            codecOutbufConf.nFrameWidth,
+                            codecOutbufConf.nFrameHeight);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] DPB(%d), FORMAT(0x%x), TYPE(0x%x) -> DPB(%d), FORMAT(0x%x), TYPE(0x%x)",
+                            pExynosComponent, __FUNCTION__,
+                            pWmvDec->hMFCWmvHandle.maxDPBNum,
+                            pWmvDec->hMFCWmvHandle.codecOutbufConf.eColorFormat,
+                            pWmvDec->hMFCWmvHandle.codecOutbufConf.eFilledDataType,
+                            maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType);
+
+        pInputPortDefinition->format.video.nFrameWidth     = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight    = codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride         = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight    = codecOutbufConf.nFrameHeight;
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            pOutputPortDefinition->nBufferCountActual  = maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin     = maxDPBNum;
+        }
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        if (eOutputExcepState == GENERAL_STATE) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* crop info of contents is changed */
+    if ((codecOutbufConf.cropRect.nTop != pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nTop) ||
+        (codecOutbufConf.cropRect.nLeft != pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nLeft) ||
+        (codecOutbufConf.cropRect.nWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nWidth) ||
+        (codecOutbufConf.cropRect.nHeight != pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nHeight)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nWidth,
+                            pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nHeight,
+                            codecOutbufConf.cropRect.nWidth,
+                            codecOutbufConf.cropRect.nHeight);
+
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    Exynos_OSAL_Memcpy(&pWmvDec->hMFCWmvHandle.codecOutbufConf, &codecOutbufConf, sizeof(codecOutbufConf));
+    pWmvDec->hMFCWmvHandle.maxDPBNum = maxDPBNum;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecUpdateResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE          *pWmvDec            = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    ExynosVideoDecOps             *pDecOps            = pWmvDec->hMFCWmvHandle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pWmvDec->hMFCWmvHandle.pOutbufOps;
+
+    OMX_CONFIG_RECTTYPE             *pCropRectangle         = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE    *pInputPortDefinition   = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE    *pOutputPortDefinition  = NULL;
+
+    FunctionIn();
+
+    /* get geometry for output */
+    Exynos_OSAL_Memset(&pWmvDec->hMFCWmvHandle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &pWmvDec->hMFCWmvHandle.codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get geometry about output", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedHeader;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    pWmvDec->hMFCWmvHandle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        pWmvDec->hMFCWmvHandle.maxDPBNum += EXTRA_DPB_NUM;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] maxDPBNum: %d", pExynosComponent, __FUNCTION__, pWmvDec->hMFCWmvHandle.maxDPBNum);
+
+    /* get interlace info */
+    if (pWmvDec->hMFCWmvHandle.codecOutbufConf.bInterlaced == VIDEO_TRUE)
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] contents is interlaced type", pExynosComponent, __FUNCTION__);
+
+    pCropRectangle          = &(pOutputPort->cropRectangle);
+    pInputPortDefinition    = &(pInputPort->portDefinition);
+    pOutputPortDefinition   = &(pOutputPort->portDefinition);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] past info: width(%d) height(%d)",
+                                            pExynosComponent, __FUNCTION__,
+                                            pInputPortDefinition->format.video.nFrameWidth,
+                                            pInputPortDefinition->format.video.nFrameHeight);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] resolution info: width(%d / %d), height(%d / %d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth,
+                                        pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nWidth,
+                                        pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight,
+                                        pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nHeight);
+
+    pCropRectangle->nTop     = pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nHeight;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth  = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride      = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight;
+#if 0
+            /* don't need to change */
+            pOutputPortDefinition->nBufferCountActual       = pOutputPort->portDefinition.nBufferCountActual;
+            pOutputPortDefinition->nBufferCountMin          = pOutputPort->portDefinition.nBufferCountMin;
+#endif
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight) ||
+            ((OMX_S32)pOutputPortDefinition->nBufferCountActual != pWmvDec->hMFCWmvHandle.maxDPBNum)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth  = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride      = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight;
+
+            pOutputPortDefinition->nBufferCountActual       = pWmvDec->hMFCWmvHandle.maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin          = pWmvDec->hMFCWmvHandle.maxDPBNum;
+
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* contents has crop info */
+    if ((pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nWidth) ||
+        (pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight != pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nHeight)) {
+        pInputPortDefinition->format.video.nFrameWidth  = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride      = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight = pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight;
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged) with crop",
+                                                pExynosComponent, __FUNCTION__);
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE          *pWmvDec           = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+    OMX_COLOR_FORMATTYPE           eOutputFormat     = pExynosOutputPort->portDefinition.format.video.eColorFormat;
+    OMX_BOOL                       bMetaData         = OMX_FALSE;
+
+    ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps  = pWmvDec->hMFCWmvHandle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_U32  nInBufferCnt   = 0;
+    OMX_BOOL bSupportFormat = OMX_FALSE;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pWmvDec->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pWmvDec->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pWmvDec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pVideoDec->bThumbnailMode == OMX_TRUE)
+        pDecOps->Set_IFrameDecoding(hMFCHandle);
+
+    if ((pDecOps->Enable_DTSMode != NULL) &&
+        (pVideoDec->bDTSMode == OMX_TRUE))
+        pDecOps->Enable_DTSMode(hMFCHandle);
+
+    /* input buffer info */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+    if (pSrcInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
+        pWmvDec->hMFCWmvHandle.wmvFormat = getFormatType(pSrcInputData->buffer.addr[0]);
+
+    if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3) {
+        bufferConf.eCompressionFormat = VIDEO_CODING_VC1_RCV;
+    } else if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_VC1) {
+        bufferConf.eCompressionFormat = VIDEO_CODING_VC1;
+    } else {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Unsupported WMV Codec Format Type", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    pInbufOps->Set_Shareable(hMFCHandle);
+
+    nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        /* OMX buffer is not used directly : CODEC buffer */
+        nAllocLen[0] = pSrcInputData->allocSize;
+    }
+
+    bufferConf.nSizeImage = nAllocLen[0];
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+    nInBufferCnt = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    /* should be done before prepare input buffer */
+    if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set output geometry */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+    bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] omx format(0x%x) is %s by h/w",
+                                            pExynosComponent, __FUNCTION__, eOutputFormat,
+                                            (bSupportFormat == OMX_TRUE)? "supported":"not supported");
+    if (bSupportFormat == OMX_TRUE) {  /* supported by H/W */
+        bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eOutputFormat, pExynosOutputPort->ePlaneType);
+        Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pExynosOutputPort->ePlaneType));
+    } else {
+        OMX_COLOR_FORMATTYPE eCheckFormat = OMX_SEC_COLOR_FormatNV12Tiled;
+        bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        if (bSupportFormat != OMX_TRUE) {
+            eCheckFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+            bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        }
+        if (bSupportFormat == OMX_TRUE) {  /* supported by CSC(NV12T/NV12 -> format) */
+            bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eCheckFormat, pExynosOutputPort->ePlaneType);
+            Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eCheckFormat, pExynosOutputPort->ePlaneType));
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not support this format (0x%x)", eOutputFormat);
+            ret = OMX_ErrorNotImplemented;
+            pInbufOps->Cleanup_Buffer(hMFCHandle);
+            goto EXIT;
+        }
+    }
+
+    pWmvDec->hMFCWmvHandle.MFCOutputColorType = bufferConf.eColorFormat;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output video format is 0x%x",
+                                            pExynosComponent, __FUNCTION__, bufferConf.eColorFormat);
+
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    bMetaData = Make_Stream_MetaData(pSrcInputData->buffer.addr[0], &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat);
+    if (bMetaData == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Fail to Make Stream MetaData", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedHeader;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    /* input buffer enqueue for header parsing */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+
+    nDataLen[0] = oneFrameSize;  /* it is possible to be changed at Make_Stream_MetaData() */
+
+    if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pSrcInputData->buffer.addr,
+                            (unsigned long *)pSrcInputData->buffer.fd,
+                            nAllocLen,
+                            nDataLen,
+                            Exynos_GetPlaneFromPort(pExynosInputPort),
+                            pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enqueue input buffer for header parsing", pExynosComponent, __FUNCTION__);
+//        ret = OMX_ErrorInsufficientResources;
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_TRUE;
+
+    /* start header parsing */
+    if (WmvCodecStart(pOMXComponent, INPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run input buffer for header parsing", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    ret = WmvCodecUpdateResolution(pOMXComponent);
+    if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+        (pExynosComponent->codecType != HW_VIDEO_DEC_SECURE_CODEC) &&
+        (oneFrameSize >= 8)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...", pExynosComponent, __FUNCTION__,
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0])    , *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 1),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 2), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 3),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 4), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 5),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 6), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 7));
+    }
+
+    if (ret != OMX_ErrorNone) {
+        WmvCodecStop(pOMXComponent, INPUT_PORT_INDEX);
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_SleepMillisec(0);
+    /*  disable header info re-input scheme
+      ret = OMX_ErrorInputDataDecodeYet;
+      WmvCodecStop(pOMXComponent, INPUT_PORT_INDEX);
+    */
+    ret = (OMX_ERRORTYPE)OMX_ErrorNoneSrcSetupFinish;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE WmvCodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE          *pWmvDec              = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort    = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecOps       *pDecOps    = pWmvDec->hMFCWmvHandle.pDecOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nOutbufs, nPlaneCnt;
+
+    FunctionIn();
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++)
+        nAllocLen[i] = pWmvDec->hMFCWmvHandle.codecOutbufConf.nAlignPlaneSize[i];
+
+    WmvCodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    /* for adaptive playback */
+    if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enable Dynamic DPB", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare output buffer */
+        if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        /* get dpb count */
+        nOutbufs = pWmvDec->hMFCWmvHandle.maxDPBNum;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        /* without Register output buffer */
+
+        /* Enqueue output buffer */
+        for (i = 0; i < nOutbufs; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+                            (unsigned long *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+                            pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+                            nDataLen,
+                            nPlaneCnt,
+                            NULL);
+        }
+
+        pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_TRUE;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* get dpb count */
+        nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+        if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pExynosOutputPort->eMetaDataType == METADATA_TYPE_DISABLED) {
+            /*************/
+            /*    TBD    */
+            /*************/
+            /* data buffer : user buffer
+             * H/W can't accept user buffer directly
+             */
+            ret = OMX_ErrorNotImplemented;
+            goto EXIT;
+        }
+
+        pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_TRUE;
+    }
+
+    if (WmvCodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pWmvDec  = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoWmv:
+    {
+        OMX_VIDEO_PARAM_WMVTYPE *pDstWmvParam = (OMX_VIDEO_PARAM_WMVTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_WMVTYPE *pSrcWmvParam = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstWmvParam->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcWmvParam = &pWmvDec->WmvComponent[pDstWmvParam->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstWmvParam) + nOffset,
+                           ((char *)pSrcWmvParam) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_WMVTYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamVideoVC1:
+    {
+        OMX_VIDEO_PARAM_VC1TYPE *pDstVc1Param = (OMX_VIDEO_PARAM_VC1TYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VC1TYPE *pSrcVc1Param = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstVc1Param, sizeof(OMX_VIDEO_PARAM_VC1TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstVc1Param->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVc1Param = &pWmvDec->Vc1Component[pDstVc1Param->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstVc1Param) + nOffset,
+                           ((char *)pSrcVc1Param) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_VC1TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VC1TYPE          *pSrcVc1Component = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVc1Component = &pWmvDec->Vc1Component[pDstProfileLevel->nPortIndex];
+
+        pDstProfileLevel->eProfile = pSrcVc1Component->eProfile;
+        pDstProfileLevel->eLevel   = pSrcVc1Component->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pWmvDec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexExynosParamReorderMode:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *pReorderParam = (EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pReorderParam, sizeof(EXYNOS_OMX_VIDEO_PARAM_REORDERMODE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pReorderParam->bReorderMode = pVideoDec->bReorderMode;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pWmvDec  = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoWmv:
+    {
+        OMX_VIDEO_PARAM_WMVTYPE *pDstWmvParam = NULL;
+        OMX_VIDEO_PARAM_WMVTYPE *pSrcWmvParam = (OMX_VIDEO_PARAM_WMVTYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcWmvParam, sizeof(OMX_VIDEO_PARAM_WMVTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcWmvParam->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstWmvParam = &pWmvDec->WmvComponent[pSrcWmvParam->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstWmvParam) + nOffset,
+                           ((char *)pSrcWmvParam) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_WMVTYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamVideoVC1:
+    {
+        OMX_VIDEO_PARAM_VC1TYPE *pDstVc1Param = NULL;
+        OMX_VIDEO_PARAM_VC1TYPE *pSrcVc1Param = (OMX_VIDEO_PARAM_VC1TYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcVc1Param, sizeof(OMX_VIDEO_PARAM_VC1TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcVc1Param->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstVc1Param = &pWmvDec->Vc1Component[pSrcVc1Param->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstVc1Param) + nOffset,
+                           ((char *)pSrcVc1Param) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_VC1TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE)) {
+            pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VC1TYPE          *pDstVc1Component = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstVc1Component = &pWmvDec->Vc1Component[pSrcProfileLevel->nPortIndex];
+
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pDstVc1Component->eProfile  = pSrcProfileLevel->eProfile;
+        pDstVc1Component->eLevel    = pSrcProfileLevel->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pWmvDec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexExynosParamReorderMode:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *pReorderParam = (EXYNOS_OMX_VIDEO_PARAM_REORDERMODE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pReorderParam, sizeof(EXYNOS_OMX_VIDEO_PARAM_REORDERMODE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pVideoDec->bReorderMode = pReorderParam->bReorderMode;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_GetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pWmvDec  = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch (nIndex) {
+    case OMX_IndexConfigCommonOutputCrop:
+    {
+        EXYNOS_OMX_BASEPORT *pExynosPort   = NULL;
+        OMX_CONFIG_RECTTYPE *pSrcRectType  = NULL;
+        OMX_CONFIG_RECTTYPE *pDstRectType  = NULL;
+
+        if (pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc == OMX_FALSE) {
+            ret = OMX_ErrorNotReady;
+            break;
+        }
+
+        pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
+
+        if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) &&
+            (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex];
+
+        pSrcRectType = &(pExynosPort->cropRectangle);
+
+        pDstRectType->nTop    = pSrcRectType->nTop;
+        pDstRectType->nLeft   = pSrcRectType->nLeft;
+        pDstRectType->nHeight = pSrcRectType->nHeight;
+        pDstRectType->nWidth  = pSrcRectType->nWidth;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pWmvDec  = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    switch (nIndex) {
+    default:
+        ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_GetExtensionIndex(
+    OMX_IN  OMX_HANDLETYPE   hComponent,
+    OMX_IN  OMX_STRING       cParameterName,
+    OMX_OUT OMX_INDEXTYPE   *pIndexType)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_REORDER_MODE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamReorderMode;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_ComponentRoleEnum(
+    OMX_HANDLETYPE hComponent,
+    OMX_U8        *cRole,
+    OMX_U32        nIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) || (cRole == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE);
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorNoMore;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_WmvDec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    ExynosVideoInstInfo *pVideoInstInfo = &(pWmvDec->hMFCWmvHandle.videoInstInfo);
+
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+    int i;
+
+    FunctionIn();
+
+    pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_FALSE;
+    pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    pVideoDec->bDiscardCSDError = OMX_FALSE;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                             pExynosInputPort->portDefinition.format.video.nBitrate,
+                                                                                             pExynosInputPort->portDefinition.format.video.xFramerate);
+
+    pVideoInstInfo->nSize        = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth       = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight      = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate     = pExynosInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate   = pExynosInputPort->portDefinition.format.video.xFramerate;
+
+    /* WMV Codec Open */
+    ret = WmvCodecOpen(pWmvDec, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+        nAllocLen[0] = ALIGN(pExynosInputPort->portDefinition.format.video.nFrameWidth *
+                             pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+        if (nAllocLen[0] < pVideoDec->nMinInBufSize)
+            nAllocLen[0] = pVideoDec->nMinInBufSize;
+
+        Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_SetPlaneToPort(pExynosOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pWmvDec->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pWmvDec->hSourceStartEvent);
+    pWmvDec->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pWmvDec->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pWmvDec->hDestinationOutStartEvent);
+
+    Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pWmvDec->hMFCWmvHandle.indexTimestamp = 0;
+    pWmvDec->hMFCWmvHandle.outputIndexTimestamp = 0;
+    /* Default WMV codec format is set as VC1*/
+    pWmvDec->hMFCWmvHandle.wmvFormat = WMV_FORMAT_VC1;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pWmvDec->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+    pVideoDec->csc_handle = csc_init(csc_method);
+    if (pVideoDec->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    pVideoDec->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_WmvDec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    FunctionIn();
+
+    if (pVideoDec->csc_handle != NULL) {
+        csc_deinit(pVideoDec->csc_handle);
+        pVideoDec->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pWmvDec->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pWmvDec->hDestinationInStartEvent);
+    pWmvDec->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pWmvDec->hDestinationOutStartEvent);
+    pWmvDec->hDestinationOutStartEvent = NULL;
+    pWmvDec->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pWmvDec->hSourceStartEvent);
+    pWmvDec->hSourceStartEvent = NULL;
+    pWmvDec->bSourceStart = OMX_FALSE;
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
+        pExynosOutputPort->codecSemID = NULL;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
+        pExynosInputPort->codecSemID = NULL;
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+    WmvCodecClose(pWmvDec);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE          *pWmvDec           = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+
+    ExynosVideoDecOps       *pDecOps     = pWmvDec->hMFCWmvHandle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps   = pWmvDec->hMFCWmvHandle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_BOOL bStartCode   = OMX_FALSE;
+
+    FunctionIn();
+
+    if (pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = WmvCodecSrcSetup(pOMXComponent, pSrcInputData);
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (pWmvDec->bDestinationStart == OMX_FALSE) &&
+        (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_FALSE)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+        ret = WmvCodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to WmvCodecDstSetup(0x%x)",
+                                            pExynosComponent, __FUNCTION__, ret);
+            goto EXIT;
+        }
+    }
+
+    bStartCode = Check_Stream_PrefixCode(pSrcInputData->buffer.addr[0], oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat);
+    if ((bStartCode == OMX_FALSE) &&
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
+        OMX_U32 bufferSizeWithHeader;
+        if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_WMV3)
+            bufferSizeWithHeader = oneFrameSize + 8;
+        else if (pWmvDec->hMFCWmvHandle.wmvFormat == WMV_FORMAT_VC1)
+            bufferSizeWithHeader = oneFrameSize + 4;
+        else
+            bufferSizeWithHeader = 0;
+
+        if (pSrcInputData->allocSize < bufferSizeWithHeader) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] can not attach startcode due to lack of buffer space", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedFrame;
+            goto EXIT;
+        }
+
+        /* try to generate a start code */
+        bStartCode = Make_Stream_StartCode(pSrcInputData->buffer.addr[0], &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat);
+    }
+
+    if ((bStartCode == OMX_TRUE) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+        if (pVideoDec->bReorderMode == OMX_FALSE) {
+            /* next slot will be used like as circular queue */
+            pExynosComponent->timeStamp[pWmvDec->hMFCWmvHandle.indexTimestamp] = pSrcInputData->timeStamp;
+            pExynosComponent->nFlags[pWmvDec->hMFCWmvHandle.indexTimestamp]    = pSrcInputData->nFlags;
+        } else {  /* MSRND */
+            Exynos_SetReorderTimestamp(pExynosComponent, &(pWmvDec->hMFCWmvHandle.indexTimestamp), pSrcInputData->timeStamp, pSrcInputData->nFlags);
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), dataLen(%d), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, oneFrameSize, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pWmvDec->hMFCWmvHandle.indexTimestamp);
+
+        pDecOps->Set_FrameTag(hMFCHandle, pWmvDec->hMFCWmvHandle.indexTimestamp);
+        pWmvDec->hMFCWmvHandle.indexTimestamp++;
+        pWmvDec->hMFCWmvHandle.indexTimestamp %= MAX_TIMESTAMP;
+
+        if ((pVideoDec->bQosChanged == OMX_TRUE) &&
+            (pDecOps->Set_QosRatio != NULL)) {
+            pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
+            pVideoDec->bQosChanged = OMX_FALSE;
+        }
+
+        if (pVideoDec->bSearchBlackBarChanged == OMX_TRUE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] BlackBar searching mode : %s",
+                                            pExynosComponent, __FUNCTION__,
+                                            (pVideoDec->bSearchBlackBar == OMX_TRUE) ? "enable" : "disable");
+            pDecOps->Set_SearchBlackBar(hMFCHandle, (ExynosVideoBoolType)pVideoDec->bSearchBlackBar);
+            pVideoDec->bSearchBlackBarChanged = OMX_FALSE;
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        /* queue work for input buffer */
+        nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+        if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        } else {
+            nAllocLen[0] = pSrcInputData->allocSize;
+
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        }
+
+        nDataLen[0] = oneFrameSize;  /* it is possible to be changed at Make_Stream_MetaData() */
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pSrcInputData->buffer.addr,
+                                (unsigned long *)pSrcInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pExynosInputPort),
+                                pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            goto EXIT;
+        }
+        WmvCodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        if (pWmvDec->bSourceStart == OMX_FALSE) {
+            pWmvDec->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pWmvDec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+        if ((pWmvDec->bDestinationStart == OMX_FALSE) &&
+            (pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc == OMX_TRUE)) {
+            pWmvDec->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pWmvDec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pWmvDec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    } else if (bStartCode == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] can not find a start code", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedFrame;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pInbufOps      = pWmvDec->hMFCWmvHandle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->allocSize  = 0;
+        pSrcOutputData->pPrivate = NULL;
+        pSrcOutputData->bufferHeader = NULL;
+    } else {
+        pSrcOutputData->buffer.addr[0] = pVideoBuffer->planes[0].addr;
+        pSrcOutputData->buffer.fd[0] = pVideoBuffer->planes[0].fd;
+        pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
+
+        if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] ==
+                        pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
+                    pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pExynosInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pOutbufOps  = pWmvDec->hMFCWmvHandle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++) {
+        nAllocLen[i] = pWmvDec->hMFCWmvHandle.codecOutbufConf.nAlignPlaneSize[i];
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] ADDR[%d]: 0x%x, size[%d]: %d", pExynosComponent, __FUNCTION__,
+                                        i, pDstInputData->buffer.addr[i], i, nAllocLen[i]);
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                nPlaneCnt,
+                                pDstInputData->bufferHeader);
+
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+        }
+
+        goto EXIT;
+    }
+
+    WmvCodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pWmvDec->hMFCWmvHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    DECODE_CODEC_EXTRA_BUFFERINFO   *pBufferInfo        = NULL;
+
+    ExynosVideoDecOps           *pDecOps        = pWmvDec->hMFCWmvHandle.pDecOps;
+    ExynosVideoDecBufferOps     *pOutbufOps     = pWmvDec->hMFCWmvHandle.pOutbufOps;
+    ExynosVideoBuffer           *pVideoBuffer   = NULL;
+    ExynosVideoBuffer            videoBuffer;
+    ExynosVideoFrameStatusType   displayStatus  = VIDEO_FRAME_STATUS_UNKNOWN;
+    ExynosVideoGeometry         *bufferGeometry = NULL;
+    ExynosVideoErrorType         codecReturn    = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+
+    OMX_S32 indexTimestamp = 0;
+    int plane, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pWmvDec->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    while (1) {
+        Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer));
+
+        codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+        if (codecReturn == VIDEO_ERROR_NONE) {
+            pVideoBuffer = &videoBuffer;
+        } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO) at ExtensionDequeue", pExynosComponent, __FUNCTION__);
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorHardware;
+            goto EXIT;
+        } else {
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        displayStatus = pVideoBuffer->displayStatus;
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus: 0x%x", pExynosComponent, __FUNCTION__, displayStatus);
+
+        if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
+            (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+            (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+            (CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+            ret = OMX_ErrorNone;
+            break;
+        }
+    }
+
+   if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+       (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) {
+        if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+            pOutputPort->exceptionFlag = NEED_PORT_FLUSH;
+            pVideoDec->bReconfigDPB = OMX_TRUE;
+            WmvCodecUpdateResolution(pOMXComponent);
+            pVideoDec->csc_set_format = OMX_FALSE;
+        }
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pWmvDec->hMFCWmvHandle.outputIndexTimestamp++;
+    pWmvDec->hMFCWmvHandle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+    pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
+    nPlaneCnt = Exynos_GetPlaneFromPort(pOutputPort);
+    for (plane = 0; plane < nPlaneCnt; plane++) {
+        pDstOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+        pDstOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+        pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        pDstOutputData->dataLen   += pVideoBuffer->planes[plane].dataSize;
+        nDataLen[plane]            = pVideoBuffer->planes[plane].dataSize;
+    }
+    pDstOutputData->usedDataLen = 0;
+    pDstOutputData->pPrivate = pVideoBuffer;
+
+    pBufferInfo     = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+    bufferGeometry  = &pWmvDec->hMFCWmvHandle.codecOutbufConf;
+    pBufferInfo->imageWidth       = bufferGeometry->nFrameWidth;
+    pBufferInfo->imageHeight      = bufferGeometry->nFrameHeight;
+    pBufferInfo->imageStride      = bufferGeometry->nStride;
+    pBufferInfo->cropRect.nLeft   = bufferGeometry->cropRect.nLeft;
+    pBufferInfo->cropRect.nTop    = bufferGeometry->cropRect.nTop;
+    pBufferInfo->cropRect.nWidth  = bufferGeometry->cropRect.nWidth;
+    pBufferInfo->cropRect.nHeight = bufferGeometry->cropRect.nHeight;
+    pBufferInfo->colorFormat      = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+    Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            goto EXIT;
+        }
+
+        /* calculate each plane info for the application */
+        Exynos_OSAL_GetPlaneSize(pOutputPort->portDefinition.format.video.eColorFormat,
+                                 PLANE_SINGLE, pOutputPort->portDefinition.format.video.nFrameWidth,
+                                 pOutputPort->portDefinition.format.video.nFrameHeight,
+                                 nDataLen, nAllocLen);
+
+        pDstOutputData->allocSize = nAllocLen[0] + nAllocLen[1] + nAllocLen[2];
+        pDstOutputData->dataLen   = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+#ifdef USE_ANDROID
+    /* get interlace frame info */
+    if ((pOutputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pWmvDec->hMFCWmvHandle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
+        (pVideoBuffer->planes[2].addr != NULL)) {
+        ExynosVideoMeta *pMeta = (ExynosVideoMeta *)pVideoBuffer->planes[2].addr;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] interlace type = %x", pExynosComponent, __FUNCTION__, pVideoBuffer->interlacedType);
+        pMeta->eType = VIDEO_INFO_TYPE_INTERLACED;
+        pMeta->data.dec.nInterlacedType = pVideoBuffer->interlacedType;
+    }
+#endif
+
+    indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+    if (pVideoDec->bReorderMode == OMX_FALSE) {
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
+                (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
+                if (indexTimestamp == INDEX_AFTER_EOS) {
+                    pDstOutputData->timeStamp = 0x00;
+                    pDstOutputData->nFlags = 0x00;
+                } else {
+                    pDstOutputData->timeStamp = pExynosComponent->timeStamp[pWmvDec->hMFCWmvHandle.outputIndexTimestamp];
+                    pDstOutputData->nFlags = pExynosComponent->nFlags[pWmvDec->hMFCWmvHandle.outputIndexTimestamp];
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] missing out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+                }
+            } else {
+                pDstOutputData->timeStamp = 0x00;
+                pDstOutputData->nFlags = 0x00;
+            }
+        } else {
+            /* For timestamp correction. if mfc support frametype detect */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] disp_pic_frame_type: %d", pExynosComponent, __FUNCTION__, pVideoBuffer->frameType);
+
+            /* NEED TIMESTAMP REORDER */
+            if (pVideoDec->bDTSMode == OMX_TRUE) {
+                if ((pVideoBuffer->frameType & VIDEO_FRAME_I) ||
+                    ((pVideoBuffer->frameType & VIDEO_FRAME_OTHERS) &&
+                        ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
+                    (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
+                    pWmvDec->hMFCWmvHandle.outputIndexTimestamp = indexTimestamp;
+                else
+                    indexTimestamp = pWmvDec->hMFCWmvHandle.outputIndexTimestamp;
+            }
+
+            pDstOutputData->timeStamp   = pExynosComponent->timeStamp[indexTimestamp];
+            pDstOutputData->nFlags      = pExynosComponent->nFlags[indexTimestamp] | OMX_BUFFERFLAG_ENDOFFRAME;
+
+            if (pVideoBuffer->frameType & VIDEO_FRAME_I)
+                pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+            if (pVideoBuffer->frameType & VIDEO_FRAME_CORRUPT)
+                pDstOutputData->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                                    pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                                    indexTimestamp);
+    } else {  /* MSRND */
+        EXYNOS_OMX_CURRENT_FRAME_TIMESTAMP sCurrentTimestamp;
+
+        Exynos_GetReorderTimestamp(pExynosComponent, &sCurrentTimestamp, indexTimestamp, pVideoBuffer->frameType);
+
+        pDstOutputData->timeStamp   = sCurrentTimestamp.timeStamp;
+        pDstOutputData->nFlags      = sCurrentTimestamp.nFlags | OMX_BUFFERFLAG_ENDOFFRAME;
+
+        pExynosComponent->nFlags[sCurrentTimestamp.nIndex]               = 0x00;
+        pExynosComponent->bTimestampSlotUsed[sCurrentTimestamp.nIndex]   = OMX_FALSE;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), reordered tag: %d, original tag: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                                    pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                                    sCurrentTimestamp.nIndex,
+                                                    indexTimestamp);
+    }
+
+    if (pVideoBuffer->frameType & VIDEO_FRAME_WITH_BLACK_BAR) {
+        if (WmvCodecUpdateBlackBarCrop(pOMXComponent) != OMX_ErrorNone)
+            goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+        (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+    }
+
+    if (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) {
+        pDstOutputData->remainDataLen = 0;
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            if (indexTimestamp != INDEX_AFTER_EOS)
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] tag(%d) is wrong", pExynosComponent, __FUNCTION__, indexTimestamp);
+            pDstOutputData->timeStamp   = 0x00;
+            pDstOutputData->nFlags      = 0x00;
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) ||
+            (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+            pExynosComponent->nFlags[indexTimestamp] &= (~OMX_BUFFERFLAG_EOS);
+        }
+    } else if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        pDstOutputData->remainDataLen = 0;
+
+        if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
+            pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+
+            if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+                pExynosComponent->bBehaviorEOS = OMX_FALSE;
+            } else {
+                pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+                pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+            }
+        }
+    } else {
+        pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_WmvDec_SrcIn(pOMXComponent, pSrcInputData);
+    if ((ret != OMX_ErrorNone) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorNoneSrcSetupFinish) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorCorruptedFrame)) {
+
+        if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+            (pVideoDec->bDiscardCSDError == OMX_TRUE)) {
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+    if ((pWmvDec->bSourceStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
+        Exynos_OSAL_SignalWait(pWmvDec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pWmvDec->hSourceStartEvent);
+    }
+
+    ret = Exynos_WmvDec_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        if (pExynosComponent->currentState == OMX_StatePause)
+            ret = (OMX_ERRORTYPE)OMX_ErrorOutputBufferUseYet;
+        else
+            ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pWmvDec->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pWmvDec->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pWmvDec->hDestinationInStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pWmvDec->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pWmvDec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+            (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+            ret = WmvCodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to WmvCodecDstSetup(0x%x)", pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+            Exynos_OSAL_SignalSet(pWmvDec->hDestinationOutStartEvent);
+        }
+    }
+
+    if (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_WmvDec_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+           Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_WmvDec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (((pWmvDec->bDestinationStart == OMX_FALSE) ||
+         (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_FALSE)) &&
+        (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pWmvDec->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pWmvDec->hDestinationOutStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pWmvDec->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pWmvDec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_WmvDec_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE  hComponent,
+    OMX_STRING      componentName)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_WMVDEC_HANDLE            *pWmvDec            = NULL;
+    OMX_S32                          wmvFormat          = WMV_FORMAT_UNKNOWN;
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) || (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_WMV_DEC, componentName) != 0) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pWmvDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_WMVDEC_HANDLE));
+    if (pWmvDec == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pWmvDec, 0, sizeof(EXYNOS_WMVDEC_HANDLE));
+    pVideoDec               = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pWmvDec;
+    pWmvDec->hMFCWmvHandle.wmvFormat = wmvFormat;
+    Exynos_OSAL_Strcpy(pExynosComponent->componentName, componentName);
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE)
+        pExynosPort->portDefinition.nBufferSize = CUSTOM_DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+
+    pVideoDec->nMinInBufSize = DEFAULT_VIDEO_MIN_INPUT_BUFFER_SIZE;  /* for DRC */
+
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/wmv");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    //pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pWmvDec->WmvComponent[i], OMX_VIDEO_PARAM_WMVTYPE);
+        pWmvDec->WmvComponent[i].nPortIndex = i;
+        pWmvDec->WmvComponent[i].eFormat    = OMX_VIDEO_WMVFormat9;
+    }
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pWmvDec->Vc1Component[i], OMX_VIDEO_PARAM_VC1TYPE);
+        pWmvDec->Vc1Component[i].nPortIndex = i;
+        pWmvDec->Vc1Component[i].eProfile   = OMX_VIDEO_VC1ProfileMain;
+        pWmvDec->Vc1Component[i].eLevel     = OMX_VIDEO_VC1LevelHigh;
+    }
+
+    pOMXComponent->GetParameter      = &Exynos_WmvDec_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_WmvDec_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_WmvDec_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_WmvDec_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_WmvDec_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_WmvDec_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_WmvDec_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_WmvDec_Terminate;
+
+    pVideoDec->exynos_codec_srcInputProcess  = &Exynos_WmvDec_srcInputBufferProcess;
+    pVideoDec->exynos_codec_srcOutputProcess = &Exynos_WmvDec_srcOutputBufferProcess;
+    pVideoDec->exynos_codec_dstInputProcess  = &Exynos_WmvDec_dstInputBufferProcess;
+    pVideoDec->exynos_codec_dstOutputProcess = &Exynos_WmvDec_dstOutputBufferProcess;
+
+    pVideoDec->exynos_codec_start         = &WmvCodecStart;
+    pVideoDec->exynos_codec_stop          = &WmvCodecStop;
+    pVideoDec->exynos_codec_bufferProcessRun = &WmvCodecOutputBufferProcessRun;
+    pVideoDec->exynos_codec_enqueueAllBuffer = &WmvCodecEnQueueAllBuffer;
+
+    pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+    pVideoDec->exynos_codec_reconfigAllBuffers        = &WmvCodecReconfigAllBuffers;
+
+    pVideoDec->exynos_codec_checkFormatSupport      = &CheckFormatHWSupport;
+    pVideoDec->exynos_codec_checkResolutionChange   = &WmvCodecCheckResolution;
+
+    pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoDec->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pWmvDec);
+        pWmvDec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pWmvDec->hMFCWmvHandle.videoInstInfo.eCodecType = VIDEO_CODING_VC1;
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        pWmvDec->hMFCWmvHandle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pWmvDec->hMFCWmvHandle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pWmvDec->hMFCWmvHandle.videoInstInfo), VIDEO_TRUE /* dec */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pWmvDec);
+        pWmvDec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_Output_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
+    OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+    EXYNOS_WMVDEC_HANDLE        *pWmvDec            = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent       = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent    = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoDec           = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pWmvDec = (EXYNOS_WMVDEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pWmvDec != NULL) {
+        Exynos_OSAL_Free(pWmvDec);
+        pWmvDec = pVideoDec->hCodecHandle = NULL;
+    }
+
+    ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h b/openmax/component/video/dec/vc1/Exynos_OMX_Wmvdec.h
new file mode 100755 (executable)
index 0000000..e058f67
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Wmvdec.h
+ * @brief
+ * @author     HyeYeon Chung (hyeon.chung@samsung.com)
+ * @author     Satish Kumar Reddy (palli.satish@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2012.07.10 : Create
+ */
+
+#ifndef EXYNOS_OMX_WMV_DEC_COMPONENT
+#define EXYNOS_OMX_WMV_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+#include "ExynosVideoApi.h"
+
+#define BITMAPINFOHEADER_SIZE               40
+#define BITMAPINFOHEADER_ASFBINDING_SIZE    41
+#define COMPRESSION_POS                     16
+
+typedef enum WMV_FORMAT {
+    WMV_FORMAT_VC1,
+    WMV_FORMAT_WMV3,
+    WMV_FORMAT_UNKNOWN
+} WMV_FORMAT;
+
+typedef struct _EXYNOS_MFC_WMVDEC_HANDLE
+{
+    OMX_HANDLETYPE hMFCHandle;
+    OMX_U32        indexTimestamp;
+    OMX_U32        outputIndexTimestamp;
+    OMX_BOOL       bConfiguredMFCSrc;
+    OMX_BOOL       bConfiguredMFCDst;
+    OMX_S32        maxDPBNum;
+    WMV_FORMAT     wmvFormat;
+
+    ExynosVideoColorFormatType MFCOutputColorType;
+    ExynosVideoDecOps         *pDecOps;
+    ExynosVideoDecBufferOps   *pInbufOps;
+    ExynosVideoDecBufferOps   *pOutbufOps;
+    ExynosVideoGeometry        codecOutbufConf;
+    ExynosVideoInstInfo        videoInstInfo;
+
+    #define MAX_PROFILE_NUM 3
+    OMX_VIDEO_VC1PROFILETYPE   profiles[MAX_PROFILE_NUM];
+    OMX_S32                    nProfileCnt;
+    OMX_VIDEO_VC1LEVELTYPE     maxLevel[MAX_PROFILE_NUM];
+} EXYNOS_MFC_WMVDEC_HANDLE;
+
+typedef struct _EXYNOS_WMVDEC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_WMVTYPE WmvComponent[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_VC1TYPE Vc1Component[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+
+    /* EXYNOS MFC Codec specific */
+    EXYNOS_MFC_WMVDEC_HANDLE            hMFCWmvHandle;
+
+    OMX_BOOL bSourceStart;
+    OMX_BOOL bDestinationStart;
+    OMX_HANDLETYPE hSourceStartEvent;
+    OMX_HANDLETYPE hDestinationInStartEvent;
+    OMX_HANDLETYPE hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE bypassBufferInfoQ;
+} EXYNOS_WMVDEC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE hComponent,
+    OMX_STRING     componentName);
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
+    OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE WmvCodecDstSetup(
+    OMX_COMPONENTTYPE *pOMXComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/vc1/Makefile.am b/openmax/component/video/dec/vc1/Makefile.am
new file mode 100755 (executable)
index 0000000..d0683a0
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libOMX.Exynos.WMV.Decoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_WMV_Decoder_la_SOURCES = Exynos_OMX_Wmvdec.c \
+                                       library_register.c
+
+libOMX_Exynos_WMV_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                      $(top_builddir)/openmax/component/video/dec/libExynosOMX_Vdec.la \
+                                      $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+libOMX_Exynos_WMV_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                      -I$(top_srcdir)/openmax/include/exynos \
+                                      -I$(top_srcdir)/openmax/osal \
+                                      -I$(top_srcdir)/openmax/core \
+                                      -I$(top_srcdir)/openmax/component/common \
+                                      -I$(top_srcdir)/openmax/component/video/dec \
+                                      -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_WMV_Decoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
+libOMX_Exynos_WMV_Decoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable
+
+libOMX_Exynos_WMV_Decoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/dec/vc1/library_register.c b/openmax/component/video/dec/vc1/library_register.c
new file mode 100755 (executable)
index 0000000..f127389
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       library_register.c
+ * @brief
+ * @author     HyeYeon Chung (hyeon.chung@samsung.com)
+ * @author     Satish Kumar Reddy (palli.satish@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2012.07.10 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_WMV_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(
+    ExynosRegisterComponentType **ppExynosComponent)
+{
+    FunctionIn();
+
+    if (ppExynosComponent == NULL)
+        goto EXIT;
+
+    /* component 1 - video decoder WMV */
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_WMV_DEC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE);
+    ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
diff --git a/openmax/component/video/dec/vc1/library_register.h b/openmax/component/video/dec/vc1/library_register.h
new file mode 100755 (executable)
index 0000000..3288921
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file    library_register.h
+ * @brief
+ * @author      HyeYeon Chung (hyeon.chung@samsung.com)
+ * @author      Satish Kumar Reddy (palli.satish@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.07.10 : Create
+ */
+
+#ifndef EXYNOS_OMX_WMV_DEC_REG
+#define EXYNOS_OMX_WMV_DEC_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM         1
+#define MAX_COMPONENT_ROLE_NUM    1
+
+/* WMV */
+#ifndef USE_CUSTOM_COMPONENT_SUPPORT
+#define EXYNOS_OMX_COMPONENT_WMV_DEC        "OMX.Exynos.WMV.Decoder"
+#else
+#define EXYNOS_OMX_COMPONENT_WMV_DEC        "OMX.Exynos.vc1.dec"
+#endif
+
+#define EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE   "video_decoder.vc1"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(
+    ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/vp8/Exynos_OMX_Vp8dec.c b/openmax/component/video/dec/vp8/Exynos_OMX_Vp8dec.c
new file mode 100755 (executable)
index 0000000..8329ade
--- /dev/null
@@ -0,0 +1,3077 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Vp8dec.c
+ * @brief
+ * @author      Satish Kumar Reddy (palli.satish@samsung.com)
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Vdec.h"
+#include "Exynos_OMX_VdecControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Vp8dec.h"
+#include "ExynosVideoApi.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+
+/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
+/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VP8_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec        = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp8Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Dec->hMFCVp8Handle.profiles[nProfileCnt++] = OMX_VIDEO_VP8ProfileMain;
+    pVp8Dec->hMFCVp8Handle.nProfileCnt = nProfileCnt;
+    pVp8Dec->hMFCVp8Handle.maxLevel = OMX_VIDEO_VP8Level_Version3;
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret           = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec     = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec       = NULL;
+
+    int nLevelCnt = 0;
+    OMX_U32 nMaxIndex = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp8Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pVp8Dec->hMFCVp8Handle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pVp8Dec->hMFCVp8Handle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pVp8Dec->hMFCVp8Handle.maxLevel;
+#else
+    while ((pVp8Dec->hMFCVp8Handle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+
+    if ((pVp8Dec->hMFCVp8Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                        pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pVp8Dec->hMFCVp8Handle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pVp8Dec->hMFCVp8Handle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] supported profile(%x), level(%x)",
+                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec  = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec    = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp8Dec == NULL)
+        goto EXIT;
+
+    while ((pVp8Dec->hMFCVp8Handle.maxLevel >> nLevelCnt++) > 0);
+
+    if ((pVp8Dec->hMFCVp8Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pVp8Dec->hMFCVp8Handle.nProfileCnt; i++) {
+        if (pVp8Dec->hMFCVp8Handle.profiles[i] == pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    while (nLevelCnt >= 0) {
+        if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+            bLevelSupport = OMX_TRUE;
+            break;
+        }
+
+        nLevelCnt--;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    FunctionOut();
+
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
+{
+    OMX_ERRORTYPE       ret          = OMX_ErrorNone;
+    ExynosVideoBuffer  *pCodecBuffer = NULL;
+
+    if (codecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
+
+    if (addr != NULL) {
+        addr[0] = pCodecBuffer->planes[0].addr;
+        addr[1] = pCodecBuffer->planes[1].addr;
+        addr[2] = pCodecBuffer->planes[2].addr;
+    }
+
+    if (size != NULL) {
+        size[0] = pCodecBuffer->planes[0].allocSize;
+        size[1] = pCodecBuffer->planes[1].allocSize;
+        size[2] = pCodecBuffer->planes[2].allocSize;
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_BOOL Check_VP8_StartCode(
+    OMX_U8     *pInputStream,
+    OMX_U32     streamSize)
+{
+    OMX_BOOL ret = OMX_FALSE;
+
+    FunctionIn();
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] streamSize: %d", __FUNCTION__, streamSize);
+    if (streamSize < 3) {
+        ret = OMX_FALSE;
+        goto EXIT;
+    }
+
+    if (!(pInputStream[0] & 0x01)){
+        /* Key Frame  Start code*/
+        if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] VP8 Key Frame Start Code not Found", __FUNCTION__);
+            ret = OMX_FALSE;
+            goto EXIT;
+        }
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] VP8 Found Key Frame Start Code", __FUNCTION__);
+    }
+
+    ret = OMX_TRUE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec        = NULL;
+    EXYNOS_OMX_BASEPORT             *pOutputPort    = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp8Dec == NULL)
+        goto EXIT;
+    pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pOutputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pVp8Dec->hMFCVp8Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pVp8Dec->hMFCVp8Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecOpen(EXYNOS_VP8DEC_HANDLE *pVp8Dec, ExynosVideoInstInfo *pVideoInstInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pVp8Dec == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pDecOps    = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
+    pInbufOps  = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+    pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+
+    if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVp8Dec->hMFCVp8Handle.pDecOps    = pDecOps;
+    pVp8Dec->hMFCVp8Handle.pInbufOps  = pInbufOps;
+    pVp8Dec->hMFCVp8Handle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pDecOps->nSize    = sizeof(ExynosVideoDecOps);
+    pInbufOps->nSize  = sizeof(ExynosVideoDecBufferOps);
+    pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
+
+    if (Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for decoder ops */
+    if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
+        (pDecOps->Get_ActualBufferCount == NULL) ||
+        (pDecOps->Set_FrameTag == NULL) || (pDecOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pVp8Dec->hMFCVp8Handle.hMFCHandle = pVp8Dec->hMFCVp8Handle.pDecOps->Init(pVideoInstInfo);
+    if (pVp8Dec->hMFCVp8Handle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pDecOps != NULL) {
+            Exynos_OSAL_Free(pDecOps);
+            pVp8Dec->hMFCVp8Handle.pDecOps = NULL;
+        }
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pVp8Dec->hMFCVp8Handle.pInbufOps = NULL;
+        }
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pVp8Dec->hMFCVp8Handle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecClose(EXYNOS_VP8DEC_HANDLE *pVp8Dec)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pVp8Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    pDecOps    = pVp8Dec->hMFCVp8Handle.pDecOps;
+    pInbufOps  = pVp8Dec->hMFCVp8Handle.pInbufOps;
+    pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pDecOps->Finalize(hMFCHandle);
+        pVp8Dec->hMFCVp8Handle.hMFCHandle = NULL;
+        pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE;
+        pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pVp8Dec->hMFCVp8Handle.pOutbufOps = NULL;
+    }
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pVp8Dec->hMFCVp8Handle.pInbufOps = NULL;
+    }
+    if (pDecOps != NULL) {
+        Exynos_OSAL_Free(pDecOps);
+        pVp8Dec->hMFCVp8Handle.pDecOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp8Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    pInbufOps  = pVp8Dec->hMFCVp8Handle.pInbufOps;
+    pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc == OMX_TRUE)) {
+        pInbufOps->Run(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_TRUE)) {
+        pOutbufOps->Run(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp8Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    pInbufOps  = pVp8Dec->hMFCVp8Handle.pInbufOps;
+    pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) {
+        pInbufOps->Stop(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) {
+        EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+        pOutbufOps->Stop(hMFCHandle);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE)
+            pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp8Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pVp8Dec->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pVp8Dec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pVp8Dec->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pVp8Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pVp8Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pVp8Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Vp8CodecReconfigAllBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = &pExynosComponent->pExynosPort[nPortIndex];
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    ExynosVideoDecBufferOps         *pBufferOps         = NULL;
+
+    FunctionIn();
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pVp8Dec->bSourceStart == OMX_TRUE)) {
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pVp8Dec->bDestinationStart == OMX_TRUE)) {
+        pBufferOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+
+        if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+            /**********************************/
+            /* Codec Buffer Free & Unregister */
+            /**********************************/
+            Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+            Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE;
+
+            /******************************************************/
+            /* V4L2 Destnation Setup for DPB Buffer Number Change */
+            /******************************************************/
+            ret = VP8CodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to Vp8CodecDstSetup(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+        } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+            /***************************/
+            /* Codec Buffer Unregister */
+            /***************************/
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE;
+        }
+    } else {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE          *pVp8Dec          = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle       = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+
+    ExynosVideoDecBufferOps *pInbufOps  = pVp8Dec->hMFCVp8Handle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+
+    int i;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecInputBuffer[i]->fd[0], pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < pVp8Dec->hMFCVp8Handle.maxDPBNum; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecOutputBuffer[i]->fd[0], pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+        }
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Vp8CodecUpdateBlackBarCrop(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE          *pVp8Dec              = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    OMX_CONFIG_RECTTYPE           *pBlackBarCropRect    = &pVideoDec->blackBarCropRect;
+
+    ExynosVideoDecBufferOps  *pOutbufOps  = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+    ExynosVideoRect           CropRect;
+
+    FunctionIn();
+
+    Exynos_OSAL_Memset(&CropRect, 0, sizeof(ExynosVideoRect));
+    if (pOutbufOps->Get_BlackBarCrop(hMFCHandle, &CropRect) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get crop info", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pBlackBarCropRect->nLeft   = CropRect.nLeft;
+    pBlackBarCropRect->nTop    = CropRect.nTop;
+    pBlackBarCropRect->nWidth  = CropRect.nWidth;
+    pBlackBarCropRect->nHeight = CropRect.nHeight;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Black Bar Info: LEFT(%d) TOP(%d) WIDTH(%d) HEIGHT(%d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pBlackBarCropRect->nLeft, pBlackBarCropRect->nTop,
+                                        pBlackBarCropRect->nWidth, pBlackBarCropRect->nHeight);
+
+    /** Send Port Settings changed call back **/
+    (*(pExynosComponent->pCallbacks->EventHandler))
+        (pOMXComponent,
+         pExynosComponent->callbackData,
+         OMX_EventPortSettingsChanged, /* The command was completed */
+         OMX_DirOutput, /* This is the port index */
+         (OMX_INDEXTYPE)OMX_IndexConfigBlackBarCrop,
+         NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Vp8CodecCheckResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE          *pVp8Dec            = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_EXCEPTION_STATE     eOutputExcepState  = pOutputPort->exceptionFlag;
+
+    ExynosVideoDecOps             *pDecOps            = pVp8Dec->hMFCVp8Handle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+    ExynosVideoGeometry            codecOutbufConf;
+
+    OMX_CONFIG_RECTTYPE          *pCropRectangle        = &(pOutputPort->cropRectangle);
+    OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition  = &(pInputPort->portDefinition);
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = &(pOutputPort->portDefinition);
+
+    int maxDPBNum = 0;
+
+    FunctionIn();
+
+    /* get geometry */
+    Exynos_OSAL_Memset(&codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry");
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        maxDPBNum += EXTRA_DPB_NUM;
+
+    pCropRectangle->nTop     = codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = codecOutbufConf.cropRect.nHeight;
+
+    /* resolution is changed */
+    if ((codecOutbufConf.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) ||
+        (codecOutbufConf.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight) ||
+        (codecOutbufConf.nStride != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nStride) ||
+#if 0  // TODO: check posibility
+        (codecOutbufConf.eColorFormat != pVp8Dec->hMFCVp8Handle.codecOutbufConf.eColorFormat) ||
+        (codecOutbufConf.eFilledDataType != pVp8Dec->hMFCVp8Handle.codecOutbufConf.eFilledDataType) ||
+#endif
+        (maxDPBNum != pVp8Dec->hMFCVp8Handle.maxDPBNum)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth,
+                            pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight,
+                            codecOutbufConf.nFrameWidth,
+                            codecOutbufConf.nFrameHeight);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] DPB(%d), FORMAT(0x%x), TYPE(0x%x) -> DPB(%d), FORMAT(0x%x), TYPE(0x%x)",
+                            pExynosComponent, __FUNCTION__,
+                            pVp8Dec->hMFCVp8Handle.maxDPBNum,
+                            pVp8Dec->hMFCVp8Handle.codecOutbufConf.eColorFormat,
+                            pVp8Dec->hMFCVp8Handle.codecOutbufConf.eFilledDataType,
+                            maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType);
+
+        pInputPortDefinition->format.video.nFrameWidth     = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight    = codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride         = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight    = codecOutbufConf.nFrameHeight;
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            pOutputPortDefinition->nBufferCountActual  = maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin     = maxDPBNum;
+        }
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        if (eOutputExcepState == GENERAL_STATE) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* crop info of contents is changed */
+    if ((codecOutbufConf.cropRect.nTop != pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nTop) ||
+        (codecOutbufConf.cropRect.nLeft != pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nLeft) ||
+        (codecOutbufConf.cropRect.nWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nWidth) ||
+        (codecOutbufConf.cropRect.nHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nHeight)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nWidth,
+                            pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nHeight,
+                            codecOutbufConf.cropRect.nWidth,
+                            codecOutbufConf.cropRect.nHeight);
+
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    Exynos_OSAL_Memcpy(&pVp8Dec->hMFCVp8Handle.codecOutbufConf, &codecOutbufConf, sizeof(codecOutbufConf));
+    pVp8Dec->hMFCVp8Handle.maxDPBNum = maxDPBNum;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Vp8CodecUpdateResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE          *pVp8Dec            = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    ExynosVideoDecOps             *pDecOps            = pVp8Dec->hMFCVp8Handle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+
+    OMX_CONFIG_RECTTYPE             *pCropRectangle         = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE    *pInputPortDefinition   = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE    *pOutputPortDefinition  = NULL;
+
+    FunctionIn();
+
+    /* get geometry for output */
+    Exynos_OSAL_Memset(&pVp8Dec->hMFCVp8Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &pVp8Dec->hMFCVp8Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get geometry about output", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedHeader;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    pVp8Dec->hMFCVp8Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        pVp8Dec->hMFCVp8Handle.maxDPBNum += EXTRA_DPB_NUM;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] maxDPBNum: %d", pExynosComponent, __FUNCTION__, pVp8Dec->hMFCVp8Handle.maxDPBNum);
+
+    pCropRectangle          = &(pOutputPort->cropRectangle);
+    pInputPortDefinition    = &(pInputPort->portDefinition);
+    pOutputPortDefinition   = &(pOutputPort->portDefinition);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] past info: width(%d) height(%d)",
+                                            pExynosComponent, __FUNCTION__,
+                                            pInputPortDefinition->format.video.nFrameWidth,
+                                            pInputPortDefinition->format.video.nFrameHeight);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] resolution info: width(%d / %d), height(%d / %d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth,
+                                        pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nWidth,
+                                        pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight,
+                                        pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nHeight);
+
+    pCropRectangle->nTop     = pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nHeight;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth  = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride      = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight;
+#if 0
+            /* don't need to change */
+            pOutputPortDefinition->nBufferCountActual       = pOutputPort->portDefinition.nBufferCountActual;
+            pOutputPortDefinition->nBufferCountMin          = pOutputPort->portDefinition.nBufferCountMin;
+#endif
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight) ||
+            ((OMX_S32)pOutputPortDefinition->nBufferCountActual != pVp8Dec->hMFCVp8Handle.maxDPBNum)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth  = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride      = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight;
+
+            pOutputPortDefinition->nBufferCountActual       = pVp8Dec->hMFCVp8Handle.maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin          = pVp8Dec->hMFCVp8Handle.maxDPBNum;
+
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* contents has crop info */
+    if ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nWidth) ||
+        (pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nHeight)) {
+        pInputPortDefinition->format.video.nFrameWidth  = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride      = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight;
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged) with crop",
+                                                pExynosComponent, __FUNCTION__);
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE          *pVp8Dec           = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_COLOR_FORMATTYPE           eOutputFormat     = pExynosOutputPort->portDefinition.format.video.eColorFormat;
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+
+    ExynosVideoDecOps       *pDecOps    = pVp8Dec->hMFCVp8Handle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps  = pVp8Dec->hMFCVp8Handle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_U32  nInBufferCnt   = 0;
+    OMX_BOOL bSupportFormat = OMX_FALSE;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pVp8Dec->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pVp8Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pVp8Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pVideoDec->bThumbnailMode == OMX_TRUE)
+        pDecOps->Set_IFrameDecoding(hMFCHandle);
+
+    if ((pDecOps->Enable_DTSMode != NULL) &&
+        (pVideoDec->bDTSMode == OMX_TRUE))
+        pDecOps->Enable_DTSMode(hMFCHandle);
+
+    /* input buffer info */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eCompressionFormat = VIDEO_CODING_VP8;
+    pInbufOps->Set_Shareable(hMFCHandle);
+
+    nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        /* OMX buffer is not used directly : CODEC buffer */
+        nAllocLen[0] = pSrcInputData->allocSize;
+    }
+
+    bufferConf.nSizeImage = nAllocLen[0];
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+    nInBufferCnt = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    /* should be done before prepare input buffer */
+    if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set output geometry */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+    bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] omx format(0x%x) is %s by h/w",
+                                            pExynosComponent, __FUNCTION__, eOutputFormat,
+                                            (bSupportFormat == OMX_TRUE)? "supported":"not supported");
+    if (bSupportFormat == OMX_TRUE) {  /* supported by H/W */
+        bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eOutputFormat, pExynosOutputPort->ePlaneType);
+        Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pExynosOutputPort->ePlaneType));
+    } else {
+        OMX_COLOR_FORMATTYPE eCheckFormat = OMX_SEC_COLOR_FormatNV12Tiled;
+        bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        if (bSupportFormat != OMX_TRUE) {
+            eCheckFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+            bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        }
+        if (bSupportFormat == OMX_TRUE) {  /* supported by CSC(NV12T/NV12 -> format) */
+            bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eCheckFormat, pExynosOutputPort->ePlaneType);
+            Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eCheckFormat, pExynosOutputPort->ePlaneType));
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not support this format (0x%x)", pExynosComponent, __FUNCTION__, eOutputFormat);
+            ret = OMX_ErrorNotImplemented;
+            pInbufOps->Cleanup_Buffer(hMFCHandle);
+            goto EXIT;
+        }
+    }
+
+    pVp8Dec->hMFCVp8Handle.MFCOutputColorType = bufferConf.eColorFormat;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output video format is 0x%x",
+                                            pExynosComponent, __FUNCTION__, bufferConf.eColorFormat);
+
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    /* input buffer enqueue for header parsing */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+
+    if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pSrcInputData->buffer.addr,
+                            (unsigned long *)pSrcInputData->buffer.fd,
+                            nAllocLen,
+                            nDataLen,
+                            Exynos_GetPlaneFromPort(pExynosInputPort),
+                            pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enqueue input buffer for header parsing", pExynosComponent, __FUNCTION__);
+//        ret = OMX_ErrorInsufficientResources;
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_TRUE;
+
+    /* start header parsing */
+    if (VP8CodecStart(pOMXComponent, INPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run input buffer for header parsing", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    ret = Vp8CodecUpdateResolution(pOMXComponent);
+    if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+        (pExynosComponent->codecType != HW_VIDEO_DEC_SECURE_CODEC) &&
+        (oneFrameSize >= 8)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...", pExynosComponent, __FUNCTION__,
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0])    , *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 1),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 2), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 3),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 4), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 5),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 6), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 7));
+    }
+
+    if (ret != OMX_ErrorNone) {
+        VP8CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_SleepMillisec(0);
+    ret = (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet;
+    VP8CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE          *pVp8Dec              = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort    = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecOps       *pDecOps    = pVp8Dec->hMFCVp8Handle.pDecOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nOutbufs, nPlaneCnt;
+
+    FunctionIn();
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++)
+        nAllocLen[i] = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nAlignPlaneSize[i];
+
+    VP8CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    /* for adaptive playback */
+    if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enable Dynamic DPB", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare output buffer */
+        if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        /* get dpb count */
+        nOutbufs = pVp8Dec->hMFCVp8Handle.maxDPBNum;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        /* Enqueue output buffer */
+        for (i = 0; i < nOutbufs; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+                            (unsigned long *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+                            pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+                            nDataLen,
+                            nPlaneCnt,
+                            NULL);
+        }
+
+        pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_TRUE;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* get dpb count */
+        nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+        if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pExynosOutputPort->eMetaDataType == METADATA_TYPE_DISABLED) {
+            /*************/
+            /*    TBD    */
+            /*************/
+            /* data buffer : user buffer
+             * H/W can't accept user buffer directly
+             */
+            ret = OMX_ErrorNotImplemented;
+            goto EXIT;
+        }
+
+        pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_TRUE;
+    }
+
+    if (VP8CodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoVp8:
+    {
+        OMX_VIDEO_PARAM_VP8TYPE *pDstVP8Component = (OMX_VIDEO_PARAM_VP8TYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP8TYPE *pSrcVP8Component = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstVP8Component, sizeof(OMX_VIDEO_PARAM_VP8TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstVP8Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVP8Component = &pVp8Dec->VP8Component[pDstVP8Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstVP8Component) + nOffset,
+                           ((char *)pSrcVP8Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_VP8TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE    *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP8TYPE             *pSrcVP8Component = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVP8Component = &pVp8Dec->VP8Component[pDstProfileLevel->nPortIndex];
+
+        pDstProfileLevel->eProfile = pSrcVP8Component->eProfile;
+        pDstProfileLevel->eLevel = pSrcVP8Component->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoVp8:
+    {
+        OMX_VIDEO_PARAM_VP8TYPE *pDstVP8Component = NULL;
+        OMX_VIDEO_PARAM_VP8TYPE *pSrcVP8Component = (OMX_VIDEO_PARAM_VP8TYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcVP8Component, sizeof(OMX_VIDEO_PARAM_VP8TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcVP8Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstVP8Component = &pVp8Dec->VP8Component[pSrcVP8Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstVP8Component) + nOffset,
+                           ((char *)pSrcVP8Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_VP8TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE)) {
+            pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel  = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP8TYPE          *pDstVP8Component  = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstVP8Component = &pVp8Dec->VP8Component[pSrcProfileLevel->nPortIndex];
+
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pDstVP8Component->eProfile  = pSrcProfileLevel->eProfile;
+        pDstVP8Component->eLevel    = pSrcProfileLevel->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_GetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch (nIndex) {
+    case OMX_IndexConfigCommonOutputCrop:
+    {
+        EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+        OMX_CONFIG_RECTTYPE *pSrcRectType  = NULL;
+        OMX_CONFIG_RECTTYPE *pDstRectType  = NULL;
+
+        if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc == OMX_FALSE) {
+            ret = OMX_ErrorNotReady;
+            break;
+        }
+
+        pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
+
+        if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) &&
+            (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex];
+
+        pSrcRectType = &(pExynosPort->cropRectangle);
+
+        pDstRectType->nTop    = pSrcRectType->nTop;
+        pDstRectType->nLeft   = pSrcRectType->nLeft;
+        pDstRectType->nHeight = pSrcRectType->nHeight;
+        pDstRectType->nWidth  = pSrcRectType->nWidth;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    switch (nIndex) {
+    default:
+        ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_GetExtensionIndex(
+    OMX_IN  OMX_HANDLETYPE  hComponent,
+    OMX_IN  OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE  *pIndexType)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_ComponentRoleEnum(
+    OMX_HANDLETYPE hComponent,
+    OMX_U8        *cRole,
+    OMX_U32        nIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) || (cRole == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE);
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorNoMore;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_VP8Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_VP8DEC_HANDLE          *pVp8Dec           = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    ExynosVideoInstInfo *pVideoInstInfo = &(pVp8Dec->hMFCVp8Handle.videoInstInfo);
+
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+    int i;
+
+    FunctionIn();
+
+    pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE;
+    pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    pVideoDec->bDiscardCSDError = OMX_FALSE;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                             pExynosInputPort->portDefinition.format.video.nBitrate,
+                                                                                             pExynosInputPort->portDefinition.format.video.xFramerate);
+
+    pVideoInstInfo->nSize        = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth       = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight      = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate     = pExynosInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate   = pExynosInputPort->portDefinition.format.video.xFramerate;
+
+    /* VP8 Codec Open */
+    ret = VP8CodecOpen(pVp8Dec, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+        nAllocLen[0] = ALIGN(pExynosInputPort->portDefinition.format.video.nFrameWidth *
+                             pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+        if (nAllocLen[0] < pVideoDec->nMinInBufSize)
+            nAllocLen[0] = pVideoDec->nMinInBufSize;
+
+        Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_SetPlaneToPort(pExynosOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pVp8Dec->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pVp8Dec->hSourceStartEvent);
+    pVp8Dec->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pVp8Dec->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pVp8Dec->hDestinationOutStartEvent);
+
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pVp8Dec->hMFCVp8Handle.indexTimestamp = 0;
+    pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = 0;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pVp8Dec->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+    pVideoDec->csc_handle = csc_init(csc_method);
+    if (pVideoDec->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    pVideoDec->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_VP8Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    FunctionIn();
+
+    if (pVideoDec->csc_handle != NULL) {
+        csc_deinit(pVideoDec->csc_handle);
+        pVideoDec->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pVp8Dec->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pVp8Dec->hDestinationInStartEvent);
+    pVp8Dec->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pVp8Dec->hDestinationOutStartEvent);
+    pVp8Dec->hDestinationOutStartEvent = NULL;
+    pVp8Dec->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pVp8Dec->hSourceStartEvent);
+    pVp8Dec->hSourceStartEvent = NULL;
+    pVp8Dec->bSourceStart = OMX_FALSE;
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
+        pExynosOutputPort->codecSemID = NULL;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
+        pExynosInputPort->codecSemID = NULL;
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+    VP8CodecClose(pVp8Dec);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE          *pVp8Dec           = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+
+    ExynosVideoDecOps       *pDecOps     = pVp8Dec->hMFCVp8Handle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps   = pVp8Dec->hMFCVp8Handle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_BOOL bInStartCode = OMX_FALSE;
+
+    FunctionIn();
+
+    if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = VP8CodecSrcSetup(pOMXComponent, pSrcInputData);
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (pVp8Dec->bDestinationStart == OMX_FALSE) &&
+        (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_FALSE)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+        ret = VP8CodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Vp8CodecDstSetup(0x%x)",
+                                            pExynosComponent, __FUNCTION__, ret);
+            goto EXIT;
+        }
+    }
+
+    if (((bInStartCode = Check_VP8_StartCode(pSrcInputData->buffer.addr[0], oneFrameSize)) == OMX_TRUE) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+        pExynosComponent->timeStamp[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pSrcInputData->timeStamp;
+        pExynosComponent->nFlags[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pSrcInputData->nFlags;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), dataLen(%d), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, oneFrameSize, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pVp8Dec->hMFCVp8Handle.indexTimestamp);
+
+        pDecOps->Set_FrameTag(hMFCHandle, pVp8Dec->hMFCVp8Handle.indexTimestamp);
+        pVp8Dec->hMFCVp8Handle.indexTimestamp++;
+        pVp8Dec->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP;
+
+        if ((pVideoDec->bQosChanged == OMX_TRUE) &&
+            (pDecOps->Set_QosRatio != NULL)) {
+            pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
+            pVideoDec->bQosChanged = OMX_FALSE;
+        }
+
+        if (pVideoDec->bSearchBlackBarChanged == OMX_TRUE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] BlackBar searching mode : %s",
+                                            pExynosComponent, __FUNCTION__,
+                                            (pVideoDec->bSearchBlackBar == OMX_TRUE) ? "enable" : "disable");
+            pDecOps->Set_SearchBlackBar(hMFCHandle, (ExynosVideoBoolType)pVideoDec->bSearchBlackBar);
+            pVideoDec->bSearchBlackBarChanged = OMX_FALSE;
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        /* queue work for input buffer */
+        nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+        if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        } else {
+            nAllocLen[0] = pSrcInputData->allocSize;
+
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        }
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pSrcInputData->buffer.addr,
+                                (unsigned long *)pSrcInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pExynosInputPort),
+                                pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            goto EXIT;
+        }
+
+        VP8CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        if (pVp8Dec->bSourceStart == OMX_FALSE) {
+            pVp8Dec->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pVp8Dec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        if ((pVp8Dec->bDestinationStart == OMX_FALSE) &&
+            (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_TRUE)) {
+            pVp8Dec->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pVp8Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pVp8Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    } else if (bInStartCode == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] can't find a start code", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedFrame;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pInbufOps      = pVp8Dec->hMFCVp8Handle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->allocSize  = 0;
+        pSrcOutputData->pPrivate = NULL;
+    } else {
+        pSrcOutputData->buffer.addr[0] = pVideoBuffer->planes[0].addr;
+        pSrcOutputData->buffer.fd[0] = pVideoBuffer->planes[0].fd;
+        pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
+
+        if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] ==
+                        pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
+                    pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pExynosInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pOutbufOps  = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++) {
+        nAllocLen[i] = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nAlignPlaneSize[i];
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] ADDR[%d]: 0x%x, size[%d]: %d", pExynosComponent, __FUNCTION__,
+                                        i, pDstInputData->buffer.addr[i], i, nAllocLen[i]);
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                nPlaneCnt,
+                                pDstInputData->bufferHeader);
+
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+        }
+
+        goto EXIT;
+    }
+
+    VP8CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    DECODE_CODEC_EXTRA_BUFFERINFO   *pBufferInfo        = NULL;
+
+    ExynosVideoDecOps           *pDecOps        = pVp8Dec->hMFCVp8Handle.pDecOps;
+    ExynosVideoDecBufferOps     *pOutbufOps     = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+    ExynosVideoBuffer           *pVideoBuffer   = NULL;
+    ExynosVideoBuffer            videoBuffer;
+    ExynosVideoFrameStatusType   displayStatus  = VIDEO_FRAME_STATUS_UNKNOWN;
+    ExynosVideoGeometry         *bufferGeometry = NULL;
+    ExynosVideoErrorType         codecReturn    = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+
+    OMX_S32 indexTimestamp = 0;
+    int plane, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pVp8Dec->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    while (1) {
+        Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer));
+
+        codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+        if (codecReturn == VIDEO_ERROR_NONE) {
+            pVideoBuffer = &videoBuffer;
+        } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO) at ExtensionDequeue", pExynosComponent, __FUNCTION__);
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorHardware;
+            goto EXIT;
+        } else {
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        displayStatus = pVideoBuffer->displayStatus;
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus: 0x%x", pExynosComponent, __FUNCTION__, displayStatus);
+
+        if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
+            (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+            (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+            (CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+            ret = OMX_ErrorNone;
+            break;
+        }
+    }
+
+   if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+       (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) {
+        if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+            pOutputPort->exceptionFlag = NEED_PORT_FLUSH;
+            pVideoDec->bReconfigDPB = OMX_TRUE;
+            Vp8CodecUpdateResolution(pOMXComponent);
+            pVideoDec->csc_set_format = OMX_FALSE;
+        }
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pVp8Dec->hMFCVp8Handle.outputIndexTimestamp++;
+    pVp8Dec->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+    pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
+    nPlaneCnt = Exynos_GetPlaneFromPort(pOutputPort);
+    for (plane = 0; plane < nPlaneCnt; plane++) {
+        pDstOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+        pDstOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+        pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        pDstOutputData->dataLen   += pVideoBuffer->planes[plane].dataSize;
+        nDataLen[plane]            = pVideoBuffer->planes[plane].dataSize;
+    }
+    pDstOutputData->usedDataLen = 0;
+    pDstOutputData->pPrivate = pVideoBuffer;
+
+    pBufferInfo     = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+    bufferGeometry  = &pVp8Dec->hMFCVp8Handle.codecOutbufConf;
+    pBufferInfo->imageWidth       = bufferGeometry->nFrameWidth;
+    pBufferInfo->imageHeight      = bufferGeometry->nFrameHeight;
+    pBufferInfo->imageStride      = bufferGeometry->nStride;
+    pBufferInfo->cropRect.nLeft   = bufferGeometry->cropRect.nLeft;
+    pBufferInfo->cropRect.nTop    = bufferGeometry->cropRect.nTop;
+    pBufferInfo->cropRect.nWidth  = bufferGeometry->cropRect.nWidth;
+    pBufferInfo->cropRect.nHeight = bufferGeometry->cropRect.nHeight;
+    pBufferInfo->colorFormat      = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+    Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            goto EXIT;
+        }
+
+        /* calculate each plane info for the application */
+        Exynos_OSAL_GetPlaneSize(pOutputPort->portDefinition.format.video.eColorFormat,
+                                 PLANE_SINGLE, pOutputPort->portDefinition.format.video.nFrameWidth,
+                                 pOutputPort->portDefinition.format.video.nFrameHeight,
+                                 nDataLen, nAllocLen);
+
+        pDstOutputData->allocSize = nAllocLen[0] + nAllocLen[1] + nAllocLen[2];
+        pDstOutputData->dataLen   = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+    indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+    if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+        if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
+            (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
+            if (indexTimestamp == INDEX_AFTER_EOS) {
+                pDstOutputData->timeStamp = 0x00;
+                pDstOutputData->nFlags = 0x00;
+            } else {
+                pDstOutputData->timeStamp = pExynosComponent->timeStamp[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp];
+                pDstOutputData->nFlags = pExynosComponent->nFlags[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp];
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] missing out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+            }
+        } else {
+            pDstOutputData->timeStamp = 0x00;
+            pDstOutputData->nFlags = 0x00;
+        }
+    } else {
+        /* For timestamp correction. if mfc support frametype detect */
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] disp_pic_frame_type: %d", pExynosComponent, __FUNCTION__, pVideoBuffer->frameType);
+
+        /* NEED TIMESTAMP REORDER */
+        if (pVideoDec->bDTSMode == OMX_TRUE) {
+            if ((pVideoBuffer->frameType & VIDEO_FRAME_I) ||
+                ((pVideoBuffer->frameType & VIDEO_FRAME_OTHERS) &&
+                    ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
+                (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
+               pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = indexTimestamp;
+            else
+               indexTimestamp = pVp8Dec->hMFCVp8Handle.outputIndexTimestamp;
+        }
+
+        pDstOutputData->timeStamp   = pExynosComponent->timeStamp[indexTimestamp];
+        pDstOutputData->nFlags      = pExynosComponent->nFlags[indexTimestamp] | OMX_BUFFERFLAG_ENDOFFRAME;
+
+        if (pVideoBuffer->frameType & VIDEO_FRAME_I)
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+        if (pVideoBuffer->frameType & VIDEO_FRAME_CORRUPT)
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+    }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                                    pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                                    indexTimestamp);
+
+    if (pVideoBuffer->frameType & VIDEO_FRAME_WITH_BLACK_BAR) {
+        if (Vp8CodecUpdateBlackBarCrop(pOMXComponent) != OMX_ErrorNone)
+            goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+        (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+    }
+
+    if (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) {
+        pDstOutputData->remainDataLen = 0;
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            if (indexTimestamp != INDEX_AFTER_EOS)
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] tag(%d) is wrong", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+            pDstOutputData->timeStamp   = 0x00;
+            pDstOutputData->nFlags      = 0x00;
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) ||
+            (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+            pExynosComponent->nFlags[indexTimestamp] &= (~OMX_BUFFERFLAG_EOS);
+        }
+    } else if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        pDstOutputData->remainDataLen = 0;
+
+        if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
+            pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+
+            if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+                pExynosComponent->bBehaviorEOS = OMX_FALSE;
+            } else {
+                pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+                pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+            }
+        }
+    } else {
+        pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_VP8Dec_SrcIn(pOMXComponent, pSrcInputData);
+    if ((ret != OMX_ErrorNone) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorCorruptedFrame)) {
+
+        if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+            (pVideoDec->bDiscardCSDError == OMX_TRUE)) {
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+    if ((pVp8Dec->bSourceStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
+        Exynos_OSAL_SignalWait(pVp8Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp8Dec->hSourceStartEvent);
+    }
+
+    ret = Exynos_VP8Dec_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        if (pExynosComponent->currentState == OMX_StatePause)
+            ret = (OMX_ERRORTYPE)OMX_ErrorOutputBufferUseYet;
+        else
+            ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVp8Dec->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pVp8Dec->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp8Dec->hDestinationInStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pVp8Dec->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pVp8Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+
+        if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+            (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+            ret = VP8CodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Vp8CodecDstSetup(0x%x)", pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+            Exynos_OSAL_SignalSet(pVp8Dec->hDestinationOutStartEvent);
+        }
+    }
+
+    if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_VP8Dec_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (((pVp8Dec->bDestinationStart == OMX_FALSE) ||
+         (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_FALSE)) &&
+        (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pVp8Dec->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp8Dec->hDestinationOutStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pVp8Dec->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pVp8Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_VP8Dec_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE  hComponent,
+    OMX_STRING      componentName)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_VP8DEC_HANDLE            *pVp8Dec            = NULL;
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) || (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP8_DEC, componentName) != 0) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pVp8Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_VP8DEC_HANDLE));
+    if (pVp8Dec == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pVp8Dec, 0, sizeof(EXYNOS_VP8DEC_HANDLE));
+    pVideoDec               = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pVp8Dec;
+    Exynos_OSAL_Strcpy(pExynosComponent->componentName, componentName);
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE)
+        pExynosPort->portDefinition.nBufferSize = CUSTOM_DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+
+    pVideoDec->nMinInBufSize = (DEFAULT_VIDEO_MIN_INPUT_BUFFER_SIZE * 2);  /* for DRC :: depends on compression ratio */
+
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/x-vnd.on2.vp8");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pVp8Dec->VP8Component[i], OMX_VIDEO_PARAM_VP8TYPE);
+        pVp8Dec->VP8Component[i].nPortIndex = i;
+        pVp8Dec->VP8Component[i].eProfile   = OMX_VIDEO_VP8ProfileMain;
+        pVp8Dec->VP8Component[i].eLevel     = OMX_VIDEO_VP8Level_Version3;
+    }
+
+    pOMXComponent->GetParameter      = &Exynos_VP8Dec_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_VP8Dec_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_VP8Dec_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_VP8Dec_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_VP8Dec_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_VP8Dec_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_VP8Dec_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_VP8Dec_Terminate;
+
+    pVideoDec->exynos_codec_srcInputProcess  = &Exynos_VP8Dec_srcInputBufferProcess;
+    pVideoDec->exynos_codec_srcOutputProcess = &Exynos_VP8Dec_srcOutputBufferProcess;
+    pVideoDec->exynos_codec_dstInputProcess  = &Exynos_VP8Dec_dstInputBufferProcess;
+    pVideoDec->exynos_codec_dstOutputProcess = &Exynos_VP8Dec_dstOutputBufferProcess;
+
+    pVideoDec->exynos_codec_start            = &VP8CodecStart;
+    pVideoDec->exynos_codec_stop             = &VP8CodecStop;
+    pVideoDec->exynos_codec_bufferProcessRun = &VP8CodecOutputBufferProcessRun;
+    pVideoDec->exynos_codec_enqueueAllBuffer = &VP8CodecEnQueueAllBuffer;
+
+    pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+    pVideoDec->exynos_codec_reconfigAllBuffers        = &Vp8CodecReconfigAllBuffers;
+
+    pVideoDec->exynos_codec_checkFormatSupport      = &CheckFormatHWSupport;
+    pVideoDec->exynos_codec_checkResolutionChange   = &Vp8CodecCheckResolution;
+
+    pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoDec->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pVp8Dec);
+        pVp8Dec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVp8Dec->hMFCVp8Handle.videoInstInfo.eCodecType = VIDEO_CODING_VP8;
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        pVp8Dec->hMFCVp8Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pVp8Dec->hMFCVp8Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pVp8Dec->hMFCVp8Handle.videoInstInfo), VIDEO_TRUE /* dec */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pVp8Dec);
+        pVp8Dec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_Output_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
+    OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+    EXYNOS_VP8DEC_HANDLE        *pVp8Dec            = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp8Dec != NULL) {
+        Exynos_OSAL_Free(pVp8Dec);
+        pVp8Dec = pVideoDec->hCodecHandle = NULL;
+    }
+
+    ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/dec/vp8/Exynos_OMX_Vp8dec.h b/openmax/component/video/dec/vp8/Exynos_OMX_Vp8dec.h
new file mode 100755 (executable)
index 0000000..a0a60c7
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Vp8dec.h
+ * @brief
+ * @author     Satish Kumar Reddy (palli.satish@samsung.com)
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_VP8_DEC_COMPONENT
+#define EXYNOS_OMX_VP8_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+#include "ExynosVideoApi.h"
+
+
+typedef struct _EXYNOS_MFC_VP8DEC_HANDLE
+{
+    OMX_HANDLETYPE             hMFCHandle;
+    OMX_U32                    indexTimestamp;
+    OMX_U32                    outputIndexTimestamp;
+    OMX_BOOL                   bConfiguredMFCSrc;
+    OMX_BOOL                   bConfiguredMFCDst;
+    OMX_S32                    maxDPBNum;
+
+    ExynosVideoColorFormatType MFCOutputColorType;
+    ExynosVideoDecOps         *pDecOps;
+    ExynosVideoDecBufferOps   *pInbufOps;
+    ExynosVideoDecBufferOps   *pOutbufOps;
+    ExynosVideoGeometry        codecOutbufConf;
+    ExynosVideoInstInfo        videoInstInfo;
+
+    #define MAX_PROFILE_NUM 1
+    OMX_VIDEO_VP8PROFILETYPE   profiles[MAX_PROFILE_NUM];
+    OMX_S32                    nProfileCnt;
+    OMX_VIDEO_VP8LEVELTYPE     maxLevel;
+} EXYNOS_MFC_VP8DEC_HANDLE;
+
+typedef struct _EXYNOS_VP8DEC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_VP8TYPE             VP8Component[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+
+    /* EXYNOS MFC Codec specific */
+    EXYNOS_MFC_VP8DEC_HANDLE            hMFCVp8Handle;
+
+    OMX_BOOL bSourceStart;
+    OMX_BOOL bDestinationStart;
+    OMX_HANDLETYPE hSourceStartEvent;
+    OMX_HANDLETYPE hDestinationInStartEvent;
+    OMX_HANDLETYPE hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE bypassBufferInfoQ;
+} EXYNOS_VP8DEC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE hComponent,
+    OMX_STRING componentName);
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
+    OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE VP8CodecDstSetup(
+    OMX_COMPONENTTYPE *pOMXComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/vp8/Makefile.am b/openmax/component/video/dec/vp8/Makefile.am
new file mode 100755 (executable)
index 0000000..14d7884
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libOMX.Exynos.VP8.Decoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_VP8_Decoder_la_SOURCES = Exynos_OMX_Vp8dec.c \
+                                       library_register.c
+
+libOMX_Exynos_VP8_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                      $(top_builddir)/openmax/component/video/dec/libExynosOMX_Vdec.la \
+                                      $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+libOMX_Exynos_VP8_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                      -I$(top_srcdir)/openmax/include/exynos \
+                                      -I$(top_srcdir)/openmax/osal \
+                                      -I$(top_srcdir)/openmax/core \
+                                      -I$(top_srcdir)/openmax/component/common \
+                                      -I$(top_srcdir)/openmax/component/video/dec \
+                                      -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_VP8_Decoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF -DUSE_VP8_SUPPORT
+libOMX_Exynos_VP8_Decoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable
+
+libOMX_Exynos_VP8_Decoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/dec/vp8/library_register.c b/openmax/component/video/dec/vp8/library_register.c
new file mode 100755 (executable)
index 0000000..3cd7c40
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       library_register.c
+ * @brief
+ * @author     Satish Kumar Reddy (palli.satish@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VP8_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(
+    ExynosRegisterComponentType **ppExynosComponent)
+{
+    FunctionIn();
+
+    if (ppExynosComponent == NULL)
+        goto EXIT;
+
+    /* component 1 - video decoder VP8 */
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_VP8_DEC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE);
+    ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
diff --git a/openmax/component/video/dec/vp8/library_register.h b/openmax/component/video/dec/vp8/library_register.h
new file mode 100755 (executable)
index 0000000..4d8ca84
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author      Satish Kumar Reddy (palli.satish@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_VP8_DEC_REG
+#define EXYNOS_OMX_VP8_DEC_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM       1
+#define MAX_COMPONENT_ROLE_NUM  1
+
+/* VP8 */
+#ifndef USE_CUSTOM_COMPONENT_SUPPORT
+#define EXYNOS_OMX_COMPONENT_VP8_DEC        "OMX.Exynos.VP8.Decoder"
+#else
+#define EXYNOS_OMX_COMPONENT_VP8_DEC        "OMX.Exynos.vp8.dec"
+#endif
+
+#define EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE   "video_decoder.vp8"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(
+    ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/vp9/Exynos_OMX_Vp9dec.c b/openmax/component/video/dec/vp9/Exynos_OMX_Vp9dec.c
new file mode 100755 (executable)
index 0000000..c8f39d4
--- /dev/null
@@ -0,0 +1,3208 @@
+/*
+ *
+ * Copyright 2014 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Vp9dec.c
+ * @brief
+ * @author     Taehwan Kim (t_h.kim@samsung.com)
+ *             SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2014.07.24 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Vdec.h"
+#include "Exynos_OMX_VdecControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Vp9dec.h"
+#include "ExynosVideoApi.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+#include "VendorVideoAPI.h"
+
+/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
+/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VP9_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec        = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp9Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Dec->hMFCVp9Handle.profiles[nProfileCnt++] = OMX_VIDEO_VP9Profile0;
+    switch (pVp9Dec->hMFCVp9Handle.videoInstInfo.HwVersion) {
+    case MFC_120:
+    case MFC_1220:
+        pVp9Dec->hMFCVp9Handle.profiles[nProfileCnt++] = OMX_VIDEO_VP9Profile2;
+        pVp9Dec->hMFCVp9Handle.profiles[nProfileCnt++] = OMX_VIDEO_VP9Profile2HDR;
+        break;
+    default:
+        break;
+    }
+    pVp9Dec->hMFCVp9Handle.nProfileCnt = nProfileCnt;
+
+    switch (pVp9Dec->hMFCVp9Handle.videoInstInfo.HwVersion) {
+    case MFC_120:
+    case MFC_1220:
+        pVp9Dec->hMFCVp9Handle.maxLevel = OMX_VIDEO_VP9Level51;
+        break;
+    default:
+        pVp9Dec->hMFCVp9Handle.maxLevel = OMX_VIDEO_VP9Level41;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret           = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec     = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec       = NULL;
+
+    OMX_U32 nMaxIndex = 0;
+
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp9Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pVp9Dec->hMFCVp9Handle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pVp9Dec->hMFCVp9Handle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pVp9Dec->hMFCVp9Handle.maxLevel;
+#else
+    while ((pVp9Dec->hMFCVp9Handle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+
+    if ((pVp9Dec->hMFCVp9Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pVp9Dec->hMFCVp9Handle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pVp9Dec->hMFCVp9Handle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] supported profile(%x), level(%x)",
+                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec  = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec    = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp9Dec == NULL)
+        goto EXIT;
+
+    while ((pVp9Dec->hMFCVp9Handle.maxLevel >> nLevelCnt++) > 0);
+
+    if ((pVp9Dec->hMFCVp9Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pVp9Dec->hMFCVp9Handle.nProfileCnt; i++) {
+        if (pVp9Dec->hMFCVp9Handle.profiles[i] == pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    while (nLevelCnt >= 0) {
+        if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+            bLevelSupport = OMX_TRUE;
+            break;
+        }
+
+        nLevelCnt--;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    FunctionOut();
+
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
+{
+    OMX_ERRORTYPE       ret          = OMX_ErrorNone;
+    ExynosVideoBuffer  *pCodecBuffer = NULL;
+
+    if (codecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
+
+    if (addr != NULL) {
+        addr[0] = pCodecBuffer->planes[0].addr;
+        addr[1] = pCodecBuffer->planes[1].addr;
+        addr[2] = pCodecBuffer->planes[2].addr;
+    }
+
+    if (size != NULL) {
+        size[0] = pCodecBuffer->planes[0].allocSize;
+        size[1] = pCodecBuffer->planes[1].allocSize;
+        size[2] = pCodecBuffer->planes[2].allocSize;
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_BOOL Check_VP9_StartCode(
+    OMX_U8     *pInputStream,
+    OMX_U32     streamSize)
+{
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] buffer: %p, streamSize: %d", __FUNCTION__, pInputStream, streamSize);
+    if (streamSize < 1) {
+        return OMX_FALSE;
+    }
+
+    return OMX_TRUE;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec      = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec        = NULL;
+    EXYNOS_OMX_BASEPORT             *pOutputPort    = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL)
+        goto EXIT;
+
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp9Dec == NULL)
+        goto EXIT;
+    pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pOutputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pVp9Dec->hMFCVp9Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pVp9Dec->hMFCVp9Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecOpen(EXYNOS_VP9DEC_HANDLE *pVp9Dec, ExynosVideoInstInfo *pVideoInstInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pVp9Dec == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pDecOps    = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
+    pInbufOps  = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+    pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
+
+    if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVp9Dec->hMFCVp9Handle.pDecOps    = pDecOps;
+    pVp9Dec->hMFCVp9Handle.pInbufOps  = pInbufOps;
+    pVp9Dec->hMFCVp9Handle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pDecOps->nSize    = sizeof(ExynosVideoDecOps);
+    pInbufOps->nSize  = sizeof(ExynosVideoDecBufferOps);
+    pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
+
+    if (Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for decoder ops */
+    if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
+        (pDecOps->Get_ActualBufferCount == NULL) ||
+        (pDecOps->Set_FrameTag == NULL) || (pDecOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pVp9Dec->hMFCVp9Handle.hMFCHandle = pVp9Dec->hMFCVp9Handle.pDecOps->Init(pVideoInstInfo);
+    if (pVp9Dec->hMFCVp9Handle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pDecOps != NULL) {
+            Exynos_OSAL_Free(pDecOps);
+            pVp9Dec->hMFCVp9Handle.pDecOps = NULL;
+        }
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pVp9Dec->hMFCVp9Handle.pInbufOps = NULL;
+        }
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pVp9Dec->hMFCVp9Handle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecClose(EXYNOS_VP9DEC_HANDLE *pVp9Dec)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoDecOps       *pDecOps    = NULL;
+    ExynosVideoDecBufferOps *pInbufOps  = NULL;
+    ExynosVideoDecBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pVp9Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    pDecOps    = pVp9Dec->hMFCVp9Handle.pDecOps;
+    pInbufOps  = pVp9Dec->hMFCVp9Handle.pInbufOps;
+    pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pDecOps->Finalize(hMFCHandle);
+        pVp9Dec->hMFCVp9Handle.hMFCHandle = NULL;
+        pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc = OMX_FALSE;
+        pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pVp9Dec->hMFCVp9Handle.pOutbufOps = NULL;
+    }
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pVp9Dec->hMFCVp9Handle.pInbufOps = NULL;
+    }
+    if (pDecOps != NULL) {
+        Exynos_OSAL_Free(pDecOps);
+        pVp9Dec->hMFCVp9Handle.pDecOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp9Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    pInbufOps  = pVp9Dec->hMFCVp9Handle.pInbufOps;
+    pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc == OMX_TRUE)) {
+        pInbufOps->Run(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst == OMX_TRUE)) {
+        pOutbufOps->Run(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoDecBufferOps         *pInbufOps          = NULL;
+    ExynosVideoDecBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp9Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    pInbufOps  = pVp9Dec->hMFCVp9Handle.pInbufOps;
+    pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) {
+        pInbufOps->Stop(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) {
+        EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+        pOutbufOps->Stop(hMFCHandle);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE)
+            pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoDec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp9Dec == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pVp9Dec->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pVp9Dec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pVp9Dec->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pVp9Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pVp9Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pVp9Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Vp9CodecReconfigAllBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = &pExynosComponent->pExynosPort[nPortIndex];
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    ExynosVideoDecBufferOps         *pBufferOps         = NULL;
+
+    FunctionIn();
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pVp9Dec->bSourceStart == OMX_TRUE)) {
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pVp9Dec->bDestinationStart == OMX_TRUE)) {
+        pBufferOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+
+        if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+            /**********************************/
+            /* Codec Buffer Free & Unregister */
+            /**********************************/
+            Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+            Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst = OMX_FALSE;
+
+            /******************************************************/
+            /* V4L2 Destnation Setup for DPB Buffer Number Change */
+            /******************************************************/
+            ret = VP9CodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to Vp9CodecDstSetup(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+        } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+            /***************************/
+            /* Codec Buffer Unregister */
+            /***************************/
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst = OMX_FALSE;
+        }
+    } else {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+
+    ExynosVideoDecBufferOps *pInbufOps  = pVp9Dec->hMFCVp9Handle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+
+    int i;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecInputBuffer[i]->fd[0], pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < pVp9Dec->hMFCVp9Handle.maxDPBNum; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoDec->pMFCDecOutputBuffer[i]->fd[0], pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+        }
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+#ifdef USE_ANDROID
+void Vp9CodecUpdateHdrInfo(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE          *pVp9Dec           = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort        = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    void                          *hMFCHandle        = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+
+    ExynosVideoDecOps  *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
+    ExynosVideoHdrInfo  sHdrInfo;
+
+    if (pDecOps->Get_HDRInfo(hMFCHandle, &sHdrInfo) == VIDEO_ERROR_NONE) {
+        /* update bitstream's info to input port */
+        EXYNOS_OMX_VIDEO_COLORASPECTS *pColorAspects = &(pInputPort->ColorAspects);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eType(0x%x) is changed", pExynosComponent, __FUNCTION__, sHdrInfo.eChangedType);
+
+        /* color aspects */
+        if (sHdrInfo.eValidType & (HDR_INFO_COLOR_ASPECTS | HDR_INFO_RANGE)) {
+            /* HDR_INFO_COLOR_ASPECTS (8) */
+            pColorAspects->nCoeffType      = sHdrInfo.sColorAspects.eCoeffType;
+            pColorAspects->nPrimaryType    = sHdrInfo.sColorAspects.ePrimariesType;
+            pColorAspects->nTransferType   = sHdrInfo.sColorAspects.eTransferType;
+
+            /* HDR_INFO_RANGE (16) */
+            pColorAspects->nRangeType      = sHdrInfo.sColorAspects.eRangeType;
+        }
+
+        /* if both have changed, should send an event once */
+        if (sHdrInfo.eChangedType & (HDR_INFO_COLOR_ASPECTS | HDR_INFO_RANGE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_IndexConfigVideoColorAspects)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 OMX_IndexConfigVideoColorAspects,
+                 NULL);
+        }
+    }
+
+EXIT:
+
+    return;
+}
+#endif // USE_ANDROID
+
+OMX_ERRORTYPE Vp9CodecUpdateBlackBarCrop(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE          *pVp9Dec              = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    OMX_CONFIG_RECTTYPE           *pBlackBarCropRect    = &pVideoDec->blackBarCropRect;
+
+    ExynosVideoDecBufferOps  *pOutbufOps  = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+    ExynosVideoRect           CropRect;
+
+    FunctionIn();
+
+    Exynos_OSAL_Memset(&CropRect, 0, sizeof(ExynosVideoRect));
+    if (pOutbufOps->Get_BlackBarCrop(hMFCHandle, &CropRect) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get crop info", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pBlackBarCropRect->nLeft   = CropRect.nLeft;
+    pBlackBarCropRect->nTop    = CropRect.nTop;
+    pBlackBarCropRect->nWidth  = CropRect.nWidth;
+    pBlackBarCropRect->nHeight = CropRect.nHeight;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Black Bar Info: LEFT(%d) TOP(%d) WIDTH(%d) HEIGHT(%d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pBlackBarCropRect->nLeft, pBlackBarCropRect->nTop,
+                                        pBlackBarCropRect->nWidth, pBlackBarCropRect->nHeight);
+
+    /** Send Port Settings changed call back **/
+    (*(pExynosComponent->pCallbacks->EventHandler))
+        (pOMXComponent,
+         pExynosComponent->callbackData,
+         OMX_EventPortSettingsChanged, /* The command was completed */
+         OMX_DirOutput, /* This is the port index */
+         (OMX_INDEXTYPE)OMX_IndexConfigBlackBarCrop,
+         NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Vp9CodecCheckResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE          *pVp9Dec            = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_EXCEPTION_STATE     eOutputExcepState  = pOutputPort->exceptionFlag;
+
+    ExynosVideoDecOps             *pDecOps            = pVp9Dec->hMFCVp9Handle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+    ExynosVideoGeometry            codecOutbufConf;
+
+    OMX_CONFIG_RECTTYPE          *pCropRectangle        = &(pOutputPort->cropRectangle);
+    OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition  = &(pInputPort->portDefinition);
+    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = &(pOutputPort->portDefinition);
+
+    int maxDPBNum = 0;
+
+    FunctionIn();
+
+    /* get geometry */
+    Exynos_OSAL_Memset(&codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry");
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        maxDPBNum += EXTRA_DPB_NUM;
+
+    pCropRectangle->nTop     = codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = codecOutbufConf.cropRect.nHeight;
+
+    /* resolution is changed */
+    if ((codecOutbufConf.nFrameWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth) ||
+        (codecOutbufConf.nFrameHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight) ||
+        (codecOutbufConf.nStride != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nStride) ||
+#if 0  // TODO: check posibility
+        (codecOutbufConf.eColorFormat != pVp9Dec->hMFCVp9Handle.codecOutbufConf.eColorFormat) ||
+        (codecOutbufConf.eFilledDataType != pVp9Dec->hMFCVp9Handle.codecOutbufConf.eFilledDataType) ||
+#endif
+        (maxDPBNum != pVp9Dec->hMFCVp9Handle.maxDPBNum)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth,
+                            pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight,
+                            codecOutbufConf.nFrameWidth,
+                            codecOutbufConf.nFrameHeight);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] DPB(%d), FORMAT(0x%x), TYPE(0x%x) -> DPB(%d), FORMAT(0x%x), TYPE(0x%x)",
+                            pExynosComponent, __FUNCTION__,
+                            pVp9Dec->hMFCVp9Handle.maxDPBNum,
+                            pVp9Dec->hMFCVp9Handle.codecOutbufConf.eColorFormat,
+                            pVp9Dec->hMFCVp9Handle.codecOutbufConf.eFilledDataType,
+                            maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType);
+
+        pInputPortDefinition->format.video.nFrameWidth     = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight    = codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride         = codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight    = codecOutbufConf.nFrameHeight;
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            pOutputPortDefinition->nBufferCountActual  = maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin     = maxDPBNum;
+        }
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        if (eOutputExcepState == GENERAL_STATE) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* crop info of contents is changed */
+    if ((codecOutbufConf.cropRect.nTop != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nTop) ||
+        (codecOutbufConf.cropRect.nLeft != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nLeft) ||
+        (codecOutbufConf.cropRect.nWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth) ||
+        (codecOutbufConf.cropRect.nHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nHeight)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][DRC] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+                            pExynosComponent, __FUNCTION__,
+                            pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth,
+                            pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nHeight,
+                            codecOutbufConf.cropRect.nWidth,
+                            codecOutbufConf.cropRect.nHeight);
+
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    Exynos_OSAL_Memcpy(&pVp9Dec->hMFCVp9Handle.codecOutbufConf, &codecOutbufConf, sizeof(codecOutbufConf));
+    pVp9Dec->hMFCVp9Handle.maxDPBNum = maxDPBNum;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Vp9CodecUpdateResolution(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE          *pVp9Dec            = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    ExynosVideoDecOps             *pDecOps            = pVp9Dec->hMFCVp9Handle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+
+    OMX_CONFIG_RECTTYPE             *pCropRectangle         = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE    *pInputPortDefinition   = NULL;
+    OMX_PARAM_PORTDEFINITIONTYPE    *pOutputPortDefinition  = NULL;
+
+    FunctionIn();
+
+    /* get geometry for output */
+    Exynos_OSAL_Memset(&pVp9Dec->hMFCVp9Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &pVp9Dec->hMFCVp9Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to get geometry about output", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedHeader;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    pVp9Dec->hMFCVp9Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+#if 0  /* no needs EXTRA_DPB, it was confirmed codec team */
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        pVp9Dec->hMFCVp9Handle.maxDPBNum += EXTRA_DPB_NUM;
+#endif
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] maxDPBNum: %d", pExynosComponent, __FUNCTION__, pVp9Dec->hMFCVp9Handle.maxDPBNum);
+
+    pCropRectangle          = &(pOutputPort->cropRectangle);
+    pInputPortDefinition    = &(pInputPort->portDefinition);
+    pOutputPortDefinition   = &(pOutputPort->portDefinition);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] past info: width(%d) height(%d)",
+                                            pExynosComponent, __FUNCTION__,
+                                            pInputPortDefinition->format.video.nFrameWidth,
+                                            pInputPortDefinition->format.video.nFrameHeight);
+
+    if (pVp9Dec->hMFCVp9Handle.codecOutbufConf.eFilledDataType & DATA_10BIT) {
+        if (pVp9Dec->hMFCVp9Handle.MFCOutputColorType != pVp9Dec->hMFCVp9Handle.codecOutbufConf.eColorFormat) {
+            OMX_COLOR_FORMATTYPE eOutputFormat = Exynos_OSAL_Video2OMXFormat(pVp9Dec->hMFCVp9Handle.codecOutbufConf.eColorFormat);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] The format(%x) is changed to %x by H/W Codec",
+                                        pExynosComponent, __FUNCTION__,
+                                        pVp9Dec->hMFCVp9Handle.MFCOutputColorType,
+                                        pVp9Dec->hMFCVp9Handle.codecOutbufConf.eColorFormat);
+
+            pVp9Dec->hMFCVp9Handle.MFCOutputColorType = pVp9Dec->hMFCVp9Handle.codecOutbufConf.eColorFormat;
+            Exynos_SetPlaneToPort(pOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pOutputPort->ePlaneType));
+        }
+
+        if (pVp9Dec->hMFCVp9Handle.codecOutbufConf.eFilledDataType == DATA_8BIT_WITH_2BIT)
+            pVideoDec->eDataType = DATA_TYPE_8BIT_WITH_2BIT;
+        else
+            pVideoDec->eDataType = DATA_TYPE_10BIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] resolution info: width(%d / %d), height(%d / %d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth,
+                                        pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth,
+                                        pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight,
+                                        pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nHeight);
+
+    pCropRectangle->nTop     = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nTop;
+    pCropRectangle->nLeft    = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nLeft;
+    pCropRectangle->nWidth   = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth;
+    pCropRectangle->nHeight  = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nHeight;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pVideoDec->eDataType & DATA_TYPE_10BIT) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth  = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride      = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
+#if 0
+            /* don't need to change */
+            pOutputPortDefinition->nBufferCountActual       = pOutputPort->portDefinition.nBufferCountActual;
+            pOutputPortDefinition->nBufferCountMin          = pOutputPort->portDefinition.nBufferCountMin;
+#endif
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pVideoDec->eDataType & DATA_TYPE_10BIT) ||
+            (pInputPortDefinition->format.video.nFrameWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPortDefinition->format.video.nFrameHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight) ||
+            ((OMX_S32)pOutputPortDefinition->nBufferCountActual != pVp9Dec->hMFCVp9Handle.maxDPBNum)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPortDefinition->format.video.nFrameWidth  = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nFrameHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
+            pInputPortDefinition->format.video.nStride      = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
+            pInputPortDefinition->format.video.nSliceHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
+
+            pOutputPortDefinition->nBufferCountActual       = pVp9Dec->hMFCVp9Handle.maxDPBNum;
+            pOutputPortDefinition->nBufferCountMin          = pVp9Dec->hMFCVp9Handle.maxDPBNum;
+
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged)",
+                                                    pExynosComponent, __FUNCTION__);
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+
+    /* contents has crop info */
+    if ((pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth) ||
+        (pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nHeight)) {
+        pInputPortDefinition->format.video.nFrameWidth  = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nFrameHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
+        pInputPortDefinition->format.video.nStride      = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
+        pInputPortDefinition->format.video.nSliceHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
+
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventPortSettingsChanged) with crop",
+                                                pExynosComponent, __FUNCTION__);
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE          *pVp9Dec           = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_COLOR_FORMATTYPE           eOutputFormat     = pExynosOutputPort->portDefinition.format.video.eColorFormat;
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+
+    EXYNOS_OMX_VIDEO_COLORASPECTS   *pFWCA           = &(pExynosOutputPort->ColorAspects);
+    EXYNOS_OMX_VIDEO_COLORASPECTS   *pBSCA           = &(pExynosInputPort->ColorAspects);
+
+    ExynosVideoDecOps       *pDecOps    = pVp9Dec->hMFCVp9Handle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps  = pVp9Dec->hMFCVp9Handle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_U32  nInBufferCnt   = 0;
+    OMX_BOOL bSupportFormat = OMX_FALSE;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pVp9Dec->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pVp9Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pVp9Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pVideoDec->bThumbnailMode == OMX_TRUE)
+        pDecOps->Set_IFrameDecoding(hMFCHandle);
+
+    if ((pDecOps->Enable_DTSMode != NULL) &&
+        (pVideoDec->bDTSMode == OMX_TRUE))
+        pDecOps->Enable_DTSMode(hMFCHandle);
+
+    /* input buffer info */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eCompressionFormat = VIDEO_CODING_VP9;
+    pInbufOps->Set_Shareable(hMFCHandle);
+
+    nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        /* OMX buffer is not used directly : CODEC buffer */
+        nAllocLen[0] = pSrcInputData->allocSize;
+    }
+
+    bufferConf.nSizeImage = nAllocLen[0];
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+    nInBufferCnt = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    /* should be done before prepare input buffer */
+    if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* set output geometry */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+    bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] omx format(0x%x) is %s by h/w",
+                                            pExynosComponent, __FUNCTION__, eOutputFormat,
+                                            (bSupportFormat == OMX_TRUE)? "supported":"not supported");
+    if (bSupportFormat == OMX_TRUE) {  /* supported by H/W */
+        bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eOutputFormat, pExynosOutputPort->ePlaneType);
+        Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pExynosOutputPort->ePlaneType));
+    } else {
+        OMX_COLOR_FORMATTYPE eCheckFormat = OMX_SEC_COLOR_FormatNV12Tiled;
+        bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        if (bSupportFormat != OMX_TRUE) {
+            eCheckFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+            bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
+        }
+        if (bSupportFormat == OMX_TRUE) {  /* supported by CSC(NV12T/NV12 -> format) */
+            bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eCheckFormat, pExynosOutputPort->ePlaneType);
+            Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eCheckFormat, pExynosOutputPort->ePlaneType));
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not support this format (0x%x)", pExynosComponent, __FUNCTION__, eOutputFormat);
+            ret = OMX_ErrorNotImplemented;
+            pInbufOps->Cleanup_Buffer(hMFCHandle);
+            goto EXIT;
+        }
+    }
+
+    pVp9Dec->hMFCVp9Handle.MFCOutputColorType = bufferConf.eColorFormat;
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output video format is 0x%x",
+                                            pExynosComponent, __FUNCTION__, bufferConf.eColorFormat);
+
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    /* input buffer enqueue for header parsing */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+
+    if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pSrcInputData->buffer.addr,
+                            (unsigned long *)pSrcInputData->buffer.fd,
+                            nAllocLen,
+                            nDataLen,
+                            Exynos_GetPlaneFromPort(pExynosInputPort),
+                            pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enqueue input buffer for header parsing", pExynosComponent, __FUNCTION__);
+//        ret = OMX_ErrorInsufficientResources;
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        goto EXIT;
+    }
+
+    pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc = OMX_TRUE;
+
+    /* start header parsing */
+    if (VP9CodecStart(pOMXComponent, INPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run input buffer for header parsing", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    ret = Vp9CodecUpdateResolution(pOMXComponent);
+    if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+        (pExynosComponent->codecType != HW_VIDEO_DEC_SECURE_CODEC) &&
+        (oneFrameSize >= 8)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...", pExynosComponent, __FUNCTION__,
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0])    , *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 1),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 2), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 3),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 4), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 5),
+                                    *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 6), *((OMX_U8 *)pSrcInputData->buffer.addr[0] + 7));
+    }
+
+    if (ret != OMX_ErrorNone) {
+        VP9CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
+        pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc = OMX_FALSE;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_SleepMillisec(0);
+    ret = (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet;
+    VP9CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec            = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE          *pVp9Dec              = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle           = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort    = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecOps       *pDecOps    = pVp9Dec->hMFCVp9Handle.pDecOps;
+    ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+
+    int i, nOutbufs, nPlaneCnt;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+
+    FunctionIn();
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++)
+        nAllocLen[i] = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nAlignPlaneSize[i];
+
+    VP9CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    /* for adaptive playback */
+    if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to enable Dynamic DPB", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare output buffer */
+        if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        /* get dpb count */
+        nOutbufs = pVp9Dec->hMFCVp9Handle.maxDPBNum;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        /* Enqueue output buffer */
+        for (i = 0; i < nOutbufs; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                            (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+                            (unsigned long *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+                            pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+                            nDataLen,
+                            nPlaneCnt,
+                            NULL);
+        }
+
+        pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst = OMX_TRUE;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* get dpb count */
+        nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+        if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        if (pExynosOutputPort->eMetaDataType == METADATA_TYPE_DISABLED) {
+            /*************/
+            /*    TBD    */
+            /*************/
+            /* data buffer : user buffer
+             * H/W can't accept user buffer directly
+             */
+            ret = OMX_ErrorNotImplemented;
+            goto EXIT;
+        }
+
+        pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst = OMX_TRUE;
+    }
+
+    if (VP9CodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoVp9:
+    {
+        OMX_VIDEO_PARAM_VP9TYPE *pDstVP9Component = (OMX_VIDEO_PARAM_VP9TYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP9TYPE *pSrcVP9Component = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstVP9Component, sizeof(OMX_VIDEO_PARAM_VP9TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstVP9Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVP9Component = &pVp9Dec->VP9Component[pDstVP9Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstVP9Component) + nOffset,
+                           ((char *)pSrcVP9Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_VP9TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP9_DEC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE    *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP9TYPE             *pSrcVP9Component = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVP9Component = &pVp9Dec->VP9Component[pDstProfileLevel->nPortIndex];
+
+        pDstProfileLevel->eProfile = pSrcVP9Component->eProfile;
+        pDstProfileLevel->eLevel = pSrcVP9Component->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pVp9Dec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoVp9:
+    {
+        OMX_VIDEO_PARAM_VP9TYPE *pDstVP9Component = NULL;
+        OMX_VIDEO_PARAM_VP9TYPE *pSrcVP9Component = (OMX_VIDEO_PARAM_VP9TYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcVP9Component, sizeof(OMX_VIDEO_PARAM_VP9TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcVP9Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstVP9Component = &pVp9Dec->VP9Component[pSrcVP9Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstVP9Component) + nOffset,
+                           ((char *)pSrcVP9Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_VP9TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP9_DEC_ROLE)) {
+            pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP9;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel  = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP9TYPE          *pDstVP9Component  = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstVP9Component = &pVp9Dec->VP9Component[pSrcProfileLevel->nPortIndex];
+
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pDstVP9Component->eProfile  = pSrcProfileLevel->eProfile;
+        pDstVP9Component->eLevel    = pSrcProfileLevel->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pVp9Dec->errorCorrectionType[INPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_GetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch (nIndex) {
+    case OMX_IndexConfigCommonOutputCrop:
+    {
+        EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+        OMX_CONFIG_RECTTYPE *pSrcRectType  = NULL;
+        OMX_CONFIG_RECTTYPE *pDstRectType  = NULL;
+
+        if (pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc == OMX_FALSE) {
+            ret = OMX_ErrorNotReady;
+            break;
+        }
+
+        pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
+
+        if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) &&
+            (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex];
+
+        pSrcRectType = &(pExynosPort->cropRectangle);
+
+        pDstRectType->nTop    = pSrcRectType->nTop;
+        pDstRectType->nLeft   = pSrcRectType->nLeft;
+        pDstRectType->nHeight = pSrcRectType->nHeight;
+        pDstRectType->nWidth  = pSrcRectType->nWidth;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE  nIndex,
+    OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch (nIndex) {
+    default:
+        ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_GetExtensionIndex(
+    OMX_IN  OMX_HANDLETYPE  hComponent,
+    OMX_IN  OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE  *pIndexType)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_ComponentRoleEnum(
+    OMX_HANDLETYPE hComponent,
+    OMX_U8        *cRole,
+    OMX_U32        nIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) || (cRole == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_VP9_DEC_ROLE);
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorNoMore;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_VP9Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_VP9DEC_HANDLE          *pVp9Dec           = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    ExynosVideoInstInfo *pVideoInstInfo = &(pVp9Dec->hMFCVp9Handle.videoInstInfo);
+
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+    int i;
+
+    FunctionIn();
+
+    pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc = OMX_FALSE;
+    pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    pVideoDec->bDiscardCSDError = OMX_FALSE;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                             pExynosInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                             pExynosInputPort->portDefinition.format.video.nBitrate,
+                                                                                             pExynosInputPort->portDefinition.format.video.xFramerate);
+
+    pVideoInstInfo->nSize        = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth       = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight      = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate     = pExynosInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate   = pExynosInputPort->portDefinition.format.video.xFramerate;
+
+    /* VP9 Codec Open */
+    ret = VP9CodecOpen(pVp9Dec, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+        nAllocLen[0] = ALIGN(pExynosInputPort->portDefinition.format.video.nFrameWidth *
+                             pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+        if (nAllocLen[0] < pVideoDec->nMinInBufSize)
+            nAllocLen[0] = pVideoDec->nMinInBufSize;
+
+        Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
+            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_SetPlaneToPort(pExynosOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pVp9Dec->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pVp9Dec->hSourceStartEvent);
+    pVp9Dec->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pVp9Dec->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pVp9Dec->hDestinationOutStartEvent);
+
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pVp9Dec->hMFCVp9Handle.indexTimestamp = 0;
+    pVp9Dec->hMFCVp9Handle.outputIndexTimestamp = 0;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pVp9Dec->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) {
+        pVideoDec->csc_handle = csc_init(CSC_METHOD_HW);
+        csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2);
+        csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_MODE_DRM, 1);
+    } else {
+        pVideoDec->csc_handle = csc_init(csc_method);
+    }
+
+    if (pVideoDec->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    pVideoDec->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_VP9Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    FunctionIn();
+
+    if (pVideoDec->csc_handle != NULL) {
+        csc_deinit(pVideoDec->csc_handle);
+        pVideoDec->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pVp9Dec->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pVp9Dec->hDestinationInStartEvent);
+    pVp9Dec->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pVp9Dec->hDestinationOutStartEvent);
+    pVp9Dec->hDestinationOutStartEvent = NULL;
+    pVp9Dec->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pVp9Dec->hSourceStartEvent);
+    pVp9Dec->hSourceStartEvent = NULL;
+    pVp9Dec->bSourceStart = OMX_FALSE;
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
+        pExynosOutputPort->codecSemID = NULL;
+    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
+        pExynosInputPort->codecSemID = NULL;
+    } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+    VP9CodecClose(pVp9Dec);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE          *pVp9Dec           = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+
+    ExynosVideoDecOps       *pDecOps     = pVp9Dec->hMFCVp9Handle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps   = pVp9Dec->hMFCVp9Handle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {oneFrameSize, 0, 0};
+    OMX_BOOL bInStartCode = OMX_FALSE;
+
+    FunctionIn();
+
+    if (pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = VP9CodecSrcSetup(pOMXComponent, pSrcInputData);
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (pVp9Dec->bDestinationStart == OMX_FALSE) &&
+        (pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst == OMX_FALSE)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+        ret = VP9CodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Vp9CodecDstSetup(0x%x)",
+                                            pExynosComponent, __FUNCTION__, ret);
+            goto EXIT;
+        }
+    }
+
+    if (((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) ||
+            ((bInStartCode = Check_VP9_StartCode(pSrcInputData->buffer.addr[0], oneFrameSize)) == OMX_TRUE)) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+        pExynosComponent->timeStamp[pVp9Dec->hMFCVp9Handle.indexTimestamp] = pSrcInputData->timeStamp;
+        pExynosComponent->nFlags[pVp9Dec->hMFCVp9Handle.indexTimestamp] = pSrcInputData->nFlags;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), dataLen(%d), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, oneFrameSize, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pVp9Dec->hMFCVp9Handle.indexTimestamp);
+
+        pDecOps->Set_FrameTag(hMFCHandle, pVp9Dec->hMFCVp9Handle.indexTimestamp);
+        pVp9Dec->hMFCVp9Handle.indexTimestamp++;
+        pVp9Dec->hMFCVp9Handle.indexTimestamp %= MAX_TIMESTAMP;
+
+        if ((pVideoDec->bQosChanged == OMX_TRUE) &&
+            (pDecOps->Set_QosRatio != NULL)) {
+            pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
+            pVideoDec->bQosChanged = OMX_FALSE;
+        }
+
+        if (pVideoDec->bSearchBlackBarChanged == OMX_TRUE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] BlackBar searching mode : %s",
+                                            pExynosComponent, __FUNCTION__,
+                                            (pVideoDec->bSearchBlackBar == OMX_TRUE) ? "enable" : "disable");
+            pDecOps->Set_SearchBlackBar(hMFCHandle, (ExynosVideoBoolType)pVideoDec->bSearchBlackBar);
+            pVideoDec->bSearchBlackBarChanged = OMX_FALSE;
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        /* queue work for input buffer */
+        nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+        if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        } else {
+            nAllocLen[0] = pSrcInputData->allocSize;
+
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        }
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pSrcInputData->buffer.addr,
+                                (unsigned long *)pSrcInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pExynosInputPort),
+                                pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            goto EXIT;
+        }
+        VP9CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        if (pVp9Dec->bSourceStart == OMX_FALSE) {
+            pVp9Dec->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pVp9Dec->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        if ((pVp9Dec->bDestinationStart == OMX_FALSE) &&
+            (pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc == OMX_TRUE)) {
+            pVp9Dec->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pVp9Dec->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pVp9Dec->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    } else if (bInStartCode == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] can't find a start code", pExynosComponent, __FUNCTION__);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCorruptedFrame;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pInbufOps      = pVp9Dec->hMFCVp9Handle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->allocSize  = 0;
+        pSrcOutputData->pPrivate = NULL;
+    } else {
+        pSrcOutputData->buffer.addr[0] = pVideoBuffer->planes[0].addr;
+        pSrcOutputData->buffer.fd[0] = pVideoBuffer->planes[0].fd;
+        pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
+
+        if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] ==
+                        pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
+                    pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pExynosInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecBufferOps *pOutbufOps  = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    int i, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+    for (i = 0; i < nPlaneCnt; i++) {
+        nAllocLen[i] = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nAlignPlaneSize[i];
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] ADDR[%d]: 0x%x, size[%d]: %d", pExynosComponent, __FUNCTION__,
+                                        i, pDstInputData->buffer.addr[i], i, nAllocLen[i]);
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                nPlaneCnt,
+                                pDstInputData->bufferHeader);
+
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+        }
+
+        goto EXIT;
+    }
+
+    VP9CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    DECODE_CODEC_EXTRA_BUFFERINFO   *pBufferInfo        = NULL;
+
+    ExynosVideoDecOps           *pDecOps        = pVp9Dec->hMFCVp9Handle.pDecOps;
+    ExynosVideoDecBufferOps     *pOutbufOps     = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+    ExynosVideoBuffer           *pVideoBuffer   = NULL;
+    ExynosVideoBuffer            videoBuffer;
+    ExynosVideoFrameStatusType   displayStatus  = VIDEO_FRAME_STATUS_UNKNOWN;
+    ExynosVideoGeometry         *bufferGeometry = NULL;
+    ExynosVideoErrorType         codecReturn    = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+
+    OMX_S32 indexTimestamp = 0;
+    int plane, nPlaneCnt;
+
+    FunctionIn();
+
+    if (pVp9Dec->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    while (1) {
+        Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer));
+
+        codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+        if (codecReturn == VIDEO_ERROR_NONE) {
+            pVideoBuffer = &videoBuffer;
+        } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO) at ExtensionDequeue", pExynosComponent, __FUNCTION__);
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorHardware;
+            goto EXIT;
+        } else {
+            pVideoBuffer = NULL;
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        displayStatus = pVideoBuffer->displayStatus;
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus: 0x%x", pExynosComponent, __FUNCTION__, displayStatus);
+
+        if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
+            (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+            (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+            (CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+            ret = OMX_ErrorNone;
+            break;
+        }
+    }
+
+   if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+       (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) {
+        if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+            pOutputPort->exceptionFlag = NEED_PORT_FLUSH;
+            pVideoDec->bReconfigDPB = OMX_TRUE;
+            Vp9CodecUpdateResolution(pOMXComponent);
+            pVideoDec->csc_set_format = OMX_FALSE;
+        }
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pVp9Dec->hMFCVp9Handle.outputIndexTimestamp++;
+    pVp9Dec->hMFCVp9Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+    pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
+    nPlaneCnt = Exynos_GetPlaneFromPort(pOutputPort);
+    for (plane = 0; plane < nPlaneCnt; plane++) {
+        pDstOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+        pDstOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+        pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        pDstOutputData->dataLen   += pVideoBuffer->planes[plane].dataSize;
+        nDataLen[plane]            = pVideoBuffer->planes[plane].dataSize;
+    }
+    pDstOutputData->usedDataLen = 0;
+    pDstOutputData->pPrivate = pVideoBuffer;
+
+    pBufferInfo     = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+    bufferGeometry  = &pVp9Dec->hMFCVp9Handle.codecOutbufConf;
+    pBufferInfo->imageWidth       = bufferGeometry->nFrameWidth;
+    pBufferInfo->imageHeight      = bufferGeometry->nFrameHeight;
+    pBufferInfo->imageStride      = bufferGeometry->nStride;
+    pBufferInfo->cropRect.nLeft   = bufferGeometry->cropRect.nLeft;
+    pBufferInfo->cropRect.nTop    = bufferGeometry->cropRect.nTop;
+    pBufferInfo->cropRect.nWidth  = bufferGeometry->cropRect.nWidth;
+    pBufferInfo->cropRect.nHeight = bufferGeometry->cropRect.nHeight;
+    pBufferInfo->colorFormat      = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+    Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            goto EXIT;
+        }
+
+        /* calculate each plane info for the application */
+        Exynos_OSAL_GetPlaneSize(pOutputPort->portDefinition.format.video.eColorFormat,
+                                 PLANE_SINGLE, pOutputPort->portDefinition.format.video.nFrameWidth,
+                                 pOutputPort->portDefinition.format.video.nFrameHeight,
+                                 nDataLen, nAllocLen);
+
+        pDstOutputData->allocSize = nAllocLen[0] + nAllocLen[1] + nAllocLen[2];
+        pDstOutputData->dataLen   = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+#ifdef USE_ANDROID
+    /* color aspects : the bitstream has only this */
+    if ((pOutputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pVideoBuffer->frameType & VIDEO_FRAME_WITH_HDR_INFO)) {
+        Vp9CodecUpdateHdrInfo(pOMXComponent);
+    }
+#endif
+
+    /* hdr static info : the bitstream doesn't have this. always sets value set by framework */
+    if ((pOutputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pVideoBuffer->planes[2].addr != NULL)) {
+        ExynosVideoMeta                 *pMeta          = (ExynosVideoMeta *)pVideoBuffer->planes[2].addr;
+        ExynosType1                     *pMetaHDR       = &(pMeta->data.dec.sHdrStaticInfo.sType1);
+        EXYNOS_OMX_VIDEO_HDRSTATICINFO  *pHDRStaticInfo = &(pOutputPort->HDRStaticInfo);
+
+        pMeta->eType = VIDEO_INFO_TYPE_HDR_STATIC;
+
+        pMetaHDR->mMaxFrameAverageLightLevel = pHDRStaticInfo->nMaxPicAverageLight;
+        pMetaHDR->mMaxContentLightLevel      = pHDRStaticInfo->nMaxContentLight;
+        pMetaHDR->mMaxDisplayLuminance       = pHDRStaticInfo->nMaxDisplayLuminance;
+        pMetaHDR->mMinDisplayLuminance       = pHDRStaticInfo->nMinDisplayLuminance;
+
+        pMetaHDR->mR.x = pHDRStaticInfo->red.x;
+        pMetaHDR->mR.y = pHDRStaticInfo->red.y;
+
+        pMetaHDR->mG.x = pHDRStaticInfo->green.x;
+        pMetaHDR->mG.y = pHDRStaticInfo->green.y;
+
+        pMetaHDR->mB.x = pHDRStaticInfo->blue.x;
+        pMetaHDR->mB.y = pHDRStaticInfo->blue.y;
+
+        pMetaHDR->mW.x = pHDRStaticInfo->white.x;
+        pMetaHDR->mW.y = pHDRStaticInfo->white.y;
+    }
+
+    indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+    if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+        if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
+            (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
+            if (indexTimestamp == INDEX_AFTER_EOS) {
+                pDstOutputData->timeStamp = 0x00;
+                pDstOutputData->nFlags = 0x00;
+            } else {
+                pDstOutputData->timeStamp = pExynosComponent->timeStamp[pVp9Dec->hMFCVp9Handle.outputIndexTimestamp];
+                pDstOutputData->nFlags = pExynosComponent->nFlags[pVp9Dec->hMFCVp9Handle.outputIndexTimestamp];
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] missing out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+            }
+        } else {
+            pDstOutputData->timeStamp = 0x00;
+            pDstOutputData->nFlags = 0x00;
+        }
+    } else {
+        /* For timestamp correction. if mfc support frametype detect */
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] disp_pic_frame_type: %d", pExynosComponent, __FUNCTION__, pVideoBuffer->frameType);
+
+        /* NEED TIMESTAMP REORDER */
+        if (pVideoDec->bDTSMode == OMX_TRUE) {
+            if ((pVideoBuffer->frameType & VIDEO_FRAME_I) ||
+                ((pVideoBuffer->frameType & VIDEO_FRAME_OTHERS) &&
+                    ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
+                (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
+               pVp9Dec->hMFCVp9Handle.outputIndexTimestamp = indexTimestamp;
+            else
+               indexTimestamp = pVp9Dec->hMFCVp9Handle.outputIndexTimestamp;
+        }
+
+        pDstOutputData->timeStamp   = pExynosComponent->timeStamp[indexTimestamp];
+        pDstOutputData->nFlags      = pExynosComponent->nFlags[indexTimestamp] | OMX_BUFFERFLAG_ENDOFFRAME;
+
+        if (pVideoBuffer->frameType & VIDEO_FRAME_I)
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+        if (pVideoBuffer->frameType & VIDEO_FRAME_CORRUPT)
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+
+    }
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), tag: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                                    pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                                    indexTimestamp);
+
+    if (pVideoBuffer->frameType & VIDEO_FRAME_WITH_BLACK_BAR) {
+        if (Vp9CodecUpdateBlackBarCrop(pOMXComponent) != OMX_ErrorNone)
+            goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+        (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+    }
+
+    if (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) {
+        pDstOutputData->remainDataLen = 0;
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            if (indexTimestamp != INDEX_AFTER_EOS)
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] tag(%d) is wrong", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+            pDstOutputData->timeStamp   = 0x00;
+            pDstOutputData->nFlags      = 0x00;
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) ||
+            (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+            pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+            pExynosComponent->nFlags[indexTimestamp] &= (~OMX_BUFFERFLAG_EOS);
+        }
+    } else if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        pDstOutputData->remainDataLen = 0;
+
+        if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
+            pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+
+            if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+                pExynosComponent->bBehaviorEOS = OMX_FALSE;
+            } else {
+                pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+                pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+            }
+        }
+    } else {
+        pDstOutputData->remainDataLen = nDataLen[0] + nDataLen[1] + nDataLen[2];
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVideoDec->bForceHeaderParsing == OMX_FALSE) &&
+        (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_VP9Dec_SrcIn(pOMXComponent, pSrcInputData);
+    if ((ret != OMX_ErrorNone) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) &&
+        ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorCorruptedFrame)) {
+
+        if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
+            (pVideoDec->bDiscardCSDError == OMX_TRUE)) {
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+    if ((pVp9Dec->bSourceStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
+        Exynos_OSAL_SignalWait(pVp9Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp9Dec->hSourceStartEvent);
+    }
+
+    ret = Exynos_VP9Dec_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        if (pExynosComponent->currentState == OMX_StatePause)
+            ret = (OMX_ERRORTYPE)OMX_ErrorOutputBufferUseYet;
+        else
+            ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVp9Dec->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pVp9Dec->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp9Dec->hDestinationInStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pVp9Dec->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pVp9Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+            (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] do DstSetup", pExynosComponent, __FUNCTION__);
+            ret = VP9CodecDstSetup(pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Vp9CodecDstSetup(0x%x)", pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+            Exynos_OSAL_SignalSet(pVp9Dec->hDestinationOutStartEvent);
+        }
+    }
+
+    if (pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_VP9Dec_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (((pVp9Dec->bDestinationStart == OMX_FALSE) ||
+         (pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst == OMX_FALSE)) &&
+        (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+        Exynos_OSAL_SignalWait(pVp9Dec->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoDec->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp9Dec->hDestinationOutStartEvent);
+    }
+
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pVp9Dec->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pVp9Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_VP9Dec_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE  hComponent,
+    OMX_STRING      componentName)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
+    EXYNOS_VP9DEC_HANDLE            *pVp9Dec            = NULL;
+    OMX_BOOL                         bSecureMode        = OMX_FALSE;
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) || (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP9_DEC, componentName) == 0) {
+        bSecureMode = OMX_FALSE;
+    } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP9_DRM_DEC, componentName) == 0) {
+        bSecureMode = OMX_TRUE;
+    } else {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = (bSecureMode == OMX_TRUE)? HW_VIDEO_DEC_SECURE_CODEC:HW_VIDEO_DEC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pVp9Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_VP9DEC_HANDLE));
+    if (pVp9Dec == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pVp9Dec, 0, sizeof(EXYNOS_VP9DEC_HANDLE));
+    pVideoDec               = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pVp9Dec;
+    Exynos_OSAL_Strcpy(pExynosComponent->componentName, componentName);
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE)
+        pExynosPort->portDefinition.nBufferSize = CUSTOM_DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+
+    pVideoDec->nMinInBufSize = DEFAULT_VIDEO_MIN_INPUT_BUFFER_SIZE;  /* for DRC */
+
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP9;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/x-vnd.on2.vp9");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+#ifdef USE_SINGLE_PLANE_IN_DRM
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        pExynosPort->ePlaneType = PLANE_SINGLE;
+#endif
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pVp9Dec->VP9Component[i], OMX_VIDEO_PARAM_VP9TYPE);
+        pVp9Dec->VP9Component[i].nPortIndex = i;
+        pVp9Dec->VP9Component[i].eProfile   = OMX_VIDEO_VP9Profile0;
+        pVp9Dec->VP9Component[i].eLevel     = OMX_VIDEO_VP9Level41;
+    }
+
+    pOMXComponent->GetParameter      = &Exynos_VP9Dec_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_VP9Dec_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_VP9Dec_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_VP9Dec_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_VP9Dec_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_VP9Dec_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_VP9Dec_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_VP9Dec_Terminate;
+
+    pVideoDec->exynos_codec_srcInputProcess  = &Exynos_VP9Dec_srcInputBufferProcess;
+    pVideoDec->exynos_codec_srcOutputProcess = &Exynos_VP9Dec_srcOutputBufferProcess;
+    pVideoDec->exynos_codec_dstInputProcess  = &Exynos_VP9Dec_dstInputBufferProcess;
+    pVideoDec->exynos_codec_dstOutputProcess = &Exynos_VP9Dec_dstOutputBufferProcess;
+
+    pVideoDec->exynos_codec_start            = &VP9CodecStart;
+    pVideoDec->exynos_codec_stop             = &VP9CodecStop;
+    pVideoDec->exynos_codec_bufferProcessRun = &VP9CodecOutputBufferProcessRun;
+    pVideoDec->exynos_codec_enqueueAllBuffer = &VP9CodecEnQueueAllBuffer;
+
+    pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+    pVideoDec->exynos_codec_reconfigAllBuffers        = &Vp9CodecReconfigAllBuffers;
+
+    pVideoDec->exynos_codec_checkFormatSupport      = &CheckFormatHWSupport;
+    pVideoDec->exynos_codec_checkResolutionChange   = &Vp9CodecCheckResolution;
+
+    pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoDec->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pVp9Dec);
+        pVp9Dec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVp9Dec->hMFCVp9Handle.videoInstInfo.eCodecType = VIDEO_CODING_VP9;
+    if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
+        pVp9Dec->hMFCVp9Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pVp9Dec->hMFCVp9Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pVp9Dec->hMFCVp9Handle.videoInstInfo), VIDEO_TRUE /* dec */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pVp9Dec);
+        pVp9Dec = pVideoDec->hCodecHandle = NULL;
+        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_Output_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
+    OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+    EXYNOS_VP9DEC_HANDLE        *pVp9Dec            = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
+    if (pVp9Dec != NULL) {
+        Exynos_OSAL_Free(pVp9Dec);
+        pVp9Dec = pVideoDec->hCodecHandle = NULL;
+    }
+
+    ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/dec/vp9/Exynos_OMX_Vp9dec.h b/openmax/component/video/dec/vp9/Exynos_OMX_Vp9dec.h
new file mode 100755 (executable)
index 0000000..7d79220
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ *
+ * Copyright 2014 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Vp9dec.h
+ * @brief
+ * @author     Taehwan Kim (t_h.kim@samsung.com)
+ *             SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2014.07.24 : Create
+ */
+
+#ifndef EXYNOS_OMX_VP9_DEC_COMPONENT
+#define EXYNOS_OMX_VP9_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+#include "ExynosVideoApi.h"
+
+
+typedef struct _EXYNOS_MFC_VP9DEC_HANDLE
+{
+    OMX_HANDLETYPE             hMFCHandle;
+    OMX_U32                    indexTimestamp;
+    OMX_U32                    outputIndexTimestamp;
+    OMX_BOOL                   bConfiguredMFCSrc;
+    OMX_BOOL                   bConfiguredMFCDst;
+    OMX_S32                    maxDPBNum;
+
+    ExynosVideoColorFormatType MFCOutputColorType;
+    ExynosVideoDecOps         *pDecOps;
+    ExynosVideoDecBufferOps   *pInbufOps;
+    ExynosVideoDecBufferOps   *pOutbufOps;
+    ExynosVideoGeometry        codecOutbufConf;
+    ExynosVideoInstInfo        videoInstInfo;
+
+    #define MAX_PROFILE_NUM 4
+    OMX_VIDEO_VP9PROFILETYPE   profiles[MAX_PROFILE_NUM];
+    OMX_S32                    nProfileCnt;
+    OMX_VIDEO_VP9LEVELTYPE     maxLevel;
+} EXYNOS_MFC_VP9DEC_HANDLE;
+
+typedef struct _EXYNOS_VP9DEC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_VP9TYPE             VP9Component[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+
+    /* EXYNOS MFC Codec specific */
+    EXYNOS_MFC_VP9DEC_HANDLE            hMFCVp9Handle;
+
+    OMX_BOOL bSourceStart;
+    OMX_BOOL bDestinationStart;
+    OMX_HANDLETYPE hSourceStartEvent;
+    OMX_HANDLETYPE hDestinationInStartEvent;
+    OMX_HANDLETYPE hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE bypassBufferInfoQ;
+} EXYNOS_VP9DEC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE hComponent,
+    OMX_STRING componentName);
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
+    OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE VP9CodecDstSetup(
+    OMX_COMPONENTTYPE *pOMXComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/dec/vp9/Makefile.am b/openmax/component/video/dec/vp9/Makefile.am
new file mode 100755 (executable)
index 0000000..e4530a8
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libOMX.Exynos.VP9.Decoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_VP9_Decoder_la_SOURCES = Exynos_OMX_Vp9dec.c \
+                                       library_register.c
+
+libOMX_Exynos_VP9_Decoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                      $(top_builddir)/openmax/component/video/dec/libExynosOMX_Vdec.la \
+                                      $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+libOMX_Exynos_VP9_Decoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                      -I$(top_srcdir)/openmax/include/exynos \
+                                      -I$(top_srcdir)/openmax/osal \
+                                      -I$(top_srcdir)/openmax/core \
+                                      -I$(top_srcdir)/openmax/component/common \
+                                      -I$(top_srcdir)/openmax/component/video/dec \
+                                      -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_VP9_Decoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF -DUSE_VP9_SUPPORT
+libOMX_Exynos_VP9_Decoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable
+
+libOMX_Exynos_VP9_Decoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/dec/vp9/library_register.c b/openmax/component/video/dec/vp9/library_register.c
new file mode 100755 (executable)
index 0000000..7543742
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright 2014 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       library_register.c
+ * @brief
+ * @author     Taehwan Kim (t_h.kim@samsung.com)
+ *             SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2014.07.24 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VP9_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(
+    ExynosRegisterComponentType **ppExynosComponent)
+{
+    FunctionIn();
+
+    if (ppExynosComponent == NULL)
+        goto EXIT;
+
+    /* component 1 - video decoder VP9 */
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_VP9_DEC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_VP9_DEC_ROLE);
+    ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+    /* component 2 - video decoder VP9 for DRM */
+    Exynos_OSAL_Strcpy(ppExynosComponent[1]->componentName, EXYNOS_OMX_COMPONENT_VP9_DRM_DEC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[1]->roles[0], EXYNOS_OMX_COMPONENT_VP9_DEC_ROLE);
+    ppExynosComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
diff --git a/openmax/component/video/dec/vp9/library_register.h b/openmax/component/video/dec/vp9/library_register.h
new file mode 100755 (executable)
index 0000000..c95b649
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author     Taehwan Kim (t_h.kim@samsung.com)
+ *             SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2014.07.24 : Create
+ */
+
+#ifndef EXYNOS_OMX_VP9_DEC_REG
+#define EXYNOS_OMX_VP9_DEC_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM       2
+#define MAX_COMPONENT_ROLE_NUM  1
+
+/* VP9 */
+#ifndef USE_CUSTOM_COMPONENT_SUPPORT
+#define EXYNOS_OMX_COMPONENT_VP9_DEC            "OMX.Exynos.VP9.Decoder"
+#define EXYNOS_OMX_COMPONENT_VP9_DRM_DEC        "OMX.Exynos.VP9.Decoder.secure"
+#else
+#define EXYNOS_OMX_COMPONENT_VP9_DEC            "OMX.Exynos.vp9.dec"
+#define EXYNOS_OMX_COMPONENT_VP9_DRM_DEC        "OMX.Exynos.vp9.dec.secure"
+#endif
+
+#define EXYNOS_OMX_COMPONENT_VP9_DEC_ROLE   "video_decoder.vp9"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(
+    ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/enc/Exynos_OMX_Venc.c b/openmax/component/video/enc/Exynos_OMX_Venc.c
new file mode 100755 (executable)
index 0000000..1d9a6bf
--- /dev/null
@@ -0,0 +1,2133 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Venc.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OMX_Venc.h"
+#include "Exynos_OMX_VencControl.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OSAL_Thread.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OSAL_ETC.h"
+#include "ExynosVideoApi.h"
+#include "csc.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VIDEO_ENC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+typedef struct __IMG_INFO {
+    OMX_S32 nFrameWidth;
+    OMX_S32 nFrameHeight;
+    OMX_S32 nImageWidth;
+    OMX_S32 nImageHeight;
+
+    /* crop */
+    OMX_S32 nLeft;
+    OMX_S32 nTop;
+    OMX_S32 nWidth;
+    OMX_S32 nHeight;
+} IMG_INFO;
+
+void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT      *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    exynosInputPort->portDefinition.nBufferSize = ALIGN(exynosInputPort->portDefinition.format.video.nFrameWidth, 16) *
+                                                  ALIGN(exynosInputPort->portDefinition.format.video.nFrameHeight, 16) * 3 / 2;
+
+    if ((exynosOutputPort->portDefinition.format.video.nFrameWidth !=
+            exynosInputPort->portDefinition.format.video.nFrameWidth) ||
+        (exynosOutputPort->portDefinition.format.video.nFrameHeight !=
+            exynosInputPort->portDefinition.format.video.nFrameHeight)) {
+        OMX_U32 width = 0, height = 0;
+
+        exynosOutputPort->portDefinition.format.video.nFrameWidth =
+            exynosInputPort->portDefinition.format.video.nFrameWidth;
+        exynosOutputPort->portDefinition.format.video.nFrameHeight =
+            exynosInputPort->portDefinition.format.video.nFrameHeight;
+        width = exynosOutputPort->portDefinition.format.video.nStride =
+            exynosInputPort->portDefinition.format.video.nStride;
+        height = exynosOutputPort->portDefinition.format.video.nSliceHeight =
+            exynosInputPort->portDefinition.format.video.nSliceHeight;
+
+        if (width && height)
+            exynosOutputPort->portDefinition.nBufferSize = ALIGN((ALIGN(width, 16) * ALIGN(height, 16) * 3) / 2, 512);
+    }
+
+    return;
+}
+
+void Exynos_Input_SetSupportFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_COLOR_FORMATTYPE             ret        = OMX_COLOR_FormatUnused;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc  = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    if ((pVideoEnc == NULL) || (pInputPort == NULL))
+        return ;
+
+    if (pInputPort->supportFormat != NULL) {
+        OMX_BOOL ret = OMX_FALSE;
+        int nLastIndex = INPUT_PORT_SUPPORTFORMAT_DEFAULT_NUM;
+        int i;
+
+        /* default supported formats */
+        pInputPort->supportFormat[0] = OMX_COLOR_FormatYUV420Planar;
+        pInputPort->supportFormat[1] = OMX_COLOR_FormatYUV420SemiPlanar;
+        pInputPort->supportFormat[2] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear;
+        pInputPort->supportFormat[3] = OMX_COLOR_Format32bitARGB8888;
+        pInputPort->supportFormat[4] = (OMX_COLOR_FORMATTYPE)OMX_COLOR_Format32BitRGBA8888;
+#ifdef USE_ANDROID
+        pInputPort->supportFormat[nLastIndex++] = OMX_COLOR_FormatAndroidOpaque;
+#endif
+
+        /* add extra formats, if It is supported by H/W. (CSC doesn't exist) */
+        /* OMX_SEC_COLOR_FormatNV12Tiled */
+        ret = pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent,
+                                            (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled);
+        if (ret == OMX_TRUE)
+            pInputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
+
+        /* OMX_SEC_COLOR_FormatYVU420Planar */
+        ret = pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent,
+                                            (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar);
+        if (ret == OMX_TRUE)
+            pInputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar;
+
+        /* OMX_COLOR_Format32bitBGRA8888 */
+        ret = pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent, OMX_COLOR_Format32bitBGRA8888);
+        if (ret == OMX_TRUE)
+            pInputPort->supportFormat[nLastIndex++] = OMX_COLOR_Format32bitBGRA8888;
+
+        for (i = 0; i < nLastIndex; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] Supported Format[%d] : 0x%x",
+                                                pExynosComponent, __FUNCTION__, i, pInputPort->supportFormat[i]);
+        }
+
+        pInputPort->supportFormat[nLastIndex] = OMX_COLOR_FormatUnused;
+    }
+
+    return ;
+}
+
+OMX_COLOR_FORMATTYPE Exynos_Input_GetActualColorFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_COLOR_FORMATTYPE             ret                = OMX_COLOR_FormatUnused;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_COLOR_FORMATTYPE             eColorFormat       = pInputPort->portDefinition.format.video.eColorFormat;
+
+#ifdef USE_ANDROID
+    if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)
+        eColorFormat = pVideoEnc->surfaceFormat;
+#endif
+
+    if (pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent, eColorFormat) == OMX_TRUE) {
+        ret = eColorFormat;
+        goto EXIT;
+    }
+
+    switch ((int)eColorFormat) {
+    case OMX_COLOR_FormatYUV420SemiPlanar:
+    case OMX_COLOR_FormatYUV420Planar:       /* converted to NV12 using CSC */
+    case OMX_COLOR_Format32bitARGB8888:      /* converted to NV12 using CSC */
+    case OMX_COLOR_Format32BitRGBA8888:      /* converted to NV12 using CSC */
+        ret = OMX_COLOR_FormatYUV420SemiPlanar;
+        break;
+    case OMX_SEC_COLOR_FormatNV21Linear:
+    case OMX_SEC_COLOR_FormatNV12Tiled:
+        ret = eColorFormat;
+        break;
+    default:
+        ret = OMX_COLOR_FormatUnused;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+void Exynos_Free_CodecBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    CODEC_ENC_BUFFER               **ppCodecBuffer      = NULL;
+
+    int nBufferCnt = 0, nPlaneCnt = 0;
+    int i, j;
+
+    FunctionIn();
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
+        nBufferCnt = MFC_INPUT_BUFFER_NUM_MAX;
+    } else {
+        ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
+        nBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
+    }
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+    for (i = 0; i < nBufferCnt; i++) {
+        if (ppCodecBuffer[i] != NULL) {
+            for (j = 0; j < nPlaneCnt; j++) {
+                if (ppCodecBuffer[i]->pVirAddr[j] != NULL) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] %s codec buffer[%d][%d] : %d",
+                                                pExynosComponent, __FUNCTION__,
+                                                (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                                i, j, ppCodecBuffer[i]->fd[j]);
+                    Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
+                }
+            }
+
+            Exynos_OSAL_Free(ppCodecBuffer[i]);
+            ppCodecBuffer[i] = NULL;
+        }
+    }
+
+    FunctionOut();
+}
+
+OMX_ERRORTYPE Exynos_Allocate_CodecBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex,
+    int                  nBufferCnt,
+    unsigned int         nAllocLen[MAX_BUFFER_PLANE])
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    MEMORY_TYPE                      eMemoryType        = CACHED_MEMORY;
+    CODEC_ENC_BUFFER               **ppCodecBuffer      = NULL;
+
+    int nPlaneCnt = 0;
+    int i, j;
+
+    FunctionIn();
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
+    } else {
+        ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
+#ifdef USE_CSC_HW
+        eMemoryType = NORMAL_MEMORY;
+#endif
+    }
+
+    nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        eMemoryType = SECURE_MEMORY;
+
+    for (i = 0; i < nBufferCnt; i++) {
+        ppCodecBuffer[i] = (CODEC_ENC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER));
+        if (ppCodecBuffer[i] == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+        Exynos_OSAL_Memset(ppCodecBuffer[i], 0, sizeof(CODEC_ENC_BUFFER));
+
+        for (j = 0; j < nPlaneCnt; j++) {
+            ppCodecBuffer[i]->pVirAddr[j] =
+                (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, nAllocLen[j], eMemoryType);
+            if (ppCodecBuffer[i]->pVirAddr[j] == NULL) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Alloc for %s codec buffer",
+                                            pExynosComponent, __FUNCTION__,
+                                            (nPortIndex == INPUT_PORT_INDEX)? "input":"output");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+
+            ppCodecBuffer[i]->fd[j] =
+                Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
+            ppCodecBuffer[i]->bufferSize[j] = nAllocLen[j];
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s codec buffer[%d][%d] : %d",
+                                        pExynosComponent, __FUNCTION__,
+                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                        i, j, ppCodecBuffer[i]->fd[j]);
+        }
+
+        ppCodecBuffer[i]->dataSize = 0;
+    }
+
+    return OMX_ErrorNone;
+
+EXIT:
+    Exynos_Free_CodecBuffers(pOMXComponent, nPortIndex);
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
+{
+    OMX_BOOL ret = OMX_FALSE;
+
+    if ((pExynosComponent == NULL) ||
+        (pExynosComponent->pExynosPort == NULL))
+        return OMX_FALSE;
+
+    if ((pExynosComponent->currentState == OMX_StateExecuting) &&
+        ((pExynosComponent->pExynosPort[nPortIndex].portState == EXYNOS_OMX_PortStateIdle) ||
+         (pExynosComponent->pExynosPort[nPortIndex].portState == EXYNOS_OMX_PortStateDisabling)) &&
+        (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+        (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
+        ret = OMX_TRUE;
+    } else {
+        ret = OMX_FALSE;
+    }
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT           *pInputPort        = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort       = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    /* Input port */
+    pInputPort->portDefinition.format.video.nFrameWidth             = DEFAULT_FRAME_WIDTH;
+    pInputPort->portDefinition.format.video.nFrameHeight            = DEFAULT_FRAME_HEIGHT;
+    pInputPort->portDefinition.format.video.nStride                 = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pInputPort->portDefinition.format.video.nSliceHeight            = 0;
+    pInputPort->portDefinition.format.video.pNativeRender           = 0;
+    pInputPort->portDefinition.format.video.bFlagErrorConcealment   = OMX_FALSE;
+    pInputPort->portDefinition.format.video.eColorFormat            = OMX_COLOR_FormatYUV420SemiPlanar;
+
+    pInputPort->portDefinition.nBufferSize  = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    pInputPort->portDefinition.bEnabled     = OMX_TRUE;
+
+    pInputPort->bufferProcessType   = BUFFER_COPY;
+    pInputPort->portWayType         = WAY2_PORT;
+    Exynos_SetPlaneToPort(pInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+
+    /* Output port */
+    pOutputPort->portDefinition.format.video.nFrameWidth            = DEFAULT_FRAME_WIDTH;
+    pOutputPort->portDefinition.format.video.nFrameHeight           = DEFAULT_FRAME_HEIGHT;
+    pOutputPort->portDefinition.format.video.nStride                = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pOutputPort->portDefinition.format.video.nSliceHeight           = 0;
+    pOutputPort->portDefinition.format.video.pNativeRender          = 0;
+    pOutputPort->portDefinition.format.video.bFlagErrorConcealment  = OMX_FALSE;
+    pOutputPort->portDefinition.format.video.eColorFormat           = OMX_COLOR_FormatUnused;
+
+    pOutputPort->portDefinition.nBufferCountActual  = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pOutputPort->portDefinition.nBufferCountMin     = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pOutputPort->portDefinition.nBufferSize  = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pOutputPort->portDefinition.bEnabled     = OMX_TRUE;
+
+    pOutputPort->bufferProcessType  = BUFFER_SHARE;
+    pOutputPort->portWayType        = WAY2_PORT;
+    pOutputPort->latestTimeStamp    = DEFAULT_TIMESTAMP_VAL;
+    Exynos_SetPlaneToPort(pOutputPort, Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420Planar, pOutputPort->ePlaneType));
+
+    /* remove a configuration command that is in piled up */
+    while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+        OMX_PTR pDynamicConfigCMD = NULL;
+        pDynamicConfigCMD = (OMX_PTR)Exynos_OSAL_Dequeue(&pExynosComponent->dynamicConfigQ);
+        Exynos_OSAL_Free(pDynamicConfigCMD);
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_CodecBufferToData(
+    CODEC_ENC_BUFFER    *pCodecBuffer,
+    EXYNOS_OMX_DATA     *pData,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    int i;
+
+    if (nPortIndex > OUTPUT_PORT_INDEX) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    pData->allocSize     = 0;
+    pData->usedDataLen   = 0;
+    pData->nFlags        = 0;
+    pData->timeStamp     = 0;
+    pData->pPrivate      = pCodecBuffer;
+    pData->bufferHeader  = NULL;
+
+    for (i = 0; i < MAX_BUFFER_PLANE; i++) {
+        pData->buffer.addr[i]   = pCodecBuffer->pVirAddr[i];
+        pData->buffer.fd[i]     = pCodecBuffer->fd[i];
+
+        pData->allocSize += pCodecBuffer->bufferSize[i];
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        pData->dataLen       = pCodecBuffer->dataSize;
+        pData->remainDataLen = pCodecBuffer->dataSize;
+    } else {
+        pData->dataLen       = 0;
+        pData->remainDataLen = 0;
+    }
+
+EXIT:
+    return ret;
+}
+
+void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
+{
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *exynosOMXPort  = NULL;
+
+    FunctionIn();
+
+    exynosOMXPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    if (((pExynosComponent->currentState == OMX_StatePause) ||
+        (pExynosComponent->currentState == OMX_StateIdle) ||
+        (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) ||
+        (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) &&
+        (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) &&
+        (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port -> pause : state(0x%x), transient state(0x%x)",
+                                        pExynosComponent, __FUNCTION__,
+                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                        pExynosComponent->currentState, pExynosComponent->transientState);
+        Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port -> resume : state(0x%x), transient state(0x%x)",
+                                        pExynosComponent, __FUNCTION__,
+                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                        pExynosComponent->currentState, pExynosComponent->transientState);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return;
+}
+
+OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
+{
+    OMX_BOOL                       ret                = OMX_FALSE;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER         *pInputUseBuffer    = &pInputPort->way.port2WayDataBuffer.inputDataBuffer;
+    CODEC_ENC_BUFFER              *pCodecInputBuffer  = (CODEC_ENC_BUFFER *)pSrcInputData->pPrivate;
+    OMX_COLOR_FORMATTYPE           eColorFormat       = pInputPort->portDefinition.format.video.eColorFormat;
+    OMX_COLOR_FORMATTYPE           eSrcColorFormat    = OMX_COLOR_FormatUnused;
+
+    void *pInputBuf                 = (void *)pInputUseBuffer->bufferHeader->pBuffer;
+    void *pSrcBuf[MAX_BUFFER_PLANE] = { NULL, };
+    void *pDstBuf[MAX_BUFFER_PLANE] = { NULL, };
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+
+    CSC_MEMTYPE     csc_memType       = CSC_MEMORY_USERPTR;
+    CSC_METHOD      csc_method        = CSC_METHOD_SW;
+    CSC_ERRORCODE   csc_ret           = CSC_ErrorNone;
+    unsigned int    csc_src_cacheable = 1;
+    unsigned int    csc_dst_cacheable = 1;
+
+    IMG_INFO srcImgInfo, dstImgInfo;
+    int nDstAlignment = 0;
+    int i, nPlaneCnt;
+
+    FunctionIn();
+
+
+    eSrcColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+
+    /* choose csc method */
+    csc_get_method(pVideoEnc->csc_handle, &csc_method);
+
+    if (csc_method == CSC_METHOD_SW) {
+        /* 1. color format is supported by MFC */
+        if (eColorFormat == eSrcColorFormat) {
+            csc_memType = CSC_MEMORY_MFC;  /* add padding data, if width is not satisfied with h/w alignment */
+            csc_method  = CSC_METHOD_SW;
+        }
+
+        /* 2. blur filtering and rotation are supported by only H/W */
+        if ((pVideoEnc->bUseBlurFilter == OMX_TRUE) ||
+            (pVideoEnc->eRotationType != ROTATE_0)) {
+            csc_ret = csc_set_method(pVideoEnc->csc_handle, CSC_METHOD_HW);
+            if (csc_ret != CSC_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] csc_set_method(CSC_METHOD_HW) for blur/rotation is failed", pExynosComponent, __FUNCTION__);
+                ret = OMX_FALSE;
+                goto EXIT;
+            }
+
+            csc_memType = CSC_MEMORY_DMABUF;
+            csc_method  = CSC_METHOD_HW;
+            csc_src_cacheable = 0;
+            csc_dst_cacheable = 0;
+        }
+
+        /* 3. forcefully want to use H/W */
+        if (pInputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+#ifdef USE_HW_CSC_GRALLOC_SOURCE
+            if (pInputPort->eMetaDataType == METADATA_TYPE_GRAPHIC) {
+#ifdef USE_FIMC_CSC
+                if (pVideoEnc->surfaceFormat != (OMX_COLOR_FORMATTYPE)OMX_COLOR_Format32BitRGBA8888)  /* FIMC doesn't support RGBA format */
+#endif  // USE_FIMC_CSC
+                {
+                    csc_ret = csc_set_method(pVideoEnc->csc_handle, CSC_METHOD_HW);
+                    if (csc_ret != CSC_ErrorNone) {
+                        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] csc_set_method(CSC_METHOD_HW) for gralloc source is failed", pExynosComponent, __FUNCTION__);
+                        ret = OMX_FALSE;
+                        goto EXIT;
+                    }
+
+                    csc_memType = CSC_MEMORY_DMABUF;
+                    csc_method  = CSC_METHOD_HW;
+                    csc_src_cacheable = 0;
+                    csc_dst_cacheable = 0;
+                }
+            }
+#endif  // USE_HW_CSC_GRALLOC_SOURCE
+        }
+    } else {
+        csc_memType = CSC_MEMORY_DMABUF;
+        csc_src_cacheable = 0;
+        csc_dst_cacheable = 0;
+    }
+
+    /******************/
+    /* get image info */
+    /******************/
+    /* 1. SRC : OMX INPUT */
+    srcImgInfo.nFrameWidth  = pInputPort->portDefinition.format.video.nFrameWidth;
+    srcImgInfo.nFrameHeight = pInputPort->portDefinition.format.video.nFrameHeight;
+    srcImgInfo.nImageWidth  = pInputPort->portDefinition.format.video.nFrameWidth;
+    srcImgInfo.nImageHeight = pInputPort->portDefinition.format.video.nFrameHeight;
+
+    srcImgInfo.nLeft   = 0;
+    srcImgInfo.nTop    = 0;
+    srcImgInfo.nWidth  = pInputPort->portDefinition.format.video.nFrameWidth;
+    srcImgInfo.nHeight = pInputPort->portDefinition.format.video.nFrameHeight;
+
+    /* 2. DST : MFC INPUT */
+    switch (pVideoEnc->eRotationType) {
+    case ROTATE_90:
+        dstImgInfo.nFrameWidth  = ALIGN(pOutputPort->portDefinition.format.video.nFrameHeight, 16);
+        dstImgInfo.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+        dstImgInfo.nImageWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        dstImgInfo.nImageHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+
+        dstImgInfo.nLeft    = 0;
+        dstImgInfo.nTop     = 0;
+        dstImgInfo.nWidth   = pOutputPort->portDefinition.format.video.nFrameHeight;
+        dstImgInfo.nHeight  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        break;
+    case ROTATE_180:
+        dstImgInfo.nFrameWidth  = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth, 16);
+        dstImgInfo.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+        dstImgInfo.nImageWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        dstImgInfo.nImageHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+
+        dstImgInfo.nLeft    = 0;
+        dstImgInfo.nTop     = 0;
+        dstImgInfo.nWidth   = pOutputPort->portDefinition.format.video.nFrameWidth;
+        dstImgInfo.nHeight  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        break;
+    case ROTATE_270:
+        dstImgInfo.nFrameWidth  = ALIGN(pOutputPort->portDefinition.format.video.nFrameHeight, 16);
+        dstImgInfo.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+        dstImgInfo.nImageWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        dstImgInfo.nImageHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+
+        dstImgInfo.nLeft    = 0;
+        dstImgInfo.nTop     = 0;
+        dstImgInfo.nWidth   = pOutputPort->portDefinition.format.video.nFrameHeight;
+        dstImgInfo.nHeight  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        break;
+    case ROTATE_0:
+    default:
+        dstImgInfo.nFrameWidth  = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth, 16);
+        dstImgInfo.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+        dstImgInfo.nImageWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        dstImgInfo.nImageHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+
+        dstImgInfo.nLeft    = 0;
+        dstImgInfo.nTop     = 0;
+        dstImgInfo.nWidth   = pOutputPort->portDefinition.format.video.nFrameWidth;
+        dstImgInfo.nHeight  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        break;
+    }
+
+#if 1 // Porting exynos 9110, NEED CHECK, FIXME
+      // error message: Exynos_OMX_Venc.c:604:26: warning: comparison between 'OMX_COLOR_FORMATTYPE' 
+      //                                     and 'enum _EXYNOS_OMX_COLOR_FORMATTYPE' [-Wenum-compare]
+
+    if ((eSrcColorFormat == OMX_SEC_COLOR_FormatS10bitYUV420SemiPlanar) ||
+        (eSrcColorFormat == OMX_SEC_COLOR_FormatS10bitYVU420SemiPlanar)) {
+        dstImgInfo.nFrameWidth = ALIGN(dstImgInfo.nFrameWidth, S10B_FORMAT_8B_ALIGNMENT);
+    }
+#endif
+
+    /*******************/
+    /* get buffer info */
+    /*******************/
+    /* 1. SRC : OMX INPUT */
+    if (pInputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+        /* 1. meta data is enabled
+         *    1) blur or rotation is used
+         *       * blur, rotation is supported by HW.
+         *    2) format is not supported at HW codec
+         *       needs CSC(Color-Space-Conversion).
+         */
+
+        EXYNOS_OMX_MULTIPLANE_BUFFER bufferInfo;
+        OMX_ERRORTYPE                err = OMX_ErrorNone;
+
+        if (pInputPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK) {
+            /* METADATA_TYPE_GRAPHIC */
+            EXYNOS_OMX_LOCK_RANGE range;
+            OMX_U32               stride = 0;
+
+            range.nWidth        = srcImgInfo.nFrameWidth;
+            range.nHeight       = srcImgInfo.nFrameHeight;
+            range.eColorFormat  = eColorFormat;  /* OMX_COLOR_FormatAndroidOpaque */
+            stride              = range.nWidth;
+
+            err = Exynos_OSAL_LockMetaData(pInputBuf,
+                                           range,
+                                           &stride, &bufferInfo,
+                                           pInputPort->eMetaDataType);
+            if (err != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to Exynos_OSAL_LockMetaData (err:0x%x)",
+                                                    pExynosComponent, __FUNCTION__, err);
+                goto EXIT;
+            }
+
+            srcImgInfo.nFrameWidth = stride;
+
+            if (csc_method == CSC_METHOD_HW) {
+                pSrcBuf[0]   = (void *)bufferInfo.fd[0];
+                pSrcBuf[1]   = (void *)bufferInfo.fd[1];
+                pSrcBuf[2]   = (void *)bufferInfo.fd[2];
+            } else {
+                pSrcBuf[0] = (void *)bufferInfo.addr[0];
+                pSrcBuf[1] = (void *)bufferInfo.addr[1];
+                pSrcBuf[2] = (void *)bufferInfo.addr[2];
+            }
+        } else {
+            /* METADATA_TYPE_DATA or METADATA_TYPE_HANDLE */
+            err = Exynos_OSAL_GetInfoFromMetaData(pInputBuf, &bufferInfo, pInputPort->eMetaDataType);
+            if (err != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to Exynos_OSAL_GetInfoFromMetaData (err:0x%x)",
+                                    pExynosComponent, __FUNCTION__, err);
+                ret = OMX_FALSE;
+                goto EXIT;
+            }
+
+            if (csc_method == CSC_METHOD_HW) {
+                pSrcBuf[0]   = (void *)bufferInfo.fd[0];
+                pSrcBuf[1]   = (void *)bufferInfo.fd[1];
+                pSrcBuf[2]   = (void *)bufferInfo.fd[2];
+            } else {
+                Exynos_OSAL_GetPlaneSize(eSrcColorFormat, pInputPort->ePlaneType, srcImgInfo.nFrameWidth, srcImgInfo.nFrameHeight, nDataLen, nAllocLen);
+                nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+
+                /* get virtual address */
+                for (i = 0; i < nPlaneCnt; i++) {
+                    if (bufferInfo.fd[i] != 0) {
+                        pSrcBuf[i] = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, bufferInfo.fd[i]);
+
+                        if(pSrcBuf[i] == NULL)  /* if there isn't addr, try to map using fd (in case of external allocation) */
+                            pSrcBuf[i] = Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, nAllocLen[i], bufferInfo.fd[i]);
+
+                        if (pSrcBuf[i] == NULL) {
+                            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to haredMemory_Map(%d) is failed",
+                                                        pExynosComponent, __FUNCTION__, bufferInfo.fd[i]);
+                            ret = OMX_FALSE;
+                            goto EXIT;
+                        }
+                    }
+                }
+            }
+        }
+    } else {
+        /* 2. meta data is not enabled (user application format)
+         *
+         *    1) HW codec cound't handle user application format
+         *       separates to each color plan and adds the padding data if it is needed.
+         *    2) format is not supported at HW codec
+         *       needs CSC(Color-Space-Conversion).
+         */
+        if (csc_method == CSC_METHOD_HW) {
+            pSrcBuf[0]   = (void *)Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, (char *)pInputBuf);
+            pSrcBuf[1]   = NULL;
+            pSrcBuf[2]   = NULL;
+        } else {
+            Exynos_OSAL_GetPlaneSize(eColorFormat, PLANE_SINGLE_USER, srcImgInfo.nFrameWidth, srcImgInfo.nFrameHeight, nDataLen, nAllocLen);
+            pSrcBuf[0]  = (void *)((char *)pInputBuf);
+            pSrcBuf[1]  = (void *)((char *)pInputBuf + nDataLen[0]);
+            pSrcBuf[2]  = (void *)((char *)pInputBuf + nDataLen[0] + nDataLen[1]);
+        }
+    }
+
+    /* 2. DST : MFC INPUT */
+    if (csc_method == CSC_METHOD_HW) {
+        pDstBuf[0] = (void *)pSrcInputData->buffer.fd[0];
+        pDstBuf[1] = (void *)pSrcInputData->buffer.fd[1];
+        pDstBuf[2] = (void *)pSrcInputData->buffer.fd[2];
+    } else {
+        if (pInputPort->ePlaneType == PLANE_SINGLE) {
+            /* single-FD. only Y addr is valid */
+            int nPlaneCnt = Exynos_OSAL_GetPlaneCount(eSrcColorFormat, PLANE_MULTIPLE);
+
+            if (nPlaneCnt == 2) {
+                /* Semi-Planar : interleaved */
+                pDstBuf[0] = pSrcInputData->buffer.addr[0];
+
+                pDstBuf[1] = (void *)(((char *)pDstBuf[0]) + GET_UV_OFFSET(dstImgInfo.nImageWidth, dstImgInfo.nImageHeight));
+            } else if (nPlaneCnt == 3) {
+                /* Planar */
+                pDstBuf[0] = pSrcInputData->buffer.addr[0];
+
+                pDstBuf[1] = (void *)(((char *)pDstBuf[0]) + GET_CB_OFFSET(dstImgInfo.nImageWidth, dstImgInfo.nImageHeight));
+                pDstBuf[2] = (void *)(((char *)pDstBuf[0]) + GET_CR_OFFSET(dstImgInfo.nImageWidth, dstImgInfo.nImageHeight));
+            }
+        } else {
+            /* multi-FD */
+            pDstBuf[0] = pSrcInputData->buffer.addr[0];
+            pDstBuf[1] = pSrcInputData->buffer.addr[1];
+            pDstBuf[2] = pSrcInputData->buffer.addr[2];
+        }
+    }
+    Exynos_OSAL_GetPlaneSize(eSrcColorFormat, pInputPort->ePlaneType, dstImgInfo.nFrameWidth, dstImgInfo.nFrameHeight, nDataLen, nAllocLen);
+    pCodecInputBuffer->dataSize = 0;
+    nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+    for (i = 0; i < nPlaneCnt; i++)
+        pCodecInputBuffer->dataSize += nDataLen[i];
+
+
+    /**************************/
+    /* [CSC] setup image info */
+    /**************************/
+    if (pVideoEnc->csc_set_format == OMX_FALSE) {
+        /********************/
+        /* get color format */
+        /********************/
+        unsigned int csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)eColorFormat, PLANE_SINGLE_USER);
+        unsigned int csc_dst_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)eSrcColorFormat, pInputPort->ePlaneType);
+
+        int colorspace = Exynos_OSAL_DataSpaceToColorSpace(pInputPort->ColorAspects.nDataSpace);
+        int range      = (pInputPort->ColorAspects.nRangeType == RANGE_FULL)? CSC_EQ_RANGE_FULL:CSC_EQ_RANGE_NARROW;
+
+        if (pInputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+            if (pInputPort->eMetaDataType == METADATA_TYPE_GRAPHIC)
+                csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)pVideoEnc->surfaceFormat, pInputPort->ePlaneType);
+            else
+                csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)eColorFormat, pInputPort->ePlaneType);
+        }
+
+        csc_set_src_format(
+            pVideoEnc->csc_handle,   /* handle */
+            srcImgInfo.nFrameWidth,  /* width */
+            srcImgInfo.nFrameHeight, /* height */
+            srcImgInfo.nLeft,        /* crop_left */
+            srcImgInfo.nTop,         /* crop_top */
+            srcImgInfo.nWidth,       /* crop_width */
+            srcImgInfo.nHeight,      /* crop_height */
+            csc_src_color_format,    /* color_format */
+            csc_src_cacheable);      /* cacheable */
+
+        csc_set_dst_format(
+            pVideoEnc->csc_handle,   /* handle */
+            dstImgInfo.nFrameWidth,  /* width */
+            dstImgInfo.nFrameHeight, /* height */
+            dstImgInfo.nLeft,        /* crop_left */
+            dstImgInfo.nTop,         /* crop_top */
+            dstImgInfo.nWidth,       /* crop_width */
+            dstImgInfo.nHeight,      /* crop_height */
+            csc_dst_color_format,    /* color_format */
+            csc_dst_cacheable);      /* cacheable */
+
+        csc_set_eq_property(
+            pVideoEnc->csc_handle,   /* handle */
+            CSC_EQ_MODE_USER,        /* user select */
+            range,                   /* Limited, Full */
+            colorspace);             /* BT.601, BT.709, BT.2020 */
+
+        pVideoEnc->csc_set_format = OMX_TRUE;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s CSC(%x) %s/ [SRC] resol(%d/%d), rect(%d/%d/%d/%d), format(0x%x) -> [DST] resol(%d/%d), rect(%d/%d/%d/%d), format(0x%x), range(0x%x), colorspace(0x%x)",
+                                               pExynosComponent, __FUNCTION__,
+                                               (csc_method == CSC_METHOD_SW)? "SW":"HW", csc_memType,
+                                               (pVideoEnc->eRotationType != ROTATE_0)? "with rotation":"",
+                                               srcImgInfo.nFrameWidth, srcImgInfo.nFrameHeight,
+                                               srcImgInfo.nLeft, srcImgInfo.nTop, srcImgInfo.nWidth, srcImgInfo.nHeight, csc_src_color_format,
+                                               dstImgInfo.nFrameWidth, dstImgInfo.nFrameHeight,
+                                               dstImgInfo.nLeft, dstImgInfo.nTop, dstImgInfo.nWidth, dstImgInfo.nHeight, csc_dst_color_format,
+                                               range, colorspace);
+    }
+
+    /********************************/
+    /* [CSC] setup blur filter info */
+    /********************************/
+    if (pVideoEnc->bUseBlurFilter == OMX_TRUE) {
+        CSC_HW_FILTER filterType = CSC_FT_NONE;
+
+        if (pVideoEnc->eBlurMode & BLUR_MODE_DOWNUP) {
+            switch (pVideoEnc->eBlurResol) {
+            case BLUR_RESOL_240:
+                filterType = CSC_FT_240;
+                break;
+            case BLUR_RESOL_480:
+                filterType = CSC_FT_480;
+                break;
+            case BLUR_RESOL_720:
+                filterType = CSC_FT_720;
+                break;
+#if 0 // Porting exynos 9110, error fix
+      // error message: Need to check csc.h version in path /scratch.armv7l.0/usr/include/csc.h
+            case BLUR_RESOL_960:
+                filterType = CSC_FT_960;
+                break;
+#endif
+            case BLUR_RESOL_1080:
+                filterType = CSC_FT_1080;
+                break;
+            default:
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invliad eBlurResol(%d)", pExynosComponent, __FUNCTION__, pVideoEnc->eBlurResol);
+                ret = OMX_FALSE;
+                goto EXIT;
+            }
+        }
+
+        if (pVideoEnc->eBlurMode & BLUR_MODE_COEFFICIENT)
+            filterType = CSC_FT_BLUR;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] blur filter is enabled : type(%x)", pExynosComponent, __FUNCTION__, filterType);
+
+        csc_set_filter_property(
+            pVideoEnc->csc_handle,
+            filterType);
+    }
+
+    /***************************/
+    /* [CSC] setup buffer info */
+    /***************************/
+    csc_set_src_buffer(
+        pVideoEnc->csc_handle,  /* handle */
+        pSrcBuf,
+        csc_memType);
+    csc_set_dst_buffer(
+        pVideoEnc->csc_handle,  /* handle */
+        pDstBuf,
+        csc_memType);
+
+    /*****************/
+    /* [CSC] convert */
+    /*****************/
+    if (pVideoEnc->eRotationType != ROTATE_0)
+        csc_ret = csc_convert_with_rotation(pVideoEnc->csc_handle, (int)pVideoEnc->eRotationType, 0, 0);
+    else
+        csc_ret = csc_convert(pVideoEnc->csc_handle);
+    ret = (csc_ret != CSC_ErrorNone)? OMX_FALSE:OMX_TRUE;
+
+    if (pInputPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK)
+        Exynos_OSAL_UnlockMetaData(pInputBuf, pInputPort->eMetaDataType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
+{
+    OMX_BOOL                         ret                = OMX_FALSE;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *exynosInputPort    = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER           *inputUseBuffer     = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
+    OMX_U32                          nFrameWidth        = exynosInputPort->portDefinition.format.video.nFrameWidth;
+    OMX_U32                          nFrameHeight       = exynosInputPort->portDefinition.format.video.nFrameHeight;
+    OMX_COLOR_FORMATTYPE             eColorFormat       = exynosInputPort->portDefinition.format.video.eColorFormat;
+
+    OMX_U32 copySize = 0;
+
+    FunctionIn();
+
+    if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+        if ((srcInputData->buffer.addr[0] == NULL) ||
+            (srcInputData->pPrivate == NULL)) {
+            ret = OMX_FALSE;
+            goto EXIT;
+        }
+    }
+
+    if (inputUseBuffer->dataValid == OMX_TRUE) {
+        if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_Shared_BufferToData(exynosInputPort, inputUseBuffer, srcInputData);
+
+            if (exynosInputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+                OMX_ERRORTYPE                err = OMX_ErrorNone;
+                EXYNOS_OMX_MULTIPLANE_BUFFER bufferInfo;
+                unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+                unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+
+                OMX_COLOR_FORMATTYPE inputColorFormat = OMX_COLOR_FormatUnused;
+
+                int i = 0, nPlaneCnt = 0;
+
+                inputColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+                Exynos_OSAL_GetPlaneSize(inputColorFormat, exynosInputPort->ePlaneType, nFrameWidth, nFrameHeight, nDataLen, nAllocLen);
+                nPlaneCnt = Exynos_GetPlaneFromPort(exynosInputPort);
+                if (pVideoEnc->nInbufSpareSize > 0) {
+                    for (i = 0; i < nPlaneCnt; i++)
+                        nAllocLen[i] += pVideoEnc->nInbufSpareSize;
+                }
+
+                if (inputUseBuffer->dataLen <= 0) {
+                    /* input data is not valid */
+                    if (!(inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) {
+                        /* w/o EOS flag */
+                        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] dataLen is zero w/o EOS flag(0x%x). this buffer(%p) will be discarded",
+                                                                pExynosComponent, __FUNCTION__,
+                                                                inputUseBuffer->nFlags, inputUseBuffer->bufferHeader);
+                        ret = OMX_FALSE;
+                        goto EXIT;
+                    } else {
+                        /* with EOS flag
+                         * makes a buffer for EOS handling needed at MFC Processing scheme.
+                         */
+                        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] dataLen is zero with EOS flag(0x%x)",
+                                                                pExynosComponent, __FUNCTION__, inputUseBuffer->nFlags);
+                        for (i = 0; i < nPlaneCnt; i++) {
+                            srcInputData->buffer.addr[i] =
+                                (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, nAllocLen[i], NORMAL_MEMORY);
+                            srcInputData->buffer.fd[i] =
+                                Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, srcInputData->buffer.addr[i]);
+                        }
+                    }
+                } else {
+                    /* input data is valid */
+#ifdef USE_ANDROID
+                    for (i = 0; i < nPlaneCnt; i++) {
+                        if ((srcInputData->buffer.fd[i] != 0) &&
+                            (srcInputData->buffer.addr[i] == NULL)) {
+                            srcInputData->buffer.addr[i] =
+                                Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, srcInputData->buffer.fd[i]);
+                            if(srcInputData->buffer.addr[i] == NULL) {
+                                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] dynamically regist a buffer(fd[%u])",
+                                                                pExynosComponent, __FUNCTION__, srcInputData->buffer.fd[i]);
+                                srcInputData->buffer.addr[i] =
+                                    Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, nAllocLen[i], srcInputData->buffer.fd[i]);
+                            }
+                        }
+                    }
+#endif
+                }
+            }
+
+            /* reset dataBuffer */
+            Exynos_ResetDataBuffer(inputUseBuffer);
+
+            ret = OMX_TRUE;
+        } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+            if (inputUseBuffer->remainDataLen == 0) {
+                inputUseBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
+                copySize = 0;
+            } else {
+                copySize = inputUseBuffer->remainDataLen;
+
+                if (exynosInputPort->eMetaDataType & METADATA_TYPE_DATA)
+                    copySize = inputUseBuffer->allocSize;
+            }
+
+            if (((srcInputData->allocSize) - (srcInputData->dataLen)) < copySize) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] codec buffer's remaining space(%d) is smaller than input data(%d)",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    ((srcInputData->allocSize) - (srcInputData->dataLen)), copySize);
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+
+                pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                        pExynosComponent->callbackData,
+                                                        OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                ret = OMX_FALSE;
+                goto EXIT;
+            }
+
+            if (copySize > 0) {
+                ret = Exynos_CSC_InputData(pOMXComponent, srcInputData);
+                if (ret != OMX_TRUE) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to CSC_InputData", pExynosComponent, __FUNCTION__);
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+
+                    pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                            pExynosComponent->callbackData,
+                                                            OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                    ret = OMX_FALSE;
+                    goto EXIT;
+                }
+            }
+
+            inputUseBuffer->dataLen         -= copySize;
+            inputUseBuffer->remainDataLen   -= copySize;
+            inputUseBuffer->usedDataLen     += copySize;
+
+            srcInputData->dataLen           += copySize;
+            srcInputData->remainDataLen     += copySize;
+
+            srcInputData->timeStamp     = inputUseBuffer->timeStamp;
+            srcInputData->nFlags        = inputUseBuffer->nFlags;
+            srcInputData->bufferHeader  = inputUseBuffer->bufferHeader;
+
+            /* return OMX buffer and reset dataBuffer */
+            Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
+
+            ret = OMX_TRUE;
+        }
+
+        if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+            if (srcInputData->dataLen != 0) {
+                pExynosComponent->bBehaviorEOS = OMX_TRUE;
+                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] behavior EOS frame", pExynosComponent, __FUNCTION__);
+            }
+        }
+
+        if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) &&
+            ((srcInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) {
+            pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
+            pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
+            pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
+            pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame timestamp after seeking %lld us (%.2f secs)",
+                            pExynosComponent, __FUNCTION__, srcInputData->timeStamp, (double)(srcInputData->timeStamp / 1E6));
+        }
+    }
+
+EXIT:
+
+    if (ret != OMX_TRUE) {
+        /* return OMX buffer and reset dataBuffer */
+        Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
+{
+    OMX_BOOL                  ret               = OMX_FALSE;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT      *exynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER    *outputUseBuffer   = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+
+    OMX_U32 copySize = 0;
+
+    FunctionIn();
+
+    if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_Shared_DataToBuffer(exynosOutputPort, outputUseBuffer, dstOutputData) == OMX_ErrorNone)
+            outputUseBuffer->dataValid = OMX_TRUE;
+    }
+
+    if (outputUseBuffer->dataValid == OMX_TRUE) {
+        if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) {
+            if (pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp) {
+                pExynosComponent->checkTimeStamp.startTimeStamp = RESET_TIMESTAMP_VAL;
+                pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
+                pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+                pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
+            } else {
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] drop frame after seeking(in: %lld vs out: %lld)",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pExynosComponent->checkTimeStamp.startTimeStamp, dstOutputData->timeStamp);
+                if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
+                    Exynos_OMX_FillThisBufferAgain(pOMXComponent, outputUseBuffer->bufferHeader);
+
+                ret = OMX_TRUE;
+                goto EXIT;
+            }
+        } else if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
+            ret = OMX_TRUE;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] not set check timestamp after seeking", pExynosComponent, __FUNCTION__);
+
+            if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
+                Exynos_OMX_FillThisBufferAgain(pOMXComponent, outputUseBuffer->bufferHeader);
+
+            goto EXIT;
+        }
+
+        if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
+            if ((dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) &&
+                (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+                copySize = dstOutputData->remainDataLen;
+                if (copySize > 0) {
+                    Exynos_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen),
+                                       ((char *)dstOutputData->buffer.addr[0] + dstOutputData->usedDataLen),
+                                       copySize);
+                }
+
+                outputUseBuffer->dataLen += copySize;
+                outputUseBuffer->remainDataLen += copySize;
+                outputUseBuffer->nFlags = dstOutputData->nFlags;
+                outputUseBuffer->timeStamp = dstOutputData->timeStamp;
+
+                ret = OMX_TRUE;
+
+                if ((outputUseBuffer->remainDataLen > 0) ||
+                    (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) ||
+                    (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+                    Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
+                }
+            } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
+                outputUseBuffer->dataLen = 0;
+                outputUseBuffer->remainDataLen = 0;
+                outputUseBuffer->nFlags = dstOutputData->nFlags;
+                outputUseBuffer->timeStamp = dstOutputData->timeStamp;
+                Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
+            } else {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] codec buffer's remaining space(%d) is smaller than output data(%d)",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    (outputUseBuffer->allocSize - outputUseBuffer->dataLen), dstOutputData->remainDataLen);
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+
+                pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                        pExynosComponent->callbackData,
+                                                        OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                ret = OMX_FALSE;
+            }
+        } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+            if ((outputUseBuffer->remainDataLen > 0) ||
+                (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) ||
+                (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+
+                Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
+            } else {
+                Exynos_OMX_FillThisBufferAgain(pOMXComponent, outputUseBuffer->bufferHeader);
+                Exynos_ResetDataBuffer(outputUseBuffer);
+            }
+        }
+    } else {
+        ret = OMX_FALSE;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ExtensionSetup(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *exynosInputPort    = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER           *srcInputUseBuffer  = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
+    EXYNOS_OMX_DATA                 *pSrcInputData      = &exynosInputPort->processData;
+    OMX_COLOR_FORMATTYPE             eColorFormat       = exynosInputPort->portDefinition.format.video.eColorFormat;
+    OMX_COLOR_FORMATTYPE             eActualFormat      = OMX_COLOR_FormatUnused;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+
+    int i = 0;
+
+    if (exynosInputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+        if ((srcInputUseBuffer->dataLen == 0) &&
+            (srcInputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) {
+            /* In this case, the metadata is not valid.
+             * sets dummy info in order to return EOS flag at output port through FBD.
+             * IL client should do stop sequence.
+             */
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] dataLen is zero with EOS flag(0x%x) at first input",
+                                                pExynosComponent, __FUNCTION__, srcInputUseBuffer->nFlags);
+
+            if (exynosInputPort->eMetaDataType == METADATA_TYPE_GRAPHIC) {
+                pVideoEnc->surfaceFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+                exynosInputPort->bufferProcessType = BUFFER_SHARE;
+                Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(pVideoEnc->surfaceFormat, exynosInputPort->ePlaneType));
+            } else {
+                Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(eColorFormat, exynosInputPort->ePlaneType));
+            }
+
+            goto EXIT;
+        } else {
+            EXYNOS_OMX_MULTIPLANE_BUFFER bufferInfo;
+
+            ret = Exynos_OSAL_GetInfoFromMetaData(srcInputUseBuffer->bufferHeader->pBuffer,
+                                                    &bufferInfo, exynosInputPort->eMetaDataType);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to Exynos_OSAL_GetInfoFromMetaData (err:0x%x)",
+                                    pExynosComponent, __FUNCTION__, ret);
+                goto EXIT;
+            }
+
+            if (exynosInputPort->eMetaDataType == METADATA_TYPE_GRAPHIC) {
+                pVideoEnc->surfaceFormat = bufferInfo.eColorFormat;
+                eActualFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+                if (eActualFormat == OMX_COLOR_FormatUnused) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] unsupported color format : ANB color is 0x%x",
+                                                    pExynosComponent, __FUNCTION__, pVideoEnc->surfaceFormat);
+                    ret = OMX_ErrorNotImplemented;
+                    goto EXIT;
+                }
+
+                if (pVideoEnc->surfaceFormat == eActualFormat) {
+                    exynosInputPort->bufferProcessType = BUFFER_SHARE;
+                    Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(pVideoEnc->surfaceFormat, exynosInputPort->ePlaneType));
+                } else {
+                    exynosInputPort->bufferProcessType = BUFFER_COPY;
+                }
+            } else {
+                Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(eColorFormat, exynosInputPort->ePlaneType));
+            }
+        }
+    }
+
+    /* forcefully have to use BUFFER_COPY mode, if blur filter is used or rotation is needed */
+    if ((pVideoEnc->bUseBlurFilter == OMX_TRUE) ||
+        (pVideoEnc->eRotationType != ROTATE_0)) {
+        exynosInputPort->bufferProcessType = BUFFER_COPY;
+         Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] %s %s: enabled", pExynosComponent, __FUNCTION__,
+                                                    (pVideoEnc->bUseBlurFilter == OMX_TRUE)? "blur filter":"",
+                                                    (pVideoEnc->eRotationType != ROTATE_0)? "rotation":"");
+    }
+
+    if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
+        OMX_U32 nFrameWidth  = exynosInputPort->portDefinition.format.video.nFrameWidth;
+        OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight;
+
+        if ((pVideoEnc->eRotationType == ROTATE_90) ||
+            (pVideoEnc->eRotationType == ROTATE_270)) {
+            nFrameWidth  = exynosInputPort->portDefinition.format.video.nFrameHeight;
+            nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameWidth;
+        }
+
+        if (pVideoEnc->bEncDRC == OMX_TRUE) {
+            Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+            Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+            pVideoEnc->bEncDRC = OMX_FALSE;
+        }
+
+        eActualFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+        if (eActualFormat == OMX_COLOR_FormatUnused) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] unsupported color format : 0x%x", pExynosComponent, __FUNCTION__, eActualFormat);
+            ret = OMX_ErrorNotImplemented;
+            goto EXIT;
+        }
+
+        Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(eActualFormat, exynosInputPort->ePlaneType));
+        Exynos_OSAL_GetPlaneSize(eActualFormat, exynosInputPort->ePlaneType, nFrameWidth, nFrameHeight, nDataLen, nAllocLen);
+
+        if (pVideoEnc->nInbufSpareSize > 0) {
+            for (i = 0; i < Exynos_GetPlaneFromPort(exynosInputPort); i++)
+                nAllocLen[i] += pVideoEnc->nInbufSpareSize;
+        }
+
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Allocate_CodecBuffers", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
+            Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
+    } else if (exynosInputPort->bufferProcessType == BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+EXIT:
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eActualFormat: 0x%x, eColorFormat: 0x%x, eBufferColorFormat: 0x%x, bufferProcessType: 0x%x",
+                                            pExynosComponent, __FUNCTION__,
+                                            eActualFormat, eColorFormat, pVideoEnc->surfaceFormat, exynosInputPort->bufferProcessType);
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *exynosInputPort    = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER           *srcInputUseBuffer  = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
+    EXYNOS_OMX_DATA                 *pSrcInputData      = &exynosInputPort->processData;
+
+    OMX_BOOL bCheckInputData = OMX_FALSE;
+
+    FunctionIn();
+
+    while (!pVideoEnc->bExitBufferProcessThread) {
+        Exynos_OSAL_SleepMillisec(0);
+        Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
+        if ((exynosInputPort->semWaitPortEnable[INPUT_WAY_INDEX] != NULL) &&
+            (!CHECK_PORT_ENABLED(exynosInputPort))) {
+            /* sema will be posted at PortEnable */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> wait(port enable)", pExynosComponent, __FUNCTION__);
+            Exynos_OSAL_SemaphoreWait(exynosInputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> post(port enable)", pExynosComponent, __FUNCTION__);
+            continue;
+        }
+
+        while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
+               (!pVideoEnc->bExitBufferProcessThread)) {
+            Exynos_OSAL_SleepMillisec(0);
+
+            if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
+                break;
+
+            Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
+            if (pVideoEnc->bFirstInput == OMX_FALSE) {
+                if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+                    OMX_PTR codecBuffer;
+                    if ((pSrcInputData->buffer.addr[0] == NULL) ||
+                        (pSrcInputData->pPrivate == NULL)) {
+                        Exynos_CodecBufferDequeue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
+                        if (pVideoEnc->bExitBufferProcessThread) {
+                            Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                            goto EXIT;
+                        }
+
+                        if (codecBuffer != NULL) {
+                            Exynos_CodecBufferToData(codecBuffer, pSrcInputData, INPUT_PORT_INDEX);
+                        }
+                        Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                        break;
+                    }
+                }
+
+                if (srcInputUseBuffer->dataValid == OMX_TRUE) {
+                    bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
+                } else {
+                    bCheckInputData = OMX_FALSE;
+                }
+            }
+
+            if ((bCheckInputData == OMX_FALSE) &&
+                (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
+                ret = Exynos_InputBufferGetQueue(pExynosComponent);
+                if (pVideoEnc->bExitBufferProcessThread) {
+                    Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                    goto EXIT;
+                }
+
+                if (ret != OMX_ErrorNone) {
+                    Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                    break;
+                }
+
+                if ((pVideoEnc->bFirstInput == OMX_TRUE) &&
+                    (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
+                    ret = Exynos_OMX_ExtensionSetup(hComponent);
+                    if (ret != OMX_ErrorNone) {
+                        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+                        (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent,
+                                    pExynosComponent->callbackData,
+                                    (OMX_U32)OMX_EventError,
+                                    (OMX_U32)OMX_ErrorNotImplemented,
+                                    INPUT_PORT_INDEX, NULL);
+                        Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                        break;
+                    }
+
+                    pVideoEnc->bFirstInput = OMX_FALSE;
+                }
+
+                Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                break;
+            }
+
+            if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
+                Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+                break;
+            }
+
+            ret = pVideoEnc->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
+
+            Exynos_ResetCodecData(pSrcInputData);
+            Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
+
+            if ((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCodecInit)
+                pVideoEnc->bExitBufferProcessThread = OMX_TRUE;
+        }
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE          ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT      *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER    *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
+    EXYNOS_OMX_DATA           srcOutputData;
+
+    FunctionIn();
+
+    Exynos_ResetCodecData(&srcOutputData);
+
+    while (!pVideoEnc->bExitBufferProcessThread) {
+        Exynos_OSAL_SleepMillisec(0);
+        if ((exynosInputPort->semWaitPortEnable[OUTPUT_WAY_INDEX] != NULL) &&
+            (!CHECK_PORT_ENABLED(exynosInputPort))) {
+            /* sema will be posted at PortEnable */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> wait(port enable)", pExynosComponent, __FUNCTION__);
+            Exynos_OSAL_SemaphoreWait(exynosInputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> post(port enable)", pExynosComponent, __FUNCTION__);
+            continue;
+        }
+
+        while (!pVideoEnc->bExitBufferProcessThread) {
+            if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+                if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
+                    break;
+            }
+            Exynos_OSAL_SleepMillisec(0);
+
+            if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
+                break;
+
+            Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
+            Exynos_OSAL_Memset(&srcOutputData, 0, sizeof(EXYNOS_OMX_DATA));
+
+            ret = pVideoEnc->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
+
+            if (ret == OMX_ErrorNone) {
+                if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+                    OMX_PTR codecBuffer;
+                    codecBuffer = srcOutputData.pPrivate;
+                    if (codecBuffer != NULL)
+                        Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
+                }
+                if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
+                    Exynos_Shared_DataToBuffer(exynosInputPort, srcOutputUseBuffer, &srcOutputData);
+                    Exynos_InputBufferReturn(pOMXComponent, srcOutputUseBuffer);
+                }
+                Exynos_ResetCodecData(&srcOutputData);
+            }
+            Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
+        }
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE          ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER    *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
+    EXYNOS_OMX_DATA           dstInputData;
+
+    FunctionIn();
+
+    Exynos_ResetCodecData(&dstInputData);
+
+    while (!pVideoEnc->bExitBufferProcessThread) {
+        Exynos_OSAL_SleepMillisec(0);
+        if ((exynosOutputPort->semWaitPortEnable[INPUT_WAY_INDEX] != NULL) &&
+            (!CHECK_PORT_ENABLED(exynosOutputPort))) {
+            /* sema will be posted at PortEnable */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> wait(port enable)", pExynosComponent, __FUNCTION__);
+            Exynos_OSAL_SemaphoreWait(exynosOutputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> post(port enable)", pExynosComponent, __FUNCTION__);
+            continue;
+        }
+
+        while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
+               (!pVideoEnc->bExitBufferProcessThread)) {
+            Exynos_OSAL_SleepMillisec(0);
+
+            if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
+                break;
+
+            Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
+
+            if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
+                CODEC_ENC_BUFFER *pCodecBuffer = NULL;
+                ret = Exynos_CodecBufferDequeue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR *)&pCodecBuffer);
+                if (pVideoEnc->bExitBufferProcessThread) {
+                    Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                    goto EXIT;
+                }
+
+                if (ret != OMX_ErrorNone) {
+                    Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                    break;
+                }
+                Exynos_CodecBufferToData(pCodecBuffer, &dstInputData, OUTPUT_PORT_INDEX);
+            }
+
+            if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+                if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
+                    (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+                    ret = Exynos_OutputBufferGetQueue(pExynosComponent);
+                    if (pVideoEnc->bExitBufferProcessThread) {
+                        Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                        goto EXIT;
+                    }
+
+                    if (ret != OMX_ErrorNone) {
+                        Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                        break;
+                    }
+
+                    ret = Exynos_Shared_BufferToData(exynosOutputPort, dstInputUseBuffer, &dstInputData);
+                    if (ret != OMX_ErrorNone) {
+                        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to GetBufferFdFromMetaData from %p",
+                                                        pExynosComponent, __FUNCTION__, dstInputUseBuffer->bufferHeader);
+                        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+                        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                                   pExynosComponent->callbackData,
+                                                                   OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                        Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                        break;
+                    }
+
+                    if (exynosOutputPort->eMetaDataType == METADATA_TYPE_HANDLE) {
+                        OMX_PTR dataBuffer = NULL;
+
+                        dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, dstInputData.buffer.fd[0]);
+                        if (dataBuffer == NULL) {
+                            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid data buffer(%u)",
+                                                                pExynosComponent, __FUNCTION__, dstInputData.buffer.fd[0]);
+                            ret = OMX_ErrorUndefined;
+                            Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                            break;
+                        }
+
+                        dstInputData.buffer.addr[0] = dataBuffer;
+                    } else {
+                        if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC) {
+                            unsigned long ionFD = (unsigned long)dstInputData.buffer.addr[0];
+
+                            OMX_PTR dataBuffer = NULL;
+                            dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, ionFD);
+                            if (dataBuffer == NULL) {
+                                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid data buffer(%u)",
+                                                                pExynosComponent, __FUNCTION__, ionFD);
+                                ret = OMX_ErrorUndefined;
+                                Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                                break;
+                            }
+
+                            dstInputData.buffer.fd[0]   = ionFD;
+                            dstInputData.buffer.addr[0] = dataBuffer;
+                        } else {
+                            dstInputData.buffer.fd[0] =
+                                Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory,
+                                            dstInputData.buffer.addr[0]);
+                        }
+                    }
+
+                    Exynos_ResetDataBuffer(dstInputUseBuffer);
+                }
+            }
+
+            if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
+                Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+                break;
+            }
+
+            ret = pVideoEnc->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
+
+            Exynos_ResetCodecData(&dstInputData);
+            Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+        }
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE          ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_OMX_DATABUFFER    *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+    EXYNOS_OMX_DATA          *pDstOutputData = &exynosOutputPort->processData;
+
+    FunctionIn();
+
+    while (!pVideoEnc->bExitBufferProcessThread) {
+        Exynos_OSAL_SleepMillisec(0);
+        Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
+        if ((exynosOutputPort->semWaitPortEnable[OUTPUT_WAY_INDEX] != NULL) &&
+            (!CHECK_PORT_ENABLED(exynosOutputPort))) {
+            /* sema will be posted at PortEnable */
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> wait(port enable)", pExynosComponent, __FUNCTION__);
+            Exynos_OSAL_SemaphoreWait(exynosOutputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> post(port enable)", pExynosComponent, __FUNCTION__);
+            continue;
+        }
+
+        while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
+               (!pVideoEnc->bExitBufferProcessThread)) {
+            Exynos_OSAL_SleepMillisec(0);
+
+            if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
+                break;
+
+            Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
+
+            if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
+                if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
+                    (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+                    ret = Exynos_OutputBufferGetQueue(pExynosComponent);
+                    if (pVideoEnc->bExitBufferProcessThread) {
+                        Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
+                        goto EXIT;
+                    }
+
+                    if (ret != OMX_ErrorNone) {
+                        Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
+                        break;
+                    }
+                }
+            }
+
+            if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
+                (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
+                ret = pVideoEnc->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
+
+            if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
+                (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
+                Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
+            }
+
+            if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
+                if (pDstOutputData->pPrivate != NULL) {
+                    Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, pDstOutputData->pPrivate);
+                    pDstOutputData->pPrivate = NULL;
+                }
+            }
+
+            /* reset outputData */
+            Exynos_ResetCodecData(pDstOutputData);
+            Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
+        }
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+
+    FunctionIn();
+
+    if (threadData == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
+
+    Exynos_OSAL_ThreadExit(NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+
+    FunctionIn();
+
+    if (threadData == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
+
+    Exynos_OSAL_ThreadExit(NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+
+    FunctionIn();
+
+    if (threadData == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_OMX_DstInputBufferProcess(pOMXComponent);
+
+    Exynos_OSAL_ThreadExit(NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+
+    FunctionIn();
+
+    if (threadData == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
+
+    Exynos_OSAL_ThreadExit(NULL);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    FunctionIn();
+
+    pVideoEnc->bExitBufferProcessThread = OMX_FALSE;
+
+    ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstOutputThread,
+                 Exynos_OMX_DstOutputProcessThread,
+                 pOMXComponent);
+    if (ret == OMX_ErrorNone)
+        ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcOutputThread,
+                     Exynos_OMX_SrcOutputProcessThread,
+                     pOMXComponent);
+    if (ret == OMX_ErrorNone)
+        ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstInputThread,
+                     Exynos_OMX_DstInputProcessThread,
+                     pOMXComponent);
+    if (ret == OMX_ErrorNone)
+        ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcInputThread,
+                     Exynos_OMX_SrcInputProcessThread,
+                     pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = (OMX_COMPONENTTYPE *)hComponent;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    OMX_S32 countValue = 0;
+
+    FunctionIn();
+
+    pVideoEnc->bExitBufferProcessThread = OMX_TRUE;
+
+    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
+    if (countValue == 0)
+        Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
+    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
+    if (countValue == 0)
+        Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
+    pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    /* srcInput */
+    Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
+    Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX]);
+    Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcInputThread);
+    pVideoEnc->hSrcInputThread = NULL;
+    Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX], 0);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] src input thread is terminated", pExynosComponent, __FUNCTION__);
+
+    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
+    if (countValue == 0)
+        Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
+    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
+    if (countValue == 0)
+        Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
+
+    /* dstInput */
+    Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
+    Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX]);
+    Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstInputThread);
+    pVideoEnc->hDstInputThread = NULL;
+    Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX], 0);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] dst input thread is terminated", pExynosComponent, __FUNCTION__);
+
+    pVideoEnc->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
+    pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
+
+    /* srcOutput */
+    Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
+    Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX]);
+    Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcOutputThread);
+    pVideoEnc->hSrcOutputThread = NULL;
+    Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX], 0);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] src output thread is terminated", pExynosComponent, __FUNCTION__);
+
+    pVideoEnc->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
+    pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    /* dstOutput */
+    Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
+    Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX]);
+    Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstOutputThread);
+    pVideoEnc->hDstOutputThread = NULL;
+    Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX], 0);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] dst output thread is terminated", pExynosComponent, __FUNCTION__);
+
+    pExynosComponent->checkTimeStamp.needSetStartTimeStamp      = OMX_FALSE;
+    pExynosComponent->checkTimeStamp.needCheckStartTimeStamp    = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to BaseComponent_Constructor", __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Port_Constructor(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Port_Constructor", __FUNCTION__);
+        Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    pVideoEnc = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
+    if (pVideoEnc == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_Port_Destructor(pOMXComponent);
+        Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Memset(pVideoEnc, 0, sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
+    pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc;
+
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+    pVideoEnc->bFirstInput  = OMX_TRUE;
+    pVideoEnc->bFirstOutput = OMX_FALSE;
+    pVideoEnc->bQosChanged  = OMX_FALSE;
+    pVideoEnc->nQosRatio       = 0;
+    pVideoEnc->nInbufSpareSize = 0;
+    pVideoEnc->quantization.nQpI = 4; // I frame quantization parameter
+    pVideoEnc->quantization.nQpP = 5; // P frame quantization parameter
+    pVideoEnc->quantization.nQpB = 5; // B frame quantization parameter
+
+    pVideoEnc->bUseBlurFilter   = OMX_FALSE;
+    pVideoEnc->eBlurMode        = BLUR_MODE_NONE;
+    pVideoEnc->eBlurResol       = BLUR_RESOL_240;
+
+    pVideoEnc->eRotationType    = ROTATE_0;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->supportFormat = Exynos_OSAL_Malloc(sizeof(OMX_COLOR_FORMATTYPE) * INPUT_PORT_SUPPORTFORMAT_NUM_MAX);
+    if (pExynosPort->supportFormat == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosPort->supportFormat, 0, (sizeof(OMX_COLOR_FORMATTYPE) * INPUT_PORT_SUPPORTFORMAT_NUM_MAX));
+
+    pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferSize = 0;
+    pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
+
+    pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
+    if (pExynosPort->portDefinition.format.video.cMIMEType == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+    pExynosPort->portDefinition.format.video.nFrameWidth = 0;
+    pExynosPort->portDefinition.format.video.nFrameHeight= 0;
+    pExynosPort->portDefinition.format.video.nStride = 0;
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.format.video.nBitrate = 1000000;
+    pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
+    pVideoEnc->eControlRate[INPUT_PORT_INDEX] = OMX_Video_ControlRateVariable;
+
+    pExynosPort->eMetaDataType = METADATA_TYPE_DISABLED;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->supportFormat = Exynos_OSAL_Malloc(sizeof(OMX_COLOR_FORMATTYPE) * OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX);
+    if (pExynosPort->supportFormat == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosPort->supportFormat, 0, (sizeof(OMX_COLOR_FORMATTYPE) * OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX));
+
+    pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
+
+    pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
+    if (pExynosPort->portDefinition.format.video.cMIMEType == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+    pExynosPort->portDefinition.format.video.nFrameWidth = 0;
+    pExynosPort->portDefinition.format.video.nFrameHeight= 0;
+    pExynosPort->portDefinition.format.video.nStride = 0;
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.format.video.nBitrate = 1000000;
+    pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
+    pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] = OMX_Video_ControlRateVariable;
+
+    pExynosPort->eMetaDataType = METADATA_TYPE_DISABLED;
+
+    pOMXComponent->UseBuffer              = &Exynos_OMX_UseBuffer;
+    pOMXComponent->AllocateBuffer         = &Exynos_OMX_AllocateBuffer;
+    pOMXComponent->FreeBuffer             = &Exynos_OMX_FreeBuffer;
+
+#ifdef TUNNELING_SUPPORT
+    pOMXComponent->ComponentTunnelRequest           = &Exynos_OMX_ComponentTunnelRequest;
+    pExynosComponent->exynos_AllocateTunnelBuffer   = &Exynos_OMX_AllocateTunnelBuffer;
+    pExynosComponent->exynos_FreeTunnelBuffer       = &Exynos_OMX_FreeTunnelBuffer;
+#endif
+
+    pExynosComponent->exynos_BufferProcessCreate    = &Exynos_OMX_BufferProcess_Create;
+    pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
+    pExynosComponent->exynos_BufferFlush          = &Exynos_OMX_BufferFlush;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+
+    int i = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    Exynos_OSAL_Free(pVideoEnc);
+    pExynosComponent->hComponentHandle = pVideoEnc = NULL;
+
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    if (pExynosPort->processData.extInfo != NULL) {
+        Exynos_OSAL_Free(pExynosPort->processData.extInfo);
+        pExynosPort->processData.extInfo = NULL;
+    }
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        pExynosPort = &pExynosComponent->pExynosPort[i];
+        Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
+        pExynosPort->portDefinition.format.video.cMIMEType = NULL;
+
+        Exynos_OSAL_Free(pExynosPort->supportFormat);
+        pExynosPort->supportFormat = NULL;
+    }
+
+    ret = Exynos_OMX_Port_Destructor(pOMXComponent);
+
+    ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/enc/Exynos_OMX_Venc.h b/openmax/component/video/enc/Exynos_OMX_Venc.h
new file mode 100755 (executable)
index 0000000..8ffd233
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Venc.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_VIDEO_ENCODE
+#define EXYNOS_OMX_VIDEO_ENCODE
+
+#include "OMX_Component.h"
+#include "Exynos_OMX_Def.h"
+#include "Exynos_OSAL_Queue.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Basecomponent.h"
+
+#define MAX_VIDEO_INPUTBUFFER_NUM    5
+#define MAX_VIDEO_OUTPUTBUFFER_NUM   4
+
+#define MAX_FRAME_WIDTH          1920
+#define MAX_FRAME_HEIGHT         1080
+
+#define DEFAULT_VIDEO_INPUT_BUFFER_SIZE    (ALIGN_TO_16B(DEFAULT_FRAME_WIDTH) * ALIGN_TO_16B(DEFAULT_FRAME_HEIGHT) + \
+                                                                                ALIGN((ALIGN_TO_16B(DEFAULT_FRAME_WIDTH) * ALIGN_TO_16B(DEFAULT_FRAME_HEIGHT))/2,256))
+#define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE   (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT) * 3 / 2
+
+#define MFC_INPUT_BUFFER_NUM_MAX            3
+#define MFC_OUTPUT_BUFFER_NUM_MAX           4
+
+#define DEFAULT_MFC_INPUT_YBUFFER_SIZE      ALIGN_TO_16B(MAX_FRAME_WIDTH) * ALIGN_TO_16B(MAX_FRAME_HEIGHT)
+#define DEFAULT_MFC_INPUT_CBUFFER_SIZE      ALIGN((DEFAULT_MFC_INPUT_YBUFFER_SIZE / 2), 256)
+#define DEFAULT_MFC_OUTPUT_BUFFER_SIZE      MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2
+
+#define INPUT_PORT_SUPPORTFORMAT_DEFAULT_NUM    5  /* I42P, NV12, NV21, BGRA8888, RGBA8888 */
+#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX        (INPUT_PORT_SUPPORTFORMAT_DEFAULT_NUM + 5)  /* Opaque, NV12T, YV12, ARGB8888, UNUSED */
+#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX       1
+
+#define MFC_DEFAULT_INPUT_BUFFER_PLANE  2
+#define MFC_DEFAULT_OUTPUT_BUFFER_PLANE 1
+
+#define MAX_INPUTBUFFER_NUM_DYNAMIC         0 /* Dynamic number of metadata buffer */
+#define MAX_OUTPUTBUFFER_NUM_DYNAMIC        0 /* Dynamic number of metadata buffer */
+
+#define OMX_VIDEO_MAX_REF_FRAMES 3
+#define OMX_VIDEO_MAX_LTR_FRAMES 4 /* LTR */
+
+#define ENC_BLOCKS_PER_SECOND               979200 /* remove it and have to read a capability at media_codecs.xml */
+
+#define GENERAL_TSVC_ENABLE (1 << 16)
+
+typedef struct
+{
+    void *pAddrY;
+    void *pAddrC;
+} CODEC_ENC_ADDR_INFO;
+
+typedef struct _BYPASS_BUFFER_INFO
+{
+    OMX_U32   nFlags;
+    OMX_TICKS timeStamp;
+} BYPASS_BUFFER_INFO;
+
+typedef struct _CODEC_ENC_BUFFER
+{
+    void           *pVirAddr[MAX_BUFFER_PLANE];   /* virtual address   */
+    unsigned int    bufferSize[MAX_BUFFER_PLANE]; /* buffer alloc size */
+    unsigned long   fd[MAX_BUFFER_PLANE];         /* buffer FD */
+    int             dataSize;                     /* total data length */
+} CODEC_ENC_BUFFER;
+
+typedef struct _EXYNOS_OMX_VIDEOENC_COMPONENT
+{
+    OMX_HANDLETYPE hCodecHandle;
+    OMX_BOOL bQosChanged;
+    OMX_U32  nQosRatio;
+    OMX_U32  nInbufSpareSize;
+    CODEC_ENC_BUFFER *pMFCEncInputBuffer[MFC_INPUT_BUFFER_NUM_MAX];
+    CODEC_ENC_BUFFER *pMFCEncOutputBuffer[MFC_OUTPUT_BUFFER_NUM_MAX];
+
+    /* Buffer Process */
+    OMX_BOOL       bExitBufferProcessThread;
+    OMX_HANDLETYPE hSrcInputThread;
+    OMX_HANDLETYPE hSrcOutputThread;
+    OMX_HANDLETYPE hDstInputThread;
+    OMX_HANDLETYPE hDstOutputThread;
+
+    /* Shared Memory Handle */
+    OMX_HANDLETYPE hSharedMemory;
+
+    OMX_BOOL                         IntraRefreshVOP;
+    OMX_VIDEO_CONTROLRATETYPE        eControlRate[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_QUANTIZATIONTYPE quantization;
+    OMX_VIDEO_PARAM_INTRAREFRESHTYPE intraRefresh;
+
+    OMX_BOOL                bPVCMode;   /* true: PVC mode on false: PVC mode off
+                                           Only h264 hevc vp8 vp9 codec valid */
+    OMX_BOOL                bUseBlurFilter;
+    EXYNOS_OMX_BLUR_MODE    eBlurMode;       /* Down/Up or Coefficient mothod */
+    EXYNOS_OMX_BLUR_RESOL   eBlurResol;
+
+    EXYNOS_OMX_ROTATION_TYPE eRotationType;
+
+    OMX_BOOL bFirstInput;
+    OMX_BOOL bFirstOutput;
+    OMX_BOOL bEncDRC;
+
+    OMX_COLOR_FORMATTYPE surfaceFormat;
+
+    /* CSC handle */
+    OMX_PTR csc_handle;
+    OMX_U32 csc_set_format;
+
+    OMX_ERRORTYPE (*exynos_codec_srcInputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData);
+    OMX_ERRORTYPE (*exynos_codec_srcOutputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData);
+    OMX_ERRORTYPE (*exynos_codec_dstInputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pOutputData);
+    OMX_ERRORTYPE (*exynos_codec_dstOutputProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pOutputData);
+
+    OMX_ERRORTYPE (*exynos_codec_start)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex);
+    OMX_ERRORTYPE (*exynos_codec_stop)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex);
+    OMX_ERRORTYPE (*exynos_codec_bufferProcessRun)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex);
+    OMX_ERRORTYPE (*exynos_codec_enqueueAllBuffer)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex);
+
+    OMX_ERRORTYPE (*exynos_codec_getCodecOutputPrivateData) (OMX_PTR codecBuffer, OMX_PTR *addr, OMX_U32 *size);
+
+    OMX_BOOL      (*exynos_codec_checkFormatSupport)(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_COLOR_FORMATTYPE eColorFormat);
+} EXYNOS_OMX_VIDEOENC_COMPONENT;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent);
+void Exynos_Input_SetSupportFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+OMX_COLOR_FORMATTYPE Exynos_Input_GetActualColorFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex);
+OMX_ERRORTYPE Exynos_CodecBufferToData(CODEC_ENC_BUFFER *codecBuffer, EXYNOS_OMX_DATA *pData, OMX_U32 nPortIndex);
+OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_Allocate_CodecBuffers(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex, int nBufferCnt, unsigned int nAllocLen[MAX_BUFFER_PLANE]);
+void Exynos_Free_CodecBuffers(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex);
+OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/component/video/enc/Exynos_OMX_VencControl.c b/openmax/component/video/enc/Exynos_OMX_VencControl.c
new file mode 100755 (executable)
index 0000000..f0b2da0
--- /dev/null
@@ -0,0 +1,2374 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_VencControl.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.5.0
+ * @history
+ *   2012.02.20 : Create
+ *   2017.08.03 : Change event handling
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OMX_Venc.h"
+#include "Exynos_OMX_VencControl.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OSAL_Thread.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_SharedMemory.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VIDEO_ENCCONTROL"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+OMX_ERRORTYPE Exynos_OMX_UseBuffer(
+    OMX_IN OMX_HANDLETYPE            hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32                   nPortIndex,
+    OMX_IN OMX_PTR                   pAppPrivate,
+    OMX_IN OMX_U32                   nSizeBytes,
+    OMX_IN OMX_U8                   *pBuffer)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+    OMX_BUFFERHEADERTYPE     *pTempBufferHdr    = NULL;
+    OMX_U32                   i                 = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid parameter(0x%x)", pExynosComponent, __FUNCTION__, nPortIndex);
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    if (pExynosPort->portState != EXYNOS_OMX_PortStateEnabling) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] %s port : invalid state : comp state(0x%x), port state(0x%x), enabled(0x%x)",
+                        pExynosComponent, __FUNCTION__,
+                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                        pExynosComponent->currentState, pExynosPort->portState, pExynosPort->portDefinition.bEnabled);
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    if (CHECK_PORT_TUNNELED(pExynosPort) &&
+        CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    pTempBufferHdr = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (pTempBufferHdr == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pTempBufferHdr, 0, sizeof(OMX_BUFFERHEADERTYPE));
+
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
+            pExynosPort->extendBufferHeader[i].OMXBufferHeader = pTempBufferHdr;
+            pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED);
+            INIT_SET_SIZE_VERSION(pTempBufferHdr, OMX_BUFFERHEADERTYPE);
+
+            pTempBufferHdr->pBuffer        = pBuffer;
+            pTempBufferHdr->nAllocLen      = nSizeBytes;
+            pTempBufferHdr->pAppPrivate    = pAppPrivate;
+
+            if (nPortIndex == INPUT_PORT_INDEX)
+                pTempBufferHdr->nInputPortIndex = INPUT_PORT_INDEX;
+            else
+                pTempBufferHdr->nOutputPortIndex = OUTPUT_PORT_INDEX;
+
+            pExynosPort->assignedBufferNum++;
+
+            *ppBufferHdr = pTempBufferHdr;
+
+            if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+                pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+
+                if ((pExynosComponent->currentState == OMX_StateLoaded) &&
+                    (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle)) {
+                    if (CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]) &&
+                        CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX])) {
+                        Exynos_OMX_SendEventCommand(pExynosComponent, EVENT_CMD_STATE_TO_IDLE_STATE, NULL);
+                    }
+                } else if((!CHECK_PORT_ENABLED(pExynosPort)) &&
+                          (pExynosPort->portState == EXYNOS_OMX_PortStateEnabling)) {
+                    Exynos_OMX_SendEventCommand(pExynosComponent,
+                                                ((nPortIndex == INPUT_PORT_INDEX)? EVENT_CMD_ENABLE_INPUT_PORT:EVENT_CMD_ENABLE_OUTPUT_PORT),
+                                                NULL);
+                }
+            }
+
+            ret = OMX_ErrorNone;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port: buffer header(%p), size(%d)",
+                                        pExynosComponent, __FUNCTION__,
+                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                        (*ppBufferHdr), nSizeBytes);
+            goto EXIT;
+        }
+    }
+
+    Exynos_OSAL_Free(pTempBufferHdr);
+    ret = OMX_ErrorInsufficientResources;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AllocateBuffer(
+    OMX_IN OMX_HANDLETYPE            hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32                   nPortIndex,
+    OMX_IN OMX_PTR                   pAppPrivate,
+    OMX_IN OMX_U32                   nSizeBytes)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    OMX_BUFFERHEADERTYPE            *pTempBufferHdr     = NULL;
+    OMX_U8                          *pTempBuffer        = NULL;
+    unsigned long                    fdTempBuffer       = 0;
+    MEMORY_TYPE                      eMemType           = NORMAL_MEMORY;
+    OMX_U32                          i                  = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid parameter(0x%x)", pExynosComponent, __FUNCTION__, nPortIndex);
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    if (pExynosPort->portState != EXYNOS_OMX_PortStateEnabling) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] %s port : invalid state : comp state(0x%x), port state(0x%x), enabled(0x%x)",
+                        pExynosComponent, __FUNCTION__,
+                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                        pExynosComponent->currentState, pExynosPort->portState, pExynosPort->portDefinition.bEnabled);
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    if (CHECK_PORT_TUNNELED(pExynosPort) &&
+        CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC) &&
+        (nPortIndex == OUTPUT_PORT_INDEX))
+        eMemType |= SECURE_MEMORY;
+
+    if (pExynosPort->bNeedContigMem == OMX_TRUE)
+        eMemType |= CONTIG_MEMORY;
+
+    if (!((nPortIndex == INPUT_PORT_INDEX) &&
+          (pExynosPort->bufferProcessType & BUFFER_SHARE)))
+        eMemType |= CACHED_MEMORY;
+
+    if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+        (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        eMemType |= CONTIG_MEMORY;  /* always set for HDCP */
+
+#ifdef USE_VIDEO_EXT_FOR_WFD_HDCP
+        if ((eMemType & SECURE_MEMORY) ||  // secure component
+            (eMemType & CONTIG_MEMORY)) {  // Normal DRM
+            eMemType |= EXT_MEMORY;
+        }
+#endif
+        pTempBuffer = Exynos_OSAL_AllocMetaDataBuffer(pVideoEnc->hSharedMemory,
+                                                      pExynosPort->eMetaDataType,
+                                                      nSizeBytes,
+                                                      eMemType);
+        if (pTempBuffer == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Alloc", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    } else {
+        pTempBuffer = Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, nSizeBytes, eMemType);
+        if (pTempBuffer == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Alloc", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        fdTempBuffer = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pTempBuffer);
+    }
+
+    pTempBufferHdr = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (pTempBufferHdr == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pTempBufferHdr, 0, sizeof(OMX_BUFFERHEADERTYPE));
+
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
+            pExynosPort->extendBufferHeader[i].OMXBufferHeader = pTempBufferHdr;
+            pExynosPort->extendBufferHeader[i].buf_fd[0] = fdTempBuffer;
+            pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED);
+            INIT_SET_SIZE_VERSION(pTempBufferHdr, OMX_BUFFERHEADERTYPE);
+
+            if ((pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC) &&
+                (pExynosPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
+                pTempBufferHdr->pBuffer = (void *)fdTempBuffer;
+            } else {
+                pTempBufferHdr->pBuffer = pTempBuffer;
+            }
+
+            pTempBufferHdr->nAllocLen      = nSizeBytes;
+            pTempBufferHdr->pAppPrivate    = pAppPrivate;
+
+            if (nPortIndex == INPUT_PORT_INDEX)
+                pTempBufferHdr->nInputPortIndex = INPUT_PORT_INDEX;
+            else
+                pTempBufferHdr->nOutputPortIndex = OUTPUT_PORT_INDEX;
+
+            pExynosPort->assignedBufferNum++;
+
+            *ppBufferHdr = pTempBufferHdr;
+
+            if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+                pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+
+                if ((pExynosComponent->currentState == OMX_StateLoaded) &&
+                    (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle)) {
+                    if (CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]) &&
+                        CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX])) {
+                        Exynos_OMX_SendEventCommand(pExynosComponent, EVENT_CMD_STATE_TO_IDLE_STATE, NULL);
+                    }
+                } else if((!CHECK_PORT_ENABLED(pExynosPort)) &&
+                          (pExynosPort->portState == EXYNOS_OMX_PortStateEnabling)) {
+                    Exynos_OMX_SendEventCommand(pExynosComponent,
+                                                ((nPortIndex == INPUT_PORT_INDEX)? EVENT_CMD_ENABLE_INPUT_PORT:EVENT_CMD_ENABLE_OUTPUT_PORT),
+                                                NULL);
+                }
+            }
+
+            ret = OMX_ErrorNone;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port: buffer header(%p), size(%d)",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                                    (*ppBufferHdr), nSizeBytes);
+            goto EXIT;
+        }
+    }
+
+    ret = OMX_ErrorInsufficientResources;
+
+EXIT:
+    if (ret == OMX_ErrorInsufficientResources) {
+        if (pTempBufferHdr != NULL)
+            Exynos_OSAL_Free(pTempBufferHdr);
+
+        if (pTempBuffer != NULL) {
+            if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+                (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+                Exynos_OSAL_FreeMetaDataBuffer(pVideoEnc->hSharedMemory, pExynosPort->eMetaDataType, pTempBuffer);
+            } else if ((pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC) &&
+                       (pExynosPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
+                OMX_PTR mapBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, fdTempBuffer);
+
+                Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pTempBuffer);
+            } else {
+                Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pTempBuffer);
+            }
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FreeBuffer(
+    OMX_IN OMX_HANDLETYPE        hComponent,
+    OMX_IN OMX_U32               nPortIndex,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    OMX_BUFFERHEADERTYPE            *pOMXBufferHdr      = NULL;
+    OMX_U32                          i                  = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid parameter(0x%x)", pExynosComponent, __FUNCTION__, nPortIndex);
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    if (CHECK_PORT_TUNNELED(pExynosPort) &&
+        CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((pExynosPort->portState != EXYNOS_OMX_PortStateDisabling) &&
+        (pExynosPort->portState != EXYNOS_OMX_PortStateFlushingForDisable) &&
+        (pExynosPort->portState != EXYNOS_OMX_PortStateInvalid)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] %s port : invalid state : comp state(0x%x), port state(0x%x), enabled(0x%x)",
+                        pExynosComponent, __FUNCTION__,
+                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                        pExynosComponent->currentState, pExynosPort->portState, pExynosPort->portDefinition.bEnabled);
+        ret = OMX_ErrorIncorrectStateOperation;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+
+        (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent,
+                        pExynosComponent->callbackData,
+                        (OMX_U32)OMX_EventError,
+                        (OMX_U32)OMX_ErrorPortUnpopulated,
+                        nPortIndex, NULL);
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    for (i = 0; i < /*pExynosPort->portDefinition.nBufferCountActual*/MAX_BUFFER_NUM; i++) {
+        if ((pExynosPort->bufferStateAllocate[i] != BUFFER_STATE_FREE) &&
+            (pExynosPort->extendBufferHeader[i].OMXBufferHeader != NULL)) {
+            pOMXBufferHdr = pExynosPort->extendBufferHeader[i].OMXBufferHeader;
+
+            if (pOMXBufferHdr->pBuffer == pBufferHdr->pBuffer) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port: buffer header(%p)",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                                        pOMXBufferHdr);
+                if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) {
+                    if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+                        (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+                        Exynos_OSAL_FreeMetaDataBuffer(pVideoEnc->hSharedMemory,
+                                                       pExynosPort->eMetaDataType,
+                                                       pOMXBufferHdr->pBuffer);
+                    } else if ((pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC) &&
+                               (pExynosPort->eMetaDataType == OUTPUT_PORT_INDEX)) {
+                        unsigned long ionFD = (unsigned long)pOMXBufferHdr->pBuffer;
+
+                        OMX_PTR mapBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, ionFD);
+                        Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, mapBuffer);
+                    } else {
+                        Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pOMXBufferHdr->pBuffer);
+                    }
+
+                    pOMXBufferHdr->pBuffer  = NULL;
+                    pBufferHdr->pBuffer     = NULL;
+                } else if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) {
+                    ; /* None*/
+                }
+
+                pExynosPort->assignedBufferNum--;
+
+                if (pExynosPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) {
+                    Exynos_OSAL_Free(pOMXBufferHdr);
+                    pExynosPort->extendBufferHeader[i].OMXBufferHeader  = NULL;
+                    pExynosPort->extendBufferHeader[i].bBufferInOMX     = OMX_FALSE;
+                    pBufferHdr = NULL;
+                }
+
+                pExynosPort->bufferStateAllocate[i] = BUFFER_STATE_FREE;
+                ret = OMX_ErrorNone;
+                goto EXIT;
+            }
+        }
+    }
+
+EXIT:
+    if (ret == OMX_ErrorNone) {
+        if (pExynosPort->assignedBufferNum < (OMX_S32)pExynosPort->portDefinition.nBufferCountActual)
+            pExynosPort->portDefinition.bPopulated = OMX_FALSE;
+
+        if (pExynosPort->assignedBufferNum == 0) {
+            if ((pExynosComponent->currentState == OMX_StateIdle) &&
+                (pExynosComponent->transientState == EXYNOS_OMX_TransStateIdleToLoaded)) {
+                if (!CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]) &&
+                    !CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX])) {
+                    Exynos_OMX_SendEventCommand(pExynosComponent, EVENT_CMD_STATE_TO_LOAD_STATE, NULL);
+                }
+            } else if((CHECK_PORT_ENABLED(pExynosPort)) &&
+                      (pExynosPort->portState == EXYNOS_OMX_PortStateDisabling)) {
+                Exynos_OMX_SendEventCommand(pExynosComponent,
+                                            ((nPortIndex == INPUT_PORT_INDEX)? EVENT_CMD_DISABLE_INPUT_PORT:EVENT_CMD_DISABLE_OUTPUT_PORT),
+                                            NULL);
+            }
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+#ifdef TUNNELING_SUPPORT
+OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer(
+    EXYNOS_OMX_BASEPORT     *pOMXBasePort,
+    OMX_U32                  nPortIndex)
+{
+    OMX_ERRORTYPE                 ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT          *pExynosPort       = NULL;
+    OMX_BUFFERHEADERTYPE         *pTempBufferHdr    = NULL;
+    OMX_U8                       *pTempBuffer       = NULL;
+    OMX_U32                       nBufferSize       = 0;
+    OMX_PARAM_PORTDEFINITIONTYPE  portDefinition;
+
+    ret = OMX_ErrorTunnelingUnsupported;
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FreeTunnelBuffer(
+    EXYNOS_OMX_BASEPORT     *pOMXBasePort,
+    OMX_U32                  nPortIndex)
+{
+    OMX_ERRORTYPE            ret            = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT     *pExynosPort    = NULL;
+    OMX_BUFFERHEADERTYPE    *pTempBufferHdr = NULL;
+    OMX_U8                  *pTempBuffer    = NULL;
+    OMX_U32                  nBufferSize    = 0;
+
+    ret = OMX_ErrorTunnelingUnsupported;
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentTunnelRequest(
+    OMX_IN OMX_HANDLETYPE hComp,
+    OMX_IN OMX_U32        nPort,
+    OMX_IN OMX_HANDLETYPE hTunneledComp,
+    OMX_IN OMX_U32        nTunneledPort,
+    OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    ret = OMX_ErrorTunnelingUnsupported;
+EXIT:
+    return ret;
+}
+#endif
+
+OMX_ERRORTYPE Exynos_OMX_GetFlushBuffer(
+    EXYNOS_OMX_BASEPORT     *pExynosPort,
+    EXYNOS_OMX_DATABUFFER   *pDataBuffer[])
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    *pDataBuffer = NULL;
+
+    if (pExynosPort->portWayType == WAY1_PORT) {
+        *pDataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer;
+    } else if (pExynosPort->portWayType == WAY2_PORT) {
+        pDataBuffer[0] = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
+        pDataBuffer[1] = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer);
+    }
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FlushPort(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_S32              nPortIndex)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+    OMX_BUFFERHEADERTYPE     *pBufferHdr        = NULL;
+    EXYNOS_OMX_DATABUFFER    *pDataBuffer[2]    = {NULL, NULL};
+    EXYNOS_OMX_MESSAGE       *pMessage          = NULL;
+    OMX_S32                   nSemaCnt          = 0;
+    int                       i                 = 0;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if ((nPortIndex < 0) ||
+        (nPortIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
+        Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &nSemaCnt);
+        if (nSemaCnt == 0)
+            Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
+
+        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+        pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+        if ((pMessage != NULL) &&
+            (pMessage->type != EXYNOS_OMX_CommandFakeBuffer)) {
+            pBufferHdr = (OMX_BUFFERHEADERTYPE *)pMessage->pCmdData;
+            pBufferHdr->nFilledLen = 0;
+
+            if (nPortIndex == OUTPUT_PORT_INDEX) {
+                Exynos_OMX_OutputBufferReturn(pOMXComponent, pBufferHdr);
+            } else if (nPortIndex == INPUT_PORT_INDEX) {
+                Exynos_OMX_InputBufferReturn(pOMXComponent, pBufferHdr);
+            }
+        }
+        Exynos_OSAL_Free(pMessage);
+        pMessage = NULL;
+    }
+
+    Exynos_OMX_GetFlushBuffer(pExynosPort, pDataBuffer);
+    if ((pDataBuffer[0] != NULL) &&
+        (pDataBuffer[0]->dataValid == OMX_TRUE)) {
+        if (nPortIndex == INPUT_PORT_INDEX)
+            Exynos_InputBufferReturn(pOMXComponent, pDataBuffer[0]);
+        else if (nPortIndex == OUTPUT_PORT_INDEX)
+            Exynos_OutputBufferReturn(pOMXComponent, pDataBuffer[0]);
+    }
+    if ((pDataBuffer[1] != NULL) &&
+        (pDataBuffer[1]->dataValid == OMX_TRUE)) {
+        if (nPortIndex == INPUT_PORT_INDEX)
+            Exynos_InputBufferReturn(pOMXComponent, pDataBuffer[1]);
+        else if (nPortIndex == OUTPUT_PORT_INDEX)
+            Exynos_OutputBufferReturn(pOMXComponent, pDataBuffer[1]);
+    }
+
+    if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+        if (pExynosPort->processData.bufferHeader != NULL) {
+            if (nPortIndex == INPUT_PORT_INDEX) {
+                if (pExynosPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK)
+                    Exynos_OSAL_UnlockMetaData(pExynosPort->processData.bufferHeader->pBuffer, pExynosPort->eMetaDataType);
+
+                Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader);
+            } else if (nPortIndex == OUTPUT_PORT_INDEX) {
+                Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader);
+            }
+        }
+        Exynos_ResetCodecData(&pExynosPort->processData);
+
+        for (i = 0; i < (OMX_S32)pExynosPort->portDefinition.nBufferCountActual; i++) {
+            if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_TRUE) {
+                if (nPortIndex == OUTPUT_PORT_INDEX) {
+                    Exynos_OMX_OutputBufferReturn(pOMXComponent,
+                                                  pExynosPort->extendBufferHeader[i].OMXBufferHeader);
+                } else if (nPortIndex == INPUT_PORT_INDEX) {
+                    if (pExynosPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK)
+                        Exynos_OSAL_UnlockMetaData(pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer, pExynosPort->eMetaDataType);
+
+                    Exynos_OMX_InputBufferReturn(pOMXComponent,
+                                                 pExynosPort->extendBufferHeader[i].OMXBufferHeader);
+                }
+            }
+        }
+    }
+
+    if (pExynosPort->bufferSemID != NULL) {
+        while (1) {
+            OMX_S32 cnt = 0;
+            Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &cnt);
+            if (cnt == 0)
+                break;
+            else if (cnt > 0)
+                Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+            else if (cnt < 0)
+                Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+    Exynos_OSAL_ResetQueue(&pExynosPort->bufferQ);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BufferFlush(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_S32              nPortIndex,
+    OMX_BOOL             bEvent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    EXYNOS_OMX_DATABUFFER           *pDataBuffer[2]     = {NULL, NULL};
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if ((nPortIndex < 0) ||
+        (nPortIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] OMX_CommandFlush start, port:%d, event:%d",
+                                    pExynosComponent, __FUNCTION__, nPortIndex, bEvent);
+
+    Exynos_OSAL_SignalSet(pExynosPort->pauseEvent);
+
+    Exynos_OMX_GetFlushBuffer(pExynosPort, pDataBuffer);
+    if (pDataBuffer[0] == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pExynosPort->bufferProcessType & BUFFER_COPY)
+        Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID);
+
+    if (pExynosPort->bufferSemID != NULL) {
+        while (1) {
+            OMX_S32 cnt = 0;
+            Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &cnt);
+            if (cnt > 0)
+                break;
+            else
+                Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, nPortIndex);
+
+    Exynos_OSAL_MutexLock(pDataBuffer[0]->bufferMutex);
+    pVideoEnc->exynos_codec_stop(pOMXComponent, nPortIndex);
+
+    if (pDataBuffer[1] != NULL)
+        Exynos_OSAL_MutexLock(pDataBuffer[1]->bufferMutex);
+
+    ret = Exynos_OMX_FlushPort(pOMXComponent, nPortIndex);
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pExynosPort->bufferProcessType & BUFFER_COPY)
+        pVideoEnc->exynos_codec_enqueueAllBuffer(pOMXComponent, nPortIndex);
+
+    Exynos_ResetCodecData(&pExynosPort->processData);
+
+    if (ret == OMX_ErrorNone) {
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE;
+            pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
+            Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, OMX_FALSE, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+            INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+            Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+            pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+            pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+            pExynosComponent->bBehaviorEOS = OMX_FALSE;
+            pExynosComponent->reInputData = OMX_FALSE;
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_CountReset(pExynosPort->hBufferCount);
+#endif
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] OMX_CommandFlush end, port:%d, event:%d",
+                                        pExynosComponent, __FUNCTION__, nPortIndex, bEvent);
+
+EXIT:
+    if (pDataBuffer[1] != NULL)
+        Exynos_OSAL_MutexUnlock(pDataBuffer[1]->bufferMutex);
+
+    if (pDataBuffer[0] != NULL)
+        Exynos_OSAL_MutexUnlock(pDataBuffer[0]->bufferMutex);
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_InputBufferReturn(
+    OMX_COMPONENTTYPE       *pOMXComponent,
+    EXYNOS_OMX_DATABUFFER   *pDataBuffer)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT         *pExynosPort        = NULL;
+    OMX_BUFFERHEADERTYPE        *pBufferHdr         = NULL;
+
+    FunctionIn();
+
+    if ((pOMXComponent == NULL) ||
+        (pDataBuffer == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]);
+
+    pBufferHdr = pDataBuffer->bufferHeader;
+
+    if (pBufferHdr != NULL) {
+        if (pExynosPort->markType.hMarkTargetComponent != NULL) {
+            pBufferHdr->hMarkTargetComponent            = pExynosPort->markType.hMarkTargetComponent;
+            pBufferHdr->pMarkData                       = pExynosPort->markType.pMarkData;
+            pExynosPort->markType.hMarkTargetComponent  = NULL;
+            pExynosPort->markType.pMarkData             = NULL;
+        }
+
+        if (pBufferHdr->hMarkTargetComponent != NULL) {
+            if (pBufferHdr->hMarkTargetComponent == pOMXComponent) {
+                pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                pExynosComponent->callbackData,
+                                OMX_EventMark,
+                                0, 0, pBufferHdr->pMarkData);
+            } else {
+                pExynosComponent->propagateMarkType.hMarkTargetComponent    = pBufferHdr->hMarkTargetComponent;
+                pExynosComponent->propagateMarkType.pMarkData               = pBufferHdr->pMarkData;
+            }
+        }
+
+        pBufferHdr->nFilledLen  = 0;
+        pBufferHdr->nOffset     = 0;
+
+        Exynos_OMX_InputBufferReturn(pOMXComponent, pBufferHdr);
+    }
+
+    /* reset dataBuffer */
+    Exynos_ResetDataBuffer(pDataBuffer);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_InputBufferGetQueue(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent)
+{
+    OMX_ERRORTYPE          ret          = OMX_ErrorUndefined;
+    EXYNOS_OMX_BASEPORT   *pExynosPort  = NULL;
+    EXYNOS_OMX_MESSAGE    *pMessage     = NULL;
+    EXYNOS_OMX_DATABUFFER *pDataBuffer  = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]);
+    pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
+
+    if (pExynosComponent->currentState != OMX_StateExecuting) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+               (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> wait(bufferSemID)",
+                                                    pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input port -> post(bufferSemID)",
+                                                    pExynosComponent, __FUNCTION__);
+
+        if (pDataBuffer->dataValid != OMX_TRUE) {
+            pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+            if (pMessage == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+            if (pMessage->type == EXYNOS_OMX_CommandFakeBuffer) {
+                Exynos_OSAL_Free(pMessage);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecFlush;
+                goto EXIT;
+            }
+
+            pDataBuffer->bufferHeader  = (OMX_BUFFERHEADERTYPE *)(pMessage->pCmdData);
+            pDataBuffer->allocSize     = pDataBuffer->bufferHeader->nAllocLen;
+            pDataBuffer->dataLen       = pDataBuffer->bufferHeader->nFilledLen;
+            pDataBuffer->remainDataLen = pDataBuffer->dataLen;
+            pDataBuffer->usedDataLen   = 0;
+            pDataBuffer->dataValid     = OMX_TRUE;
+            pDataBuffer->nFlags        = pDataBuffer->bufferHeader->nFlags;
+            pDataBuffer->timeStamp     = pDataBuffer->bufferHeader->nTimeStamp;
+
+            Exynos_OSAL_Free(pMessage);
+
+            if (pDataBuffer->allocSize < pDataBuffer->dataLen) {
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] buffer size(%d) is smaller than dataLen(%d)",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pDataBuffer->allocSize, pDataBuffer->dataLen);
+            }
+        }
+
+        ret = OMX_ErrorNone;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OutputBufferReturn(
+    OMX_COMPONENTTYPE       *pOMXComponent,
+    EXYNOS_OMX_DATABUFFER   *pDataBuffer)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+    OMX_BUFFERHEADERTYPE     *pBufferHdr        = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+
+    if (pDataBuffer != NULL)
+        pBufferHdr = pDataBuffer->bufferHeader;
+
+    if (pBufferHdr != NULL) {
+        pBufferHdr->nFilledLen = pDataBuffer->remainDataLen;
+        pBufferHdr->nOffset    = 0;
+        pBufferHdr->nFlags     = pDataBuffer->nFlags;
+        pBufferHdr->nTimeStamp = pDataBuffer->timeStamp;
+
+        if ((pExynosPort->eMetaDataType & METADATA_TYPE_DATA) &&
+            (pBufferHdr->nFilledLen > 0)) {
+            pBufferHdr->nFilledLen = pBufferHdr->nAllocLen;
+        }
+
+        if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) {
+            pBufferHdr->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent;
+            pBufferHdr->pMarkData            = pExynosComponent->propagateMarkType.pMarkData;
+            pExynosComponent->propagateMarkType.hMarkTargetComponent    = NULL;
+            pExynosComponent->propagateMarkType.pMarkData               = NULL;
+        }
+
+        if ((pBufferHdr->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] send event(OMX_EventBufferFlag)",
+                                                pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                            pExynosComponent->callbackData,
+                            OMX_EventBufferFlag,
+                            OUTPUT_PORT_INDEX,
+                            pBufferHdr->nFlags, NULL);
+        }
+
+        Exynos_OMX_OutputBufferReturn(pOMXComponent, pBufferHdr);
+    }
+
+    /* reset dataBuffer */
+    Exynos_ResetDataBuffer(pDataBuffer);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OutputBufferGetQueue(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent)
+{
+    OMX_ERRORTYPE          ret          = OMX_ErrorUndefined;
+    EXYNOS_OMX_BASEPORT   *pExynosPort  = NULL;
+    EXYNOS_OMX_MESSAGE    *pMessage     = NULL;
+    EXYNOS_OMX_DATABUFFER *pDataBuffer  = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+
+    if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+        pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer);
+    } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+        pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
+    } else {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->currentState != OMX_StateExecuting) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+               (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
+       Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> wait(bufferSemID)",
+                                                pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+       Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> post(bufferSemID)",
+                                                pExynosComponent, __FUNCTION__);
+        if (pDataBuffer->dataValid != OMX_TRUE) {
+            pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+            if (pMessage == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+            if (pMessage->type == EXYNOS_OMX_CommandFakeBuffer) {
+                Exynos_OSAL_Free(pMessage);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecFlush;
+                goto EXIT;
+            }
+
+            pDataBuffer->bufferHeader  = (OMX_BUFFERHEADERTYPE *)(pMessage->pCmdData);
+            pDataBuffer->allocSize     = pDataBuffer->bufferHeader->nAllocLen;
+            pDataBuffer->dataLen       = 0; //dataBuffer->bufferHeader->nFilledLen;
+            pDataBuffer->remainDataLen = pDataBuffer->dataLen;
+            pDataBuffer->usedDataLen   = 0; //dataBuffer->bufferHeader->nOffset;
+            pDataBuffer->dataValid     = OMX_TRUE;
+            /* pDataBuffer->nFlags             = pDataBuffer->bufferHeader->nFlags; */
+            /* pDtaBuffer->nTimeStamp         = pDataBuffer->bufferHeader->nTimeStamp; */
+/*
+            if (pExynosPort->bufferProcessType & BUFFER_SHARE)
+                pDataBuffer->pPrivate      = pDataBuffer->bufferHeader->pOutputPortPrivate;
+            else if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+                pExynosPort->processData.dataBuffer = pDataBuffer->bufferHeader->pBuffer;
+                pExynosPort->processData.allocSize  = pDataBuffer->bufferHeader->nAllocLen;
+            }
+*/
+            Exynos_OSAL_Free(pMessage);
+        }
+
+        ret = OMX_ErrorNone;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_BUFFERHEADERTYPE *Exynos_OutputBufferGetQueue_Direct(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent)
+{
+    OMX_BUFFERHEADERTYPE  *pBufferHdr   = NULL;
+    EXYNOS_OMX_BASEPORT   *pExynosPort  = NULL;
+    EXYNOS_OMX_MESSAGE    *pMessage     = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        pBufferHdr = NULL;
+        goto EXIT;
+    }
+    pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+
+    if (pExynosComponent->currentState != OMX_StateExecuting) {
+        pBufferHdr = NULL;
+        goto EXIT;
+    } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+               (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> wait(bufferSemID)",
+                                                pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output port -> post(bufferSemID)",
+                                                pExynosComponent, __FUNCTION__);
+
+        pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+        if (pMessage == NULL) {
+            pBufferHdr = NULL;
+            goto EXIT;
+        }
+        if (pMessage->type == EXYNOS_OMX_CommandFakeBuffer) {
+            Exynos_OSAL_Free(pMessage);
+            pBufferHdr = NULL;
+            goto EXIT;
+        }
+
+        pBufferHdr  = (OMX_BUFFERHEADERTYPE *)(pMessage->pCmdData);
+        Exynos_OSAL_Free(pMessage);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return pBufferHdr;
+}
+
+OMX_ERRORTYPE Exynos_CodecBufferEnqueue(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_U32                      nPortIndex,
+    OMX_PTR                      pData)
+{
+    OMX_ERRORTYPE          ret         = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT   *pExynosPort = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &(pExynosComponent->pExynosPort[nPortIndex]);
+
+    if (pData == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_Queue(&pExynosPort->codecBufferQ, (void *)pData);
+    if (ret != 0) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+    Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_CodecBufferDequeue(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_U32                      nPortIndex,
+    OMX_PTR                     *pData)
+{
+    OMX_ERRORTYPE          ret         = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT   *pExynosPort = NULL;
+    OMX_PTR                pTempData   = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &(pExynosComponent->pExynosPort[nPortIndex]);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port -> wait(codecSemID)",
+                                            pExynosComponent, __FUNCTION__,
+                                            (nPortIndex == INPUT_PORT_INDEX)? "input":"output");
+    Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port -> post(codecSemID)",
+                                            pExynosComponent, __FUNCTION__,
+                                            (nPortIndex == INPUT_PORT_INDEX)? "input":"output");
+
+    pTempData = (OMX_PTR)Exynos_OSAL_Dequeue(&pExynosPort->codecBufferQ);
+    if (pTempData != NULL) {
+        *pData = (OMX_PTR)pTempData;
+        ret = OMX_ErrorNone;
+    } else {
+        *pData = NULL;
+        ret = OMX_ErrorUndefined;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_CodecBufferReset(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_U32                      nPortIndex)
+{
+    OMX_ERRORTYPE          ret          = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT   *pExynosPort  = NULL;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &(pExynosComponent->pExynosPort[nPortIndex]);
+
+    ret = Exynos_OSAL_ResetQueue(&pExynosPort->codecBufferQ);
+    if (ret != 0) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    while (1) {
+        OMX_S32 cnt = 0;
+        Exynos_OSAL_Get_SemaphoreCount(pExynosPort->codecSemID, &cnt);
+        if (cnt > 0)
+            Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID);
+        else
+            break;
+    }
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoInit:
+    {
+        OMX_PORT_PARAM_TYPE *pPortParam = (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortParam, sizeof(OMX_PORT_PARAM_TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pPortParam->nPorts           = pExynosComponent->portParam.nPorts;
+        pPortParam->nStartPortNumber = pExynosComponent->portParam.nStartPortNumber;
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
+        OMX_U32                         nPortIndex  = pPortFormat->nPortIndex;
+        OMX_U32                         nIndex      = pPortFormat->nIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE   *pPortDef    = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            if (nIndex > (INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1)) {
+                ret = OMX_ErrorNoMore;
+                goto EXIT;
+            }
+
+            pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+            pPortDef = &pExynosPort->portDefinition;
+
+            pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+            pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
+
+            if (pExynosPort->supportFormat[nIndex] == OMX_COLOR_FormatUnused) {
+                ret = OMX_ErrorNoMore;
+                goto EXIT;
+            }
+            pPortFormat->eColorFormat = pExynosPort->supportFormat[nIndex];
+        } else if (nPortIndex == OUTPUT_PORT_INDEX) {
+            if (nIndex > (OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1)) {
+                ret = OMX_ErrorNoMore;
+                goto EXIT;
+            }
+
+            pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+            pPortDef = &pExynosPort->portDefinition;
+
+            pPortFormat->eCompressionFormat = pPortDef->format.video.eCompressionFormat;
+            pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
+            pPortFormat->eColorFormat       = pPortDef->format.video.eColorFormat;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoBitrate:
+    {
+        OMX_VIDEO_PARAM_BITRATETYPE     *pVideoBitrate  = (OMX_VIDEO_PARAM_BITRATETYPE *)pComponentParameterStructure;
+        OMX_U32                          nPortIndex     = pVideoBitrate->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE    *pPortDef       = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+            if (pVideoEnc == NULL) {
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+            }
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            pPortDef = &pExynosPort->portDefinition;
+
+            pVideoBitrate->eControlRate = pVideoEnc->eControlRate[nPortIndex];
+            pVideoBitrate->nTargetBitrate = pPortDef->format.video.nBitrate;
+        }
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoQuantization:
+    {
+        OMX_VIDEO_PARAM_QUANTIZATIONTYPE  *pVideoQuantization = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)pComponentParameterStructure;
+        OMX_U32                            nPortIndex         = pVideoQuantization->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE      *pPortDef           = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            pPortDef = &pExynosPort->portDefinition;
+
+            pVideoQuantization->nQpI = pVideoEnc->quantization.nQpI;
+            pVideoQuantization->nQpP = pVideoEnc->quantization.nQpP;
+            pVideoQuantization->nQpB = pVideoEnc->quantization.nQpB;
+        }
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDef      = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
+        OMX_U32                       nPortIndex    = pPortDef->nPortIndex;
+        ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        ret = Exynos_OSAL_GetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+    }
+        break;
+    case OMX_IndexVendorNeedContigMemory:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *pPortMemType = (EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *)pComponentParameterStructure;
+        OMX_U32                             nPortIndex   = pPortMemType->nPortIndex;
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortMemType, sizeof(EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        pPortMemType->bNeedContigMem = pExynosPort->bNeedContigMem;
+    }
+        break;
+    case OMX_IndexParamVideoIntraRefresh:
+    {
+        OMX_VIDEO_PARAM_INTRAREFRESHTYPE *pIntraRefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pComponentParameterStructure;
+        OMX_U32                           nPortIndex    = pIntraRefresh->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pIntraRefresh, sizeof(OMX_VIDEO_PARAM_INTRAREFRESHTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pIntraRefresh->eRefreshMode = pVideoEnc->intraRefresh.eRefreshMode;
+        pIntraRefresh->nAirMBs      = pVideoEnc->intraRefresh.nAirMBs;
+        pIntraRefresh->nAirRef      = pVideoEnc->intraRefresh.nAirRef;
+        pIntraRefresh->nCirMBs      = pVideoEnc->intraRefresh.nCirMBs;
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamRotationInfo:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO *pRotationInfo = (EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO *)pComponentParameterStructure;
+        OMX_U32                               nPortIndex    = pRotationInfo->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pRotationInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pRotationInfo->eRotationType = pVideoEnc->eRotationType;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamConsumerUsageBits:
+    {
+        ret = Exynos_OSAL_GetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+    }
+        break;
+#endif
+    default:
+    {
+        ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+    }
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
+        OMX_U32                         nPortIndex  = pPortFormat->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE   *pPortDef    = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        pPortDef = &(pExynosComponent->pExynosPort[nPortIndex].portDefinition);
+
+        if ((nPortIndex == INPUT_PORT_INDEX) &&
+            ((pPortFormat->xFramerate >> 16) <= 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] xFramerate is invalid(%d)",
+                                              pExynosComponent, __FUNCTION__, pPortFormat->xFramerate >> 16);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pPortDef->format.video.eColorFormat       = pPortFormat->eColorFormat;
+        pPortDef->format.video.eCompressionFormat = pPortFormat->eCompressionFormat;
+        pPortDef->format.video.xFramerate         = pPortFormat->xFramerate;
+    }
+        break;
+    case OMX_IndexParamVideoBitrate:
+    {
+        OMX_VIDEO_PARAM_BITRATETYPE  *pVideoBitrate = (OMX_VIDEO_PARAM_BITRATETYPE *)pComponentParameterStructure;
+        OMX_U32                       nPortIndex    = pVideoBitrate->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDef      = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pPortDef = &(pExynosComponent->pExynosPort[nPortIndex].portDefinition);
+            pVideoEnc->eControlRate[nPortIndex] = pVideoBitrate->eControlRate;
+            pPortDef->format.video.nBitrate = pVideoBitrate->nTargetBitrate;
+        }
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoQuantization:
+    {
+        OMX_VIDEO_PARAM_QUANTIZATIONTYPE *pVideoQuantization = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)pComponentParameterStructure;
+        OMX_U32                           nPortIndex         = pVideoQuantization->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE     *pPortDef           = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            pPortDef = &pExynosPort->portDefinition;
+
+            pVideoEnc->quantization.nQpI = pVideoQuantization->nQpI;
+            pVideoEnc->quantization.nQpP = pVideoQuantization->nQpP;
+            pVideoEnc->quantization.nQpB = pVideoQuantization->nQpB;
+        }
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDef   = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
+        OMX_U32                       nPortIndex = pPortDef->nPortIndex;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        if (pPortDef->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if ((nPortIndex == INPUT_PORT_INDEX) &&
+            ((pPortDef->format.video.xFramerate >> 16) <= 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s[%x] xFramerate is invalid(%d)",
+                                              __FUNCTION__, OMX_IndexParamPortDefinition, pPortDef->format.video.xFramerate >> 16);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Memcpy(((char *)&pExynosPort->portDefinition) + nOffset,
+                           ((char *)pPortDef) + nOffset,
+                           pPortDef->nSize - nOffset);
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+            Exynos_UpdateFrameSize(pOMXComponent);
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] the size of output buffer is %d",
+                                                pExynosComponent, __FUNCTION__, pExynosPort->portDefinition.nBufferSize);
+        }
+        ret = OMX_ErrorNone;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamAllocateNativeHandle:
+#endif
+     // Porting exynos 9110, code from SM-R765(7270)
+    case OMX_IndexParamStoreMetaDataBuffer:
+    {
+        ret = Exynos_OSAL_SetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+    }
+        break;
+    case OMX_IndexVendorNeedContigMemory:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *pPortMemType = (EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *)pComponentParameterStructure;
+        OMX_U32                             nPortIndex   = pPortMemType->nPortIndex;
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortMemType, sizeof(EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        pExynosPort->bNeedContigMem = pPortMemType->bNeedContigMem;
+    }
+        break;
+    case OMX_IndexParamVideoIntraRefresh:
+    {
+        OMX_VIDEO_PARAM_INTRAREFRESHTYPE *pIntraRefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pComponentParameterStructure;
+        OMX_U32                           nPortIndex    = pIntraRefresh->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pIntraRefresh, sizeof(OMX_VIDEO_PARAM_INTRAREFRESHTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pIntraRefresh->eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) {
+            pVideoEnc->intraRefresh.eRefreshMode    = pIntraRefresh->eRefreshMode;
+            pVideoEnc->intraRefresh.nCirMBs         = pIntraRefresh->nCirMBs;
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_VIDEO_IntraRefreshCyclic Enable, nCirMBs: %d",
+                            pVideoEnc->intraRefresh.nCirMBs);
+        } else {
+            ret = OMX_ErrorUnsupportedSetting;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamEnableBlurFilter:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_BLURFILTER *pBlurMode  = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_BLURFILTER *)pComponentParameterStructure;
+        OMX_U32                                   nPortIndex = pBlurMode->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pBlurMode, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_BLURFILTER));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pVideoEnc->bUseBlurFilter = pBlurMode->bUseBlurFilter;
+    }
+        break;
+    case OMX_IndexParamRotationInfo:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO *pRotationInfo = (EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO *)pComponentParameterStructure;
+        OMX_U32                               nPortIndex    = pRotationInfo->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pRotationInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pVideoEnc->bFirstInput != OMX_TRUE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] can't change a rotation info", pExynosComponent, __FUNCTION__);
+        } else {
+            if ((pRotationInfo->eRotationType != ROTATE_0) &&
+                (pRotationInfo->eRotationType != ROTATE_90) &&
+                (pRotationInfo->eRotationType != ROTATE_180) &&
+                (pRotationInfo->eRotationType != ROTATE_270)) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] can't accecpt a rotation value(%d)", pExynosComponent, __FUNCTION__,
+                                                    pRotationInfo->eRotationType);
+                ret = OMX_ErrorUnsupportedSetting;
+                goto EXIT;
+            }
+
+            pVideoEnc->eRotationType = pRotationInfo->eRotationType;
+        }
+    }
+        break;
+    default:
+    {
+        ret = Exynos_OMX_SetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+    }
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nParamIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexConfigVideoBitrate:
+    {
+        OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure;
+        OMX_U32                       nPortIndex     = pConfigBitrate->nPortIndex;
+        EXYNOS_OMX_BASEPORT          *pExynosPort    = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            pConfigBitrate->nEncodeBitrate = pExynosPort->portDefinition.format.video.nBitrate;
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoFramerate:
+    {
+        OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure;
+        OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
+        EXYNOS_OMX_BASEPORT      *pExynosPort      = NULL;
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+        pConfigFramerate->xEncodeFramerate = pExynosPort->portDefinition.format.video.xFramerate;
+    }
+        break;
+    case OMX_IndexVendorGetBufferFD:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO *pBufferInfo = (EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pBufferInfo, sizeof(EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pBufferInfo->fd = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pBufferInfo->pVirAddr);
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexConfigVideoColorAspects:
+    {
+        ret = Exynos_OSAL_GetConfig(hComponent, nParamIndex, pComponentConfigStructure);
+    }
+        break;
+    case OMX_IndexConfigAndroidVendorExtension:
+    {
+        ret = Exynos_OSAL_GetVendorExt(hComponent, pComponentConfigStructure);
+    }
+        break;
+#endif
+    default:
+    {
+        ret = Exynos_OMX_GetConfig(hComponent, nParamIndex, pComponentConfigStructure);
+    }
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nParamIndex,
+    OMX_PTR         pComponentConfigStructure)
+    {
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexConfigVideoBitrate:
+    {
+        OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure;
+        OMX_U32                       nPortIndex     = pConfigBitrate->nPortIndex;
+        EXYNOS_OMX_BASEPORT          *pExynosPort    = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            if (pVideoEnc->eControlRate[nPortIndex] == OMX_Video_ControlRateDisable) {
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Rate control(eControlRate) is disable. can not change a bitrate",
+                                                    pExynosComponent, __FUNCTION__);
+                goto EXIT;
+            }
+
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            pExynosPort->portDefinition.format.video.nBitrate = pConfigBitrate->nEncodeBitrate;
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoFramerate:
+    {
+        OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure;
+        OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
+        EXYNOS_OMX_BASEPORT      *pExynosPort      = NULL;
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((nPortIndex == INPUT_PORT_INDEX) &&
+            ((pConfigFramerate->xEncodeFramerate >> 16) <= 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] xFramerate is invalid(%d)",
+                                              pExynosComponent, __FUNCTION__, pConfigFramerate->xEncodeFramerate >> 16);
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+        pExynosPort->portDefinition.format.video.xFramerate = pConfigFramerate->xEncodeFramerate;
+    }
+        break;
+    case OMX_IndexConfigVideoIntraVOPRefresh:
+    {
+        OMX_CONFIG_INTRAREFRESHVOPTYPE *pIntraRefreshVOP = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pComponentConfigStructure;
+        OMX_U32                         nPortIndex       = pIntraRefreshVOP->nPortIndex;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pVideoEnc->IntraRefreshVOP = pIntraRefreshVOP->IntraRefreshVOP;
+        }
+    }
+        break;
+    case OMX_IndexConfigOperatingRate:  /* since M version */
+    {
+        OMX_PARAM_U32TYPE *pConfigRate = (OMX_PARAM_U32TYPE *)pComponentConfigStructure;
+        OMX_U32            xFramerate  = 0;
+
+        ret = Exynos_OMX_Check_SizeVersion(pConfigRate, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        xFramerate = pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.xFramerate;
+        if (xFramerate == 0) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] xFramerate is zero. can't calculate QosRatio",
+                                                pExynosComponent, __FUNCTION__);
+            pVideoEnc->nQosRatio = 100;
+        } else {
+            pVideoEnc->nQosRatio = (OMX_U32)((pConfigRate->nU32 / (double)xFramerate) * 100);
+        }
+
+        pVideoEnc->bQosChanged = OMX_TRUE;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] operating rate(%.1lf) / frame rate(%.1lf) / ratio(%d)",pExynosComponent, __FUNCTION__,
+                                                pConfigRate->nU32 / (double)65536, xFramerate / (double)65536, pVideoEnc->nQosRatio);
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexConfigBlurInfo:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_BLURINFO *pBlurMode   = (EXYNOS_OMX_VIDEO_CONFIG_BLURINFO *)pComponentConfigStructure;
+        OMX_U32                           nPortIndex  = pBlurMode->nPortIndex;
+        EXYNOS_OMX_BASEPORT              *pExynosPort = NULL;
+
+        int nEncResol;
+
+        ret = Exynos_OMX_Check_SizeVersion(pBlurMode, sizeof(EXYNOS_OMX_VIDEO_CONFIG_BLURINFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+        nEncResol   = pExynosPort->portDefinition.format.video.nFrameWidth * pExynosPort->portDefinition.format.video.nFrameHeight;
+
+        if (pVideoEnc->bUseBlurFilter == OMX_TRUE) {
+            if ((pBlurMode->eBlurMode & BLUR_MODE_DOWNUP) &&
+                (nEncResol < (int)pBlurMode->eTargetResol)) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Resolution(%d x %d) is smaller than target resolution",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pExynosPort->portDefinition.format.video.nFrameWidth,
+                                                    pExynosPort->portDefinition.format.video.nFrameHeight);
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+            }
+
+            pVideoEnc->eBlurMode = pBlurMode->eBlurMode;
+            pVideoEnc->eBlurResol = pBlurMode->eTargetResol;
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Blur Filter is not enabled, it will be discard",
+                                                    pExynosComponent, __FUNCTION__);
+        }
+
+        ret = (OMX_ERRORTYPE)OMX_ErrorNoneExpiration;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexConfigVideoColorAspects:
+    {
+        ret = Exynos_OSAL_SetConfig(hComponent, nParamIndex, pComponentConfigStructure);
+    }
+        break;
+    case OMX_IndexConfigAndroidVendorExtension:
+    {
+        ret = Exynos_OSAL_SetVendorExt(hComponent, pComponentConfigStructure);
+        if (ret == OMX_ErrorNone)
+            ret = (OMX_ERRORTYPE)OMX_ErrorNoneExpiration;
+    }
+        break;
+#endif
+    default:
+    {
+        ret = Exynos_OMX_SetConfig(hComponent, nParamIndex, pComponentConfigStructure);
+    }
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetExtensionIndex(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_STRING      szParamName,
+    OMX_OUT OMX_INDEXTYPE *pIndexType)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (szParamName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexConfigVideoIntraPeriod;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_PARAM_NEED_CONTIG_MEMORY) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorNeedContigMemory;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_CONFIG_GET_BUFFER_FD) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorGetBufferFD;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_PARAM_VIDEO_QPRANGE_TYPE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamVideoQPRange;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_CONFIG_VIDEO_QPRANGE_TYPE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigVideoQPRange;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_PARAM_ENABLE_BLUR_FILTER) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamEnableBlurFilter;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_CONFIG_BLUR_INFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigBlurInfo;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_PARAM_ROATION_INFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamRotationInfo;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamStoreMetaDataBuffer;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_CONFIG_VIDEO_COLOR_ASPECTS_INFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigVideoColorAspects;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_PARAM_ALLOCATE_NATIVE_HANDLE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamAllocateNativeHandle;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+#endif
+
+    ret = Exynos_OMX_GetExtensionIndex(hComponent, szParamName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+// jdkim, 20180518 patch
+OMX_ERRORTYPE Exynos_Shared_BufferToData(
+    EXYNOS_OMX_BASEPORT     *pExynosPort,
+    EXYNOS_OMX_DATABUFFER   *pUseBuffer,
+    EXYNOS_OMX_DATA         *pData)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((pExynosPort == NULL) ||
+        (pUseBuffer == NULL) ||
+        (pData == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if ((pUseBuffer->bufferHeader == NULL) ||
+        (pUseBuffer->bufferHeader->pBuffer == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pExynosPort->exceptionFlag != GENERAL_STATE) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if (pExynosPort->eMetaDataType == METADATA_TYPE_DISABLED) {
+        pData->buffer.addr[0] = pUseBuffer->bufferHeader->pBuffer;
+    } else {
+        /* metadata type */
+        EXYNOS_OMX_MULTIPLANE_BUFFER bufferInfo;
+
+        if (pExynosPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK) {
+            EXYNOS_OMX_LOCK_RANGE range;
+            OMX_U32 stride;
+
+            range.nWidth        = pExynosPort->portDefinition.format.video.nFrameWidth;
+            range.nHeight       = pExynosPort->portDefinition.format.video.nFrameHeight;
+            range.eColorFormat  = pExynosPort->portDefinition.format.video.eColorFormat;
+            stride              = range.nWidth;
+
+            ret = Exynos_OSAL_LockMetaData(pUseBuffer->bufferHeader->pBuffer,
+                                           range,
+                                           &stride, &bufferInfo,
+                                           pExynosPort->eMetaDataType);
+            if (ret != OMX_ErrorNone) {
+                /* if dataLen is zero with EOS flag, it is not an error.
+                 * in this case, buffer handle can be null by framework.
+                 */
+                if ((pUseBuffer->dataLen <= 0) &&
+                    (pUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) {
+                    pData->allocSize     = pUseBuffer->allocSize;
+                    pData->dataLen       = pUseBuffer->dataLen;
+                    pData->usedDataLen   = pUseBuffer->usedDataLen;
+                    pData->remainDataLen = pUseBuffer->remainDataLen;
+                    pData->timeStamp     = pUseBuffer->timeStamp;
+                    pData->nFlags        = pUseBuffer->nFlags;
+                    pData->pPrivate      = pUseBuffer->pPrivate;
+                    pData->bufferHeader  = pUseBuffer->bufferHeader;
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s]: Failed to Exynos_OSAL_LockMetaData() but, this buffer is for EOS handling.", __FUNCTION__);
+                    goto EXIT;
+                }
+
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s]: Failed to Exynos_OSAL_LockMetaData (err:0x%x)",
+                                    __FUNCTION__, ret);
+                goto EXIT;
+            }
+        } else {
+            ret = Exynos_OSAL_GetInfoFromMetaData(pUseBuffer->bufferHeader->pBuffer,
+                                                    &bufferInfo, pExynosPort->eMetaDataType);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s]: Failed to Exynos_OSAL_GetInfoFromMetaData (err:0x%x)",
+                                    __FUNCTION__, ret);
+                goto EXIT;
+            }
+        }
+
+        pData->buffer.addr[0] = bufferInfo.addr[0];
+        pData->buffer.addr[1] = bufferInfo.addr[1];
+        pData->buffer.addr[2] = bufferInfo.addr[2];
+
+        pData->buffer.fd[0] = bufferInfo.fd[0];
+        pData->buffer.fd[1] = bufferInfo.fd[1];
+        pData->buffer.fd[2] = bufferInfo.fd[2];
+    }
+
+    pData->allocSize     = pUseBuffer->allocSize;
+    pData->dataLen       = pUseBuffer->dataLen;
+    pData->usedDataLen   = pUseBuffer->usedDataLen;
+    pData->remainDataLen = pUseBuffer->remainDataLen;
+    pData->timeStamp     = pUseBuffer->timeStamp;
+    pData->nFlags        = pUseBuffer->nFlags;
+    pData->pPrivate      = pUseBuffer->pPrivate;
+    pData->bufferHeader  = pUseBuffer->bufferHeader;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Shared_DataToBuffer(
+    EXYNOS_OMX_BASEPORT     *pExynosPort,
+    EXYNOS_OMX_DATABUFFER   *pUseBuffer,
+    EXYNOS_OMX_DATA         *pData)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((pExynosPort == NULL) ||
+        (pUseBuffer == NULL) ||
+        (pData == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if ((pData->bufferHeader == NULL) ||
+        (pData->bufferHeader->pBuffer == NULL)) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    pUseBuffer->bufferHeader          = pData->bufferHeader;
+    pUseBuffer->allocSize             = pData->allocSize;
+    pUseBuffer->dataLen               = pData->dataLen;
+    pUseBuffer->usedDataLen           = pData->usedDataLen;
+    pUseBuffer->remainDataLen         = pData->remainDataLen;
+    pUseBuffer->timeStamp             = pData->timeStamp;
+    pUseBuffer->nFlags                = pData->nFlags;
+    pUseBuffer->pPrivate              = pData->pPrivate;
+
+    if (pExynosPort->eMetaDataType & METADATA_TYPE_BUFFER_LOCK)
+        Exynos_OSAL_UnlockMetaData(pUseBuffer->bufferHeader->pBuffer, pExynosPort->eMetaDataType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/enc/Exynos_OMX_VencControl.h b/openmax/component/video/enc/Exynos_OMX_VencControl.h
new file mode 100755 (executable)
index 0000000..985446a
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_VencControl.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.5.0
+ * @history
+ *   2012.02.20 : Create
+ *   2017.08.03 : Change event handling
+ */
+
+#ifndef EXYNOS_OMX_VIDEO_ENCODECONTROL
+#define EXYNOS_OMX_VIDEO_ENCODECONTROL
+
+#include "OMX_Component.h"
+#include "Exynos_OMX_Def.h"
+#include "Exynos_OSAL_Queue.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Basecomponent.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_ERRORTYPE Exynos_OMX_UseBuffer(
+    OMX_IN OMX_HANDLETYPE            hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32                   nPortIndex,
+    OMX_IN OMX_PTR                   pAppPrivate,
+    OMX_IN OMX_U32                   nSizeBytes,
+    OMX_IN OMX_U8                   *pBuffer);
+OMX_ERRORTYPE Exynos_OMX_AllocateBuffer(
+    OMX_IN OMX_HANDLETYPE            hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
+    OMX_IN OMX_U32                   nPortIndex,
+    OMX_IN OMX_PTR                   pAppPrivate,
+    OMX_IN OMX_U32                   nSizeBytes);
+OMX_ERRORTYPE Exynos_OMX_FreeBuffer(
+    OMX_IN OMX_HANDLETYPE        hComponent,
+    OMX_IN OMX_U32               nPortIndex,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr);
+
+#ifdef TUNNELING_SUPPORT
+OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer(
+    EXYNOS_OMX_BASEPORT *pOMXBasePort,
+    OMX_U32              nPortIndex);
+OMX_ERRORTYPE Exynos_OMX_FreeTunnelBuffer(
+    EXYNOS_OMX_BASEPORT *pOMXBasePort,
+    OMX_U32              nPortIndex);
+OMX_ERRORTYPE Exynos_OMX_ComponentTunnelRequest(
+    OMX_IN OMX_HANDLETYPE  hComp,
+    OMX_IN OMX_U32         nPort,
+    OMX_IN OMX_HANDLETYPE  hTunneledComp,
+    OMX_IN OMX_U32         nTunneledPort,
+    OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup);
+#endif
+
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure);
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure);
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure);
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure);
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetExtensionIndex(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_STRING      szParameterName,
+    OMX_OUT OMX_INDEXTYPE *pIndexType);
+
+OMX_ERRORTYPE Exynos_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *pDataBuffer);
+OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *pDataBuffer);
+
+OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent);
+
+OMX_BUFFERHEADERTYPE *Exynos_OutputBufferGetQueue_Direct(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+OMX_ERRORTYPE Exynos_InputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+OMX_ERRORTYPE Exynos_OutputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+
+OMX_ERRORTYPE Exynos_CodecBufferEnqueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex, OMX_PTR pData);
+OMX_ERRORTYPE Exynos_CodecBufferDequeue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex, OMX_PTR *pData);
+OMX_ERRORTYPE Exynos_CodecBufferReset(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex);
+
+OMX_ERRORTYPE Exynos_Shared_BufferToData(EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData);
+OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/openmax/component/video/enc/Makefile.am b/openmax/component/video/enc/Makefile.am
new file mode 100755 (executable)
index 0000000..cdb6625
--- /dev/null
@@ -0,0 +1,19 @@
+SUBDIRS = . h264 hevc mpeg4 vp8
+
+lib_LTLIBRARIES = libExynosOMX_Venc.la
+
+libExynosOMX_Venc_la_SOURCES = Exynos_OMX_Venc.c \
+                               Exynos_OMX_VencControl.c
+
+libExynosOMX_Venc_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                              $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la
+
+libExynosOMX_Venc_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                              -I$(top_srcdir)/openmax/include/exynos \
+                              -I$(top_srcdir)/openmax/osal \
+                              -I$(top_srcdir)/openmax/core \
+                              -I$(top_srcdir)/openmax/component/common \
+                              -I$(top_srcdir)/exynos/libvideocodec/include
+
+libExynosOMX_Venc_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
+libExynosOMX_Venc_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable
diff --git a/openmax/component/video/enc/h264/Exynos_OMX_H264enc.c b/openmax/component/video/enc/h264/Exynos_OMX_H264enc.c
new file mode 100755 (executable)
index 0000000..e5e9fcb
--- /dev/null
@@ -0,0 +1,4085 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_H264enc.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Venc.h"
+#include "Exynos_OMX_VencControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "Exynos_OMX_H264enc.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OSAL_Queue.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+#ifdef USE_ANDROID
+#include "VendorVideoAPI.h"
+#endif
+
+#ifdef USE_SKYPE_HD
+#include "Exynos_OSAL_SkypeHD.h"
+#endif
+
+/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
+/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_H264_ENC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc       = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Enc->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileBaseline;
+    pH264Enc->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileMain;
+    pH264Enc->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileHigh;
+    pH264Enc->hMFCH264Handle.profiles[nProfileCnt++] = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedBaseline;
+    pH264Enc->hMFCH264Handle.profiles[nProfileCnt++] = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedHigh;
+    pH264Enc->hMFCH264Handle.nProfileCnt = nProfileCnt;
+
+    switch (pH264Enc->hMFCH264Handle.videoInstInfo.HwVersion) {
+    case MFC_1220:
+    case MFC_120:
+    case MFC_110:
+    case MFC_100:
+    case MFC_101:
+        pH264Enc->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel52;
+        break;
+    case MFC_80:
+    case MFC_90:
+    case MFC_1010:
+    case MFC_1120:
+        pH264Enc->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel51;
+        break;
+    case MFC_61:
+    case MFC_65:
+    case MFC_72:
+    case MFC_723:
+    case MFC_77:
+    case MFC_1011:
+        pH264Enc->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel42;
+        break;
+    case MFC_51:
+    case MFC_78:
+    case MFC_78D:
+    case MFC_92:
+    case MFC_1020:
+    case MFC_1021:
+    default:
+        pH264Enc->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel4;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc       = NULL;
+
+    int nLevelCnt = 0;
+    OMX_U32 nMaxIndex = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pH264Enc->hMFCH264Handle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pH264Enc->hMFCH264Handle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pH264Enc->hMFCH264Handle.maxLevel;
+#else
+    while ((pH264Enc->hMFCH264Handle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+
+    if ((pH264Enc->hMFCH264Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pH264Enc->hMFCH264Handle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pH264Enc->hMFCH264Handle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : supported profile(%x), level(%x)",
+                                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc  = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc   = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL)
+        goto EXIT;
+
+    while ((pH264Enc->hMFCH264Handle.maxLevel >> nLevelCnt++) > 0);
+
+    if ((pH264Enc->hMFCH264Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pH264Enc->hMFCH264Handle.nProfileCnt; i++) {
+        if (pH264Enc->hMFCH264Handle.profiles[i] == pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    while (nLevelCnt >= 0) {
+        if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+            bLevelSupport = OMX_TRUE;
+            break;
+        }
+
+        nLevelCnt--;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_U32 OMXAVCProfileToProfileIDC(OMX_VIDEO_AVCPROFILETYPE profile)
+{
+    OMX_U32 ret = 0;
+
+    if (profile == OMX_VIDEO_AVCProfileBaseline)
+        ret = 0;
+    else if ((EXYNOS_OMX_VIDEO_AVCPROFILETYPE)profile == OMX_VIDEO_AVCProfileConstrainedBaseline)
+        ret = 1;
+    else if (profile == OMX_VIDEO_AVCProfileMain)
+        ret = 2;
+    else if (profile == OMX_VIDEO_AVCProfileHigh)
+        ret = 4;
+    else if ((EXYNOS_OMX_VIDEO_AVCPROFILETYPE)profile == OMX_VIDEO_AVCProfileConstrainedHigh)
+        ret = 17;
+
+    return ret;
+}
+
+static OMX_U32 OMXAVCLevelToLevelIDC(OMX_VIDEO_AVCLEVELTYPE level)
+{
+    OMX_U32 ret = 11; //default OMX_VIDEO_AVCLevel4
+
+    if (level == OMX_VIDEO_AVCLevel1)
+        ret = 0;
+    else if (level == OMX_VIDEO_AVCLevel1b)
+        ret = 1;
+    else if (level == OMX_VIDEO_AVCLevel11)
+        ret = 2;
+    else if (level == OMX_VIDEO_AVCLevel12)
+        ret = 3;
+    else if (level == OMX_VIDEO_AVCLevel13)
+        ret = 4;
+    else if (level == OMX_VIDEO_AVCLevel2)
+        ret = 5;
+    else if (level == OMX_VIDEO_AVCLevel21)
+        ret = 6;
+    else if (level == OMX_VIDEO_AVCLevel22)
+        ret = 7;
+    else if (level == OMX_VIDEO_AVCLevel3)
+        ret = 8;
+    else if (level == OMX_VIDEO_AVCLevel31)
+        ret = 9;
+    else if (level == OMX_VIDEO_AVCLevel32)
+        ret = 10;
+    else if (level == OMX_VIDEO_AVCLevel4)
+        ret = 11;
+    else if (level == OMX_VIDEO_AVCLevel41)
+        ret = 12;
+    else if (level == OMX_VIDEO_AVCLevel42)
+        ret = 13;
+
+    return ret;
+}
+
+static OMX_U8 *FindDelimiter(OMX_U8 *pBuffer, OMX_U32 size)
+{
+    OMX_U32 i;
+
+    for (i = 0; i < size - 3; i++) {
+        if ((pBuffer[i] == 0x00)   &&
+            (pBuffer[i + 1] == 0x00) &&
+            (pBuffer[i + 2] == 0x00) &&
+            (pBuffer[i + 3] == 0x01))
+            return (pBuffer + i);
+    }
+
+    return NULL;
+}
+
+static void Print_H264Enc_Param(ExynosVideoEncParam *pEncParam)
+{
+    ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam;
+    ExynosVideoEncH264Param   *pH264Param   = &pEncParam->codecParam.h264;
+
+    /* common parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceWidth             : %d", pCommonParam->SourceWidth);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceHeight            : %d", pCommonParam->SourceHeight);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "IDRPeriod               : %d", pCommonParam->IDRPeriod);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SliceMode               : %d", pCommonParam->SliceMode);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "RandomIntraMBRefresh    : %d", pCommonParam->RandomIntraMBRefresh);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Bitrate                 : %d", pCommonParam->Bitrate);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp                 : %d", pCommonParam->FrameQp);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp_P               : %d", pCommonParam->FrameQp_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(I) ranege            : %d / %d", pCommonParam->QpRange.QpMin_I, pCommonParam->QpRange.QpMax_I);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(P) ranege            : %d / %d", pCommonParam->QpRange.QpMin_P, pCommonParam->QpRange.QpMax_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(B) ranege            : %d / %d", pCommonParam->QpRange.QpMin_B, pCommonParam->QpRange.QpMax_B);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "PadControlOn            : %d", pCommonParam->PadControlOn);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LumaPadVal              : %d", pCommonParam->LumaPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CbPadVal                : %d", pCommonParam->CbPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CrPadVal                : %d", pCommonParam->CrPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameMap                : %d", pCommonParam->FrameMap);
+
+    /* H.264 specific parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "ProfileIDC              : %d", pH264Param->ProfileIDC);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LevelIDC                : %d", pH264Param->LevelIDC);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp_B               : %d", pH264Param->FrameQp_B);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameRate               : %d", pH264Param->FrameRate);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SliceArgument           : %d", pH264Param->SliceArgument);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumberBFrames           : %d", pH264Param->NumberBFrames);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumberReferenceFrames   : %d", pH264Param->NumberReferenceFrames);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumberRefForPframes     : %d", pH264Param->NumberRefForPframes);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LoopFilterDisable       : %d", pH264Param->LoopFilterDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LoopFilterAlphaC0Offset : %d", pH264Param->LoopFilterAlphaC0Offset);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LoopFilterBetaOffset    : %d", pH264Param->LoopFilterBetaOffset);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SymbolMode              : %d", pH264Param->SymbolMode);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "PictureInterlace        : %d", pH264Param->PictureInterlace);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "Transform8x8Mode        : %d", pH264Param->Transform8x8Mode);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "DarkDisable             : %d", pH264Param->DarkDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SmoothDisable           : %d", pH264Param->SmoothDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "StaticDisable           : %d", pH264Param->StaticDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "ActivityDisable         : %d", pH264Param->ActivityDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "HierarType:             : %d", pH264Param->HierarType);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "VuiRestrictionEnable:   : %d", pH264Param->VuiRestrictionEnable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "HeaderWithIFrame:       : %d", pH264Param->HeaderWithIFrame);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SarEnable:              : %d", pH264Param->SarEnable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SarIndex:               : %d", pH264Param->SarIndex);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SarWidth:               : %d", pH264Param->SarWidth);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SarHeight:              : %d", pH264Param->SarHeight);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LTRFrames:              : %d", pH264Param->LTRFrames);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "ROIEnable:              : %d", pH264Param->ROIEnable);
+
+    /* rate control related parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableFRMRateControl    : %d", pCommonParam->EnableFRMRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableMBRateControl     : %d", pCommonParam->EnableMBRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CBRPeriodRf             : %d", pCommonParam->CBRPeriodRf);
+}
+
+static void Set_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_BASEPORT           *pInputPort       = NULL;
+    EXYNOS_OMX_BASEPORT           *pOutputPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc         = NULL;
+    EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle   = NULL;
+    OMX_COLOR_FORMATTYPE           eColorFormat     = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncParam       *pEncParam    = NULL;
+    ExynosVideoEncCommonParam *pCommonParam = NULL;
+    ExynosVideoEncH264Param   *pH264Param   = NULL;
+
+    int i;
+
+    pVideoEnc           = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pH264Enc            = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCH264Handle      = &pH264Enc->hMFCH264Handle;
+    pInputPort          = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pOutputPort         = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    pEncParam       = &pMFCH264Handle->encParam;
+    pCommonParam    = &pEncParam->commonParam;
+    pH264Param      = &pEncParam->codecParam.h264;
+    pEncParam->eCompressionFormat = VIDEO_CODING_AVC;
+
+    /* common parameters */
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+    } else {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+    }
+    pCommonParam->IDRPeriod    = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
+    pCommonParam->SliceMode    = pH264Enc->AVCSliceFmo.eSliceMode;
+    pCommonParam->Bitrate      = pOutputPort->portDefinition.format.video.nBitrate;
+    pCommonParam->FrameQp      = pVideoEnc->quantization.nQpI;
+    pCommonParam->FrameQp_P    = pVideoEnc->quantization.nQpP;
+
+    pCommonParam->QpRange.QpMin_I = pH264Enc->qpRangeI.nMinQP;
+    pCommonParam->QpRange.QpMax_I = pH264Enc->qpRangeI.nMaxQP;
+    pCommonParam->QpRange.QpMin_P = pH264Enc->qpRangeP.nMinQP;
+    pCommonParam->QpRange.QpMax_P = pH264Enc->qpRangeP.nMaxQP;
+    pCommonParam->QpRange.QpMin_B = pH264Enc->qpRangeB.nMinQP;
+    pCommonParam->QpRange.QpMax_B = pH264Enc->qpRangeB.nMaxQP;
+
+    pCommonParam->PadControlOn = 0;    /* 0: disable, 1: enable */
+    pCommonParam->LumaPadVal   = 0;
+    pCommonParam->CbPadVal     = 0;
+    pCommonParam->CrPadVal     = 0;
+
+    if (pVideoEnc->intraRefresh.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) {
+        /* Cyclic Mode */
+        pCommonParam->RandomIntraMBRefresh = pVideoEnc->intraRefresh.nCirMBs;
+    } else {
+        /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+        pCommonParam->RandomIntraMBRefresh = 0;
+    }
+
+    /* Perceptual Mode */
+    pCommonParam->PerceptualMode = (pVideoEnc->bPVCMode)? VIDEO_TRUE:VIDEO_FALSE;
+
+    eColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+    pCommonParam->FrameMap = Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    /* H.264 specific parameters */
+    pH264Param->ProfileIDC   = OMXAVCProfileToProfileIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eProfile);    /*0: OMX_VIDEO_AVCProfileMain */
+    pH264Param->LevelIDC     = OMXAVCLevelToLevelIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eLevel);    /*40: OMX_VIDEO_AVCLevel4 */
+    pH264Param->FrameQp_B    = pVideoEnc->quantization.nQpB;
+    pH264Param->FrameRate    = (pInputPort->portDefinition.format.video.xFramerate) >> 16;
+    if (pH264Enc->AVCSliceFmo.eSliceMode == OMX_VIDEO_SLICEMODE_AVCDefault) {
+        pH264Param->SliceArgument = 0;    /* Slice mb/byte size number */
+
+        if (pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nSliceHeaderSpacing > 0) {
+            pCommonParam->SliceMode   = OMX_VIDEO_SLICEMODE_AVCMBSlice;
+            pH264Param->SliceArgument = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nSliceHeaderSpacing;
+        }
+    } else {
+        pH264Param->SliceArgument = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nSliceHeaderSpacing;
+    }
+
+    pH264Param->NumberBFrames           = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nBFrames;   /* 0 ~ 2 */
+    pH264Param->NumberRefForPframes     = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nRefFrames; /* 1 ~ 2 */
+    pH264Param->NumberReferenceFrames   = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nRefFrames;
+
+    pH264Param->LoopFilterDisable       = 0;    /* 1: Loop Filter Disable, 0: Filter Enable */
+    pH264Param->LoopFilterAlphaC0Offset = 0;
+    pH264Param->LoopFilterBetaOffset    = 0;
+    pH264Param->SymbolMode       = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].bEntropyCodingCABAC;    /* 0: CAVLC, 1: CABAC */
+    pH264Param->PictureInterlace = 0;
+    pH264Param->Transform8x8Mode = 1;    /* 0: 4x4, 1: allow 8x8 */
+    pH264Param->DarkDisable      = 1;
+    pH264Param->SmoothDisable    = 1;
+    pH264Param->StaticDisable    = 1;
+    pH264Param->ActivityDisable  = 1;
+
+    /* Temporal SVC */
+    /* If MaxTemporalLayerCount value is 0, codec supported max value will be set */
+    pH264Param->MaxTemporalLayerCount           = (unsigned int)pH264Enc->nMaxTemporalLayerCount;
+    pH264Param->TemporalSVC.nTemporalLayerCount = (unsigned int)pH264Enc->nTemporalLayerCount;
+
+#ifdef USE_SKYPE_HD
+    if (pH264Enc->hMFCH264Handle.bEnableSkypeHD == OMX_TRUE)
+        pH264Param->TemporalSVC.nTemporalLayerCount |= GENERAL_TSVC_ENABLE;  /* always uses short-term reference */
+#endif
+
+    if (pH264Enc->bUseTemporalLayerBitrateRatio == OMX_TRUE) {
+        for (i = 0; i < OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS; i++)
+            pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)pH264Enc->nTemporalLayerBitrateRatio[i];
+    } else {
+        for (i = 0; i < OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS; i++)
+            pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[i] = pOutputPort->portDefinition.format.video.nBitrate;
+    }
+
+    /* Hierarchal P & B */
+    pH264Param->HierarType = pH264Enc->hMFCH264Handle.eHierarchicalType;
+
+    /* SPS VUI */
+    if (pH264Enc->hMFCH264Handle.stSarParam.SarEnable == OMX_TRUE) {
+        pH264Param->SarEnable = 1;
+        pH264Param->SarIndex  = pH264Enc->hMFCH264Handle.stSarParam.SarIndex;
+        pH264Param->SarWidth  = pH264Enc->hMFCH264Handle.stSarParam.SarWidth;
+        pH264Param->SarHeight = pH264Enc->hMFCH264Handle.stSarParam.SarHeight;
+    } else {
+        pH264Param->SarEnable = 0;
+        pH264Param->SarIndex  = 0;
+        pH264Param->SarWidth  = 0;
+        pH264Param->SarHeight = 0;
+    }
+
+#ifdef USE_SKYPE_HD
+    if (pH264Enc->hMFCH264Handle.bLowLatency == OMX_TRUE) {
+        pH264Param->HeaderWithIFrame                = 0; /* 1: header + first frame */
+        pH264Param->LoopFilterDisable               = 0; /* 1: disable, 0: enable */
+        pH264Param->VuiRestrictionEnable            = (int)OMX_TRUE;
+        pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]  = OMX_Video_ControlRateDisable;
+        pCommonParam->EnableFRMQpControl            = 1; /* 0: Disable,  1: Per frame QP */
+    } else {
+        pH264Param->VuiRestrictionEnable = (int)OMX_FALSE;
+    }
+#endif
+
+    pH264Param->LTRFrames = pMFCH264Handle->nLTRFrames;
+
+    pH264Param->ROIEnable = (pMFCH264Handle->bRoiInfo == OMX_TRUE)? 1:0;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eControlRate: 0x%x", pExynosComponent, __FUNCTION__, pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]);
+    /* rate control related parameters */
+    switch ((int)pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) {
+    case OMX_Video_ControlRateDisable:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR");
+        pCommonParam->EnableFRMRateControl = 0;    /* 0: Disable,  1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 0;    /* 0: Disable,  1: MB level RC */
+        pCommonParam->CBRPeriodRf          = 100;
+        break;
+    case OMX_Video_ControlRateConstantVTCall:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR VT Call");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable,  1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable,  1: MB level RC */
+        pCommonParam->CBRPeriodRf          = 5;
+        pCommonParam->bFixedSlice          = VIDEO_TRUE;
+        break;
+    case OMX_Video_ControlRateConstant:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable,  1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable,  1: MB level RC */
+        pCommonParam->CBRPeriodRf          = 10;
+        break;
+    case OMX_Video_ControlRateVariable:
+    default: /*Android default */
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable,  1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable,  1: MB level RC */
+        pCommonParam->CBRPeriodRf          = 100;
+        break;
+    }
+
+//    Print_H264Enc_Param(pEncParam);
+}
+
+static OMX_ERRORTYPE Change_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = NULL;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc          = NULL;
+    EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle    = NULL;
+    OMX_PTR                        pDynamicConfigCMD = NULL;
+    OMX_PTR                        pConfigData       = NULL;
+    OMX_S32                        nCmdIndex         = 0;
+    ExynosVideoEncOps             *pEncOps           = NULL;
+    int                            nValue            = 0;
+
+    int i;
+
+    pVideoEnc       = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pH264Enc        = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCH264Handle  = &pH264Enc->hMFCH264Handle;
+    pEncOps         = pMFCH264Handle->pEncOps;
+
+    pDynamicConfigCMD = (OMX_PTR)Exynos_OSAL_Dequeue(&pExynosComponent->dynamicConfigQ);
+    if (pDynamicConfigCMD == NULL)
+        goto EXIT;
+
+    nCmdIndex   = *(OMX_S32 *)pDynamicConfigCMD;
+    pConfigData = (OMX_PTR)((OMX_U8 *)pDynamicConfigCMD + sizeof(OMX_S32));
+
+    switch ((int)nCmdIndex) {
+    case OMX_IndexConfigVideoIntraVOPRefresh:
+    {
+        nValue = VIDEO_FRAME_I;
+        pEncOps->Set_FrameType(pMFCH264Handle->hMFCHandle, nValue);
+        pVideoEnc->IntraRefreshVOP = OMX_FALSE;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] VOP Refresh", pExynosComponent, __FUNCTION__);
+    }
+        break;
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        OMX_S32 nPFrames = (*((OMX_S32 *)pConfigData)) - 1;
+
+        nValue = nPFrames + 1;
+        pEncOps->Set_IDRPeriod(pH264Enc->hMFCH264Handle.hMFCHandle, nValue);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] IDR period: %d", pExynosComponent, __FUNCTION__, nValue);
+    }
+        break;
+    case OMX_IndexConfigVideoAVCIntraPeriod:
+    {
+        OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pConfigData;
+
+        nValue = pAVCIntraPeriod->nIDRPeriod;
+        pEncOps->Set_IDRPeriod(pMFCH264Handle->hMFCHandle, nValue);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] IDR period: %d", pExynosComponent, __FUNCTION__, nValue);
+    }
+        break;
+    case OMX_IndexConfigVideoBitrate:
+    {
+        OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pConfigData;
+
+        if (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] != OMX_Video_ControlRateDisable) {
+            nValue = pConfigBitrate->nEncodeBitrate;
+            pEncOps->Set_BitRate(pH264Enc->hMFCH264Handle.hMFCHandle, nValue);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bitrate: %d", pExynosComponent, __FUNCTION__, nValue);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoFramerate:
+    {
+        OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pConfigData;
+        OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
+
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            nValue = (pConfigFramerate->xEncodeFramerate) >> 16;
+            pEncOps->Set_FrameRate(pH264Enc->hMFCH264Handle.hMFCHandle, nValue);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] framerate: %d", pExynosComponent, __FUNCTION__, nValue);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange = (OMX_VIDEO_QPRANGETYPE *)pConfigData;
+        ExynosVideoQPRange     qpRange;
+
+        qpRange.QpMin_I = pQpRange->qpRangeI.nMinQP;
+        qpRange.QpMax_I = pQpRange->qpRangeI.nMaxQP;
+        qpRange.QpMin_P = pQpRange->qpRangeP.nMinQP;
+        qpRange.QpMax_P = pQpRange->qpRangeP.nMaxQP;
+        qpRange.QpMin_B = pQpRange->qpRangeB.nMinQP;
+        qpRange.QpMax_B = pQpRange->qpRangeB.nMaxQP;
+
+        pEncOps->Set_QpRange(pMFCH264Handle->hMFCHandle, qpRange);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qp range: I(%d, %d), P(%d, %d), B(%d, %d)",
+                                    pExynosComponent, __FUNCTION__,
+                                    qpRange.QpMin_I, qpRange.QpMax_I,
+                                    qpRange.QpMin_P, qpRange.QpMax_P,
+                                    qpRange.QpMin_B, qpRange.QpMax_B);
+    }
+        break;
+    case OMX_IndexConfigOperatingRate:
+    {
+        OMX_PARAM_U32TYPE *pConfigRate = (OMX_PARAM_U32TYPE *)pConfigData;
+        OMX_U32            xFramerate  = pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.xFramerate;
+
+        if (xFramerate == 0)
+            nValue = 100;
+        else
+            nValue = (OMX_U32)((pConfigRate->nU32 / (double)xFramerate) * 100);
+
+        pEncOps->Set_QosRatio(pMFCH264Handle->hMFCHandle, nValue);
+        pVideoEnc->bQosChanged = OMX_FALSE;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qos ratio: %d", pExynosComponent, __FUNCTION__, nValue);
+    }
+        break;
+    case OMX_IndexConfigVideoTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pTemporalSVC = (EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *)pConfigData;
+        ExynosVideoQPRange qpRange;
+        TemporalLayerShareBuffer TemporalSVC;
+
+        qpRange.QpMin_I = pTemporalSVC->nMinQuantizer;
+        qpRange.QpMax_I = pTemporalSVC->nMaxQuantizer;
+        qpRange.QpMin_P = pTemporalSVC->nMinQuantizer;
+        qpRange.QpMax_P = pTemporalSVC->nMaxQuantizer;
+        qpRange.QpMin_B = pTemporalSVC->nMinQuantizer;
+        qpRange.QpMax_B = pTemporalSVC->nMaxQuantizer;
+
+        pEncOps->Set_QpRange(pMFCH264Handle->hMFCHandle, qpRange);
+        pEncOps->Set_IDRPeriod(pMFCH264Handle->hMFCHandle, pTemporalSVC->nKeyFrameInterval);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // qp range: I(%d, %d), P(%d, %d), B(%d, %d)",
+                                    pExynosComponent, __FUNCTION__,
+                                    qpRange.QpMin_I, qpRange.QpMax_I,
+                                    qpRange.QpMin_P, qpRange.QpMax_P,
+                                    qpRange.QpMin_B, qpRange.QpMax_B);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // IDR period: %d", pExynosComponent, __FUNCTION__, nValue);
+
+        /* Temporal SVC */
+        Exynos_OSAL_Memset(&TemporalSVC, 0, sizeof(TemporalLayerShareBuffer));
+
+        TemporalSVC.nTemporalLayerCount = (unsigned int)pTemporalSVC->nTemporalLayerCount;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // layer count: %d", pExynosComponent, __FUNCTION__, TemporalSVC.nTemporalLayerCount);
+
+        for (i = 0; i < OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS; i++) {
+            TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)pTemporalSVC->nTemporalLayerBitrateRatio[i];
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // bitrate ratio[%d]: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    i, TemporalSVC.nTemporalLayerBitrateRatio[i]);
+        }
+        if (pEncOps->Set_LayerChange(pMFCH264Handle->hMFCHandle, TemporalSVC) != VIDEO_ERROR_NONE)
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Not supported control: Set_LayerChange", pExynosComponent, __FUNCTION__);
+    }
+        break;
+    case OMX_IndexConfigVideoRoiInfo:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *pRoiInfo = (EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *)pConfigData;
+
+        /* ROI INFO */
+        RoiInfoShareBuffer RoiInfo;
+
+        Exynos_OSAL_Memset(&RoiInfo, 0, sizeof(RoiInfo));
+        RoiInfo.pRoiMBInfo     = (OMX_U64)(unsigned long)(((OMX_U8 *)pConfigData) + sizeof(EXYNOS_OMX_VIDEO_CONFIG_ROIINFO));
+        RoiInfo.nRoiMBInfoSize = pRoiInfo->nRoiMBInfoSize;
+        RoiInfo.nUpperQpOffset = pRoiInfo->nUpperQpOffset;
+        RoiInfo.nLowerQpOffset = pRoiInfo->nLowerQpOffset;
+        RoiInfo.bUseRoiInfo    = (pRoiInfo->bUseRoiInfo == OMX_TRUE)? VIDEO_TRUE:VIDEO_FALSE;
+
+        if (pEncOps->Set_RoiInfo(pMFCH264Handle->hMFCHandle, &RoiInfo) != VIDEO_ERROR_NONE)
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Set_RoiInfo()", pExynosComponent, __FUNCTION__);
+    }
+        break;
+    case OMX_IndexConfigIFrameRatio:
+    {
+        OMX_PARAM_U32TYPE *pIFrameRatio = (OMX_PARAM_U32TYPE *)pConfigData;
+
+        pEncOps->Set_IFrameRatio(pMFCH264Handle->hMFCHandle, pIFrameRatio->nU32);
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexConfigAndroidVideoTemporalLayering:
+    {
+        OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *pTemporalLayering = (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *)pConfigData;
+
+        TemporalLayerShareBuffer TemporalSVC;
+
+        /* Temporal SVC */
+        Exynos_OSAL_Memset(&TemporalSVC, 0, sizeof(TemporalLayerShareBuffer));
+
+        TemporalSVC.nTemporalLayerCount = (unsigned int)(pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual);
+
+        if (pTemporalLayering->bBitrateRatiosSpecified == OMX_TRUE) {
+            for (i = 0; i < (int)pH264Enc->nMaxTemporalLayerCount; i++) {
+
+                TemporalSVC.nTemporalLayerBitrateRatio[i] = (pTemporalLayering->nBitrateRatios[i] >> 16);
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // bitrate ratio[%d]: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        i, TemporalSVC.nTemporalLayerBitrateRatio[i]);
+            }
+        } else {
+            EXYNOS_OMX_BASEPORT *pOutputPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+
+            for (i = 0; i < (int)pH264Enc->nMaxTemporalLayerCount; i++) {
+                TemporalSVC.nTemporalLayerBitrateRatio[i] = pOutputPort->portDefinition.format.video.nBitrate;
+
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // bitrate ratio[%d]: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        i, TemporalSVC.nTemporalLayerBitrateRatio[i]);
+            }
+        }
+
+        if (pEncOps->Set_LayerChange(pMFCH264Handle->hMFCHandle, TemporalSVC) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Not supported control: Set_LayerChange", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Max(%d), layer(%d), B-layer(%d)", pExynosComponent, __FUNCTION__,
+                                               pH264Enc->nMaxTemporalLayerCount, TemporalSVC.nTemporalLayerCount, pTemporalLayering->nBLayerCountActual);
+    }
+        break;
+#endif
+    default:
+#ifdef USE_SKYPE_HD
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bSkypeSupport == VIDEO_TRUE) {
+            ret = Change_H264Enc_SkypeHDParam(pExynosComponent, pDynamicConfigCMD);
+            if (ret != OMX_ErrorNone)
+                goto EXIT;
+        }
+#endif
+        break;
+    }
+
+    Exynos_OSAL_Free(pDynamicConfigCMD);
+
+    Set_H264Enc_Param(pExynosComponent);
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE GetCodecOutputPrivateData(
+    OMX_PTR  pCodecBuffer,
+    OMX_PTR *pVirtAddr,
+    OMX_U32 *pDataSize)
+{
+    OMX_ERRORTYPE      ret          = OMX_ErrorNone;
+    ExynosVideoBuffer *pVideoBuffer = NULL;
+
+    if (pCodecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoBuffer = (ExynosVideoBuffer *)pCodecBuffer;
+
+    if (pVirtAddr != NULL)
+        *pVirtAddr = pVideoBuffer->planes[0].addr;
+
+    if (pDataSize != NULL)
+        *pDataSize = pVideoBuffer->planes[0].allocSize;
+
+EXIT:
+    return ret;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc       = NULL;
+    EXYNOS_OMX_BASEPORT             *pInputPort     = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL)
+        goto EXIT;
+    pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecOpen(
+    EXYNOS_H264ENC_HANDLE   *pH264Enc,
+    ExynosVideoInstInfo     *pVideoInstInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pH264Enc == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pEncOps     = (ExynosVideoEncOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncOps));
+    pInbufOps   = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+    pOutbufOps  = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+
+    if ((pEncOps == NULL) ||
+        (pInbufOps == NULL) ||
+        (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pH264Enc->hMFCH264Handle.pEncOps = pEncOps;
+    pH264Enc->hMFCH264Handle.pInbufOps = pInbufOps;
+    pH264Enc->hMFCH264Handle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pEncOps->nSize = sizeof(ExynosVideoEncOps);
+    pInbufOps->nSize = sizeof(ExynosVideoEncBufferOps);
+    pOutbufOps->nSize = sizeof(ExynosVideoEncBufferOps);
+
+    if (Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for encoder ops */
+    if ((pEncOps->Init == NULL) ||
+        (pEncOps->Finalize == NULL) ||
+        (pEncOps->Set_FrameTag == NULL) ||
+        (pEncOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pH264Enc->hMFCH264Handle.hMFCHandle = pH264Enc->hMFCH264Handle.pEncOps->Init(pVideoInstInfo);
+    if (pH264Enc->hMFCH264Handle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pEncOps != NULL) {
+            Exynos_OSAL_Free(pEncOps);
+            pH264Enc->hMFCH264Handle.pEncOps = NULL;
+        }
+
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pH264Enc->hMFCH264Handle.pInbufOps = NULL;
+        }
+
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pH264Enc->hMFCH264Handle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecClose(EXYNOS_H264ENC_HANDLE *pH264Enc)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pH264Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
+    pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
+    pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
+    pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pEncOps->Finalize(hMFCHandle);
+        hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle = NULL;
+        pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
+        pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Encoder(pEncOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps = NULL;
+    }
+
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps = NULL;
+    }
+
+    if (pEncOps != NULL) {
+        Exynos_OSAL_Free(pEncOps);
+        pEncOps = pH264Enc->hMFCH264Handle.pEncOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecStart(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
+    pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
+    pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+
+    if (nPortIndex == INPUT_PORT_INDEX)
+        pInbufOps->Run(hMFCHandle);
+    else if (nPortIndex == OUTPUT_PORT_INDEX)
+        pOutbufOps->Run(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecStop(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
+    pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
+    pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
+        pInbufOps->Stop(hMFCHandle);
+    else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
+        pOutbufOps->Stop(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecOutputBufferProcessRun(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pH264Enc->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pH264Enc->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pH264Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pH264Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecEnqueueAllBuffer(
+    OMX_COMPONENTTYPE *pOMXComponent,
+    OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc         = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle       = pH264Enc->hMFCH264Handle.hMFCHandle;
+
+    ExynosVideoEncBufferOps *pInbufOps              = pH264Enc->hMFCH264Handle.pInbufOps;
+    ExynosVideoEncBufferOps *pOutbufOps             = pH264Enc->hMFCH264Handle.pOutbufOps;
+
+    int i;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) &&
+        (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pH264Enc->bSourceStart == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)  {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoEnc->pMFCEncInputBuffer[i]->fd[0], pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pH264Enc->bDestinationStart == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoEnc->pMFCEncOutputBuffer[i]->fd[0], pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoEnc->pMFCEncOutputBuffer[i]);
+        }
+
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecSrcSetup(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc         = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle   = &pH264Enc->hMFCH264Handle;
+    void                          *hMFCHandle       = pMFCH264Handle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort       = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort      = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize     = pSrcInputData->dataLen;
+
+    ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
+    ExynosVideoEncParam     *pEncParam  = NULL;
+
+    ExynosVideoGeometry      bufferConf;
+    OMX_U32                  inputBufferNumber = 0;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pH264Enc->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pH264Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pH264Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    Set_H264Enc_Param(pExynosComponent);
+
+    pEncParam = &pMFCH264Handle->encParam;
+    if (pEncOps->Set_EncParam) {
+        if(pEncOps->Set_EncParam(pH264Enc->hMFCH264Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set encParam", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    Print_H264Enc_Param(pEncParam);
+
+    if (pMFCH264Handle->bPrependSpsPpsToIdr == OMX_TRUE) {
+        if (pEncOps->Enable_PrependSpsPpsToIdr)
+            pEncOps->Enable_PrependSpsPpsToIdr(pH264Enc->hMFCH264Handle.hMFCHandle);
+        else
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Not supported control: Enable_PrependSpsPpsToIdr", pExynosComponent, __FUNCTION__);
+    }
+
+#ifdef USE_ANDROID
+    if ((pInputPort->eMetaDataType == METADATA_TYPE_GRAPHIC) &&
+        ((pInputPort->bufferProcessType & BUFFER_SHARE) &&
+         (pSrcInputData->buffer.addr[2] != NULL))) {
+        ExynosVideoMeta *pMeta = (ExynosVideoMeta *)pSrcInputData->buffer.addr[2];
+
+        if (pMeta->eType & VIDEO_INFO_TYPE_YSUM_DATA) {
+            if (VIDEO_ERROR_NONE == pEncOps->Enable_WeightedPrediction(hMFCHandle))
+                pMFCH264Handle->bWeightedPrediction = OMX_TRUE;
+        }
+    }
+#endif
+
+#ifdef USE_ANDROID
+    if (pMFCH264Handle->videoInstInfo.supportInfo.enc.bColorAspectsSupport == VIDEO_TRUE) {
+        ExynosVideoColorAspects BSCA;
+        Exynos_OSAL_Memset(&BSCA, 0, sizeof(BSCA));
+
+        Exynos_OSAL_GetColorAspectsForBitstream(&(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].ColorAspects),
+                                                &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects));
+
+        BSCA.eRangeType     = (ExynosRangeType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nRangeType;
+        BSCA.ePrimariesType = (ExynosPrimariesType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nPrimaryType;
+        BSCA.eTransferType  = (ExynosTransferType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nTransferType;
+        BSCA.eCoeffType     = (ExynosMatrixCoeffType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nCoeffType;
+
+        pEncOps->Set_ColorAspects(hMFCHandle, &BSCA);
+    }
+#endif
+
+    /* input buffer info: only 3 config values needed */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        bufferConf.nFrameWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        bufferConf.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+        bufferConf.nStride      = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth, 16);
+    } else {
+        bufferConf.nFrameWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        bufferConf.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+        bufferConf.nStride      = ALIGN(pOutputPort->portDefinition.format.video.nFrameHeight, 16);
+    }
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+    pInbufOps->Set_Shareable(hMFCHandle);
+    inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare input buffer */
+        if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry) {
+        if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if ((pInputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pInputPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
+        /* data buffer */
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    }
+
+    pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc             = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle       = &pH264Enc->hMFCH264Handle;
+    void                          *hMFCHandle           = pMFCH264Handle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0};
+    unsigned int nDataLen[VIDEO_BUFFER_MAX_PLANES]  = {0, 0, 0};
+    int i, nOutBufSize = 0, nOutputBufferCnt = 0;
+
+    FunctionIn();
+
+    nOutBufSize = pOutputPort->portDefinition.nBufferSize;
+    if ((pOutputPort->bufferProcessType & BUFFER_COPY) ||
+        (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        /* OMX buffer is not used directly : CODEC buffer or MetaData */
+        nOutBufSize = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth *
+                            pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+    }
+
+    /* set geometry for output (dst) */
+    if (pOutbufOps->Set_Geometry) {
+        /* output buffer info: only 2 config values needed */
+        bufferConf.eCompressionFormat = VIDEO_CODING_AVC;
+        bufferConf.nSizeImage = nOutBufSize;
+        bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pOutputPort);
+
+        if (pOutbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* should be done before prepare output buffer */
+    if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY)
+        nOutputBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
+    else
+        nOutputBufferCnt = pOutputPort->portDefinition.nBufferCountActual;
+
+    if (pOutbufOps->Setup(pH264Enc->hMFCH264Handle.hMFCHandle, nOutputBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        nAllocLen[0] = nOutBufSize;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Allocate_CodecBuffers for output", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        /* Enqueue output buffer */
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
+                                (unsigned long *)pVideoEnc->pMFCEncOutputBuffer[i]->fd,
+                                pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pOutputPort),
+                                NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* Register output buffer */
+        /*************/
+        /*    TBD    */
+        /*************/
+    }
+
+    pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
+
+    if (H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = NULL;
+
+    int i;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nParamIndex %x", pExynosComponent, __FUNCTION__, (int)nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoAvc:
+    {
+        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcAVCComponent = &pH264Enc->AVCComponent[pDstAVCComponent->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstAVCComponent) + nOffset,
+                           ((char *)pSrcAVCComponent) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_AVCTYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamVideoSliceFMO:
+    {
+        OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = NULL;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pSrcSliceFmo = &pH264Enc->AVCSliceFmo;
+
+        Exynos_OSAL_Memcpy(((char *)pDstSliceFmo) + nOffset,
+                           ((char *)pSrcSliceFmo) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+            Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DRM_ENC_ROLE);
+        else
+            Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcAVCComponent = &pH264Enc->AVCComponent[pDstProfileLevel->nPortIndex];
+        pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile;
+        pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pH264Enc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pH264Enc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pH264Enc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pH264Enc->qpRangeP.nMaxQP;
+        pQpRange->qpRangeB.nMinQP = pH264Enc->qpRangeB.nMinQP;
+        pQpRange->qpRangeB.nMaxQP = pH264Enc->qpRangeB.nMaxQP;
+    }
+        break;
+    case OMX_IndexParamVideoAVCEnableTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC *pDstEnableTemporalSVC = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstEnableTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstEnableTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstEnableTemporalSVC->bEnableTemporalSVC = pH264Enc->hMFCH264Handle.bTemporalSVC;
+    }
+        break;
+    case OMX_IndexParamVideoEnableRoiInfo:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *pDstEnableRoiInfo = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstEnableRoiInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstEnableRoiInfo->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstEnableRoiInfo->bEnableRoiInfo = pH264Enc->hMFCH264Handle.bRoiInfo;
+    }
+        break;
+    case OMX_IndexParamVideoEnablePVC:
+    {
+        OMX_PARAM_U32TYPE *pEnablePVC = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pEnablePVC, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pEnablePVC->nU32 = pVideoEnc->bPVCMode;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamAndroidVideoTemporalLayering:
+    {
+        OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalLayering = (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pTemporalLayering, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pTemporalLayering->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) {
+            pTemporalLayering->eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternNone;
+            pTemporalLayering->nLayerCountMax     = 1;  /* not supported */
+            pTemporalLayering->nBLayerCountMax    = 0;
+            pTemporalLayering->ePattern           = OMX_VIDEO_AndroidTemporalLayeringPatternNone;
+        } else {
+            pTemporalLayering->eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+
+            if (pH264Enc->hMFCH264Handle.bTemporalSVC == OMX_TRUE) {  /* already enabled */
+                pTemporalLayering->nLayerCountMax   = pH264Enc->nMaxTemporalLayerCount;
+                pTemporalLayering->nBLayerCountMax  = pH264Enc->nMaxTemporalLayerCountForB;
+                pTemporalLayering->ePattern         = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+            } else {
+                pTemporalLayering->nLayerCountMax   = OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS;
+                pTemporalLayering->nBLayerCountMax  = OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS_FOR_B;
+                pTemporalLayering->ePattern         = OMX_VIDEO_AndroidTemporalLayeringPatternNone;
+            }
+        }
+
+        pTemporalLayering->nPLayerCountActual = pH264Enc->nTemporalLayerCount;
+        pTemporalLayering->nBLayerCountActual = pH264Enc->nTemporalLayerCountForB;
+
+        pTemporalLayering->bBitrateRatiosSpecified = pH264Enc->bUseTemporalLayerBitrateRatio;
+        if (pTemporalLayering->bBitrateRatiosSpecified == OMX_TRUE) {
+            for (i = 0; i < OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS; i++)
+                pTemporalLayering->nBitrateRatios[i] = (pH264Enc->nTemporalLayerBitrateRatio[i] << 16);
+        }
+    }
+        break;
+#endif
+    default:
+#ifdef USE_SKYPE_HD
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bSkypeSupport == VIDEO_TRUE) {
+            ret = Exynos_H264Enc_GetParameter_SkypeHD(hComponent, nParamIndex, pComponentParameterStructure);
+            if (ret == OMX_ErrorNone)
+                goto EXIT;
+        }
+#endif
+        ret = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = NULL;
+
+    int i;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoAvc:
+    {
+        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
+        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstAVCComponent = &pH264Enc->AVCComponent[pSrcAVCComponent->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstAVCComponent) + nOffset,
+                           ((char *)pSrcAVCComponent) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_AVCTYPE) - nOffset);
+
+        if (pDstAVCComponent->nBFrames > 2) {  /* 0 ~ 2 */
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] nBFrames(%d) is over a maximum value(2). it is limited to max",
+                                                    pExynosComponent, __FUNCTION__, pDstAVCComponent->nBFrames);
+            pDstAVCComponent->nBFrames = 2;
+        }
+
+        if (pDstAVCComponent->nRefFrames > 2) {  /* 1 ~ 2 */
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] nRefFrames(%d) is over a maximum value(2). it is limited to max",
+                                                    pExynosComponent, __FUNCTION__, pDstAVCComponent->nRefFrames);
+            pDstAVCComponent->nRefFrames = 2;
+        } else if (pDstAVCComponent->nRefFrames == 0) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] nRefFrames(%d) is smaller than minimum value(1). it is limited to min",
+                                                    pExynosComponent, __FUNCTION__, pDstAVCComponent->nRefFrames);
+            pDstAVCComponent->nRefFrames = 1;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoSliceFMO:
+    {
+        OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = NULL;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pDstSliceFmo = &pH264Enc->AVCSliceFmo;
+
+        Exynos_OSAL_Memcpy(((char *)pDstSliceFmo) + nOffset,
+                           ((char *)pSrcSliceFmo) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE) ||
+            !Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DRM_ENC_ROLE)) {
+            pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCTYPE          *pDstAVCComponent = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstAVCComponent = &pH264Enc->AVCComponent[pSrcProfileLevel->nPortIndex];
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile;
+        pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP) ||
+            (pQpRange->qpRangeB.nMinQP > pQpRange->qpRangeB.nMaxQP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d], B[min:%d, max:%d])", __FUNCTION__,
+                            pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                            pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP,
+                            pQpRange->qpRangeB.nMinQP, pQpRange->qpRangeB.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pH264Enc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pH264Enc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pH264Enc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pH264Enc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+        pH264Enc->qpRangeB.nMinQP = pQpRange->qpRangeB.nMinQP;
+        pH264Enc->qpRangeB.nMaxQP = pQpRange->qpRangeB.nMaxQP;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamPrependSPSPPSToIDR:
+    {
+        ret = Exynos_OSAL_SetPrependSPSPPSToIDR(pComponentParameterStructure, &(pH264Enc->hMFCH264Handle.bPrependSpsPpsToIdr));
+    }
+        break;
+    case OMX_IndexParamAndroidVideoTemporalLayering:
+    {
+        OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalLayering = (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pTemporalLayering, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pTemporalLayering->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pTemporalLayering->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternNone) {
+            /* ENABLE */
+            if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] Temporal SVC is not supported", pExynosComponent, __FUNCTION__);
+                ret = OMX_ErrorUnsupportedIndex;
+                goto EXIT;
+            }
+
+            if (pTemporalLayering->nLayerCountMax > OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] total layer : Max value(%d) > supportable Max value(%d)",
+                                        pExynosComponent, __FUNCTION__, pTemporalLayering->nLayerCountMax, OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS);
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+            }
+
+            if (pTemporalLayering->nBLayerCountMax > OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS_FOR_B) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] B layer : Max value(%d) > supportable Max value(%d)",
+                                        pExynosComponent, __FUNCTION__, pTemporalLayering->nBLayerCountMax, OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS_FOR_B);
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+            }
+
+            pH264Enc->hMFCH264Handle.bTemporalSVC = OMX_TRUE;
+            pH264Enc->nMaxTemporalLayerCount      = pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual;
+            pH264Enc->nMaxTemporalLayerCountForB  = pTemporalLayering->nBLayerCountActual;
+            pH264Enc->nTemporalLayerCount         = pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual;
+            pH264Enc->nTemporalLayerCountForB     = pTemporalLayering->nBLayerCountActual;
+
+            pH264Enc->bUseTemporalLayerBitrateRatio = pTemporalLayering->bBitrateRatiosSpecified;
+            if (pH264Enc->bUseTemporalLayerBitrateRatio == OMX_TRUE) {
+                for (i = 0; i < (int)pH264Enc->nMaxTemporalLayerCount; i++)
+                    pH264Enc->nTemporalLayerBitrateRatio[i] = (pTemporalLayering->nBitrateRatios[i] >> 16);
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Max(%d), B-Max(%d), layer(%d), B-layer(%d)", pExynosComponent, __FUNCTION__,
+                                                    pH264Enc->nMaxTemporalLayerCount, pH264Enc->nMaxTemporalLayerCountForB,
+                                                    pH264Enc->nTemporalLayerCount, pH264Enc->nTemporalLayerCountForB);
+        } else {
+            /* DISABLE */
+            pH264Enc->hMFCH264Handle.bTemporalSVC   = OMX_FALSE;
+            pH264Enc->nMaxTemporalLayerCount        = 0;
+            pH264Enc->nMaxTemporalLayerCountForB    = 0;
+            pH264Enc->nTemporalLayerCount           = 0;
+            pH264Enc->nTemporalLayerCountForB       = 0;
+            pH264Enc->bUseTemporalLayerBitrateRatio = OMX_FALSE;
+            Exynos_OSAL_Memset(pH264Enc->nTemporalLayerBitrateRatio, 0, sizeof(pH264Enc->nTemporalLayerBitrateRatio));
+        }
+    }
+        break;
+#endif
+    case OMX_IndexParamVideoAVCEnableTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC   *pSrcEnableTemporalSVC  = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC *)pComponentParameterStructure;
+        OMX_PARAM_PORTDEFINITIONTYPE                *pPortDef               = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition);
+        int i;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcEnableTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcEnableTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) &&
+            (pSrcEnableTemporalSVC->bEnableTemporalSVC == OMX_TRUE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Temporal SVC is not supported", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        if ((pSrcEnableTemporalSVC->bEnableTemporalSVC == OMX_TRUE) &&
+            (pH264Enc->hMFCH264Handle.bTemporalSVC == OMX_FALSE)) {
+            /* ENABLE : not initialized yet */
+            pH264Enc->hMFCH264Handle.bTemporalSVC   = OMX_TRUE;
+            pH264Enc->nMaxTemporalLayerCount        = OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS;
+            pH264Enc->nMaxTemporalLayerCountForB    = OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS_FOR_B;
+            pH264Enc->nTemporalLayerCount           = 1;
+            pH264Enc->nTemporalLayerCountForB       = 0;
+            pH264Enc->bUseTemporalLayerBitrateRatio = OMX_TRUE;
+            pH264Enc->nTemporalLayerBitrateRatio[0] = pPortDef->format.video.nBitrate;
+        } else if (pSrcEnableTemporalSVC->bEnableTemporalSVC == OMX_FALSE) {
+            /* DISABLE */
+            pH264Enc->hMFCH264Handle.bTemporalSVC   = OMX_FALSE;  /* DISABLE */
+            pH264Enc->nMaxTemporalLayerCount        = 0;
+            pH264Enc->nMaxTemporalLayerCountForB    = 0;
+            pH264Enc->nTemporalLayerCount           = 0;
+            pH264Enc->nTemporalLayerCountForB       = 0;
+            pH264Enc->bUseTemporalLayerBitrateRatio = OMX_FALSE;
+            Exynos_OSAL_Memset(pH264Enc->nTemporalLayerBitrateRatio, 0, sizeof(pH264Enc->nTemporalLayerBitrateRatio));
+        }
+    }
+        break;
+    case OMX_IndexParamVideoEnableRoiInfo:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *pSrcEnableRoiInfo = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcEnableRoiInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcEnableRoiInfo->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bRoiInfoSupport == VIDEO_FALSE) &&
+            (pSrcEnableRoiInfo->bEnableRoiInfo == OMX_TRUE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Roi Info is not supported", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        pH264Enc->hMFCH264Handle.bRoiInfo = pSrcEnableRoiInfo->bEnableRoiInfo;
+    }
+        break;
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE    *pPortDef       = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
+        OMX_U32                          nPortIndex     = pPortDef->nPortIndex;
+        EXYNOS_OMX_BASEPORT             *pExynosPort    = &pExynosComponent->pExynosPort[nPortIndex];;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        if (pPortDef->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if ((nPortIndex == INPUT_PORT_INDEX) &&
+            ((pPortDef->format.video.xFramerate >> 16) <= 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] xFramerate is invalid(%d)",
+                                              pExynosComponent, __FUNCTION__, pPortDef->format.video.xFramerate >> 16);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Memcpy(((char *)&pExynosPort->portDefinition) + nOffset,
+                           ((char *)pPortDef) + nOffset,
+                           pPortDef->nSize - nOffset);
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            if (pVideoEnc->bFirstInput == OMX_FALSE)
+                pVideoEnc->bEncDRC = OMX_TRUE;
+
+            pVideoEnc->bFirstInput = OMX_TRUE;
+            pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] pOutputPort->portDefinition.nBufferSize: %d", pExynosComponent, __FUNCTION__, pExynosPort->portDefinition.nBufferSize);
+        } else if (nPortIndex == OUTPUT_PORT_INDEX) {
+            pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoEnablePVC:
+    {
+        OMX_PARAM_U32TYPE *pEnablePVC  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pEnablePVC, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bPVCSupport == VIDEO_FALSE) &&
+            (pEnablePVC->nU32 != 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] PVC mode is not supported", pExynosComponent, __FUNCTION__);
+        }
+
+        pVideoEnc->bPVCMode = (pEnablePVC->nU32 != 0)? OMX_TRUE:OMX_FALSE;
+    }
+        break;
+    default:
+#ifdef USE_SKYPE_HD
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bSkypeSupport == VIDEO_TRUE) {
+            ret = Exynos_H264Enc_SetParameter_SkypeHD(hComponent, nIndex, pComponentParameterStructure);
+            if (ret == OMX_ErrorNone)
+                goto EXIT;
+        }
+#endif
+        ret = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_GetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = NULL;
+
+    int i;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoAVCIntraPeriod:
+    {
+        OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
+        OMX_U32                          portIndex       = pAVCIntraPeriod->nPortIndex;
+
+        if ((portIndex != OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pAVCIntraPeriod->nIDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
+            pAVCIntraPeriod->nPFrames = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames;
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pH264Enc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pH264Enc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pH264Enc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pH264Enc->qpRangeP.nMaxQP;
+        pQpRange->qpRangeB.nMinQP = pH264Enc->qpRangeB.nMinQP;
+        pQpRange->qpRangeB.nMaxQP = pH264Enc->qpRangeB.nMaxQP;
+    }
+        break;
+    case OMX_IndexConfigVideoTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pDstTemporalSVC = (EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *)pComponentConfigStructure;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstTemporalSVC->nKeyFrameInterval   = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
+        pDstTemporalSVC->nMinQuantizer       = pH264Enc->qpRangeI.nMinQP;
+        pDstTemporalSVC->nMaxQuantizer       = pH264Enc->qpRangeI.nMaxQP;
+        pDstTemporalSVC->nTemporalLayerCount = pH264Enc->nTemporalLayerCount;
+        for (i = 0; i < OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS; i++)
+            pDstTemporalSVC->nTemporalLayerBitrateRatio[i] = pH264Enc->nTemporalLayerBitrateRatio[i];
+    }
+        break;
+    default:
+#ifdef USE_SKYPE_HD
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bSkypeSupport == VIDEO_TRUE) {
+            ret = Exynos_H264Enc_GetConfig_SkypeHD(hComponent, nIndex, pComponentConfigStructure);
+            if (ret == OMX_ErrorNone)
+                goto EXIT;
+        }
+#endif
+        ret = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_SetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = NULL;
+
+    int i;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1;
+        pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = nPFrames;
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexConfigVideoAVCIntraPeriod:
+    {
+        OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
+        OMX_U32                          portIndex       = pAVCIntraPeriod->nPortIndex;
+
+        if ((portIndex != OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            if (pAVCIntraPeriod->nIDRPeriod == (pAVCIntraPeriod->nPFrames + 1))
+                pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = pAVCIntraPeriod->nPFrames;
+            else {
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+            }
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP) ||
+            (pQpRange->qpRangeB.nMinQP > pQpRange->qpRangeB.nMaxQP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d], B[min:%d, max:%d])",
+                            pExynosComponent, __FUNCTION__,
+                            pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                            pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP,
+                            pQpRange->qpRangeB.nMinQP, pQpRange->qpRangeB.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_FALSE)
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] only I-frame's QP range is applied", pExynosComponent, __FUNCTION__);
+
+        pH264Enc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pH264Enc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pH264Enc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pH264Enc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+        pH264Enc->qpRangeB.nMinQP = pQpRange->qpRangeB.nMinQP;
+        pH264Enc->qpRangeB.nMaxQP = pQpRange->qpRangeB.nMaxQP;
+    }
+        break;
+    case OMX_IndexConfigVideoTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pSrcTemporalSVC = (EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *)pComponentConfigStructure;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pH264Enc->hMFCH264Handle.bTemporalSVC == OMX_FALSE) ||
+            (pSrcTemporalSVC->nTemporalLayerCount > OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = pSrcTemporalSVC->nKeyFrameInterval - 1;
+
+        pH264Enc->qpRangeI.nMinQP = pSrcTemporalSVC->nMinQuantizer;
+        pH264Enc->qpRangeI.nMaxQP = pSrcTemporalSVC->nMaxQuantizer;
+        pH264Enc->qpRangeP.nMinQP = pSrcTemporalSVC->nMinQuantizer;
+        pH264Enc->qpRangeP.nMaxQP = pSrcTemporalSVC->nMaxQuantizer;
+        pH264Enc->qpRangeB.nMinQP = pSrcTemporalSVC->nMinQuantizer;
+        pH264Enc->qpRangeB.nMaxQP = pSrcTemporalSVC->nMaxQuantizer;
+
+        pH264Enc->nTemporalLayerCount = pSrcTemporalSVC->nTemporalLayerCount;
+        for (i = 0; i < OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS; i++)
+            pH264Enc->nTemporalLayerBitrateRatio[i] = pSrcTemporalSVC->nTemporalLayerBitrateRatio[i];
+
+    }
+        break;
+    case OMX_IndexConfigVideoRoiInfo:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *pRoiInfo = (EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *)pComponentConfigStructure;
+
+        if (pRoiInfo->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pH264Enc->hMFCH264Handle.bRoiInfo == OMX_FALSE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] RoiInfo is not enabled", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if ((pRoiInfo->bUseRoiInfo == OMX_TRUE) &&
+            ((pRoiInfo->nRoiMBInfoSize <= 0) || (pRoiInfo->pRoiMBInfo == NULL))) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] parameter is invalid : nRoiMBInfoSize(%d)/pRoiMBInfo(%p)",
+                                pExynosComponent, __FUNCTION__, pRoiInfo->nRoiMBInfoSize, pRoiInfo->pRoiMBInfo);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexConfigIFrameRatio:
+    {
+        OMX_PARAM_U32TYPE *pIFrameRatio = (OMX_PARAM_U32TYPE *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pIFrameRatio, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pIFrameRatio->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bIFrameRatioSupport == VIDEO_FALSE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] I-Frame ratio feature is not supported", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorNoneExpiration;
+            goto EXIT;
+        }
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexConfigAndroidVideoTemporalLayering:
+    {
+        OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *pTemporalLayering = (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pTemporalLayering, sizeof(OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pTemporalLayering->nPortIndex != OUTPUT_PORT_INDEX) ||
+            (pH264Enc->hMFCH264Handle.bTemporalSVC == OMX_FALSE)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pTemporalLayering->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] can not disable TemporalSVC while encoding", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if (((pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual) > pH264Enc->nMaxTemporalLayerCount) ||
+            ((pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual) == 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] layer count is invalid(MAX(%d), layer(%d), B-layer(%d))",
+                                    pExynosComponent, __FUNCTION__,
+                                    pH264Enc->nMaxTemporalLayerCount,
+                                    pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual,
+                                    pTemporalLayering->nBLayerCountActual);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pH264Enc->nTemporalLayerCount     = pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual;
+        pH264Enc->nTemporalLayerCountForB = pTemporalLayering->nBLayerCountActual;
+
+        pH264Enc->bUseTemporalLayerBitrateRatio = pTemporalLayering->bBitrateRatiosSpecified;
+        if (pH264Enc->bUseTemporalLayerBitrateRatio == OMX_TRUE) {
+            for (i = 0; i < (int)pH264Enc->nMaxTemporalLayerCount; i++)
+                pH264Enc->nTemporalLayerBitrateRatio[i] = (pTemporalLayering->nBitrateRatios[i] >> 16);
+        } else {
+            Exynos_OSAL_Memset(pH264Enc->nTemporalLayerBitrateRatio, 0, sizeof(pH264Enc->nTemporalLayerBitrateRatio));
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Max(%d), layer(%d), B-layer(%d)", pExynosComponent, __FUNCTION__,
+                                               pH264Enc->nMaxTemporalLayerCount, pH264Enc->nTemporalLayerCount, pH264Enc->nTemporalLayerCountForB);
+    }
+        break;
+#endif
+    default:
+#ifdef USE_SKYPE_HD
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bSkypeSupport == VIDEO_TRUE) {
+            ret = Exynos_H264Enc_SetConfig_SkypeHD(hComponent, nIndex, pComponentConfigStructure);
+            if (ret == OMX_ErrorNone)
+                goto EXIT;
+        }
+#endif
+        ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    if (ret == OMX_ErrorNone) {
+        OMX_PTR pDynamicConfigCMD = NULL;
+        pDynamicConfigCMD = Exynos_OMX_MakeDynamicConfig(nIndex, pComponentConfigStructure);
+        Exynos_OSAL_Queue(&pExynosComponent->dynamicConfigQ, (void *)pDynamicConfigCMD);
+    }
+
+    if (ret == (OMX_ERRORTYPE)OMX_ErrorNoneExpiration)
+        ret = OMX_ErrorNone;
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_GetExtensionIndex(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE *pIndexType)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_TEMPORALSVC) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexConfigVideoTemporalSVC;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_VIDEO_AVC_ENABLE_TEMPORALSVC) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamVideoAVCEnableTemporalSVC;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_ROIINFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexConfigVideoRoiInfo;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_VIDEO_ENABLE_ROIINFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamVideoEnableRoiInfo;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_PVC) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamVideoEnablePVC;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_IFRAME_RATIO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexConfigIFrameRatio;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamPrependSPSPPSToIDR;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+#endif
+
+    ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_ComponentRoleEnum(
+    OMX_HANDLETYPE   hComponent,
+    OMX_U8          *cRole,
+    OMX_U32          nIndex)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) || (cRole == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+        if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+            Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_DRM_ENC_ROLE);
+        else
+            Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE);
+
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorNoMore;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_H264ENC_HANDLE       *pMFCH264Handle     = &pH264Enc->hMFCH264Handle;
+    OMX_COLOR_FORMATTYPE             eColorFormat       = pInputPort->portDefinition.format.video.eColorFormat;
+
+    ExynosVideoInstInfo *pVideoInstInfo = &(pH264Enc->hMFCH264Handle.videoInstInfo);
+
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+
+    FunctionIn();
+
+    pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
+    pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
+    pVideoEnc->bFirstInput  = OMX_TRUE;
+    pVideoEnc->bFirstOutput = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+    if (pInputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+        /* metadata buffer */
+        pInputPort->bufferProcessType = BUFFER_SHARE;
+
+#ifdef USE_ANDROID
+        if ((pInputPort->eMetaDataType == METADATA_TYPE_DATA) &&
+            (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)) {
+            pInputPort->eMetaDataType     = METADATA_TYPE_GRAPHIC;  /* AndoridOpaque means GrallocSource */
+            pInputPort->bufferProcessType = BUFFER_COPY;  /* will determine a process type after getting a hal format at handle */
+        }
+#else
+        if (pInputPort->eMetaDataType == METADATA_TYPE_UBM_BUFFER) {
+            pInputPort->bufferProcessType = BUFFER_COPY;
+        }
+#endif
+    } else {
+        /* data buffer */
+        pInputPort->bufferProcessType = BUFFER_COPY;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                            pInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                            pInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                            pInputPort->portDefinition.format.video.nBitrate,
+                                                                                            pInputPort->portDefinition.format.video.xFramerate);
+    pVideoInstInfo->nSize        = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth       = pInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight      = pInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate     = pInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate   = pInputPort->portDefinition.format.video.xFramerate;
+
+    /* H.264 Codec Open */
+    ret = H264CodecOpen(pH264Enc, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    Exynos_SetPlaneToPort(pOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+
+    Exynos_OSAL_SemaphoreCreate(&pInputPort->codecSemID);
+    Exynos_OSAL_QueueCreate(&pInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pH264Enc->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pH264Enc->hSourceStartEvent);
+    pH264Enc->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pH264Enc->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pH264Enc->hDestinationOutStartEvent);
+
+    Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pH264Enc->hMFCH264Handle.indexTimestamp       = 0;
+    pH264Enc->hMFCH264Handle.outputIndexTimestamp = 0;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pH264Enc->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC) {
+        pVideoEnc->csc_handle = csc_init(CSC_METHOD_HW);
+        csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2);
+        csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_MODE_DRM, 1);
+    } else {
+        pVideoEnc->csc_handle = csc_init(csc_method);
+    }
+    if (pVideoEnc->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVideoEnc->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    FunctionIn();
+
+    if (pVideoEnc->csc_handle != NULL) {
+        csc_deinit(pVideoEnc->csc_handle);
+        pVideoEnc->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pH264Enc->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pH264Enc->hDestinationInStartEvent);
+    pH264Enc->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pH264Enc->hDestinationOutStartEvent);
+    pH264Enc->hDestinationOutStartEvent = NULL;
+    pH264Enc->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pH264Enc->hSourceStartEvent);
+    pH264Enc->hSourceStartEvent = NULL;
+    pH264Enc->bSourceStart = OMX_FALSE;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pOutputPort->codecSemID);
+        pOutputPort->codecSemID = NULL;
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+    } else if (pInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_OSAL_QueueTerminate(&pInputPort->codecBufferQ);
+    Exynos_OSAL_SemaphoreTerminate(pInputPort->codecSemID);
+    pInputPort->codecSemID = NULL;
+
+    H264CodecClose(pH264Enc);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_SrcIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc         = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle       = pH264Enc->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort       = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+    OMX_COLOR_FORMATTYPE           inputColorFormat  = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncOps       *pEncOps     = pH264Enc->hMFCH264Handle.pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps   = pH264Enc->hMFCH264Handle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]   = {0, 0, 0};
+    int i, nPlaneCnt, nConfigCnt;
+
+    FunctionIn();
+
+    if (pH264Enc->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
+        if ((ret != OMX_ErrorNone) ||
+            ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to H264CodecSrcSetup(0x%x)",
+                                                pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+    }
+    if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
+        ret = H264CodecDstSetup(pOMXComponent);
+
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to H264CodecDstSetup(0x%x)",
+                                                pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+    }
+
+#ifdef USE_SKYPE_HD
+    if ((pH264Enc->hMFCH264Handle.bEnableSkypeHD == OMX_TRUE) &&
+        (pSrcInputData->dataLen > 0)) {
+        do {
+            /* process dynamic control until meet input trigger.
+             * if there are several input triggers, do process until empty.
+             */
+            ret = Change_H264Enc_Param(pExynosComponent);
+        } while (ret == OMX_ErrorNone);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] all config messages were handled", pExynosComponent, __FUNCTION__);
+    } else
+#endif
+    {
+        nConfigCnt = Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ);
+        if (nConfigCnt > 0) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] has config message(%d)", pExynosComponent, __FUNCTION__, nConfigCnt);
+            while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+                Change_H264Enc_Param(pExynosComponent);
+            }
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] all config messages were handled", pExynosComponent, __FUNCTION__);
+        }
+    }
+
+    if ((pSrcInputData->dataLen > 0) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+        pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp]            = pSrcInputData->timeStamp;
+        pExynosComponent->bTimestampSlotUsed[pH264Enc->hMFCH264Handle.indexTimestamp]   = OMX_TRUE;
+        pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp]               = pSrcInputData->nFlags;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), Tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pH264Enc->hMFCH264Handle.indexTimestamp);
+        pEncOps->Set_FrameTag(hMFCHandle, pH264Enc->hMFCH264Handle.indexTimestamp);
+        pH264Enc->hMFCH264Handle.indexTimestamp++;
+        pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        inputColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+        if ((pVideoEnc->eRotationType == ROTATE_0) ||
+            (pVideoEnc->eRotationType == ROTATE_180)) {
+            Exynos_OSAL_GetPlaneSize(inputColorFormat,
+                                     pInputPort->ePlaneType,
+                                     pInputPort->portDefinition.format.video.nFrameWidth,
+                                     pInputPort->portDefinition.format.video.nFrameHeight,
+                                     nDataLen,
+                                     nAllocLen);
+        } else {
+            Exynos_OSAL_GetPlaneSize(inputColorFormat,
+                                     pInputPort->ePlaneType,
+                                     pInputPort->portDefinition.format.video.nFrameHeight,
+                                     pInputPort->portDefinition.format.video.nFrameWidth,
+                                     nDataLen,
+                                     nAllocLen);
+        }
+
+        if (pInputPort->bufferProcessType == BUFFER_COPY) {
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        } else {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        }
+
+        nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+        if (pVideoEnc->nInbufSpareSize > 0) {
+            for (i = 0; i < nPlaneCnt; i++)
+                nAllocLen[i] = nAllocLen[i] + pVideoEnc->nInbufSpareSize;
+        }
+
+        if (pSrcInputData->dataLen == 0) {
+            for (i = 0; i < nPlaneCnt; i++)
+                nDataLen[i] = 0;
+        }
+#ifdef USE_ANDROID
+          else {
+            /* when having valid input */
+            if ((pH264Enc->hMFCH264Handle.bWeightedPrediction == OMX_TRUE) &&
+                (pSrcInputData->buffer.addr[2] != NULL)) {
+                ExynosVideoMeta *pVideoMeta = (ExynosVideoMeta *)pSrcInputData->buffer.addr[2];
+
+                if (pVideoMeta->eType & VIDEO_INFO_TYPE_YSUM_DATA) {
+                    codecReturn = pEncOps->Set_YSumData(hMFCHandle, pVideoMeta->data.enc.sYsumData.high,
+                                                        pVideoMeta->data.enc.sYsumData.low);
+                    if (codecReturn != VIDEO_ERROR_NONE)
+                        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Failed to Set_YSumData()", pExynosComponent, __FUNCTION__);
+                }
+            }
+        }
+#endif
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                    (void **)pSrcInputData->buffer.addr,
+                                    (unsigned long *)pSrcInputData->buffer.fd,
+                                    nAllocLen,
+                                    nDataLen,
+                                    nPlaneCnt,
+                                    pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+            goto EXIT;
+        }
+
+        H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        if (pH264Enc->bSourceStart == OMX_FALSE) {
+            pH264Enc->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
+            (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE)) {
+            pH264Enc->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pH264Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pH264Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_SrcOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                            *hMFCHandle         = pH264Enc->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pInbufOps      = pH264Enc->hMFCH264Handle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->allocSize     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->pPrivate = NULL;
+    } else {
+        int plane = 0, nPlaneCnt;
+        nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+        for (plane = 0; plane < nPlaneCnt; plane++) {
+            pSrcOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+            pSrcOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+            pSrcOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        }
+
+        if (pInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] ==
+                        pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) {
+                    pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_DstIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc             = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle           = pH264Enc->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pOutbufOps  = pH264Enc->hMFCH264Handle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0};
+    unsigned int nDataLen[VIDEO_BUFFER_MAX_PLANES]  = {0, 0, 0};
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    nAllocLen[0] = pOutputPort->portDefinition.nBufferSize;
+    if ((pOutputPort->bufferProcessType & BUFFER_COPY) ||
+        (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        /* OMX buffer is not used directly : CODEC buffer or MetaData */
+        nAllocLen[0] = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth * pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pOutputPort),
+                                pDstInputData->bufferHeader);
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                            pExynosComponent, __FUNCTION__, codecReturn);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+        goto EXIT;
+    }
+
+    H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_DstOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc         = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort      = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    void                          *hMFCHandle       = pH264Enc->hMFCH264Handle.hMFCHandle;
+
+    ExynosVideoEncOps          *pEncOps        = pH264Enc->hMFCH264Handle.pEncOps;
+    ExynosVideoEncBufferOps    *pOutbufOps     = pH264Enc->hMFCH264Handle.pOutbufOps;
+    ExynosVideoBuffer          *pVideoBuffer   = NULL;
+    ExynosVideoBuffer           videoBuffer;
+    ExynosVideoErrorType        codecReturn    = VIDEO_ERROR_NONE;
+
+    OMX_S32 indexTimestamp = 0;
+
+    FunctionIn();
+
+    if (pH264Enc->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+    if (codecReturn == VIDEO_ERROR_NONE) {
+        pVideoBuffer = &videoBuffer;
+    } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO)", pExynosComponent, __FUNCTION__);
+        pVideoBuffer = NULL;
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    } else {
+        pVideoBuffer = NULL;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pH264Enc->hMFCH264Handle.outputIndexTimestamp++;
+    pH264Enc->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+    pDstOutputData->buffer.addr[0]  = pVideoBuffer->planes[0].addr;
+    pDstOutputData->buffer.fd[0]    = pVideoBuffer->planes[0].fd;
+
+    pDstOutputData->allocSize       = pVideoBuffer->planes[0].allocSize;
+    pDstOutputData->dataLen         = pVideoBuffer->planes[0].dataSize;
+    pDstOutputData->remainDataLen   = pVideoBuffer->planes[0].dataSize;
+    pDstOutputData->usedDataLen     = 0;
+
+    pDstOutputData->pPrivate        = pVideoBuffer;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+            goto EXIT;
+        }
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+    if (pVideoEnc->bFirstOutput == OMX_FALSE) {
+        if (pExynosComponent->codecType != HW_VIDEO_ENC_SECURE_CODEC) {
+            OMX_U8 *p = NULL;
+            OMX_U32 iSpsSize = 0;
+            OMX_U32 iPpsSize = 0;
+
+            /* start header return */
+            /* Calculate sps/pps size if needed */
+            p = FindDelimiter((OMX_U8 *)((char *)pDstOutputData->buffer.addr[0] + 4),
+                                pDstOutputData->dataLen - 4);
+
+            iSpsSize = PTR_TO_INT((p - (OMX_U8 *)pDstOutputData->buffer.addr[0]));
+            pH264Enc->hMFCH264Handle.headerData.pHeaderSPS =
+                (OMX_PTR)pDstOutputData->buffer.addr[0];
+            pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize;
+
+            iPpsSize = pDstOutputData->dataLen - iSpsSize;
+            pH264Enc->hMFCH264Handle.headerData.pHeaderPPS =
+                (OMX_U8 *)pDstOutputData->buffer.addr[0] + iSpsSize;
+            pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] codec specific data is generated", pExynosComponent, __FUNCTION__);
+        pDstOutputData->timeStamp = 0;
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
+        pVideoEnc->bFirstOutput = OMX_TRUE;
+    } else {
+        indexTimestamp = pEncOps->Get_FrameTag(pH264Enc->hMFCH264Handle.hMFCHandle);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Tag(%d) is invalid. changes to use outputIndexTimestamp(%d)",
+                                                  pExynosComponent, __FUNCTION__,
+                                                  indexTimestamp, pH264Enc->hMFCH264Handle.outputIndexTimestamp);
+            indexTimestamp = pH264Enc->hMFCH264Handle.outputIndexTimestamp;
+        }
+
+        if (pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nBFrames > 0) {
+            if ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) &&
+                (pVideoBuffer->frameType == VIDEO_FRAME_P)) {
+                /* move an EOS flag to previous slot
+                 * B1 B2 P(EOS) -> P B1 B2(EOS)
+                 * B1 P(EOS) -> P B1(EOS)
+                 */
+                int index = ((indexTimestamp - 1) < 0)? (MAX_TIMESTAMP - 1):(indexTimestamp - 1);
+
+                if (pExynosComponent->bTimestampSlotUsed[index] == OMX_TRUE) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] EOS flag is moved to %d from %d",
+                                                            pExynosComponent, __FUNCTION__,
+                                                            index, indexTimestamp);
+                    pExynosComponent->nFlags[indexTimestamp] &= (~OMX_BUFFERFLAG_EOS);
+                    pExynosComponent->nFlags[index] |= OMX_BUFFERFLAG_EOS;
+                }
+            }
+        }
+
+        /* In case of Video buffer batch mode, use timestamp from MFC device driver */
+        if (pVideoBuffer->timestamp != 0)
+            pDstOutputData->timeStamp = pVideoBuffer->timestamp;
+        else
+            pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
+
+        pExynosComponent->bTimestampSlotUsed[indexTimestamp]    = OMX_FALSE;
+        pDstOutputData->nFlags                                  = pExynosComponent->nFlags[indexTimestamp];
+        pDstOutputData->nFlags                                 |= OMX_BUFFERFLAG_ENDOFFRAME;
+    }
+
+    if (pVideoBuffer->frameType == VIDEO_FRAME_I)
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, frameType: %d, dataLen: %d, timestamp %lld us (%.2f secs), Tag: %d",
+                                            pExynosComponent, __FUNCTION__,
+                                            pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                            pVideoBuffer->frameType, pDstOutputData->dataLen,
+                                            pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                            indexTimestamp);
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] got end of stream", pExynosComponent, __FUNCTION__);
+
+        if (pExynosComponent->bBehaviorEOS == OMX_FALSE)
+            pDstOutputData->remainDataLen = 0;
+        else
+            pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_srcInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT      *pInputPort        = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pInputPort)) ||
+        (!CHECK_PORT_POPULATED(pInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_H264Enc_SrcIn(pOMXComponent, pSrcInputData);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_srcOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pInputPort)) ||
+        (!CHECK_PORT_POPULATED(pInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    if ((pH264Enc->bSourceStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pInputPort))) {
+        Exynos_OSAL_SignalWait(pH264Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pH264Enc->hSourceStartEvent);
+    }
+
+    ret = Exynos_H264Enc_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_dstInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+        Exynos_OSAL_SignalWait(pH264Enc->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pH264Enc->hDestinationInStartEvent);
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pH264Enc->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pH264Enc->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_H264Enc_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_dstOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+        Exynos_OSAL_SignalWait(pH264Enc->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pH264Enc->hDestinationOutStartEvent);
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pH264Enc->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pH264Enc->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_H264Enc_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE hComponent,
+    OMX_STRING     componentName)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc         = NULL;
+    OMX_BOOL                       bSecureMode      = OMX_FALSE;
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_ENC, componentName) == 0) {
+        bSecureMode = OMX_FALSE;
+    } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DRM_ENC, componentName) == 0) {
+        bSecureMode = OMX_TRUE;
+    } else {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = (bSecureMode == OMX_TRUE)? HW_VIDEO_ENC_SECURE_CODEC:HW_VIDEO_ENC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pH264Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264ENC_HANDLE));
+    if (pH264Enc == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pH264Enc, 0, sizeof(EXYNOS_H264ENC_HANDLE));
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pH264Enc;
+    pH264Enc->qpRangeI.nMinQP = 5;
+    pH264Enc->qpRangeI.nMaxQP = 50;
+    pH264Enc->qpRangeP.nMinQP = 5;
+    pH264Enc->qpRangeP.nMaxQP = 50;
+    pH264Enc->qpRangeB.nMinQP = 5;
+    pH264Enc->qpRangeB.nMaxQP = 50;
+
+    pVideoEnc->quantization.nQpI = 29;
+    pVideoEnc->quantization.nQpP = 30;
+    pVideoEnc->quantization.nQpB = 32;
+
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_DRM_ENC);
+    else
+        Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_ENC);
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+#ifdef USE_SINGLE_PLANE_IN_DRM
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        pExynosPort->ePlaneType = PLANE_SINGLE;
+#endif
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pH264Enc->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
+        pH264Enc->AVCComponent[i].nPortIndex = i;
+        pH264Enc->AVCComponent[i].eProfile   = OMX_VIDEO_AVCProfileBaseline;
+        pH264Enc->AVCComponent[i].eLevel     = OMX_VIDEO_AVCLevel31;
+
+        pH264Enc->AVCComponent[i].nPFrames      = 29;
+        pH264Enc->AVCComponent[i].nBFrames      = 0;
+        pH264Enc->AVCComponent[i].nRefFrames    = 1;
+    }
+
+    pH264Enc->hMFCH264Handle.bTemporalSVC   = OMX_FALSE;
+    pH264Enc->nMaxTemporalLayerCount        = 0;
+    pH264Enc->nTemporalLayerCount           = 0;
+    pH264Enc->bUseTemporalLayerBitrateRatio = 0;
+    Exynos_OSAL_Memset(pH264Enc->nTemporalLayerBitrateRatio, 0, sizeof(pH264Enc->nTemporalLayerBitrateRatio));
+
+    pOMXComponent->GetParameter      = &Exynos_H264Enc_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_H264Enc_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_H264Enc_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_H264Enc_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_H264Enc_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_H264Enc_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_H264Enc_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Enc_Terminate;
+
+    pVideoEnc->exynos_codec_srcInputProcess  = &Exynos_H264Enc_srcInputBufferProcess;
+    pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_H264Enc_srcOutputBufferProcess;
+    pVideoEnc->exynos_codec_dstInputProcess  = &Exynos_H264Enc_dstInputBufferProcess;
+    pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_H264Enc_dstOutputBufferProcess;
+
+    pVideoEnc->exynos_codec_start         = &H264CodecStart;
+    pVideoEnc->exynos_codec_stop          = &H264CodecStop;
+    pVideoEnc->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun;
+    pVideoEnc->exynos_codec_enqueueAllBuffer = &H264CodecEnqueueAllBuffer;
+
+    pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+
+    pVideoEnc->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
+
+    pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoEnc->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pH264Enc);
+        pH264Enc = pVideoEnc->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pH264Enc->hMFCH264Handle.videoInstInfo.eCodecType = VIDEO_CODING_AVC;
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        pH264Enc->hMFCH264Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pH264Enc->hMFCH264Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pH264Enc->hMFCH264Handle.videoInstInfo), VIDEO_FALSE /* enc */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pH264Enc);
+        pH264Enc = pVideoEnc->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for enc : ext(%d)/temporal-svc(%d)/skype(%d)/roi(%d)/qp-range(%d)/fix(%d)/pvc(%d)/I-ratio(%d)/CA(%d)",
+            pExynosComponent, __FUNCTION__,
+            (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.nSpareSize),
+            (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport),
+            (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bSkypeSupport),
+            (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bRoiInfoSupport),
+            (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bQpRangePBSupport),
+            (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bFixedSliceSupport),
+            (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bPVCSupport),
+            (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bIFrameRatioSupport),
+            (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bColorAspectsSupport));
+
+    if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.nSpareSize > 0)
+        pVideoEnc->nInbufSpareSize = pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.nSpareSize;
+
+    Exynos_Input_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_AddVendorExt(hComponent, "sec-ext-enc-qp-range", (OMX_INDEXTYPE)OMX_IndexConfigVideoQPRange);
+#ifdef USE_SKYPE_HD
+    if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bSkypeSupport == VIDEO_TRUE) {
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-caps-vt-driver-version", (OMX_INDEXTYPE)OMX_IndexSkypeParamDriverVersion);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-low-latency", (OMX_INDEXTYPE)OMX_IndexSkypeParamLowLatency);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-caps-temporal-layers", (OMX_INDEXTYPE)OMX_IndexSkypeParamEncoderMaxTemporalLayerCount);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-caps-ltr", (OMX_INDEXTYPE)OMX_IndexSkypeParamEncoderMaxLTR);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-ltr-count", (OMX_INDEXTYPE)OMX_IndexSkypeParamEncoderLTR);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-caps-preprocess", (OMX_INDEXTYPE)OMX_IndexSkypeParamEncoderPreprocess);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-custom-profile-level", (OMX_INDEXTYPE)OMX_IndexParamVideoProfileLevelCurrent);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-sar", (OMX_INDEXTYPE)OMX_IndexSkypeParamEncoderSar);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-slice", (OMX_INDEXTYPE)OMX_IndexParamVideoAvc);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-ltr", (OMX_INDEXTYPE)OMX_IndexSkypeConfigEncoderLTR);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-frame-qp", (OMX_INDEXTYPE)OMX_IndexSkypeConfigQP);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-base-layer-pid", (OMX_INDEXTYPE)OMX_IndexSkypeConfigBasePid);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-app-input-control", (OMX_INDEXTYPE)OMX_IndexSkypeParamEncoderInputControl);
+        Exynos_OSAL_AddVendorExt(hComponent, "rtc-ext-enc-input-trigger", (OMX_INDEXTYPE)OMX_IndexSkypeConfigEncoderInputTrigger);
+    }
+#endif
+#endif
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent       = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent    = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoEnc           = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc != NULL) {
+        Exynos_OSAL_Free(pH264Enc);
+        pH264Enc = pVideoEnc->hCodecHandle = NULL;
+    }
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_DelVendorExts(hComponent);
+#endif
+
+    ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/enc/h264/Exynos_OMX_H264enc.h b/openmax/component/video/enc/h264/Exynos_OMX_H264enc.h
new file mode 100755 (executable)
index 0000000..94ce5e3
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_H264enc.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_H264_ENC_COMPONENT
+#define EXYNOS_OMX_H264_ENC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+
+#include "ExynosVideoApi.h"
+#include "library_register.h"
+
+
+typedef struct _H264_VUI_SAR {
+    OMX_BOOL SarEnable;
+    OMX_U32  SarIndex;
+    OMX_U32  SarWidth;
+    OMX_U32  SarHeight;
+} H264_VUI_SAR;
+
+typedef struct _EXTRA_DATA
+{
+    OMX_PTR   pHeaderSPS;
+    OMX_U32   SPSLen;
+    OMX_PTR   pHeaderPPS;
+    OMX_U32   PPSLen;
+} EXTRA_DATA;
+
+typedef struct _EXYNOS_MFC_H264ENC_HANDLE
+{
+    OMX_HANDLETYPE hMFCHandle;
+
+    OMX_U32 indexTimestamp;
+    OMX_U32 outputIndexTimestamp;
+
+    OMX_BOOL bConfiguredMFCSrc;
+    OMX_BOOL bConfiguredMFCDst;
+
+    OMX_BOOL bPrependSpsPpsToIdr;
+    OMX_BOOL bTemporalSVC;
+    OMX_BOOL bRoiInfo;
+    OMX_BOOL bWeightedPrediction;
+
+    /* skypeHD */
+    OMX_BOOL                            bEnableSkypeHD;
+    OMX_S64                             nTriggerTS;
+    OMX_U32                             nLTRFrames;
+    OMX_BOOL                            bLowLatency;
+    EXYNOS_OMX_HIERARCHICAL_CODING_TYPE eHierarchicalType;
+    H264_VUI_SAR                        stSarParam;
+    OMX_S32                             nBaseLayerPid;
+
+    EXTRA_DATA headerData;
+
+    ExynosVideoEncOps       *pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps;
+    ExynosVideoEncBufferOps *pOutbufOps;
+    ExynosVideoEncParam      encParam;
+    ExynosVideoInstInfo      videoInstInfo;
+
+    #define MAX_PROFILE_NUM 5
+    OMX_VIDEO_AVCPROFILETYPE   profiles[MAX_PROFILE_NUM];
+    OMX_S32                    nProfileCnt;
+    OMX_VIDEO_AVCLEVELTYPE     maxLevel;
+} EXYNOS_MFC_H264ENC_HANDLE;
+
+typedef struct _EXYNOS_H264ENC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_AVCTYPE             AVCComponent[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_AVCSLICEFMO         AVCSliceFmo;
+    OMX_VIDEO_QPRANGE                   qpRangeI;
+    OMX_VIDEO_QPRANGE                   qpRangeP;
+    OMX_VIDEO_QPRANGE                   qpRangeB;
+
+    /* Temporal SVC */
+    OMX_U32  nMaxTemporalLayerCount;
+    OMX_U32  nMaxTemporalLayerCountForB;
+    OMX_U32  nTemporalLayerCount;
+    OMX_U32  nTemporalLayerCountForB;
+    OMX_BOOL bUseTemporalLayerBitrateRatio;
+    OMX_U32  nTemporalLayerBitrateRatio[OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS];
+
+    /* SEC MFC Codec specific */
+    EXYNOS_MFC_H264ENC_HANDLE hMFCH264Handle;
+
+    OMX_BOOL bSourceStart;
+    OMX_BOOL bDestinationStart;
+    OMX_HANDLETYPE hSourceStartEvent;
+    OMX_HANDLETYPE hDestinationInStartEvent;
+    OMX_HANDLETYPE hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE bypassBufferInfoQ;
+} EXYNOS_H264ENC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName);
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/enc/h264/Makefile.am b/openmax/component/video/enc/h264/Makefile.am
new file mode 100755 (executable)
index 0000000..66a113b
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libOMX.Exynos.AVC.Encoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_AVC_Encoder_la_SOURCES = Exynos_OMX_H264enc.c \
+                                       library_register.c
+
+libOMX_Exynos_AVC_Encoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                      $(top_builddir)/openmax/component/video/enc/libExynosOMX_Venc.la \
+                                      $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+libOMX_Exynos_AVC_Encoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                      -I$(top_srcdir)/openmax/include/exynos \
+                                      -I$(top_srcdir)/openmax/osal \
+                                      -I$(top_srcdir)/openmax/core \
+                                      -I$(top_srcdir)/openmax/component/common \
+                                      -I$(top_srcdir)/openmax/component/video/enc \
+                                      -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_AVC_Encoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
+libOMX_Exynos_AVC_Encoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable
+
+libOMX_Exynos_AVC_Encoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/enc/h264/library_register.c b/openmax/component/video/enc/h264/library_register.c
new file mode 100755 (executable)
index 0000000..e2810cc
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+#include "Exynos_OSAL_Log.h"
+
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents)
+{
+    FunctionIn();
+
+    if (exynosComponents == NULL)
+        goto EXIT;
+
+    /* component 1 - video Encoder H.264 */
+    Exynos_OSAL_Strcpy(exynosComponents[0]->componentName, EXYNOS_OMX_COMPONENT_H264_ENC);
+    Exynos_OSAL_Strcpy(exynosComponents[0]->roles[0], EXYNOS_OMX_COMPONENT_H264_ENC_ROLE);
+    exynosComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+    /* component 2 - video Encoder H.264 for DRM */
+    Exynos_OSAL_Strcpy(exynosComponents[1]->componentName, EXYNOS_OMX_COMPONENT_H264_DRM_ENC);
+    Exynos_OSAL_Strcpy(exynosComponents[1]->roles[0], EXYNOS_OMX_COMPONENT_H264_DRM_ENC_ROLE);
+    exynosComponents[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
+
diff --git a/openmax/component/video/enc/h264/library_register.h b/openmax/component/video/enc/h264/library_register.h
new file mode 100755 (executable)
index 0000000..4e9fd23
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_H264_REG
+#define EXYNOS_OMX_H264_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM       2
+#define MAX_COMPONENT_ROLE_NUM  1
+
+/* H.264 */
+#define EXYNOS_OMX_COMPONENT_H264_ENC      "OMX.Exynos.AVC.Encoder"
+#define EXYNOS_OMX_COMPONENT_H264_DRM_ENC  "OMX.Exynos.AVC.Encoder.secure"
+#define EXYNOS_OMX_COMPONENT_H264_ENC_ROLE "video_encoder.avc"
+#define EXYNOS_OMX_COMPONENT_H264_DRM_ENC_ROLE "video_encoder.avc-wfd"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
diff --git a/openmax/component/video/enc/h264wfd/Exynos_OMX_H264enc_wfd.c b/openmax/component/video/enc/h264wfd/Exynos_OMX_H264enc_wfd.c
new file mode 100755 (executable)
index 0000000..483abe3
--- /dev/null
@@ -0,0 +1,5666 @@
+/*
+ *
+ * Copyright 2017 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_H264enc_wfd.c
+ * @brief
+ * @author      SeungBeom Kim  (sbcrux.kim@samsung.com)
+ *              Taehwan Kim    (t_h.kim@samsung.com)
+ *              ByungGwan Kang (bk0917.kang@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2017.06.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Venc.h"
+#include "Exynos_OMX_VencControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "Exynos_OMX_H264enc_wfd.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OSAL_Queue.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_H264_WFD_ENC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+typedef struct _OMX_BUFFERHEADER_ARRAY {
+    OMX_BUFFERHEADERTYPE *pBuffer;
+    OMX_BOOL              bInOMX;
+} OMX_BUFFERHEADER_ARRAY;
+
+static OMX_BUFFERHEADER_ARRAY inputBufArray[MAX_BUFFER_NUM];
+static OMX_BUFFERHEADER_ARRAY outputBufArray[MAX_BUFFER_NUM];
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc       = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Enc->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileBaseline;
+    pH264Enc->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileMain;
+    pH264Enc->hMFCH264Handle.profiles[nProfileCnt++] = OMX_VIDEO_AVCProfileHigh;
+    pH264Enc->hMFCH264Handle.profiles[nProfileCnt++] = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedBaseline;
+    pH264Enc->hMFCH264Handle.profiles[nProfileCnt++] = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedHigh;
+    pH264Enc->hMFCH264Handle.nProfileCnt = nProfileCnt;
+
+    switch (pH264Enc->hMFCH264Handle.videoInstInfo.HwVersion) {
+    case MFC_120:
+    case MFC_1220:
+    case MFC_110:
+    case MFC_100:
+    case MFC_101:
+        pH264Enc->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel52;
+        break;
+    case MFC_80:
+    case MFC_90:
+    case MFC_1010:
+    case MFC_1120:
+        pH264Enc->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel51;
+        break;
+    case MFC_61:
+    case MFC_65:
+    case MFC_72:
+    case MFC_723:
+    case MFC_77:
+    case MFC_1011:
+        pH264Enc->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel42;
+        break;
+    case MFC_51:
+    case MFC_78:
+    case MFC_78D:
+    case MFC_92:
+    case MFC_1020:
+    case MFC_1021:
+    default:
+        pH264Enc->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel4;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc       = NULL;
+
+    int nLevelCnt = 0;
+    OMX_U32 nMaxIndex = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pH264Enc->hMFCH264Handle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pH264Enc->hMFCH264Handle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pH264Enc->hMFCH264Handle.maxLevel;
+#else
+    while ((pH264Enc->hMFCH264Handle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+
+    if ((pH264Enc->hMFCH264Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pH264Enc->hMFCH264Handle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pH264Enc->hMFCH264Handle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : supported profile(%x), level(%x)",
+                                        pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc  = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc   = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL)
+        goto EXIT;
+
+    while ((pH264Enc->hMFCH264Handle.maxLevel >> nLevelCnt++) > 0);
+
+    if ((pH264Enc->hMFCH264Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pH264Enc->hMFCH264Handle.nProfileCnt; i++) {
+        if (pH264Enc->hMFCH264Handle.profiles[i] == pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    while (nLevelCnt >= 0) {
+        if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+            bLevelSupport = OMX_TRUE;
+            break;
+        }
+
+        nLevelCnt--;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                        pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                        (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_U32 OMXAVCProfileToProfileIDC(OMX_VIDEO_AVCPROFILETYPE profile)
+{
+    OMX_U32 ret = 0;
+
+    if (profile == OMX_VIDEO_AVCProfileBaseline)
+        ret = 0;
+    else if ((EXYNOS_OMX_VIDEO_AVCPROFILETYPE)profile == OMX_VIDEO_AVCProfileConstrainedBaseline)
+        ret = 1;
+    else if (profile == OMX_VIDEO_AVCProfileMain)
+        ret = 2;
+    else if (profile == OMX_VIDEO_AVCProfileHigh)
+        ret = 4;
+    else if ((EXYNOS_OMX_VIDEO_AVCPROFILETYPE)profile == OMX_VIDEO_AVCProfileConstrainedHigh)
+        ret = 17;
+
+    return ret;
+}
+
+static OMX_U32 OMXAVCLevelToLevelIDC(OMX_VIDEO_AVCLEVELTYPE level)
+{
+    OMX_U32 ret = 11; //default OMX_VIDEO_AVCLevel4
+
+    if (level == OMX_VIDEO_AVCLevel1)
+        ret = 0;
+    else if (level == OMX_VIDEO_AVCLevel1b)
+        ret = 1;
+    else if (level == OMX_VIDEO_AVCLevel11)
+        ret = 2;
+    else if (level == OMX_VIDEO_AVCLevel12)
+        ret = 3;
+    else if (level == OMX_VIDEO_AVCLevel13)
+        ret = 4;
+    else if (level == OMX_VIDEO_AVCLevel2)
+        ret = 5;
+    else if (level == OMX_VIDEO_AVCLevel21)
+        ret = 6;
+    else if (level == OMX_VIDEO_AVCLevel22)
+        ret = 7;
+    else if (level == OMX_VIDEO_AVCLevel3)
+        ret = 8;
+    else if (level == OMX_VIDEO_AVCLevel31)
+        ret = 9;
+    else if (level == OMX_VIDEO_AVCLevel32)
+        ret = 10;
+    else if (level == OMX_VIDEO_AVCLevel4)
+        ret = 11;
+    else if (level == OMX_VIDEO_AVCLevel41)
+        ret = 12;
+    else if (level == OMX_VIDEO_AVCLevel42)
+        ret = 13;
+
+    return ret;
+}
+
+static OMX_U8 *FindDelimiter(OMX_U8 *pBuffer, OMX_U32 size)
+{
+    OMX_U32 i;
+
+    for (i = 0; i < size - 3; i++) {
+        if ((pBuffer[i] == 0x00)   &&
+            (pBuffer[i + 1] == 0x00) &&
+            (pBuffer[i + 2] == 0x00) &&
+            (pBuffer[i + 3] == 0x01))
+            return (pBuffer + i);
+    }
+
+    return NULL;
+}
+
+static void Print_H264WFDEnc_Param(ExynosVideoEncParam *pEncParam)
+{
+    ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam;
+    ExynosVideoEncH264Param   *pH264Param   = &pEncParam->codecParam.h264;
+
+    /* common parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceWidth             : %d", pCommonParam->SourceWidth);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceHeight            : %d", pCommonParam->SourceHeight);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "IDRPeriod               : %d", pCommonParam->IDRPeriod);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SliceMode               : %d", pCommonParam->SliceMode);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "RandomIntraMBRefresh    : %d", pCommonParam->RandomIntraMBRefresh);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Bitrate                 : %d", pCommonParam->Bitrate);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp                 : %d", pCommonParam->FrameQp);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp_P               : %d", pCommonParam->FrameQp_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(I) ranege            : %d / %d", pCommonParam->QpRange.QpMin_I, pCommonParam->QpRange.QpMax_I);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(P) ranege            : %d / %d", pCommonParam->QpRange.QpMin_P, pCommonParam->QpRange.QpMax_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(B) ranege            : %d / %d", pCommonParam->QpRange.QpMin_B, pCommonParam->QpRange.QpMax_B);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "PadControlOn            : %d", pCommonParam->PadControlOn);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LumaPadVal              : %d", pCommonParam->LumaPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CbPadVal                : %d", pCommonParam->CbPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CrPadVal                : %d", pCommonParam->CrPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameMap                : %d", pCommonParam->FrameMap);
+
+    /* H.264 specific parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "ProfileIDC              : %d", pH264Param->ProfileIDC);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LevelIDC                : %d", pH264Param->LevelIDC);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp_B               : %d", pH264Param->FrameQp_B);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameRate               : %d", pH264Param->FrameRate);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SliceArgument           : %d", pH264Param->SliceArgument);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumberBFrames           : %d", pH264Param->NumberBFrames);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumberReferenceFrames   : %d", pH264Param->NumberReferenceFrames);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumberRefForPframes     : %d", pH264Param->NumberRefForPframes);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LoopFilterDisable       : %d", pH264Param->LoopFilterDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LoopFilterAlphaC0Offset : %d", pH264Param->LoopFilterAlphaC0Offset);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LoopFilterBetaOffset    : %d", pH264Param->LoopFilterBetaOffset);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SymbolMode              : %d", pH264Param->SymbolMode);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "PictureInterlace        : %d", pH264Param->PictureInterlace);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "Transform8x8Mode        : %d", pH264Param->Transform8x8Mode);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "DarkDisable             : %d", pH264Param->DarkDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SmoothDisable           : %d", pH264Param->SmoothDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "StaticDisable           : %d", pH264Param->StaticDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "ActivityDisable         : %d", pH264Param->ActivityDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "HierarType:             : %d", pH264Param->HierarType);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "VuiRestrictionEnable:   : %d", pH264Param->VuiRestrictionEnable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "HeaderWithIFrame:       : %d", pH264Param->HeaderWithIFrame);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LTRFrames:              : %d", pH264Param->LTRFrames);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "ROIEnable:              : %d", pH264Param->ROIEnable);
+
+    /* rate control related parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableFRMRateControl    : %d", pCommonParam->EnableFRMRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableMBRateControl     : %d", pCommonParam->EnableMBRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CBRPeriodRf             : %d", pCommonParam->CBRPeriodRf);
+}
+
+static void Set_H264WFDEnc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_BASEPORT            *pInputPort       = NULL;
+    EXYNOS_OMX_BASEPORT            *pOutputPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT  *pVideoEnc        = NULL;
+    EXYNOS_H264WFDENC_HANDLE       *pH264Enc         = NULL;
+    EXYNOS_MFC_H264WFDENC_HANDLE   *pMFCH264Handle   = NULL;
+    OMX_COLOR_FORMATTYPE            eColorFormat     = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncParam       *pEncParam    = NULL;
+    ExynosVideoEncCommonParam *pCommonParam = NULL;
+    ExynosVideoEncH264Param   *pH264Param   = NULL;
+
+    int i;
+
+    pVideoEnc           = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pH264Enc            = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCH264Handle      = &pH264Enc->hMFCH264Handle;
+    pInputPort          = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pOutputPort         = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    pEncParam       = &pMFCH264Handle->encParam;
+    pCommonParam    = &pEncParam->commonParam;
+    pH264Param      = &pEncParam->codecParam.h264;
+    pEncParam->eCompressionFormat = VIDEO_CODING_AVC;
+
+    /* common parameters */
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+    } else {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+    }
+    pCommonParam->IDRPeriod    = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
+    pCommonParam->SliceMode    = pH264Enc->AVCSliceFmo.eSliceMode;
+    pCommonParam->Bitrate      = pOutputPort->portDefinition.format.video.nBitrate;
+    pCommonParam->FrameQp      = pVideoEnc->quantization.nQpI;
+    pCommonParam->FrameQp_P    = pVideoEnc->quantization.nQpP;
+
+    pCommonParam->QpRange.QpMin_I = pH264Enc->qpRangeI.nMinQP;
+    pCommonParam->QpRange.QpMax_I = pH264Enc->qpRangeI.nMaxQP;
+    pCommonParam->QpRange.QpMin_P = pH264Enc->qpRangeP.nMinQP;
+    pCommonParam->QpRange.QpMax_P = pH264Enc->qpRangeP.nMaxQP;
+    pCommonParam->QpRange.QpMin_B = pH264Enc->qpRangeB.nMinQP;
+    pCommonParam->QpRange.QpMax_B = pH264Enc->qpRangeB.nMaxQP;
+
+    pCommonParam->PadControlOn = 0;    /* 0: disable, 1: enable */
+    pCommonParam->LumaPadVal   = 0;
+    pCommonParam->CbPadVal     = 0;
+    pCommonParam->CrPadVal     = 0;
+
+    if (pVideoEnc->intraRefresh.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) {
+        /* Cyclic Mode */
+        pCommonParam->RandomIntraMBRefresh = pVideoEnc->intraRefresh.nCirMBs;
+    } else {
+        /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+        pCommonParam->RandomIntraMBRefresh = 0;
+    }
+        /* Perceptual Mode */
+    pCommonParam->PerceptualMode = (pVideoEnc->bPVCMode)? VIDEO_TRUE:VIDEO_FALSE;
+
+    eColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+    pCommonParam->FrameMap = Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    /* H.264 specific parameters */
+    pH264Param->ProfileIDC   = OMXAVCProfileToProfileIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eProfile);    /*0: OMX_VIDEO_AVCProfileMain */
+    pH264Param->LevelIDC     = OMXAVCLevelToLevelIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eLevel);    /*40: OMX_VIDEO_AVCLevel4 */
+    pH264Param->FrameQp_B    = pVideoEnc->quantization.nQpB;
+    pH264Param->FrameRate    = (pInputPort->portDefinition.format.video.xFramerate) >> 16;
+    if (pH264Enc->AVCSliceFmo.eSliceMode == OMX_VIDEO_SLICEMODE_AVCDefault)
+        pH264Param->SliceArgument = 0;    /* Slice mb/byte size number */
+    else
+        pH264Param->SliceArgument = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nSliceHeaderSpacing;
+
+    pH264Param->NumberBFrames           = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nBFrames;   /* 0 ~ 2 */
+    pH264Param->NumberRefForPframes     = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nRefFrames; /* 1 ~ 2 */
+    pH264Param->NumberReferenceFrames   = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nRefFrames;
+
+    pH264Param->LoopFilterDisable       = 0;    /* 1: Loop Filter Disable, 0: Filter Enable */
+    pH264Param->LoopFilterAlphaC0Offset = 0;
+    pH264Param->LoopFilterBetaOffset    = 0;
+    pH264Param->SymbolMode       = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].bEntropyCodingCABAC;    /* 0: CAVLC, 1: CABAC */
+    pH264Param->PictureInterlace = 0;
+    pH264Param->Transform8x8Mode = 1;    /* 0: 4x4, 1: allow 8x8 */
+    pH264Param->DarkDisable      = 1;
+    pH264Param->SmoothDisable    = 1;
+    pH264Param->StaticDisable    = 1;
+    pH264Param->ActivityDisable  = 1;
+
+    /* Temporal SVC */
+    /* If MaxTemporalLayerCount value is 0, codec supported max value will be set */
+    pH264Param->MaxTemporalLayerCount           = (unsigned int)pH264Enc->nMaxTemporalLayerCount;
+    pH264Param->TemporalSVC.nTemporalLayerCount = (unsigned int)pH264Enc->TemporalSVC.nTemporalLayerCount;
+    for (i = 0; i < OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS; i++)
+        pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)pH264Enc->TemporalSVC.nTemporalLayerBitrateRatio[i];
+
+    /* Hierarchal P & B */
+    pH264Param->HierarType = pH264Enc->eHierarchicalType;
+
+    if (pH264Enc->bLowLatency == OMX_TRUE) {
+        pH264Param->HeaderWithIFrame                = 0; /* 1: header + first frame */
+        pH264Param->LoopFilterDisable               = 0; /* 1: disable, 0: enable */
+        pH264Param->VuiRestrictionEnable            = (int)OMX_TRUE;
+        pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]  = OMX_Video_ControlRateDisable;
+        pCommonParam->EnableFRMQpControl            = 1; /* 0: Disable,  1: Per frame QP */
+    } else {
+        pH264Param->VuiRestrictionEnable = (int)OMX_FALSE;
+    }
+
+    pH264Param->LTRFrames = pMFCH264Handle->nLTRFrames;
+
+    if (pMFCH264Handle->bRoiInfo == OMX_TRUE)
+        pH264Param->ROIEnable = 1;
+    else
+        pH264Param->ROIEnable = 0;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eControlRate: 0x%x", pExynosComponent, __FUNCTION__, pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]);
+    /* rate control related parameters */
+    switch ((int)pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) {
+    case OMX_Video_ControlRateDisable:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR");
+        pCommonParam->EnableFRMRateControl = 0;    /* 0: Disable,  1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 0;    /* 0: Disable,  1: MB level RC */
+        pCommonParam->CBRPeriodRf          = 100;
+        break;
+    case OMX_Video_ControlRateConstantVTCall:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR VT Call");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable,  1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable,  1: MB level RC */
+        pCommonParam->CBRPeriodRf          = 5;
+        pCommonParam->bFixedSlice          = VIDEO_TRUE;
+        break;
+    case OMX_Video_ControlRateConstant:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable,  1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable,  1: MB level RC */
+        pCommonParam->CBRPeriodRf          = 10;
+        break;
+    case OMX_Video_ControlRateVariable:
+    default: /*Android default */
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable,  1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable,  1: MB level RC */
+        pCommonParam->CBRPeriodRf          = 100;
+        break;
+    }
+
+//    Print_H264Enc_Param(pEncParam);
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc       = NULL;
+    EXYNOS_OMX_BASEPORT             *pInputPort     = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL)
+        goto EXIT;
+    pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pH264Enc->hMFCH264Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE H264WFDCodecOpen(
+    EXYNOS_H264WFDENC_HANDLE   *pH264Enc,
+    ExynosVideoInstInfo        *pVideoInstInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pH264Enc == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pEncOps     = (ExynosVideoEncOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncOps));
+    pInbufOps   = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+    pOutbufOps  = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+
+    if ((pEncOps == NULL) ||
+        (pInbufOps == NULL) ||
+        (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pH264Enc->hMFCH264Handle.pEncOps = pEncOps;
+    pH264Enc->hMFCH264Handle.pInbufOps = pInbufOps;
+    pH264Enc->hMFCH264Handle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pEncOps->nSize = sizeof(ExynosVideoEncOps);
+    pInbufOps->nSize = sizeof(ExynosVideoEncBufferOps);
+    pOutbufOps->nSize = sizeof(ExynosVideoEncBufferOps);
+
+    if (Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for encoder ops */
+    if ((pEncOps->Init == NULL) ||
+        (pEncOps->Finalize == NULL) ||
+        (pEncOps->Set_FrameTag == NULL) ||
+        (pEncOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pH264Enc->hMFCH264Handle.hMFCHandle = pH264Enc->hMFCH264Handle.pEncOps->Init(pVideoInstInfo);
+    if (pH264Enc->hMFCH264Handle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pEncOps != NULL) {
+            Exynos_OSAL_Free(pEncOps);
+            pH264Enc->hMFCH264Handle.pEncOps = NULL;
+        }
+
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pH264Enc->hMFCH264Handle.pInbufOps = NULL;
+        }
+
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pH264Enc->hMFCH264Handle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264WFDCodecClose(EXYNOS_H264WFDENC_HANDLE *pH264Enc)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pH264Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
+    pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
+    pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
+    pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pEncOps->Finalize(hMFCHandle);
+        hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle = NULL;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Encoder(pEncOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps = NULL;
+    }
+
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps = NULL;
+    }
+
+    if (pEncOps != NULL) {
+        Exynos_OSAL_Free(pEncOps);
+        pEncOps = pH264Enc->hMFCH264Handle.pEncOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264WFDCodecStart(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc           = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
+    pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
+    pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+
+    if (nPortIndex == INPUT_PORT_INDEX)
+        pInbufOps->Run(hMFCHandle);
+    else if (nPortIndex == OUTPUT_PORT_INDEX)
+        pOutbufOps->Run(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264WFDCodecStop(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc           = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
+    pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
+    pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
+        pInbufOps->Stop(hMFCHandle);
+    else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
+        pOutbufOps->Stop(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264WFDEnc_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nParamIndex %x", pExynosComponent, __FUNCTION__, (int)nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoAvc:
+    {
+        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcAVCComponent = &pH264Enc->AVCComponent[pDstAVCComponent->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstAVCComponent) + nOffset,
+                           ((char *)pSrcAVCComponent) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_AVCTYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamVideoSliceFMO:
+    {
+        OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = NULL;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pSrcSliceFmo = &pH264Enc->AVCSliceFmo;
+
+        Exynos_OSAL_Memcpy(((char *)pDstSliceFmo) + nOffset,
+                           ((char *)pSrcSliceFmo) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_WFD_ENC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcAVCComponent = &pH264Enc->AVCComponent[pDstProfileLevel->nPortIndex];
+        pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile;
+        pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pH264Enc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pH264Enc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pH264Enc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pH264Enc->qpRangeP.nMaxQP;
+        pQpRange->qpRangeB.nMinQP = pH264Enc->qpRangeB.nMinQP;
+        pQpRange->qpRangeB.nMaxQP = pH264Enc->qpRangeB.nMaxQP;
+    }
+        break;
+    case OMX_IndexParamVideoAVCEnableTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC *pDstEnableTemporalSVC = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstEnableTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstEnableTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstEnableTemporalSVC->bEnableTemporalSVC = pH264Enc->hMFCH264Handle.bTemporalSVC;
+    }
+        break;
+    case OMX_IndexParamVideoEnableRoiInfo:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *pDstEnableRoiInfo = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstEnableRoiInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstEnableRoiInfo->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstEnableRoiInfo->bEnableRoiInfo = pH264Enc->hMFCH264Handle.bRoiInfo;
+    }
+        break;
+    case OMX_IndexParamVideoEnablePVC:
+    {
+        OMX_PARAM_U32TYPE *pEnablePVC  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pEnablePVC, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pEnablePVC->nU32 = pVideoEnc->bPVCMode;
+    }
+        break;
+
+    case OMX_IndexParamVideoInit:
+    {
+        OMX_PORT_PARAM_TYPE *pPortParam = (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortParam, sizeof(OMX_PORT_PARAM_TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pPortParam->nPorts           = pExynosComponent->portParam.nPorts;
+        pPortParam->nStartPortNumber = pExynosComponent->portParam.nStartPortNumber;
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
+        OMX_U32                         nPortIndex  = pPortFormat->nPortIndex;
+        OMX_U32                         nIndex      = pPortFormat->nIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE   *pPortDef    = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            if (nIndex > (INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1)) {
+                ret = OMX_ErrorNoMore;
+                goto EXIT;
+            }
+
+            pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+            pPortDef = &pExynosPort->portDefinition;
+
+            pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
+            pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
+
+            if (pExynosPort->supportFormat[nIndex] == OMX_COLOR_FormatUnused) {
+                ret = OMX_ErrorNoMore;
+                goto EXIT;
+            }
+            pPortFormat->eColorFormat = pExynosPort->supportFormat[nIndex];
+        } else if (nPortIndex == OUTPUT_PORT_INDEX) {
+            if (nIndex > (OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1)) {
+                ret = OMX_ErrorNoMore;
+                goto EXIT;
+            }
+
+            pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+            pPortDef = &pExynosPort->portDefinition;
+
+            pPortFormat->eCompressionFormat = pPortDef->format.video.eCompressionFormat;
+            pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
+            pPortFormat->eColorFormat       = pPortDef->format.video.eColorFormat;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoBitrate:
+    {
+        OMX_VIDEO_PARAM_BITRATETYPE     *pVideoBitrate  = (OMX_VIDEO_PARAM_BITRATETYPE *)pComponentParameterStructure;
+        OMX_U32                          nPortIndex     = pVideoBitrate->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE    *pPortDef       = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+            if (pVideoEnc == NULL) {
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+            }
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            pPortDef = &pExynosPort->portDefinition;
+
+            pVideoBitrate->eControlRate = pVideoEnc->eControlRate[nPortIndex];
+            pVideoBitrate->nTargetBitrate = pPortDef->format.video.nBitrate;
+        }
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoQuantization:
+    {
+        OMX_VIDEO_PARAM_QUANTIZATIONTYPE  *pVideoQuantization = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)pComponentParameterStructure;
+        OMX_U32                            nPortIndex         = pVideoQuantization->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE      *pPortDef           = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            pPortDef = &pExynosPort->portDefinition;
+
+            pVideoQuantization->nQpI = pVideoEnc->quantization.nQpI;
+            pVideoQuantization->nQpP = pVideoEnc->quantization.nQpP;
+            pVideoQuantization->nQpB = pVideoEnc->quantization.nQpB;
+        }
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
+        OMX_U32                       portIndex      = portDefinition->nPortIndex;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        if (portIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+        Exynos_OSAL_Memcpy(((char *)portDefinition) + nOffset,
+                           ((char *)&pExynosPort->portDefinition) + nOffset,
+                           portDefinition->nSize - nOffset);
+
+        ret = Exynos_OSAL_GetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+    }
+        break;
+    case OMX_IndexVendorNeedContigMemory:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *pPortMemType = (EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *)pComponentParameterStructure;
+        OMX_U32                             nPortIndex   = pPortMemType->nPortIndex;
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortMemType, sizeof(EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        pPortMemType->bNeedContigMem = pExynosPort->bNeedContigMem;
+    }
+        break;
+    case OMX_IndexParamVideoIntraRefresh:
+    {
+        OMX_VIDEO_PARAM_INTRAREFRESHTYPE *pIntraRefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pComponentParameterStructure;
+        OMX_U32                           nPortIndex    = pIntraRefresh->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pIntraRefresh, sizeof(OMX_VIDEO_PARAM_INTRAREFRESHTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pIntraRefresh->eRefreshMode = pVideoEnc->intraRefresh.eRefreshMode;
+        pIntraRefresh->nAirMBs      = pVideoEnc->intraRefresh.nAirMBs;
+        pIntraRefresh->nAirRef      = pVideoEnc->intraRefresh.nAirRef;
+        pIntraRefresh->nCirMBs      = pVideoEnc->intraRefresh.nCirMBs;
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamRotationInfo:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO *pRotationInfo = (EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO *)pComponentParameterStructure;
+        OMX_U32                               nPortIndex    = pRotationInfo->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pRotationInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pRotationInfo->eRotationType = pVideoEnc->eRotationType;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamConsumerUsageBits:
+    {
+        ret = Exynos_OSAL_GetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+    }
+        break;
+#endif
+
+    // below is from Exynos_OMX_GetParameter
+    case OMX_IndexParamAudioInit:
+    case OMX_IndexParamImageInit:
+    case OMX_IndexParamOtherInit:
+    {
+        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+        portParam->nPorts               = 0;
+        portParam->nStartPortNumber     = 0;
+    }
+        break;
+    case OMX_IndexParamPriorityMgmt:
+    {
+        OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE));
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+
+        compPriority->nGroupID       = pExynosComponent->compPriority.nGroupID;
+        compPriority->nGroupPriority = pExynosComponent->compPriority.nGroupPriority;
+    }
+        break;
+
+    case OMX_IndexParamCompBufferSupplier:
+    {
+        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)pComponentParameterStructure;
+        OMX_U32                       portIndex = bufferSupplier->nPortIndex;
+        EXYNOS_OMX_BASEPORT          *pExynosPort;
+
+        if ((pExynosComponent->currentState == OMX_StateLoaded) ||
+            (pExynosComponent->currentState == OMX_StateWaitForResources)) {
+            if (portIndex >= pExynosComponent->portParam.nPorts) {
+                ret = OMX_ErrorBadPortIndex;
+                goto EXIT;
+            }
+            ret = Exynos_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
+            if (ret != OMX_ErrorNone) {
+                goto EXIT;
+            }
+
+            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+
+
+            if (pExynosPort->portDefinition.eDir == OMX_DirInput) {
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;
+                } else if (CHECK_PORT_TUNNELED(pExynosPort)) {
+                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;
+                } else {
+                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
+                }
+            } else {
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;
+                } else if (CHECK_PORT_TUNNELED(pExynosPort)) {
+                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;
+                } else {
+                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
+                }
+            }
+        }
+        else
+        {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+    }
+        break;
+    default:
+    {
+        ret = OMX_ErrorUnsupportedIndex;
+        goto EXIT;
+    }
+        break;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264WFDEnc_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoAvc:
+    {
+        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
+        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstAVCComponent = &pH264Enc->AVCComponent[pSrcAVCComponent->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstAVCComponent) + nOffset,
+                           ((char *)pSrcAVCComponent) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_AVCTYPE) - nOffset);
+
+        if (pDstAVCComponent->nBFrames > 2) {  /* 0 ~ 2 */
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] nBFrames(%d) is over a maximum value(2). it is limited to max",
+                                                    pExynosComponent, __FUNCTION__, pDstAVCComponent->nBFrames);
+            pDstAVCComponent->nBFrames = 2;
+        }
+
+        if (pDstAVCComponent->nRefFrames > 2) {  /* 1 ~ 2 */
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] nRefFrames(%d) is over a maximum value(2). it is limited to max",
+                                                    pExynosComponent, __FUNCTION__, pDstAVCComponent->nRefFrames);
+            pDstAVCComponent->nRefFrames = 2;
+        } else if (pDstAVCComponent->nRefFrames == 0) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] nRefFrames(%d) is smaller than minimum value(1). it is limited to min",
+                                                    pExynosComponent, __FUNCTION__, pDstAVCComponent->nRefFrames);
+            pDstAVCComponent->nRefFrames = 1;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoSliceFMO:
+    {
+        OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = NULL;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pDstSliceFmo = &pH264Enc->AVCSliceFmo;
+
+        Exynos_OSAL_Memcpy(((char *)pDstSliceFmo) + nOffset,
+                           ((char *)pSrcSliceFmo) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_WFD_ENC_ROLE)) {
+            pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
+        } else {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_AVCTYPE          *pDstAVCComponent = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstAVCComponent = &pH264Enc->AVCComponent[pSrcProfileLevel->nPortIndex];
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile;
+        pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP) ||
+            (pQpRange->qpRangeB.nMinQP > pQpRange->qpRangeB.nMaxQP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d], B[min:%d, max:%d])", __FUNCTION__,
+                                                pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                                                pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP,
+                                                pQpRange->qpRangeB.nMinQP, pQpRange->qpRangeB.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pH264Enc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pH264Enc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pH264Enc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pH264Enc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+        pH264Enc->qpRangeB.nMinQP = pQpRange->qpRangeB.nMinQP;
+        pH264Enc->qpRangeB.nMaxQP = pQpRange->qpRangeB.nMaxQP;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamPrependSPSPPSToIDR:
+    {
+        ret = Exynos_OSAL_SetPrependSPSPPSToIDR(pComponentParameterStructure, &(pH264Enc->hMFCH264Handle.bPrependSpsPpsToIdr));
+    }
+        break;
+#endif
+    case OMX_IndexParamVideoAVCEnableTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC   *pSrcEnableTemporalSVC  = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC *)pComponentParameterStructure;
+        OMX_PARAM_PORTDEFINITIONTYPE                *pPortDef               = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition);
+        int i;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcEnableTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcEnableTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) &&
+            (pSrcEnableTemporalSVC->bEnableTemporalSVC == OMX_TRUE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] MFC D/D doesn't support Temporal SVC", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        pH264Enc->hMFCH264Handle.bTemporalSVC = pSrcEnableTemporalSVC->bEnableTemporalSVC;
+        if ((pH264Enc->hMFCH264Handle.bTemporalSVC == OMX_TRUE) &&
+            (pH264Enc->TemporalSVC.nTemporalLayerCount == 0)) {  /* not initialized yet */
+            pH264Enc->TemporalSVC.nTemporalLayerCount           = 1;
+            pH264Enc->TemporalSVC.nTemporalLayerBitrateRatio[0] = pPortDef->format.video.nBitrate;
+        } else if (pH264Enc->hMFCH264Handle.bTemporalSVC == OMX_FALSE) {  /* set default value */
+            pH264Enc->TemporalSVC.nTemporalLayerCount = 0;
+            for (i = 0; i < OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS; i++)
+                pH264Enc->TemporalSVC.nTemporalLayerBitrateRatio[i] = pPortDef->format.video.nBitrate;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoEnableRoiInfo:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *pSrcEnableRoiInfo = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcEnableRoiInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcEnableRoiInfo->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bRoiInfoSupport == VIDEO_FALSE) &&
+            (pSrcEnableRoiInfo->bEnableRoiInfo == OMX_TRUE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] MFC D/D doesn't support Roi Info", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        pH264Enc->hMFCH264Handle.bRoiInfo = pSrcEnableRoiInfo->bEnableRoiInfo;
+    }
+        break;
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE    *pPortDef       = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
+        OMX_U32                          nPortIndex     = pPortDef->nPortIndex;
+        EXYNOS_OMX_BASEPORT             *pExynosPort    = &pExynosComponent->pExynosPort[nPortIndex];;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        if (pPortDef->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if ((nPortIndex == INPUT_PORT_INDEX) &&
+            ((pPortDef->format.video.xFramerate >> 16) <= 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] xFramerate is invalid(%d)",
+                                              pExynosComponent, __FUNCTION__, pPortDef->format.video.xFramerate >> 16);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Memcpy(((char *)&pExynosPort->portDefinition) + nOffset,
+                           ((char *)pPortDef) + nOffset,
+                           pPortDef->nSize - nOffset);
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+            Exynos_UpdateFrameSize(pOMXComponent);
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] pOutputPort->portDefinition.nBufferSize: %d", pExynosComponent, __FUNCTION__, pExynosPort->portDefinition.nBufferSize);
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoEnablePVC:
+    {
+        OMX_PARAM_U32TYPE *pEnablePVC  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pEnablePVC, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pVideoEnc->bPVCMode = (pEnablePVC->nU32)? OMX_TRUE:OMX_FALSE;
+    }
+        break;
+
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
+        OMX_U32                         nPortIndex  = pPortFormat->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE   *pPortDef    = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        pPortDef = &(pExynosComponent->pExynosPort[nPortIndex].portDefinition);
+
+        if ((nPortIndex == INPUT_PORT_INDEX) &&
+            ((pPortFormat->xFramerate >> 16) <= 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] xFramerate is invalid(%d)",
+                                              pExynosComponent, __FUNCTION__, pPortFormat->xFramerate >> 16);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pPortDef->format.video.eColorFormat       = pPortFormat->eColorFormat;
+        pPortDef->format.video.eCompressionFormat = pPortFormat->eCompressionFormat;
+        pPortDef->format.video.xFramerate         = pPortFormat->xFramerate;
+    }
+        break;
+    case OMX_IndexParamVideoBitrate:
+    {
+        OMX_VIDEO_PARAM_BITRATETYPE  *pVideoBitrate = (OMX_VIDEO_PARAM_BITRATETYPE *)pComponentParameterStructure;
+        OMX_U32                       nPortIndex    = pVideoBitrate->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDef      = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pPortDef = &(pExynosComponent->pExynosPort[nPortIndex].portDefinition);
+            pVideoEnc->eControlRate[nPortIndex] = pVideoBitrate->eControlRate;
+            pPortDef->format.video.nBitrate = pVideoBitrate->nTargetBitrate;
+        }
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoQuantization:
+    {
+        OMX_VIDEO_PARAM_QUANTIZATIONTYPE *pVideoQuantization = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)pComponentParameterStructure;
+        OMX_U32                           nPortIndex         = pVideoQuantization->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE     *pPortDef           = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            pPortDef = &pExynosPort->portDefinition;
+
+            pVideoEnc->quantization.nQpI = pVideoQuantization->nQpI;
+            pVideoEnc->quantization.nQpP = pVideoQuantization->nQpP;
+            pVideoEnc->quantization.nQpB = pVideoQuantization->nQpB;
+        }
+        ret = OMX_ErrorNone;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamAllocateNativeHandle:
+#endif
+    // (2018-05-28) to follow H.264 encoder implementation.
+    case OMX_IndexParamStoreMetaDataBuffer:
+    {
+        ret = Exynos_OSAL_SetParameter(hComponent, nIndex, pComponentParameterStructure);
+    }
+        break;
+    case OMX_IndexVendorNeedContigMemory:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *pPortMemType = (EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *)pComponentParameterStructure;
+        OMX_U32                             nPortIndex   = pPortMemType->nPortIndex;
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortMemType, sizeof(EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        pExynosPort->bNeedContigMem = pPortMemType->bNeedContigMem;
+    }
+        break;
+    case OMX_IndexParamVideoIntraRefresh:
+    {
+        OMX_VIDEO_PARAM_INTRAREFRESHTYPE *pIntraRefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)pComponentParameterStructure;
+        OMX_U32                           nPortIndex    = pIntraRefresh->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pIntraRefresh, sizeof(OMX_VIDEO_PARAM_INTRAREFRESHTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pIntraRefresh->eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) {
+            pVideoEnc->intraRefresh.eRefreshMode    = pIntraRefresh->eRefreshMode;
+            pVideoEnc->intraRefresh.nCirMBs         = pIntraRefresh->nCirMBs;
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_VIDEO_IntraRefreshCyclic Enable, nCirMBs: %d",
+                            pVideoEnc->intraRefresh.nCirMBs);
+        } else {
+            ret = OMX_ErrorUnsupportedSetting;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamEnableBlurFilter:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_BLURFILTER *pBlurMode  = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_BLURFILTER *)pComponentParameterStructure;
+        OMX_U32                                   nPortIndex = pBlurMode->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pBlurMode, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_BLURFILTER));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pVideoEnc->bUseBlurFilter = pBlurMode->bUseBlurFilter;
+    }
+        break;
+    case OMX_IndexParamRotationInfo:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO *pRotationInfo = (EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO *)pComponentParameterStructure;
+        OMX_U32                               nPortIndex    = pRotationInfo->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pRotationInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pRotationInfo->eRotationType != ROTATE_0) &&
+                (pRotationInfo->eRotationType != ROTATE_90) &&
+                (pRotationInfo->eRotationType != ROTATE_180) &&
+                (pRotationInfo->eRotationType != ROTATE_270)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] can't accecpt a rotation value(%d)", pExynosComponent, __FUNCTION__,
+                    pRotationInfo->eRotationType);
+            ret = OMX_ErrorUnsupportedSetting;
+            goto EXIT;
+        }
+
+        pVideoEnc->eRotationType = pRotationInfo->eRotationType;
+    }
+        break;
+
+    case OMX_IndexParamVideoInit:
+    {
+        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        /* ret = OMX_ErrorUndefined; */
+        /* Exynos_OSAL_Memcpy(&pExynosComponent->portParam, portParam, sizeof(OMX_PORT_PARAM_TYPE)); */
+    }
+        break;
+    case OMX_IndexParamPriorityMgmt:
+    {
+        OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)pComponentParameterStructure;
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE));
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+
+        pExynosComponent->compPriority.nGroupID = compPriority->nGroupID;
+        pExynosComponent->compPriority.nGroupPriority = compPriority->nGroupPriority;
+    }
+        break;
+    case OMX_IndexParamCompBufferSupplier:
+    {
+        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)pComponentParameterStructure;
+        OMX_U32           portIndex = bufferSupplier->nPortIndex;
+        EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+
+        if (portIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        ret = Exynos_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
+        if (ret != OMX_ErrorNone) {
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyUnspecified) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+        if (CHECK_PORT_TUNNELED(pExynosPort) == 0) {
+            ret = OMX_ErrorNone; /*OMX_ErrorNone ?????*/
+            goto EXIT;
+        }
+
+        if (pExynosPort->portDefinition.eDir == OMX_DirInput) {
+            if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) {
+                /*
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    ret = OMX_ErrorNone;
+                }
+                */
+                pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER;
+                bufferSupplier->nPortIndex = pExynosPort->tunneledPort;
+                ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier);
+                goto EXIT;
+            } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) {
+                ret = OMX_ErrorNone;
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER;
+                    bufferSupplier->nPortIndex = pExynosPort->tunneledPort;
+                    ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier);
+                }
+                goto EXIT;
+            }
+        } else if (pExynosPort->portDefinition.eDir == OMX_DirOutput) {
+            if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) {
+                ret = OMX_ErrorNone;
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER;
+                    ret = OMX_ErrorNone;
+                }
+                goto EXIT;
+            } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) {
+                /*
+                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+                    ret = OMX_ErrorNone;
+                }
+                */
+                pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER;
+                ret = OMX_ErrorNone;
+                goto EXIT;
+            }
+        }
+    }
+        break;
+    default:
+    {
+        ret = OMX_ErrorUnsupportedIndex;
+        goto EXIT;
+    }
+        break;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264WFDEnc_GetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoAVCIntraPeriod:
+    {
+        OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
+        OMX_U32                          portIndex       = pAVCIntraPeriod->nPortIndex;
+
+        if ((portIndex != OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pAVCIntraPeriod->nIDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
+            pAVCIntraPeriod->nPFrames = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames;
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pH264Enc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pH264Enc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pH264Enc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pH264Enc->qpRangeP.nMaxQP;
+        pQpRange->qpRangeB.nMinQP = pH264Enc->qpRangeB.nMinQP;
+        pQpRange->qpRangeB.nMaxQP = pH264Enc->qpRangeB.nMaxQP;
+    }
+        break;
+    case OMX_IndexConfigVideoTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pDstTemporalSVC = (EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *)pComponentConfigStructure;
+        EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pSrcTemporalSVC = &pH264Enc->TemporalSVC;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcTemporalSVC->nKeyFrameInterval = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
+        pSrcTemporalSVC->nMinQuantizer = pH264Enc->qpRangeI.nMinQP;
+        pSrcTemporalSVC->nMaxQuantizer = pH264Enc->qpRangeI.nMaxQP;
+
+        Exynos_OSAL_Memcpy(((char *)pDstTemporalSVC) + nOffset,
+                           ((char *)pSrcTemporalSVC) + nOffset,
+                           sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC) - nOffset);
+    }
+        break;
+
+    // below is from Exynos_OMX_VideoEncodeGetConfig
+    case OMX_IndexConfigVideoBitrate:
+    {
+        OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure;
+        OMX_U32                       nPortIndex     = pConfigBitrate->nPortIndex;
+        EXYNOS_OMX_BASEPORT          *pExynosPort    = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            pConfigBitrate->nEncodeBitrate = pExynosPort->portDefinition.format.video.nBitrate;
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoFramerate:
+    {
+        OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure;
+        OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
+        EXYNOS_OMX_BASEPORT      *pExynosPort      = NULL;
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+        pConfigFramerate->xEncodeFramerate = pExynosPort->portDefinition.format.video.xFramerate;
+    }
+        break;
+    case OMX_IndexVendorGetBufferFD:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO *pBufferInfo = (EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pBufferInfo, sizeof(EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pBufferInfo->fd = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pBufferInfo->pVirAddr);
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexConfigVideoColorAspects:
+    {
+        ret = Exynos_OSAL_GetConfig(hComponent, nIndex, pComponentConfigStructure);
+    }
+        break;
+#endif
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264WFDEnc_SetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc           = NULL;
+    EXYNOS_MFC_H264WFDENC_HANDLE    *pMFCH264WFDHandle  = NULL;
+    ExynosVideoEncOps               *pEncOps            = NULL;
+    int                              i;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    if (&(pH264Enc->hMFCH264Handle) == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMFCH264WFDHandle = (EXYNOS_MFC_H264WFDENC_HANDLE *)&pH264Enc->hMFCH264Handle;
+
+    if (pMFCH264WFDHandle->pEncOps == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pEncOps = (ExynosVideoEncOps *)pMFCH264WFDHandle->pEncOps;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1;
+        pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = nPFrames;
+        pEncOps->Set_IDRPeriod(pH264Enc->hMFCH264Handle.hMFCHandle, nPFrames + 1);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] IDR period: %d", pExynosComponent, __FUNCTION__, nPFrames + 1);
+        ret = OMX_ErrorNone ;
+    }
+        break;
+    case OMX_IndexConfigVideoAVCIntraPeriod:
+    {
+        OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
+        OMX_U32                          portIndex       = pAVCIntraPeriod->nPortIndex;
+
+        if ((portIndex != OUTPUT_PORT_INDEX)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            if (pAVCIntraPeriod->nIDRPeriod == (pAVCIntraPeriod->nPFrames + 1)) {
+                pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = pAVCIntraPeriod->nPFrames;
+                pEncOps->Set_IDRPeriod(pMFCH264WFDHandle->hMFCHandle, pAVCIntraPeriod->nIDRPeriod);
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] IDR period: %d", pExynosComponent, __FUNCTION__, pAVCIntraPeriod->nIDRPeriod);
+            } else {
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+            }
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+        ExynosVideoQPRange     qpRange;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP) ||
+            (pQpRange->qpRangeB.nMinQP > pQpRange->qpRangeB.nMaxQP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d], B[min:%d, max:%d])", __FUNCTION__,
+                                                pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                                                pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP,
+                                                pQpRange->qpRangeB.nMinQP, pQpRange->qpRangeB.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pH264Enc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pH264Enc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pH264Enc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pH264Enc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+        pH264Enc->qpRangeB.nMinQP = pQpRange->qpRangeB.nMinQP;
+        pH264Enc->qpRangeB.nMaxQP = pQpRange->qpRangeB.nMaxQP;
+
+        qpRange.QpMin_I = pQpRange->qpRangeI.nMinQP;
+        qpRange.QpMax_I = pQpRange->qpRangeI.nMaxQP;
+        qpRange.QpMin_P = pQpRange->qpRangeP.nMinQP;
+        qpRange.QpMax_P = pQpRange->qpRangeP.nMaxQP;
+        qpRange.QpMin_B = pQpRange->qpRangeB.nMinQP;
+        qpRange.QpMax_B = pQpRange->qpRangeB.nMaxQP;
+
+        pEncOps->Set_QpRange(pMFCH264WFDHandle->hMFCHandle, qpRange);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qp range: I(%d, %d), P(%d, %d), B(%d, %d)",
+                                                pExynosComponent, __FUNCTION__,
+                                                qpRange.QpMin_I, qpRange.QpMax_I,
+                                                qpRange.QpMin_P, qpRange.QpMax_P,
+                                                qpRange.QpMin_B, qpRange.QpMax_B);
+    }
+        break;
+    case OMX_IndexConfigVideoTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pDstTemporalSVC = &pH264Enc->TemporalSVC;
+        EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pSrcTemporalSVC = (EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *)pComponentConfigStructure;
+        ExynosVideoQPRange qpRange;
+        TemporalLayerShareBuffer TemporalSVC;
+
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pH264Enc->hMFCH264Handle.bTemporalSVC == OMX_FALSE) ||
+            (pSrcTemporalSVC->nTemporalLayerCount > OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = pSrcTemporalSVC->nKeyFrameInterval - 1;
+
+        pH264Enc->qpRangeI.nMinQP = pSrcTemporalSVC->nMinQuantizer;
+        pH264Enc->qpRangeI.nMaxQP = pSrcTemporalSVC->nMaxQuantizer;
+        pH264Enc->qpRangeP.nMinQP = pSrcTemporalSVC->nMinQuantizer;
+        pH264Enc->qpRangeP.nMaxQP = pSrcTemporalSVC->nMaxQuantizer;
+        pH264Enc->qpRangeB.nMinQP = pSrcTemporalSVC->nMinQuantizer;
+        pH264Enc->qpRangeB.nMaxQP = pSrcTemporalSVC->nMaxQuantizer;
+
+        Exynos_OSAL_Memcpy(((char *)pDstTemporalSVC) + nOffset,
+                           ((char *)pSrcTemporalSVC) + nOffset,
+                           sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC) - nOffset);
+
+        qpRange.QpMin_I = pDstTemporalSVC->nMinQuantizer;
+        qpRange.QpMax_I = pDstTemporalSVC->nMaxQuantizer;
+        qpRange.QpMin_P = pDstTemporalSVC->nMinQuantizer;
+        qpRange.QpMax_P = pDstTemporalSVC->nMaxQuantizer;
+        qpRange.QpMin_B = pDstTemporalSVC->nMinQuantizer;
+        qpRange.QpMax_B = pDstTemporalSVC->nMaxQuantizer;
+
+        pEncOps->Set_QpRange(pMFCH264WFDHandle->hMFCHandle, qpRange);
+        pEncOps->Set_IDRPeriod(pMFCH264WFDHandle->hMFCHandle, pDstTemporalSVC->nKeyFrameInterval);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // qp range: I(%d, %d), P(%d, %d), B(%d, %d)",
+                                                pExynosComponent, __FUNCTION__,
+                                                qpRange.QpMin_I, qpRange.QpMax_I,
+                                                qpRange.QpMin_P, qpRange.QpMax_P,
+                                                qpRange.QpMin_B, qpRange.QpMax_B);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // IDR period: %d", pExynosComponent, __FUNCTION__, pDstTemporalSVC->nKeyFrameInterval);
+
+        /* Temporal SVC */
+        Exynos_OSAL_Memset(&TemporalSVC, 0, sizeof(TemporalLayerShareBuffer));
+
+        TemporalSVC.nTemporalLayerCount = (unsigned int)pDstTemporalSVC->nTemporalLayerCount;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // layer count: %d", pExynosComponent, __FUNCTION__, TemporalSVC.nTemporalLayerCount);
+
+        for (i = 0; i < OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS; i++) {
+            TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)pDstTemporalSVC->nTemporalLayerBitrateRatio[i];
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // bitrate ratio[%d]: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    i, TemporalSVC.nTemporalLayerBitrateRatio[i]);
+        }
+        if (pEncOps->Set_LayerChange(pMFCH264WFDHandle->hMFCHandle, TemporalSVC) != VIDEO_ERROR_NONE)
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Not supported control: Set_LayerChange", pExynosComponent, __FUNCTION__);
+    }
+        break;
+    case OMX_IndexConfigVideoRoiInfo:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *pRoiInfo = (EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *)pComponentConfigStructure;
+        RoiInfoShareBuffer               RoiInfo;
+
+        if (pRoiInfo->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pH264Enc->hMFCH264Handle.bRoiInfo == OMX_FALSE) ||
+            ((pRoiInfo->bUseRoiInfo == OMX_TRUE) &&
+            ((pRoiInfo->nRoiMBInfoSize <= 0) ||
+            (pRoiInfo->pRoiMBInfo == NULL)))) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: bUseRoiInfo %d nRoiMBInfoSize %d pRoiMBInfo %p", __FUNCTION__, __LINE__,
+                                                    pRoiInfo->bUseRoiInfo, pRoiInfo->nRoiMBInfoSize, pRoiInfo->pRoiMBInfo);
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+        }
+
+        Exynos_OSAL_Memset(&RoiInfo, 0, sizeof(RoiInfo));
+        RoiInfo.pRoiMBInfo     = (OMX_U64)(unsigned long)(((OMX_U8 *)pComponentConfigStructure) + sizeof(EXYNOS_OMX_VIDEO_CONFIG_ROIINFO));
+        RoiInfo.nRoiMBInfoSize = pRoiInfo->nRoiMBInfoSize;
+        RoiInfo.nUpperQpOffset = pRoiInfo->nUpperQpOffset;
+        RoiInfo.nLowerQpOffset = pRoiInfo->nLowerQpOffset;
+        RoiInfo.bUseRoiInfo    = (pRoiInfo->bUseRoiInfo == OMX_TRUE)? VIDEO_TRUE:VIDEO_FALSE;
+        if (pEncOps->Set_RoiInfo != NULL) {
+            pEncOps->Set_RoiInfo(pMFCH264WFDHandle->hMFCHandle, &RoiInfo);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] roi info: %s", pExynosComponent, __FUNCTION__,
+                                                    (RoiInfo.bUseRoiInfo == VIDEO_TRUE)? "enabled":"disabled");
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s]: Not supported control: Set_RoiInfo",
+                                                    pExynosComponent, __FUNCTION__);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoBitrate:
+    {
+        OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure;
+        OMX_U32                       nPortIndex     = pConfigBitrate->nPortIndex;
+        EXYNOS_OMX_BASEPORT          *pExynosPort    = NULL;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            if (pVideoEnc->eControlRate[nPortIndex] == OMX_Video_ControlRateDisable) {
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Rate control(eControlRate) is disable. can not change a bitrate",
+                                                    pExynosComponent, __FUNCTION__);
+                goto EXIT;
+            }
+
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            pExynosPort->portDefinition.format.video.nBitrate = pConfigBitrate->nEncodeBitrate;
+            pEncOps->Set_BitRate(pH264Enc->hMFCH264Handle.hMFCHandle, pConfigBitrate->nEncodeBitrate);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bitrate: %d", pExynosComponent, __FUNCTION__, pConfigBitrate->nEncodeBitrate);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoFramerate:
+    {
+        OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure;
+        OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
+        EXYNOS_OMX_BASEPORT      *pExynosPort      = NULL;
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((nPortIndex == INPUT_PORT_INDEX) &&
+            ((pConfigFramerate->xEncodeFramerate >> 16) <= 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] xFramerate is invalid(%d)",
+                                              pExynosComponent, __FUNCTION__, pConfigFramerate->xEncodeFramerate >> 16);
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+        pExynosPort->portDefinition.format.video.xFramerate = pConfigFramerate->xEncodeFramerate;
+
+        pEncOps->Set_FrameRate(pH264Enc->hMFCH264Handle.hMFCHandle, (pConfigFramerate->xEncodeFramerate) >> 16);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] framerate: %d", pExynosComponent, __FUNCTION__, (pConfigFramerate->xEncodeFramerate) >> 16);
+    }
+        break;
+    case OMX_IndexConfigVideoIntraVOPRefresh:
+    {
+        OMX_CONFIG_INTRAREFRESHVOPTYPE *pIntraRefreshVOP = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pComponentConfigStructure;
+        OMX_U32                         nPortIndex       = pIntraRefreshVOP->nPortIndex;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        } else {
+            pVideoEnc->IntraRefreshVOP = pIntraRefreshVOP->IntraRefreshVOP;
+        }
+
+        pEncOps->Set_FrameType(pMFCH264WFDHandle->hMFCHandle, VIDEO_FRAME_I);
+        pVideoEnc->IntraRefreshVOP = OMX_FALSE;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] VOP Refresh", pExynosComponent, __FUNCTION__);
+    }
+        break;
+    case OMX_IndexConfigOperatingRate:  /* since M version */
+    {
+        OMX_PARAM_U32TYPE *pConfigRate = (OMX_PARAM_U32TYPE *)pComponentConfigStructure;
+        OMX_U32            xFramerate  = 0;
+
+        ret = Exynos_OMX_Check_SizeVersion(pConfigRate, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        xFramerate = pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.xFramerate;
+        if (xFramerate == 0) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] xFramerate is zero. can't calculate QosRatio",
+                                                pExynosComponent, __FUNCTION__);
+            pVideoEnc->nQosRatio = 100;
+        } else {
+            pVideoEnc->nQosRatio = (OMX_U32)((pConfigRate->nU32 / (double)xFramerate) * 100);
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] operating rate(%.1lf) / frame rate(%.1lf) / ratio(%d)",pExynosComponent, __FUNCTION__,
+                                                pConfigRate->nU32 / (double)65536, xFramerate / (double)65536, pVideoEnc->nQosRatio);
+
+        pEncOps->Set_QosRatio(pMFCH264WFDHandle->hMFCHandle, pVideoEnc->nQosRatio);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qos ratio: %d", pExynosComponent, __FUNCTION__, pVideoEnc->nQosRatio);
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexConfigBlurInfo:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_BLURINFO *pBlurMode   = (EXYNOS_OMX_VIDEO_CONFIG_BLURINFO *)pComponentConfigStructure;
+        OMX_U32                           nPortIndex  = pBlurMode->nPortIndex;
+        EXYNOS_OMX_BASEPORT              *pExynosPort = NULL;
+
+        int nEncResol;
+
+        ret = Exynos_OMX_Check_SizeVersion(pBlurMode, sizeof(EXYNOS_OMX_VIDEO_CONFIG_BLURINFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+        nEncResol   = pExynosPort->portDefinition.format.video.nFrameWidth * pExynosPort->portDefinition.format.video.nFrameHeight;
+
+        if (pVideoEnc->bUseBlurFilter == OMX_TRUE) {
+            if ((pBlurMode->eBlurMode & BLUR_MODE_DOWNUP) &&
+                (nEncResol < (int)pBlurMode->eTargetResol)) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Resolution(%d x %d) is smaller than target resolution",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    pExynosPort->portDefinition.format.video.nFrameWidth,
+                                                    pExynosPort->portDefinition.format.video.nFrameHeight);
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+            }
+
+            pVideoEnc->eBlurMode = pBlurMode->eBlurMode;
+            pVideoEnc->eBlurResol = pBlurMode->eTargetResol;
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Blur Filter is not enabled, it will be discard",
+                                                    pExynosComponent, __FUNCTION__);
+        }
+
+        ret = (OMX_ERRORTYPE)OMX_ErrorNoneExpiration;
+    }
+        break;
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+    if (ret == (OMX_ERRORTYPE)OMX_ErrorNoneExpiration)
+        ret = OMX_ErrorNone;
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264WFDEnc_GetExtensionIndex(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE *pIndexType)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_TEMPORALSVC) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexConfigVideoTemporalSVC;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_VIDEO_AVC_ENABLE_TEMPORALSVC) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamVideoAVCEnableTemporalSVC;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_ROIINFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexConfigVideoRoiInfo;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_VIDEO_ENABLE_ROIINFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamVideoEnableRoiInfo;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_PVC) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamVideoEnablePVC;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamPrependSPSPPSToIDR;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+#endif
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexConfigVideoIntraPeriod;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_NEED_CONTIG_MEMORY) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorNeedContigMemory;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_GET_BUFFER_FD) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorGetBufferFD;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_VIDEO_QPRANGE_TYPE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamVideoQPRange;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_QPRANGE_TYPE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigVideoQPRange;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_BLUR_FILTER) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamEnableBlurFilter;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_BLUR_INFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigBlurInfo;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ROATION_INFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamRotationInfo;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamStoreMetaDataBuffer;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_COLOR_ASPECTS_INFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigVideoColorAspects;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+#endif
+
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ALLOCATE_NATIVE_HANDLE) == 0) {
+        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamAllocateNativeHandle;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorBadParameter;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264WFDEnc_ComponentRoleEnum(
+    OMX_HANDLETYPE   hComponent,
+    OMX_U8          *cRole,
+    OMX_U32          nIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cRole == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_WFD_ENC_ROLE);
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorNoMore;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_H264WFDEnc_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc           = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_H264WFDENC_HANDLE    *pMFCH264Handle     = &pH264Enc->hMFCH264Handle;
+    OMX_COLOR_FORMATTYPE             eColorFormat       = pInputPort->portDefinition.format.video.eColorFormat;
+
+    FunctionIn();
+
+    if (pInputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+        /* metadata buffer */
+        pInputPort->bufferProcessType = BUFFER_SHARE;
+
+#ifdef USE_ANDROID
+        if ((pInputPort->eMetaDataType == METADATA_TYPE_DATA) &&
+            (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)) {
+            pInputPort->eMetaDataType     = METADATA_TYPE_GRAPHIC;  /* AndoridOpaque means GrallocSource */
+            pInputPort->bufferProcessType = BUFFER_COPY;  /* will determine a process type after getting a hal format at handle */
+        }
+#endif
+    } else {
+        /* data buffer */
+        pInputPort->bufferProcessType = BUFFER_COPY;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                            pInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                            pInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                            pInputPort->portDefinition.format.video.nBitrate,
+                                                                                            pInputPort->portDefinition.format.video.xFramerate);
+
+    Exynos_SetPlaneToPort(pInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    Exynos_SetPlaneToPort(pOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+
+    Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pH264Enc->hMFCH264Handle.indexTimestamp       = 0;
+    pH264Enc->hMFCH264Handle.outputIndexTimestamp = 0;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_H264WFDEnc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc           = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    FunctionIn();
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE hComponent,
+    OMX_STRING     componentName)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_OMX_BASEPORT           *pInputPort       = NULL;
+    EXYNOS_OMX_BASEPORT           *pOutputPort      = NULL;
+    EXYNOS_H264WFDENC_HANDLE      *pH264Enc         = NULL;
+    OMX_BOOL                       bSecureMode      = OMX_FALSE;
+
+    ExynosVideoInstInfo           *pVideoInstInfo = NULL;
+
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_WFD_ENC, componentName) == 0) {
+        bSecureMode = OMX_FALSE;
+    } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_WFD_DRM_ENC, componentName) == 0) {
+        bSecureMode = OMX_TRUE;
+    } else {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit for WFD (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = (bSecureMode == OMX_TRUE)? HW_VIDEO_ENC_SECURE_CODEC:HW_VIDEO_ENC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pH264Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264WFDENC_HANDLE));
+    if (pH264Enc == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pH264Enc, 0, sizeof(EXYNOS_H264WFDENC_HANDLE));
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pH264Enc;
+    pH264Enc->qpRangeI.nMinQP = 5;
+    pH264Enc->qpRangeI.nMaxQP = 50;
+    pH264Enc->qpRangeP.nMinQP = 5;
+    pH264Enc->qpRangeP.nMaxQP = 50;
+    pH264Enc->qpRangeB.nMinQP = 5;
+    pH264Enc->qpRangeB.nMaxQP = 50;
+
+    pVideoEnc->quantization.nQpI = 29;
+    pVideoEnc->quantization.nQpP = 30;
+    pVideoEnc->quantization.nQpB = 32;
+
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_WFD_DRM_ENC);
+    else
+        Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_WFD_ENC);
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+#ifdef USE_SINGLE_PLANE_IN_DRM
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        pExynosPort->ePlaneType = PLANE_SINGLE;
+#endif
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pH264Enc->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
+        pH264Enc->AVCComponent[i].nPortIndex = i;
+        pH264Enc->AVCComponent[i].eProfile   = OMX_VIDEO_AVCProfileBaseline;
+        pH264Enc->AVCComponent[i].eLevel     = OMX_VIDEO_AVCLevel31;
+
+        pH264Enc->AVCComponent[i].nPFrames      = 29;
+        pH264Enc->AVCComponent[i].nBFrames      = 0;
+        pH264Enc->AVCComponent[i].nRefFrames    = 1;
+    }
+
+    Exynos_OSAL_Memset(&pH264Enc->TemporalSVC, 0, sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC));
+    INIT_SET_SIZE_VERSION(&pH264Enc->TemporalSVC, EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC);
+    pH264Enc->TemporalSVC.nKeyFrameInterval = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
+    pH264Enc->TemporalSVC.nTemporalLayerCount    = 0;
+    pH264Enc->nMaxTemporalLayerCount             = 0;
+    pH264Enc->hMFCH264Handle.bTemporalSVC         = OMX_FALSE;
+    for (i = 0; i < OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS; i++) {
+        pH264Enc->TemporalSVC.nTemporalLayerBitrateRatio[i] =
+                                pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.nBitrate;
+    }
+    pH264Enc->TemporalSVC.nMinQuantizer = pH264Enc->qpRangeI.nMinQP;
+    pH264Enc->TemporalSVC.nMaxQuantizer = pH264Enc->qpRangeI.nMaxQP;
+
+    pH264Enc->hMFCH264Handle.videoInstInfo.bOTFMode = VIDEO_TRUE;
+
+    pOMXComponent->GetParameter      = &Exynos_H264WFDEnc_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_H264WFDEnc_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_H264WFDEnc_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_H264WFDEnc_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_H264WFDEnc_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_H264WFDEnc_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_H264WFDEnc_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264WFDEnc_Terminate;
+
+    pVideoEnc->exynos_codec_start         = &H264WFDCodecStart;
+    pVideoEnc->exynos_codec_stop          = &H264WFDCodecStop;
+
+    pVideoEnc->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
+
+    pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoEnc->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pH264Enc);
+        pH264Enc = pVideoEnc->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pH264Enc->hMFCH264Handle.videoInstInfo.eCodecType = VIDEO_CODING_AVC;
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        pH264Enc->hMFCH264Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pH264Enc->hMFCH264Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pH264Enc->hMFCH264Handle.videoInstInfo), VIDEO_FALSE /* enc */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pH264Enc);
+        pH264Enc = pVideoEnc->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for enc : ext(%d)/temporal-svc(%d))/qp-range(%d)",
+                                            pExynosComponent, __FUNCTION__,
+                                            (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.nSpareSize),
+                                            (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport));
+
+    if (pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.nSpareSize > 0)
+        pVideoEnc->nInbufSpareSize = pH264Enc->hMFCH264Handle.videoInstInfo.supportInfo.enc.nSpareSize;
+
+    Exynos_Input_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+    pInputPort     = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pOutputPort    = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    pVideoInstInfo = &(pH264Enc->hMFCH264Handle.videoInstInfo);
+
+    pVideoInstInfo->nSize        = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth       = pInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight      = pInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate     = pInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate   = pInputPort->portDefinition.format.video.xFramerate;
+
+    /* H.264 Codec Open */
+    ret = H264WFDCodecOpen(pH264Enc, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc           = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent       = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent    = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoEnc           = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pH264Enc = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pH264Enc != NULL) {
+        H264WFDCodecClose(pH264Enc);
+        Exynos_OSAL_Free(pH264Enc);
+        pH264Enc = pVideoEnc->hCodecHandle = NULL;
+    }
+
+    ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosInputPort  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosOutputPort = NULL;
+    int i = 0, j = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] OMX_ErrorBadParameter (0x%x) Line:%d", __FUNCTION__, ret, __LINE__);
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] OMX_ErrorBadParameter (0x%x) Line:%d", __FUNCTION__, ret, __LINE__);
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    INIT_SET_SIZE_VERSION(&pExynosComponent->portParam, OMX_PORT_PARAM_TYPE);
+    pExynosComponent->portParam.nPorts = ALL_PORT_NUM;
+    pExynosComponent->portParam.nStartPortNumber = INPUT_PORT_INDEX;
+
+    pExynosPort = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM);
+    if (pExynosPort == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosPort, 0, sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM);
+    pExynosComponent->pExynosPort = pExynosPort;
+
+    /* Input Port */
+    pExynosInputPort = &pExynosPort[INPUT_PORT_INDEX];
+
+    pExynosInputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
+    if (pExynosInputPort->extendBufferHeader == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosInputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
+
+    pExynosInputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM);
+    if (pExynosInputPort->bufferStateAllocate == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM);
+
+    pExynosInputPort->bufferSemID = NULL;
+    pExynosInputPort->assignedBufferNum = 0;
+    pExynosInputPort->portState = EXYNOS_OMX_PortStateLoaded;
+    pExynosInputPort->tunneledComponent = NULL;
+    pExynosInputPort->tunneledPort = 0;
+    pExynosInputPort->tunnelBufferNum = 0;
+    pExynosInputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
+    pExynosInputPort->tunnelFlags = 0;
+    pExynosInputPort->supportFormat = NULL;
+    pExynosInputPort->bNeedContigMem = OMX_FALSE;
+    pExynosInputPort->latestTimeStamp = DEFAULT_TIMESTAMP_VAL;
+
+    INIT_SET_SIZE_VERSION(&pExynosInputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
+    pExynosInputPort->portDefinition.nPortIndex = INPUT_PORT_INDEX;
+    pExynosInputPort->portDefinition.eDir = OMX_DirInput;
+    pExynosInputPort->portDefinition.nBufferCountActual = 0;
+    pExynosInputPort->portDefinition.nBufferCountMin = 0;
+    pExynosInputPort->portDefinition.nBufferSize = 0;
+    pExynosInputPort->portDefinition.bEnabled = OMX_FALSE;
+    pExynosInputPort->portDefinition.bPopulated = OMX_FALSE;
+    pExynosInputPort->portDefinition.eDomain = OMX_PortDomainMax;
+    pExynosInputPort->portDefinition.bBuffersContiguous = OMX_FALSE;
+    pExynosInputPort->portDefinition.nBufferAlignment = 0;
+
+    /* Output Port */
+    pExynosOutputPort = &pExynosPort[OUTPUT_PORT_INDEX];
+
+    pExynosOutputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
+    if (pExynosOutputPort->extendBufferHeader == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosOutputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
+
+    pExynosOutputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM);
+    if (pExynosOutputPort->bufferStateAllocate == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosOutputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM);
+
+    pExynosOutputPort->bufferSemID = NULL;
+    pExynosOutputPort->assignedBufferNum = 0;
+    pExynosOutputPort->portState = EXYNOS_OMX_PortStateLoaded;
+    pExynosOutputPort->tunneledComponent = NULL;
+    pExynosOutputPort->tunneledPort = 0;
+    pExynosOutputPort->tunnelBufferNum = 0;
+    pExynosOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
+    pExynosOutputPort->tunnelFlags = 0;
+    pExynosOutputPort->supportFormat = NULL;
+    pExynosOutputPort->bNeedContigMem = OMX_FALSE;
+    pExynosOutputPort->latestTimeStamp = DEFAULT_TIMESTAMP_VAL;
+
+    INIT_SET_SIZE_VERSION(&pExynosOutputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
+    pExynosOutputPort->portDefinition.nPortIndex = OUTPUT_PORT_INDEX;
+    pExynosOutputPort->portDefinition.eDir = OMX_DirOutput;
+    pExynosOutputPort->portDefinition.nBufferCountActual = 0;
+    pExynosOutputPort->portDefinition.nBufferCountMin = 0;
+    pExynosOutputPort->portDefinition.nBufferSize = 0;
+    pExynosOutputPort->portDefinition.bEnabled = OMX_FALSE;
+    pExynosOutputPort->portDefinition.bPopulated = OMX_FALSE;
+    pExynosOutputPort->portDefinition.eDomain = OMX_PortDomainMax;
+    pExynosOutputPort->portDefinition.bBuffersContiguous = OMX_FALSE;
+    pExynosOutputPort->portDefinition.nBufferAlignment = 0;
+
+    pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+    pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
+    pExynosComponent->checkTimeStamp.startTimeStamp = 0;
+    pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
+
+    pOMXComponent->EmptyThisBuffer = &Exynos_OMX_EmptyThisBuffer;
+    pOMXComponent->FillThisBuffer  = &Exynos_OMX_FillThisBuffer;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent != NULL) &&
+        (pExynosComponent->pExynosPort != NULL)) {
+        for (i = 0; i < ALL_PORT_NUM; i++) {
+            pExynosPort = &pExynosComponent->pExynosPort[i];
+
+            Exynos_OSAL_Free(pExynosPort->bufferStateAllocate);
+            pExynosPort->bufferStateAllocate = NULL;
+            Exynos_OSAL_Free(pExynosPort->extendBufferHeader);
+            pExynosPort->extendBufferHeader = NULL;
+        }
+
+        Exynos_OSAL_Free(pExynosComponent->pExynosPort);
+        pExynosComponent->pExynosPort = NULL;
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_Port_Destructor(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+
+    int i = 0, j = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    for (i = 0; i < ALL_PORT_NUM; i++) {
+        pExynosPort = &pExynosComponent->pExynosPort[i];
+
+        Exynos_OSAL_Free(pExynosPort->bufferStateAllocate);
+        pExynosPort->bufferStateAllocate = NULL;
+        Exynos_OSAL_Free(pExynosPort->extendBufferHeader);
+        pExynosPort->extendBufferHeader = NULL;
+    }
+
+    Exynos_OSAL_Free(pExynosComponent->pExynosPort);
+    pExynosComponent->pExynosPort = NULL;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT      *pExynosPort      = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_U32                   i                = 0;
+
+    pExynosComponent->pCallbacks->EmptyBufferDone(pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                bufferHeader);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bufferHeader: %p", pExynosComponent, __FUNCTION__, bufferHeader);
+
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (bufferHeader == inputBufArray[i].pBuffer) {
+            inputBufArray[i].bInOMX = OMX_FALSE;
+            break;
+        }
+    }
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT      *pExynosPort      = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                   i                = 0;
+
+    pExynosComponent->pCallbacks->FillBufferDone(pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                bufferHeader);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bufferHeader: %p", pExynosComponent, __FUNCTION__, bufferHeader);
+
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (bufferHeader == outputBufArray[i].pBuffer) {
+            outputBufArray[i].bInOMX = OMX_FALSE;
+            break;
+        }
+    }
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BufferFlushProcess(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_S32             nPortIndex,
+    OMX_BOOL            bEvent)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    OMX_S32                   nIndex            = 0;
+
+    OMX_U32 i = 0, cnt = 0;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    cnt = (nPortIndex == ALL_PORT_INDEX) ? ALL_PORT_NUM : 1;
+    for (i = 0; i < cnt; i++) {
+        if (nPortIndex == ALL_PORT_INDEX)
+            nIndex = i;
+        else
+            nIndex = nPortIndex;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Flush %s Port", pExynosComponent, __FUNCTION__,
+                                                (nIndex == INPUT_PORT_INDEX)? "input":"output");
+
+        ret = pExynosComponent->exynos_BufferFlush(pOMXComponent, nIndex, bEvent);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port is flushed", pExynosComponent, __FUNCTION__,
+                                                (nIndex == INPUT_PORT_INDEX)? "input":"output");
+        if (ret == OMX_ErrorNone) {
+            pExynosComponent->pExynosPort[nIndex].portState = EXYNOS_OMX_PortStateIdle;
+
+            if (bEvent == OMX_TRUE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(EventCmdComplete/Flush/%s port)",
+                                                        pExynosComponent, __FUNCTION__, (nIndex == INPUT_PORT_INDEX)? "input":"output");
+                pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                        pExynosComponent->callbackData,
+                                                        OMX_EventCmdComplete,
+                                                        OMX_CommandFlush, nIndex, NULL);
+            }
+        }
+    }
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        if ((pOMXComponent != NULL) &&
+            (pExynosComponent != NULL)) {
+            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                    pExynosComponent->callbackData,
+                                                    OMX_EventError,
+                                                    ret, 0, NULL);
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_EnablePort(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_S32             nPortIndex)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+
+    OMX_U32 i = 0;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_PortEnableProcess(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_S32             nPortIndex)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+    OMX_S32                   nIndex           = 0;
+
+    OMX_U32 i = 0, cnt = 0;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    cnt = (nPortIndex == ALL_PORT_INDEX) ? ALL_PORT_NUM : 1;
+    for (i = 0; i < cnt; i++) {
+        if (nPortIndex == ALL_PORT_INDEX)
+            nIndex = i;
+        else
+            nIndex = nPortIndex;
+    }
+
+EXIT:
+    if ((ret != OMX_ErrorNone) &&
+        (pOMXComponent != NULL) &&
+        (pExynosComponent != NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError,
+                                                ret, 0, NULL);
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_DisablePort(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_S32             nPortIndex)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    pExynosPort->portDefinition.bEnabled = OMX_FALSE;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_PortDisableProcess(
+    OMX_COMPONENTTYPE  *pOMXComponent,
+    OMX_S32             nPortIndex)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    OMX_S32                   nIndex            = 0;
+
+    OMX_U32 i = 0, cnt = 0;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1;
+
+    if ((pExynosComponent->currentState == OMX_StateExecuting) ||
+        (pExynosComponent->currentState == OMX_StatePause)) {
+        /* port flush*/
+        for(i = 0; i < cnt; i++) {
+            if (nPortIndex == ALL_PORT_INDEX)
+                nIndex = i;
+            else
+                nIndex = nPortIndex;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] Before disabling %s port, do flush",
+                                                pExynosComponent, __FUNCTION__,
+                                                (nIndex == INPUT_PORT_INDEX)? "input":"output");
+            pExynosComponent->pExynosPort[nIndex].portState = EXYNOS_OMX_PortStateFlushingForDisable;
+            ret = pExynosComponent->exynos_BufferFlush(pOMXComponent, nIndex, OMX_FALSE);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s Port is flushed", pExynosComponent, __FUNCTION__,
+                                                    (nIndex == INPUT_PORT_INDEX)? "input":"output");
+            if (ret != OMX_ErrorNone)
+                goto EXIT;
+        }
+    }
+
+    for(i = 0; i < cnt; i++) {
+        if (nPortIndex == ALL_PORT_INDEX)
+            nIndex = i;
+        else
+            nIndex = nPortIndex;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] Disable %s Port",
+                                            pExynosComponent, __FUNCTION__,
+                                            (nIndex == INPUT_PORT_INDEX)? "input":"output");
+        pExynosComponent->pExynosPort[nIndex].portState = EXYNOS_OMX_PortStateDisabling;
+        ret = Exynos_OMX_DisablePort(pOMXComponent, nIndex);
+    }
+
+EXIT:
+    if ((ret != OMX_ErrorNone) &&
+        (pOMXComponent != NULL) &&
+        (pExynosComponent != NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError,
+                                                ret, 0, NULL);
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+/* Change CHECK_SIZE_VERSION Macro */
+OMX_ERRORTYPE Exynos_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size)
+{
+    OMX_ERRORTYPE        ret        = OMX_ErrorNone;
+    OMX_VERSIONTYPE     *version    = NULL;
+
+    if (header == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    version = (OMX_VERSIONTYPE*)((char*)header + sizeof(OMX_U32));
+    if (*((OMX_U32*)header) != size) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_FUNC_TRACE, "[%s] nVersionMajor:%d, nVersionMinor:%d", __FUNCTION__, version->s.nVersionMajor, version->s.nVersionMinor);
+
+    if ((version->s.nVersionMajor != VERSIONMAJOR_NUMBER) ||
+        (version->s.nVersionMinor > VERSIONMINOR_NUMBER)) {
+        ret = OMX_ErrorVersionMismatch;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    return ret;
+}
+
+int Exynos_GetPlaneFromPort(EXYNOS_OMX_BASEPORT *pPort)
+{
+    int ret = 0;
+
+    if (pPort == NULL)
+        goto EXIT;
+
+    ret = pPort->processData.buffer.nPlanes;
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_SetPlaneToPort(EXYNOS_OMX_BASEPORT *pPort, int nPlaneNum)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if (pPort == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pPort->processData.buffer.nPlanes = nPlaneNum;
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_EmptyThisBuffer(
+    OMX_IN OMX_HANDLETYPE        hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT         *pExynosPort        = NULL;
+    int                          i                  = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->pExynosPort == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pBuffer->nInputPortIndex != INPUT_PORT_INDEX) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if ((pExynosComponent->currentState != OMX_StateIdle) &&
+        (pExynosComponent->currentState != OMX_StateExecuting) &&
+        (pExynosComponent->currentState != OMX_StatePause)) {
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (inputBufArray[i].bInOMX == OMX_FALSE) {
+            inputBufArray[i].pBuffer  = pBuffer;
+            inputBufArray[i].bInOMX   = OMX_TRUE;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] pBuffer[%d]: %p",
+                                                    pExynosComponent, __FUNCTION__, i, pBuffer);
+            break;
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FillThisBuffer(
+    OMX_IN OMX_HANDLETYPE        hComponent,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+    EXYNOS_OMX_BASEPORT         *pExynosPort        = NULL;
+    int                          i                  = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->pExynosPort == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pBuffer->nOutputPortIndex != OUTPUT_PORT_INDEX) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if ((pExynosComponent->currentState != OMX_StateIdle) &&
+        (pExynosComponent->currentState != OMX_StateExecuting) &&
+        (pExynosComponent->currentState != OMX_StatePause)) {
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (outputBufArray[i].bInOMX == OMX_FALSE) {
+            outputBufArray[i].pBuffer  = pBuffer;
+            outputBufArray[i].bInOMX   = OMX_TRUE;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] pBuffer[%d]: %p",
+                                                    pExynosComponent, __FUNCTION__, i, pBuffer);
+            break;
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_GetComponentVersion(
+    OMX_IN  OMX_HANDLETYPE   hComponent,
+    OMX_OUT OMX_STRING       pComponentName,
+    OMX_OUT OMX_VERSIONTYPE *pComponentVersion,
+    OMX_OUT OMX_VERSIONTYPE *pSpecVersion,
+    OMX_OUT OMX_UUIDTYPE    *pComponentUUID)
+{
+    OMX_ERRORTYPE             ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+    unsigned long             compUUID[3];
+
+    FunctionIn();
+
+    /* check parameters */
+    if (hComponent     == NULL ||
+        pComponentName == NULL || pComponentVersion == NULL ||
+        pSpecVersion   == NULL || pComponentUUID    == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Strcpy(pComponentName, pExynosComponent->componentName);
+    Exynos_OSAL_Memcpy(pComponentVersion, &(pExynosComponent->componentVersion), sizeof(OMX_VERSIONTYPE));
+    Exynos_OSAL_Memcpy(pSpecVersion, &(pExynosComponent->specVersion), sizeof(OMX_VERSIONTYPE));
+
+    /* Fill UUID with handle address, PID and UID.
+     * This should guarantee uiniqness */
+    compUUID[0] = (unsigned long)pOMXComponent;
+    compUUID[1] = (unsigned long)getpid();
+    compUUID[2] = (unsigned long)getuid();
+    Exynos_OSAL_Memcpy(*pComponentUUID, compUUID, 3 * sizeof(*compUUID));
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_GetState(
+        OMX_IN OMX_HANDLETYPE  hComponent,
+        OMX_OUT OMX_STATETYPE *pState)
+{
+    OMX_ERRORTYPE             ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL || pState == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    *pState = pExynosComponent->currentState;
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_SetPortFlush(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
+{
+    OMX_ERRORTYPE        ret         = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+    OMX_S32              nPortIndex  = nParam;
+    unsigned int         i;
+
+    if ((pExynosComponent->currentState == OMX_StateExecuting) ||
+        (pExynosComponent->currentState == OMX_StatePause)) {
+        if ((nPortIndex != ALL_PORT_INDEX) &&
+           ((OMX_S32)nPortIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (nPortIndex == ALL_PORT_INDEX) {
+            for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+                pExynosPort = &pExynosComponent->pExynosPort[i];
+                if (!CHECK_PORT_ENABLED(pExynosPort)) {
+                    ret = OMX_ErrorIncorrectStateOperation;
+                    goto EXIT;
+                }
+
+                pExynosPort->portState = EXYNOS_OMX_PortStateFlushing;
+            }
+        } else {
+            pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+            if (!CHECK_PORT_ENABLED(pExynosPort)) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+
+            pExynosPort->portState = EXYNOS_OMX_PortStateFlushing;
+        }
+    } else {
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_SetPortDisable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT *pExynosPort    = NULL;
+    OMX_S32              nPortIndex     = nParam;
+    unsigned int         i;
+
+    FunctionIn();
+
+    if ((nPortIndex != ALL_PORT_INDEX) &&
+            ((OMX_S32)nPortIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((nPortIndex != ALL_PORT_INDEX) &&
+        ((OMX_S32)nPortIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == ALL_PORT_INDEX) {
+        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+            pExynosPort = &pExynosComponent->pExynosPort[i];
+            if (!CHECK_PORT_ENABLED(pExynosPort)) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+
+            pExynosPort->portState = EXYNOS_OMX_PortStateDisabling;
+        }
+    } else {
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+        if (!CHECK_PORT_ENABLED(pExynosPort)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        pExynosPort->portState = EXYNOS_OMX_PortStateDisabling;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_SetPortEnable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
+{
+    OMX_ERRORTYPE        ret            = OMX_ErrorNone;
+    EXYNOS_OMX_BASEPORT *pExynosPort    = NULL;
+    OMX_S32              nPortIndex     = nParam;
+
+    OMX_U16 i = 0;
+
+    FunctionIn();
+
+    if ((nPortIndex != ALL_PORT_INDEX) &&
+            ((OMX_S32)nPortIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if (nPortIndex == ALL_PORT_INDEX) {
+        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+            pExynosPort = &pExynosComponent->pExynosPort[i];
+            if (CHECK_PORT_ENABLED(pExynosPort)) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+
+            pExynosPort->portState = EXYNOS_OMX_PortStateEnabling;
+        }
+    } else {
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+        if (CHECK_PORT_ENABLED(pExynosPort)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        pExynosPort->portState = EXYNOS_OMX_PortStateEnabling;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+
+}
+
+static OMX_ERRORTYPE Exynos_SetStateSet(
+        EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+        OMX_U32                     nParam)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    OMX_U32 i = 0;
+
+    FunctionIn();
+
+    if (pExynosComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    switch ((OMX_STATETYPE)nParam) {
+    case OMX_StateIdle:
+    {
+        /* Loaded to Idle */
+        if (pExynosComponent->currentState == OMX_StateLoaded) {
+            pExynosComponent->transientState = EXYNOS_OMX_TransStateLoadedToIdle;
+
+            for(i = 0; i < pExynosComponent->portParam.nPorts; i++)
+                pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateEnabling;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateLoaded to OMX_StateIdle", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        /* Executing to Idle */
+        if (pExynosComponent->currentState == OMX_StateExecuting) {
+            EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+            pExynosComponent->transientState = EXYNOS_OMX_TransStateExecutingToIdle;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateExecuting to OMX_StateIdle", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        /* Pause to Idle */
+        if (pExynosComponent->currentState == OMX_StatePause) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StatePause to OMX_StateIdle", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        if (pExynosComponent->currentState == OMX_StateInvalid) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_StateExecuting:
+    {
+        /* Idle to Executing */
+        if (pExynosComponent->currentState == OMX_StateIdle) {
+            pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToExecuting;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateIdle to OMX_StateExecuting", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        /* Pause to Executing */
+        if (pExynosComponent->currentState == OMX_StatePause) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StatePause to OMX_StateIdle", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+
+        ret = OMX_ErrorBadParameter;
+    }
+        break;
+    case OMX_StateLoaded:
+    {
+        /* Idle to Loaded */
+        if (pExynosComponent->currentState == OMX_StateIdle) {
+            pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToLoaded;
+
+            for (i = 0; i < pExynosComponent->portParam.nPorts; i++)
+                pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateDisabling;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateIdle to OMX_StateLoaded", pExynosComponent, __FUNCTION__);
+        }
+    }
+        break;
+    case OMX_StateInvalid:
+    {
+        for (i = 0; i < pExynosComponent->portParam.nPorts; i++)
+            pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateInvalid;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s to OMX_StateInvalid",
+                                                pExynosComponent, __FUNCTION__, stateString(pExynosComponent->currentState));
+    }
+        break;
+    default:
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s to %s", pExynosComponent, __FUNCTION__,
+                                                stateString(pExynosComponent->currentState), stateString(nParam));
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_StateSet(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
+{
+    OMX_U32 destState = nParam;
+    OMX_U32 i = 0;
+
+    if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StateLoaded)) {
+        for(i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+            pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateEnabling;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateLoaded to OMX_StateIdle", pExynosComponent, __FUNCTION__);
+    } else if ((destState == OMX_StateLoaded) && (pExynosComponent->currentState == OMX_StateIdle)) {
+        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+            pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateDisabling;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateIdle to OMX_StateLoaded", pExynosComponent, __FUNCTION__);
+    } else if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StateExecuting)) {
+        EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateExecuting to OMX_StateIdle", pExynosComponent, __FUNCTION__);
+    } else if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StatePause)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StatePause to OMX_StateIdle", pExynosComponent, __FUNCTION__);
+    } else if ((destState == OMX_StateExecuting) && (pExynosComponent->currentState == OMX_StateIdle)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] OMX_StateIdle to OMX_StateExecuting", pExynosComponent, __FUNCTION__);
+    } else if (destState == OMX_StateInvalid) {
+        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+            pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateInvalid;
+        }
+    }
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nParam)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    OMX_STATETYPE                    destState        = nParam;
+    OMX_STATETYPE                    currentState     = pExynosComponent->currentState;
+    EXYNOS_OMX_BASEPORT             *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264WFDENC_HANDLE        *pH264Enc         = (EXYNOS_H264WFDENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+
+    ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
+    ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+    ExynosVideoEncParam     *pEncParam  = NULL;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int  i = 0, j = 0;
+    int           k = 0;
+    int           nOutBufSize = 0, nOutputBufferCnt = 0;
+
+    FunctionIn();
+
+    /* check parameters */
+    if (currentState == destState) {
+         ret = OMX_ErrorSameState;
+            goto EXIT;
+    }
+    if (currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] current:(%s) dest:(%s)", pExynosComponent, __FUNCTION__, stateString(currentState), stateString(destState));
+    switch (destState) {
+    case OMX_StateInvalid:
+        switch (currentState) {
+        case OMX_StateWaitForResources:
+        case OMX_StateIdle:
+        case OMX_StateExecuting:
+        case OMX_StatePause:
+        case OMX_StateLoaded:
+            pExynosComponent->currentState = OMX_StateInvalid;
+
+            if (currentState != OMX_StateLoaded)
+                pExynosComponent->exynos_codec_componentTerminate(pOMXComponent);
+
+            ret = OMX_ErrorInvalidState;
+            break;
+        default:
+            ret = OMX_ErrorInvalidState;
+            break;
+        }
+        break;
+    case OMX_StateLoaded:
+        switch (currentState) {
+        case OMX_StateIdle:
+            for(i = 0; i < pExynosComponent->portParam.nPorts; i++)
+                pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateDisabling;
+
+            ret = pExynosComponent->exynos_codec_componentTerminate(pOMXComponent);
+            if (ret != OMX_ErrorNone)
+                goto EXIT;
+            else
+                goto NO_EVENT_EXIT;
+
+            break;
+        case OMX_StateWaitForResources:
+            pExynosComponent->currentState = OMX_StateLoaded;
+            break;
+        case OMX_StateExecuting:
+        case OMX_StatePause:
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+        break;
+    case OMX_StateIdle:
+        switch (currentState) {
+        case OMX_StateLoaded:
+            for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+                pExynosPort = &(pExynosComponent->pExynosPort[i]);
+                pExynosPort->portState = EXYNOS_OMX_PortStateEnabling;
+            }
+
+            Exynos_OSAL_Get_Log_Property(); // For debuging, Function called when GetHandle function is success
+            ret = pExynosComponent->exynos_codec_componentInit(pOMXComponent);
+            if (ret != OMX_ErrorNone)
+                goto EXIT;
+            else
+                goto NO_EVENT_EXIT;
+
+            break;
+        case OMX_StateExecuting:
+            Exynos_SetPortFlush(pExynosComponent, ALL_PORT_INDEX);
+            Exynos_OMX_BufferFlushProcess(pOMXComponent, ALL_PORT_INDEX, OMX_FALSE);
+            pExynosComponent->currentState = OMX_StateIdle;
+            break;
+        case OMX_StatePause:
+            Exynos_SetPortFlush(pExynosComponent, ALL_PORT_INDEX);
+            Exynos_OMX_BufferFlushProcess(pOMXComponent, ALL_PORT_INDEX, OMX_FALSE);
+            pExynosComponent->currentState = OMX_StateIdle;
+            break;
+        case OMX_StateWaitForResources:
+            pExynosComponent->currentState = OMX_StateIdle;
+            break;
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+        break;
+    case OMX_StateExecuting:
+        switch (currentState) {
+        case OMX_StateLoaded:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        case OMX_StateIdle:
+            pExynosComponent->currentState = OMX_StateExecuting;
+
+            /* Set EncParam for input (src) */
+            Set_H264WFDEnc_Param(pExynosComponent);
+            pEncParam = &(pH264Enc->hMFCH264Handle.encParam);
+            if (pEncOps->Set_EncParam) {
+                if(pEncOps->Set_EncParam(pH264Enc->hMFCH264Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set encParam", pExynosComponent, __FUNCTION__);
+                    ret = OMX_ErrorInsufficientResources;
+                    goto EXIT;
+                }
+            }
+            Print_H264WFDEnc_Param(pEncParam);
+
+            /* set geometry for output (dst) */
+            pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+            nOutBufSize = pExynosPort->portDefinition.nBufferSize;
+            if ((pExynosPort->bufferProcessType & BUFFER_COPY) ||
+                    (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+                /* OMX buffer is not used directly : CODEC buffer or MetaData */
+                nOutBufSize = ALIGN(pExynosPort->portDefinition.format.video.nFrameWidth *
+                        pExynosPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+            }
+            if (pOutbufOps->Set_Geometry) {
+                /* output buffer info: only 2 config values needed */
+                bufferConf.eCompressionFormat = VIDEO_CODING_AVC;
+                bufferConf.nSizeImage = nOutBufSize;
+                bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosPort);
+
+                if (pOutbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+                    ret = OMX_ErrorInsufficientResources;
+                    goto EXIT;
+                }
+            }
+            break;
+        case OMX_StatePause:
+            pExynosComponent->currentState = OMX_StateExecuting;
+            break;
+        case OMX_StateWaitForResources:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+        break;
+    case OMX_StatePause:
+        switch (currentState) {
+        case OMX_StateLoaded:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        case OMX_StateIdle:
+            pExynosComponent->currentState = OMX_StatePause;
+            break;
+        case OMX_StateExecuting:
+            pExynosComponent->currentState = OMX_StatePause;
+            break;
+        case OMX_StateWaitForResources:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+        break;
+    case OMX_StateWaitForResources:
+        switch (currentState) {
+        case OMX_StateLoaded:
+            pExynosComponent->currentState = OMX_StateWaitForResources;
+            break;
+        case OMX_StateIdle:
+        case OMX_StateExecuting:
+        case OMX_StatePause:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        default:
+            ret = OMX_ErrorIncorrectStateTransition;
+            break;
+        }
+        break;
+    default:
+        ret = OMX_ErrorIncorrectStateTransition;
+        break;
+    }
+
+EXIT:
+    if (ret == OMX_ErrorNone) {
+        if (pExynosComponent->pCallbacks != NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete", pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+            pExynosComponent->callbackData,
+            OMX_EventCmdComplete, OMX_CommandStateSet,
+            destState, NULL);
+        }
+    } else {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] (0x%x)", pExynosComponent, __FUNCTION__, ret);
+        if (pExynosComponent->pCallbacks != NULL) {
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+            pExynosComponent->callbackData,
+            OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+NO_EVENT_EXIT: /* postpone to send event */
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_SendCommand(
+        OMX_IN OMX_HANDLETYPE  hComponent,
+        OMX_IN OMX_COMMANDTYPE Cmd,
+        OMX_IN OMX_U32         nParam,
+        OMX_IN OMX_PTR         pCmdData)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    switch (Cmd) {
+    case OMX_CommandStateSet :
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Command: OMX_CommandStateSet", pExynosComponent, __FUNCTION__);
+        ret = Exynos_StateSet(pExynosComponent, nParam);
+        if (ret == OMX_ErrorNone)
+           Exynos_SetStateSet(pExynosComponent, nParam);
+        ret = Exynos_OMX_ComponentStateSet(pOMXComponent, nParam);
+        break;
+    case OMX_CommandFlush :
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Command: OMX_CommandFlush", pExynosComponent, __FUNCTION__);
+        ret = Exynos_SetPortFlush(pExynosComponent, nParam);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+        ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, nParam, OMX_TRUE);
+        break;
+    case OMX_CommandPortDisable :
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Command: OMX_CommandPortDisable", pExynosComponent, __FUNCTION__);
+        ret = Exynos_SetPortDisable(pExynosComponent, nParam);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+        ret = Exynos_OMX_PortDisableProcess(pOMXComponent, nParam);
+        break;
+    case OMX_CommandPortEnable :
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Command: OMX_CommandPortEnable", pExynosComponent, __FUNCTION__);
+        ret = Exynos_SetPortEnable(pExynosComponent, nParam);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+        ret = Exynos_OMX_PortEnableProcess(pOMXComponent, nParam);
+        break;
+    default:
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_SetCallbacks(
+    OMX_IN OMX_HANDLETYPE    hComponent,
+    OMX_IN OMX_CALLBACKTYPE* pCallbacks,
+    OMX_IN OMX_PTR           pAppData)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pCallbacks == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+    if (pExynosComponent->currentState != OMX_StateLoaded) {
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    pExynosComponent->pCallbacks   = pCallbacks;
+    pExynosComponent->callbackData = pAppData;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BaseComponent_Constructor(
+    OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] lib version is %s", __FUNCTION__, IS_64BIT_OS? "64bit":"32bit");
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] OMX_ErrorBadParameter (0x%x)", __FUNCTION__, ret);
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASECOMPONENT));
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Malloc (0x%x)", __FUNCTION__, ret);
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent, 0, sizeof(EXYNOS_OMX_BASECOMPONENT));
+    pOMXComponent->pComponentPrivate = (OMX_PTR)pExynosComponent;
+
+    pOMXComponent->GetComponentVersion = &Exynos_OMX_GetComponentVersion;
+    pOMXComponent->SendCommand         = &Exynos_OMX_SendCommand;
+    pOMXComponent->GetState            = &Exynos_OMX_GetState;
+    pOMXComponent->SetCallbacks        = &Exynos_OMX_SetCallbacks;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor(
+    OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    Exynos_OSAL_Free(pExynosComponent);
+    pExynosComponent = NULL;
+
+    ret = OMX_ErrorNone;
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT      *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    exynosInputPort->portDefinition.nBufferSize = ALIGN(exynosInputPort->portDefinition.format.video.nFrameWidth, 16) *
+                                                  ALIGN(exynosInputPort->portDefinition.format.video.nFrameHeight, 16) * 3 / 2;
+
+    if ((exynosOutputPort->portDefinition.format.video.nFrameWidth !=
+            exynosInputPort->portDefinition.format.video.nFrameWidth) ||
+        (exynosOutputPort->portDefinition.format.video.nFrameHeight !=
+            exynosInputPort->portDefinition.format.video.nFrameHeight)) {
+        OMX_U32 width = 0, height = 0;
+
+        exynosOutputPort->portDefinition.format.video.nFrameWidth =
+            exynosInputPort->portDefinition.format.video.nFrameWidth;
+        exynosOutputPort->portDefinition.format.video.nFrameHeight =
+            exynosInputPort->portDefinition.format.video.nFrameHeight;
+        width = exynosOutputPort->portDefinition.format.video.nStride =
+            exynosInputPort->portDefinition.format.video.nStride;
+        height = exynosOutputPort->portDefinition.format.video.nSliceHeight =
+            exynosInputPort->portDefinition.format.video.nSliceHeight;
+
+        if (width && height)
+            exynosOutputPort->portDefinition.nBufferSize = ALIGN((ALIGN(width, 16) * ALIGN(height, 16) * 3) / 2, 512);
+    }
+
+    return;
+}
+
+void Exynos_Input_SetSupportFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_COLOR_FORMATTYPE             ret        = OMX_COLOR_FormatUnused;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc  = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    if ((pVideoEnc == NULL) || (pInputPort == NULL))
+        return ;
+
+    if (pInputPort->supportFormat != NULL) {
+        OMX_BOOL ret = OMX_FALSE;
+        int nLastIndex = INPUT_PORT_SUPPORTFORMAT_DEFAULT_NUM;
+        int i;
+
+        /* default supported formats */
+        pInputPort->supportFormat[0] = OMX_COLOR_FormatYUV420Planar;
+        pInputPort->supportFormat[1] = OMX_COLOR_FormatYUV420SemiPlanar;
+        pInputPort->supportFormat[2] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear;
+        pInputPort->supportFormat[3] = OMX_COLOR_Format32bitARGB8888;
+        pInputPort->supportFormat[4] = (OMX_COLOR_FORMATTYPE)OMX_COLOR_Format32BitRGBA8888;
+#ifdef USE_ANDROID
+        pInputPort->supportFormat[nLastIndex++] = OMX_COLOR_FormatAndroidOpaque;
+#endif
+
+        /* add extra formats, if It is supported by H/W. (CSC doesn't exist) */
+        /* OMX_SEC_COLOR_FormatNV12Tiled */
+        ret = pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent,
+                                            (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled);
+        if (ret == OMX_TRUE)
+            pInputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
+
+        /* OMX_SEC_COLOR_FormatYVU420Planar */
+        ret = pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent,
+                                            (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar);
+        if (ret == OMX_TRUE)
+            pInputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar;
+
+        /* OMX_COLOR_Format32bitBGRA8888 */
+        ret = pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent, OMX_COLOR_Format32bitBGRA8888);
+        if (ret == OMX_TRUE)
+            pInputPort->supportFormat[nLastIndex++] = OMX_COLOR_Format32bitBGRA8888;
+
+        for (i = 0; i < nLastIndex; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] Supported Format[%d] : 0x%x",
+                                                pExynosComponent, __FUNCTION__, i, pInputPort->supportFormat[i]);
+        }
+
+        pInputPort->supportFormat[nLastIndex] = OMX_COLOR_FormatUnused;
+    }
+
+    return ;
+}
+
+OMX_COLOR_FORMATTYPE Exynos_Input_GetActualColorFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_COLOR_FORMATTYPE             ret                = OMX_COLOR_FormatUnused;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_COLOR_FORMATTYPE             eColorFormat       = pInputPort->portDefinition.format.video.eColorFormat;
+
+#ifdef USE_ANDROID
+    if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)
+        eColorFormat = pVideoEnc->surfaceFormat;
+#endif
+
+    if (pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent, eColorFormat) == OMX_TRUE) {
+        ret = eColorFormat;
+        goto EXIT;
+    }
+
+    switch ((int)eColorFormat) {
+    case OMX_COLOR_FormatYUV420SemiPlanar:
+    case OMX_COLOR_FormatYUV420Planar:       /* converted to NV12 using CSC */
+    case OMX_COLOR_Format32bitARGB8888:      /* converted to NV12 using CSC */
+    case OMX_COLOR_Format32BitRGBA8888:      /* converted to NV12 using CSC */
+        ret = OMX_COLOR_FormatYUV420SemiPlanar;
+        break;
+    case OMX_SEC_COLOR_FormatNV21Linear:
+    case OMX_SEC_COLOR_FormatNV12Tiled:
+        ret = eColorFormat;
+        break;
+    default:
+        ret = OMX_COLOR_FormatUnused;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT           *pInputPort        = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort       = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    /* Input port */
+    pInputPort->portDefinition.format.video.nFrameWidth             = DEFAULT_FRAME_WIDTH;
+    pInputPort->portDefinition.format.video.nFrameHeight            = DEFAULT_FRAME_HEIGHT;
+    pInputPort->portDefinition.format.video.nStride                 = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pInputPort->portDefinition.format.video.nSliceHeight            = 0;
+    pInputPort->portDefinition.format.video.pNativeRender           = 0;
+    pInputPort->portDefinition.format.video.bFlagErrorConcealment   = OMX_FALSE;
+    pInputPort->portDefinition.format.video.eColorFormat            = OMX_COLOR_FormatYUV420SemiPlanar;
+
+    pInputPort->portDefinition.nBufferSize  = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    pInputPort->portDefinition.bEnabled     = OMX_TRUE;
+
+    pInputPort->bufferProcessType   = BUFFER_COPY;
+    pInputPort->portWayType         = WAY2_PORT;
+    Exynos_SetPlaneToPort(pInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+
+    /* Output port */
+    pOutputPort->portDefinition.format.video.nFrameWidth            = DEFAULT_FRAME_WIDTH;
+    pOutputPort->portDefinition.format.video.nFrameHeight           = DEFAULT_FRAME_HEIGHT;
+    pOutputPort->portDefinition.format.video.nStride                = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pOutputPort->portDefinition.format.video.nSliceHeight           = 0;
+    pOutputPort->portDefinition.format.video.pNativeRender          = 0;
+    pOutputPort->portDefinition.format.video.bFlagErrorConcealment  = OMX_FALSE;
+    pOutputPort->portDefinition.format.video.eColorFormat           = OMX_COLOR_FormatUnused;
+
+    pOutputPort->portDefinition.nBufferCountActual  = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pOutputPort->portDefinition.nBufferCountMin     = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pOutputPort->portDefinition.nBufferSize  = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pOutputPort->portDefinition.bEnabled     = OMX_TRUE;
+
+    pOutputPort->bufferProcessType  = BUFFER_SHARE;
+    pOutputPort->portWayType        = WAY2_PORT;
+    pOutputPort->latestTimeStamp    = DEFAULT_TIMESTAMP_VAL;
+    Exynos_SetPlaneToPort(pOutputPort, Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420Planar, pOutputPort->ePlaneType));
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to construct BaseComponent for WFD", __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Port_Constructor(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Port_Constructor", __FUNCTION__);
+        Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    pVideoEnc = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
+    if (pVideoEnc == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_Port_Destructor(pOMXComponent);
+        Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Memset(pVideoEnc, 0, sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
+    pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc;
+
+    pVideoEnc->nQosRatio       = 0;
+    pVideoEnc->nInbufSpareSize = 0;
+    pVideoEnc->quantization.nQpI = 4; // I frame quantization parameter
+    pVideoEnc->quantization.nQpP = 5; // P frame quantization parameter
+    pVideoEnc->quantization.nQpB = 5; // B frame quantization parameter
+
+    pVideoEnc->bUseBlurFilter   = OMX_FALSE;
+    pVideoEnc->eBlurMode        = BLUR_MODE_NONE;
+    pVideoEnc->eBlurResol       = BLUR_RESOL_240;
+
+    pVideoEnc->eRotationType    = ROTATE_0;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->supportFormat = Exynos_OSAL_Malloc(sizeof(OMX_COLOR_FORMATTYPE) * INPUT_PORT_SUPPORTFORMAT_NUM_MAX);
+    if (pExynosPort->supportFormat == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosPort->supportFormat, 0, (sizeof(OMX_COLOR_FORMATTYPE) * INPUT_PORT_SUPPORTFORMAT_NUM_MAX));
+
+    pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferSize = 0;
+    pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
+
+    pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
+    if (pExynosPort->portDefinition.format.video.cMIMEType == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+    pExynosPort->portDefinition.format.video.nFrameWidth = 0;
+    pExynosPort->portDefinition.format.video.nFrameHeight= 0;
+    pExynosPort->portDefinition.format.video.nStride = 0;
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.format.video.nBitrate = 1000000;
+    pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pVideoEnc->eControlRate[INPUT_PORT_INDEX] = OMX_Video_ControlRateVariable;
+
+    pExynosPort->eMetaDataType = METADATA_TYPE_DISABLED;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->supportFormat = Exynos_OSAL_Malloc(sizeof(OMX_COLOR_FORMATTYPE) * OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX);
+    if (pExynosPort->supportFormat == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosPort->supportFormat, 0, (sizeof(OMX_COLOR_FORMATTYPE) * OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX));
+
+    pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
+
+    pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
+    if (pExynosPort->portDefinition.format.video.cMIMEType == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+    pExynosPort->portDefinition.format.video.nFrameWidth = 0;
+    pExynosPort->portDefinition.format.video.nFrameHeight= 0;
+    pExynosPort->portDefinition.format.video.nStride = 0;
+    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
+    pExynosPort->portDefinition.format.video.nBitrate = 1000000;
+    pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] = OMX_Video_ControlRateVariable;
+
+    pExynosPort->eMetaDataType = METADATA_TYPE_DISABLED;
+
+    pOMXComponent->UseBuffer              = &Exynos_OMX_UseBuffer;
+    pOMXComponent->AllocateBuffer         = &Exynos_OMX_AllocateBuffer;
+    pOMXComponent->FreeBuffer             = &Exynos_OMX_FreeBuffer;
+
+    pExynosComponent->exynos_BufferFlush  = &Exynos_OMX_BufferFlush;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+
+    int i = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    Exynos_OSAL_Free(pVideoEnc);
+    pExynosComponent->hComponentHandle = pVideoEnc = NULL;
+
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    if (pExynosPort->processData.extInfo != NULL) {
+        Exynos_OSAL_Free(pExynosPort->processData.extInfo);
+        pExynosPort->processData.extInfo = NULL;
+    }
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        pExynosPort = &pExynosComponent->pExynosPort[i];
+        Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
+        pExynosPort->portDefinition.format.video.cMIMEType = NULL;
+
+        Exynos_OSAL_Free(pExynosPort->supportFormat);
+        pExynosPort->supportFormat = NULL;
+    }
+
+    ret = Exynos_OMX_Port_Destructor(pOMXComponent);
+
+    ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AllocateBuffer(
+        OMX_IN OMX_HANDLETYPE            hComponent,
+        OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+        OMX_IN OMX_U32                   nPortIndex,
+        OMX_IN OMX_PTR                   pAppPrivate,
+        OMX_IN OMX_U32                   nSizeBytes)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    OMX_BUFFERHEADERTYPE            *pTempBufferHdr     = NULL;
+    OMX_U8                          *pTempBuffer        = NULL;
+    OMX_U32                          i                  = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid parameter(0x%x)", pExynosComponent, __FUNCTION__, nPortIndex);
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    if (pExynosPort->portState != EXYNOS_OMX_PortStateEnabling) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] %s port : invalid state : comp state(0x%x), port state(0x%x), enabled(0x%x)",
+                                            pExynosComponent, __FUNCTION__,
+                                            (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                            pExynosComponent->currentState, pExynosPort->portState, pExynosPort->portDefinition.bEnabled);
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    pTempBuffer = (OMX_U8 *)Exynos_OSAL_Malloc(64);
+    Exynos_OSAL_Memset(pTempBuffer, 0, 64);
+
+    pTempBufferHdr = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (pTempBufferHdr == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pTempBufferHdr, 0, sizeof(OMX_BUFFERHEADERTYPE));
+
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
+            pExynosPort->extendBufferHeader[i].OMXBufferHeader = pTempBufferHdr;
+            pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED);
+            INIT_SET_SIZE_VERSION(pTempBufferHdr, OMX_BUFFERHEADERTYPE);
+
+            pTempBufferHdr->pBuffer        = pTempBuffer;
+            pTempBufferHdr->nAllocLen      = nSizeBytes;
+            pTempBufferHdr->pAppPrivate    = pAppPrivate;
+
+            if (nPortIndex == INPUT_PORT_INDEX)
+                pTempBufferHdr->nInputPortIndex = INPUT_PORT_INDEX;
+            else
+                pTempBufferHdr->nOutputPortIndex = OUTPUT_PORT_INDEX;
+
+            pExynosPort->assignedBufferNum++;
+
+            *ppBufferHdr = pTempBufferHdr;
+
+            if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+                pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+
+                if ((pExynosComponent->currentState == OMX_StateLoaded) &&
+                    (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle)) {
+                    if (CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]) &&
+                        CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX])) {
+                        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete", pExynosComponent, __FUNCTION__);
+                        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                                pExynosComponent->callbackData,
+                                                                OMX_EventCmdComplete, OMX_CommandStateSet,
+                                                                OMX_StateIdle, NULL);
+
+                        for (i = 0; i < (int)pExynosComponent->portParam.nPorts; i++)
+                            pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateIdle;
+
+                        pExynosComponent->transientState = EXYNOS_OMX_TransStateMax;
+                        pExynosComponent->currentState = OMX_StateIdle;
+                    }
+                } else if(!(CHECK_PORT_ENABLED(pExynosPort)) &&
+                        (pExynosPort->portState == EXYNOS_OMX_PortStateEnabling)) {
+                    pExynosPort->portState = EXYNOS_OMX_PortStateIdle;
+
+                    Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] Enable %s Port", pExynosComponent, __FUNCTION__,
+                                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output");
+                    ret = Exynos_OMX_EnablePort(pOMXComponent, nPortIndex);
+
+                    if ((ret == OMX_ErrorNone) && (pExynosComponent->pCallbacks != NULL)) {
+                        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete(Enable/%s port)",
+                                                            pExynosComponent, __FUNCTION__,
+                                                            (nPortIndex == INPUT_PORT_INDEX) ? "input" : "output");
+
+                        pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                                pExynosComponent->callbackData,
+                                                                OMX_EventCmdComplete,
+                                                                OMX_CommandPortEnable,
+                                                                (nPortIndex == INPUT_PORT_INDEX) ? INPUT_PORT_INDEX : OUTPUT_PORT_INDEX,
+                                                                NULL);
+
+                        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(EventCmdComplete/Enable/%s port)",
+                                                                pExynosComponent, __FUNCTION__,
+                                                                (nPortIndex == INPUT_PORT_INDEX)? "input":"output");
+
+                    }
+                }
+            }
+
+            ret = OMX_ErrorNone;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port: buffer header(%p), size(%d)",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                                    (*ppBufferHdr), nSizeBytes);
+            goto EXIT;
+        }
+    }
+
+    ret = OMX_ErrorInsufficientResources;
+
+EXIT:
+    if (ret == OMX_ErrorInsufficientResources) {
+        if (pTempBufferHdr != NULL)
+            Exynos_OSAL_Free(pTempBufferHdr);
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_UseBuffer(
+    OMX_IN OMX_HANDLETYPE            hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32                   nPortIndex,
+    OMX_IN OMX_PTR                   pAppPrivate,
+    OMX_IN OMX_U32                   nSizeBytes,
+    OMX_IN OMX_U8                   *pBuffer)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+    OMX_BUFFERHEADERTYPE     *pTempBufferHdr    = NULL;
+    OMX_U32                   i                 = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid parameter(0x%x)", pExynosComponent, __FUNCTION__, nPortIndex);
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    if (pExynosPort->portState != EXYNOS_OMX_PortStateEnabling) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] %s port : invalid state : comp state(0x%x), port state(0x%x), enabled(0x%x)",
+                                            pExynosComponent, __FUNCTION__,
+                                            (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                            pExynosComponent->currentState, pExynosPort->portState, pExynosPort->portDefinition.bEnabled);
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    pTempBufferHdr = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
+    if (pTempBufferHdr == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pTempBufferHdr, 0, sizeof(OMX_BUFFERHEADERTYPE));
+
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
+            pExynosPort->extendBufferHeader[i].OMXBufferHeader = pTempBufferHdr;
+            pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED);
+            INIT_SET_SIZE_VERSION(pTempBufferHdr, OMX_BUFFERHEADERTYPE);
+
+            pTempBufferHdr->pBuffer        = pBuffer;
+            pTempBufferHdr->nAllocLen      = nSizeBytes;
+            pTempBufferHdr->pAppPrivate    = pAppPrivate;
+
+            if (nPortIndex == INPUT_PORT_INDEX)
+                pTempBufferHdr->nInputPortIndex = INPUT_PORT_INDEX;
+            else
+                pTempBufferHdr->nOutputPortIndex = OUTPUT_PORT_INDEX;
+
+            pExynosPort->assignedBufferNum++;
+
+            *ppBufferHdr = pTempBufferHdr;
+
+            ret = OMX_ErrorNone;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port: buffer header(%p), size(%d)",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                                    (*ppBufferHdr), nSizeBytes);
+            goto EXIT;
+        }
+    }
+
+    Exynos_OSAL_Free(pTempBufferHdr);
+    ret = OMX_ErrorInsufficientResources;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FreeBuffer(
+    OMX_IN OMX_HANDLETYPE        hComponent,
+    OMX_IN OMX_U32               nPortIndex,
+    OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+    OMX_BUFFERHEADERTYPE            *pOMXBufferHdr      = NULL;
+    OMX_U32                          i                  = 0;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] invalid parameter(0x%x)", pExynosComponent, __FUNCTION__, nPortIndex);
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((pExynosPort->portState != EXYNOS_OMX_PortStateDisabling) &&
+        (pExynosPort->portState != EXYNOS_OMX_PortStateFlushingForDisable) &&
+        (pExynosPort->portState != EXYNOS_OMX_PortStateInvalid)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] %s port : invalid state : comp state(0x%x), port state(0x%x), enabled(0x%x)",
+                                            pExynosComponent, __FUNCTION__,
+                                            (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                            pExynosComponent->currentState, pExynosPort->portState, pExynosPort->portDefinition.bEnabled);
+        ret = OMX_ErrorIncorrectStateOperation;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)", pExynosComponent, __FUNCTION__);
+
+        (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent,
+                                                    pExynosComponent->callbackData,
+                                                    (OMX_U32)OMX_EventError,
+                                                    (OMX_U32)OMX_ErrorPortUnpopulated,
+                                                    nPortIndex, NULL);
+        ret = OMX_ErrorIncorrectStateOperation;
+        goto EXIT;
+    }
+
+    for (i = 0; i < /*pExynosPort->portDefinition.nBufferCountActual*/MAX_BUFFER_NUM; i++) {
+        if ((pExynosPort->bufferStateAllocate[i] != BUFFER_STATE_FREE) &&
+                (pExynosPort->extendBufferHeader[i].OMXBufferHeader != NULL)) {
+            pOMXBufferHdr = pExynosPort->extendBufferHeader[i].OMXBufferHeader;
+
+            if (pOMXBufferHdr->pBuffer == pBufferHdr->pBuffer) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s port: buffer header(%p)",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                                        pOMXBufferHdr);
+                if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) {
+                    pOMXBufferHdr->pBuffer  = NULL;
+                    pBufferHdr->pBuffer     = NULL;
+                }
+
+                pExynosPort->assignedBufferNum--;
+
+                if (pExynosPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) {
+                    Exynos_OSAL_Free(pOMXBufferHdr);
+                    pExynosPort->extendBufferHeader[i].OMXBufferHeader = NULL;
+                    pBufferHdr = NULL;
+                }
+
+                pExynosPort->bufferStateAllocate[i] = BUFFER_STATE_FREE;
+                ret = OMX_ErrorNone;
+                goto EXIT;
+            }
+        }
+    }
+
+EXIT:
+    if (ret == OMX_ErrorNone) {
+        if (pExynosPort->assignedBufferNum < (OMX_S32)pExynosPort->portDefinition.nBufferCountActual)
+            pExynosPort->portDefinition.bPopulated = OMX_FALSE;
+
+        if (pExynosPort->assignedBufferNum == 0) {
+            if ((pExynosComponent->currentState == OMX_StateIdle) &&
+                (pExynosComponent->transientState == EXYNOS_OMX_TransStateIdleToLoaded)) {
+                if (!CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[INPUT_PORT_INDEX]) &&
+                    !CHECK_PORT_POPULATED(&pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX])) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] OMX_EventCmdComplete", pExynosComponent, __FUNCTION__);
+                    pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                            pExynosComponent->callbackData,
+                                                            OMX_EventCmdComplete, OMX_CommandStateSet,
+                                                            OMX_StateLoaded, NULL);
+
+                    for (i = 0; i < (int)pExynosComponent->portParam.nPorts; i++)
+                        pExynosComponent->pExynosPort[i].portState = EXYNOS_OMX_PortStateLoaded;
+
+                    pExynosComponent->transientState = EXYNOS_OMX_TransStateMax;
+                    pExynosComponent->currentState = OMX_StateLoaded;
+                }
+            }
+
+            if (pExynosPort->portState == EXYNOS_OMX_PortStateDisabling) {
+                if (!CHECK_PORT_ENABLED(pExynosPort)) {
+                    pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+                                                            pExynosComponent->callbackData,
+                                                            OMX_EventCmdComplete,
+                                                            OMX_CommandPortDisable, nPortIndex, NULL);
+
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s]send event(EventCmdComplete/Disable/%s port)",
+                                                            pExynosComponent, __FUNCTION__,
+                                                            (nPortIndex == INPUT_PORT_INDEX)? "input":"output");
+
+                    pExynosPort->portState = EXYNOS_OMX_PortStateLoaded;
+                }
+            }
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FlushPort(
+        OMX_COMPONENTTYPE   *pOMXComponent,
+        OMX_S32              nPortIndex)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    OMX_BUFFERHEADERTYPE     *pBufferHdr        = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
+    EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
+    int                       i                 = 0;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if ((nPortIndex < 0) ||
+            (nPortIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            if (inputBufArray[i].bInOMX == OMX_TRUE) {
+                if (inputBufArray[i].pBuffer != NULL) {
+                    pBufferHdr = inputBufArray[i].pBuffer;
+                    pBufferHdr->nFilledLen = 0;
+                    Exynos_OMX_InputBufferReturn(pOMXComponent, pBufferHdr);
+                }
+            }
+        } else {
+            if (outputBufArray[i].bInOMX == OMX_TRUE) {
+                if (outputBufArray[i].pBuffer != NULL) {
+                    pBufferHdr = outputBufArray[i].pBuffer;
+                    pBufferHdr->nFilledLen = 0;
+                    Exynos_OMX_OutputBufferReturn(pOMXComponent, pBufferHdr);
+                }
+            }
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BufferFlush(
+        OMX_COMPONENTTYPE   *pOMXComponent,
+        OMX_S32              nPortIndex,
+        OMX_BOOL             bEvent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if ((nPortIndex < 0) ||
+            (nPortIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] OMX_CommandFlush start, port:%d, event:%d",
+                                        pExynosComponent, __FUNCTION__, nPortIndex, bEvent);
+
+    ret = Exynos_OMX_FlushPort(pOMXComponent, nPortIndex);
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    Exynos_ResetCodecData(&pExynosPort->processData);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] OMX_CommandFlush end, port:%d, event:%d",
+                                        pExynosComponent, __FUNCTION__, nPortIndex, bEvent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_ResetCodecData(EXYNOS_OMX_DATA *pData)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if (pData == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    /* caution: nPlanes in buffer structure might be used all times */
+    Exynos_OSAL_Memset(&(pData->buffer.fd), 0, sizeof(pData->buffer.fd));
+    Exynos_OSAL_Memset(&(pData->buffer.addr), 0, sizeof(pData->buffer.addr));
+
+    pData->dataLen       = 0;
+    pData->usedDataLen   = 0;
+    pData->remainDataLen = 0;
+    pData->nFlags        = 0;
+    pData->timeStamp     = 0;
+    pData->pPrivate      = NULL;
+    pData->bufferHeader  = NULL;
+
+EXIT:
+    return ret;
+}
diff --git a/openmax/component/video/enc/h264wfd/Exynos_OMX_H264enc_wfd.h b/openmax/component/video/enc/h264wfd/Exynos_OMX_H264enc_wfd.h
new file mode 100755 (executable)
index 0000000..28261a2
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ *
+ * Copyright 2017 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_H264enc_wfd.h
+ * @brief
+ * @author      SeungBeom Kim  (sbcrux.kim@samsung.com)
+ *              Taehwan Kim    (t_h.kim@samsung.com)
+ *              ByungGwan Kang (bk0917.kang@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2017.06.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_H264_WFD_ENC_COMPONENT
+#define EXYNOS_OMX_H264_WFD_ENC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+
+#include "ExynosVideoApi.h"
+#include "library_register.h"
+
+typedef struct _EXYNOS_MFC_H264WFDENC_HANDLE
+{
+    OMX_HANDLETYPE hMFCHandle;
+
+    OMX_U32 indexTimestamp;
+    OMX_U32 outputIndexTimestamp;
+    OMX_BOOL bPrependSpsPpsToIdr;
+    OMX_BOOL bTemporalSVC;
+    OMX_BOOL bRoiInfo;
+    OMX_U32  nLTRFrames;
+
+    ExynosVideoEncOps       *pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps;
+    ExynosVideoEncBufferOps *pOutbufOps;
+    ExynosVideoEncParam      encParam;
+    ExynosVideoInstInfo      videoInstInfo;
+
+    #define MAX_PROFILE_NUM 5
+    OMX_VIDEO_AVCPROFILETYPE   profiles[MAX_PROFILE_NUM];
+    OMX_S32                    nProfileCnt;
+    OMX_VIDEO_AVCLEVELTYPE     maxLevel;
+} EXYNOS_MFC_H264WFDENC_HANDLE;
+
+typedef struct _EXYNOS_H264WFDENC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_AVCTYPE             AVCComponent[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_AVCSLICEFMO         AVCSliceFmo;
+    OMX_VIDEO_QPRANGE                   qpRangeI;
+    OMX_VIDEO_QPRANGE                   qpRangeP;
+    OMX_VIDEO_QPRANGE                   qpRangeB;
+    EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC TemporalSVC;    /* Temporal SVC */
+
+    /* SEC MFC Codec specific */
+    EXYNOS_MFC_H264WFDENC_HANDLE hMFCH264Handle;
+
+    EXYNOS_QUEUE bypassBufferInfoQ;
+
+    OMX_BOOL                            bLowLatency;
+    EXYNOS_OMX_HIERARCHICAL_CODING_TYPE eHierarchicalType;
+
+    OMX_S32                             nBaseLayerPid;
+    OMX_U32                             nMaxTemporalLayerCount;
+} EXYNOS_H264WFDENC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName);
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent);
+
+OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_Port_Destructor(OMX_HANDLETYPE hComponent);
+int Exynos_GetPlaneFromPort(EXYNOS_OMX_BASEPORT *pPort);
+OMX_ERRORTYPE Exynos_SetPlaneToPort(EXYNOS_OMX_BASEPORT *pPort, int nPlaneNum);
+OMX_ERRORTYPE Exynos_OMX_EmptyThisBuffer(OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
+OMX_ERRORTYPE Exynos_OMX_FillThisBuffer(OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
+
+
+OMX_ERRORTYPE Exynos_OMX_BaseComponent_Constructor(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size);
+
+void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent);
+void Exynos_Input_SetSupportFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+OMX_COLOR_FORMATTYPE Exynos_Input_GetActualColorFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent);
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent);
+
+OMX_ERRORTYPE Exynos_OMX_UseBuffer(
+        OMX_IN OMX_HANDLETYPE            hComponent,
+        OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+        OMX_IN OMX_U32                   nPortIndex,
+        OMX_IN OMX_PTR                   pAppPrivate,
+        OMX_IN OMX_U32                   nSizeBytes,
+        OMX_IN OMX_U8                   *pBuffer);
+OMX_ERRORTYPE Exynos_OMX_AllocateBuffer(
+        OMX_IN OMX_HANDLETYPE            hComponent,
+        OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
+        OMX_IN OMX_U32                   nPortIndex,
+        OMX_IN OMX_PTR                   pAppPrivate,
+        OMX_IN OMX_U32                   nSizeBytes);
+OMX_ERRORTYPE Exynos_OMX_FreeBuffer(
+        OMX_IN OMX_HANDLETYPE        hComponent,
+        OMX_IN OMX_U32               nPortIndex,
+        OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/enc/h264wfd/NOTICE b/openmax/component/video/enc/h264wfd/NOTICE
new file mode 100755 (executable)
index 0000000..316b4eb
--- /dev/null
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2014, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/openmax/component/video/enc/h264wfd/library_register.c b/openmax/component/video/enc/h264wfd/library_register.c
new file mode 100755 (executable)
index 0000000..99988a3
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2017 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.c
+ * @brief
+ * @author      SeungBeom Kim  (sbcrux.kim@samsung.com)
+ *              Taehwan Kim    (t_h.kim@samsung.com)
+ *              ByungGwan Kang (bk0917.kang@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2017.06.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+#include "Exynos_OSAL_Log.h"
+
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents)
+{
+    FunctionIn();
+
+    if (exynosComponents == NULL)
+        goto EXIT;
+
+    /* component 1 - video Encoder H.264 */
+    Exynos_OSAL_Strcpy(exynosComponents[0]->componentName, EXYNOS_OMX_COMPONENT_H264_WFD_ENC);
+    Exynos_OSAL_Strcpy(exynosComponents[0]->roles[0], EXYNOS_OMX_COMPONENT_H264_WFD_ENC_ROLE);
+    exynosComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+    /* component 2 - video Encoder H.264 for DRM */
+    Exynos_OSAL_Strcpy(exynosComponents[1]->componentName, EXYNOS_OMX_COMPONENT_H264_WFD_DRM_ENC);
+    Exynos_OSAL_Strcpy(exynosComponents[1]->roles[0], EXYNOS_OMX_COMPONENT_H264_WFD_ENC_ROLE);
+    exynosComponents[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
+
diff --git a/openmax/component/video/enc/h264wfd/library_register.h b/openmax/component/video/enc/h264wfd/library_register.h
new file mode 100755 (executable)
index 0000000..17e0a98
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2017 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author      SeungBeom Kim  (sbcrux.kim@samsung.com)
+ *              Taehwan Kim    (t_h.kim@samsung.com)
+ *              ByungGwan Kang (bk0917.kang@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2017.06.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_H264_WFD_REG
+#define EXYNOS_OMX_H264_WFD_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM       2
+#define MAX_COMPONENT_ROLE_NUM  1
+
+/* H.264 */
+#define EXYNOS_OMX_COMPONENT_H264_WFD_ENC      "OMX.Exynos.AVC.WFD.Encoder"
+#define EXYNOS_OMX_COMPONENT_H264_WFD_DRM_ENC  "OMX.Exynos.AVC.WFD.Encoder.secure"
+#define EXYNOS_OMX_COMPONENT_H264_WFD_ENC_ROLE "video_encoder.avc-wfd"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
diff --git a/openmax/component/video/enc/hevc/Exynos_OMX_HEVCenc.c b/openmax/component/video/enc/hevc/Exynos_OMX_HEVCenc.c
new file mode 100755 (executable)
index 0000000..d38374d
--- /dev/null
@@ -0,0 +1,3774 @@
+/*
+ *
+ * Copyright 2014 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_HEVCenc.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2014.05.22 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Venc.h"
+#include "Exynos_OMX_VencControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_HEVCenc.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OSAL_Queue.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+#ifdef USE_ANDROID
+#include "VendorVideoAPI.h"
+#endif
+
+/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
+/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_HEVC_ENC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc       = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pHevcEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcEnc->hMFCHevcHandle.profiles[nProfileCnt++] = OMX_VIDEO_HEVCProfileMain;
+    pHevcEnc->hMFCHevcHandle.nProfileCnt = nProfileCnt;
+
+    switch (pHevcEnc->hMFCHevcHandle.videoInstInfo.HwVersion) {
+    case MFC_1220:
+    case MFC_120:
+    case MFC_110:
+        pHevcEnc->hMFCHevcHandle.profiles[nProfileCnt++] = OMX_VIDEO_HEVCProfileMain10;
+        pHevcEnc->hMFCHevcHandle.nProfileCnt = nProfileCnt;
+
+        pHevcEnc->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel6;
+        break;
+    case MFC_100:
+    case MFC_101:
+        pHevcEnc->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel51;
+        break;
+    case MFC_90:
+    case MFC_1010:
+    case MFC_1120:
+        pHevcEnc->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel5;
+        break;
+    case MFC_1011:
+    case MFC_1020:
+        pHevcEnc->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel41;
+        break;
+    case MFC_92:
+    case MFC_1021:
+    default:
+        pHevcEnc->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel4;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc       = NULL;
+
+    int nLevelCnt = 0;
+    OMX_U32 nMaxIndex = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pHevcEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pHevcEnc->hMFCHevcHandle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pHevcEnc->hMFCHevcHandle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pHevcEnc->hMFCHevcHandle.maxLevel;
+#else
+    while ((pHevcEnc->hMFCHevcHandle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+
+    if ((pHevcEnc->hMFCHevcHandle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pHevcEnc->hMFCHevcHandle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pHevcEnc->hMFCHevcHandle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : supported profile(%x), level(%x)",
+                                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc  = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc   = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pHevcEnc == NULL)
+        goto EXIT;
+
+    while ((pHevcEnc->hMFCHevcHandle.maxLevel >> nLevelCnt++) > 0);
+
+    if ((pHevcEnc->hMFCHevcHandle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pHevcEnc->hMFCHevcHandle.nProfileCnt; i++) {
+        if (pHevcEnc->hMFCHevcHandle.profiles[i] == pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    while (nLevelCnt >= 0) {
+        if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+            bLevelSupport = OMX_TRUE;
+            break;
+        }
+
+        nLevelCnt--;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_U32 OMXHevcProfileToProfileIDC(OMX_VIDEO_HEVCPROFILETYPE eProfile)
+{
+    OMX_U32 ret = 0;
+
+    switch (eProfile) {
+    case OMX_VIDEO_HEVCProfileMain:
+        ret = 0;
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+
+    return ret;
+}
+
+static OMX_U32 OMXHevcLevelToTierIDC(OMX_VIDEO_HEVCLEVELTYPE eLevel)
+{
+    OMX_U32 ret = 0; //default Main tier
+
+    switch (eLevel) {
+    case OMX_VIDEO_HEVCMainTierLevel1:
+    case OMX_VIDEO_HEVCMainTierLevel2:
+    case OMX_VIDEO_HEVCMainTierLevel21:
+    case OMX_VIDEO_HEVCMainTierLevel3:
+    case OMX_VIDEO_HEVCMainTierLevel31:
+    case OMX_VIDEO_HEVCMainTierLevel4:
+    case OMX_VIDEO_HEVCMainTierLevel41:
+    case OMX_VIDEO_HEVCMainTierLevel5:
+        ret = 0;
+        break;
+    case OMX_VIDEO_HEVCHighTierLevel1:
+    case OMX_VIDEO_HEVCHighTierLevel2:
+    case OMX_VIDEO_HEVCHighTierLevel21:
+    case OMX_VIDEO_HEVCHighTierLevel3:
+    case OMX_VIDEO_HEVCHighTierLevel31:
+    case OMX_VIDEO_HEVCHighTierLevel4:
+    case OMX_VIDEO_HEVCHighTierLevel41:
+    case OMX_VIDEO_HEVCHighTierLevel5:
+        ret = 1;
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+
+    return ret;
+}
+
+static OMX_U32 OMXHevcLevelToLevelIDC(OMX_VIDEO_HEVCLEVELTYPE eLevel)
+{
+    OMX_U32 ret = 40; //default OMX_VIDEO_HEVCLevel4
+
+    switch (eLevel) {
+    case OMX_VIDEO_HEVCMainTierLevel1:
+    case OMX_VIDEO_HEVCHighTierLevel1:
+        ret = 10;
+        break;
+    case OMX_VIDEO_HEVCMainTierLevel2:
+    case OMX_VIDEO_HEVCHighTierLevel2:
+        ret = 20;
+        break;
+    case OMX_VIDEO_HEVCMainTierLevel21:
+    case OMX_VIDEO_HEVCHighTierLevel21:
+        ret = 21;
+        break;
+    case OMX_VIDEO_HEVCMainTierLevel3:
+    case OMX_VIDEO_HEVCHighTierLevel3:
+        ret = 30;
+        break;
+    case OMX_VIDEO_HEVCMainTierLevel31:
+    case OMX_VIDEO_HEVCHighTierLevel31:
+        ret = 31;
+        break;
+    case OMX_VIDEO_HEVCMainTierLevel4:
+    case OMX_VIDEO_HEVCHighTierLevel4:
+        ret = 40;
+        break;
+    case OMX_VIDEO_HEVCMainTierLevel41:
+    case OMX_VIDEO_HEVCHighTierLevel41:
+        ret = 41;
+        break;
+    case OMX_VIDEO_HEVCMainTierLevel5:
+    case OMX_VIDEO_HEVCHighTierLevel5:
+        ret = 50;
+        break;
+    default:
+        ret = 40;
+        break;
+    }
+
+    return ret;
+}
+
+static void Print_HEVCEnc_Param(ExynosVideoEncParam *pEncParam)
+{
+    ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam;
+    ExynosVideoEncHevcParam   *pHEVCParam   = &pEncParam->codecParam.hevc;
+
+    /* common parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceWidth             : %d", pCommonParam->SourceWidth);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceHeight            : %d", pCommonParam->SourceHeight);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "IDRPeriod               : %d", pCommonParam->IDRPeriod);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SliceMode               : %d", pCommonParam->SliceMode);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "RandomIntraMBRefresh    : %d", pCommonParam->RandomIntraMBRefresh);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Bitrate                 : %d", pCommonParam->Bitrate);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp                 : %d", pCommonParam->FrameQp);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp_P               : %d", pCommonParam->FrameQp_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(I) ranege            : %d / %d", pCommonParam->QpRange.QpMin_I, pCommonParam->QpRange.QpMax_I);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(P) ranege            : %d / %d", pCommonParam->QpRange.QpMin_P, pCommonParam->QpRange.QpMax_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(B) ranege            : %d / %d", pCommonParam->QpRange.QpMin_B, pCommonParam->QpRange.QpMax_B);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "PadControlOn            : %d", pCommonParam->PadControlOn);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LumaPadVal              : %d", pCommonParam->LumaPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CbPadVal                : %d", pCommonParam->CbPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CrPadVal                : %d", pCommonParam->CrPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameMap                : %d", pCommonParam->FrameMap);
+
+    /* HEVC specific parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "ProfileIDC              : %d", pHEVCParam->ProfileIDC);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "TierIDC                 : %d", pHEVCParam->TierIDC);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LevelIDC                : %d", pHEVCParam->LevelIDC);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp_B               : %d", pHEVCParam->FrameQp_B);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameRate               : %d", pHEVCParam->FrameRate);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "MaxPartitionDepth       : %d", pHEVCParam->MaxPartitionDepth);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumberBFrames           : %d", pHEVCParam->NumberBFrames);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumberRefForPframes     : %d", pHEVCParam->NumberRefForPframes);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LoopFilterDisable       : %d", pHEVCParam->LoopFilterDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LoopFilterSliceFlag     : %d", pHEVCParam->LoopFilterSliceFlag);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LoopFilterTcOffset      : %d", pHEVCParam->LoopFilterTcOffset);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LoopFilterBetaOffset    : %d", pHEVCParam->LoopFilterBetaOffset);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LongtermRefEnable       : %d", pHEVCParam->LongtermRefEnable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LongtermUserRef         : %d", pHEVCParam->LongtermUserRef);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LongtermStoreRef        : %d", pHEVCParam->LongtermStoreRef);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "DarkDisable             : %d", pHEVCParam->DarkDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SmoothDisable           : %d", pHEVCParam->SmoothDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "StaticDisable           : %d", pHEVCParam->StaticDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "ActivityDisable         : %d", pHEVCParam->ActivityDisable);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "ROIEnable:              : %d", pHEVCParam->ROIEnable);
+
+    /* rate control related parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableFRMRateControl    : %d", pCommonParam->EnableFRMRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableMBRateControl     : %d", pCommonParam->EnableMBRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CBRPeriodRf             : %d", pCommonParam->CBRPeriodRf);
+}
+
+static void Set_HEVCEnc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_BASEPORT           *pInputPort       = NULL;
+    EXYNOS_OMX_BASEPORT           *pOutputPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_HEVCENC_HANDLE         *pHevcEnc         = NULL;
+    EXYNOS_MFC_HEVCENC_HANDLE     *pMFCHevcHandle   = NULL;
+    OMX_COLOR_FORMATTYPE           eColorFormat     = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncParam       *pEncParam    = NULL;
+    ExynosVideoEncCommonParam *pCommonParam = NULL;
+    ExynosVideoEncHevcParam   *pHEVCParam   = NULL;
+
+    int i;
+
+    pVideoEnc           = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pHevcEnc            = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCHevcHandle      = &pHevcEnc->hMFCHevcHandle;
+    pInputPort          = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pOutputPort         = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    pEncParam       = &pMFCHevcHandle->encParam;
+    pCommonParam    = &pEncParam->commonParam;
+    pHEVCParam      = &pEncParam->codecParam.hevc;
+
+    pEncParam->eCompressionFormat = VIDEO_CODING_HEVC;
+
+    /* common parameters */
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+    } else {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+    }
+    pCommonParam->IDRPeriod    = pHevcEnc->HevcComponent[OUTPUT_PORT_INDEX].nKeyFrameInterval;
+    pCommonParam->SliceMode    = 0;
+    pCommonParam->Bitrate      = pOutputPort->portDefinition.format.video.nBitrate;
+    pCommonParam->FrameQp      = pVideoEnc->quantization.nQpI;
+    pCommonParam->FrameQp_P    = pVideoEnc->quantization.nQpP;
+
+    pCommonParam->QpRange.QpMin_I = pHevcEnc->qpRangeI.nMinQP;
+    pCommonParam->QpRange.QpMax_I = pHevcEnc->qpRangeI.nMaxQP;
+    pCommonParam->QpRange.QpMin_P = pHevcEnc->qpRangeP.nMinQP;
+    pCommonParam->QpRange.QpMax_P = pHevcEnc->qpRangeP.nMaxQP;
+    pCommonParam->QpRange.QpMin_B = pHevcEnc->qpRangeB.nMinQP;
+    pCommonParam->QpRange.QpMax_B = pHevcEnc->qpRangeB.nMaxQP;
+
+    pCommonParam->PadControlOn = 0;    /* 0: disable, 1: enable */
+    pCommonParam->LumaPadVal   = 0;
+    pCommonParam->CbPadVal     = 0;
+    pCommonParam->CrPadVal     = 0;
+
+    if (pVideoEnc->intraRefresh.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) {
+        /* Cyclic Mode */
+        pCommonParam->RandomIntraMBRefresh = pVideoEnc->intraRefresh.nCirMBs;
+    } else {
+        /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+        pCommonParam->RandomIntraMBRefresh = 0;
+    }
+
+    /* Perceptual Mode */
+    pCommonParam->PerceptualMode = (pVideoEnc->bPVCMode)? VIDEO_TRUE:VIDEO_FALSE;
+
+    eColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+    pCommonParam->FrameMap = Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    /* HEVC specific parameters */
+    pHEVCParam->ProfileIDC = OMXHevcProfileToProfileIDC(pHevcEnc->HevcComponent[OUTPUT_PORT_INDEX].eProfile);
+    pHEVCParam->TierIDC    = OMXHevcLevelToTierIDC(pHevcEnc->HevcComponent[OUTPUT_PORT_INDEX].eLevel);
+    pHEVCParam->LevelIDC   = OMXHevcLevelToLevelIDC(pHevcEnc->HevcComponent[OUTPUT_PORT_INDEX].eLevel);
+
+    pHEVCParam->FrameQp_B  = pVideoEnc->quantization.nQpB;
+    pHEVCParam->FrameRate  = (pInputPort->portDefinition.format.video.xFramerate) >> 16;
+
+    /* there is no interface at OMX IL component */
+    pHEVCParam->NumberBFrames         = 0;    /* 0 ~ 2 */
+    pHEVCParam->NumberRefForPframes   = 1;    /* 1 ~ 2 */
+
+    pHEVCParam->MaxPartitionDepth     = 1;
+    pHEVCParam->LoopFilterDisable     = 0;    /* 1: Loop Filter Disable, 0: Filter Enable */
+    pHEVCParam->LoopFilterSliceFlag   = 1;
+    pHEVCParam->LoopFilterTcOffset    = 0;
+    pHEVCParam->LoopFilterBetaOffset  = 0;
+
+    pHEVCParam->LongtermRefEnable     = 0;
+    pHEVCParam->LongtermUserRef       = 0;
+    pHEVCParam->LongtermStoreRef      = 0;
+
+    pHEVCParam->DarkDisable           = 1;    /* disable adaptive rate control on dark region */
+    pHEVCParam->SmoothDisable         = 1;    /* disable adaptive rate control on smooth region */
+    pHEVCParam->StaticDisable         = 1;    /* disable adaptive rate control on static region */
+    pHEVCParam->ActivityDisable       = 1;    /* disable adaptive rate control on high activity region */
+
+    /* Temporal SVC */
+    /* If MaxTemporalLayerCount value is 0, codec supported max value will be set */
+    pHEVCParam->MaxTemporalLayerCount           = (unsigned int)pHevcEnc->nMaxTemporalLayerCount;
+    pHEVCParam->TemporalSVC.nTemporalLayerCount = (unsigned int)pHevcEnc->nTemporalLayerCount;
+
+    if (pHevcEnc->bUseTemporalLayerBitrateRatio == OMX_TRUE) {
+        for (i = 0; i < OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS; i++)
+            pHEVCParam->TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)pHevcEnc->nTemporalLayerBitrateRatio[i];
+    } else {
+        for (i = 0; i < OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS; i++)
+            pHEVCParam->TemporalSVC.nTemporalLayerBitrateRatio[i] = pOutputPort->portDefinition.format.video.nBitrate;
+    }
+
+    pHEVCParam->ROIEnable = (pMFCHevcHandle->bRoiInfo == OMX_TRUE)? 1:0;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eControlRate: 0x%x", pExynosComponent, __FUNCTION__, pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]);
+    /* rate control related parameters */
+    switch ((int)pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) {
+    case OMX_Video_ControlRateDisable:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR");
+        pCommonParam->EnableFRMRateControl = 0;    /* 0: Disable,  1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 0;    /* 0: Disable,  1: MB level RC */
+        pCommonParam->CBRPeriodRf          = 100;
+        break;
+    case OMX_Video_ControlRateConstantVTCall:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR VT Call");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable,  1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable,  1: MB level RC */
+        pCommonParam->CBRPeriodRf          = 5;
+        pCommonParam->bFixedSlice          = VIDEO_TRUE;
+        break;
+    case OMX_Video_ControlRateConstant:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 9;
+        break;
+    case OMX_Video_ControlRateVariable:
+    default: /*Android default */
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 100;
+        break;
+    }
+
+//    Print_HEVCEnc_Param(pEncParam);
+}
+
+static void Change_HEVCEnc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = NULL;
+    EXYNOS_HEVCENC_HANDLE         *pHevcEnc          = NULL;
+    EXYNOS_MFC_HEVCENC_HANDLE     *pMFCHevcHandle    = NULL;
+    OMX_PTR                        pDynamicConfigCMD = NULL;
+    OMX_PTR                        pConfigData       = NULL;
+    OMX_S32                        nCmdIndex         = 0;
+    ExynosVideoEncOps             *pEncOps           = NULL;
+    int                            nValue            = 0;
+
+    int i;
+
+    pVideoEnc       = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pHevcEnc        = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCHevcHandle  = &pHevcEnc->hMFCHevcHandle;
+    pEncOps         = pMFCHevcHandle->pEncOps;
+
+    pDynamicConfigCMD = (OMX_PTR)Exynos_OSAL_Dequeue(&pExynosComponent->dynamicConfigQ);
+    if (pDynamicConfigCMD == NULL)
+        goto EXIT;
+
+    nCmdIndex   = *(OMX_S32 *)pDynamicConfigCMD;
+    pConfigData = (OMX_PTR)((OMX_U8 *)pDynamicConfigCMD + sizeof(OMX_S32));
+
+    switch ((int)nCmdIndex) {
+    case OMX_IndexConfigVideoIntraVOPRefresh:
+    {
+        nValue = VIDEO_FRAME_I;
+        pEncOps->Set_FrameType(pMFCHevcHandle->hMFCHandle, nValue);
+        pVideoEnc->IntraRefreshVOP = OMX_FALSE;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] VOP Refresh", pExynosComponent, __FUNCTION__);
+    }
+        break;
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        OMX_S32 nPFrames = (*((OMX_U32 *)pConfigData)) - 1;
+        nValue = nPFrames + 1;
+        pEncOps->Set_IDRPeriod(pMFCHevcHandle->hMFCHandle, nValue);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] IDR period: %d", pExynosComponent, __FUNCTION__, nValue);
+    }
+        break;
+    case OMX_IndexConfigVideoBitrate:
+    {
+        OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pConfigData;
+
+        if (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] != OMX_Video_ControlRateDisable) {
+            nValue = pConfigBitrate->nEncodeBitrate;
+            pEncOps->Set_BitRate(pMFCHevcHandle->hMFCHandle, nValue);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bitrate: %d", pExynosComponent, __FUNCTION__, nValue);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoFramerate:
+    {
+        OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pConfigData;
+        OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
+
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            nValue = (pConfigFramerate->xEncodeFramerate) >> 16;
+            pEncOps->Set_FrameRate(pMFCHevcHandle->hMFCHandle, nValue);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] framerate: %d", pExynosComponent, __FUNCTION__, nValue);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange = (OMX_VIDEO_QPRANGETYPE *)pConfigData;
+        ExynosVideoQPRange     qpRange;
+
+        qpRange.QpMin_I = pQpRange->qpRangeI.nMinQP;
+        qpRange.QpMax_I = pQpRange->qpRangeI.nMaxQP;
+        qpRange.QpMin_P = pQpRange->qpRangeP.nMinQP;
+        qpRange.QpMax_P = pQpRange->qpRangeP.nMaxQP;
+        qpRange.QpMin_B = pQpRange->qpRangeB.nMinQP;
+        qpRange.QpMax_B = pQpRange->qpRangeB.nMaxQP;
+
+        pEncOps->Set_QpRange(pMFCHevcHandle->hMFCHandle, qpRange);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qp range: I(%d, %d), P(%d, %d), B(%d, %d)",
+                                    pExynosComponent, __FUNCTION__,
+                                    qpRange.QpMin_I, qpRange.QpMax_I,
+                                    qpRange.QpMin_P, qpRange.QpMax_P,
+                                    qpRange.QpMin_B, qpRange.QpMax_B);
+    }
+        break;
+    case OMX_IndexConfigOperatingRate:
+    {
+        OMX_PARAM_U32TYPE *pConfigRate = (OMX_PARAM_U32TYPE *)pConfigData;
+        OMX_U32            xFramerate  = pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.xFramerate;
+
+        if (xFramerate == 0)
+            nValue = 100;
+        else
+            nValue = (OMX_U32)((pConfigRate->nU32 / (double)xFramerate) * 100);
+
+        pEncOps->Set_QosRatio(pMFCHevcHandle->hMFCHandle, nValue);
+        pVideoEnc->bQosChanged = OMX_FALSE;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qos ratio: %d", pExynosComponent, __FUNCTION__, nValue);
+    }
+        break;
+    case OMX_IndexConfigVideoTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pTemporalSVC = (EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *)pConfigData;
+        ExynosVideoQPRange qpRange;
+        TemporalLayerShareBuffer TemporalSVC;
+
+        qpRange.QpMin_I = pTemporalSVC->nMinQuantizer;
+        qpRange.QpMax_I = pTemporalSVC->nMaxQuantizer;
+        qpRange.QpMin_P = pTemporalSVC->nMinQuantizer;
+        qpRange.QpMax_P = pTemporalSVC->nMaxQuantizer;
+        qpRange.QpMin_B = pTemporalSVC->nMinQuantizer;
+        qpRange.QpMax_B = pTemporalSVC->nMaxQuantizer;
+
+        pEncOps->Set_QpRange(pMFCHevcHandle->hMFCHandle, qpRange);
+        pEncOps->Set_IDRPeriod(pMFCHevcHandle->hMFCHandle, pTemporalSVC->nKeyFrameInterval);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // qp range: I(%d, %d), P(%d, %d), B(%d, %d)",
+                                    pExynosComponent, __FUNCTION__,
+                                    qpRange.QpMin_I, qpRange.QpMax_I,
+                                    qpRange.QpMin_P, qpRange.QpMax_P,
+                                    qpRange.QpMin_B, qpRange.QpMax_B);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // IDR period: %d", pExynosComponent, __FUNCTION__, nValue);
+
+        /* Temporal SVC */
+        Exynos_OSAL_Memset(&TemporalSVC, 0, sizeof(TemporalLayerShareBuffer));
+
+        TemporalSVC.nTemporalLayerCount = (unsigned int)pTemporalSVC->nTemporalLayerCount;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // layer count: %d", pExynosComponent, __FUNCTION__, TemporalSVC.nTemporalLayerCount);
+
+        for (i = 0; i < OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS; i++) {
+            TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)pTemporalSVC->nTemporalLayerBitrateRatio[i];
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // bitrate ratio[%d]: %d",
+                                                    pExynosComponent, __FUNCTION__,
+                                                    i, TemporalSVC.nTemporalLayerBitrateRatio[i]);
+        }
+        if (pEncOps->Set_LayerChange(pMFCHevcHandle->hMFCHandle, TemporalSVC) != VIDEO_ERROR_NONE)
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Not supported control: Set_LayerChange", pExynosComponent, __FUNCTION__);
+    }
+        break;
+     case OMX_IndexConfigVideoRoiInfo:
+     {
+        EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *pRoiInfo = (EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *)pConfigData;
+
+        /* ROI INFO */
+        RoiInfoShareBuffer RoiInfo;
+
+        Exynos_OSAL_Memset(&RoiInfo, 0, sizeof(RoiInfo));
+        RoiInfo.pRoiMBInfo     = (OMX_U64)(unsigned long)(((OMX_U8 *)pConfigData) + sizeof(EXYNOS_OMX_VIDEO_CONFIG_ROIINFO));
+        RoiInfo.nRoiMBInfoSize = pRoiInfo->nRoiMBInfoSize;
+        RoiInfo.nUpperQpOffset = pRoiInfo->nUpperQpOffset;
+        RoiInfo.nLowerQpOffset = pRoiInfo->nLowerQpOffset;
+        RoiInfo.bUseRoiInfo    = (pRoiInfo->bUseRoiInfo == OMX_TRUE)? VIDEO_TRUE:VIDEO_FALSE;
+
+        if (pEncOps->Set_RoiInfo(pMFCHevcHandle->hMFCHandle, &RoiInfo) != VIDEO_ERROR_NONE)
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Set_RoiInfo()", pExynosComponent, __FUNCTION__);
+    }
+        break;
+    case OMX_IndexConfigIFrameRatio:
+    {
+        OMX_PARAM_U32TYPE *pIFrameRatio = (OMX_PARAM_U32TYPE *)pConfigData;
+
+        pEncOps->Set_IFrameRatio(pMFCHevcHandle->hMFCHandle, pIFrameRatio->nU32);
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexConfigAndroidVideoTemporalLayering:
+    {
+        OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *pTemporalLayering = (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *)pConfigData;
+
+        TemporalLayerShareBuffer TemporalSVC;
+
+        /* Temporal SVC */
+        Exynos_OSAL_Memset(&TemporalSVC, 0, sizeof(TemporalLayerShareBuffer));
+
+        TemporalSVC.nTemporalLayerCount = (unsigned int)(pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual);
+
+        if (pTemporalLayering->bBitrateRatiosSpecified == OMX_TRUE) {
+            for (i = 0; i < (int)pHevcEnc->nMaxTemporalLayerCount; i++) {
+
+                TemporalSVC.nTemporalLayerBitrateRatio[i] = (pTemporalLayering->nBitrateRatios[i] >> 16);
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // bitrate ratio[%d]: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        i, TemporalSVC.nTemporalLayerBitrateRatio[i]);
+            }
+        } else {
+            EXYNOS_OMX_BASEPORT *pOutputPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+
+            for (i = 0; i < (int)pHevcEnc->nMaxTemporalLayerCount; i++) {
+                TemporalSVC.nTemporalLayerBitrateRatio[i] = pOutputPort->portDefinition.format.video.nBitrate;
+
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] temporal svc // bitrate ratio[%d]: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        i, TemporalSVC.nTemporalLayerBitrateRatio[i]);
+            }
+        }
+
+        if (pEncOps->Set_LayerChange(pMFCHevcHandle->hMFCHandle, TemporalSVC) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Not supported control: Set_LayerChange", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Max(%d), layer(%d), B-layer(%d)", pExynosComponent, __FUNCTION__,
+                                               pHevcEnc->nMaxTemporalLayerCount, TemporalSVC.nTemporalLayerCount, pTemporalLayering->nBLayerCountActual);
+    }
+        break;
+#endif
+    default:
+        break;
+    }
+
+    Exynos_OSAL_Free(pDynamicConfigCMD);
+
+    Set_HEVCEnc_Param(pExynosComponent);
+
+EXIT:
+    return;
+}
+
+OMX_ERRORTYPE GetCodecOutputPrivateData(
+    OMX_PTR  pCodecBuffer,
+    OMX_PTR *pVirtAddr,
+    OMX_U32 *pDataSize)
+{
+    OMX_ERRORTYPE      ret          = OMX_ErrorNone;
+    ExynosVideoBuffer *pVideoBuffer = NULL;
+
+    if (pCodecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoBuffer = (ExynosVideoBuffer *)pCodecBuffer;
+
+    if (pVirtAddr != NULL)
+        *pVirtAddr = pVideoBuffer->planes[0].addr;
+
+    if (pDataSize != NULL)
+        *pDataSize = pVideoBuffer->planes[0].allocSize;
+
+EXIT:
+    return ret;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc       = NULL;
+    EXYNOS_OMX_BASEPORT             *pInputPort     = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pHevcEnc == NULL)
+        goto EXIT;
+    pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE HEVCCodecOpen(
+    EXYNOS_HEVCENC_HANDLE   *pHevcEnc,
+    ExynosVideoInstInfo     *pVideoInstInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pHevcEnc == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pEncOps     = (ExynosVideoEncOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncOps));
+    pInbufOps   = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+    pOutbufOps  = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+
+    if ((pEncOps == NULL) ||
+        (pInbufOps == NULL) ||
+        (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pHevcEnc->hMFCHevcHandle.pEncOps    = pEncOps;
+    pHevcEnc->hMFCHevcHandle.pInbufOps  = pInbufOps;
+    pHevcEnc->hMFCHevcHandle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pEncOps->nSize     = sizeof(ExynosVideoEncOps);
+    pInbufOps->nSize   = sizeof(ExynosVideoEncBufferOps);
+    pOutbufOps->nSize  = sizeof(ExynosVideoEncBufferOps);
+
+    if (Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for encoder ops */
+    if ((pEncOps->Init == NULL) ||
+        (pEncOps->Finalize == NULL) ||
+        (pEncOps->Set_FrameTag == NULL) ||
+        (pEncOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pHevcEnc->hMFCHevcHandle.hMFCHandle = pHevcEnc->hMFCHevcHandle.pEncOps->Init(pVideoInstInfo);
+    if (pHevcEnc->hMFCHevcHandle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pEncOps != NULL) {
+            Exynos_OSAL_Free(pEncOps);
+            pHevcEnc->hMFCHevcHandle.pEncOps = NULL;
+        }
+
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pHevcEnc->hMFCHevcHandle.pInbufOps = NULL;
+        }
+
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pHevcEnc->hMFCHevcHandle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HEVCCodecClose(EXYNOS_HEVCENC_HANDLE *pHevcEnc)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pHevcEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pHevcEnc->hMFCHevcHandle.hMFCHandle;
+    pEncOps    = pHevcEnc->hMFCHevcHandle.pEncOps;
+    pInbufOps  = pHevcEnc->hMFCHevcHandle.pInbufOps;
+    pOutbufOps = pHevcEnc->hMFCHevcHandle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pEncOps->Finalize(hMFCHandle);
+        hMFCHandle = pHevcEnc->hMFCHevcHandle.hMFCHandle = NULL;
+        pHevcEnc->hMFCHevcHandle.bConfiguredMFCSrc = OMX_FALSE;
+        pHevcEnc->hMFCHevcHandle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Encoder(pEncOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pOutbufOps = pHevcEnc->hMFCHevcHandle.pOutbufOps = NULL;
+    }
+
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pInbufOps = pHevcEnc->hMFCHevcHandle.pInbufOps = NULL;
+    }
+
+    if (pEncOps != NULL) {
+        Exynos_OSAL_Free(pEncOps);
+        pEncOps = pHevcEnc->hMFCHevcHandle.pEncOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HEVCCodecStart(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pHevcEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pHevcEnc->hMFCHevcHandle.hMFCHandle;
+    pInbufOps  = pHevcEnc->hMFCHevcHandle.pInbufOps;
+    pOutbufOps = pHevcEnc->hMFCHevcHandle.pOutbufOps;
+
+    if (nPortIndex == INPUT_PORT_INDEX)
+        pInbufOps->Run(hMFCHandle);
+    else if (nPortIndex == OUTPUT_PORT_INDEX)
+        pOutbufOps->Run(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HEVCCodecStop(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pHevcEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pHevcEnc->hMFCHevcHandle.hMFCHandle;
+    pInbufOps  = pHevcEnc->hMFCHevcHandle.pInbufOps;
+    pOutbufOps = pHevcEnc->hMFCHevcHandle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
+        pInbufOps->Stop(hMFCHandle);
+    else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
+        pOutbufOps->Stop(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HEVCCodecOutputBufferProcessRun(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = NULL;
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pHevcEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pHevcEnc->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pHevcEnc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pHevcEnc->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pHevcEnc->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pHevcEnc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HEVCCodecEnqueueAllBuffer(
+    OMX_COMPONENTTYPE *pOMXComponent,
+    OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                            *hMFCHandle         = pHevcEnc->hMFCHevcHandle.hMFCHandle;
+
+    ExynosVideoEncBufferOps *pInbufOps  = pHevcEnc->hMFCHevcHandle.pInbufOps;
+    ExynosVideoEncBufferOps *pOutbufOps = pHevcEnc->hMFCHevcHandle.pOutbufOps;
+
+    int i;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) &&
+        (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pHevcEnc->bSourceStart == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)  {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoEnc->pMFCEncInputBuffer[i]->fd[0], pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pHevcEnc->bDestinationStart == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoEnc->pMFCEncOutputBuffer[i]->fd[0], pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoEnc->pMFCEncOutputBuffer[i]);
+        }
+
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HEVCCodecSrcSetup(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCENC_HANDLE         *pHevcEnc         = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_HEVCENC_HANDLE     *pMFCHevcHandle   = &pHevcEnc->hMFCHevcHandle;
+    void                          *hMFCHandle       = pMFCHevcHandle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort       = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort      = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize     = pSrcInputData->dataLen;
+
+    ExynosVideoEncOps       *pEncOps    = pHevcEnc->hMFCHevcHandle.pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps  = pHevcEnc->hMFCHevcHandle.pInbufOps;
+    ExynosVideoEncParam     *pEncParam    = NULL;
+
+    ExynosVideoGeometry      bufferConf;
+    OMX_U32                  inputBufferNumber = 0;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pHevcEnc->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pHevcEnc->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pHevcEnc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    Set_HEVCEnc_Param(pExynosComponent);
+
+    pEncParam = &pMFCHevcHandle->encParam;
+    if (pEncOps->Set_EncParam) {
+        if(pEncOps->Set_EncParam(pHevcEnc->hMFCHevcHandle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set encParam", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    Print_HEVCEnc_Param(pEncParam);
+
+     if (pMFCHevcHandle->bPrependSpsPpsToIdr == OMX_TRUE) {
+         if (pEncOps->Enable_PrependSpsPpsToIdr)
+             pEncOps->Enable_PrependSpsPpsToIdr(pHevcEnc->hMFCHevcHandle.hMFCHandle);
+         else
+             Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Not supported control: Enable_PrependSpsPpsToIdr", pExynosComponent, __FUNCTION__);
+     }
+
+#ifdef USE_ANDROID
+    if ((pInputPort->eMetaDataType == METADATA_TYPE_GRAPHIC) &&
+        ((pInputPort->bufferProcessType & BUFFER_SHARE) &&
+         (pSrcInputData->buffer.addr[2] != NULL))) {
+        ExynosVideoMeta *pMeta = (ExynosVideoMeta *)pSrcInputData->buffer.addr[2];
+
+        if (pMeta->eType & VIDEO_INFO_TYPE_YSUM_DATA) {
+            if (VIDEO_ERROR_NONE == pEncOps->Enable_WeightedPrediction(hMFCHandle))
+                pMFCHevcHandle->bWeightedPrediction = OMX_TRUE;
+        }
+    }
+#endif
+
+#ifdef USE_ANDROID
+    if (pMFCHevcHandle->videoInstInfo.supportInfo.enc.bColorAspectsSupport == VIDEO_TRUE) {
+        ExynosVideoColorAspects BSCA;
+        Exynos_OSAL_Memset(&BSCA, 0, sizeof(BSCA));
+
+        Exynos_OSAL_GetColorAspectsForBitstream(&(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].ColorAspects),
+                                                &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects));
+
+        BSCA.eRangeType     = (ExynosRangeType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nRangeType;
+        BSCA.ePrimariesType = (ExynosPrimariesType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nPrimaryType;
+        BSCA.eTransferType  = (ExynosTransferType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nTransferType;
+        BSCA.eCoeffType     = (ExynosMatrixCoeffType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nCoeffType;
+
+        pEncOps->Set_ColorAspects(hMFCHandle, &BSCA);
+    }
+#endif
+
+    /* input buffer info: only 3 config values needed */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        bufferConf.nFrameWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        bufferConf.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+        bufferConf.nStride      = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth, 16);
+    } else {
+        bufferConf.nFrameWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        bufferConf.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+        bufferConf.nStride      = ALIGN(pOutputPort->portDefinition.format.video.nFrameHeight, 16);
+    }
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+    pInbufOps->Set_Shareable(hMFCHandle);
+    inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare input buffer */
+        if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry) {
+        if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if ((pInputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pInputPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
+        /* data buffer */
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    }
+
+    pHevcEnc->hMFCHevcHandle.bConfiguredMFCSrc = OMX_TRUE;
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE HEVCCodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCENC_HANDLE         *pHevcEnc             = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_HEVCENC_HANDLE     *pMFCHevcHandle       = &pHevcEnc->hMFCHevcHandle;
+    void                          *hMFCHandle           = pMFCHevcHandle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pOutbufOps = pHevcEnc->hMFCHevcHandle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0};
+    unsigned int nDataLen[VIDEO_BUFFER_MAX_PLANES]  = {0, 0, 0};
+    int i, nOutBufSize = 0, nOutputBufferCnt = 0;
+
+    FunctionIn();
+
+    nOutBufSize = pOutputPort->portDefinition.nBufferSize;
+    if ((pOutputPort->bufferProcessType & BUFFER_COPY) ||
+        (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        /* OMX buffer is not used directly : CODEC buffer or MetaData */
+        nOutBufSize = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth *
+                            pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+    }
+
+    /* set geometry for output (dst) */
+    if (pOutbufOps->Set_Geometry) {
+        /* output buffer info: only 2 config values needed */
+        bufferConf.eCompressionFormat = VIDEO_CODING_HEVC;
+        bufferConf.nSizeImage = nOutBufSize;
+        bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pOutputPort);
+
+        if (pOutbufOps->Set_Geometry(pHevcEnc->hMFCHevcHandle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* should be done before prepare output buffer */
+    if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY)
+        nOutputBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
+    else
+        nOutputBufferCnt = pOutputPort->portDefinition.nBufferCountActual;
+
+    if (pOutbufOps->Setup(pHevcEnc->hMFCHevcHandle.hMFCHandle, nOutputBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        nAllocLen[0] = nOutBufSize;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Allocate_CodecBuffers for output", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        /* Enqueue output buffer */
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
+                                (unsigned long *)pVideoEnc->pMFCEncOutputBuffer[i]->fd,
+                                pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pOutputPort),
+                                NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* Register output buffer */
+        /*************/
+        /*    TBD    */
+        /*************/
+    }
+
+    pHevcEnc->hMFCHevcHandle.bConfiguredMFCDst = OMX_TRUE;
+
+    if (HEVCCodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_GetParameter(
+    OMX_IN    OMX_HANDLETYPE hComponent,
+    OMX_IN    OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc         = NULL;
+
+    int i;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nParamIndex %x", pExynosComponent, __FUNCTION__, (int)nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoHevc:
+    {
+        OMX_VIDEO_PARAM_HEVCTYPE *pDstHevcComponent = (OMX_VIDEO_PARAM_HEVCTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_HEVCTYPE *pSrcHevcComponent = NULL;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstHevcComponent, sizeof(OMX_VIDEO_PARAM_HEVCTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstHevcComponent->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcHevcComponent = &pHevcEnc->HevcComponent[pDstHevcComponent->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstHevcComponent) + nOffset,
+                           ((char *)pSrcHevcComponent) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_HEVCTYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+            Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_HEVC_DRM_ENC_ROLE);
+        else
+            Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_HEVC_ENC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel  = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_HEVCTYPE         *pSrcHevcComponent = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcHevcComponent = &pHevcEnc->HevcComponent[pDstProfileLevel->nPortIndex];
+
+        pDstProfileLevel->eProfile = pSrcHevcComponent->eProfile;
+        pDstProfileLevel->eLevel   = pSrcHevcComponent->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pHevcEnc->errorCorrectionType[OUTPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC              = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync           = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing   = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC             = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pHevcEnc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pHevcEnc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pHevcEnc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pHevcEnc->qpRangeP.nMaxQP;
+        pQpRange->qpRangeB.nMinQP = pHevcEnc->qpRangeB.nMinQP;
+        pQpRange->qpRangeB.nMaxQP = pHevcEnc->qpRangeB.nMaxQP;
+    }
+        break;
+    case OMX_IndexParamVideoHevcEnableTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC *pDstEnableTemporalSVC = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstEnableTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstEnableTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstEnableTemporalSVC->bEnableTemporalSVC = pHevcEnc->hMFCHevcHandle.bTemporalSVC;
+    }
+        break;
+    case OMX_IndexParamVideoEnableRoiInfo:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *pDstEnableRoiInfo = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstEnableRoiInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstEnableRoiInfo->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstEnableRoiInfo->bEnableRoiInfo = pHevcEnc->hMFCHevcHandle.bRoiInfo;
+    }
+        break;
+    case OMX_IndexParamVideoEnablePVC:
+    {
+        OMX_PARAM_U32TYPE *pEnablePVC  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pEnablePVC, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pEnablePVC->nU32 = pVideoEnc->bPVCMode;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamAndroidVideoTemporalLayering:
+    {
+        OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalLayering = (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pTemporalLayering, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pTemporalLayering->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) {
+            pTemporalLayering->eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternNone;
+            pTemporalLayering->nLayerCountMax     = 1;  /* not supported */
+            pTemporalLayering->nBLayerCountMax    = 0;
+            pTemporalLayering->ePattern           = OMX_VIDEO_AndroidTemporalLayeringPatternNone;
+        } else {
+            pTemporalLayering->eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+
+            if (pHevcEnc->hMFCHevcHandle.bTemporalSVC == OMX_TRUE) {
+                pTemporalLayering->nLayerCountMax   = pHevcEnc->nMaxTemporalLayerCount;
+                pTemporalLayering->nBLayerCountMax  = pHevcEnc->nMaxTemporalLayerCountForB;
+                pTemporalLayering->ePattern         = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+            } else {
+                pTemporalLayering->nLayerCountMax   = OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS;
+                pTemporalLayering->nBLayerCountMax  = OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS_FOR_B;
+                pTemporalLayering->ePattern         = OMX_VIDEO_AndroidTemporalLayeringPatternNone;
+            }
+        }
+
+        pTemporalLayering->nPLayerCountActual = pHevcEnc->nTemporalLayerCount;
+        pTemporalLayering->nBLayerCountActual = pHevcEnc->nTemporalLayerCountForB;
+
+        pTemporalLayering->bBitrateRatiosSpecified = pHevcEnc->bUseTemporalLayerBitrateRatio;
+        if (pTemporalLayering->bBitrateRatiosSpecified == OMX_TRUE) {
+            for (i = 0; i < OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS; i++)
+                pTemporalLayering->nBitrateRatios[i] = (pHevcEnc->nTemporalLayerBitrateRatio[i] << 16);
+        }
+    }
+        break;
+#endif
+    default:
+        ret = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc         = NULL;
+
+    int i;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoHevc:
+    {
+        OMX_VIDEO_PARAM_HEVCTYPE *pDstHevcComponent = NULL;
+        OMX_VIDEO_PARAM_HEVCTYPE *pSrcHevcComponent = (OMX_VIDEO_PARAM_HEVCTYPE *)pComponentParameterStructure;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcHevcComponent, sizeof(OMX_VIDEO_PARAM_HEVCTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcHevcComponent->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstHevcComponent = &pHevcEnc->HevcComponent[pSrcHevcComponent->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstHevcComponent) + nOffset,
+                           ((char *)pSrcHevcComponent) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_HEVCTYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_HEVC_ENC_ROLE) ||
+            !Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_HEVC_DRM_ENC_ROLE)) {
+            pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel  = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_HEVCTYPE         *pDstHevcComponent = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstHevcComponent = &pHevcEnc->HevcComponent[pSrcProfileLevel->nPortIndex];
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pDstHevcComponent->eProfile = pSrcProfileLevel->eProfile;
+        pDstHevcComponent->eLevel   = pSrcProfileLevel->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pHevcEnc->errorCorrectionType[OUTPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP) ||
+            (pQpRange->qpRangeB.nMinQP > pQpRange->qpRangeB.nMaxQP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d], B[min:%d, max:%d])", __FUNCTION__,
+                            pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                            pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP,
+                            pQpRange->qpRangeB.nMinQP, pQpRange->qpRangeB.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pHevcEnc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pHevcEnc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pHevcEnc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pHevcEnc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+        pHevcEnc->qpRangeB.nMinQP = pQpRange->qpRangeB.nMinQP;
+        pHevcEnc->qpRangeB.nMaxQP = pQpRange->qpRangeB.nMaxQP;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamPrependSPSPPSToIDR:
+    {
+
+        ret = Exynos_OSAL_SetPrependSPSPPSToIDR(pComponentParameterStructure, &(pHevcEnc->hMFCHevcHandle.bPrependSpsPpsToIdr));
+    }
+        break;
+    case OMX_IndexParamAndroidVideoTemporalLayering:
+    {
+        OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalLayering = (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pTemporalLayering, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pTemporalLayering->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pTemporalLayering->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternNone) {
+            /* ENABLE */
+            if (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] Temporal SVC is not supported", pExynosComponent, __FUNCTION__);
+                ret = OMX_ErrorUnsupportedIndex;
+                goto EXIT;
+            }
+
+            if (pTemporalLayering->nLayerCountMax > OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] total layer : Max value(%d) > supportable Max value(%d)",
+                                        pExynosComponent, __FUNCTION__, pTemporalLayering->nLayerCountMax, OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS);
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+            }
+
+            if (pTemporalLayering->nBLayerCountMax > OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS_FOR_B) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] B layer : Max value(%d) > supportable Max value(%d)",
+                                        pExynosComponent, __FUNCTION__, pTemporalLayering->nBLayerCountMax, OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS_FOR_B);
+                ret = OMX_ErrorBadParameter;
+                goto EXIT;
+            }
+
+            pHevcEnc->hMFCHevcHandle.bTemporalSVC = OMX_TRUE;
+            pHevcEnc->nMaxTemporalLayerCount      = pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual;
+            pHevcEnc->nMaxTemporalLayerCountForB  = pTemporalLayering->nBLayerCountActual;
+            pHevcEnc->nTemporalLayerCount         = pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual;
+            pHevcEnc->nTemporalLayerCountForB     = pTemporalLayering->nBLayerCountActual;
+
+            pHevcEnc->bUseTemporalLayerBitrateRatio = pTemporalLayering->bBitrateRatiosSpecified;
+            if (pHevcEnc->bUseTemporalLayerBitrateRatio == OMX_TRUE) {
+                for (i = 0; i < (int)pHevcEnc->nMaxTemporalLayerCount; i++)
+                    pHevcEnc->nTemporalLayerBitrateRatio[i] = (pTemporalLayering->nBitrateRatios[i] >> 16);
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Max(%d), B-Max(%d), layer(%d), B-layer(%d)", pExynosComponent, __FUNCTION__,
+                                                    pHevcEnc->nMaxTemporalLayerCount, pHevcEnc->nMaxTemporalLayerCountForB,
+                                                    pHevcEnc->nTemporalLayerCount, pHevcEnc->nTemporalLayerCountForB);
+        } else {
+            /* DISABLE */
+            pHevcEnc->hMFCHevcHandle.bTemporalSVC   = OMX_FALSE;
+            pHevcEnc->nMaxTemporalLayerCount        = 0;
+            pHevcEnc->nMaxTemporalLayerCountForB    = 0;
+            pHevcEnc->nTemporalLayerCount           = 0;
+            pHevcEnc->nTemporalLayerCountForB       = 0;
+            pHevcEnc->bUseTemporalLayerBitrateRatio = OMX_FALSE;
+            Exynos_OSAL_Memset(pHevcEnc->nTemporalLayerBitrateRatio, 0, sizeof(pHevcEnc->nTemporalLayerBitrateRatio));
+        }
+    }
+        break;
+#endif
+    case OMX_IndexParamVideoHevcEnableTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC   *pSrcEnableTemporalSVC  = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC *)pComponentParameterStructure;
+        OMX_PARAM_PORTDEFINITIONTYPE                *pPortDef               = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition);
+        int i;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcEnableTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcEnableTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) &&
+            (pSrcEnableTemporalSVC->bEnableTemporalSVC == OMX_TRUE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Temporal SVC is not supported", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        if ((pSrcEnableTemporalSVC->bEnableTemporalSVC == OMX_TRUE) &&
+            (pHevcEnc->hMFCHevcHandle.bTemporalSVC == OMX_FALSE)) {
+            /* ENABLE : not initialized yet */
+            pHevcEnc->hMFCHevcHandle.bTemporalSVC   = OMX_TRUE;
+            pHevcEnc->nMaxTemporalLayerCount        = OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS;
+            pHevcEnc->nMaxTemporalLayerCountForB    = OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS_FOR_B;
+            pHevcEnc->nTemporalLayerCount           = 1;
+            pHevcEnc->nTemporalLayerCountForB       = 0;
+            pHevcEnc->bUseTemporalLayerBitrateRatio = OMX_TRUE;
+            pHevcEnc->nTemporalLayerBitrateRatio[0] = pPortDef->format.video.nBitrate;
+        } else if (pSrcEnableTemporalSVC->bEnableTemporalSVC == OMX_FALSE) {
+            /* DISABLE */
+            pHevcEnc->hMFCHevcHandle.bTemporalSVC   = OMX_FALSE;  /* DISABLE */
+            pHevcEnc->nMaxTemporalLayerCount        = 0;
+            pHevcEnc->nMaxTemporalLayerCountForB    = 0;
+            pHevcEnc->nTemporalLayerCount           = 0;
+            pHevcEnc->nTemporalLayerCountForB       = 0;
+            pHevcEnc->bUseTemporalLayerBitrateRatio = OMX_FALSE;
+            Exynos_OSAL_Memset(pHevcEnc->nTemporalLayerBitrateRatio, 0, sizeof(pHevcEnc->nTemporalLayerBitrateRatio));
+        }
+    }
+        break;
+    case OMX_IndexParamVideoEnableRoiInfo:
+    {
+        EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *pSrcEnableRoiInfo = (EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcEnableRoiInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcEnableRoiInfo->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bRoiInfoSupport == VIDEO_FALSE) &&
+            (pSrcEnableRoiInfo->bEnableRoiInfo == OMX_TRUE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Roi Info is not supported", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        pHevcEnc->hMFCHevcHandle.bRoiInfo = pSrcEnableRoiInfo->bEnableRoiInfo;
+    }
+        break;
+    case OMX_IndexParamVideoEnablePVC:
+    {
+        OMX_PARAM_U32TYPE *pEnablePVC  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pEnablePVC, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bPVCSupport == VIDEO_FALSE) &&
+            (pEnablePVC->nU32 != 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] PVC mode is not supported", pExynosComponent, __FUNCTION__);
+        }
+
+        pVideoEnc->bPVCMode = (pEnablePVC->nU32 != 0)? OMX_TRUE:OMX_FALSE;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_GetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc         = NULL;
+
+    int i;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pHevcEnc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pHevcEnc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pHevcEnc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pHevcEnc->qpRangeP.nMaxQP;
+        pQpRange->qpRangeB.nMinQP = pHevcEnc->qpRangeB.nMinQP;
+        pQpRange->qpRangeB.nMaxQP = pHevcEnc->qpRangeB.nMaxQP;
+    }
+        break;
+    case OMX_IndexConfigVideoTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pDstTemporalSVC = (EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *)pComponentConfigStructure;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstTemporalSVC->nKeyFrameInterval   = pHevcEnc->HevcComponent[OUTPUT_PORT_INDEX].nKeyFrameInterval;
+        pDstTemporalSVC->nMinQuantizer       = pHevcEnc->qpRangeI.nMinQP;
+        pDstTemporalSVC->nMaxQuantizer       = pHevcEnc->qpRangeI.nMaxQP;
+        pDstTemporalSVC->nTemporalLayerCount = pHevcEnc->nTemporalLayerCount;
+        for (i = 0; i < OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS; i++)
+            pDstTemporalSVC->nTemporalLayerBitrateRatio[i] = pHevcEnc->nTemporalLayerBitrateRatio[i];
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_SetConfig(
+    OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex,
+    OMX_PTR pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                   ret                 = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = NULL;
+
+    int i;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        pHevcEnc->HevcComponent[OUTPUT_PORT_INDEX].nKeyFrameInterval = *((OMX_U32 *)pComponentConfigStructure);
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP) ||
+            (pQpRange->qpRangeB.nMinQP > pQpRange->qpRangeB.nMaxQP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d], B[min:%d, max:%d])",
+                            pExynosComponent, __FUNCTION__,
+                            pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                            pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP,
+                            pQpRange->qpRangeB.nMinQP, pQpRange->qpRangeB.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_FALSE)
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] only I-frame's QP range is applied", pExynosComponent, __FUNCTION__);
+
+        pHevcEnc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pHevcEnc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pHevcEnc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pHevcEnc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+        pHevcEnc->qpRangeB.nMinQP = pQpRange->qpRangeB.nMinQP;
+        pHevcEnc->qpRangeB.nMaxQP = pQpRange->qpRangeB.nMaxQP;
+    }
+        break;
+    case OMX_IndexConfigVideoTemporalSVC:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pSrcTemporalSVC = (EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *)pComponentConfigStructure;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcTemporalSVC, sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pHevcEnc->hMFCHevcHandle.bTemporalSVC == OMX_FALSE) ||
+            (pSrcTemporalSVC->nTemporalLayerCount > OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pHevcEnc->HevcComponent[OUTPUT_PORT_INDEX].nKeyFrameInterval = pSrcTemporalSVC->nKeyFrameInterval;
+
+        pHevcEnc->qpRangeI.nMinQP = pSrcTemporalSVC->nMinQuantizer;
+        pHevcEnc->qpRangeI.nMaxQP = pSrcTemporalSVC->nMaxQuantizer;
+
+        pHevcEnc->nTemporalLayerCount = pSrcTemporalSVC->nTemporalLayerCount;
+        for (i = 0; i < OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS; i++)
+            pHevcEnc->nTemporalLayerBitrateRatio[i] = pSrcTemporalSVC->nTemporalLayerBitrateRatio[i];
+    }
+        break;
+    case OMX_IndexConfigVideoRoiInfo:
+    {
+        EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *pRoiInfo = (EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *)pComponentConfigStructure;
+
+        if (pRoiInfo->nPortIndex != INPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pHevcEnc->hMFCHevcHandle.bRoiInfo == OMX_FALSE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] RoiInfo is not enabled", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if ((pRoiInfo->bUseRoiInfo == OMX_TRUE) &&
+            ((pRoiInfo->nRoiMBInfoSize <= 0) || (pRoiInfo->pRoiMBInfo == NULL))) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] parameter is invalid : nRoiMBInfoSize(%d)/pRoiMBInfo(%p)",
+                                pExynosComponent, __FUNCTION__, pRoiInfo->nRoiMBInfoSize, pRoiInfo->pRoiMBInfo);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexConfigIFrameRatio:
+    {
+        OMX_PARAM_U32TYPE *pIFrameRatio = (OMX_PARAM_U32TYPE *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pIFrameRatio, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pIFrameRatio->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bIFrameRatioSupport == VIDEO_FALSE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] I-Frame ratio feature is not supported", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorNoneExpiration;
+            goto EXIT;
+        }
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexConfigAndroidVideoTemporalLayering:
+    {
+        OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *pTemporalLayering = (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pTemporalLayering, sizeof(OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pTemporalLayering->nPortIndex != OUTPUT_PORT_INDEX) ||
+            (pHevcEnc->hMFCHevcHandle.bTemporalSVC == OMX_FALSE)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pTemporalLayering->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] can not disable TemporalSVC while encoding", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if (((pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual) > pHevcEnc->nMaxTemporalLayerCount) ||
+            ((pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual) == 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] layer count is invalid(MAX(%d), layer(%d), B-layer(%d))",
+                                    pExynosComponent, __FUNCTION__,
+                                    pHevcEnc->nMaxTemporalLayerCount,
+                                    pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual,
+                                    pTemporalLayering->nBLayerCountActual);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pHevcEnc->nTemporalLayerCount     = pTemporalLayering->nPLayerCountActual + pTemporalLayering->nBLayerCountActual;
+        pHevcEnc->nTemporalLayerCountForB = pTemporalLayering->nBLayerCountActual;
+
+        pHevcEnc->bUseTemporalLayerBitrateRatio = pTemporalLayering->bBitrateRatiosSpecified;
+        if (pHevcEnc->bUseTemporalLayerBitrateRatio == OMX_TRUE) {
+            for (i = 0; i < (int)pHevcEnc->nMaxTemporalLayerCount; i++)
+                pHevcEnc->nTemporalLayerBitrateRatio[i] = (pTemporalLayering->nBitrateRatios[i] >> 16);
+        } else {
+            Exynos_OSAL_Memset(pHevcEnc->nTemporalLayerBitrateRatio, 0, sizeof(pHevcEnc->nTemporalLayerBitrateRatio));
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Max(%d), layer(%d), B-layer(%d)", pExynosComponent, __FUNCTION__,
+                                               pHevcEnc->nMaxTemporalLayerCount, pHevcEnc->nTemporalLayerCount, pHevcEnc->nTemporalLayerCountForB);
+    }
+        break;
+#endif
+    default:
+        ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    if (ret == OMX_ErrorNone) {
+        OMX_PTR pDynamicConfigCMD = NULL;
+        pDynamicConfigCMD = Exynos_OMX_MakeDynamicConfig(nIndex, pComponentConfigStructure);
+        Exynos_OSAL_Queue(&pExynosComponent->dynamicConfigQ, (void *)pDynamicConfigCMD);
+    }
+
+    if (ret == (OMX_ERRORTYPE)OMX_ErrorNoneExpiration)
+        ret = OMX_ErrorNone;
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_GetExtensionIndex(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE *pIndexType)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_TEMPORALSVC) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexConfigVideoTemporalSVC;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_VIDEO_HEVC_ENABLE_TEMPORALSVC) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamVideoHevcEnableTemporalSVC;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_ROIINFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexConfigVideoRoiInfo;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_VIDEO_ENABLE_ROIINFO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamVideoEnableRoiInfo;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_PVC) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamVideoEnablePVC;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_IFRAME_RATIO) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexConfigIFrameRatio;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamPrependSPSPPSToIDR;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+#endif
+
+    ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_ComponentRoleEnum(
+    OMX_HANDLETYPE   hComponent,
+    OMX_U8          *cRole,
+    OMX_U32          nIndex)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) || (cRole == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+        if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+            Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_HEVC_ENC_ROLE);
+        else
+            Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_HEVC_DRM_ENC_ROLE);
+
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorNoMore;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_HEVCEnc_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    OMX_COLOR_FORMATTYPE             eColorFormat       = pInputPort->portDefinition.format.video.eColorFormat;
+
+    ExynosVideoInstInfo *pVideoInstInfo = &(pHevcEnc->hMFCHevcHandle.videoInstInfo);
+
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+
+    FunctionIn();
+
+    pHevcEnc->hMFCHevcHandle.bConfiguredMFCSrc = OMX_FALSE;
+    pHevcEnc->hMFCHevcHandle.bConfiguredMFCDst = OMX_FALSE;
+    pVideoEnc->bFirstInput         = OMX_TRUE;
+    pVideoEnc->bFirstOutput        = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+    if (pInputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+        /* metadata buffer */
+        pInputPort->bufferProcessType = BUFFER_SHARE;
+
+#ifdef USE_ANDROID
+        if ((pInputPort->eMetaDataType == METADATA_TYPE_DATA) &&
+            (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)) {
+            pInputPort->eMetaDataType     = METADATA_TYPE_GRAPHIC;  /* AndoridOpaque means GrallocSource */
+            pInputPort->bufferProcessType = BUFFER_COPY;  /* will determine a process type after getting a hal format at handle */
+        }
+#else
+        if (pInputPort->eMetaDataType == METADATA_TYPE_UBM_BUFFER) {
+            pInputPort->bufferProcessType = BUFFER_COPY;
+        }
+#endif
+    } else {
+        /* data buffer */
+        pInputPort->bufferProcessType = BUFFER_COPY;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                            pInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                            pInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                            pInputPort->portDefinition.format.video.nBitrate,
+                                                                                            pInputPort->portDefinition.format.video.xFramerate);
+    pVideoInstInfo->nSize        = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth       = pInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight      = pInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate     = pInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate   = pInputPort->portDefinition.format.video.xFramerate;
+
+    /* HEVC Codec Open */
+    ret = HEVCCodecOpen(pHevcEnc, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    Exynos_SetPlaneToPort(pOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+
+    Exynos_OSAL_SemaphoreCreate(&pInputPort->codecSemID);
+    Exynos_OSAL_QueueCreate(&pInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pHevcEnc->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pHevcEnc->hSourceStartEvent);
+    pHevcEnc->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pHevcEnc->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pHevcEnc->hDestinationOutStartEvent);
+
+    Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pHevcEnc->hMFCHevcHandle.indexTimestamp = 0;
+    pHevcEnc->hMFCHevcHandle.outputIndexTimestamp = 0;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pHevcEnc->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC) {
+        pVideoEnc->csc_handle = csc_init(CSC_METHOD_HW);
+        csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2);
+        csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_MODE_DRM, 1);
+    } else {
+        pVideoEnc->csc_handle = csc_init(csc_method);
+    }
+    if (pVideoEnc->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVideoEnc->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_HEVCEnc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    FunctionIn();
+
+    if (pVideoEnc->csc_handle != NULL) {
+        csc_deinit(pVideoEnc->csc_handle);
+        pVideoEnc->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pHevcEnc->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pHevcEnc->hDestinationInStartEvent);
+    pHevcEnc->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pHevcEnc->hDestinationOutStartEvent);
+    pHevcEnc->hDestinationOutStartEvent = NULL;
+    pHevcEnc->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pHevcEnc->hSourceStartEvent);
+    pHevcEnc->hSourceStartEvent = NULL;
+    pHevcEnc->bSourceStart = OMX_FALSE;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pOutputPort->codecSemID);
+        pOutputPort->codecSemID = NULL;
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+    } else if (pInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_OSAL_QueueTerminate(&pInputPort->codecBufferQ);
+    Exynos_OSAL_SemaphoreTerminate(pInputPort->codecSemID);
+    pInputPort->codecSemID = NULL;
+
+    HEVCCodecClose(pHevcEnc);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_SrcIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCENC_HANDLE         *pHevcEnc         = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle       = pHevcEnc->hMFCHevcHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort       = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_U32                        oneFrameSize      = pSrcInputData->dataLen;
+    OMX_COLOR_FORMATTYPE           inputColorFormat  = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncOps       *pEncOps     = pHevcEnc->hMFCHevcHandle.pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps   = pHevcEnc->hMFCHevcHandle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]   = {0, 0, 0};
+    int i, nPlaneCnt, nConfigCnt;
+
+    FunctionIn();
+
+    if (pHevcEnc->hMFCHevcHandle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = HEVCCodecSrcSetup(pOMXComponent, pSrcInputData);
+        if ((ret != OMX_ErrorNone) ||
+            ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to HEVCCodecSrcSetup(0x%x)",
+                                                pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+    }
+
+    if (pHevcEnc->hMFCHevcHandle.bConfiguredMFCDst == OMX_FALSE) {
+        ret = HEVCCodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to HEVCCodecDstSetup(0x%x)",
+                                                pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+    }
+
+    nConfigCnt = Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ);
+    if (nConfigCnt > 0) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] has config message(%d)", pExynosComponent, __FUNCTION__, nConfigCnt);
+        while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+            Change_HEVCEnc_Param(pExynosComponent);
+        }
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] all config messages were handled", pExynosComponent, __FUNCTION__);
+    }
+
+    if ((pSrcInputData->dataLen > 0) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+        pExynosComponent->timeStamp[pHevcEnc->hMFCHevcHandle.indexTimestamp]            = pSrcInputData->timeStamp;
+        pExynosComponent->bTimestampSlotUsed[pHevcEnc->hMFCHevcHandle.indexTimestamp]   = OMX_TRUE;
+        pExynosComponent->nFlags[pHevcEnc->hMFCHevcHandle.indexTimestamp]               = pSrcInputData->nFlags;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), Tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pHevcEnc->hMFCHevcHandle.indexTimestamp);
+
+        pEncOps->Set_FrameTag(hMFCHandle, pHevcEnc->hMFCHevcHandle.indexTimestamp);
+        pHevcEnc->hMFCHevcHandle.indexTimestamp++;
+        pHevcEnc->hMFCHevcHandle.indexTimestamp %= MAX_TIMESTAMP;
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        inputColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+        if ((pVideoEnc->eRotationType == ROTATE_0) ||
+            (pVideoEnc->eRotationType == ROTATE_180)) {
+            Exynos_OSAL_GetPlaneSize(inputColorFormat,
+                                     pInputPort->ePlaneType,
+                                     pInputPort->portDefinition.format.video.nFrameWidth,
+                                     pInputPort->portDefinition.format.video.nFrameHeight,
+                                     nDataLen,
+                                     nAllocLen);
+        } else {
+            Exynos_OSAL_GetPlaneSize(inputColorFormat,
+                                     pInputPort->ePlaneType,
+                                     pInputPort->portDefinition.format.video.nFrameHeight,
+                                     pInputPort->portDefinition.format.video.nFrameWidth,
+                                     nDataLen,
+                                     nAllocLen);
+        }
+
+        if (pInputPort->bufferProcessType == BUFFER_COPY) {
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        } else {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        }
+
+        nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+        if (pVideoEnc->nInbufSpareSize > 0) {
+            for (i = 0; i < nPlaneCnt; i++)
+                nAllocLen[i] = nAllocLen[i] + pVideoEnc->nInbufSpareSize;
+        }
+
+        if (pSrcInputData->dataLen == 0) {
+            for (i = 0; i < nPlaneCnt; i++)
+                nDataLen[i] = 0;
+        }
+#ifdef USE_ANDROID
+          else {
+            /* when having valid input */
+            if ((pHevcEnc->hMFCHevcHandle.bWeightedPrediction == OMX_TRUE) &&
+                (pSrcInputData->buffer.addr[2] != NULL)) {
+                ExynosVideoMeta *pVideoMeta = (ExynosVideoMeta *)pSrcInputData->buffer.addr[2];
+
+                if (pVideoMeta->eType & VIDEO_INFO_TYPE_YSUM_DATA) {
+                    codecReturn = pEncOps->Set_YSumData(hMFCHandle, pVideoMeta->data.enc.sYsumData.high,
+                                                        pVideoMeta->data.enc.sYsumData.low);
+                    if (codecReturn != VIDEO_ERROR_NONE)
+                        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Failed to Set_YSumData()", pExynosComponent, __FUNCTION__);
+                }
+            }
+        }
+#endif
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                    (void **)pSrcInputData->buffer.addr,
+                                    (unsigned long *)pSrcInputData->buffer.fd,
+                                    nAllocLen,
+                                    nDataLen,
+                                    nPlaneCnt,
+                                    pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+            goto EXIT;
+        }
+
+        HEVCCodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        if (pHevcEnc->bSourceStart == OMX_FALSE) {
+            pHevcEnc->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pHevcEnc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        if ((pHevcEnc->bDestinationStart == OMX_FALSE) &&
+            (pHevcEnc->hMFCHevcHandle.bConfiguredMFCSrc == OMX_TRUE)) {
+            pHevcEnc->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pHevcEnc->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pHevcEnc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_SrcOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                            *hMFCHandle         = pHevcEnc->hMFCHevcHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pInbufOps      = pHevcEnc->hMFCHevcHandle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->allocSize     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->pPrivate = NULL;
+    } else {
+        int plane = 0, nPlaneCnt;
+        nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+        for (plane = 0; plane < nPlaneCnt; plane++) {
+            pSrcOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+            pSrcOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+            pSrcOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        }
+
+        if (pInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] ==
+                        pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) {
+                    pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_DstIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCENC_HANDLE         *pHevcEnc             = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle           = pHevcEnc->hMFCHevcHandle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pOutbufOps  = pHevcEnc->hMFCHevcHandle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0};
+    unsigned int nDataLen[VIDEO_BUFFER_MAX_PLANES]  = {0, 0, 0};
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    nAllocLen[0] = pOutputPort->portDefinition.nBufferSize;
+    if ((pOutputPort->bufferProcessType & BUFFER_COPY) ||
+        (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        /* OMX buffer is not used directly : CODEC buffer or MetaData */
+        nAllocLen[0] = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth * pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pOutputPort),
+                                pDstInputData->bufferHeader);
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                            pExynosComponent, __FUNCTION__, codecReturn);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+        goto EXIT;
+    }
+
+    HEVCCodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_DstOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCENC_HANDLE         *pHevcEnc         = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort      = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    void                          *hMFCHandle        = pHevcEnc->hMFCHevcHandle.hMFCHandle;
+
+    ExynosVideoEncOps          *pEncOps        = pHevcEnc->hMFCHevcHandle.pEncOps;
+    ExynosVideoEncBufferOps    *pOutbufOps     = pHevcEnc->hMFCHevcHandle.pOutbufOps;
+    ExynosVideoBuffer          *pVideoBuffer   = NULL;
+    ExynosVideoBuffer           videoBuffer;
+    ExynosVideoErrorType        codecReturn    = VIDEO_ERROR_NONE;
+
+    OMX_S32 indexTimestamp = 0;
+
+    FunctionIn();
+
+    if (pHevcEnc->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+    if (codecReturn == VIDEO_ERROR_NONE) {
+        pVideoBuffer = &videoBuffer;
+    } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO)", pExynosComponent, __FUNCTION__);
+        pVideoBuffer = NULL;
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    } else {
+        pVideoBuffer = NULL;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pHevcEnc->hMFCHevcHandle.outputIndexTimestamp++;
+    pHevcEnc->hMFCHevcHandle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+    pDstOutputData->buffer.addr[0]  = pVideoBuffer->planes[0].addr;
+    pDstOutputData->buffer.fd[0]    = pVideoBuffer->planes[0].fd;
+
+    pDstOutputData->allocSize       = pVideoBuffer->planes[0].allocSize;
+    pDstOutputData->dataLen         = pVideoBuffer->planes[0].dataSize;
+    pDstOutputData->remainDataLen   = pVideoBuffer->planes[0].dataSize;
+    pDstOutputData->usedDataLen     = 0;
+
+    pDstOutputData->pPrivate        = pVideoBuffer;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+            goto EXIT;
+        }
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+    if (pVideoEnc->bFirstOutput == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] codec specific data is generated", pExynosComponent, __FUNCTION__);
+        pDstOutputData->timeStamp = 0;
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
+        pVideoEnc->bFirstOutput = OMX_TRUE;
+    } else {
+        indexTimestamp = pEncOps->Get_FrameTag(pHevcEnc->hMFCHevcHandle.hMFCHandle);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Tag(%d) is invalid. changes to use outputIndexTimestamp(%d)",
+                                                pExynosComponent, __FUNCTION__,
+                                                indexTimestamp, pHevcEnc->hMFCHevcHandle.outputIndexTimestamp);
+            indexTimestamp = pHevcEnc->hMFCHevcHandle.outputIndexTimestamp;
+        }
+
+        /* In case of Video buffer batch mode, use timestamp from MFC device driver */
+        if (pVideoBuffer->timestamp != 0)
+            pDstOutputData->timeStamp = pVideoBuffer->timestamp;
+        else
+            pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
+
+        pExynosComponent->bTimestampSlotUsed[indexTimestamp]    = OMX_FALSE;
+        pDstOutputData->nFlags                                  = pExynosComponent->nFlags[indexTimestamp];
+        pDstOutputData->nFlags                                 |= OMX_BUFFERFLAG_ENDOFFRAME;
+    }
+
+    if (pVideoBuffer->frameType == VIDEO_FRAME_I)
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, frameType: %d, dataLen: %d, timestamp %lld us (%.2f secs), Tag: %d",
+                                            pExynosComponent, __FUNCTION__,
+                                            pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                            pVideoBuffer->frameType, pDstOutputData->dataLen,
+                                            pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                            indexTimestamp);
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] got end of stream", pExynosComponent, __FUNCTION__);
+
+        if (pExynosComponent->bBehaviorEOS == OMX_FALSE)
+            pDstOutputData->remainDataLen = 0;
+        else
+            pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_srcInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT      *pInputPort        = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pInputPort)) ||
+        (!CHECK_PORT_POPULATED(pInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_HEVCEnc_SrcIn(pOMXComponent, pSrcInputData);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_srcOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pInputPort)) ||
+        (!CHECK_PORT_POPULATED(pInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    if ((pHevcEnc->bSourceStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pInputPort))) {
+        Exynos_OSAL_SignalWait(pHevcEnc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pHevcEnc->hSourceStartEvent);
+    }
+
+    ret = Exynos_HEVCEnc_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_dstInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pHevcEnc->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+        Exynos_OSAL_SignalWait(pHevcEnc->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pHevcEnc->hDestinationInStartEvent);
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pHevcEnc->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pHevcEnc->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    if (pHevcEnc->hMFCHevcHandle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_HEVCEnc_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_HEVCEnc_dstOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pHevcEnc->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+        Exynos_OSAL_SignalWait(pHevcEnc->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pHevcEnc->hDestinationOutStartEvent);
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pHevcEnc->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pHevcEnc->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_HEVCEnc_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE hComponent,
+    OMX_STRING     componentName)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_HEVCENC_HANDLE         *pHevcEnc         = NULL;
+    OMX_BOOL                       bSecureMode      = OMX_FALSE;
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_HEVC_ENC, componentName) == 0) {
+        bSecureMode = OMX_FALSE;
+    } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_HEVC_DRM_ENC, componentName) == 0) {
+        bSecureMode = OMX_TRUE;
+    } else {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = (bSecureMode == OMX_TRUE)? HW_VIDEO_ENC_SECURE_CODEC:HW_VIDEO_ENC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pHevcEnc = Exynos_OSAL_Malloc(sizeof(EXYNOS_HEVCENC_HANDLE));
+    if (pHevcEnc == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pHevcEnc, 0, sizeof(EXYNOS_HEVCENC_HANDLE));
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pHevcEnc;
+    pHevcEnc->qpRangeI.nMinQP = 0;
+    pHevcEnc->qpRangeI.nMaxQP = 50;
+    pHevcEnc->qpRangeP.nMinQP = 0;
+    pHevcEnc->qpRangeP.nMaxQP = 50;
+    pHevcEnc->qpRangeB.nMinQP = 0;
+    pHevcEnc->qpRangeB.nMaxQP = 50;
+
+    pVideoEnc->quantization.nQpI = 29;
+    pVideoEnc->quantization.nQpP = 30;
+    pVideoEnc->quantization.nQpB = 32;
+
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_HEVC_DRM_ENC);
+    else
+        Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_HEVC_ENC);
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+#ifdef USE_SINGLE_PLANE_IN_DRM
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        pExynosPort->ePlaneType = PLANE_SINGLE;
+#endif
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pHevcEnc->HevcComponent[i], OMX_VIDEO_PARAM_HEVCTYPE);
+        pHevcEnc->HevcComponent[i].nPortIndex = i;
+        pHevcEnc->HevcComponent[i].eProfile   = OMX_VIDEO_HEVCProfileMain;
+        pHevcEnc->HevcComponent[i].eLevel     = OMX_VIDEO_HEVCMainTierLevel4;
+    }
+    pHevcEnc->HevcComponent[OUTPUT_PORT_INDEX].nKeyFrameInterval = 30;
+
+    pHevcEnc->hMFCHevcHandle.bTemporalSVC   = OMX_FALSE;
+    pHevcEnc->nMaxTemporalLayerCount        = 0;
+    pHevcEnc->nTemporalLayerCount           = 0;
+    pHevcEnc->bUseTemporalLayerBitrateRatio = 0;
+    Exynos_OSAL_Memset(pHevcEnc->nTemporalLayerBitrateRatio, 0, sizeof(pHevcEnc->nTemporalLayerBitrateRatio));
+
+    pOMXComponent->GetParameter      = &Exynos_HEVCEnc_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_HEVCEnc_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_HEVCEnc_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_HEVCEnc_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_HEVCEnc_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_HEVCEnc_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_HEVCEnc_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_HEVCEnc_Terminate;
+
+    pVideoEnc->exynos_codec_srcInputProcess  = &Exynos_HEVCEnc_srcInputBufferProcess;
+    pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_HEVCEnc_srcOutputBufferProcess;
+    pVideoEnc->exynos_codec_dstInputProcess  = &Exynos_HEVCEnc_dstInputBufferProcess;
+    pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_HEVCEnc_dstOutputBufferProcess;
+
+    pVideoEnc->exynos_codec_start            = &HEVCCodecStart;
+    pVideoEnc->exynos_codec_stop             = &HEVCCodecStop;
+    pVideoEnc->exynos_codec_bufferProcessRun = &HEVCCodecOutputBufferProcessRun;
+    pVideoEnc->exynos_codec_enqueueAllBuffer = &HEVCCodecEnqueueAllBuffer;
+
+    pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+
+    pVideoEnc->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
+
+    pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoEnc->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pHevcEnc);
+        pHevcEnc = pVideoEnc->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pHevcEnc->hMFCHevcHandle.videoInstInfo.eCodecType = VIDEO_CODING_HEVC;
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        pHevcEnc->hMFCHevcHandle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pHevcEnc->hMFCHevcHandle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pHevcEnc->hMFCHevcHandle.videoInstInfo), VIDEO_FALSE /* enc */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pHevcEnc);
+        pHevcEnc = pVideoEnc->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for enc : ext(%d)/temporal-svc(%d)/roi(%d)/qp-range(%d)/pvc(%d)/I-ratio(%d)/CA(%d)",
+            pExynosComponent, __FUNCTION__,
+            (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.nSpareSize),
+            (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport),
+            (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bRoiInfoSupport),
+            (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bQpRangePBSupport),
+            (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bPVCSupport),
+            (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bIFrameRatioSupport),
+            (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.bColorAspectsSupport));
+
+    if (pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.nSpareSize > 0)
+        pVideoEnc->nInbufSpareSize = pHevcEnc->hMFCHevcHandle.videoInstInfo.supportInfo.enc.nSpareSize;
+
+    Exynos_Input_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_AddVendorExt(hComponent, "sec-ext-enc-qp-range", (OMX_INDEXTYPE)OMX_IndexConfigVideoQPRange);
+#endif
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_HEVCENC_HANDLE           *pHevcEnc           = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent       = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent    = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoEnc           = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pHevcEnc != NULL) {
+        Exynos_OSAL_Free(pHevcEnc);
+        pHevcEnc = pVideoEnc->hCodecHandle = NULL;
+    }
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_DelVendorExts(hComponent);
+#endif
+
+    ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/enc/hevc/Exynos_OMX_HEVCenc.h b/openmax/component/video/enc/hevc/Exynos_OMX_HEVCenc.h
new file mode 100755 (executable)
index 0000000..3a39c15
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *
+ * Copyright 2014 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_HEVCenc.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2014.05.22 : Create
+ */
+
+#ifndef EXYNOS_OMX_HEVC_ENC_COMPONENT
+#define EXYNOS_OMX_HEVC_ENC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+
+#include "ExynosVideoApi.h"
+
+typedef struct _EXYNOS_MFC_HEVCENC_HANDLE
+{
+    OMX_HANDLETYPE hMFCHandle;
+
+    OMX_U32 indexTimestamp;
+    OMX_U32 outputIndexTimestamp;
+
+    OMX_BOOL bConfiguredMFCSrc;
+    OMX_BOOL bConfiguredMFCDst;
+    OMX_BOOL bPrependSpsPpsToIdr;
+    OMX_BOOL bTemporalSVC;
+    OMX_BOOL bRoiInfo;
+    OMX_BOOL bWeightedPrediction;
+
+    ExynosVideoEncOps       *pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps;
+    ExynosVideoEncBufferOps *pOutbufOps;
+    ExynosVideoEncParam      encParam;
+    ExynosVideoInstInfo      videoInstInfo;
+
+    #define MAX_PROFILE_NUM 2
+    OMX_VIDEO_HEVCPROFILETYPE   profiles[MAX_PROFILE_NUM];
+    OMX_S32                     nProfileCnt;
+    OMX_VIDEO_HEVCLEVELTYPE     maxLevel;
+} EXYNOS_MFC_HEVCENC_HANDLE;
+
+typedef struct _EXYNOS_HEVCENC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_HEVCTYPE            HevcComponent[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+    OMX_VIDEO_QPRANGE                   qpRangeI;
+    OMX_VIDEO_QPRANGE                   qpRangeP;
+    OMX_VIDEO_QPRANGE                   qpRangeB;
+
+    /* Temporal SVC */
+    OMX_U32  nMaxTemporalLayerCount;
+    OMX_U32  nMaxTemporalLayerCountForB;
+    OMX_U32  nTemporalLayerCount;
+    OMX_U32  nTemporalLayerCountForB;
+    OMX_BOOL bUseTemporalLayerBitrateRatio;
+    OMX_U32  nTemporalLayerBitrateRatio[OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS];
+
+    /* SEC MFC Codec specific */
+    EXYNOS_MFC_HEVCENC_HANDLE hMFCHevcHandle;
+
+    OMX_BOOL bSourceStart;
+    OMX_BOOL bDestinationStart;
+    OMX_HANDLETYPE hSourceStartEvent;
+    OMX_HANDLETYPE hDestinationInStartEvent;
+    OMX_HANDLETYPE hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE bypassBufferInfoQ;
+} EXYNOS_HEVCENC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName);
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/enc/hevc/Makefile.am b/openmax/component/video/enc/hevc/Makefile.am
new file mode 100755 (executable)
index 0000000..5804788
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libOMX.Exynos.HEVC.Encoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_HEVC_Encoder_la_SOURCES = Exynos_OMX_HEVCenc.c \
+                                        library_register.c
+
+libOMX_Exynos_HEVC_Encoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                       $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                       $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                       $(top_builddir)/openmax/component/video/enc/libExynosOMX_Venc.la \
+                                       $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+libOMX_Exynos_HEVC_Encoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                       -I$(top_srcdir)/openmax/include/exynos \
+                                       -I$(top_srcdir)/openmax/osal \
+                                       -I$(top_srcdir)/openmax/core \
+                                       -I$(top_srcdir)/openmax/component/common \
+                                       -I$(top_srcdir)/openmax/component/video/enc \
+                                       -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_HEVC_Encoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF -DUSE_HEVC_SUPPORT
+libOMX_Exynos_HEVC_Encoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable
+
+libOMX_Exynos_HEVC_Encoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/enc/hevc/library_register.c b/openmax/component/video/enc/hevc/library_register.c
new file mode 100755 (executable)
index 0000000..391044c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2014 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2014.05.22 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+#include "Exynos_OSAL_Log.h"
+
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents)
+{
+    FunctionIn();
+
+    if (exynosComponents == NULL)
+        goto EXIT;
+
+    /* component 1 - video Encoder HEVC */
+    Exynos_OSAL_Strcpy(exynosComponents[0]->componentName, EXYNOS_OMX_COMPONENT_HEVC_ENC);
+    Exynos_OSAL_Strcpy(exynosComponents[0]->roles[0], EXYNOS_OMX_COMPONENT_HEVC_ENC_ROLE);
+    exynosComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+    /* component 2 - video Encoder HEVC for DRM */
+    Exynos_OSAL_Strcpy(exynosComponents[1]->componentName, EXYNOS_OMX_COMPONENT_HEVC_DRM_ENC);
+    Exynos_OSAL_Strcpy(exynosComponents[1]->roles[0], EXYNOS_OMX_COMPONENT_HEVC_DRM_ENC_ROLE);
+    exynosComponents[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
+
diff --git a/openmax/component/video/enc/hevc/library_register.h b/openmax/component/video/enc/hevc/library_register.h
new file mode 100755 (executable)
index 0000000..37b5f4a
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2014 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2014.05.22 : Create
+ */
+
+#ifndef EXYNOS_OMX_HEVC_REG
+#define EXYNOS_OMX_HEVC_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM       2
+#define MAX_COMPONENT_ROLE_NUM  1
+
+/* HEVC */
+#define EXYNOS_OMX_COMPONENT_HEVC_ENC      "OMX.Exynos.HEVC.Encoder"
+#define EXYNOS_OMX_COMPONENT_HEVC_DRM_ENC  "OMX.Exynos.HEVC.Encoder.secure"
+#define EXYNOS_OMX_COMPONENT_HEVC_ENC_ROLE "video_encoder.hevc"
+#define EXYNOS_OMX_COMPONENT_HEVC_DRM_ENC_ROLE "video_encoder.hevc-wfd"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
diff --git a/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c b/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c
new file mode 100755 (executable)
index 0000000..39a112b
--- /dev/null
@@ -0,0 +1,3301 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Mpeg4enc.c
+ * @brief
+ * @author      Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Venc.h"
+#include "Exynos_OMX_VencControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Mpeg4enc.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OSAL_Queue.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
+/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_MPEG4_ENC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc      = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pMpeg4Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) {
+        pMpeg4Enc->hMFCMpeg4Handle.profiles[nProfileCnt++] = (int)OMX_VIDEO_MPEG4ProfileSimple;
+        pMpeg4Enc->hMFCMpeg4Handle.profiles[nProfileCnt++] = (int)OMX_VIDEO_MPEG4ProfileAdvancedSimple;
+        pMpeg4Enc->hMFCMpeg4Handle.nProfileCnt = nProfileCnt;
+        pMpeg4Enc->hMFCMpeg4Handle.maxLevel = (int)OMX_VIDEO_MPEG4Level5;
+    } else {
+        pMpeg4Enc->hMFCMpeg4Handle.profiles[nProfileCnt++] = (int)OMX_VIDEO_H263ProfileBaseline;
+        pMpeg4Enc->hMFCMpeg4Handle.nProfileCnt = nProfileCnt;
+        pMpeg4Enc->hMFCMpeg4Handle.maxLevel = (int)OMX_VIDEO_H263Level70;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc      = NULL;
+
+    int nLevelCnt = 0;
+    OMX_U32 nMaxIndex = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pMpeg4Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pMpeg4Enc->hMFCMpeg4Handle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pMpeg4Enc->hMFCMpeg4Handle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pMpeg4Enc->hMFCMpeg4Handle.maxLevel;
+#else
+    while ((pMpeg4Enc->hMFCMpeg4Handle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+
+    if ((pMpeg4Enc->hMFCMpeg4Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pMpeg4Enc->hMFCMpeg4Handle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pMpeg4Enc->hMFCMpeg4Handle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : supported profile(%x), level(%x)",
+                                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc  = NULL;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc  = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pMpeg4Enc == NULL)
+        goto EXIT;
+
+    while ((pMpeg4Enc->hMFCMpeg4Handle.maxLevel >> nLevelCnt++) > 0);
+
+    if ((pMpeg4Enc->hMFCMpeg4Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pMpeg4Enc->hMFCMpeg4Handle.nProfileCnt; i++) {
+        if (pMpeg4Enc->hMFCMpeg4Handle.profiles[i] == (int)pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    while (nLevelCnt >= 0) {
+        if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+            bLevelSupport = OMX_TRUE;
+            break;
+        }
+
+        nLevelCnt--;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_U32 OMXMpeg4ProfileToMFCProfile(OMX_VIDEO_MPEG4PROFILETYPE profile)
+{
+    OMX_U32 ret;
+
+    switch (profile) {
+    case OMX_VIDEO_MPEG4ProfileSimple:
+        ret = 0;
+        break;
+    case OMX_VIDEO_MPEG4ProfileAdvancedSimple:
+        ret = 1;
+        break;
+    default:
+        ret = 0;
+    };
+
+    return ret;
+}
+
+static OMX_U32 OMXMpeg4LevelToMFCLevel(OMX_VIDEO_MPEG4LEVELTYPE level)
+{
+    OMX_U32 ret;
+
+    switch (level) {
+    case OMX_VIDEO_MPEG4Level0:
+        ret = 0;
+        break;
+    case OMX_VIDEO_MPEG4Level0b:
+        ret = 1;
+        break;
+    case OMX_VIDEO_MPEG4Level1:
+        ret = 2;
+        break;
+    case OMX_VIDEO_MPEG4Level2:
+        ret = 3;
+        break;
+    case OMX_VIDEO_MPEG4Level3:
+        ret = 4;
+        break;
+    case OMX_VIDEO_MPEG4Level4:
+    case OMX_VIDEO_MPEG4Level4a:
+        ret = 6;
+        break;
+    case OMX_VIDEO_MPEG4Level5:
+        ret = 7;
+        break;
+    default:
+        ret = 0;
+    };
+
+    return ret;
+}
+
+static void Print_Mpeg4Enc_Param(ExynosVideoEncParam *pEncParam)
+{
+    ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam;
+    ExynosVideoEncMpeg4Param  *pMpeg4Param  = &pEncParam->codecParam.mpeg4;
+
+    /* common parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceWidth             : %d", pCommonParam->SourceWidth);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceHeight            : %d", pCommonParam->SourceHeight);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "IDRPeriod               : %d", pCommonParam->IDRPeriod);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SliceMode               : %d", pCommonParam->SliceMode);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "RandomIntraMBRefresh    : %d", pCommonParam->RandomIntraMBRefresh);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Bitrate                 : %d", pCommonParam->Bitrate);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp                 : %d", pCommonParam->FrameQp);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp_P               : %d", pCommonParam->FrameQp_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(I) ranege            : %d / %d", pCommonParam->QpRange.QpMin_I, pCommonParam->QpRange.QpMax_I);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(P) ranege            : %d / %d", pCommonParam->QpRange.QpMin_P, pCommonParam->QpRange.QpMax_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(B) ranege            : %d / %d", pCommonParam->QpRange.QpMin_B, pCommonParam->QpRange.QpMax_B);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "PadControlOn            : %d", pCommonParam->PadControlOn);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LumaPadVal              : %d", pCommonParam->LumaPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CbPadVal                : %d", pCommonParam->CbPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CrPadVal                : %d", pCommonParam->CrPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameMap                : %d", pCommonParam->FrameMap);
+
+    /* Mpeg4 specific parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "ProfileIDC              : %d", pMpeg4Param->ProfileIDC);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LevelIDC                : %d", pMpeg4Param->LevelIDC);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp_B               : %d", pMpeg4Param->FrameQp_B);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "TimeIncreamentRes       : %d", pMpeg4Param->TimeIncreamentRes);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "VopTimeIncreament       : %d", pMpeg4Param->VopTimeIncreament);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "SliceArgument           : %d", pMpeg4Param->SliceArgument);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumberBFrames           : %d", pMpeg4Param->NumberBFrames);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "DisableQpelME           : %d", pMpeg4Param->DisableQpelME);
+
+    /* rate control related parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableFRMRateControl    : %d", pCommonParam->EnableFRMRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableMBRateControl     : %d", pCommonParam->EnableMBRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CBRPeriodRf             : %d", pCommonParam->CBRPeriodRf);
+}
+
+static void Print_H263Enc_Param(ExynosVideoEncParam *pEncParam)
+{
+    ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam;
+    ExynosVideoEncH263Param   *pH263Param   = &pEncParam->codecParam.h263;
+
+    /* common parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceWidth             : %d", pCommonParam->SourceWidth);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceHeight            : %d", pCommonParam->SourceHeight);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "IDRPeriod               : %d", pCommonParam->IDRPeriod);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SliceMode               : %d", pCommonParam->SliceMode);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "RandomIntraMBRefresh    : %d", pCommonParam->RandomIntraMBRefresh);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Bitrate                 : %d", pCommonParam->Bitrate);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp                 : %d", pCommonParam->FrameQp);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp_P               : %d", pCommonParam->FrameQp_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(I) ranege            : %d / %d", pCommonParam->QpRange.QpMin_I, pCommonParam->QpRange.QpMax_I);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(P) ranege            : %d / %d", pCommonParam->QpRange.QpMin_P, pCommonParam->QpRange.QpMax_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "PadControlOn            : %d", pCommonParam->PadControlOn);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LumaPadVal              : %d", pCommonParam->LumaPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CbPadVal                : %d", pCommonParam->CbPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CrPadVal                : %d", pCommonParam->CrPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameMap                : %d", pCommonParam->FrameMap);
+
+    /* H263 specific parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameRate               : %d", pH263Param->FrameRate);
+
+    /* rate control related parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableFRMRateControl    : %d", pCommonParam->EnableFRMRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableMBRateControl     : %d", pCommonParam->EnableMBRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CBRPeriodRf             : %d", pCommonParam->CBRPeriodRf);
+}
+
+static void Set_Mpeg4Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_BASEPORT           *pInputPort        = NULL;
+    EXYNOS_OMX_BASEPORT           *pOutputPort       = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = NULL;
+    EXYNOS_MPEG4ENC_HANDLE        *pMpeg4Enc         = NULL;
+    EXYNOS_MFC_MPEG4ENC_HANDLE    *pMFCMpeg4Handle   = NULL;
+    OMX_COLOR_FORMATTYPE           eColorFormat      = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncParam       *pEncParam    = NULL;
+    ExynosVideoEncCommonParam *pCommonParam = NULL;
+    ExynosVideoEncMpeg4Param  *pMpeg4Param  = NULL;
+
+    pVideoEnc           = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pMpeg4Enc           = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCMpeg4Handle     = &pMpeg4Enc->hMFCMpeg4Handle;
+    pInputPort    = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pOutputPort   = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    pEncParam    = &pMFCMpeg4Handle->encParam;
+    pCommonParam = &pEncParam->commonParam;
+    pMpeg4Param  = &pEncParam->codecParam.mpeg4;
+    pEncParam->eCompressionFormat = VIDEO_CODING_MPEG4;
+
+    /* common parameters */
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+    } else {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+    }
+    pCommonParam->IDRPeriod    = pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1;
+    pCommonParam->SliceMode    = 0;
+    pCommonParam->Bitrate      = pOutputPort->portDefinition.format.video.nBitrate;
+    pCommonParam->FrameQp      = pVideoEnc->quantization.nQpI;
+    pCommonParam->FrameQp_P    = pVideoEnc->quantization.nQpP;
+
+    pCommonParam->QpRange.QpMin_I = pMpeg4Enc->qpRangeI.nMinQP;
+    pCommonParam->QpRange.QpMax_I = pMpeg4Enc->qpRangeI.nMaxQP;
+    pCommonParam->QpRange.QpMin_P = pMpeg4Enc->qpRangeP.nMinQP;
+    pCommonParam->QpRange.QpMax_P = pMpeg4Enc->qpRangeP.nMaxQP;
+    pCommonParam->QpRange.QpMin_B = pMpeg4Enc->qpRangeB.nMinQP;
+    pCommonParam->QpRange.QpMax_B = pMpeg4Enc->qpRangeB.nMaxQP;
+
+    pCommonParam->PadControlOn = 0; /* 0: Use boundary pixel, 1: Use the below setting value */
+    pCommonParam->LumaPadVal   = 0;
+    pCommonParam->CbPadVal     = 0;
+    pCommonParam->CrPadVal     = 0;
+
+    if (pVideoEnc->intraRefresh.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) {
+        /* Cyclic Mode */
+        pCommonParam->RandomIntraMBRefresh = pVideoEnc->intraRefresh.nCirMBs;
+    } else {
+        /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+        pCommonParam->RandomIntraMBRefresh = 0;
+    }
+
+    /* Perceptual Mode MPEG4/H263 does not support */
+    pCommonParam->PerceptualMode = VIDEO_FALSE;
+
+    eColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+    pCommonParam->FrameMap = Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    /* Mpeg4 specific parameters */
+    pMpeg4Param->ProfileIDC        = OMXMpeg4ProfileToMFCProfile(pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].eProfile);
+    pMpeg4Param->LevelIDC          = OMXMpeg4LevelToMFCLevel(pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].eLevel);
+    pMpeg4Param->FrameQp_B         = pVideoEnc->quantization.nQpB;
+    pMpeg4Param->TimeIncreamentRes = (pInputPort->portDefinition.format.video.xFramerate) >> 16;
+    pMpeg4Param->VopTimeIncreament = 1;
+    pMpeg4Param->SliceArgument     = 0; /* MB number or byte number */
+    pMpeg4Param->NumberBFrames     = pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nBFrames;  /* 0 ~ 2 */
+    pMpeg4Param->DisableQpelME     = 1;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eControlRate: 0x%x", pExynosComponent, __FUNCTION__, pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]);
+    /* rate control related parameters */
+    switch ((int)pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) {
+    case OMX_Video_ControlRateDisable:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR");
+        pCommonParam->EnableFRMRateControl = 0; /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 0; /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 100;
+        break;
+    case OMX_Video_ControlRateConstant:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR");
+        pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1; /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 9;
+        break;
+    case OMX_Video_ControlRateVariable:
+    default: /*Android default */
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR");
+        pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1; /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 100;
+        break;
+    }
+
+//    Print_Mpeg4Enc_Param(pEncParam);
+}
+
+static void Set_H263Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_BASEPORT           *pInputPort  = NULL;
+    EXYNOS_OMX_BASEPORT           *pOutputPort = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = NULL;
+    EXYNOS_MPEG4ENC_HANDLE        *pMpeg4Enc         = NULL;
+    EXYNOS_MFC_MPEG4ENC_HANDLE    *pMFCMpeg4Handle   = NULL;
+    OMX_COLOR_FORMATTYPE           eColorFormat      = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncParam       *pEncParam    = NULL;
+    ExynosVideoEncCommonParam *pCommonParam = NULL;
+    ExynosVideoEncH263Param   *pH263Param   = NULL;
+
+    pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pMpeg4Enc          = pVideoEnc->hCodecHandle;
+    pMFCMpeg4Handle    = &pMpeg4Enc->hMFCMpeg4Handle;
+    pInputPort   = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    pEncParam    = &pMFCMpeg4Handle->encParam;
+    pCommonParam = &pEncParam->commonParam;
+    pH263Param   = &pEncParam->codecParam.h263;
+    pEncParam->eCompressionFormat = VIDEO_CODING_H263;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "eCompressionFormat: %d", pEncParam->eCompressionFormat);
+
+    /* common parameters */
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+    } else {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+    }
+    pCommonParam->IDRPeriod    = pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1;
+    pCommonParam->SliceMode    = 0;
+    pCommonParam->Bitrate      = pOutputPort->portDefinition.format.video.nBitrate;
+    pCommonParam->FrameQp      = pVideoEnc->quantization.nQpI;
+    pCommonParam->FrameQp_P    = pVideoEnc->quantization.nQpP;
+
+    pCommonParam->QpRange.QpMin_I = pMpeg4Enc->qpRangeI.nMinQP;
+    pCommonParam->QpRange.QpMax_I = pMpeg4Enc->qpRangeI.nMaxQP;
+    pCommonParam->QpRange.QpMin_P = pMpeg4Enc->qpRangeP.nMinQP;
+    pCommonParam->QpRange.QpMax_P = pMpeg4Enc->qpRangeP.nMaxQP;
+
+    pCommonParam->PadControlOn = 0; /* 0: Use boundary pixel, 1: Use the below setting value */
+    pCommonParam->LumaPadVal   = 0;
+    pCommonParam->CbPadVal     = 0;
+    pCommonParam->CrPadVal     = 0;
+
+    if (pVideoEnc->intraRefresh.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) {
+        /* Cyclic Mode */
+        pCommonParam->RandomIntraMBRefresh = pVideoEnc->intraRefresh.nCirMBs;
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh: %d", pCommonParam->RandomIntraMBRefresh);
+    } else {
+        /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+        pCommonParam->RandomIntraMBRefresh = 0;
+    }
+
+    /* Perceptual Mode MPEG4 H263 does not support */
+    pCommonParam->PerceptualMode = VIDEO_FALSE;
+
+    eColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+    pCommonParam->FrameMap = Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    /* H263 specific parameters */
+    pH263Param->FrameRate            = (pInputPort->portDefinition.format.video.xFramerate) >> 16;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eControlRate: 0x%x", pExynosComponent, __FUNCTION__, pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]);
+    /* rate control related parameters */
+    switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) {
+    case OMX_Video_ControlRateDisable:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR");
+        pCommonParam->EnableFRMRateControl = 0; /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 0; /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 100;
+        break;
+    case OMX_Video_ControlRateConstant:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR");
+        pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1; /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 9;
+        break;
+    case OMX_Video_ControlRateVariable:
+    default: /*Android default */
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR");
+        pCommonParam->EnableFRMRateControl = 1; /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1; /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 100;
+        break;
+    }
+
+//    Print_H263Enc_Param(pEncParam);
+}
+
+static void Change_Mpeg4Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = NULL;
+    EXYNOS_MPEG4ENC_HANDLE        *pMpeg4Enc         = NULL;
+    EXYNOS_MFC_MPEG4ENC_HANDLE    *pMFCMpeg4Handle   = NULL;
+    OMX_PTR                        pDynamicConfigCMD = NULL;
+    OMX_PTR                        pConfigData       = NULL;
+    OMX_S32                        nCmdIndex         = 0;
+    ExynosVideoEncOps             *pEncOps           = NULL;
+    int                            nValue            = 0;
+
+    pVideoEnc           = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pMpeg4Enc           = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCMpeg4Handle     = &pMpeg4Enc->hMFCMpeg4Handle;
+    pEncOps             = pMFCMpeg4Handle->pEncOps;
+
+    pDynamicConfigCMD = (OMX_PTR)Exynos_OSAL_Dequeue(&pExynosComponent->dynamicConfigQ);
+    if (pDynamicConfigCMD == NULL)
+        goto EXIT;
+
+    nCmdIndex   = *(OMX_S32 *)pDynamicConfigCMD;
+    pConfigData = (OMX_PTR)((OMX_U8 *)pDynamicConfigCMD + sizeof(OMX_S32));
+
+    switch ((int)nCmdIndex) {
+    case OMX_IndexConfigVideoIntraVOPRefresh:
+    {
+        nValue = VIDEO_FRAME_I;
+        pEncOps->Set_FrameType(pMFCMpeg4Handle->hMFCHandle, nValue);
+        pVideoEnc->IntraRefreshVOP = OMX_FALSE;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] VOP Refresh", pExynosComponent, __FUNCTION__);
+    }
+        break;
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        OMX_S32 nPFrames = (*((OMX_U32 *)pConfigData)) - 1;
+        nValue = nPFrames + 1;
+        pEncOps->Set_IDRPeriod(pMFCMpeg4Handle->hMFCHandle, nValue);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] IDR period: %d", pExynosComponent, __FUNCTION__, nValue);
+    }
+        break;
+    case OMX_IndexConfigVideoBitrate:
+    {
+        OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pConfigData;
+
+        if (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] != OMX_Video_ControlRateDisable) {
+            nValue = pConfigBitrate->nEncodeBitrate;
+            pEncOps->Set_BitRate(pMFCMpeg4Handle->hMFCHandle, nValue);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bitrate: %d", pExynosComponent, __FUNCTION__, nValue);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoFramerate:
+    {
+        OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pConfigData;
+        OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
+
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            nValue = (pConfigFramerate->xEncodeFramerate) >> 16;
+            pEncOps->Set_FrameRate(pMFCMpeg4Handle->hMFCHandle, nValue);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] framerate: %d", pExynosComponent, __FUNCTION__, nValue);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange = (OMX_VIDEO_QPRANGETYPE *)pConfigData;
+        ExynosVideoQPRange     qpRange;
+
+        qpRange.QpMin_I = pQpRange->qpRangeI.nMinQP;
+        qpRange.QpMax_I = pQpRange->qpRangeI.nMaxQP;
+        qpRange.QpMin_P = pQpRange->qpRangeP.nMinQP;
+        qpRange.QpMax_P = pQpRange->qpRangeP.nMaxQP;
+        qpRange.QpMin_B = pQpRange->qpRangeB.nMinQP;
+        qpRange.QpMax_B = pQpRange->qpRangeB.nMaxQP;
+
+        pEncOps->Set_QpRange(pMFCMpeg4Handle->hMFCHandle, qpRange);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qp range: I(%d, %d), P(%d, %d), B(%d, %d)",
+                                    pExynosComponent, __FUNCTION__,
+                                    qpRange.QpMin_I, qpRange.QpMax_I,
+                                    qpRange.QpMin_P, qpRange.QpMax_P,
+                                    qpRange.QpMin_B, qpRange.QpMax_B);
+    }
+        break;
+    case OMX_IndexConfigOperatingRate:
+    {
+        OMX_PARAM_U32TYPE *pConfigRate = (OMX_PARAM_U32TYPE *)pConfigData;
+        OMX_U32            xFramerate  = pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.xFramerate;
+
+        if (xFramerate == 0)
+            nValue = 100;
+        else
+            nValue = (OMX_U32)((pConfigRate->nU32 / (double)xFramerate) * 100);
+
+        pEncOps->Set_QosRatio(pMFCMpeg4Handle->hMFCHandle, nValue);
+        pVideoEnc->bQosChanged = OMX_FALSE;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qos ratio: %d", pExynosComponent, __FUNCTION__, nValue);
+    }
+        break;
+    default:
+        break;
+    }
+
+    Exynos_OSAL_Free(pDynamicConfigCMD);
+
+    if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
+        Set_Mpeg4Enc_Param(pExynosComponent);
+    else
+        Set_H263Enc_Param(pExynosComponent);
+
+EXIT:
+    return;
+}
+
+OMX_ERRORTYPE GetCodecOutputPrivateData(
+    OMX_PTR  pCodecBuffer,
+    OMX_PTR *pVirtAddr,
+    OMX_U32 *pDataSize)
+{
+    OMX_ERRORTYPE      ret          = OMX_ErrorNone;
+    ExynosVideoBuffer *pVideoBuffer = NULL;
+
+    if (pCodecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoBuffer = (ExynosVideoBuffer *)pCodecBuffer;
+
+    if (pVirtAddr != NULL)
+        *pVirtAddr = pVideoBuffer->planes[0].addr;
+
+    if (pDataSize != NULL)
+        *pDataSize = pVideoBuffer->planes[0].allocSize;
+
+EXIT:
+    return ret;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc      = NULL;
+    EXYNOS_OMX_BASEPORT             *pInputPort     = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pMpeg4Enc == NULL)
+        goto EXIT;
+    pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecOpen(
+    EXYNOS_MPEG4ENC_HANDLE  *pMpeg4Enc,
+    ExynosVideoInstInfo     *pVideoInstInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pMpeg4Enc == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pEncOps     = (ExynosVideoEncOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncOps));
+    pInbufOps   = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+    pOutbufOps  = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+
+    if ((pEncOps == NULL) ||
+        (pInbufOps == NULL) ||
+        (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pMpeg4Enc->hMFCMpeg4Handle.pEncOps    = pEncOps;
+    pMpeg4Enc->hMFCMpeg4Handle.pInbufOps  = pInbufOps;
+    pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pEncOps->nSize      = sizeof(ExynosVideoEncOps);
+    pInbufOps->nSize    = sizeof(ExynosVideoEncBufferOps);
+    pOutbufOps->nSize   = sizeof(ExynosVideoEncBufferOps);
+
+    if (Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for encoder ops */
+    if ((pEncOps->Init == NULL) ||
+        (pEncOps->Finalize == NULL) ||
+        (pEncOps->Set_FrameTag == NULL) ||
+        (pEncOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.pEncOps->Init(pVideoInstInfo);
+    if (pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pEncOps != NULL) {
+            Exynos_OSAL_Free(pEncOps);
+            pMpeg4Enc->hMFCMpeg4Handle.pEncOps = NULL;
+        }
+
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pMpeg4Enc->hMFCMpeg4Handle.pInbufOps = NULL;
+        }
+
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecClose(EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pMpeg4Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
+    pEncOps    = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+    pInbufOps  = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+    pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pEncOps->Finalize(hMFCHandle);
+        hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = NULL;
+        pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE;
+        pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Encoder(pEncOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps = NULL;
+    }
+
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps = NULL;
+    }
+
+    if (pEncOps != NULL) {
+        Exynos_OSAL_Free(pEncOps);
+        pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecStart(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pMpeg4Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
+    pInbufOps  = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+    pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+
+    if (nPortIndex == INPUT_PORT_INDEX)
+        pInbufOps->Run(hMFCHandle);
+    else if (nPortIndex == OUTPUT_PORT_INDEX)
+        pOutbufOps->Run(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecStop(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pMpeg4Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
+    pInbufOps  = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+    pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
+        pInbufOps->Stop(hMFCHandle);
+    else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
+        pOutbufOps->Stop(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecOutputBufferProcessRun(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pMpeg4Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pMpeg4Enc->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pMpeg4Enc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pMpeg4Enc->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecEnqueueAllBuffer(
+    OMX_COMPONENTTYPE *pOMXComponent,
+    OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4ENC_HANDLE        *pMpeg4Enc        = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle       = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
+
+    ExynosVideoEncBufferOps *pInbufOps  = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+    ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+
+    int i;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) &&
+        (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pMpeg4Enc->bSourceStart == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)  {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoEnc->pMFCEncInputBuffer[i]->fd[0], pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pMpeg4Enc->bDestinationStart == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoEnc->pMFCEncOutputBuffer[i]->fd[0], pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoEnc->pMFCEncOutputBuffer[i]);
+        }
+
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecSrcSetup(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_MPEG4ENC_HANDLE      *pMFCMpeg4Handle    = &pMpeg4Enc->hMFCMpeg4Handle;
+    void                            *hMFCHandle         = pMFCMpeg4Handle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                          oneFrameSize       = pSrcInputData->dataLen;
+
+    ExynosVideoEncOps       *pEncOps    = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps  = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+    ExynosVideoEncParam     *pEncParam    = NULL;
+
+    ExynosVideoGeometry      bufferConf;
+    OMX_U32                  inputBufferNumber = 0;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pMpeg4Enc->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
+        Set_Mpeg4Enc_Param(pExynosComponent);
+    else
+        Set_H263Enc_Param(pExynosComponent);
+
+    pEncParam = &pMFCMpeg4Handle->encParam;
+    if (pEncOps->Set_EncParam) {
+        if(pEncOps->Set_EncParam(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set encParam", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+    Print_Mpeg4Enc_Param(pEncParam);
+
+    /* input buffer info: only 3 config values needed */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        bufferConf.nFrameWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        bufferConf.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+        bufferConf.nStride      = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth, 16);
+    } else {
+        bufferConf.nFrameWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        bufferConf.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+        bufferConf.nStride      = ALIGN(pOutputPort->portDefinition.format.video.nFrameHeight, 16);
+    }
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+    pInbufOps->Set_Shareable(hMFCHandle);
+    inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare input buffer */
+        if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry) {
+        if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if ((pInputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pInputPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
+        /* data buffer */
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    }
+
+    pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_TRUE;
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret      = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4ENC_HANDLE        *pMpeg4Enc            = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_MPEG4ENC_HANDLE    *pMFCMpeg4Handle      = &pMpeg4Enc->hMFCMpeg4Handle;
+    void                          *hMFCHandle           = pMFCMpeg4Handle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0};
+    unsigned int nDataLen[VIDEO_BUFFER_MAX_PLANES]  = {0, 0, 0};
+    int i, nOutBufSize = 0, nOutputBufferCnt = 0;
+
+    FunctionIn();
+
+    nOutBufSize = pOutputPort->portDefinition.nBufferSize;
+    if ((pOutputPort->bufferProcessType & BUFFER_COPY) ||
+        (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        /* OMX buffer is not used directly : CODEC buffer or MetaData */
+        nOutBufSize = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth *
+                            pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+    }
+
+    /* set geometry for output (dst) */
+    if (pOutbufOps->Set_Geometry) {
+        /* only 2 config values needed */
+        if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
+            bufferConf.eCompressionFormat = VIDEO_CODING_MPEG4;
+        else
+            bufferConf.eCompressionFormat = VIDEO_CODING_H263;
+        bufferConf.nSizeImage             = nOutBufSize;
+        bufferConf.nPlaneCnt              = Exynos_GetPlaneFromPort(pOutputPort);
+
+        if (pOutbufOps->Set_Geometry(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* should be done before prepare output buffer */
+    if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY)
+        nOutputBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
+    else
+        nOutputBufferCnt = pOutputPort->portDefinition.nBufferCountActual;
+
+    if (pOutbufOps->Setup(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, nOutputBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        nAllocLen[0] = nOutBufSize;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Allocate_CodecBuffers for output", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        /* Enqueue output buffer */
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
+                                (unsigned long *)pVideoEnc->pMFCEncOutputBuffer[i]->fd,
+                                pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pOutputPort),
+                                NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* Register output buffer */
+        /*************/
+        /*    TBD    */
+        /*************/
+    }
+
+    pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE;
+
+    if (Mpeg4CodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_GetParameter(
+    OMX_IN    OMX_HANDLETYPE hComponent,
+    OMX_IN    OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc        = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nParamIndex %x", pExynosComponent, __FUNCTION__, (int)nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoMpeg4:
+    {
+        OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Component = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Component = NULL;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstMpeg4Component, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstMpeg4Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcMpeg4Component = &pMpeg4Enc->mpeg4Component[pDstMpeg4Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstMpeg4Component) + nOffset,
+                           ((char *)pSrcMpeg4Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_MPEG4TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamVideoH263:
+    {
+        OMX_VIDEO_PARAM_H263TYPE *pDstH263Component = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_H263TYPE *pSrcH263Component = NULL;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstH263Component, sizeof(OMX_VIDEO_PARAM_H263TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstH263Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcH263Component = &pMpeg4Enc->h263Component[pDstH263Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstH263Component) + nOffset,
+                           ((char *)pSrcH263Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_H263TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_S32                      codecType      = pMpeg4Enc->hMFCMpeg4Handle.codecType;
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (codecType == CODEC_TYPE_MPEG4)
+            Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_ENC_ROLE);
+        else
+            Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_ENC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel   = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_MPEG4TYPE        *pSrcMpeg4Component = NULL;
+        OMX_VIDEO_PARAM_H263TYPE         *pSrcH263Component  = NULL;
+        OMX_S32                           codecType          = pMpeg4Enc->hMFCMpeg4Handle.codecType;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (codecType == CODEC_TYPE_MPEG4) {
+            pSrcMpeg4Component = &pMpeg4Enc->mpeg4Component[pDstProfileLevel->nPortIndex];
+            pDstProfileLevel->eProfile = pSrcMpeg4Component->eProfile;
+            pDstProfileLevel->eLevel = pSrcMpeg4Component->eLevel;
+        } else {
+            pSrcH263Component = &pMpeg4Enc->h263Component[pDstProfileLevel->nPortIndex];
+            pDstProfileLevel->eProfile = pSrcH263Component->eProfile;
+            pDstProfileLevel->eLevel = pSrcH263Component->eLevel;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pMpeg4Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
+
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+        OMX_S32                codecType  = pMpeg4Enc->hMFCMpeg4Handle.codecType;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pMpeg4Enc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pMpeg4Enc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pMpeg4Enc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pMpeg4Enc->qpRangeP.nMaxQP;
+
+        if (codecType == CODEC_TYPE_MPEG4) {
+            pQpRange->qpRangeB.nMinQP = pMpeg4Enc->qpRangeB.nMinQP;
+            pQpRange->qpRangeB.nMaxQP = pMpeg4Enc->qpRangeB.nMaxQP;
+        }
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc        = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoMpeg4:
+    {
+        OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Component = NULL;
+        OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Component = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcMpeg4Component, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcMpeg4Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstMpeg4Component = &pMpeg4Enc->mpeg4Component[pSrcMpeg4Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstMpeg4Component) + nOffset,
+                           ((char *)pSrcMpeg4Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_MPEG4TYPE) - nOffset);
+
+        if (pDstMpeg4Component->nBFrames > 2) {  /* 0 ~ 2 */
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] nBFrames(%d) is over a maximum value(2). it is limited to max",
+                                                pExynosComponent, __FUNCTION__, pDstMpeg4Component->nBFrames);
+            pDstMpeg4Component->nBFrames = 2;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoH263:
+    {
+        OMX_VIDEO_PARAM_H263TYPE *pDstH263Component = NULL;
+        OMX_VIDEO_PARAM_H263TYPE *pSrcH263Component = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcH263Component, sizeof(OMX_VIDEO_PARAM_H263TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcH263Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstH263Component = &pMpeg4Enc->h263Component[pSrcH263Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstH263Component) + nOffset,
+                           ((char *)pSrcH263Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_H263TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_ENC_ROLE)) {
+            pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
+            //((EXYNOS_MPEG4ENC_HANDLE *)(((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_MPEG4;
+        } else if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_ENC_ROLE)) {
+            pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
+            //((EXYNOS_MPEG4ENC_HANDLE *)(((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_H263;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel   = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_MPEG4TYPE        *pDstMpeg4Component = NULL;
+        OMX_VIDEO_PARAM_H263TYPE         *pDstH263Component  = NULL;
+        OMX_S32                           codecType          = pMpeg4Enc->hMFCMpeg4Handle.codecType;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if (codecType == CODEC_TYPE_MPEG4) {
+            /*
+             * To do: Check validity of profile & level parameters
+             */
+
+            pDstMpeg4Component = &pMpeg4Enc->mpeg4Component[pSrcProfileLevel->nPortIndex];
+            pDstMpeg4Component->eProfile = pSrcProfileLevel->eProfile;
+            pDstMpeg4Component->eLevel = pSrcProfileLevel->eLevel;
+        } else {
+            /*
+             * To do: Check validity of profile & level parameters
+             */
+
+            pDstH263Component = &pMpeg4Enc->h263Component[pSrcProfileLevel->nPortIndex];
+            pDstH263Component->eProfile = pSrcProfileLevel->eProfile;
+            pDstH263Component->eLevel = pSrcProfileLevel->eLevel;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pMpeg4Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
+        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+        OMX_S32                codecType  = pMpeg4Enc->hMFCMpeg4Handle.codecType;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP) ||
+            ((codecType == CODEC_TYPE_MPEG4) &&
+             (pQpRange->qpRangeB.nMinQP > pQpRange->qpRangeB.nMaxQP))) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d], B[min:%d, max:%d])", __FUNCTION__,
+                            pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                            pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP,
+                            pQpRange->qpRangeB.nMinQP, pQpRange->qpRangeB.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pMpeg4Enc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pMpeg4Enc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pMpeg4Enc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pMpeg4Enc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+
+        if (codecType == CODEC_TYPE_MPEG4) {
+            pMpeg4Enc->qpRangeB.nMinQP = pQpRange->qpRangeB.nMinQP;
+            pMpeg4Enc->qpRangeB.nMaxQP = pQpRange->qpRangeB.nMaxQP;
+        }
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_GetConfig(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc        = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+        OMX_S32                codecType  = pMpeg4Enc->hMFCMpeg4Handle.codecType;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pMpeg4Enc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pMpeg4Enc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pMpeg4Enc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pMpeg4Enc->qpRangeP.nMaxQP;
+
+        if (codecType == CODEC_TYPE_MPEG4) {
+            pQpRange->qpRangeB.nMinQP = pMpeg4Enc->qpRangeB.nMinQP;
+            pQpRange->qpRangeB.nMaxQP = pMpeg4Enc->qpRangeB.nMaxQP;
+        }
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_SetConfig(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_MPEG4ENC_HANDLE        *pMpeg4Enc        = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+        OMX_S32                codecType  = pMpeg4Enc->hMFCMpeg4Handle.codecType;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP) ||
+            ((codecType == CODEC_TYPE_MPEG4) &&
+             (pQpRange->qpRangeB.nMinQP > pQpRange->qpRangeB.nMaxQP))) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d], B[min:%d, max:%d])",
+                            pExynosComponent, __FUNCTION__,
+                            pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                            pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP,
+                            pQpRange->qpRangeB.nMinQP, pQpRange->qpRangeB.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_FALSE)
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] only I-frame's QP range is applied", pExynosComponent, __FUNCTION__);
+
+        pMpeg4Enc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pMpeg4Enc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pMpeg4Enc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pMpeg4Enc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+
+        if (codecType == CODEC_TYPE_MPEG4) {
+            pMpeg4Enc->qpRangeB.nMinQP = pQpRange->qpRangeB.nMinQP;
+            pMpeg4Enc->qpRangeB.nMaxQP = pQpRange->qpRangeB.nMaxQP;
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1;
+
+        if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
+            pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames = nPFrames;
+        else
+            pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames = nPFrames;
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    if (ret == OMX_ErrorNone) {
+        OMX_PTR pDynamicConfigCMD = NULL;
+        pDynamicConfigCMD = Exynos_OMX_MakeDynamicConfig(nIndex, pComponentConfigStructure);
+        Exynos_OSAL_Queue(&pExynosComponent->dynamicConfigQ, (void *)pDynamicConfigCMD);
+    }
+
+    if (ret == (OMX_ERRORTYPE)OMX_ErrorNoneExpiration)
+        ret = OMX_ErrorNone;
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_GetExtensionIndex(
+    OMX_IN  OMX_HANDLETYPE  hComponent,
+    OMX_IN  OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE  *pIndexType)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_ComponentRoleEnum(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_OUT OMX_U8        *cRole,
+    OMX_IN  OMX_U32        nIndex)
+{
+    OMX_ERRORTYPE               ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE          *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent = NULL;
+    OMX_S32                     codecType;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cRole == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) { /* supports only one role */
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid ) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    codecType = ((EXYNOS_MPEG4ENC_HANDLE *)(((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType;
+    if (codecType == CODEC_TYPE_MPEG4)
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MPEG4_ENC_ROLE);
+    else
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H263_ENC_ROLE);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;;
+    OMX_COLOR_FORMATTYPE             eColorFormat       = pInputPort->portDefinition.format.video.eColorFormat;
+
+    ExynosVideoInstInfo     *pVideoInstInfo = &(pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo);
+
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+
+    FunctionIn();
+
+    pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE;
+    pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE;
+    pVideoEnc->bFirstInput         = OMX_TRUE;
+    pVideoEnc->bFirstOutput        = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+    if (pInputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+        /* metadata buffer */
+        pInputPort->bufferProcessType = BUFFER_SHARE;
+
+#ifdef USE_ANDROID
+        if ((pInputPort->eMetaDataType == METADATA_TYPE_DATA) &&
+            (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)) {
+            pInputPort->eMetaDataType     = METADATA_TYPE_GRAPHIC;  /* AndoridOpaque means GrallocSource */
+            pInputPort->bufferProcessType = BUFFER_COPY;  /* will determine a process type after getting a hal format at handle */
+        }
+#else
+        if (pInputPort->eMetaDataType == METADATA_TYPE_UBM_BUFFER) {
+            pInputPort->bufferProcessType = BUFFER_COPY;
+        }
+#endif
+    } else {
+        /* data buffer */
+        pInputPort->bufferProcessType = BUFFER_COPY;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W: %d H:%d  Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__, pInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                              pInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                              pInputPort->portDefinition.format.video.nBitrate,
+                                                                                              pInputPort->portDefinition.format.video.xFramerate);
+    pVideoInstInfo->nSize       = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth      = pInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight     = pInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate    = pInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate  = pInputPort->portDefinition.format.video.xFramerate;
+
+    /* Mpeg4/H.263 Codec Open */
+    ret = Mpeg4CodecOpen(pMpeg4Enc, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    Exynos_SetPlaneToPort(pOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+
+    Exynos_OSAL_SemaphoreCreate(&pInputPort->codecSemID);
+    Exynos_OSAL_QueueCreate(&pInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pMpeg4Enc->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pMpeg4Enc->hSourceStartEvent);
+    pMpeg4Enc->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pMpeg4Enc->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pMpeg4Enc->hDestinationOutStartEvent);
+
+    Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp = 0;
+    pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp = 0;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pMpeg4Enc->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+    pVideoEnc->csc_handle = csc_init(csc_method);
+    if (pVideoEnc->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVideoEnc->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_Mpeg4Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if (pVideoEnc->csc_handle != NULL) {
+        csc_deinit(pVideoEnc->csc_handle);
+        pVideoEnc->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pMpeg4Enc->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pMpeg4Enc->hDestinationInStartEvent);
+    pMpeg4Enc->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pMpeg4Enc->hDestinationOutStartEvent);
+    pMpeg4Enc->hDestinationOutStartEvent = NULL;
+    pMpeg4Enc->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pMpeg4Enc->hSourceStartEvent);
+    pMpeg4Enc->hSourceStartEvent = NULL;
+    pMpeg4Enc->bSourceStart = OMX_FALSE;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pOutputPort->codecSemID);
+        pOutputPort->codecSemID = NULL;
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+    } else if (pInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_OSAL_QueueTerminate(&pInputPort->codecBufferQ);
+    Exynos_OSAL_SemaphoreTerminate(pInputPort->codecSemID);
+    pInputPort->codecSemID = NULL;
+
+    Mpeg4CodecClose(pMpeg4Enc);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_MPEG4Enc_SrcIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_U32                          oneFrameSize       = pSrcInputData->dataLen;
+    OMX_COLOR_FORMATTYPE             inputColorFormat   = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncOps       *pEncOps     = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps   = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]   = {0, 0, 0};
+    int i, nPlaneCnt, nConfigCnt;
+
+    FunctionIn();
+
+    if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = Mpeg4CodecSrcSetup(pOMXComponent, pSrcInputData);
+        if ((ret != OMX_ErrorNone) ||
+            ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to HEVCCodecSrcSetup(0x%x)",
+                                                pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+    }
+
+    if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE) {
+        ret = Mpeg4CodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to HEVCCodecDstSetup(0x%x)",
+                                                pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+    }
+
+    nConfigCnt = Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ);
+    if (nConfigCnt > 0) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] has config message(%d)", pExynosComponent, __FUNCTION__, nConfigCnt);
+        while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+            Change_Mpeg4Enc_Param(pExynosComponent);
+        }
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] all config messages were handled", pExynosComponent, __FUNCTION__);
+    }
+
+    if ((pSrcInputData->dataLen > 0) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+        pExynosComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp]            = pSrcInputData->timeStamp;
+        pExynosComponent->bTimestampSlotUsed[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp]   = OMX_TRUE;
+        pExynosComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp]               = pSrcInputData->nFlags;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), Tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp);
+        pEncOps->Set_FrameTag(hMFCHandle, pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp);
+        pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++;
+        pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP;
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        inputColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+        if ((pVideoEnc->eRotationType == ROTATE_0) ||
+            (pVideoEnc->eRotationType == ROTATE_180)) {
+            Exynos_OSAL_GetPlaneSize(inputColorFormat,
+                                     pInputPort->ePlaneType,
+                                     pInputPort->portDefinition.format.video.nFrameWidth,
+                                     pInputPort->portDefinition.format.video.nFrameHeight,
+                                     nDataLen,
+                                     nAllocLen);
+        } else {
+            Exynos_OSAL_GetPlaneSize(inputColorFormat,
+                                     pInputPort->ePlaneType,
+                                     pInputPort->portDefinition.format.video.nFrameHeight,
+                                     pInputPort->portDefinition.format.video.nFrameWidth,
+                                     nDataLen,
+                                     nAllocLen);
+        }
+
+        if (pInputPort->bufferProcessType == BUFFER_COPY) {
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        } else {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        }
+
+        nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+        if (pVideoEnc->nInbufSpareSize> 0) {
+            for (i = 0; i < nPlaneCnt; i++)
+                nAllocLen[i] = nAllocLen[i] + pVideoEnc->nInbufSpareSize;
+        }
+
+        if (pSrcInputData->dataLen == 0) {
+            for (i = 0; i < nPlaneCnt; i++)
+                nDataLen[i] = 0;
+        }
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                    (void **)pSrcInputData->buffer.addr,
+                                    (unsigned long *)pSrcInputData->buffer.fd,
+                                    nAllocLen,
+                                    nDataLen,
+                                    nPlaneCnt,
+                                    pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+            goto EXIT;
+        }
+
+        Mpeg4CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        if (pMpeg4Enc->bSourceStart == OMX_FALSE) {
+            pMpeg4Enc->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pMpeg4Enc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        if ((pMpeg4Enc->bDestinationStart == OMX_FALSE) &&
+            (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE)) {
+            pMpeg4Enc->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_SrcOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pInbufOps      = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->allocSize     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->pPrivate = NULL;
+    } else {
+        int plane = 0, nPlaneCnt;
+        nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+        for (plane = 0; plane < nPlaneCnt; plane++) {
+            pSrcOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+            pSrcOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+            pSrcOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        }
+
+        if (pInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] ==
+                        pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) {
+                    pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_DstIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                            *hMFCHandle         = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pOutbufOps     = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn    = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0};
+    unsigned int nDataLen[VIDEO_BUFFER_MAX_PLANES]  = {0, 0, 0};
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    nAllocLen[0] = pOutputPort->portDefinition.nBufferSize;
+    if ((pOutputPort->bufferProcessType & BUFFER_COPY) ||
+        (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        /* OMX buffer is not used directly : CODEC buffer or MetaData */
+        nAllocLen[0] = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth * pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pOutputPort),
+                                pDstInputData->bufferHeader);
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                            pExynosComponent, __FUNCTION__, codecReturn);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+        goto EXIT;
+    }
+
+    Mpeg4CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_DstOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4ENC_HANDLE        *pMpeg4Enc         = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort       = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    void                          *hMFCHandle        = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
+
+    ExynosVideoEncOps           *pEncOps        = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+    ExynosVideoEncBufferOps     *pOutbufOps     = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+    ExynosVideoBuffer           *pVideoBuffer   = NULL;
+    ExynosVideoBuffer            videoBuffer;
+    ExynosVideoErrorType         codecReturn    = VIDEO_ERROR_NONE;
+
+    OMX_S32 indexTimestamp = 0;
+    int i;
+
+    FunctionIn();
+
+    if (pMpeg4Enc->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+    if (codecReturn == VIDEO_ERROR_NONE) {
+        pVideoBuffer = &videoBuffer;
+    } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO)", pExynosComponent, __FUNCTION__);
+        pVideoBuffer = NULL;
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    } else {
+        pVideoBuffer = NULL;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp++;
+    pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+    pDstOutputData->buffer.addr[0]  = pVideoBuffer->planes[0].addr;
+    pDstOutputData->buffer.fd[0]    = pVideoBuffer->planes[0].fd;
+
+    pDstOutputData->allocSize       = pVideoBuffer->planes[0].allocSize;
+    pDstOutputData->dataLen         = pVideoBuffer->planes[0].dataSize;
+    pDstOutputData->remainDataLen   = pVideoBuffer->planes[0].dataSize;
+    pDstOutputData->usedDataLen     = 0;
+
+    pDstOutputData->pPrivate        = pVideoBuffer;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+            goto EXIT;
+        }
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+    if (pVideoEnc->bFirstOutput == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] codec specific data is generated", pExynosComponent, __FUNCTION__);
+        pDstOutputData->timeStamp = 0;
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
+        pVideoEnc->bFirstOutput = OMX_TRUE;
+    } else {
+        indexTimestamp = pEncOps->Get_FrameTag(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Tag(%d) is invalid. changes to use outputIndexTimestamp(%d)",
+                                                  pExynosComponent, __FUNCTION__,
+                                                  indexTimestamp, pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp);
+            indexTimestamp = pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp;
+        }
+
+        /* mpeg4 codec supports b-frame encoding */
+        if ((pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) &&
+            (pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nBFrames > 0)) {
+            if ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) &&
+                (pVideoBuffer->frameType == VIDEO_FRAME_P)) {
+                /* move an EOS flag to previous slot
+                 * B1 B2 P(EOS) -> P B1 B2(EOS)
+                 * B1 P(EOS) -> P B1(EOS)
+                 */
+                int index = ((indexTimestamp - 1) < 0)? (MAX_TIMESTAMP - 1):(indexTimestamp - 1);
+
+                if (pExynosComponent->bTimestampSlotUsed[index] == OMX_TRUE) {
+                    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] EOS flag is moved to %d from %d",
+                                                            pExynosComponent, __FUNCTION__,
+                                                            index, indexTimestamp);
+                    pExynosComponent->nFlags[indexTimestamp] &= (~OMX_BUFFERFLAG_EOS);
+                    pExynosComponent->nFlags[index] |= OMX_BUFFERFLAG_EOS;
+                }
+            }
+        }
+
+        /* In case of Video buffer batch mode, use timestamp from MFC device driver */
+        if (pVideoBuffer->timestamp != 0)
+            pDstOutputData->timeStamp = pVideoBuffer->timestamp;
+        else
+            pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
+
+        pExynosComponent->bTimestampSlotUsed[indexTimestamp]    = OMX_FALSE;
+        pDstOutputData->nFlags                                  = pExynosComponent->nFlags[indexTimestamp];
+        pDstOutputData->nFlags                                 |= OMX_BUFFERFLAG_ENDOFFRAME;
+    }
+
+    if (pVideoBuffer->frameType == VIDEO_FRAME_I)
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, frameType: %d, dataLen: %d, timestamp %lld us (%.2f secs), Tag: %d",
+                                            pExynosComponent, __FUNCTION__,
+                                            pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                            pVideoBuffer->frameType, pDstOutputData->dataLen,
+                                            pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                            indexTimestamp);
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] got end of stream", pExynosComponent, __FUNCTION__);
+
+        if (pExynosComponent->bBehaviorEOS == OMX_FALSE)
+            pDstOutputData->remainDataLen = 0;
+        else
+            pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_srcInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT      *pInputPort        = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pInputPort)) ||
+        (!CHECK_PORT_POPULATED(pInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_MPEG4Enc_SrcIn(pOMXComponent, pSrcInputData);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_srcOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pInputPort)) ||
+        (!CHECK_PORT_POPULATED(pInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    if ((pMpeg4Enc->bSourceStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pInputPort))) {
+        Exynos_OSAL_SignalWait(pMpeg4Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pMpeg4Enc->hSourceStartEvent);
+    }
+
+    ret = Exynos_Mpeg4Enc_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_dstInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pMpeg4Enc->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+        Exynos_OSAL_SignalWait(pMpeg4Enc->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pMpeg4Enc->hDestinationInStartEvent);
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pMpeg4Enc->bypassBufferInfoQ) > 0) {
+
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pMpeg4Enc->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_Mpeg4Enc_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_Mpeg4Enc_dstOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pMpeg4Enc->bDestinationStart == OMX_FALSE) &&
+       (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+        Exynos_OSAL_SignalWait(pMpeg4Enc->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pMpeg4Enc->hDestinationOutStartEvent);
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pMpeg4Enc->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pMpeg4Enc->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_Mpeg4Enc_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE hComponent,
+    OMX_STRING     componentName)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_MPEG4ENC_HANDLE        *pMpeg4Enc        = NULL;
+    OMX_S32                        codecType        = -1;
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG4_ENC, componentName) == 0) {
+        codecType = CODEC_TYPE_MPEG4;
+    } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H263_ENC, componentName) == 0) {
+        codecType = CODEC_TYPE_H263;
+    } else {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = HW_VIDEO_ENC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pMpeg4Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_MPEG4ENC_HANDLE));
+    if (pMpeg4Enc == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pMpeg4Enc, 0, sizeof(EXYNOS_MPEG4ENC_HANDLE));
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Enc;
+    pMpeg4Enc->qpRangeI.nMinQP = 3;
+    pMpeg4Enc->qpRangeI.nMaxQP = 30;
+    pMpeg4Enc->qpRangeP.nMinQP = 3;
+    pMpeg4Enc->qpRangeP.nMaxQP = 30;
+    pMpeg4Enc->qpRangeB.nMinQP = 3;
+    pMpeg4Enc->qpRangeB.nMaxQP = 30;
+
+    pVideoEnc->quantization.nQpI = 15;
+    pVideoEnc->quantization.nQpP = 16;
+    pVideoEnc->quantization.nQpB = 18;
+
+    pMpeg4Enc->hMFCMpeg4Handle.codecType = codecType;
+    if (codecType == CODEC_TYPE_MPEG4)
+        Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MPEG4_ENC);
+    else
+        Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H263_ENC);
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nBitrate = 64000;
+    pExynosPort->portDefinition.format.video.xFramerate= (15 << 16);
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nBitrate = 64000;
+    pExynosPort->portDefinition.format.video.xFramerate= (15 << 16);
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    if (codecType == CODEC_TYPE_MPEG4) {
+        pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
+        Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+        Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/mpeg4");
+    } else {
+        pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
+        Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+        Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/h263");
+    }
+    pExynosPort->portDefinition.format.video.pNativeRender = 0;
+    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    if (codecType == CODEC_TYPE_MPEG4) {
+        for(i = 0; i < ALL_PORT_NUM; i++) {
+            INIT_SET_SIZE_VERSION(&pMpeg4Enc->mpeg4Component[i], OMX_VIDEO_PARAM_MPEG4TYPE);
+            pMpeg4Enc->mpeg4Component[i].nPortIndex = i;
+            pMpeg4Enc->mpeg4Component[i].eProfile   = OMX_VIDEO_MPEG4ProfileSimple;
+            pMpeg4Enc->mpeg4Component[i].eLevel     = OMX_VIDEO_MPEG4Level4;
+
+            pMpeg4Enc->mpeg4Component[i].nPFrames = 29;
+            pMpeg4Enc->mpeg4Component[i].nBFrames = 0;
+            pMpeg4Enc->mpeg4Component[i].nMaxPacketSize = 256;  /* Default value */
+            pMpeg4Enc->mpeg4Component[i].nAllowedPictureTypes =  OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
+            pMpeg4Enc->mpeg4Component[i].bGov = OMX_FALSE;
+
+        }
+    } else {
+        for(i = 0; i < ALL_PORT_NUM; i++) {
+            INIT_SET_SIZE_VERSION(&pMpeg4Enc->h263Component[i], OMX_VIDEO_PARAM_H263TYPE);
+            pMpeg4Enc->h263Component[i].nPortIndex = i;
+            pMpeg4Enc->h263Component[i].eProfile   = OMX_VIDEO_H263ProfileBaseline;
+            pMpeg4Enc->h263Component[i].eLevel     = OMX_VIDEO_H263Level45;
+
+            pMpeg4Enc->h263Component[i].nPFrames = 29;
+            pMpeg4Enc->h263Component[i].nBFrames = 0;          /* No support for B frames */
+            pMpeg4Enc->h263Component[i].bPLUSPTYPEAllowed = OMX_FALSE;
+            pMpeg4Enc->h263Component[i].nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
+            pMpeg4Enc->h263Component[i].bForceRoundingTypeToZero = OMX_TRUE;
+            pMpeg4Enc->h263Component[i].nPictureHeaderRepetition = 0;
+            pMpeg4Enc->h263Component[i].nGOBHeaderInterval = 0;
+        }
+    }
+
+    pOMXComponent->GetParameter      = &Exynos_Mpeg4Enc_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_Mpeg4Enc_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_Mpeg4Enc_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_Mpeg4Enc_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_Mpeg4Enc_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_Mpeg4Enc_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_Mpeg4Enc_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_Mpeg4Enc_Terminate;
+
+    pVideoEnc->exynos_codec_srcInputProcess  = &Exynos_Mpeg4Enc_srcInputBufferProcess;
+    pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_Mpeg4Enc_srcOutputBufferProcess;
+    pVideoEnc->exynos_codec_dstInputProcess  = &Exynos_Mpeg4Enc_dstInputBufferProcess;
+    pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_Mpeg4Enc_dstOutputBufferProcess;
+
+    pVideoEnc->exynos_codec_start            = &Mpeg4CodecStart;
+    pVideoEnc->exynos_codec_stop             = &Mpeg4CodecStop;
+    pVideoEnc->exynos_codec_bufferProcessRun = &Mpeg4CodecOutputBufferProcessRun;
+    pVideoEnc->exynos_codec_enqueueAllBuffer = &Mpeg4CodecEnqueueAllBuffer;
+
+    pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+
+    pVideoEnc->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
+
+    pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoEnc->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pMpeg4Enc);
+        pMpeg4Enc = pVideoEnc->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
+        pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.eCodecType = VIDEO_CODING_MPEG4;
+    else
+        pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.eCodecType = VIDEO_CODING_H263;
+
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo), VIDEO_FALSE /* enc */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pMpeg4Enc);
+        pMpeg4Enc = pVideoEnc->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for enc : ext(%d)/qp-range(%d)", pExynosComponent, __FUNCTION__,
+            (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.supportInfo.enc.nSpareSize),
+            (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.supportInfo.enc.bQpRangePBSupport));
+
+    if (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.supportInfo.enc.nSpareSize > 0)
+        pVideoEnc->nInbufSpareSize = pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.supportInfo.enc.nSpareSize;
+
+    Exynos_Input_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_AddVendorExt(hComponent, "sec-ext-enc-qp-range", (OMX_INDEXTYPE)OMX_IndexConfigVideoQPRange);
+#endif
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_MPEG4ENC_HANDLE          *pMpeg4Enc          = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent       = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent    = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoEnc           = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pMpeg4Enc != NULL) {
+        Exynos_OSAL_Free(pMpeg4Enc);
+        pMpeg4Enc = pVideoEnc->hCodecHandle = NULL;
+    }
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_DelVendorExts(hComponent);
+#endif
+
+    ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h b/openmax/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.h
new file mode 100755 (executable)
index 0000000..45391cc
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Mpeg4enc.h
+ * @brief
+ * @author      Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_MPEG4_ENC_COMPONENT
+#define EXYNOS_OMX_MPEG4_ENC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+
+#include "ExynosVideoApi.h"
+
+typedef enum _CODEC_TYPE
+{
+    CODEC_TYPE_H263,
+    CODEC_TYPE_MPEG4
+} CODEC_TYPE;
+
+typedef struct _EXYNOS_MFC_MPEG4ENC_HANDLE
+{
+    OMX_HANDLETYPE             hMFCHandle;
+
+    OMX_U32                    indexTimestamp;
+    OMX_U32 outputIndexTimestamp;
+    OMX_BOOL bConfiguredMFCSrc;
+    OMX_BOOL bConfiguredMFCDst;
+    CODEC_TYPE                 codecType;
+
+    ExynosVideoEncOps       *pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps;
+    ExynosVideoEncBufferOps *pOutbufOps;
+    ExynosVideoEncParam      encParam;
+    ExynosVideoInstInfo      videoInstInfo;
+
+    #define MAX_PROFILE_NUM 4
+    OMX_S32 profiles[MAX_PROFILE_NUM];
+    OMX_S32 nProfileCnt;
+    OMX_S32 maxLevel;
+} EXYNOS_MFC_MPEG4ENC_HANDLE;
+
+typedef struct _EXYNOS_MPEG4ENC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_H263TYPE            h263Component[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_MPEG4TYPE           mpeg4Component[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+
+    OMX_VIDEO_QPRANGE                   qpRangeI;
+    OMX_VIDEO_QPRANGE                   qpRangeP;
+    OMX_VIDEO_QPRANGE                   qpRangeB;  /* MPEG4 ONLY */
+
+    /* SEC MFC Codec specific */
+    EXYNOS_MFC_MPEG4ENC_HANDLE   hMFCMpeg4Handle;
+
+    OMX_BOOL bSourceStart;
+    OMX_BOOL bDestinationStart;
+    OMX_HANDLETYPE hSourceStartEvent;
+    OMX_HANDLETYPE hDestinationInStartEvent;
+    OMX_HANDLETYPE hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE bypassBufferInfoQ;
+} EXYNOS_MPEG4ENC_HANDLE;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName);
+                OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/enc/mpeg4/Makefile.am b/openmax/component/video/enc/mpeg4/Makefile.am
new file mode 100755 (executable)
index 0000000..45bc624
--- /dev/null
@@ -0,0 +1,25 @@
+lib_LTLIBRARIES = libOMX.Exynos.MPEG4.Encoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_MPEG4_Encoder_la_SOURCES = Exynos_OMX_Mpeg4enc.c \
+                                         library_register.c
+
+libOMX_Exynos_MPEG4_Encoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                        $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                        $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                        $(top_builddir)/openmax/component/video/enc/libExynosOMX_Venc.la \
+                                        $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+
+libOMX_Exynos_MPEG4_Encoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                        -I$(top_srcdir)/openmax/include/exynos \
+                                        -I$(top_srcdir)/openmax/osal \
+                                        -I$(top_srcdir)/openmax/core \
+                                        -I$(top_srcdir)/openmax/component/common \
+                                        -I$(top_srcdir)/openmax/component/video/enc \
+                                      -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_MPEG4_Encoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
+libOMX_Exynos_MPEG4_Encoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable -Wno-unused-function
+
+libOMX_Exynos_MPEG4_Encoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/enc/mpeg4/library_register.c b/openmax/component/video/enc/mpeg4/library_register.c
new file mode 100755 (executable)
index 0000000..6b9f5ea
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.c
+ * @brief
+ * @author      Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_MPEG4_ENC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent)
+{
+    FunctionIn();
+
+    if (ppExynosComponent == NULL)
+        goto EXIT;
+
+    /* component 1 - video encoder MPEG4 */
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_MPEG4_ENC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_MPEG4_ENC_ROLE);
+    ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+    /* component 2 - video encoder H.263 */
+    Exynos_OSAL_Strcpy(ppExynosComponent[1]->componentName, EXYNOS_OMX_COMPONENT_H263_ENC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[1]->roles[0], EXYNOS_OMX_COMPONENT_H263_ENC_ROLE);
+    ppExynosComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
diff --git a/openmax/component/video/enc/mpeg4/library_register.h b/openmax/component/video/enc/mpeg4/library_register.h
new file mode 100755 (executable)
index 0000000..60f6037
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author      Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_MPEG4_ENC_REG
+#define EXYNOS_OMX_MPEG4_ENC_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM       2
+#define MAX_COMPONENT_ROLE_NUM  1
+
+/* MPEG4 */
+#define EXYNOS_OMX_COMPONENT_MPEG4_ENC         "OMX.Exynos.MPEG4.Encoder"
+#define EXYNOS_OMX_COMPONENT_MPEG4_ENC_ROLE    "video_encoder.mpeg4"
+
+/* H.263 */
+#define EXYNOS_OMX_COMPONENT_H263_ENC          "OMX.Exynos.H263.Encoder"
+#define EXYNOS_OMX_COMPONENT_H263_ENC_ROLE     "video_encoder.h263"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
diff --git a/openmax/component/video/enc/vp8/Exynos_OMX_Vp8enc.c b/openmax/component/video/enc/vp8/Exynos_OMX_Vp8enc.c
new file mode 100755 (executable)
index 0000000..ef1f0f0
--- /dev/null
@@ -0,0 +1,3189 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Vp8enc.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2013.02.14 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Venc.h"
+#include "Exynos_OMX_VencControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Vp8enc.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OSAL_Queue.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
+/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VP8_ENC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+#define VP8_QP_INDEX_RANGE 64
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc        = NULL;
+
+    int nProfileCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp8Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Enc->hMFCVp8Handle.profiles[nProfileCnt++] = OMX_VIDEO_VP8ProfileMain;
+    pVp8Enc->hMFCVp8Handle.nProfileCnt = nProfileCnt;
+    pVp8Enc->hMFCVp8Handle.maxLevel = OMX_VIDEO_VP8Level_Version3;
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret           = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc     = NULL;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc       = NULL;
+
+    int nLevelCnt = 0;
+    OMX_U32 nMaxIndex = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp8Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pVp8Enc->hMFCVp8Handle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pVp8Enc->hMFCVp8Handle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pVp8Enc->hMFCVp8Handle.maxLevel;
+#else
+    while ((pVp8Enc->hMFCVp8Handle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+
+    if ((pVp8Enc->hMFCVp8Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pVp8Enc->hMFCVp8Handle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pVp8Enc->hMFCVp8Handle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : supported profile(%x), level(%x)",
+                                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc  = NULL;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc    = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp8Enc == NULL)
+        goto EXIT;
+
+    while ((pVp8Enc->hMFCVp8Handle.maxLevel >> nLevelCnt++) > 0);
+
+    if ((pVp8Enc->hMFCVp8Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pVp8Enc->hMFCVp8Handle.nProfileCnt; i++) {
+        if (pVp8Enc->hMFCVp8Handle.profiles[i] == pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    while (nLevelCnt >= 0) {
+        if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+            bLevelSupport = OMX_TRUE;
+            break;
+        }
+
+        nLevelCnt--;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_U32 OMXVP8ProfileToProfileIDC(OMX_VIDEO_VP8PROFILETYPE eProfile)
+{
+    OMX_U32 ret;
+
+    switch (eProfile) {
+    case OMX_VIDEO_VP8ProfileMain:
+        ret = 0;
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+
+    return ret;
+}
+
+static OMX_U32 OMXVP8LevelToMFCVersion(OMX_VIDEO_VP8LEVELTYPE eLevel)
+{
+    OMX_U32 ret;
+
+    switch (eLevel) {
+    case OMX_VIDEO_VP8Level_Version0:
+        ret = 0;
+        break;
+    case OMX_VIDEO_VP8Level_Version1:
+        ret = 1;
+        break;
+    case OMX_VIDEO_VP8Level_Version2:
+        ret = 2;
+        break;
+    case OMX_VIDEO_VP8Level_Version3:
+        ret = 3;
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+
+    return ret;
+}
+
+static void Print_VP8Enc_Param(ExynosVideoEncParam *pEncParam)
+{
+    ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam;
+    ExynosVideoEncVp8Param    *pVp8Param    = &pEncParam->codecParam.vp8;
+
+    /* common parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceWidth             : %d", pCommonParam->SourceWidth);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceHeight            : %d", pCommonParam->SourceHeight);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "IDRPeriod               : %d", pCommonParam->IDRPeriod);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SliceMode               : %d", pCommonParam->SliceMode);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "RandomIntraMBRefresh    : %d", pCommonParam->RandomIntraMBRefresh);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Bitrate                 : %d", pCommonParam->Bitrate);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp                 : %d", pCommonParam->FrameQp);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp_P               : %d", pCommonParam->FrameQp_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(I) ranege            : %d / %d", pCommonParam->QpRange.QpMin_I, pCommonParam->QpRange.QpMax_I);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(P) ranege            : %d / %d", pCommonParam->QpRange.QpMin_P, pCommonParam->QpRange.QpMax_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "PadControlOn            : %d", pCommonParam->PadControlOn);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LumaPadVal              : %d", pCommonParam->LumaPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CbPadVal                : %d", pCommonParam->CbPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CrPadVal                : %d", pCommonParam->CrPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameMap                : %d", pCommonParam->FrameMap);
+
+    /* Vp8 specific parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameRate               : %d", pVp8Param->FrameRate);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Vp8Version              : %d", pVp8Param->Vp8Version);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "Vp8NumberOfPartitions   : %d", pVp8Param->Vp8NumberOfPartitions);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "Vp8FilterLevel          : %d", pVp8Param->Vp8FilterLevel);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "Vp8FilterSharpness      : %d", pVp8Param->Vp8FilterSharpness);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "Vp8GoldenFrameSel       : %d", pVp8Param->Vp8GoldenFrameSel);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "Vp8GFRefreshPeriod      : %d", pVp8Param->Vp8GFRefreshPeriod);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "RefNumberForPFrame      : %d", pVp8Param->RefNumberForPFrame);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "DisableIntraMd4x4       : %d", pVp8Param->DisableIntraMd4x4);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumTemporalLayer        : %d", pVp8Param->TemporalSVC.nTemporalLayerCount);
+
+    /* rate control related parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableFRMRateControl    : %d", pCommonParam->EnableFRMRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableMBRateControl     : %d", pCommonParam->EnableMBRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CBRPeriodRf             : %d", pCommonParam->CBRPeriodRf);
+}
+
+static void Set_VP8Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_BASEPORT           *pInputPort       = NULL;
+    EXYNOS_OMX_BASEPORT           *pOutputPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_VP8ENC_HANDLE          *pVp8Enc          = NULL;
+    EXYNOS_MFC_VP8ENC_HANDLE      *pMFCVp8Handle    = NULL;
+    OMX_COLOR_FORMATTYPE           eColorFormat     = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncParam       *pEncParam    = NULL;
+    ExynosVideoEncCommonParam *pCommonParam = NULL;
+    ExynosVideoEncVp8Param    *pVp8Param    = NULL;
+
+    int i;
+
+    pVideoEnc       = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVp8Enc         = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCVp8Handle   = &pVp8Enc->hMFCVp8Handle;
+    pInputPort      = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pOutputPort     = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pEncParam       = &pMFCVp8Handle->encParam;
+    pCommonParam    = &pEncParam->commonParam;
+    pVp8Param       = &pEncParam->codecParam.vp8;
+
+    pEncParam->eCompressionFormat = VIDEO_CODING_VP8;
+
+    /* common parameters */
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+    } else {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+    }
+    pCommonParam->IDRPeriod    = pVp8Enc->nPFrames + 1;
+    pCommonParam->SliceMode    = 0;
+    pCommonParam->Bitrate      = pOutputPort->portDefinition.format.video.nBitrate;
+    pCommonParam->FrameQp      = pVideoEnc->quantization.nQpI;
+    pCommonParam->FrameQp_P    = pVideoEnc->quantization.nQpP;
+
+    pCommonParam->QpRange.QpMin_I = pVp8Enc->qpRangeI.nMinQP;
+    pCommonParam->QpRange.QpMax_I = pVp8Enc->qpRangeI.nMaxQP;
+    pCommonParam->QpRange.QpMin_P = pVp8Enc->qpRangeP.nMinQP;
+    pCommonParam->QpRange.QpMax_P = pVp8Enc->qpRangeP.nMaxQP;
+
+    pCommonParam->PadControlOn = 0;    /* 0: Use boundary pixel, 1: Use the below setting value */
+    pCommonParam->LumaPadVal   = 0;
+    pCommonParam->CbPadVal     = 0;
+    pCommonParam->CrPadVal     = 0;
+
+    if (pVideoEnc->intraRefresh.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) {
+        /* Cyclic Mode */
+        pCommonParam->RandomIntraMBRefresh = pVideoEnc->intraRefresh.nCirMBs;
+    } else {
+        /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+        pCommonParam->RandomIntraMBRefresh = 0;
+    }
+
+    /* Perceptual Mode */
+    pCommonParam->PerceptualMode = (pVideoEnc->bPVCMode)? VIDEO_TRUE:VIDEO_FALSE;
+
+    eColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+    pCommonParam->FrameMap = Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    /* Vp8 specific parameters */
+    pVp8Param->Vp8Version = OMXVP8LevelToMFCVersion(pVp8Enc->VP8Component[OUTPUT_PORT_INDEX].eLevel);
+    pVp8Param->FrameRate = (pInputPort->portDefinition.format.video.xFramerate) >> 16;
+    if (pVp8Param->FrameRate <= 0)
+        pVp8Param->FrameRate = 30;  /* default : 30fps, zero means that DynamicFramerateChange mode is set */
+
+    /* there is no interface at OMX IL component */
+    pVp8Param->RefNumberForPFrame       = 1;  /* 1 ~ 2 */
+
+    pVp8Param->Vp8NumberOfPartitions    = pVp8Enc->VP8Component[OUTPUT_PORT_INDEX].nDCTPartitions;
+    pVp8Param->Vp8FilterLevel           = 28;
+    pVp8Param->Vp8FilterSharpness       = 6;
+    pVp8Param->Vp8GoldenFrameSel        = 0;
+    pVp8Param->Vp8GFRefreshPeriod       = 10;
+    pVp8Param->DisableIntraMd4x4        = 0;
+
+    /* Temporal SVC */
+    pVp8Param->TemporalSVC.nTemporalLayerCount = (unsigned int)pVp8Enc->AndroidVp8EncoderType.nTemporalLayerCount;
+    pVp8Param->TemporalSVC.nTemporalLayerBitrateRatio[0] = (unsigned int)(pOutputPort->portDefinition.format.video.nBitrate *
+                                                                          pVp8Enc->AndroidVp8EncoderType.nTemporalLayerBitrateRatio[0] / 100);
+    for (i = 1; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
+        pVp8Param->TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)(pOutputPort->portDefinition.format.video.nBitrate *
+                                                                              (pVp8Enc->AndroidVp8EncoderType.nTemporalLayerBitrateRatio[i] -
+                                                                               pVp8Enc->AndroidVp8EncoderType.nTemporalLayerBitrateRatio[i - 1])
+                                                                              / 100);
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eControlRate: 0x%x", pExynosComponent, __FUNCTION__, pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]);
+    /* rate control related parameters */
+    switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) {
+    case OMX_Video_ControlRateDisable:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR");
+        pCommonParam->EnableFRMRateControl = 0;    /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 0;    /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 200;
+        break;
+    case OMX_Video_ControlRateConstant:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 9;
+        break;
+    case OMX_Video_ControlRateVariable:
+    default: /*Android default */
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 200;
+        break;
+    }
+
+//    Print_VP8Enc_Param(pEncParam);
+}
+
+static void Change_VP8Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = NULL;
+    EXYNOS_VP8ENC_HANDLE          *pVp8Enc           = NULL;
+    EXYNOS_MFC_VP8ENC_HANDLE      *pMFCVp8Handle     = NULL;
+    OMX_PTR                        pDynamicConfigCMD = NULL;
+    OMX_PTR                        pConfigData       = NULL;
+    OMX_S32                        nCmdIndex         = 0;
+    ExynosVideoEncOps             *pEncOps           = NULL;
+    int                            nValue            = 0;
+
+    int i;
+
+    pVideoEnc       = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVp8Enc         = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCVp8Handle   = &pVp8Enc->hMFCVp8Handle;
+    pEncOps         = pMFCVp8Handle->pEncOps;
+
+    pDynamicConfigCMD = (OMX_PTR)Exynos_OSAL_Dequeue(&pExynosComponent->dynamicConfigQ);
+    if (pDynamicConfigCMD == NULL)
+        goto EXIT;
+
+    nCmdIndex   = *(OMX_S32 *)pDynamicConfigCMD;
+    pConfigData = (OMX_PTR)((OMX_U8 *)pDynamicConfigCMD + sizeof(OMX_S32));
+
+    switch ((int)nCmdIndex) {
+    case OMX_IndexConfigVideoIntraVOPRefresh:
+    {
+        nValue = VIDEO_FRAME_I;
+        pEncOps->Set_FrameType(pMFCVp8Handle->hMFCHandle, nValue);
+        pVideoEnc->IntraRefreshVOP = OMX_FALSE;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] VOP Refresh", pExynosComponent, __FUNCTION__);
+    }
+        break;
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        OMX_S32 nPFrames = (*((OMX_U32 *)pConfigData)) - 1;
+        nValue = nPFrames + 1;
+        pEncOps->Set_IDRPeriod(pMFCVp8Handle->hMFCHandle, nValue);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] IDR period: %d", pExynosComponent, __FUNCTION__, nValue);
+    }
+        break;
+    case OMX_IndexConfigVideoBitrate:
+    {
+        OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pConfigData;
+
+        if (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] != OMX_Video_ControlRateDisable) {
+            /* bitrate : main */
+            nValue = pConfigBitrate->nEncodeBitrate;
+            pEncOps->Set_BitRate(pMFCVp8Handle->hMFCHandle, nValue);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bitrate: %d", pExynosComponent, __FUNCTION__, nValue);
+            /* bitrate : layer */
+            TemporalLayerShareBuffer TemporalSVC;
+            Exynos_OSAL_Memset(&TemporalSVC, 0, sizeof(TemporalLayerShareBuffer));
+            TemporalSVC.nTemporalLayerCount = (unsigned int)pVp8Enc->AndroidVp8EncoderType.nTemporalLayerCount;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "nTemporalLayerCount     : %d", TemporalSVC.nTemporalLayerCount);
+            TemporalSVC.nTemporalLayerBitrateRatio[0] = (unsigned int)(pConfigBitrate->nEncodeBitrate *
+                                                                   pVp8Enc->AndroidVp8EncoderType.nTemporalLayerBitrateRatio[0] / 100);
+            for (i = 1; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
+                TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)(pConfigBitrate->nEncodeBitrate *
+                                                                           (pVp8Enc->AndroidVp8EncoderType.nTemporalLayerBitrateRatio[i] -
+                                                                            pVp8Enc->AndroidVp8EncoderType.nTemporalLayerBitrateRatio[i - 1])
+                                                                           / 100);
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "nTempBitrateRatio[%d]   : %d", i, TemporalSVC.nTemporalLayerBitrateRatio[i]);
+            }
+            pEncOps->Set_LayerChange(pMFCVp8Handle->hMFCHandle, TemporalSVC);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoFramerate:
+    {
+        OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pConfigData;
+        OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
+
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            nValue = (pConfigFramerate->xEncodeFramerate) >> 16;
+            pEncOps->Set_FrameRate(pMFCVp8Handle->hMFCHandle, nValue);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] framerate: %d", pExynosComponent, __FUNCTION__, nValue);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange = (OMX_VIDEO_QPRANGETYPE *)pConfigData;
+        ExynosVideoQPRange     qpRange;
+
+        Exynos_OSAL_Memset(&qpRange, 0, sizeof(ExynosVideoQPRange));
+
+        qpRange.QpMin_I = pQpRange->qpRangeI.nMinQP;
+        qpRange.QpMax_I = pQpRange->qpRangeI.nMaxQP;
+        qpRange.QpMin_P = pQpRange->qpRangeP.nMinQP;
+        qpRange.QpMax_P = pQpRange->qpRangeP.nMaxQP;
+
+        pEncOps->Set_QpRange(pMFCVp8Handle->hMFCHandle, qpRange);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qp range: I(%d, %d), P(%d, %d)",
+                                    pExynosComponent, __FUNCTION__,
+                                    qpRange.QpMin_I, qpRange.QpMax_I,
+                                    qpRange.QpMin_P, qpRange.QpMax_P);
+    }
+        break;
+    case OMX_IndexConfigOperatingRate:
+    {
+        OMX_PARAM_U32TYPE *pConfigRate = (OMX_PARAM_U32TYPE *)pConfigData;
+        OMX_U32            xFramerate  = pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.xFramerate;
+
+        if (xFramerate == 0)
+            nValue = 100;
+        else
+            nValue = (OMX_U32)((pConfigRate->nU32 / (double)xFramerate) * 100);
+
+        pEncOps->Set_QosRatio(pMFCVp8Handle->hMFCHandle, nValue);
+        pVideoEnc->bQosChanged = OMX_FALSE;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qos ratio: %d", pExynosComponent, __FUNCTION__, nValue);
+    }
+        break;
+    default:
+        break;
+    }
+
+    Exynos_OSAL_Free(pDynamicConfigCMD);
+
+    Set_VP8Enc_Param(pExynosComponent);
+
+EXIT:
+    return;
+}
+
+OMX_ERRORTYPE GetCodecOutputPrivateData(
+    OMX_PTR  pCodecBuffer,
+    OMX_PTR *pVirtAddr,
+    OMX_U32 *pDataSize)
+{
+    OMX_ERRORTYPE      ret          = OMX_ErrorNone;
+    ExynosVideoBuffer *pVideoBuffer = NULL;
+
+    if (pCodecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoBuffer = (ExynosVideoBuffer *)pCodecBuffer;
+
+    if (pVirtAddr != NULL)
+        *pVirtAddr = pVideoBuffer->planes[0].addr;
+
+    if (pDataSize != NULL)
+        *pDataSize = pVideoBuffer->planes[0].allocSize;
+
+EXIT:
+    return ret;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc        = NULL;
+    EXYNOS_OMX_BASEPORT             *pInputPort     = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp8Enc == NULL)
+        goto EXIT;
+    pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pVp8Enc->hMFCVp8Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pVp8Enc->hMFCVp8Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecOpen(
+    EXYNOS_VP8ENC_HANDLE    *pVp8Enc,
+    ExynosVideoInstInfo     *pVideoInstInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pVp8Enc == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pEncOps     = (ExynosVideoEncOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncOps));
+    pInbufOps   = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+    pOutbufOps  = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+
+    if ((pEncOps == NULL) ||
+        (pInbufOps == NULL) ||
+        (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVp8Enc->hMFCVp8Handle.pEncOps    = pEncOps;
+    pVp8Enc->hMFCVp8Handle.pInbufOps  = pInbufOps;
+    pVp8Enc->hMFCVp8Handle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pEncOps->nSize    = sizeof(ExynosVideoEncOps);
+    pInbufOps->nSize  = sizeof(ExynosVideoEncBufferOps);
+    pOutbufOps->nSize = sizeof(ExynosVideoEncBufferOps);
+
+    if (Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for encoder ops */
+    if ((pEncOps->Init == NULL) ||
+        (pEncOps->Finalize == NULL) ||
+        (pEncOps->Set_FrameTag == NULL) ||
+        (pEncOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pVp8Enc->hMFCVp8Handle.hMFCHandle = pVp8Enc->hMFCVp8Handle.pEncOps->Init(pVideoInstInfo);
+    if (pVp8Enc->hMFCVp8Handle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pEncOps != NULL) {
+            Exynos_OSAL_Free(pEncOps);
+            pVp8Enc->hMFCVp8Handle.pEncOps = NULL;
+        }
+
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pVp8Enc->hMFCVp8Handle.pInbufOps = NULL;
+        }
+
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pVp8Enc->hMFCVp8Handle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecClose(EXYNOS_VP8ENC_HANDLE *pVp8Enc)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pVp8Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle;
+    pEncOps    = pVp8Enc->hMFCVp8Handle.pEncOps;
+    pInbufOps  = pVp8Enc->hMFCVp8Handle.pInbufOps;
+    pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pEncOps->Finalize(hMFCHandle);
+        hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle = NULL;
+        pVp8Enc->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE;
+        pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Encoder(pEncOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps = NULL;
+    }
+
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps = NULL;
+    }
+
+    if (pEncOps != NULL) {
+        Exynos_OSAL_Free(pEncOps);
+        pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecStart(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc            = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp8Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle;
+    pInbufOps  = pVp8Enc->hMFCVp8Handle.pInbufOps;
+    pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps;
+
+    if (nPortIndex == INPUT_PORT_INDEX)
+        pInbufOps->Run(hMFCHandle);
+    else if (nPortIndex == OUTPUT_PORT_INDEX)
+        pOutbufOps->Run(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecStop(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc            = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp8Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle;
+    pInbufOps  = pVp8Enc->hMFCVp8Handle.pInbufOps;
+    pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
+        pInbufOps->Stop(hMFCHandle);
+    else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
+        pOutbufOps->Stop(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecOutputBufferProcessRun(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc            = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp8Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pVp8Enc->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pVp8Enc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pVp8Enc->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pVp8Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pVp8Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecEnqueueAllBuffer(
+    OMX_COMPONENTTYPE *pOMXComponent,
+    OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc            = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                            *hMFCHandle         = pVp8Enc->hMFCVp8Handle.hMFCHandle;
+    int i;
+
+    ExynosVideoEncBufferOps *pInbufOps  = pVp8Enc->hMFCVp8Handle.pInbufOps;
+    ExynosVideoEncBufferOps *pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) &&
+        (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pVp8Enc->bSourceStart == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)  {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoEnc->pMFCEncInputBuffer[i]->fd[0], pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pVp8Enc->bDestinationStart == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoEnc->pMFCEncOutputBuffer[i]->fd[0], pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoEnc->pMFCEncOutputBuffer[i]);
+        }
+
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecSrcSetup(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc            = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_VP8ENC_HANDLE        *pMFCVp8Handle      = &pVp8Enc->hMFCVp8Handle;
+    void                            *hMFCHandle         = pMFCVp8Handle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                          oneFrameSize       = pSrcInputData->dataLen;
+
+    ExynosVideoEncOps       *pEncOps    = pVp8Enc->hMFCVp8Handle.pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps  = pVp8Enc->hMFCVp8Handle.pInbufOps;
+    ExynosVideoEncParam     *pEncParam  = NULL;
+
+    ExynosVideoGeometry      bufferConf;
+    OMX_U32                  inputBufferNumber = 0;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pVp8Enc->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pVp8Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pVp8Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    Set_VP8Enc_Param(pExynosComponent);
+
+    pEncParam = &pMFCVp8Handle->encParam;
+    if (pEncOps->Set_EncParam) {
+        if(pEncOps->Set_EncParam(pVp8Enc->hMFCVp8Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+    Print_VP8Enc_Param(pEncParam);
+
+    /* input buffer info: only 3 config values needed */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        bufferConf.nFrameWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        bufferConf.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+        bufferConf.nStride      = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth, 16);
+    } else {
+        bufferConf.nFrameWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        bufferConf.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+        bufferConf.nStride      = ALIGN(pOutputPort->portDefinition.format.video.nFrameHeight, 16);
+    }
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+    pInbufOps->Set_Shareable(hMFCHandle);
+    inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare input buffer */
+        if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry) {
+        if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if ((pInputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pInputPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
+        /* data buffer */
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    }
+
+    pVp8Enc->hMFCVp8Handle.bConfiguredMFCSrc = OMX_TRUE;
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc            = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_VP8ENC_HANDLE        *pMFCVp8Handle      = &pVp8Enc->hMFCVp8Handle;
+    void                            *hMFCHandle         = pMFCVp8Handle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0};
+    unsigned int nDataLen[VIDEO_BUFFER_MAX_PLANES]  = {0, 0, 0};
+    int i, nOutBufSize = 0, nOutputBufferCnt = 0;
+
+    FunctionIn();
+
+    nOutBufSize = pOutputPort->portDefinition.nBufferSize;
+    if ((pOutputPort->bufferProcessType & BUFFER_COPY) ||
+        (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        /* OMX buffer is not used directly : CODEC buffer or MetaData */
+        nOutBufSize = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth *
+                            pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+    }
+
+    /* set geometry for output (dst) */
+    if (pOutbufOps->Set_Geometry) {
+        /* only 2 config values needed */
+        bufferConf.eCompressionFormat   = VIDEO_CODING_VP8;
+        bufferConf.nSizeImage           = nOutBufSize;
+        bufferConf.nPlaneCnt            = Exynos_GetPlaneFromPort(pOutputPort);
+
+        if (pOutbufOps->Set_Geometry(pVp8Enc->hMFCVp8Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* should be done before prepare output buffer */
+    if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY)
+        nOutputBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
+    else
+        nOutputBufferCnt = pOutputPort->portDefinition.nBufferCountActual;
+
+    if (pOutbufOps->Setup(pVp8Enc->hMFCVp8Handle.hMFCHandle, nOutputBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        nAllocLen[0] = nOutBufSize;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Allocate_CodecBuffers for output", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        /* Enqueue output buffer */
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
+                                (unsigned long *)pVideoEnc->pMFCEncOutputBuffer[i]->fd,
+                                pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pOutputPort),
+                                NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* Register output buffer */
+        /*************/
+        /*    TBD    */
+        /*************/
+    }
+
+    pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst = OMX_TRUE;
+
+    if (VP8CodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nParamIndex %x", pExynosComponent, __FUNCTION__, (int)nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoVp8:
+    {
+        OMX_VIDEO_PARAM_VP8TYPE *pDstVP8Component = (OMX_VIDEO_PARAM_VP8TYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP8TYPE *pSrcVP8Component = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstVP8Component, sizeof(OMX_VIDEO_PARAM_VP8TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstVP8Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVP8Component = &pVp8Enc->VP8Component[pDstVP8Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstVP8Component) + nOffset,
+                           ((char *)pSrcVP8Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_VP8TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_ENC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP8TYPE          *pSrcVP8Component = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVP8Component = &pVp8Enc->VP8Component[pDstProfileLevel->nPortIndex];
+        pDstProfileLevel->eProfile  = pSrcVP8Component->eProfile;
+        pDstProfileLevel->eLevel    = pSrcVP8Component->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pVp8Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
+        pDstErrorCorrectionType->bEnableHEC              = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync           = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing   = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC             = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pVp8Enc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pVp8Enc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pVp8Enc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pVp8Enc->qpRangeP.nMaxQP;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamVideoAndroidVp8Encoder:
+    {
+
+        OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *pDstVp8EncoderType = (OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *pSrcVp8EncoderType = &pVp8Enc->AndroidVp8EncoderType;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstVp8EncoderType, sizeof(OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstVp8EncoderType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVp8EncoderType->nKeyFrameInterval = pVp8Enc->nPFrames + 1;
+        pSrcVp8EncoderType->nMinQuantizer = pVp8Enc->qpRangeI.nMinQP;
+        pSrcVp8EncoderType->nMaxQuantizer = pVp8Enc->qpRangeI.nMaxQP;
+
+        Exynos_OSAL_Memcpy(((char *)pDstVp8EncoderType) + nOffset,
+                           ((char *)pSrcVp8EncoderType) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE) - nOffset);
+    }
+        break;
+#endif
+    case OMX_IndexParamVideoEnablePVC:
+    {
+        OMX_PARAM_U32TYPE *pEnablePVC  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pEnablePVC, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pEnablePVC->nU32 = pVideoEnc->bPVCMode;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoVp8:
+    {
+        OMX_VIDEO_PARAM_VP8TYPE *pDstVP8Component = NULL;
+        OMX_VIDEO_PARAM_VP8TYPE *pSrcVP8Component = (OMX_VIDEO_PARAM_VP8TYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcVP8Component, sizeof(OMX_VIDEO_PARAM_VP8TYPE));
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        if (pSrcVP8Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstVP8Component = &pVp8Enc->VP8Component[pSrcVP8Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstVP8Component) + nOffset,
+                           ((char *)pSrcVP8Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_VP8TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_ENC_ROLE)) {
+            pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP8TYPE          *pDstVP8Component = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstVP8Component = &pVp8Enc->VP8Component[pSrcProfileLevel->nPortIndex];
+
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pDstVP8Component->eProfile  = pSrcProfileLevel->eProfile;
+        pDstVP8Component->eLevel    = pSrcProfileLevel->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pVp8Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
+        pDstErrorCorrectionType->bEnableHEC                 = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync              = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing      = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning    = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC                = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoPortFormat:
+    {
+        OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat     = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
+        OMX_U32                         nPortIndex      = pPortFormat->nPortIndex;
+        OMX_PARAM_PORTDEFINITIONTYPE   *pPortDef        = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pPortDef = &(pExynosComponent->pExynosPort[nPortIndex].portDefinition);
+        if ((nPortIndex == INPUT_PORT_INDEX) &&
+            ((pPortDef->format.video.xFramerate >> 16) > 0) &&
+            ((pPortFormat->xFramerate >> 16) <= 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] xFramerate is changed to invalid value(%d)",
+                                              pExynosComponent, __FUNCTION__, pPortFormat->xFramerate >> 16);
+        }
+
+        pPortDef->format.video.eColorFormat       = pPortFormat->eColorFormat;
+        pPortDef->format.video.eCompressionFormat = pPortFormat->eCompressionFormat;
+        pPortDef->format.video.xFramerate         = pPortFormat->xFramerate;
+    }
+        break;
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE *pPortDef      = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
+        OMX_U32                       nPortIndex    = pPortDef->nPortIndex;
+        EXYNOS_OMX_BASEPORT          *pExynosPort   = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_Check_SizeVersion(pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+                ret = OMX_ErrorIncorrectStateOperation;
+                goto EXIT;
+            }
+        }
+
+        if (pPortDef->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if ((nPortIndex == INPUT_PORT_INDEX) &&
+            ((pExynosPort->portDefinition.format.video.xFramerate >> 16) > 0) &&
+            ((pPortDef->format.video.xFramerate >> 16) <= 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] xFramerate is invalid(%d)",
+                                              pExynosComponent, __FUNCTION__, pPortDef->format.video.xFramerate >> 16);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Memcpy(((char *)&pExynosPort->portDefinition) + nOffset,
+                           ((char *)pPortDef) + nOffset,
+                           pPortDef->nSize - nOffset);
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+            Exynos_UpdateFrameSize(pOMXComponent);
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pOutputPort->portDefinition.nBufferSize: %d",
+                            pExynosPort->portDefinition.nBufferSize);
+        }
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d])", __FUNCTION__,
+                            pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                            pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pVp8Enc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pVp8Enc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pVp8Enc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pVp8Enc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamVideoAndroidVp8Encoder:
+    {
+        OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *pSrcVp8EncoderType = (OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *pDstVp8EncoderType = &pVp8Enc->AndroidVp8EncoderType;
+
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcVp8EncoderType, sizeof(OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE));
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        if (pSrcVp8EncoderType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pVp8Enc->hMFCVp8Handle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) &&
+            (pSrcVp8EncoderType->eTemporalPattern != OMX_VIDEO_VPXTemporalLayerPatternNone)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Temporal SVC is not supported", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        if ((pSrcVp8EncoderType->nMinQuantizer > pSrcVp8EncoderType->nMaxQuantizer) ||
+            (pSrcVp8EncoderType->nMaxQuantizer >= VP8_QP_INDEX_RANGE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] QP value is invalid(min:%d, max:%d)", pExynosComponent, __FUNCTION__,
+                            pSrcVp8EncoderType->nMinQuantizer, pSrcVp8EncoderType->nMaxQuantizer);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pVp8Enc->nPFrames = pSrcVp8EncoderType->nKeyFrameInterval - 1;
+
+        pVp8Enc->qpRangeI.nMinQP = pSrcVp8EncoderType->nMinQuantizer;
+        pVp8Enc->qpRangeI.nMaxQP = pSrcVp8EncoderType->nMaxQuantizer;
+
+        Exynos_OSAL_Memcpy(((char *)pDstVp8EncoderType) + nOffset,
+                           ((char *)pSrcVp8EncoderType) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE) - nOffset);
+    }
+        break;
+#endif
+    case OMX_IndexParamVideoEnablePVC:
+    {
+        OMX_PARAM_U32TYPE *pEnablePVC  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pEnablePVC, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pVideoEnc->bPVCMode = (pEnablePVC->nU32)? OMX_TRUE:OMX_FALSE;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_GetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pVp8Enc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pVp8Enc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pVp8Enc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pVp8Enc->qpRangeP.nMaxQP;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_SetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_VP8ENC_HANDLE          *pVp8Enc          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoFramerate:
+    {
+        OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure;
+        OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
+        EXYNOS_OMX_BASEPORT      *pExynosPort      = NULL;
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+        if ((nPortIndex == INPUT_PORT_INDEX) &&
+            ((pExynosPort->portDefinition.format.video.xFramerate >> 16) > 0) &&
+            ((pConfigFramerate->xEncodeFramerate >> 16) <= 0)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s[%x] xFramerate is changed to invalid value(%d)",
+                                              __FUNCTION__, OMX_IndexConfigVideoFramerate, pConfigFramerate->xEncodeFramerate >> 16);
+        }
+        pExynosPort->portDefinition.format.video.xFramerate = pConfigFramerate->xEncodeFramerate;
+    }
+        break;
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1;
+
+        pVp8Enc->nPFrames = nPFrames;
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d])",
+                            pExynosComponent, __FUNCTION__,
+                            pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                            pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if (pVp8Enc->hMFCVp8Handle.videoInstInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_FALSE)
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] only I-frame's QP range is applied", pExynosComponent, __FUNCTION__);
+
+        pVp8Enc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pVp8Enc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pVp8Enc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pVp8Enc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    if (ret == OMX_ErrorNone) {
+        OMX_PTR pDynamicConfigCMD = NULL;
+        pDynamicConfigCMD = Exynos_OMX_MakeDynamicConfig(nIndex, pComponentConfigStructure);
+        Exynos_OSAL_Queue(&pExynosComponent->dynamicConfigQ, (void *)pDynamicConfigCMD);
+    }
+
+    if (ret == (OMX_ERRORTYPE)OMX_ErrorNoneExpiration)
+        ret = OMX_ErrorNone;
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_GetExtensionIndex(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE *pIndexType)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_PVC) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamVideoEnablePVC;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_ComponentRoleEnum(
+    OMX_HANDLETYPE   hComponent,
+    OMX_U8          *cRole,
+    OMX_U32          nIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cRole == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_VP8_ENC_ROLE);
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorNoMore;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_VP8Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort           = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_VP8ENC_HANDLE          *pVp8Enc              = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    OMX_COLOR_FORMATTYPE           eColorFormat         = pInputPort->portDefinition.format.video.eColorFormat;
+
+    ExynosVideoInstInfo *pVideoInstInfo = &(pVp8Enc->hMFCVp8Handle.videoInstInfo);
+
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+
+    FunctionIn();
+
+    pVp8Enc->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE;
+    pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE;
+    pVideoEnc->bFirstInput         = OMX_TRUE;
+    pVideoEnc->bFirstOutput        = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+    if (pInputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+        /* metadata buffer */
+        pInputPort->bufferProcessType = BUFFER_SHARE;
+
+#ifdef USE_ANDROID
+        if ((pInputPort->eMetaDataType == METADATA_TYPE_DATA) &&
+            (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)) {
+            pInputPort->eMetaDataType     = METADATA_TYPE_GRAPHIC;  /* AndoridOpaque means GrallocSource */
+            pInputPort->bufferProcessType = BUFFER_COPY;  /* will determine a process type after getting a hal format at handle */
+        }
+#else
+        if (pInputPort->eMetaDataType == METADATA_TYPE_UBM_BUFFER) {
+            pInputPort->bufferProcessType = BUFFER_COPY;
+        }
+#endif
+    } else {
+        /* data buffer */
+        pInputPort->bufferProcessType = BUFFER_COPY;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                            pInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                            pInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                            pInputPort->portDefinition.format.video.nBitrate,
+                                                                                            pInputPort->portDefinition.format.video.xFramerate);
+    pVideoInstInfo->nSize        = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth       = pInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight      = pInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate     = pInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate   = pInputPort->portDefinition.format.video.xFramerate;
+
+    /* VP8 Codec Open */
+    ret = VP8CodecOpen(pVp8Enc, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    Exynos_SetPlaneToPort(pOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+
+    Exynos_OSAL_SemaphoreCreate(&pInputPort->codecSemID);
+    Exynos_OSAL_QueueCreate(&pInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pVp8Enc->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pVp8Enc->hSourceStartEvent);
+    pVp8Enc->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pVp8Enc->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pVp8Enc->hDestinationOutStartEvent);
+
+    Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pVp8Enc->hMFCVp8Handle.indexTimestamp       = 0;
+    pVp8Enc->hMFCVp8Handle.outputIndexTimestamp = 0;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pVp8Enc->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+
+    pVideoEnc->csc_handle = csc_init(csc_method);
+    if (pVideoEnc->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVideoEnc->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_VP8Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
+    EXYNOS_OMX_BASEPORT           *pInputPort           = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_VP8ENC_HANDLE          *pVp8Enc              = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    FunctionIn();
+
+    if (pVideoEnc->csc_handle != NULL) {
+        csc_deinit(pVideoEnc->csc_handle);
+        pVideoEnc->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pVp8Enc->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pVp8Enc->hDestinationInStartEvent);
+    pVp8Enc->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pVp8Enc->hDestinationOutStartEvent);
+    pVp8Enc->hDestinationOutStartEvent = NULL;
+    pVp8Enc->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pVp8Enc->hSourceStartEvent);
+    pVp8Enc->hSourceStartEvent = NULL;
+    pVp8Enc->bSourceStart = OMX_FALSE;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pOutputPort->codecSemID);
+        pOutputPort->codecSemID = NULL;
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+    } else if (pInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_OSAL_QueueTerminate(&pInputPort->codecBufferQ);
+    Exynos_OSAL_SemaphoreTerminate(pInputPort->codecSemID);
+    pInputPort->codecSemID = NULL;
+
+    VP8CodecClose(pVp8Enc);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_SrcIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8ENC_HANDLE          *pVp8Enc          = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle       = pVp8Enc->hMFCVp8Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort       = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_COLOR_FORMATTYPE           inputColorFormat = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncOps       *pEncOps     = pVp8Enc->hMFCVp8Handle.pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps   = pVp8Enc->hMFCVp8Handle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]   = {0, 0, 0};
+    int i, nPlaneCnt, nConfigCnt;
+
+    FunctionIn();
+
+    if (pVp8Enc->hMFCVp8Handle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = VP8CodecSrcSetup(pOMXComponent, pSrcInputData);
+        if ((ret != OMX_ErrorNone) ||
+            ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VP8CodecSrcSetup(0x%x)",
+                                                pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+    }
+
+    if (pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst == OMX_FALSE) {
+        ret = VP8CodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VP8CodecDstSetup(0x%x)",
+                                                pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+    }
+
+    nConfigCnt = Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ);
+    if (nConfigCnt > 0) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] has config message(%d)", pExynosComponent, __FUNCTION__, nConfigCnt);
+        while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+            Change_VP8Enc_Param(pExynosComponent);
+        }
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] all config messages were handled", pExynosComponent, __FUNCTION__);
+    }
+
+    if ((pSrcInputData->dataLen > 0) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+        pExynosComponent->timeStamp[pVp8Enc->hMFCVp8Handle.indexTimestamp]              = pSrcInputData->timeStamp;
+        pExynosComponent->bTimestampSlotUsed[pVp8Enc->hMFCVp8Handle.indexTimestamp]     = OMX_TRUE;
+        pExynosComponent->nFlags[pVp8Enc->hMFCVp8Handle.indexTimestamp]                 = pSrcInputData->nFlags;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), Tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pVp8Enc->hMFCVp8Handle.indexTimestamp);
+        pEncOps->Set_FrameTag(hMFCHandle, pVp8Enc->hMFCVp8Handle.indexTimestamp);
+        pVp8Enc->hMFCVp8Handle.indexTimestamp++;
+        pVp8Enc->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP;
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        inputColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+        if ((pVideoEnc->eRotationType == ROTATE_0) ||
+            (pVideoEnc->eRotationType == ROTATE_180)) {
+            Exynos_OSAL_GetPlaneSize(inputColorFormat,
+                                     pInputPort->ePlaneType,
+                                     pInputPort->portDefinition.format.video.nFrameWidth,
+                                     pInputPort->portDefinition.format.video.nFrameHeight,
+                                     nDataLen,
+                                     nAllocLen);
+        } else {
+            Exynos_OSAL_GetPlaneSize(inputColorFormat,
+                                     pInputPort->ePlaneType,
+                                     pInputPort->portDefinition.format.video.nFrameHeight,
+                                     pInputPort->portDefinition.format.video.nFrameWidth,
+                                     nDataLen,
+                                     nAllocLen);
+        }
+
+        if (pInputPort->bufferProcessType == BUFFER_COPY) {
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        } else {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        }
+
+        nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+        if (pVideoEnc->nInbufSpareSize > 0) {
+            for (i = 0; i < nPlaneCnt; i++)
+                nAllocLen[i] = nAllocLen[i] + pVideoEnc->nInbufSpareSize;
+        }
+
+        if (pSrcInputData->dataLen == 0) {
+            for (i = 0; i < nPlaneCnt; i++)
+                nDataLen[i] = 0;
+        }
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                    (void **)pSrcInputData->buffer.addr,
+                                    (unsigned long *)pSrcInputData->buffer.fd,
+                                    nAllocLen,
+                                    nDataLen,
+                                    nPlaneCnt,
+                                    pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+            goto EXIT;
+        }
+
+        VP8CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+
+        if (pVp8Enc->bSourceStart == OMX_FALSE) {
+            pVp8Enc->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pVp8Enc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        if ((pVp8Enc->bDestinationStart == OMX_FALSE) &&
+            (pVp8Enc->hMFCVp8Handle.bConfiguredMFCSrc == OMX_TRUE)) {
+            pVp8Enc->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pVp8Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pVp8Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_SrcOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8ENC_HANDLE          *pVp8Enc          = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle       = pVp8Enc->hMFCVp8Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pInbufOps      = pVp8Enc->hMFCVp8Handle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->allocSize     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->pPrivate = NULL;
+    } else {
+        int plane = 0, nPlaneCnt;
+        nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+        for (plane = 0; plane < nPlaneCnt; plane++) {
+            pSrcOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+            pSrcOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+            pSrcOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        }
+
+        if (pInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] ==
+                        pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) {
+                    pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_DstIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8ENC_HANDLE          *pVp8Enc              = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle           = pVp8Enc->hMFCVp8Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pOutbufOps  = pVp8Enc->hMFCVp8Handle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0};
+    unsigned int nDataLen[VIDEO_BUFFER_MAX_PLANES]  = {0, 0, 0};
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    nAllocLen[0] = pOutputPort->portDefinition.nBufferSize;
+    if ((pOutputPort->bufferProcessType & BUFFER_COPY) ||
+        (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        /* OMX buffer is not used directly : CODEC buffer or MetaData */
+        nAllocLen[0] = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth * pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)&pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pOutputPort),
+                                pDstInputData->bufferHeader);
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                            pExynosComponent, __FUNCTION__, codecReturn);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+        goto EXIT;
+    }
+
+    VP8CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_DstOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8ENC_HANDLE          *pVp8Enc              = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    void                          *hMFCHandle           = pVp8Enc->hMFCVp8Handle.hMFCHandle;
+
+    ExynosVideoEncOps           *pEncOps        = pVp8Enc->hMFCVp8Handle.pEncOps;
+    ExynosVideoEncBufferOps     *pOutbufOps     = pVp8Enc->hMFCVp8Handle.pOutbufOps;
+    ExynosVideoBuffer           *pVideoBuffer   = NULL;
+    ExynosVideoBuffer            videoBuffer;
+    ExynosVideoErrorType         codecReturn    = VIDEO_ERROR_NONE;
+
+    OMX_S32 indexTimestamp = 0;
+
+    FunctionIn();
+
+    if (pVp8Enc->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+    if (codecReturn == VIDEO_ERROR_NONE) {
+        pVideoBuffer = &videoBuffer;
+    } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO)", pExynosComponent, __FUNCTION__);
+        pVideoBuffer = NULL;
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    } else {
+        pVideoBuffer = NULL;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pVp8Enc->hMFCVp8Handle.outputIndexTimestamp++;
+    pVp8Enc->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+    pDstOutputData->buffer.addr[0]  = pVideoBuffer->planes[0].addr;
+    pDstOutputData->buffer.fd[0]    = pVideoBuffer->planes[0].fd;
+
+    pDstOutputData->allocSize       = pVideoBuffer->planes[0].allocSize;
+    pDstOutputData->dataLen         = pVideoBuffer->planes[0].dataSize;
+    pDstOutputData->remainDataLen   = pVideoBuffer->planes[0].dataSize;
+    pDstOutputData->usedDataLen     = 0;
+
+    pDstOutputData->pPrivate        = pVideoBuffer;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+            goto EXIT;
+        }
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+    if (pVideoEnc->bFirstOutput == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] codec specific data is generated", pExynosComponent, __FUNCTION__);
+        pDstOutputData->timeStamp   = 0;
+        pDstOutputData->nFlags     |= OMX_BUFFERFLAG_CODECCONFIG;
+        pDstOutputData->nFlags     |= OMX_BUFFERFLAG_ENDOFFRAME;
+        pVideoEnc->bFirstOutput     = OMX_TRUE;
+    } else {
+        indexTimestamp = pEncOps->Get_FrameTag(pVp8Enc->hMFCVp8Handle.hMFCHandle);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Tag(%d) is invalid. changes to use outputIndexTimestamp(%d)",
+                                                  pExynosComponent, __FUNCTION__,
+                                                  indexTimestamp, pVp8Enc->hMFCVp8Handle.outputIndexTimestamp);
+            indexTimestamp = pVp8Enc->hMFCVp8Handle.outputIndexTimestamp;
+        }
+
+        /* In case of Video buffer batch mode, use timestamp from MFC device driver */
+        if (pVideoBuffer->timestamp != 0)
+            pDstOutputData->timeStamp = pVideoBuffer->timestamp;
+        else
+            pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
+
+        pExynosComponent->bTimestampSlotUsed[indexTimestamp]    = OMX_FALSE;
+        pDstOutputData->nFlags                                  = pExynosComponent->nFlags[indexTimestamp];
+        pDstOutputData->nFlags                                 |= OMX_BUFFERFLAG_ENDOFFRAME;
+    }
+
+    if (pVideoBuffer->frameType == VIDEO_FRAME_I)
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, frameType: %d, dataLen: %d, timestamp %lld us (%.2f secs), Tag: %d",
+                                            pExynosComponent, __FUNCTION__,
+                                            pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                            pVideoBuffer->frameType, pDstOutputData->dataLen,
+                                            pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                            indexTimestamp);
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] got end of stream", pExynosComponent, __FUNCTION__);
+
+        if (pExynosComponent->bBehaviorEOS == OMX_FALSE)
+            pDstOutputData->remainDataLen = 0;
+        else
+            pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_srcInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT         *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pInputPort)) ||
+        (!CHECK_PORT_POPULATED(pInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_VP8Enc_SrcIn(pOMXComponent, pSrcInputData);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_srcOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc            = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pInputPort)) ||
+        (!CHECK_PORT_POPULATED(pInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    if ((pVp8Enc->bSourceStart == OMX_FALSE) &&
+        (!CHECK_PORT_BEING_FLUSHED(pInputPort))) {
+        Exynos_OSAL_SignalWait(pVp8Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp8Enc->hSourceStartEvent);
+    }
+
+    ret = Exynos_VP8Enc_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_dstInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc            = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVp8Enc->bDestinationStart == OMX_FALSE) &&
+        (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+        Exynos_OSAL_SignalWait(pVp8Enc->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp8Enc->hDestinationInStartEvent);
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pVp8Enc->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pVp8Enc->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    if (pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_VP8Enc_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP8Enc_dstOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc            = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVp8Enc->bDestinationStart == OMX_FALSE) &&
+        (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+        Exynos_OSAL_SignalWait(pVp8Enc->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp8Enc->hDestinationOutStartEvent);
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pVp8Enc->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pVp8Enc->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_VP8Enc_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE hComponent,
+    OMX_STRING     componentName)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_VP8ENC_HANDLE          *pVp8Enc          = NULL;
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP8_ENC, componentName) != 0) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = HW_VIDEO_ENC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pVp8Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_VP8ENC_HANDLE));
+    if (pVp8Enc == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pVp8Enc, 0, sizeof(EXYNOS_VP8ENC_HANDLE));
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pVp8Enc;
+    pVp8Enc->qpRangeI.nMinQP = 2;   /* index = 2, value = 2 */
+    pVp8Enc->qpRangeI.nMaxQP = 63;  /* index = 63, value = 127 */
+    pVp8Enc->qpRangeP.nMinQP = 2;   /* index = 2, value = 2 */;
+    pVp8Enc->qpRangeP.nMaxQP = 63;  /* index = 63, value = 127 */
+
+    pVideoEnc->quantization.nQpI = 37;
+    pVideoEnc->quantization.nQpP = 40;
+    pVideoEnc->quantization.nQpB = 40;
+
+    Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_VP8_ENC);
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth  = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth  = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride = 0;
+    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
+    pExynosPort->portWayType = WAY2_PORT;
+    pExynosPort->ePlaneType = PLANE_SINGLE;
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pVp8Enc->VP8Component[i], OMX_VIDEO_PARAM_VP8TYPE);
+        pVp8Enc->VP8Component[i].nPortIndex = i;
+        pVp8Enc->VP8Component[i].eProfile   = OMX_VIDEO_VP8ProfileMain;
+        pVp8Enc->VP8Component[i].eLevel     = OMX_VIDEO_VP8Level_Version0;
+    }
+    pVp8Enc->nPFrames = -1;  /* for GTS issue */
+
+    Exynos_OSAL_Memset(&pVp8Enc->AndroidVp8EncoderType, 0, sizeof(OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE));
+    INIT_SET_SIZE_VERSION(&pVp8Enc->AndroidVp8EncoderType, OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE);
+    pVp8Enc->AndroidVp8EncoderType.nKeyFrameInterval    = pVp8Enc->nPFrames + 1;
+    pVp8Enc->AndroidVp8EncoderType.eTemporalPattern     = OMX_VIDEO_VPXTemporalLayerPatternNone;
+    pVp8Enc->AndroidVp8EncoderType.nTemporalLayerCount  = 1;
+    for (i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++)
+        pVp8Enc->AndroidVp8EncoderType.nTemporalLayerBitrateRatio[i] = 100;
+
+    pVp8Enc->AndroidVp8EncoderType.nMinQuantizer = pVp8Enc->qpRangeI.nMinQP;
+    pVp8Enc->AndroidVp8EncoderType.nMaxQuantizer = pVp8Enc->qpRangeI.nMaxQP;
+
+    pOMXComponent->GetParameter      = &Exynos_VP8Enc_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_VP8Enc_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_VP8Enc_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_VP8Enc_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_VP8Enc_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_VP8Enc_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_VP8Enc_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_VP8Enc_Terminate;
+
+    pVideoEnc->exynos_codec_srcInputProcess  = &Exynos_VP8Enc_srcInputBufferProcess;
+    pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_VP8Enc_srcOutputBufferProcess;
+    pVideoEnc->exynos_codec_dstInputProcess  = &Exynos_VP8Enc_dstInputBufferProcess;
+    pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_VP8Enc_dstOutputBufferProcess;
+
+    pVideoEnc->exynos_codec_start            = &VP8CodecStart;
+    pVideoEnc->exynos_codec_stop             = &VP8CodecStop;
+    pVideoEnc->exynos_codec_bufferProcessRun = &VP8CodecOutputBufferProcessRun;
+    pVideoEnc->exynos_codec_enqueueAllBuffer = &VP8CodecEnqueueAllBuffer;
+
+    pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+
+    pVideoEnc->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
+
+    pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoEnc->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pVp8Enc);
+        pVp8Enc = pVideoEnc->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVp8Enc->hMFCVp8Handle.videoInstInfo.eCodecType = VIDEO_CODING_VP8;
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        pVp8Enc->hMFCVp8Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pVp8Enc->hMFCVp8Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pVp8Enc->hMFCVp8Handle.videoInstInfo), VIDEO_FALSE /* enc */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Failed to GetInstInfo", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pVp8Enc);
+        pVp8Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for enc : ext(%d)/temporal-svc(%d)/qp-range(%d)/pvc(%d)",
+            pExynosComponent, __FUNCTION__,
+            (pVp8Enc->hMFCVp8Handle.videoInstInfo.supportInfo.enc.nSpareSize),
+            (pVp8Enc->hMFCVp8Handle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport),
+            (pVp8Enc->hMFCVp8Handle.videoInstInfo.supportInfo.enc.bQpRangePBSupport),
+            (pVp8Enc->hMFCVp8Handle.videoInstInfo.supportInfo.enc.bPVCSupport));
+
+    if (pVp8Enc->hMFCVp8Handle.videoInstInfo.supportInfo.enc.nSpareSize > 0)
+        pVideoEnc->nInbufSpareSize = pVp8Enc->hMFCVp8Handle.videoInstInfo.supportInfo.enc.nSpareSize;
+
+    Exynos_Input_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_AddVendorExt(hComponent, "sec-ext-enc-qp-range", (OMX_INDEXTYPE)OMX_IndexConfigVideoQPRange);
+#endif
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_VP8ENC_HANDLE            *pVp8Enc            = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp8Enc != NULL) {
+        Exynos_OSAL_Free(pVp8Enc);
+        pVp8Enc = pVideoEnc->hCodecHandle = NULL;
+    }
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_DelVendorExts(hComponent);
+#endif
+
+    ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/enc/vp8/Exynos_OMX_Vp8enc.h b/openmax/component/video/enc/vp8/Exynos_OMX_Vp8enc.h
new file mode 100755 (executable)
index 0000000..67d61bd
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Vp8enc.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2013.02.14 : Create
+ */
+
+#ifndef EXYNOS_OMX_VP8_ENC_COMPONENT
+#define EXYNOS_OMX_VP8_ENC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+
+#include "ExynosVideoApi.h"
+
+typedef struct _EXYNOS_MFC_VP8ENC_HANDLE
+{
+    OMX_HANDLETYPE  hMFCHandle;
+
+    OMX_U32     indexTimestamp;
+    OMX_U32     outputIndexTimestamp;
+    OMX_BOOL    bConfiguredMFCSrc;
+    OMX_BOOL    bConfiguredMFCDst;
+
+    ExynosVideoEncOps           *pEncOps;
+    ExynosVideoEncBufferOps     *pInbufOps;
+    ExynosVideoEncBufferOps     *pOutbufOps;
+    ExynosVideoEncParam          encParam;
+    ExynosVideoInstInfo          videoInstInfo;
+
+    #define MAX_PROFILE_NUM 1
+    OMX_VIDEO_VP8PROFILETYPE   profiles[MAX_PROFILE_NUM];
+    OMX_S32                    nProfileCnt;
+    OMX_VIDEO_VP8LEVELTYPE     maxLevel;
+} EXYNOS_MFC_VP8ENC_HANDLE;
+
+typedef struct _EXYNOS_VP8ENC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_VP8TYPE             VP8Component[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+    OMX_U32                             nPFrames;  /* IDR period control */
+    OMX_VIDEO_QPRANGE                   qpRangeI;
+    OMX_VIDEO_QPRANGE                   qpRangeP;
+
+    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE  AndroidVp8EncoderType;
+
+    /* SEC MFC Codec specific */
+    EXYNOS_MFC_VP8ENC_HANDLE hMFCVp8Handle;
+
+    OMX_BOOL        bSourceStart;
+    OMX_BOOL        bDestinationStart;
+    OMX_HANDLETYPE  hSourceStartEvent;
+    OMX_HANDLETYPE  hDestinationInStartEvent;
+    OMX_HANDLETYPE  hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE    bypassBufferInfoQ;
+} EXYNOS_VP8ENC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName);
+                OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/enc/vp8/Makefile.am b/openmax/component/video/enc/vp8/Makefile.am
new file mode 100755 (executable)
index 0000000..9fdd3c5
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libOMX.Exynos.VP8.Encoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_VP8_Encoder_la_SOURCES = Exynos_OMX_Vp8enc.c \
+                                       library_register.c
+
+libOMX_Exynos_VP8_Encoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                      $(top_builddir)/openmax/component/video/enc/libExynosOMX_Venc.la \
+                                      $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+libOMX_Exynos_VP8_Encoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                      -I$(top_srcdir)/openmax/include/exynos \
+                                      -I$(top_srcdir)/openmax/osal \
+                                      -I$(top_srcdir)/openmax/core \
+                                      -I$(top_srcdir)/openmax/component/common \
+                                      -I$(top_srcdir)/openmax/component/video/enc \
+                                      -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_VP8_Encoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF -DUSE_VP8_SUPPORT
+libOMX_Exynos_VP8_Encoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable -Wno-unused-function
+
+libOMX_Exynos_VP8_Encoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/enc/vp8/library_register.c b/openmax/component/video/enc/vp8/library_register.c
new file mode 100755 (executable)
index 0000000..ccd44f7
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2013.02.14 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VP8_ENC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent)
+{
+    FunctionIn();
+
+    if (ppExynosComponent == NULL)
+        goto EXIT;
+
+    /* component 1 - video encoder VP8 */
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_VP8_ENC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_VP8_ENC_ROLE);
+    ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
diff --git a/openmax/component/video/enc/vp8/library_register.h b/openmax/component/video/enc/vp8/library_register.h
new file mode 100755 (executable)
index 0000000..d0a3090
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2013.02.14 : Create
+ */
+
+#ifndef EXYNOS_OMX_VP8_ENC_REG
+#define EXYNOS_OMX_VP8_ENC_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM       1
+#define MAX_COMPONENT_ROLE_NUM  1
+
+/* VP8 */
+#define EXYNOS_OMX_COMPONENT_VP8_ENC      "OMX.Exynos.VP8.Encoder"
+#define EXYNOS_OMX_COMPONENT_VP8_ENC_ROLE "video_encoder.vp8"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
diff --git a/openmax/component/video/enc/vp9/Exynos_OMX_Vp9enc.c b/openmax/component/video/enc/vp9/Exynos_OMX_Vp9enc.c
new file mode 100755 (executable)
index 0000000..2a6267c
--- /dev/null
@@ -0,0 +1,3103 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Vp9enc.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2015.04.14 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Venc.h"
+#include "Exynos_OMX_VencControl.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Vp9enc.h"
+#include "Exynos_OSAL_SharedMemory.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OSAL_Queue.h"
+
+#include "Exynos_OSAL_Platform.h"
+
+/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
+/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
+#include "csc.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VP9_ENC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+#define VP9_QP_INDEX_RANGE 64
+
+static OMX_ERRORTYPE SetProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc        = NULL;
+
+    int nProfileCnt = 0;
+    int nLevelCnt = 0;
+
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp9Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Enc->hMFCVp9Handle.profiles[nProfileCnt++] = OMX_VIDEO_VP9Profile0;
+    pVp9Enc->hMFCVp9Handle.nProfileCnt = nProfileCnt;
+
+    switch (pVp9Enc->hMFCVp9Handle.videoInstInfo.HwVersion) {
+    case MFC_1220:
+    case MFC_120:
+        pVp9Enc->hMFCVp9Handle.maxLevel = OMX_VIDEO_VP9Level51;
+        break;
+    default:
+        pVp9Enc->hMFCVp9Handle.maxLevel = OMX_VIDEO_VP9Level41;
+        break;
+    }
+
+EXIT:
+    return ret;
+}
+
+static OMX_ERRORTYPE GetIndexToProfileLevel(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    OMX_ERRORTYPE                    ret           = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc     = NULL;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc       = NULL;
+
+    OMX_U32 nMaxIndex = 0;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp9Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef USE_ANDROID
+    if (pVp9Enc->hMFCVp9Handle.nProfileCnt <= (int)pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pVp9Enc->hMFCVp9Handle.profiles[pProfileLevelType->nProfileIndex];
+    pProfileLevelType->eLevel   = pVp9Enc->hMFCVp9Handle.maxLevel;
+#else
+    while ((pVp9Enc->hMFCVp9Handle.maxLevel >> nLevelCnt) > 0) {
+        nLevelCnt++;
+    }
+
+    if ((pVp9Enc->hMFCVp9Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    nMaxIndex = pVp9Enc->hMFCVp9Handle.nProfileCnt * nLevelCnt;
+    if (nMaxIndex <= pProfileLevelType->nProfileIndex) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    pProfileLevelType->eProfile = pVp9Enc->hMFCVp9Handle.profiles[pProfileLevelType->nProfileIndex / nLevelCnt];
+    pProfileLevelType->eLevel = 0x1 << (pProfileLevelType->nProfileIndex % nLevelCnt);
+#endif
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : supported profile(%x), level(%x)",
+                                            pExynosComponent, __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+    return ret;
+}
+
+static OMX_BOOL CheckProfileLevelSupport(
+    EXYNOS_OMX_BASECOMPONENT         *pExynosComponent,
+    OMX_VIDEO_PARAM_PROFILELEVELTYPE *pProfileLevelType)
+{
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc  = NULL;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc    = NULL;
+
+    OMX_BOOL bProfileSupport = OMX_FALSE;
+    OMX_BOOL bLevelSupport   = OMX_FALSE;
+
+    int nLevelCnt = 0;
+    int i;
+
+    FunctionIn();
+
+    if ((pExynosComponent == NULL) ||
+        (pProfileLevelType == NULL)) {
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp9Enc == NULL)
+        goto EXIT;
+
+    while ((pVp9Enc->hMFCVp9Handle.maxLevel >> nLevelCnt++) > 0);
+
+    if ((pVp9Enc->hMFCVp9Handle.nProfileCnt == 0) ||
+        (nLevelCnt == 0)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] : there is no any profile/level",
+                                            pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    for (i = 0; i < pVp9Enc->hMFCVp9Handle.nProfileCnt; i++) {
+        if (pVp9Enc->hMFCVp9Handle.profiles[i] == pProfileLevelType->eProfile) {
+            bProfileSupport = OMX_TRUE;
+            break;
+        }
+    }
+
+    if (bProfileSupport != OMX_TRUE)
+        goto EXIT;
+
+    while (nLevelCnt >= 0) {
+        if ((int)pProfileLevelType->eLevel == (0x1 << nLevelCnt)) {
+            bLevelSupport = OMX_TRUE;
+            break;
+        }
+
+        nLevelCnt--;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : profile(%x)/level(%x) is %ssupported", pExynosComponent, __FUNCTION__,
+                                            pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+                                            (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+    return (bProfileSupport && bLevelSupport);
+}
+
+static OMX_U32 OMXVP9ProfileToProfileIDC(OMX_VIDEO_VP9PROFILETYPE eProfile)
+{
+    OMX_U32 ret;
+
+    switch (eProfile) {
+    case OMX_VIDEO_VP9Profile0:
+        ret = 0;
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+
+    return ret;
+}
+
+static OMX_U32 OMXVP9LevelToMFCVersion(OMX_VIDEO_VP9LEVELTYPE eLevel)
+{
+    OMX_U32 ret;
+
+    /* refer to UM, MFC supports only 0 value */
+    switch (eLevel) {
+    case OMX_VIDEO_VP9Level1:
+    case OMX_VIDEO_VP9Level11:
+    case OMX_VIDEO_VP9Level2:
+    case OMX_VIDEO_VP9Level21:
+    case OMX_VIDEO_VP9Level3:
+    case OMX_VIDEO_VP9Level31:
+    case OMX_VIDEO_VP9Level4:
+    case OMX_VIDEO_VP9Level41:
+        ret = 0;
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+
+    return ret;
+}
+
+static void Print_VP9Enc_Param(ExynosVideoEncParam *pEncParam)
+{
+    ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam;
+    ExynosVideoEncVp9Param    *pVp9Param    = &pEncParam->codecParam.vp9;
+
+    /* common parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceWidth             : %d", pCommonParam->SourceWidth);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SourceHeight            : %d", pCommonParam->SourceHeight);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "IDRPeriod               : %d", pCommonParam->IDRPeriod);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SliceMode               : %d", pCommonParam->SliceMode);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "RandomIntraMBRefresh    : %d", pCommonParam->RandomIntraMBRefresh);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Bitrate                 : %d", pCommonParam->Bitrate);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp                 : %d", pCommonParam->FrameQp);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameQp_P               : %d", pCommonParam->FrameQp_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(I) ranege            : %d / %d", pCommonParam->QpRange.QpMin_I, pCommonParam->QpRange.QpMax_I);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "QP(P) ranege            : %d / %d", pCommonParam->QpRange.QpMin_P, pCommonParam->QpRange.QpMax_P);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "PadControlOn            : %d", pCommonParam->PadControlOn);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "LumaPadVal              : %d", pCommonParam->LumaPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CbPadVal                : %d", pCommonParam->CbPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "CrPadVal                : %d", pCommonParam->CrPadVal);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameMap                : %d", pCommonParam->FrameMap);
+
+    /* Vp9 specific parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "FrameRate               : %d", pVp9Param->FrameRate);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Vp9Version              : %d", pVp9Param->Vp9Version);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "Vp9GoldenFrameSel       : %d", pVp9Param->Vp9GoldenFrameSel);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "Vp9GFRefreshPeriod      : %d", pVp9Param->Vp9GFRefreshPeriod);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "RefNumberForPFrame      : %d", pVp9Param->RefNumberForPFrame);
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,     "MaxPartitionDepth       : %d", pVp9Param->MaxPartitionDepth);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumTemporalLayer        : %d", pVp9Param->TemporalSVC.nTemporalLayerCount);
+
+    /* rate control related parameters */
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableFRMRateControl    : %d", pCommonParam->EnableFRMRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "EnableMBRateControl     : %d", pCommonParam->EnableMBRateControl);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CBRPeriodRf             : %d", pCommonParam->CBRPeriodRf);
+}
+
+static void Set_VP9Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_BASEPORT           *pInputPort       = NULL;
+    EXYNOS_OMX_BASEPORT           *pOutputPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_VP9ENC_HANDLE          *pVp9Enc          = NULL;
+    EXYNOS_MFC_VP9ENC_HANDLE      *pMFCVp9Handle    = NULL;
+    OMX_COLOR_FORMATTYPE           eColorFormat     = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncParam       *pEncParam    = NULL;
+    ExynosVideoEncCommonParam *pCommonParam = NULL;
+    ExynosVideoEncVp9Param    *pVp9Param    = NULL;
+
+    int i;
+
+    pVideoEnc       = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVp9Enc         = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCVp9Handle   = &pVp9Enc->hMFCVp9Handle;
+    pInputPort      = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pOutputPort     = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pEncParam       = &pMFCVp9Handle->encParam;
+    pCommonParam    = &pEncParam->commonParam;
+    pVp9Param       = &pEncParam->codecParam.vp9;
+
+    pEncParam->eCompressionFormat = VIDEO_CODING_VP9;
+
+    /* common parameters */
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+    } else {
+        pCommonParam->SourceWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        pCommonParam->SourceHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+    }
+    pCommonParam->IDRPeriod    = pVp9Enc->nPFrames + 1;
+    pCommonParam->SliceMode    = 0;
+    pCommonParam->Bitrate      = pOutputPort->portDefinition.format.video.nBitrate;
+    pCommonParam->FrameQp      = pVideoEnc->quantization.nQpI;
+    pCommonParam->FrameQp_P    = pVideoEnc->quantization.nQpP;
+
+    pCommonParam->QpRange.QpMin_I = pVp9Enc->qpRangeI.nMinQP;
+    pCommonParam->QpRange.QpMax_I = pVp9Enc->qpRangeI.nMaxQP;
+    pCommonParam->QpRange.QpMin_P = pVp9Enc->qpRangeP.nMinQP;
+    pCommonParam->QpRange.QpMax_P = pVp9Enc->qpRangeP.nMaxQP;
+
+    pCommonParam->PadControlOn = 0;    /* 0: Use boundary pixel, 1: Use the below setting value */
+    pCommonParam->LumaPadVal   = 0;
+    pCommonParam->CbPadVal     = 0;
+    pCommonParam->CrPadVal     = 0;
+
+    if (pVideoEnc->intraRefresh.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) {
+        /* Cyclic Mode */
+        pCommonParam->RandomIntraMBRefresh = pVideoEnc->intraRefresh.nCirMBs;
+    } else {
+        /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+        pCommonParam->RandomIntraMBRefresh = 0;
+    }
+
+    /* Perceptual Mode */
+    pCommonParam->PerceptualMode = (pVideoEnc->bPVCMode)? VIDEO_TRUE:VIDEO_FALSE;
+
+    eColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+    pCommonParam->FrameMap = Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    /* Vp9 specific parameters */
+    pVp9Param->Vp9Version = OMXVP9LevelToMFCVersion(pVp9Enc->VP9Component[OUTPUT_PORT_INDEX].eLevel);
+    pVp9Param->FrameRate = (pInputPort->portDefinition.format.video.xFramerate) >> 16;
+    if (pVp9Param->FrameRate <= 0)
+        pVp9Param->FrameRate = 30;  /* default : 30fps, zero means that DynamicFramerateChange mode is set */
+
+    /* there is no interface at OMX IL component */
+    pVp9Param->RefNumberForPFrame       = 2;
+
+    pVp9Param->Vp9GoldenFrameSel        = 0;
+    pVp9Param->Vp9GFRefreshPeriod       = 30;
+    pVp9Param->MaxPartitionDepth        = 1;
+
+    /* Temporal SVC */
+    pVp9Param->TemporalSVC.nTemporalLayerCount = (unsigned int)pVp9Enc->AndroidVp9EncoderType.nTemporalLayerCount;
+    pVp9Param->TemporalSVC.nTemporalLayerBitrateRatio[0] = (unsigned int)(pOutputPort->portDefinition.format.video.nBitrate *
+                                                                          pVp9Enc->AndroidVp9EncoderType.nTemporalLayerBitrateRatio[0] / 100);
+    for (i = 1; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
+        pVp9Param->TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)(pOutputPort->portDefinition.format.video.nBitrate *
+                                                                              (pVp9Enc->AndroidVp9EncoderType.nTemporalLayerBitrateRatio[i] -
+                                                                               pVp9Enc->AndroidVp9EncoderType.nTemporalLayerBitrateRatio[i - 1])
+                                                                              / 100);
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eControlRate: 0x%x", pExynosComponent, __FUNCTION__, pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]);
+    /* rate control related parameters */
+    switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) {
+    case OMX_Video_ControlRateDisable:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR");
+        pCommonParam->EnableFRMRateControl = 0;    /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 0;    /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 200;
+        break;
+    case OMX_Video_ControlRateConstant:
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 9;
+        break;
+    case OMX_Video_ControlRateVariable:
+    default: /*Android default */
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR");
+        pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable, 1: Frame level RC */
+        pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable, 1:MB level RC */
+        pCommonParam->CBRPeriodRf          = 200;
+        break;
+    }
+
+//    Print_VP9Enc_Param(pEncParam);
+}
+
+static void Change_VP9Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = NULL;
+    EXYNOS_VP9ENC_HANDLE          *pVp9Enc           = NULL;
+    EXYNOS_MFC_VP9ENC_HANDLE      *pMFCVp9Handle     = NULL;
+    OMX_PTR                        pDynamicConfigCMD = NULL;
+    OMX_PTR                        pConfigData       = NULL;
+    OMX_S32                        nCmdIndex         = 0;
+    ExynosVideoEncOps             *pEncOps           = NULL;
+    int                            nValue            = 0;
+
+    int i;
+
+    pVideoEnc       = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVp9Enc         = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCVp9Handle   = &pVp9Enc->hMFCVp9Handle;
+    pEncOps         = pMFCVp9Handle->pEncOps;
+
+    pDynamicConfigCMD = (OMX_PTR)Exynos_OSAL_Dequeue(&pExynosComponent->dynamicConfigQ);
+    if (pDynamicConfigCMD == NULL)
+        goto EXIT;
+
+    nCmdIndex   = *(OMX_S32 *)pDynamicConfigCMD;
+    pConfigData = (OMX_PTR)((OMX_U8 *)pDynamicConfigCMD + sizeof(OMX_S32));
+
+    switch ((int)nCmdIndex) {
+    case OMX_IndexConfigVideoIntraVOPRefresh:
+    {
+        nValue = VIDEO_FRAME_I;
+        pEncOps->Set_FrameType(pMFCVp9Handle->hMFCHandle, nValue);
+        pVideoEnc->IntraRefreshVOP = OMX_FALSE;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] VOP Refresh", pExynosComponent, __FUNCTION__);
+    }
+        break;
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        OMX_S32 nPFrames = (*((OMX_U32 *)pConfigData)) - 1;
+        nValue = nPFrames + 1;
+        pEncOps->Set_IDRPeriod(pMFCVp9Handle->hMFCHandle, nValue);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] IDR period: %d", pExynosComponent, __FUNCTION__, nValue);
+    }
+        break;
+    case OMX_IndexConfigVideoBitrate:
+    {
+        OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pConfigData;
+
+        if (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] != OMX_Video_ControlRateDisable) {
+            /* bitrate : main */
+            nValue = pConfigBitrate->nEncodeBitrate;
+            pEncOps->Set_BitRate(pMFCVp9Handle->hMFCHandle, nValue);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bitrate: %d", pExynosComponent, __FUNCTION__, nValue);
+            /* bitrate : layer */
+            TemporalLayerShareBuffer TemporalSVC;
+            Exynos_OSAL_Memset(&TemporalSVC, 0, sizeof(TemporalLayerShareBuffer));
+            TemporalSVC.nTemporalLayerCount = (unsigned int)pVp9Enc->AndroidVp9EncoderType.nTemporalLayerCount;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "nTemporalLayerCount     : %d", TemporalSVC.nTemporalLayerCount);
+            TemporalSVC.nTemporalLayerBitrateRatio[0] = (unsigned int)(pConfigBitrate->nEncodeBitrate *
+                                                                   pVp9Enc->AndroidVp9EncoderType.nTemporalLayerBitrateRatio[0] / 100);
+            for (i = 1; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
+                TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)(pConfigBitrate->nEncodeBitrate *
+                                                                           (pVp9Enc->AndroidVp9EncoderType.nTemporalLayerBitrateRatio[i] -
+                                                                            pVp9Enc->AndroidVp9EncoderType.nTemporalLayerBitrateRatio[i - 1])
+                                                                           / 100);
+                Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "nTempBitrateRatio[%d]   : %d", i, TemporalSVC.nTemporalLayerBitrateRatio[i]);
+            }
+            pEncOps->Set_LayerChange(pMFCVp9Handle->hMFCHandle, TemporalSVC);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoFramerate:
+    {
+        OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pConfigData;
+        OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
+
+        if (nPortIndex == INPUT_PORT_INDEX) {
+            nValue = (pConfigFramerate->xEncodeFramerate) >> 16;
+            pEncOps->Set_FrameRate(pMFCVp9Handle->hMFCHandle, nValue);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] framerate: %d", pExynosComponent, __FUNCTION__, nValue);
+        }
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange = (OMX_VIDEO_QPRANGETYPE *)pConfigData;
+        ExynosVideoQPRange     qpRange;
+
+        Exynos_OSAL_Memset(&qpRange, 0, sizeof(ExynosVideoQPRange));
+
+        qpRange.QpMin_I = pQpRange->qpRangeI.nMinQP;
+        qpRange.QpMax_I = pQpRange->qpRangeI.nMaxQP;
+        qpRange.QpMin_P = pQpRange->qpRangeP.nMinQP;
+        qpRange.QpMax_P = pQpRange->qpRangeP.nMaxQP;
+
+        pEncOps->Set_QpRange(pMFCVp9Handle->hMFCHandle, qpRange);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qp range: I(%d, %d), P(%d, %d)",
+                                    pExynosComponent, __FUNCTION__,
+                                    qpRange.QpMin_I, qpRange.QpMax_I,
+                                    qpRange.QpMin_P, qpRange.QpMax_P);
+    }
+        break;
+    case OMX_IndexConfigOperatingRate:
+    {
+        OMX_PARAM_U32TYPE *pConfigRate = (OMX_PARAM_U32TYPE *)pConfigData;
+        OMX_U32            xFramerate  = pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.xFramerate;
+
+        if (xFramerate == 0)
+            nValue = 100;
+        else
+            nValue = (OMX_U32)((pConfigRate->nU32 / (double)xFramerate) * 100);
+
+        pEncOps->Set_QosRatio(pMFCVp9Handle->hMFCHandle, nValue);
+        pVideoEnc->bQosChanged = OMX_FALSE;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] qos ratio: %d", pExynosComponent, __FUNCTION__, nValue);
+    }
+        break;
+    default:
+        break;
+    }
+
+    Exynos_OSAL_Free(pDynamicConfigCMD);
+
+    Set_VP9Enc_Param(pExynosComponent);
+
+EXIT:
+    return;
+}
+
+OMX_ERRORTYPE GetCodecOutputPrivateData(
+    OMX_PTR  pCodecBuffer,
+    OMX_PTR *pVirtAddr,
+    OMX_U32 *pDataSize)
+{
+    OMX_ERRORTYPE      ret          = OMX_ErrorNone;
+    ExynosVideoBuffer *pVideoBuffer = NULL;
+
+    if (pCodecBuffer == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoBuffer = (ExynosVideoBuffer *)pCodecBuffer;
+
+    if (pVirtAddr != NULL)
+        *pVirtAddr = pVideoBuffer->planes[0].addr;
+
+    if (pDataSize != NULL)
+        *pDataSize = pVideoBuffer->planes[0].allocSize;
+
+EXIT:
+    return ret;
+}
+
+OMX_BOOL CheckFormatHWSupport(
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
+    OMX_COLOR_FORMATTYPE         eColorFormat)
+{
+    OMX_BOOL                         ret            = OMX_FALSE;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc        = NULL;
+    EXYNOS_OMX_BASEPORT             *pInputPort     = NULL;
+    ExynosVideoColorFormatType       eVideoFormat   = VIDEO_COLORFORMAT_UNKNOWN;
+    int i;
+
+    if (pExynosComponent == NULL)
+        goto EXIT;
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL)
+        goto EXIT;
+
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp9Enc == NULL)
+        goto EXIT;
+    pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+    for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
+        if (pVp9Enc->hMFCVp9Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
+            break;
+
+        if (pVp9Enc->hMFCVp9Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
+            ret = OMX_TRUE;
+            break;
+        }
+    }
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecOpen(
+    EXYNOS_VP9ENC_HANDLE    *pVp9Enc,
+    ExynosVideoInstInfo     *pVideoInstInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if ((pVp9Enc == NULL) ||
+        (pVideoInstInfo == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    /* alloc ops structure */
+    pEncOps    = (ExynosVideoEncOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncOps));
+    pInbufOps  = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+    pOutbufOps = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
+
+    if ((pEncOps == NULL) ||
+        (pInbufOps == NULL) ||
+        (pOutbufOps == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate decoder ops buffer", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVp9Enc->hMFCVp9Handle.pEncOps    = pEncOps;
+    pVp9Enc->hMFCVp9Handle.pInbufOps  = pInbufOps;
+    pVp9Enc->hMFCVp9Handle.pOutbufOps = pOutbufOps;
+
+    /* function pointer mapping */
+    pEncOps->nSize    = sizeof(ExynosVideoEncOps);
+    pInbufOps->nSize  = sizeof(ExynosVideoEncBufferOps);
+    pOutbufOps->nSize = sizeof(ExynosVideoEncBufferOps);
+
+    if (Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to get decoder ops", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for encoder ops */
+    if ((pEncOps->Init == NULL) ||
+        (pEncOps->Finalize == NULL) ||
+        (pEncOps->Set_FrameTag == NULL) ||
+        (pEncOps->Get_FrameTag == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* check mandatory functions for buffer ops */
+    if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
+        (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
+        (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
+        (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
+        (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Mandatory functions must be supplied", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_DMABUF;
+#else
+    pVideoInstInfo->nMemoryType = VIDEO_MEMORY_USERPTR;
+#endif
+    pVp9Enc->hMFCVp9Handle.hMFCHandle = pVp9Enc->hMFCVp9Handle.pEncOps->Init(pVideoInstInfo);
+    if (pVp9Enc->hMFCVp9Handle.hMFCHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to init", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    if (ret != OMX_ErrorNone) {
+        if (pEncOps != NULL) {
+            Exynos_OSAL_Free(pEncOps);
+            pVp9Enc->hMFCVp9Handle.pEncOps = NULL;
+        }
+
+        if (pInbufOps != NULL) {
+            Exynos_OSAL_Free(pInbufOps);
+            pVp9Enc->hMFCVp9Handle.pInbufOps = NULL;
+        }
+
+        if (pOutbufOps != NULL) {
+            Exynos_OSAL_Free(pOutbufOps);
+            pVp9Enc->hMFCVp9Handle.pOutbufOps = NULL;
+        }
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecClose(EXYNOS_VP9ENC_HANDLE *pVp9Enc)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    void                    *hMFCHandle = NULL;
+    ExynosVideoEncOps       *pEncOps    = NULL;
+    ExynosVideoEncBufferOps *pInbufOps  = NULL;
+    ExynosVideoEncBufferOps *pOutbufOps = NULL;
+
+    FunctionIn();
+
+    if (pVp9Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp9Enc->hMFCVp9Handle.hMFCHandle;
+    pEncOps    = pVp9Enc->hMFCVp9Handle.pEncOps;
+    pInbufOps  = pVp9Enc->hMFCVp9Handle.pInbufOps;
+    pOutbufOps = pVp9Enc->hMFCVp9Handle.pOutbufOps;
+
+    if (hMFCHandle != NULL) {
+        pEncOps->Finalize(hMFCHandle);
+        hMFCHandle = pVp9Enc->hMFCVp9Handle.hMFCHandle = NULL;
+        pVp9Enc->hMFCVp9Handle.bConfiguredMFCSrc = OMX_FALSE;
+        pVp9Enc->hMFCVp9Handle.bConfiguredMFCDst = OMX_FALSE;
+    }
+
+    /* Unregister function pointers */
+    Exynos_Video_Unregister_Encoder(pEncOps, pInbufOps, pOutbufOps);
+
+    if (pOutbufOps != NULL) {
+        Exynos_OSAL_Free(pOutbufOps);
+        pOutbufOps = pVp9Enc->hMFCVp9Handle.pOutbufOps = NULL;
+    }
+
+    if (pInbufOps != NULL) {
+        Exynos_OSAL_Free(pInbufOps);
+        pInbufOps = pVp9Enc->hMFCVp9Handle.pInbufOps = NULL;
+    }
+
+    if (pEncOps != NULL) {
+        Exynos_OSAL_Free(pEncOps);
+        pEncOps = pVp9Enc->hMFCVp9Handle.pEncOps = NULL;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecStart(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc            = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp9Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp9Enc->hMFCVp9Handle.hMFCHandle;
+    pInbufOps  = pVp9Enc->hMFCVp9Handle.pInbufOps;
+    pOutbufOps = pVp9Enc->hMFCVp9Handle.pOutbufOps;
+
+    if (nPortIndex == INPUT_PORT_INDEX)
+        pInbufOps->Run(hMFCHandle);
+    else if (nPortIndex == OUTPUT_PORT_INDEX)
+        pOutbufOps->Run(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecStop(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    void                            *hMFCHandle         = NULL;
+    ExynosVideoEncBufferOps         *pInbufOps          = NULL;
+    ExynosVideoEncBufferOps         *pOutbufOps         = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc            = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp9Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    hMFCHandle = pVp9Enc->hMFCVp9Handle.hMFCHandle;
+    pInbufOps  = pVp9Enc->hMFCVp9Handle.pInbufOps;
+    pOutbufOps = pVp9Enc->hMFCVp9Handle.pOutbufOps;
+
+    if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
+        pInbufOps->Stop(hMFCHandle);
+    else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
+        pOutbufOps->Stop(hMFCHandle);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecOutputBufferProcessRun(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc            = NULL;
+
+    FunctionIn();
+
+    if (pOMXComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    if (pVideoEnc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp9Enc == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        if (pVp9Enc->bSourceStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pVp9Enc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        if (pVp9Enc->bDestinationStart == OMX_FALSE) {
+            Exynos_OSAL_SignalSet(pVp9Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pVp9Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecEnqueueAllBuffer(
+    OMX_COMPONENTTYPE *pOMXComponent,
+    OMX_U32 nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc            = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                            *hMFCHandle         = pVp9Enc->hMFCVp9Handle.hMFCHandle;
+    int i;
+
+    ExynosVideoEncBufferOps *pInbufOps  = pVp9Enc->hMFCVp9Handle.pInbufOps;
+    ExynosVideoEncBufferOps *pOutbufOps = pVp9Enc->hMFCVp9Handle.pOutbufOps;
+
+    FunctionIn();
+
+    if ((nPortIndex != INPUT_PORT_INDEX) &&
+        (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pVp9Enc->bSourceStart == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)  {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(input) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoEnc->pMFCEncInputBuffer[i]->fd[0], pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
+        }
+
+        pInbufOps->Clear_Queue(hMFCHandle);
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pVp9Enc->bDestinationStart == OMX_TRUE)) {
+        Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] CodecBuffer(output) [%d]: FD(0x%x), VA(0x%x)",
+                                                pExynosComponent, __FUNCTION__,
+                                                i, pVideoEnc->pMFCEncOutputBuffer[i]->fd[0], pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoEnc->pMFCEncOutputBuffer[i]);
+        }
+
+        pOutbufOps->Clear_Queue(hMFCHandle);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecSrcSetup(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc            = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_VP9ENC_HANDLE        *pMFCVp9Handle      = &pVp9Enc->hMFCVp9Handle;
+    void                            *hMFCHandle         = pMFCVp9Handle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_U32                          oneFrameSize       = pSrcInputData->dataLen;
+
+    ExynosVideoEncOps       *pEncOps    = pVp9Enc->hMFCVp9Handle.pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps  = pVp9Enc->hMFCVp9Handle.pInbufOps;
+    ExynosVideoEncParam     *pEncParam  = NULL;
+
+    ExynosVideoGeometry      bufferConf;
+    OMX_U32                  inputBufferNumber = 0;
+
+    FunctionIn();
+
+    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] first frame has only EOS flag. EOS flag will be returned through FBD",
+                                                pExynosComponent, __FUNCTION__);
+
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pVp9Enc->bypassBufferInfoQ, (void *)pBufferInfo);
+
+        if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+            Exynos_OSAL_SignalSet(pVp9Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        } else if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+            Exynos_OSAL_SignalSet(pVp9Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    Set_VP9Enc_Param(pExynosComponent);
+
+    pEncParam = &pMFCVp9Handle->encParam;
+    if (pEncOps->Set_EncParam) {
+        if(pEncOps->Set_EncParam(pVp9Enc->hMFCVp9Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+    Print_VP9Enc_Param(pEncParam);
+
+#ifdef USE_ANDROID
+    if (pMFCVp9Handle->videoInstInfo.supportInfo.enc.bColorAspectsSupport == VIDEO_TRUE) {
+        ExynosVideoColorAspects BSCA;
+        Exynos_OSAL_Memset(&BSCA, 0, sizeof(BSCA));
+
+        Exynos_OSAL_GetColorAspectsForBitstream(&(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].ColorAspects),
+                                                &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects));
+
+        BSCA.eRangeType     = (ExynosRangeType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nRangeType;
+        BSCA.ePrimariesType = (ExynosPrimariesType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nPrimaryType;
+        BSCA.eTransferType  = (ExynosTransferType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nTransferType;
+        BSCA.eCoeffType     = (ExynosMatrixCoeffType)pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].ColorAspects.nCoeffType;
+
+        pEncOps->Set_ColorAspects(hMFCHandle, &BSCA);
+    }
+#endif
+
+    /* input buffer info: only 3 config values needed */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;
+    if ((pVideoEnc->eRotationType == ROTATE_0) ||
+        (pVideoEnc->eRotationType == ROTATE_180)) {
+        bufferConf.nFrameWidth  = pOutputPort->portDefinition.format.video.nFrameWidth;
+        bufferConf.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameHeight;
+        bufferConf.nStride      = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth, 16);
+    } else {
+        bufferConf.nFrameWidth  = pOutputPort->portDefinition.format.video.nFrameHeight;
+        bufferConf.nFrameHeight = pOutputPort->portDefinition.format.video.nFrameWidth;
+        bufferConf.nStride      = ALIGN(pOutputPort->portDefinition.format.video.nFrameHeight, 16);
+    }
+    bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+    pInbufOps->Set_Shareable(hMFCHandle);
+    inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        /* should be done before prepare input buffer */
+        if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry) {
+        if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about input", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup input buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if ((pInputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pInputPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
+        /* data buffer */
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    }
+
+    pVp9Enc->hMFCVp9Handle.bConfiguredMFCSrc = OMX_TRUE;
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE VP9CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc            = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_MFC_VP9ENC_HANDLE        *pMFCVp9Handle      = &pVp9Enc->hMFCVp9Handle;
+    void                            *hMFCHandle         = pMFCVp9Handle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pOutbufOps = pVp9Enc->hMFCVp9Handle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+
+    unsigned int nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0};
+    unsigned int nDataLen[VIDEO_BUFFER_MAX_PLANES]  = {0, 0, 0};
+    int i, nOutBufSize = 0, nOutputBufferCnt = 0;
+
+    FunctionIn();
+
+    nOutBufSize = pOutputPort->portDefinition.nBufferSize;
+    if ((pOutputPort->bufferProcessType & BUFFER_COPY) ||
+        (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        /* OMX buffer is not used directly : CODEC buffer or MetaData */
+        nOutBufSize = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth *
+                            pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+    }
+
+    /* set geometry for output (dst) */
+    if (pOutbufOps->Set_Geometry) {
+        /* only 2 config values needed */
+        bufferConf.eCompressionFormat   = VIDEO_CODING_VP9;
+        bufferConf.nSizeImage           = nOutBufSize;
+        bufferConf.nPlaneCnt            = Exynos_GetPlaneFromPort(pOutputPort);
+
+        if (pOutbufOps->Set_Geometry(pVp9Enc->hMFCVp9Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to set geometry about output", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* should be done before prepare output buffer */
+    if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY)
+        nOutputBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
+    else
+        nOutputBufferCnt = pOutputPort->portDefinition.nBufferCountActual;
+
+    if (pOutbufOps->Setup(pVp9Enc->hMFCVp9Handle.hMFCHandle, nOutputBufferCnt) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to setup output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        nAllocLen[0] = nOutBufSize;
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX, nAllocLen);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Allocate_CodecBuffers for output", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        /* Enqueue output buffer */
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
+                                (unsigned long *)pVideoEnc->pMFCEncOutputBuffer[i]->fd,
+                                pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pOutputPort),
+                                NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /* Register output buffer */
+        /*************/
+        /*    TBD    */
+        /*************/
+    }
+
+    pVp9Enc->hMFCVp9Handle.bConfiguredMFCDst = OMX_TRUE;
+
+    if (VP9CodecStart(pOMXComponent, OUTPUT_PORT_INDEX) != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to run output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nParamIndex %x", pExynosComponent, __FUNCTION__, (int)nParamIndex);
+    switch ((int)nParamIndex) {
+    case OMX_IndexParamVideoVp9:
+    {
+        OMX_VIDEO_PARAM_VP9TYPE *pDstVP9Component = (OMX_VIDEO_PARAM_VP9TYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP9TYPE *pSrcVP9Component = NULL;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstVP9Component, sizeof(OMX_VIDEO_PARAM_VP9TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstVP9Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVP9Component = &pVp9Enc->VP9Component[pDstVP9Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstVP9Component) + nOffset,
+                           ((char *)pSrcVP9Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_VP9TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP9_ENC_ROLE);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelQuerySupported:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        ret = GetIndexToProfileLevel(pExynosComponent, pDstProfileLevel);
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP9TYPE          *pSrcVP9Component = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVP9Component = &pVp9Enc->VP9Component[pDstProfileLevel->nPortIndex];
+        pDstProfileLevel->eProfile  = pSrcVP9Component->eProfile;
+        pDstProfileLevel->eLevel    = pSrcVP9Component->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcErrorCorrectionType = &pVp9Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
+        pDstErrorCorrectionType->bEnableHEC              = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync           = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing   = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC             = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pVp9Enc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pVp9Enc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pVp9Enc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pVp9Enc->qpRangeP.nMaxQP;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamVideoAndroidVp8Encoder:
+    {
+
+        OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *pDstVp9EncoderType = (OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *pSrcVp9EncoderType = &pVp9Enc->AndroidVp9EncoderType;
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pDstVp9EncoderType, sizeof(OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDstVp9EncoderType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSrcVp9EncoderType->nKeyFrameInterval = pVp9Enc->nPFrames + 1;
+        pSrcVp9EncoderType->nMinQuantizer = pVp9Enc->qpRangeI.nMinQP;
+        pSrcVp9EncoderType->nMaxQuantizer = pVp9Enc->qpRangeI.nMaxQP;
+
+        Exynos_OSAL_Memcpy(((char *)pDstVp9EncoderType) + nOffset,
+                           ((char *)pSrcVp9EncoderType) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE) - nOffset);
+    }
+        break;
+#endif
+    case OMX_IndexParamVideoEnablePVC:
+    {
+        OMX_PARAM_U32TYPE *pEnablePVC  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pEnablePVC, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pEnablePVC->nU32 = pVideoEnc->bPVCMode;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamVideoVp9:
+    {
+        OMX_VIDEO_PARAM_VP9TYPE *pDstVP9Component = NULL;
+        OMX_VIDEO_PARAM_VP9TYPE *pSrcVP9Component = (OMX_VIDEO_PARAM_VP9TYPE *)pComponentParameterStructure;
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcVP9Component, sizeof(OMX_VIDEO_PARAM_VP9TYPE));
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        if (pSrcVP9Component->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstVP9Component = &pVp9Enc->VP9Component[pSrcVP9Component->nPortIndex];
+
+        Exynos_OSAL_Memcpy(((char *)pDstVP9Component) + nOffset,
+                           ((char *)pSrcVP9Component) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_VP9TYPE) - nOffset);
+    }
+        break;
+    case OMX_IndexParamStandardComponentRole:
+    {
+        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
+            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+            ret = OMX_ErrorIncorrectStateOperation;
+            goto EXIT;
+        }
+
+        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP9_ENC_ROLE)) {
+            pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP9;
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexParamVideoProfileLevelCurrent:
+    {
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_VP9TYPE          *pDstVP9Component = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstVP9Component = &pVp9Enc->VP9Component[pSrcProfileLevel->nPortIndex];
+
+        if (OMX_FALSE == CheckProfileLevelSupport(pExynosComponent, pSrcProfileLevel)) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pDstVP9Component->eProfile  = pSrcProfileLevel->eProfile;
+        pDstVP9Component->eLevel    = pSrcProfileLevel->eLevel;
+    }
+        break;
+    case OMX_IndexParamVideoErrorCorrection:
+    {
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDstErrorCorrectionType = &pVp9Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
+        pDstErrorCorrectionType->bEnableHEC                 = pSrcErrorCorrectionType->bEnableHEC;
+        pDstErrorCorrectionType->bEnableResync              = pSrcErrorCorrectionType->bEnableResync;
+        pDstErrorCorrectionType->nResynchMarkerSpacing      = pSrcErrorCorrectionType->nResynchMarkerSpacing;
+        pDstErrorCorrectionType->bEnableDataPartitioning    = pSrcErrorCorrectionType->bEnableDataPartitioning;
+        pDstErrorCorrectionType->bEnableRVLC                = pSrcErrorCorrectionType->bEnableRVLC;
+    }
+        break;
+    case OMX_IndexParamVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentParameterStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d])", __FUNCTION__,
+                            pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                            pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pVp9Enc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pVp9Enc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pVp9Enc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pVp9Enc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+    }
+        break;
+#ifdef USE_ANDROID
+    case OMX_IndexParamVideoAndroidVp8Encoder:
+    {
+        OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *pSrcVp9EncoderType = (OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *)pComponentParameterStructure;
+        OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *pDstVp9EncoderType = &pVp9Enc->AndroidVp9EncoderType;
+
+
+        /* except nSize, nVersion and nPortIndex */
+        int nOffset = sizeof(OMX_U32) + sizeof(OMX_VERSIONTYPE) + sizeof(OMX_U32);
+
+        ret = Exynos_OMX_Check_SizeVersion(pSrcVp9EncoderType, sizeof(OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE));
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+
+        if (pSrcVp9EncoderType->nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pVp9Enc->hMFCVp9Handle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) &&
+            (pSrcVp9EncoderType->eTemporalPattern != OMX_VIDEO_VPXTemporalLayerPatternNone)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: Temporal SVC is not supported", __FUNCTION__);
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        if ((pSrcVp9EncoderType->nMinQuantizer > pSrcVp9EncoderType->nMaxQuantizer) ||
+            (pSrcVp9EncoderType->nMaxQuantizer >= VP9_QP_INDEX_RANGE)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: QP value is invalid(min:%d, max:%d)", __FUNCTION__,
+                            pSrcVp9EncoderType->nMinQuantizer, pSrcVp9EncoderType->nMaxQuantizer);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pVp9Enc->nPFrames = pSrcVp9EncoderType->nKeyFrameInterval - 1;
+
+        pVp9Enc->qpRangeI.nMinQP = pSrcVp9EncoderType->nMinQuantizer;
+        pVp9Enc->qpRangeI.nMaxQP = pSrcVp9EncoderType->nMaxQuantizer;
+
+        Exynos_OSAL_Memcpy(((char *)pDstVp9EncoderType) + nOffset,
+                           ((char *)pSrcVp9EncoderType) + nOffset,
+                           sizeof(OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE) - nOffset);
+    }
+        break;
+#endif
+    case OMX_IndexParamVideoEnablePVC:
+    {
+        OMX_PARAM_U32TYPE *pEnablePVC  = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pEnablePVC, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        pVideoEnc->bPVCMode = (pEnablePVC->nU32)? OMX_TRUE:OMX_FALSE;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+        break;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_GetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                    ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc        = NULL;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pQpRange->qpRangeI.nMinQP = pVp9Enc->qpRangeI.nMinQP;
+        pQpRange->qpRangeI.nMaxQP = pVp9Enc->qpRangeI.nMaxQP;
+        pQpRange->qpRangeP.nMinQP = pVp9Enc->qpRangeP.nMinQP;
+        pQpRange->qpRangeP.nMaxQP = pVp9Enc->qpRangeP.nMaxQP;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_SetConfig(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_VP9ENC_HANDLE          *pVp9Enc          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexConfigVideoIntraPeriod:
+    {
+        OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1;
+
+        pVp9Enc->nPFrames = nPFrames;
+
+        ret = OMX_ErrorNone;
+    }
+        break;
+    case OMX_IndexConfigVideoQPRange:
+    {
+        OMX_VIDEO_QPRANGETYPE *pQpRange   = (OMX_VIDEO_QPRANGETYPE *)pComponentConfigStructure;
+        OMX_U32                nPortIndex = pQpRange->nPortIndex;
+
+        ret = Exynos_OMX_Check_SizeVersion(pQpRange, sizeof(OMX_VIDEO_QPRANGETYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex != OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pQpRange->qpRangeI.nMinQP > pQpRange->qpRangeI.nMaxQP) ||
+            (pQpRange->qpRangeP.nMinQP > pQpRange->qpRangeP.nMaxQP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] QP value is invalid(I[min:%d, max:%d], P[min:%d, max:%d])",
+                            pExynosComponent, __FUNCTION__,
+                            pQpRange->qpRangeI.nMinQP, pQpRange->qpRangeI.nMaxQP,
+                            pQpRange->qpRangeP.nMinQP, pQpRange->qpRangeP.nMaxQP);
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        if (pVp9Enc->hMFCVp9Handle.videoInstInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_FALSE)
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] only I-frame's QP range is applied", pExynosComponent, __FUNCTION__);
+
+        pVp9Enc->qpRangeI.nMinQP = pQpRange->qpRangeI.nMinQP;
+        pVp9Enc->qpRangeI.nMaxQP = pQpRange->qpRangeI.nMaxQP;
+        pVp9Enc->qpRangeP.nMinQP = pQpRange->qpRangeP.nMinQP;
+        pVp9Enc->qpRangeP.nMaxQP = pQpRange->qpRangeP.nMaxQP;
+    }
+        break;
+    default:
+        ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+        break;
+    }
+
+EXIT:
+    if (ret == OMX_ErrorNone) {
+        OMX_PTR pDynamicConfigCMD = NULL;
+        pDynamicConfigCMD = Exynos_OMX_MakeDynamicConfig(nIndex, pComponentConfigStructure);
+        Exynos_OSAL_Queue(&pExynosComponent->dynamicConfigQ, (void *)pDynamicConfigCMD);
+    }
+
+    if (ret == (OMX_ERRORTYPE)OMX_ErrorNoneExpiration)
+        ret = OMX_ErrorNone;
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_GetExtensionIndex(
+    OMX_IN OMX_HANDLETYPE  hComponent,
+    OMX_IN OMX_STRING      cParameterName,
+    OMX_OUT OMX_INDEXTYPE *pIndexType)
+{
+    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cParameterName == NULL) ||
+        (pIndexType == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_PVC) == 0) {
+        *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamVideoEnablePVC;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_ComponentRoleEnum(
+    OMX_HANDLETYPE   hComponent,
+    OMX_U8          *cRole,
+    OMX_U32          nIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (cRole == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_VP9_ENC_ROLE);
+        ret = OMX_ErrorNone;
+    } else {
+        ret = OMX_ErrorNoMore;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Init */
+OMX_ERRORTYPE Exynos_VP9Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort           = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_VP9ENC_HANDLE          *pVp9Enc              = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    OMX_COLOR_FORMATTYPE           eColorFormat         = pInputPort->portDefinition.format.video.eColorFormat;
+
+    ExynosVideoInstInfo *pVideoInstInfo = &(pVp9Enc->hMFCVp9Handle.videoInstInfo);
+
+    CSC_METHOD csc_method = CSC_METHOD_SW;
+
+    FunctionIn();
+
+    pVp9Enc->hMFCVp9Handle.bConfiguredMFCSrc = OMX_FALSE;
+    pVp9Enc->hMFCVp9Handle.bConfiguredMFCDst = OMX_FALSE;
+    pVideoEnc->bFirstInput         = OMX_TRUE;
+    pVideoEnc->bFirstOutput        = OMX_FALSE;
+    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+    if (pInputPort->eMetaDataType != METADATA_TYPE_DISABLED) {
+        /* metadata buffer */
+        pInputPort->bufferProcessType = BUFFER_SHARE;
+
+#ifdef USE_ANDROID
+        if ((pInputPort->eMetaDataType == METADATA_TYPE_DATA) &&
+            (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)) {
+            pInputPort->eMetaDataType     = METADATA_TYPE_GRAPHIC;  /* AndoridOpaque means GrallocSource */
+            pInputPort->bufferProcessType = BUFFER_COPY;  /* will determine a process type after getting a hal format at handle */
+        }
+#else
+        if (pInputPort->eMetaDataType == METADATA_TYPE_UBM_BUFFER) {
+            pInputPort->bufferProcessType = BUFFER_COPY;
+        }
+#endif
+    } else {
+        /* data buffer */
+        pInputPort->bufferProcessType = BUFFER_COPY;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W:%d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
+                                                                                            pInputPort->portDefinition.format.video.nFrameWidth,
+                                                                                            pInputPort->portDefinition.format.video.nFrameHeight,
+                                                                                            pInputPort->portDefinition.format.video.nBitrate,
+                                                                                            pInputPort->portDefinition.format.video.xFramerate);
+    pVideoInstInfo->nSize        = sizeof(ExynosVideoInstInfo);
+    pVideoInstInfo->nWidth       = pInputPort->portDefinition.format.video.nFrameWidth;
+    pVideoInstInfo->nHeight      = pInputPort->portDefinition.format.video.nFrameHeight;
+    pVideoInstInfo->nBitrate     = pInputPort->portDefinition.format.video.nBitrate;
+    pVideoInstInfo->xFramerate   = pInputPort->portDefinition.format.video.xFramerate;
+
+    /* VP9 Codec Open */
+    ret = VP9CodecOpen(pVp9Enc, pVideoInstInfo);
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    Exynos_SetPlaneToPort(pInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+    Exynos_SetPlaneToPort(pOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+
+    Exynos_OSAL_SemaphoreCreate(&pInputPort->codecSemID);
+    Exynos_OSAL_QueueCreate(&pInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_OSAL_SemaphoreCreate(&pOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    pVp9Enc->bSourceStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pVp9Enc->hSourceStartEvent);
+    pVp9Enc->bDestinationStart = OMX_FALSE;
+    Exynos_OSAL_SignalCreate(&pVp9Enc->hDestinationInStartEvent);
+    Exynos_OSAL_SignalCreate(&pVp9Enc->hDestinationOutStartEvent);
+
+    Exynos_OSAL_Memset(pExynosComponent->bTimestampSlotUsed, 0, sizeof(OMX_BOOL) * MAX_TIMESTAMP);
+    INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+    pVp9Enc->hMFCVp9Handle.indexTimestamp       = 0;
+    pVp9Enc->hMFCVp9Handle.outputIndexTimestamp = 0;
+
+    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+    Exynos_OSAL_QueueCreate(&pVp9Enc->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
+#endif
+
+    pVideoEnc->csc_handle = csc_init(csc_method);
+    if (pVideoEnc->csc_handle == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVideoEnc->csc_set_format = OMX_FALSE;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/* MFC Terminate */
+OMX_ERRORTYPE Exynos_VP9Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
+    EXYNOS_OMX_BASEPORT           *pInputPort           = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    EXYNOS_VP9ENC_HANDLE          *pVp9Enc              = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    FunctionIn();
+
+    if (pVideoEnc->csc_handle != NULL) {
+        csc_deinit(pVideoEnc->csc_handle);
+        pVideoEnc->csc_handle = NULL;
+    }
+
+    Exynos_OSAL_QueueTerminate(&pVp9Enc->bypassBufferInfoQ);
+
+    Exynos_OSAL_SignalTerminate(pVp9Enc->hDestinationInStartEvent);
+    pVp9Enc->hDestinationInStartEvent = NULL;
+    Exynos_OSAL_SignalTerminate(pVp9Enc->hDestinationOutStartEvent);
+    pVp9Enc->hDestinationOutStartEvent = NULL;
+    pVp9Enc->bDestinationStart = OMX_FALSE;
+
+    Exynos_OSAL_SignalTerminate(pVp9Enc->hSourceStartEvent);
+    pVp9Enc->hSourceStartEvent = NULL;
+    pVp9Enc->bSourceStart = OMX_FALSE;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+        Exynos_OSAL_QueueTerminate(&pOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pOutputPort->codecSemID);
+        pOutputPort->codecSemID = NULL;
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+    } else if (pInputPort->bufferProcessType & BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
+    Exynos_OSAL_QueueTerminate(&pInputPort->codecBufferQ);
+    Exynos_OSAL_SemaphoreTerminate(pInputPort->codecSemID);
+    pInputPort->codecSemID = NULL;
+
+    VP9CodecClose(pVp9Enc);
+
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_SrcIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9ENC_HANDLE          *pVp9Enc          = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle       = pVp9Enc->hMFCVp9Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort       = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    OMX_COLOR_FORMATTYPE           inputColorFormat = OMX_COLOR_FormatUnused;
+
+    ExynosVideoEncOps       *pEncOps     = pVp9Enc->hMFCVp9Handle.pEncOps;
+    ExynosVideoEncBufferOps *pInbufOps   = pVp9Enc->hMFCVp9Handle.pInbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
+    unsigned int nAllocLen[MAX_BUFFER_PLANE]  = {0, 0, 0};
+    unsigned int nDataLen[MAX_BUFFER_PLANE]   = {0, 0, 0};
+    int i, nPlaneCnt, nConfigCnt;
+
+    FunctionIn();
+
+    if (pVp9Enc->hMFCVp9Handle.bConfiguredMFCSrc == OMX_FALSE) {
+        ret = VP9CodecSrcSetup(pOMXComponent, pSrcInputData);
+        if ((ret != OMX_ErrorNone) ||
+            ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VP9CodecSrcSetup(0x%x)",
+                                                pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+    }
+
+    if (pVp9Enc->hMFCVp9Handle.bConfiguredMFCDst == OMX_FALSE) {
+        ret = VP9CodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VP9CodecDstSetup(0x%x)",
+                                                pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+    }
+
+    nConfigCnt = Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ);
+    if (nConfigCnt > 0) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] has config message(%d)", pExynosComponent, __FUNCTION__, nConfigCnt);
+        while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+            Change_VP9Enc_Param(pExynosComponent);
+        }
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] all config messages were handled", pExynosComponent, __FUNCTION__);
+    }
+
+    if ((pSrcInputData->dataLen > 0) ||
+        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+        pExynosComponent->timeStamp[pVp9Enc->hMFCVp9Handle.indexTimestamp]              = pSrcInputData->timeStamp;
+        pExynosComponent->bTimestampSlotUsed[pVp9Enc->hMFCVp9Handle.indexTimestamp]     = OMX_TRUE;
+        pExynosComponent->nFlags[pVp9Enc->hMFCVp9Handle.indexTimestamp]                 = pSrcInputData->nFlags;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p), nFlags: 0x%x, timestamp %lld us (%.2f secs), Tag: %d",
+                                                        pExynosComponent, __FUNCTION__,
+                                                        pSrcInputData->bufferHeader, pSrcInputData->nFlags,
+                                                        pSrcInputData->timeStamp, (double)(pSrcInputData->timeStamp / 1E6),
+                                                        pVp9Enc->hMFCVp9Handle.indexTimestamp);
+        pEncOps->Set_FrameTag(hMFCHandle, pVp9Enc->hMFCVp9Handle.indexTimestamp);
+        pVp9Enc->hMFCVp9Handle.indexTimestamp++;
+        pVp9Enc->hMFCVp9Handle.indexTimestamp %= MAX_TIMESTAMP;
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountIncrease(pInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+        inputColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+        if ((pVideoEnc->eRotationType == ROTATE_0) ||
+            (pVideoEnc->eRotationType == ROTATE_180)) {
+            Exynos_OSAL_GetPlaneSize(inputColorFormat,
+                                     pInputPort->ePlaneType,
+                                     pInputPort->portDefinition.format.video.nFrameWidth,
+                                     pInputPort->portDefinition.format.video.nFrameHeight,
+                                     nDataLen,
+                                     nAllocLen);
+        } else {
+            Exynos_OSAL_GetPlaneSize(inputColorFormat,
+                                     pInputPort->ePlaneType,
+                                     pInputPort->portDefinition.format.video.nFrameHeight,
+                                     pInputPort->portDefinition.format.video.nFrameWidth,
+                                     nDataLen,
+                                     nAllocLen);
+        }
+
+        if (pInputPort->bufferProcessType == BUFFER_COPY) {
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        } else {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        }
+
+        nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+        if (pVideoEnc->nInbufSpareSize > 0) {
+            for (i = 0; i < nPlaneCnt; i++)
+                nAllocLen[i] = nAllocLen[i] + pVideoEnc->nInbufSpareSize;
+        }
+
+        if (pSrcInputData->dataLen == 0) {
+            for (i = 0; i < nPlaneCnt; i++)
+                nDataLen[i] = 0;
+        }
+
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                    (void **)pSrcInputData->buffer.addr,
+                                    (unsigned long *)pSrcInputData->buffer.fd,
+                                    nAllocLen,
+                                    nDataLen,
+                                    nPlaneCnt,
+                                    pPrivate);
+        if (codecReturn != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about input (0x%x)",
+                                                pExynosComponent, __FUNCTION__, codecReturn);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+            goto EXIT;
+        }
+
+        VP9CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+
+        if (pVp9Enc->bSourceStart == OMX_FALSE) {
+            pVp9Enc->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pVp9Enc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+
+        if ((pVp9Enc->bDestinationStart == OMX_FALSE) &&
+            (pVp9Enc->hMFCVp9Handle.bConfiguredMFCDst == OMX_TRUE)) {
+            pVp9Enc->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pVp9Enc->hDestinationInStartEvent);
+            Exynos_OSAL_SignalSet(pVp9Enc->hDestinationOutStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_SrcOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9ENC_HANDLE          *pVp9Enc          = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle       = pVp9Enc->hMFCVp9Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort       = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pInbufOps      = pVp9Enc->hMFCVp9Handle.pInbufOps;
+    ExynosVideoBuffer       *pVideoBuffer   = NULL;
+    ExynosVideoBuffer        videoBuffer;
+
+    FunctionIn();
+
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
+
+    pSrcOutputData->dataLen       = 0;
+    pSrcOutputData->usedDataLen   = 0;
+    pSrcOutputData->remainDataLen = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->allocSize     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
+
+    if (pVideoBuffer == NULL) {
+        pSrcOutputData->buffer.addr[0] = NULL;
+        pSrcOutputData->pPrivate = NULL;
+    } else {
+        int plane = 0, nPlaneCnt;
+        nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+        for (plane = 0; plane < nPlaneCnt; plane++) {
+            pSrcOutputData->buffer.addr[plane]  = pVideoBuffer->planes[plane].addr;
+            pSrcOutputData->buffer.fd[plane]    = pVideoBuffer->planes[plane].fd;
+
+            pSrcOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+        }
+
+        if (pInputPort->bufferProcessType & BUFFER_COPY) {
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.addr[0] ==
+                        pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) {
+                    pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i];
+                    break;
+                }
+            }
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+                goto EXIT;
+            }
+        }
+
+        /* For Share Buffer */
+        if (pInputPort->bufferProcessType == BUFFER_SHARE) {
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input / buffer header(%p)",
+                                                pExynosComponent, __FUNCTION__, pSrcOutputData->bufferHeader);
+        }
+
+#ifdef PERFORMANCE_DEBUG
+        Exynos_OSAL_V4L2CountDecrease(pInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_DstIn(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9ENC_HANDLE          *pVp9Enc              = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    void                          *hMFCHandle           = pVp9Enc->hMFCVp9Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoEncBufferOps *pOutbufOps  = pVp9Enc->hMFCVp9Handle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    unsigned int nAllocLen[VIDEO_BUFFER_MAX_PLANES] = {0, 0, 0};
+    unsigned int nDataLen[VIDEO_BUFFER_MAX_PLANES]  = {0, 0, 0};
+
+    FunctionIn();
+
+    if (pDstInputData->buffer.addr[0] == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to find output buffer", pExynosComponent, __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+#ifdef PERFORMANCE_DEBUG
+    Exynos_OSAL_V4L2CountIncrease(pOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+    nAllocLen[0] = pOutputPort->portDefinition.nBufferSize;
+    if ((pOutputPort->bufferProcessType & BUFFER_COPY) ||
+        (pOutputPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        /* OMX buffer is not used directly : CODEC buffer or MetaData */
+        nAllocLen[0] = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth * pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p)",
+                                        pExynosComponent, __FUNCTION__, pDstInputData->bufferHeader);
+
+    codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+                                (void **)pDstInputData->buffer.addr,
+                                (unsigned long *)&pDstInputData->buffer.fd,
+                                nAllocLen,
+                                nDataLen,
+                                Exynos_GetPlaneFromPort(pOutputPort),
+                                pDstInputData->bufferHeader);
+    if (codecReturn != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to ExtensionEnqueue about output (0x%x)",
+                                            pExynosComponent, __FUNCTION__, codecReturn);
+        ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+        goto EXIT;
+    }
+
+    VP9CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_DstOut(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                  ret                  = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent     = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc            = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9ENC_HANDLE          *pVp9Enc              = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT           *pOutputPort          = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    void                          *hMFCHandle           = pVp9Enc->hMFCVp9Handle.hMFCHandle;
+
+    ExynosVideoEncOps           *pEncOps        = pVp9Enc->hMFCVp9Handle.pEncOps;
+    ExynosVideoEncBufferOps     *pOutbufOps     = pVp9Enc->hMFCVp9Handle.pOutbufOps;
+    ExynosVideoBuffer           *pVideoBuffer   = NULL;
+    ExynosVideoBuffer            videoBuffer;
+    ExynosVideoErrorType         codecReturn    = VIDEO_ERROR_NONE;
+
+    OMX_S32 indexTimestamp = 0;
+
+    FunctionIn();
+
+    if (pVp9Enc->bDestinationStart == OMX_FALSE) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
+    if (codecReturn == VIDEO_ERROR_NONE) {
+        pVideoBuffer = &videoBuffer;
+    } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] HW is not available(EIO)", pExynosComponent, __FUNCTION__);
+        pVideoBuffer = NULL;
+        ret = OMX_ErrorHardware;
+        goto EXIT;
+    } else {
+        pVideoBuffer = NULL;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pVp9Enc->hMFCVp9Handle.outputIndexTimestamp++;
+    pVp9Enc->hMFCVp9Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+    pDstOutputData->buffer.addr[0]  = pVideoBuffer->planes[0].addr;
+    pDstOutputData->buffer.fd[0]    = pVideoBuffer->planes[0].fd;
+
+    pDstOutputData->allocSize       = pVideoBuffer->planes[0].allocSize;
+    pDstOutputData->dataLen         = pVideoBuffer->planes[0].dataSize;
+    pDstOutputData->remainDataLen   = pVideoBuffer->planes[0].dataSize;
+    pDstOutputData->usedDataLen     = 0;
+
+    pDstOutputData->pPrivate        = pVideoBuffer;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.addr[0] ==
+                pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Can not find a codec buffer", pExynosComponent, __FUNCTION__);
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+            goto EXIT;
+        }
+    }
+
+    /* For Share Buffer */
+    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+    if (pVideoEnc->bFirstOutput == OMX_FALSE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] codec specific data is generated", pExynosComponent, __FUNCTION__);
+        pDstOutputData->timeStamp   = 0;
+        pDstOutputData->nFlags     |= OMX_BUFFERFLAG_CODECCONFIG;
+        pDstOutputData->nFlags     |= OMX_BUFFERFLAG_ENDOFFRAME;
+        pVideoEnc->bFirstOutput     = OMX_TRUE;
+    } else {
+        indexTimestamp = pEncOps->Get_FrameTag(pVp9Enc->hMFCVp9Handle.hMFCHandle);
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
+
+        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] Tag(%d) is invalid. changes to use outputIndexTimestamp(%d)",
+                                                  pExynosComponent, __FUNCTION__,
+                                                  indexTimestamp, pVp9Enc->hMFCVp9Handle.outputIndexTimestamp);
+            indexTimestamp = pVp9Enc->hMFCVp9Handle.outputIndexTimestamp;
+        }
+
+        /* In case of Video buffer batch mode, use timestamp from MFC device driver */
+        if (pVideoBuffer->timestamp != 0)
+            pDstOutputData->timeStamp = pVideoBuffer->timestamp;
+        else
+            pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
+
+        pExynosComponent->bTimestampSlotUsed[indexTimestamp]    = OMX_FALSE;
+        pDstOutputData->nFlags                                  = pExynosComponent->nFlags[indexTimestamp];
+        pDstOutputData->nFlags                                 |= OMX_BUFFERFLAG_ENDOFFRAME;
+    }
+
+    if (pVideoBuffer->frameType == VIDEO_FRAME_I)
+        pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output / buffer header(%p), nFlags: 0x%x, frameType: %d, dataLen: %d, timestamp %lld us (%.2f secs), Tag: %d",
+                                            pExynosComponent, __FUNCTION__,
+                                            pDstOutputData->bufferHeader, pDstOutputData->nFlags,
+                                            pVideoBuffer->frameType, pDstOutputData->dataLen,
+                                            pDstOutputData->timeStamp, (double)(pDstOutputData->timeStamp / 1E6),
+                                            indexTimestamp);
+
+#ifdef PERFORMANCE_DEBUG
+    if (pDstOutputData->bufferHeader != NULL) {
+        pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+        Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+    }
+#endif
+
+    if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] got end of stream", pExynosComponent, __FUNCTION__);
+
+        if (pExynosComponent->bBehaviorEOS == OMX_FALSE)
+            pDstOutputData->remainDataLen = 0;
+        else
+            pExynosComponent->bBehaviorEOS = OMX_FALSE;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_srcInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcInputData)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT         *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pInputPort)) ||
+        (!CHECK_PORT_POPULATED(pInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    ret = Exynos_VP9Enc_SrcIn(pOMXComponent, pSrcInputData);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_srcOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pSrcOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc            = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pInputPort)) ||
+        (!CHECK_PORT_POPULATED(pInputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (pInputPort->bufferProcessType & BUFFER_COPY) {
+        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    if ((pVp9Enc->bSourceStart == OMX_FALSE) &&
+        (!CHECK_PORT_BEING_FLUSHED(pInputPort))) {
+        Exynos_OSAL_SignalWait(pVp9Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get SourceStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp9Enc->hSourceStartEvent);
+    }
+
+    ret = Exynos_VP9Enc_SrcOut(pOMXComponent, pSrcOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_dstInputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstInputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc            = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVp9Enc->bDestinationStart == OMX_FALSE) &&
+        (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+        Exynos_OSAL_SignalWait(pVp9Enc->hDestinationInStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationInStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp9Enc->hDestinationInStartEvent);
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if (Exynos_OSAL_GetElemNum(&pVp9Enc->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pVp9Enc->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    if (pVp9Enc->hMFCVp9Handle.bConfiguredMFCDst == OMX_TRUE) {
+        ret = Exynos_VP9Enc_DstIn(pOMXComponent, pDstInputData);
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                    pExynosComponent, __FUNCTION__);
+            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_VP9Enc_dstOutputBufferProcess(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    EXYNOS_OMX_DATA     *pDstOutputData)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc            = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    EXYNOS_OMX_BASEPORT             *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    FunctionIn();
+
+    if ((!CHECK_PORT_ENABLED(pOutputPort)) ||
+        (!CHECK_PORT_POPULATED(pOutputPort))) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    if ((pVp9Enc->bDestinationStart == OMX_FALSE) &&
+        (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+        Exynos_OSAL_SignalWait(pVp9Enc->hDestinationOutStartEvent, DEF_MAX_WAIT_TIME);
+        if (pVideoEnc->bExitBufferProcessThread)
+            goto EXIT;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] get DestinationOutStartEvent", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_SignalReset(pVp9Enc->hDestinationOutStartEvent);
+    }
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if (Exynos_OSAL_GetElemNum(&pVp9Enc->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bypassBufferInfoQ has EOS buffer", pExynosComponent, __FUNCTION__);
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pVp9Enc->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
+    }
+
+    ret = Exynos_VP9Enc_DstOut(pOMXComponent, pDstOutputData);
+    if ((ret != OMX_ErrorNone) &&
+        (pExynosComponent->currentState == OMX_StateExecuting)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] send event(OMX_EventError)",
+                                                pExynosComponent, __FUNCTION__);
+        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+                                                pExynosComponent->callbackData,
+                                                OMX_EventError, ret, 0, NULL);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
+    OMX_HANDLETYPE hComponent,
+    OMX_STRING     componentName)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_VP9ENC_HANDLE          *pVp9Enc          = NULL;
+    int i = 0;
+
+    Exynos_OSAL_Get_Log_Property(); // For debuging
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (componentName == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP9_ENC, componentName) != 0) {
+        ret = OMX_ErrorBadParameter;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported component name(%s)", __FUNCTION__, componentName);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s][%s] Failed to VideoDecodeComponentInit (0x%x)", componentName, __FUNCTION__, ret);
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pExynosComponent->codecType = HW_VIDEO_ENC_CODEC;
+
+    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+    if (pExynosComponent->componentName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+
+    pVp9Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_VP9ENC_HANDLE));
+    if (pVp9Enc == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to malloc (0x%x) Line:%d", pExynosComponent, __FUNCTION__, ret, __LINE__);
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(pVp9Enc, 0, sizeof(EXYNOS_VP9ENC_HANDLE));
+
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pVp9Enc;
+    pVp9Enc->qpRangeI.nMinQP = 2;   /* index = 2, value = 9 */
+    pVp9Enc->qpRangeI.nMaxQP = 63;  /* index = 63, value = 255 */
+    pVp9Enc->qpRangeP.nMinQP = 2;   /* index = 2, value = 9 */
+    pVp9Enc->qpRangeP.nMaxQP = 63;  /* index = 63, value = 255 */
+
+    pVideoEnc->quantization.nQpI    = 90;
+    pVideoEnc->quantization.nQpP    = 100;
+    pVideoEnc->quantization.nQpB    = 100;
+
+    Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_VP9_ENC);
+
+    /* Set componentVersion */
+    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    /* Input port */
+    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth    = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight   = DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride        = 0;
+    pExynosPort->portDefinition.nBufferSize                 = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    pExynosPort->portDefinition.bEnabled    = OMX_TRUE;
+    pExynosPort->bufferProcessType          = BUFFER_COPY;
+    pExynosPort->portWayType                = WAY2_PORT;
+    pExynosPort->ePlaneType                 = PLANE_MULTIPLE;
+
+    /* Output port */
+    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    pExynosPort->portDefinition.format.video.nFrameWidth    = DEFAULT_FRAME_WIDTH;
+    pExynosPort->portDefinition.format.video.nFrameHeight   = DEFAULT_FRAME_HEIGHT;
+    pExynosPort->portDefinition.format.video.nStride        = 0;
+    pExynosPort->portDefinition.nBufferSize                 = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP9;
+    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+    pExynosPort->portDefinition.bEnabled    = OMX_TRUE;
+    pExynosPort->bufferProcessType          = BUFFER_SHARE;
+    pExynosPort->portWayType                = WAY2_PORT;
+    pExynosPort->ePlaneType                 = PLANE_SINGLE;
+
+    for(i = 0; i < ALL_PORT_NUM; i++) {
+        INIT_SET_SIZE_VERSION(&pVp9Enc->VP9Component[i], OMX_VIDEO_PARAM_VP9TYPE);
+        pVp9Enc->VP9Component[i].nPortIndex = i;
+        pVp9Enc->VP9Component[i].eProfile   = OMX_VIDEO_VP9Profile0;
+        pVp9Enc->VP9Component[i].eLevel     = OMX_VIDEO_VP9Level41;
+    }
+    pVp9Enc->nPFrames = -1;
+
+    Exynos_OSAL_Memset(&pVp9Enc->AndroidVp9EncoderType, 0, sizeof(OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE));
+    INIT_SET_SIZE_VERSION(&pVp9Enc->AndroidVp9EncoderType, OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE);
+    pVp9Enc->AndroidVp9EncoderType.nKeyFrameInterval    = pVp9Enc->nPFrames + 1;
+    pVp9Enc->AndroidVp9EncoderType.eTemporalPattern     = OMX_VIDEO_VPXTemporalLayerPatternNone;
+    pVp9Enc->AndroidVp9EncoderType.nTemporalLayerCount  = 1;
+    for (i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++)
+        pVp9Enc->AndroidVp9EncoderType.nTemporalLayerBitrateRatio[i] = 100;
+
+    pVp9Enc->AndroidVp9EncoderType.nMinQuantizer = pVp9Enc->qpRangeI.nMinQP;
+    pVp9Enc->AndroidVp9EncoderType.nMaxQuantizer = pVp9Enc->qpRangeI.nMaxQP;
+
+    pOMXComponent->GetParameter      = &Exynos_VP9Enc_GetParameter;
+    pOMXComponent->SetParameter      = &Exynos_VP9Enc_SetParameter;
+    pOMXComponent->GetConfig         = &Exynos_VP9Enc_GetConfig;
+    pOMXComponent->SetConfig         = &Exynos_VP9Enc_SetConfig;
+    pOMXComponent->GetExtensionIndex = &Exynos_VP9Enc_GetExtensionIndex;
+    pOMXComponent->ComponentRoleEnum = &Exynos_VP9Enc_ComponentRoleEnum;
+    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
+
+    pExynosComponent->exynos_codec_componentInit      = &Exynos_VP9Enc_Init;
+    pExynosComponent->exynos_codec_componentTerminate = &Exynos_VP9Enc_Terminate;
+
+    pVideoEnc->exynos_codec_srcInputProcess  = &Exynos_VP9Enc_srcInputBufferProcess;
+    pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_VP9Enc_srcOutputBufferProcess;
+    pVideoEnc->exynos_codec_dstInputProcess  = &Exynos_VP9Enc_dstInputBufferProcess;
+    pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_VP9Enc_dstOutputBufferProcess;
+
+    pVideoEnc->exynos_codec_start            = &VP9CodecStart;
+    pVideoEnc->exynos_codec_stop             = &VP9CodecStop;
+    pVideoEnc->exynos_codec_bufferProcessRun = &VP9CodecOutputBufferProcessRun;
+    pVideoEnc->exynos_codec_enqueueAllBuffer = &VP9CodecEnqueueAllBuffer;
+
+    pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+
+    pVideoEnc->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
+
+    pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+    if (pVideoEnc->hSharedMemory == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to SharedMemory_Open", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pVp9Enc);
+        pVp9Enc = pVideoEnc->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    pVp9Enc->hMFCVp9Handle.videoInstInfo.eCodecType = VIDEO_CODING_VP9;
+    if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
+        pVp9Enc->hMFCVp9Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
+    else
+        pVp9Enc->hMFCVp9Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
+
+    if (Exynos_Video_GetInstInfo(&(pVp9Enc->hMFCVp9Handle.videoInstInfo), VIDEO_FALSE /* enc */) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
+        Exynos_OSAL_Free(pVp9Enc);
+        pVp9Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for enc : ext(%d)/temporal-svc(%d)/qp-range(%d)/pvc(%d)/CA(%d)",
+            pExynosComponent, __FUNCTION__,
+            (pVp9Enc->hMFCVp9Handle.videoInstInfo.supportInfo.enc.nSpareSize),
+            (pVp9Enc->hMFCVp9Handle.videoInstInfo.supportInfo.enc.bTemporalSvcSupport),
+            (pVp9Enc->hMFCVp9Handle.videoInstInfo.supportInfo.enc.bQpRangePBSupport),
+            (pVp9Enc->hMFCVp9Handle.videoInstInfo.supportInfo.enc.bPVCSupport),
+            (pVp9Enc->hMFCVp9Handle.videoInstInfo.supportInfo.enc.bColorAspectsSupport));
+
+    if (pVp9Enc->hMFCVp9Handle.videoInstInfo.supportInfo.enc.nSpareSize > 0)
+        pVideoEnc->nInbufSpareSize = pVp9Enc->hMFCVp9Handle.videoInstInfo.supportInfo.enc.nSpareSize;
+
+    Exynos_Input_SetSupportFormat(pExynosComponent);
+    SetProfileLevel(pExynosComponent);
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_AddVendorExt(hComponent, "sec-ext-enc-qp-range", (OMX_INDEXTYPE)OMX_IndexConfigVideoQPRange);
+#endif
+
+    pExynosComponent->currentState = OMX_StateLoaded;
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_VP9ENC_HANDLE            *pVp9Enc            = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (((pExynosComponent->currentState != OMX_StateInvalid) &&
+         (pExynosComponent->currentState != OMX_StateLoaded)) ||
+        ((pExynosComponent->currentState == OMX_StateLoaded) &&
+         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle))) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] in curState(0x%x), OMX_FreeHandle() is called. change to OMX_StateInvalid",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        Exynos_OMX_Component_AbnormalTermination(hComponent);
+    }
+
+    Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
+
+    Exynos_OSAL_Free(pExynosComponent->componentName);
+    pExynosComponent->componentName = NULL;
+
+    pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    if (pVp9Enc != NULL) {
+        Exynos_OSAL_Free(pVp9Enc);
+        pVp9Enc = pVideoEnc->hCodecHandle = NULL;
+    }
+
+#ifdef USE_ANDROID
+    Exynos_OSAL_DelVendorExts(hComponent);
+#endif
+
+    ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to VideoDecodeComponentDeinit", pExynosComponent, __FUNCTION__);
+        goto EXIT;
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/component/video/enc/vp9/Exynos_OMX_Vp9enc.h b/openmax/component/video/enc/vp9/Exynos_OMX_Vp9enc.h
new file mode 100755 (executable)
index 0000000..b066b71
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OMX_Vp9enc.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2015.04.14 : Create
+ */
+
+#ifndef EXYNOS_OMX_VP9_ENC_COMPONENT
+#define EXYNOS_OMX_VP9_ENC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "OMX_Video.h"
+
+#include "ExynosVideoApi.h"
+
+typedef struct _EXYNOS_MFC_VP9ENC_HANDLE
+{
+    OMX_HANDLETYPE  hMFCHandle;
+
+    OMX_U32     indexTimestamp;
+    OMX_U32     outputIndexTimestamp;
+    OMX_BOOL    bConfiguredMFCSrc;
+    OMX_BOOL    bConfiguredMFCDst;
+
+    ExynosVideoEncOps           *pEncOps;
+    ExynosVideoEncBufferOps     *pInbufOps;
+    ExynosVideoEncBufferOps     *pOutbufOps;
+    ExynosVideoEncParam          encParam;
+    ExynosVideoInstInfo          videoInstInfo;
+
+    #define MAX_PROFILE_NUM 4
+    OMX_VIDEO_VP9PROFILETYPE   profiles[MAX_PROFILE_NUM];
+    OMX_S32                    nProfileCnt;
+    OMX_VIDEO_VP9LEVELTYPE     maxLevel;
+} EXYNOS_MFC_VP9ENC_HANDLE;
+
+typedef struct _EXYNOS_VP9ENC_HANDLE
+{
+    /* OMX Codec specific */
+    OMX_VIDEO_PARAM_VP9TYPE             VP9Component[ALL_PORT_NUM];
+    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM];
+    OMX_U32                             nPFrames;  /* IDR period control */
+    OMX_VIDEO_QPRANGE                   qpRangeI;
+    OMX_VIDEO_QPRANGE                   qpRangeP;
+
+    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE  AndroidVp9EncoderType;
+
+    /* SEC MFC Codec specific */
+    EXYNOS_MFC_VP9ENC_HANDLE hMFCVp9Handle;
+
+    OMX_BOOL        bSourceStart;
+    OMX_BOOL        bDestinationStart;
+    OMX_HANDLETYPE  hSourceStartEvent;
+    OMX_HANDLETYPE  hDestinationInStartEvent;
+    OMX_HANDLETYPE  hDestinationOutStartEvent;
+
+    EXYNOS_QUEUE    bypassBufferInfoQ;
+} EXYNOS_VP9ENC_HANDLE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName);
+                OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/openmax/component/video/enc/vp9/Makefile.am b/openmax/component/video/enc/vp9/Makefile.am
new file mode 100755 (executable)
index 0000000..2706097
--- /dev/null
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libOMX.Exynos.VP9.Encoder.la
+libdir = @prefix@/lib/omx
+
+libOMX_Exynos_VP9_Encoder_la_SOURCES = Exynos_OMX_Vp9enc.c \
+                                       library_register.c
+
+libOMX_Exynos_VP9_Encoder_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                                      $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la \
+                                      $(top_builddir)/openmax/component/video/enc/libExynosOMX_Venc.la \
+                                      $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la
+
+libOMX_Exynos_VP9_Encoder_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                                      -I$(top_srcdir)/openmax/include/exynos \
+                                      -I$(top_srcdir)/openmax/osal \
+                                      -I$(top_srcdir)/openmax/core \
+                                      -I$(top_srcdir)/openmax/component/common \
+                                      -I$(top_srcdir)/openmax/component/video/enc \
+                                      -I$(top_srcdir)/exynos/libvideocodec/include
+
+libOMX_Exynos_VP9_Encoder_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF -DUSE_VP9_SUPPORT
+libOMX_Exynos_VP9_Encoder_la_CFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable -Wno-unused-function
+
+libOMX_Exynos_VP9_Encoder_la_LDFLAGS = -module -avoid-version
diff --git a/openmax/component/video/enc/vp9/library_register.c b/openmax/component/video/enc/vp9/library_register.c
new file mode 100755 (executable)
index 0000000..d74b842
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2015.04.14 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "library_register.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VP9_ENC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent)
+{
+    FunctionIn();
+
+    if (ppExynosComponent == NULL)
+        goto EXIT;
+
+    /* component 1 - video encoder VP9 */
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_VP9_ENC);
+    Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_VP9_ENC_ROLE);
+    ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+    FunctionOut();
+
+    return MAX_COMPONENT_NUM;
+}
diff --git a/openmax/component/video/enc/vp9/library_register.h b/openmax/component/video/enc/vp9/library_register.h
new file mode 100755 (executable)
index 0000000..bcb1b21
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright 2013 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        library_register.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2015.04.14 : Create
+ */
+
+#ifndef EXYNOS_OMX_VP9_ENC_REG
+#define EXYNOS_OMX_VP9_ENC_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "Exynos_OMX_Component_Register.h"
+
+
+#define OSCL_EXPORT_REF __attribute__((visibility("default")))
+#define MAX_COMPONENT_NUM       1
+#define MAX_COMPONENT_ROLE_NUM  1
+
+/* VP9 */
+#define EXYNOS_OMX_COMPONENT_VP9_ENC      "OMX.Exynos.VP9.Encoder"
+#define EXYNOS_OMX_COMPONENT_VP9_ENC_ROLE "video_encoder.vp9"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
diff --git a/openmax/core/Exynos_OMX_Component_Register.c b/openmax/core/Exynos_OMX_Component_Register.c
new file mode 100755 (executable)
index 0000000..7a8107a
--- /dev/null
@@ -0,0 +1,686 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Component_Register.c
+ * @brief      Exynos OpenMAX IL Component Register
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *    2012.02.20 : Create
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <assert.h>
+#include <dirent.h>
+
+#include "OMX_Component.h"
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Library.h"
+#include "Exynos_OMX_Component_Register.h"
+#include "Exynos_OMX_Macros.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_COMP_REGS"
+#include "Exynos_OSAL_Log.h"
+
+static EXYNOS_OMX_COMPONENT_REGLIST gTableComponents[] = {
+#ifndef USE_CUSTOM_COMPONENT_SUPPORT
+    /* Video Decoder */
+    {
+        { "OMX.Exynos.AVC.Decoder",
+          {
+            {"video_decoder.avc"},
+          },
+          1,
+        },
+        "libOMX.Exynos.AVC.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.AVC.Decoder.secure",
+          {
+            {"video_decoder.avc"},
+          },
+          1,
+        },
+        "libOMX.Exynos.AVC.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.HEVC.Decoder",
+          {
+            {"video_decoder.hevc"},
+          },
+          1,
+        },
+        "libOMX.Exynos.HEVC.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.HEVC.Decoder.secure",
+          {
+            {"video_decoder.hevc"},
+          },
+          1,
+        },
+        "libOMX.Exynos.HEVC.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.MPEG2.Decoder",
+          {
+            {"video_decoder.mpeg2"},
+          },
+          1,
+        },
+        "libOMX.Exynos.MPEG2.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.MPEG4.Decoder",
+          {
+            {"video_decoder.mpeg4"},
+          },
+          1,
+        },
+        "libOMX.Exynos.MPEG4.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.MPEG4.Decoder.secure",
+          {
+            {"video_decoder.mpeg4"},
+          },
+          1,
+        },
+        "libOMX.Exynos.MPEG4.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.H263.Decoder",
+          {
+            {"video_decoder.h263"},
+          },
+          1,
+        },
+        "libOMX.Exynos.MPEG4.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.WMV.Decoder",
+          {
+            {"video_decoder.vc1"},
+          },
+          1,
+        },
+        "libOMX.Exynos.WMV.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.VP8.Decoder",
+          {
+            {"video_decoder.vp8"},
+          },
+          1,
+        },
+        "libOMX.Exynos.VP8.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.VP9.Decoder",
+          {
+            {"video_decoder.vp9"},
+          },
+          1,
+        },
+        "libOMX.Exynos.VP9.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.VP9.Decoder.secure",
+          {
+            {"video_decoder.vp9"},
+          },
+          1,
+        },
+          "libOMX.Exynos.VP9.Decoder.so"
+    },
+#else
+    {
+        { "OMX.Exynos.avc.dec",
+          {
+            {"video_decoder.avc"},
+          },
+          1,
+        },
+        "libOMX.Exynos.AVC.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.avc.dec.secure",
+          {
+            {"video_decoder.avc"},
+          },
+          1,
+        },
+        "libOMX.Exynos.AVC.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.hevc.dec",
+          {
+            {"video_decoder.hevc"},
+          },
+          1,
+        },
+        "libOMX.Exynos.HEVC.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.hevc.dec.secure",
+          {
+            {"video_decoder.hevc"},
+          },
+          1,
+        },
+        "libOMX.Exynos.HEVC.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.mpeg2.dec",
+          {
+            {"video_decoder.mpeg2"},
+          },
+          1,
+        },
+        "libOMX.Exynos.MPEG2.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.mpeg4.dec",
+          {
+            {"video_decoder.mpeg4"},
+          },
+          1,
+        },
+        "libOMX.Exynos.MPEG4.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.mpeg4.dec.secure",
+          {
+            {"video_decoder.mpeg4"},
+          },
+          1,
+        },
+        "libOMX.Exynos.MPEG4.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.h263.dec",
+          {
+            {"video_decoder.h263"},
+          },
+          1,
+        },
+        "libOMX.Exynos.MPEG4.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.vc1.dec",
+          {
+            {"video_decoder.vc1"},
+          },
+          1,
+        },
+        "libOMX.Exynos.WMV.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.vp8.dec",
+          {
+            {"video_decoder.vp8"},
+          },
+          1,
+        },
+        "libOMX.Exynos.VP8.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.vp9.dec",
+          {
+            {"video_decoder.vp9"},
+          },
+          1,
+        },
+        "libOMX.Exynos.VP9.Decoder.so"
+    },
+    {
+        { "OMX.Exynos.vp9.dec.secure",
+          {
+            {"video_decoder.vp9"},
+          },
+          1,
+        },
+          "libOMX.Exynos.VP9.Decoder.so"
+    },
+#endif
+
+    /* Video Encoder */
+    {
+        { "OMX.Exynos.AVC.Encoder",
+          {
+            {"video_encoder.avc"},
+          },
+          1,
+        },
+        "libOMX.Exynos.AVC.Encoder.so"
+    },
+    {
+        { "OMX.Exynos.AVC.Encoder.secure",
+          {
+            {"video_encoder.avc-wfd"},
+          },
+          1,
+        },
+        "libOMX.Exynos.AVC.Encoder.so"
+    },
+    {
+        { "OMX.Exynos.HEVC.Encoder",
+          {
+            {"video_encoder.hevc"},
+          },
+          1,
+        },
+        "libOMX.Exynos.HEVC.Encoder.so"
+    },
+    {
+        { "OMX.Exynos.HEVC.Encoder.secure",
+          {
+            {"video_encoder.hevc-wfd"},
+          },
+          1,
+        },
+        "libOMX.Exynos.HEVC.Encoder.so"
+    },
+    {
+        { "OMX.Exynos.MPEG4.Encoder",
+          {
+            {"video_encoder.mpeg4"},
+          },
+          1,
+        },
+        "libOMX.Exynos.MPEG4.Encoder.so"
+    },
+    {
+        { "OMX.Exynos.H263.Encoder",
+          {
+            {"video_encoder.h263"},
+          },
+          1,
+        },
+        "libOMX.Exynos.MPEG4.Encoder.so"
+    },
+    {
+        { "OMX.Exynos.VP8.Encoder",
+          {
+            {"video_encoder.vp8"},
+          },
+          1,
+        },
+        "libOMX.Exynos.VP8.Encoder.so"
+    },
+    {
+        { "OMX.Exynos.VP9.Encoder",
+          {
+            {"video_encoder.vp9"},
+          },
+          1,
+        },
+        "libOMX.Exynos.VP9.Encoder.so"
+    },
+    {
+        { "OMX.Exynos.AVC.WFD.Encoder",
+            {
+                {"video_encoder.avc-wfd"},
+            },
+            1,
+        },
+        "libOMX.Exynos.AVC.WFD.Encoder.so"
+    },
+    {
+        { "OMX.Exynos.AVC.WFD.Encoder.secure",
+            {
+                {"video_encoder.avc-wfd"},
+            },
+            1,
+        },
+        "libOMX.Exynos.AVC.WFD.Encoder.so"
+    },
+
+    // Only video components are registered.  (2018-05-21)
+};
+
+static void registComponent(
+    char                         *sLibName,
+    EXYNOS_OMX_COMPONENT_REGLIST *pComponentList,
+    int                          *pNumComponents)
+{
+    const char *libPath = NULL;
+    int nComponents = 0;
+    unsigned int i;
+
+    FunctionIn();
+
+    if ((sLibName == NULL) ||
+        (pComponentList == NULL) ||
+        (pNumComponents == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        return;
+    }
+
+    nComponents = (*pNumComponents);
+    libPath = Exynos_OSAL_GetLibPath();
+
+    for (i = 0; i < sizeof(gTableComponents)/sizeof(EXYNOS_OMX_COMPONENT_REGLIST); i++) {
+        if (Exynos_OSAL_Strcmp(sLibName, gTableComponents[i].libName) == 0) {
+            Exynos_OSAL_Memcpy(&(pComponentList[nComponents]), &(gTableComponents[i]), sizeof(gTableComponents[i]));
+            Exynos_OSAL_Memset(pComponentList[nComponents].libName, 0, MAX_OMX_COMPONENT_LIBNAME_SIZE);
+            Exynos_OSAL_Strcpy(pComponentList[nComponents].libName, (OMX_PTR)libPath);
+            Exynos_OSAL_Strcat(pComponentList[nComponents].libName, sLibName);
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "%s: %s", pComponentList[nComponents].libName, gTableComponents[i].component.componentName);
+            nComponents++;
+        }
+    }
+
+    (*pNumComponents) = nComponents;
+
+EXIT:
+    FunctionOut();
+
+    return;
+}
+
+OMX_ERRORTYPE Exynos_OMX_Component_Register(EXYNOS_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum)
+{
+    OMX_ERRORTYPE  ret = OMX_ErrorNone;
+    int            componentNum = 0, totalCompNum = 0;
+    const char    *libPath = NULL;
+    char          *libName = NULL;
+    const char    *errorMsg = NULL;
+    DIR           *dir = NULL;
+    struct dirent *d = NULL;
+
+    int i, j;
+
+    int (*Exynos_OMX_COMPONENT_Library_Register)(ExynosRegisterComponentType **exynosComponents);
+    ExynosRegisterComponentType **exynosComponentsTemp = NULL;
+    EXYNOS_OMX_COMPONENT_REGLIST *componentList        = NULL;
+
+    FunctionIn();
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s lib is loaded", (IS_64BIT_OS? "64bit":"32bit"));
+    libPath = Exynos_OSAL_GetLibPath();
+    dir = opendir(libPath);
+    if (dir == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to opendir(%s)", __FUNCTION__, libPath);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    componentList = (EXYNOS_OMX_COMPONENT_REGLIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM);
+    if (componentList == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Malloc()", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+    Exynos_OSAL_Memset(componentList, 0, sizeof(EXYNOS_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM);
+
+    libName = Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_LIBNAME_SIZE);
+    if (libName == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Malloc()", __FUNCTION__);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    while ((d = readdir(dir)) != NULL) {
+        OMX_HANDLETYPE soHandle = NULL;
+
+        if (Exynos_OSAL_CheckLibName(d->d_name) == 0) {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "Loading the library: %s", d->d_name);
+
+#ifndef USE_DISABLE_RAPID_COMPONENT_LOAD
+            registComponent(d->d_name, componentList, &totalCompNum);
+#else
+            Exynos_OSAL_Memset(libName, 0, MAX_OMX_COMPONENT_LIBNAME_SIZE);
+            Exynos_OSAL_Strcpy(libName, (OMX_PTR)libPath);
+            Exynos_OSAL_Strcat(libName, d->d_name);
+
+            if ((soHandle = Exynos_OSAL_dlopen(libName, RTLD_NOW)) != NULL) {
+                Exynos_OSAL_dlerror();    /* clear error*/
+                if ((Exynos_OMX_COMPONENT_Library_Register = Exynos_OSAL_dlsym(soHandle, "Exynos_OMX_COMPONENT_Library_Register")) != NULL) {
+                    componentNum = (*Exynos_OMX_COMPONENT_Library_Register)(NULL);
+                    exynosComponentsTemp = (ExynosRegisterComponentType **)Exynos_OSAL_Malloc(sizeof(ExynosRegisterComponentType *) * componentNum);
+                    if (exynosComponentsTemp == NULL) {
+                        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Malloc()", __FUNCTION__);
+                        ret = OMX_ErrorInsufficientResources;
+                        goto EXIT;
+                    }
+
+                    for (i = 0; i < componentNum; i++) {
+                        exynosComponentsTemp[i] = Exynos_OSAL_Malloc(sizeof(ExynosRegisterComponentType));
+                        if (exynosComponentsTemp[i] == NULL) {
+                            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Malloc()", __FUNCTION__);
+                            for (j = 0; j < i; j++) {
+                                Exynos_OSAL_Free(exynosComponentsTemp[j]);
+                                exynosComponentsTemp[j] = NULL;
+                            }
+
+                            Exynos_OSAL_Free(exynosComponentsTemp);
+                            exynosComponentsTemp = NULL;
+                            ret = OMX_ErrorInsufficientResources;
+                            goto EXIT;
+                        }
+
+                        Exynos_OSAL_Memset(exynosComponentsTemp[i], 0, sizeof(ExynosRegisterComponentType));
+                    }
+
+                    (*Exynos_OMX_COMPONENT_Library_Register)(exynosComponentsTemp);
+
+                    for (i = 0; i < componentNum; i++) {
+                        Exynos_OSAL_Strcpy(componentList[totalCompNum].component.componentName, exynosComponentsTemp[i]->componentName);
+                        for (j = 0; j < (int)exynosComponentsTemp[i]->totalRoleNum; j++)
+                            Exynos_OSAL_Strcpy(componentList[totalCompNum].component.roles[j], exynosComponentsTemp[i]->roles[j]);
+                        componentList[totalCompNum].component.totalRoleNum = exynosComponentsTemp[i]->totalRoleNum;
+
+                        Exynos_OSAL_Strcpy(componentList[totalCompNum].libName, libName);
+
+                        totalCompNum++;
+                    }
+
+                    for (i = 0; i < componentNum; i++) {
+                        Exynos_OSAL_Free(exynosComponentsTemp[i]);
+                        exynosComponentsTemp[i] = NULL;
+                    }
+
+                    Exynos_OSAL_Free(exynosComponentsTemp);
+                    exynosComponentsTemp = NULL;
+                } else {
+                    if ((errorMsg = Exynos_OSAL_dlerror()) != NULL)
+                        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "dlsym failed: %s", errorMsg);
+                }
+
+                Exynos_OSAL_dlclose(soHandle);
+                soHandle = NULL;
+            } else {
+                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "dlopen failed: %s", Exynos_OSAL_dlerror());
+            }
+#endif
+        } else {
+            /* not a component name line. skip */
+            continue;
+        }
+    }
+
+    *compList = componentList;
+    *compNum = totalCompNum;
+
+EXIT:
+    if ((ret != OMX_ErrorNone) &&
+        (componentList != NULL)) {
+        Exynos_OSAL_Free(componentList);
+        componentList = NULL;
+    }
+
+    if (dir != NULL) {
+        closedir(dir);
+        dir = NULL;
+    }
+
+    if (libName != NULL) {
+        Exynos_OSAL_Free(libName);
+        libName = NULL;
+    }
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_Component_Unregister(EXYNOS_OMX_COMPONENT_REGLIST *componentList)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    Exynos_OSAL_Free(componentList);
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentAPICheck(OMX_COMPONENTTYPE *component)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if ((NULL == component->GetComponentVersion)    ||
+        (NULL == component->SendCommand)            ||
+        (NULL == component->GetParameter)           ||
+        (NULL == component->SetParameter)           ||
+        (NULL == component->GetConfig)              ||
+        (NULL == component->SetConfig)              ||
+        (NULL == component->GetExtensionIndex)      ||
+        (NULL == component->GetState)               ||
+#ifdef TUNNELING_SUPPORT
+        (NULL == component->ComponentTunnelRequest) ||
+#endif
+        (NULL == component->UseBuffer)              ||
+        (NULL == component->AllocateBuffer)         ||
+        (NULL == component->FreeBuffer)             ||
+        (NULL == component->EmptyThisBuffer)        ||
+        (NULL == component->FillThisBuffer)         ||
+        (NULL == component->SetCallbacks)           ||
+        (NULL == component->ComponentDeInit)        ||
+#ifdef EGL_IMAGE_SUPPORT
+        (NULL == component->UseEGLImage)            ||
+#endif
+        (NULL == component->ComponentRoleEnum))
+        ret = OMX_ErrorInvalidComponent;
+    else
+        ret = OMX_ErrorNone;
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentLoad(EXYNOS_OMX_COMPONENT *exynos_component)
+{
+    OMX_ERRORTYPE      ret           = OMX_ErrorNone;
+    OMX_HANDLETYPE     libHandle     = NULL;
+    OMX_COMPONENTTYPE *pOMXComponent = NULL;
+
+    FunctionIn();
+
+    OMX_ERRORTYPE (*Exynos_OMX_ComponentInit)(OMX_HANDLETYPE hComponent, OMX_STRING componentName);
+
+    libHandle = Exynos_OSAL_dlopen((OMX_STRING)exynos_component->libName, RTLD_NOW);
+    if (libHandle == NULL) {
+        ret = OMX_ErrorInvalidComponentName;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_dlopen(%s)", __FUNCTION__, exynos_component->libName);
+        goto EXIT;
+    }
+
+    Exynos_OMX_ComponentInit = Exynos_OSAL_dlsym(libHandle, "Exynos_OMX_ComponentInit");
+    if (Exynos_OMX_ComponentInit == NULL) {
+        Exynos_OSAL_dlclose(libHandle);
+        ret = OMX_ErrorInvalidComponent;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_dlsym(Exynos_OMX_ComponentInit)", __FUNCTION__);
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_COMPONENTTYPE));
+    if (pOMXComponent == NULL) {
+        Exynos_OSAL_dlclose(libHandle);
+        ret = OMX_ErrorInsufficientResources;
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Malloc() (ret:0x%x)", __FUNCTION__, ret);
+        goto EXIT;
+    }
+    INIT_SET_SIZE_VERSION(pOMXComponent, OMX_COMPONENTTYPE);
+
+    ret = (*Exynos_OMX_ComponentInit)((OMX_HANDLETYPE)pOMXComponent, (OMX_STRING)exynos_component->componentName);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Free(pOMXComponent);
+        Exynos_OSAL_dlclose(libHandle);
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OMX_ComponentInit() (ret:0x%x)", __FUNCTION__, ret);
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    } else {
+        if (Exynos_OMX_ComponentAPICheck(pOMXComponent) != OMX_ErrorNone) {
+            if (NULL != pOMXComponent->ComponentDeInit)
+                pOMXComponent->ComponentDeInit(pOMXComponent);
+
+            Exynos_OSAL_Free(pOMXComponent);
+            Exynos_OSAL_dlclose(libHandle);
+            ret = OMX_ErrorInvalidComponent;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OMX_ComponentAPICheck()", __FUNCTION__);
+            goto EXIT;
+        }
+
+        exynos_component->libHandle     = libHandle;
+        exynos_component->pOMXComponent = pOMXComponent;
+        ret = OMX_ErrorNone;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_ComponentUnload(EXYNOS_OMX_COMPONENT *exynos_component)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = NULL;
+
+    FunctionIn();
+
+    if (!exynos_component) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = exynos_component->pOMXComponent;
+    if (pOMXComponent != NULL) {
+        pOMXComponent->ComponentDeInit(pOMXComponent);
+        Exynos_OSAL_Free(pOMXComponent);
+        exynos_component->pOMXComponent = NULL;
+    }
+
+    if (exynos_component->libHandle != NULL) {
+        Exynos_OSAL_dlclose(exynos_component->libHandle);
+        exynos_component->libHandle = NULL;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
diff --git a/openmax/core/Exynos_OMX_Component_Register.h b/openmax/core/Exynos_OMX_Component_Register.h
new file mode 100755 (executable)
index 0000000..1860978
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Component_Register.h
+ * @brief      Exynos OpenMAX IL Component Register
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *    2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_COMPONENT_REG
+#define EXYNOS_OMX_COMPONENT_REG
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+#include "OMX_Component.h"
+
+
+typedef struct _ExynosRegisterComponentType
+{
+    OMX_U8  componentName[MAX_OMX_COMPONENT_NAME_SIZE];
+    OMX_U8  roles[MAX_OMX_COMPONENT_ROLE_NUM][MAX_OMX_COMPONENT_ROLE_SIZE];
+    OMX_U32 totalRoleNum;
+} ExynosRegisterComponentType;
+
+typedef struct _EXYNOS_OMX_COMPONENT_REGLIST
+{
+    ExynosRegisterComponentType component;
+    OMX_U8  libName[MAX_OMX_COMPONENT_LIBNAME_SIZE];
+} EXYNOS_OMX_COMPONENT_REGLIST;
+
+struct EXYNOS_OMX_COMPONENT;
+typedef struct _EXYNOS_OMX_COMPONENT
+{
+    OMX_U8                        componentName[MAX_OMX_COMPONENT_NAME_SIZE];
+    OMX_U8                        libName[MAX_OMX_COMPONENT_LIBNAME_SIZE];
+    OMX_HANDLETYPE                libHandle;
+    OMX_COMPONENTTYPE            *pOMXComponent;
+    struct _EXYNOS_OMX_COMPONENT *nextOMXComp;
+} EXYNOS_OMX_COMPONENT;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+OMX_ERRORTYPE Exynos_OMX_Component_Register(EXYNOS_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum);
+OMX_ERRORTYPE Exynos_OMX_Component_Unregister(EXYNOS_OMX_COMPONENT_REGLIST *componentList);
+OMX_ERRORTYPE Exynos_OMX_ComponentLoad(EXYNOS_OMX_COMPONENT *exynos_component);
+OMX_ERRORTYPE Exynos_OMX_ComponentUnload(EXYNOS_OMX_COMPONENT *exynos_component);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/core/Exynos_OMX_Core.c b/openmax/core/Exynos_OMX_Core.c
new file mode 100755 (executable)
index 0000000..77bc5e7
--- /dev/null
@@ -0,0 +1,488 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Core.c
+ * @brief      Exynos OpenMAX IL Core
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ *             HyeYeon Chung (hyeon.chung@samsung.com)
+ *             Yunji Kim (yunji.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *    2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+#include "Exynos_OMX_Core.h"
+#include "Exynos_OMX_Component_Register.h"
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OMX_Resourcemanager.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OMX_Basecomponent.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_OMX_CORE"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+static int gInitialized = 0;
+static OMX_U32 gComponentNum = 0;
+
+static EXYNOS_OMX_COMPONENT_REGLIST *gComponentList = NULL;
+static EXYNOS_OMX_COMPONENT *gLoadComponentList = NULL;
+static OMX_HANDLETYPE ghLoadComponentListMutex = NULL;
+
+static int gRefCount = 0;
+static pthread_mutex_t gMutex;
+
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_Init(void)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    pthread_mutex_lock(&gMutex);
+
+    if (gInitialized == 0) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] core is not initialized", __FUNCTION__);
+        if (Exynos_OMX_Component_Register(&gComponentList, &gComponentNum)) {
+            ret = OMX_ErrorInsufficientResources;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OMX_Component_Register()", __FUNCTION__);
+            goto EXIT;
+        }
+
+        ret = Exynos_OMX_ResourceManager_Init();
+        if (OMX_ErrorNone != ret) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OMX_ResourceManager_Init()", __FUNCTION__);
+            goto EXIT;
+        }
+
+        ret = Exynos_OSAL_MutexCreate(&ghLoadComponentListMutex);
+        if (OMX_ErrorNone != ret) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_MutexCreate()", __FUNCTION__);
+            goto EXIT;
+        }
+
+        gInitialized = 1;
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] core is initialized", __FUNCTION__);
+    }
+
+    gRefCount++;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] current refCount(%d)", __FUNCTION__, gRefCount);
+
+EXIT:
+    pthread_mutex_unlock(&gMutex);
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_Deinit(void)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    pthread_mutex_lock(&gMutex);
+
+
+    gRefCount--;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] current refCount(%d)", __FUNCTION__, gRefCount);
+
+    if (gRefCount > 0)
+        goto EXIT;
+
+    Exynos_OSAL_MutexTerminate(ghLoadComponentListMutex);
+    ghLoadComponentListMutex = NULL;
+
+    Exynos_OMX_ResourceManager_Deinit();
+
+    if (OMX_ErrorNone != Exynos_OMX_Component_Unregister(gComponentList)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OMX_Component_Unregister()", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    gComponentList = NULL;
+    gComponentNum = 0;
+    gInitialized = 0;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] core is deinitialized", __FUNCTION__);
+
+EXIT:
+
+    pthread_mutex_unlock(&gMutex);
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_ComponentNameEnum(
+    OMX_OUT OMX_STRING cComponentName,
+    OMX_IN  OMX_U32 nNameLength,
+    OMX_IN  OMX_U32 nIndex)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (nIndex >= gComponentNum) {
+        ret = OMX_ErrorNoMore;
+        goto EXIT;
+    }
+
+    snprintf(cComponentName, nNameLength, "%s", gComponentList[nIndex].component.componentName);
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_GetHandle(
+    OMX_OUT OMX_HANDLETYPE *pHandle,
+    OMX_IN  OMX_STRING cComponentName,
+    OMX_IN  OMX_PTR pAppData,
+    OMX_IN  OMX_CALLBACKTYPE *pCallBacks)
+{
+    OMX_ERRORTYPE         ret = OMX_ErrorNone;
+    EXYNOS_OMX_COMPONENT *loadComponent;
+    EXYNOS_OMX_COMPONENT *currentComponent;
+    unsigned int i = 0;
+
+    FunctionIn();
+
+    if (gInitialized != 1) {
+        ret = OMX_ErrorNotReady;
+        goto EXIT;
+    }
+
+    if ((pHandle == NULL) || (cComponentName == NULL) || (pCallBacks == NULL)) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] ComponentName : %s", __FUNCTION__, cComponentName);
+
+    for (i = 0; i < gComponentNum; i++) {
+        if (Exynos_OSAL_Strcmp(cComponentName, gComponentList[i].component.componentName) == 0) {
+            loadComponent = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_COMPONENT));
+            if (loadComponent == NULL) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Malloc()", __FUNCTION__);
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+
+            Exynos_OSAL_Memset(loadComponent, 0, sizeof(EXYNOS_OMX_COMPONENT));
+
+            Exynos_OSAL_Strcpy(loadComponent->libName, gComponentList[i].libName);
+            Exynos_OSAL_Strcpy(loadComponent->componentName, gComponentList[i].component.componentName);
+            ret = Exynos_OMX_ComponentLoad(loadComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OSAL_Free(loadComponent);
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OMX_ComponentLoad()", __FUNCTION__);
+                goto EXIT;
+            }
+
+            ret = loadComponent->pOMXComponent->SetCallbacks(loadComponent->pOMXComponent, pCallBacks, pAppData);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OMX_ComponentUnload(loadComponent);
+                Exynos_OSAL_Free(loadComponent);
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to SetCallbacks()", __FUNCTION__);
+                goto EXIT;
+            }
+
+            Exynos_OSAL_MutexLock(ghLoadComponentListMutex);
+            ret = Exynos_OMX_Get_Resource(loadComponent->pOMXComponent);
+            if (ret != OMX_ErrorNone) {
+                Exynos_OMX_ComponentUnload(loadComponent);
+                Exynos_OSAL_Free(loadComponent);
+                Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex);
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OMX_Get_Resource()", __FUNCTION__);
+                goto EXIT;
+            }
+
+            if (gLoadComponentList == NULL) {
+                gLoadComponentList = loadComponent;
+            } else {
+                currentComponent = gLoadComponentList;
+                while (currentComponent->nextOMXComp != NULL) {
+                    currentComponent = currentComponent->nextOMXComp;
+                }
+                currentComponent->nextOMXComp = loadComponent;
+            }
+            Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex);
+
+            *pHandle = loadComponent->pOMXComponent;
+            ret = OMX_ErrorNone;
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] %s is created", __FUNCTION__, cComponentName);
+            goto EXIT;
+        }
+    }
+
+    ret = OMX_ErrorComponentNotFound;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE         ret = OMX_ErrorNone;
+    EXYNOS_OMX_COMPONENT *currentComponent = NULL;
+    EXYNOS_OMX_COMPONENT *deleteComponent  = NULL;
+
+    FunctionIn();
+
+    if ((gInitialized != 1) ||
+        (gLoadComponentList == NULL)) {
+        ret = OMX_ErrorNotReady;
+        goto EXIT;
+    }
+
+    if (!hComponent) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_MutexLock(ghLoadComponentListMutex);
+    Exynos_OMX_Release_Resource(hComponent);
+
+    if (gLoadComponentList->pOMXComponent == hComponent) {
+        deleteComponent = gLoadComponentList;
+        gLoadComponentList = gLoadComponentList->nextOMXComp;
+    } else {
+        currentComponent = gLoadComponentList;
+
+        while ((currentComponent != NULL) &&
+               (currentComponent->nextOMXComp != NULL)) {
+            if (currentComponent->nextOMXComp->pOMXComponent == hComponent) {
+                deleteComponent = currentComponent->nextOMXComp;
+                currentComponent->nextOMXComp = deleteComponent->nextOMXComp;
+                break;
+            }
+            currentComponent = currentComponent->nextOMXComp;
+        }
+
+        if (deleteComponent == NULL) {
+            ret = OMX_ErrorComponentNotFound;
+            Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex);
+            goto EXIT;
+        }
+    }
+    Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex);
+
+    Exynos_OMX_ComponentUnload(deleteComponent);
+    Exynos_OSAL_Free(deleteComponent);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_SetupTunnel(
+    OMX_IN OMX_HANDLETYPE hOutput,
+    OMX_IN OMX_U32 nPortOutput,
+    OMX_IN OMX_HANDLETYPE hInput,
+    OMX_IN OMX_U32 nPortInput)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNotImplemented;
+
+    OMX_PTR srcComponent    = hOutput;
+    OMX_U32 srcPort         = nPortOutput;
+
+    OMX_PTR dstComponent    = hInput;
+    OMX_U32 dstPort         = nPortInput;
+
+EXIT:
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE Exynos_OMX_GetContentPipe(
+    OMX_OUT OMX_HANDLETYPE *hPipe,
+    OMX_IN  OMX_STRING szURI)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNotImplemented;
+
+    OMX_PTR     pipe = hPipe;
+    OMX_STRING  name = szURI;
+EXIT:
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE Exynos_OMX_GetComponentsOfRole(
+    OMX_IN    OMX_STRING role,
+    OMX_INOUT OMX_U32 *pNumComps,
+    OMX_INOUT OMX_U8  **compNames)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    int           max_role_num = 0;
+    int i = 0, j = 0;
+
+    FunctionIn();
+
+    if (gInitialized != 1) {
+        ret = OMX_ErrorNotReady;
+        goto EXIT;
+    }
+
+    *pNumComps = 0;
+
+    for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) {
+        max_role_num = gComponentList[i].component.totalRoleNum;
+
+        for (j = 0; j < max_role_num; j++) {
+            if (Exynos_OSAL_Strcmp(gComponentList[i].component.roles[j], role) == 0) {
+                if (compNames != NULL) {
+                    Exynos_OSAL_Strcpy((OMX_STRING)compNames[*pNumComps], gComponentList[i].component.componentName);
+                }
+                *pNumComps = (*pNumComps + 1);
+            }
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE Exynos_OMX_GetRolesOfComponent (
+    OMX_IN    OMX_STRING compName,
+    OMX_INOUT OMX_U32 *pNumRoles,
+    OMX_OUT   OMX_U8 **roles)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_BOOL      detectComp = OMX_FALSE;
+    int           compNum = 0, totalRoleNum = 0;
+    int i = 0;
+
+    FunctionIn();
+
+    if (gInitialized != 1) {
+        ret = OMX_ErrorNotReady;
+        goto EXIT;
+    }
+
+    for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) {
+        if (gComponentList != NULL) {
+            if (Exynos_OSAL_Strcmp(gComponentList[i].component.componentName, compName) == 0) {
+                *pNumRoles = totalRoleNum = gComponentList[i].component.totalRoleNum;
+                compNum = i;
+                detectComp = OMX_TRUE;
+                break;
+            }
+        } else {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+    }
+
+    if (detectComp == OMX_FALSE) {
+        *pNumRoles = 0;
+        ret = OMX_ErrorComponentNotFound;
+        goto EXIT;
+    }
+
+    if (roles != NULL) {
+        for (i = 0; i < totalRoleNum; i++) {
+            Exynos_OSAL_Strcpy(roles[i], gComponentList[compNum].component.roles[i]);
+        }
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void)
+{
+    return Exynos_OMX_Init();
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void)
+{
+    return Exynos_OMX_Deinit();
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(
+    OMX_OUT   OMX_STRING        cComponentName,
+    OMX_IN    OMX_U32           nNameLength,
+    OMX_IN    OMX_U32           nIndex)
+{
+    return Exynos_OMX_ComponentNameEnum(cComponentName, nNameLength, nIndex);
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
+    OMX_OUT   OMX_HANDLETYPE   *pHandle,
+    OMX_IN    OMX_STRING        cComponentName,
+    OMX_IN    OMX_PTR           pAppData,
+    OMX_IN    OMX_CALLBACKTYPE *pCallBacks)
+{
+    return Exynos_OMX_GetHandle(pHandle, cComponentName, pAppData, pCallBacks);
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
+    OMX_IN    OMX_HANDLETYPE    hComponent)
+{
+    return Exynos_OMX_FreeHandle(hComponent);
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(
+    OMX_IN    OMX_HANDLETYPE    hOutput,
+    OMX_IN    OMX_U32           nPortOutput,
+    OMX_IN    OMX_HANDLETYPE    hInput,
+    OMX_IN    OMX_U32           nPortInput)
+{
+    return Exynos_OMX_SetupTunnel(hOutput, nPortOutput, hInput, nPortInput);
+}
+
+OMX_API OMX_ERRORTYPE OMX_GetContentPipe(
+    OMX_OUT   OMX_HANDLETYPE   *hPipe,
+    OMX_IN    OMX_STRING        szURI)
+{
+    return Exynos_OMX_GetContentPipe(hPipe, szURI);
+}
+
+OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole(
+    OMX_IN    OMX_STRING        role,
+    OMX_INOUT OMX_U32          *pNumComps,
+    OMX_INOUT OMX_U8          **compNames)
+{
+    return Exynos_OMX_GetComponentsOfRole(role, pNumComps, compNames);
+}
+
+OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent(
+    OMX_IN    OMX_STRING        compName,
+    OMX_INOUT OMX_U32          *pNumRoles,
+    OMX_OUT   OMX_U8          **roles)
+{
+    return Exynos_OMX_GetRolesOfComponent(compName, pNumRoles, roles);
+}
diff --git a/openmax/core/Exynos_OMX_Core.h b/openmax/core/Exynos_OMX_Core.h
new file mode 100755 (executable)
index 0000000..4ccebf4
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OMX_Core.h
+ * @brief      Exynos OpenMAX IL Core
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ *             HyeYeon Chung (hyeon.chung@samsung.com)
+ *             Yunji Kim (yunji.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *    2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_CORE
+#define EXYNOS_OMX_CORE
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_Init(void);
+EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_Deinit(void);
+EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_ComponentNameEnum(
+    OMX_OUT   OMX_STRING        cComponentName,
+    OMX_IN    OMX_U32           nNameLength,
+    OMX_IN    OMX_U32           nIndex);
+EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_GetHandle(
+    OMX_OUT   OMX_HANDLETYPE   *pHandle,
+    OMX_IN    OMX_STRING        cComponentName,
+    OMX_IN    OMX_PTR           pAppData,
+    OMX_IN    OMX_CALLBACKTYPE *pCallBacks);
+EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_FreeHandle(
+    OMX_IN    OMX_HANDLETYPE    hComponent);
+EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_SetupTunnel(
+    OMX_IN    OMX_HANDLETYPE    hOutput,
+    OMX_IN    OMX_U32           nPortOutput,
+    OMX_IN    OMX_HANDLETYPE    hInput,
+    OMX_IN    OMX_U32           nPortInput);
+EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE              Exynos_OMX_GetContentPipe(
+    OMX_OUT   OMX_HANDLETYPE   *hPipe,
+    OMX_IN    OMX_STRING        szURI);
+EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE              Exynos_OMX_GetComponentsOfRole(
+    OMX_IN    OMX_STRING        role,
+    OMX_INOUT OMX_U32          *pNumComps,
+    OMX_INOUT OMX_U8          **compNames);
+EXYNOS_EXPORT_REF OMX_API OMX_ERRORTYPE              Exynos_OMX_GetRolesOfComponent(
+    OMX_IN    OMX_STRING        compName,
+    OMX_INOUT OMX_U32          *pNumRoles,
+    OMX_OUT   OMX_U8          **roles);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/openmax/core/Makefile.am b/openmax/core/Makefile.am
new file mode 100755 (executable)
index 0000000..f1f2aa9
--- /dev/null
@@ -0,0 +1,30 @@
+lib_LTLIBRARIES = libExynosOMX_Core.la
+
+libExynosOMX_Core_la_SOURCES = Exynos_OMX_Component_Register.c \
+                               Exynos_OMX_Core.c
+
+libExynosOMX_Core_la_LIBADD = $(top_builddir)/openmax/osal/libExynosOMX_OSAL.la \
+                              $(top_builddir)/openmax/component/common/libExynosOMX_Basecomponent.la \
+                              $(top_builddir)/openmax/component/common/libExynosOMX_Resourcemanager.la
+
+libExynosOMX_Core_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                              -I$(top_srcdir)/openmax/include/exynos \
+                              -I$(top_srcdir)/openmax/osal \
+                              -I$(top_srcdir)/openmax/component/common
+
+libExynosOMX_Core_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF 
+libExynosOMX_Core_la_CFLAGS += -Wno-unused-variable -Wno-unused-label
+
+includelibExynosOMX_Coredir = $(includedir)/libomxil-e9110
+includelibExynosOMX_Core_HEADERS = $(top_srcdir)/openmax/include/khronos/OMX_Audio.h \
+                                   $(top_srcdir)/openmax/include/khronos/OMX_Core.h \
+                                   $(top_srcdir)/openmax/include/khronos/OMX_Image.h \
+                                   $(top_srcdir)/openmax/include/khronos/OMX_IVCommon.h \
+                                   $(top_srcdir)/openmax/include/khronos/OMX_Types.h \
+                                   $(top_srcdir)/openmax/include/khronos/OMX_Component.h \
+                                   $(top_srcdir)/openmax/include/khronos/OMX_Index.h \
+                                   $(top_srcdir)/openmax/include/khronos/OMX_Other.h \
+                                   $(top_srcdir)/openmax/include/khronos/OMX_Video.h \
+                                   $(top_srcdir)/openmax/include/khronos/OMX_ContentPipe.h \
+                                   $(top_srcdir)/openmax/include/exynos/Exynos_OMX_Def.h \
+                                   $(top_srcdir)/openmax/include/exynos/Exynos_OMX_Macros.h
diff --git a/openmax/include/exynos/Exynos_OMX_Def.h b/openmax/include/exynos/Exynos_OMX_Def.h
new file mode 100755 (executable)
index 0000000..e1c0566
--- /dev/null
@@ -0,0 +1,1202 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file    Exynos_OMX_Def.h
+ * @brief   Exynos_OMX specific define
+ * @author  SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_DEF
+#define EXYNOS_OMX_DEF
+
+//#define PERFORMANCE_DEBUG
+
+#include "OMX_Types.h"
+#include "OMX_IVCommon.h"
+#include "OMX_Video.h"
+#include "OMX_VideoExt.h"
+#include "OMX_IndexExt.h"
+
+#define VERSIONMAJOR_NUMBER                1
+#define VERSIONMINOR_NUMBER                1
+#define REVISION_NUMBER                    2
+#define STEP_NUMBER                        0
+
+#define RESOURCE_VIDEO_DEC 16
+#define RESOURCE_VIDEO_ENC 16
+#define RESOURCE_AUDIO_DEC 10
+
+#define MAX_OMX_COMPONENT_NUM              40
+#define MAX_OMX_COMPONENT_ROLE_NUM         10
+#define MAX_OMX_COMPONENT_NAME_SIZE        OMX_MAX_STRINGNAME_SIZE
+#define MAX_OMX_COMPONENT_ROLE_SIZE        OMX_MAX_STRINGNAME_SIZE
+#define MAX_OMX_COMPONENT_LIBNAME_SIZE     OMX_MAX_STRINGNAME_SIZE * 2
+#define MAX_OMX_MIMETYPE_SIZE              OMX_MAX_STRINGNAME_SIZE
+
+#define MAX_BUFFER_REF       40
+#define MAX_TIMESTAMP        MAX_BUFFER_REF
+#define MAX_FLAGS            MAX_BUFFER_REF
+
+#define MAX_BUFFER_PLANE     3
+
+#define INDEX_AFTER_EOS      0xE05
+
+#define DEFAULT_TIMESTAMP_VAL (-1010101010)
+#define RESET_TIMESTAMP_VAL   (-1001001001)
+
+// The largest metadata buffer size advertised
+// when metadata buffer mode is used
+#define  MAX_METADATA_BUFFER_SIZE (64)
+
+#define  MAX_VENDOR_EXT_NUM (32)
+
+#define  PREFIX_COMPONENT_NAME "OMX.Exynos."
+#define  IS_CUSTOM_COMPONENT(name) (((char)(name[((int)sizeof(PREFIX_COMPONENT_NAME))-1]) >= 0x61)? OMX_TRUE:OMX_FALSE)
+
+#define IS_64BIT_OS                 (((sizeof(int) != sizeof(void *))? OMX_TRUE:OMX_FALSE))
+
+#define InitOMXParams(params, size) \
+    do { \
+        (params)->nSize = size; \
+        (params)->nVersion.s.nVersionMajor = 1; \
+        (params)->nVersion.s.nVersionMinor = 0; \
+        (params)->nVersion.s.nRevision     = 0; \
+        (params)->nVersion.s.nStep         = 0; \
+    } while(0)
+
+typedef enum _EXYNOS_CODEC_TYPE
+{
+    SW_CODEC,
+    HW_VIDEO_DEC_CODEC,
+    HW_VIDEO_ENC_CODEC,
+    HW_VIDEO_DEC_SECURE_CODEC,
+    HW_VIDEO_ENC_SECURE_CODEC,
+    HW_AUDIO_DEC_CODEC,
+    HW_AUDIO_ENC_CODEC
+} EXYNOS_CODEC_TYPE;
+
+#define PLANE_MAX_NUM 3
+typedef enum _PLANE_TYPE {
+    PLANE_MULTIPLE      = 0x00,
+    PLANE_SINGLE        = 0x11,
+    PLANE_SINGLE_USER   = 0x12,
+} PLANE_TYPE;
+
+typedef enum _EXYNOS_OMX_INDEXTYPE
+{
+#define EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD "OMX.SEC.index.VideoIntraPeriod"
+    OMX_IndexConfigVideoIntraPeriod             = 0x7F000002,
+#ifdef USE_S3D_SUPPORT
+#define EXYNOS_INDEX_PARAM_GET_S3D "OMX.SEC.index.S3DMode"
+    OMX_IndexVendorS3DMode                      = 0x7F000003,
+#endif
+#define EXYNOS_INDEX_PARAM_NEED_CONTIG_MEMORY "OMX.SEC.index.NeedContigMemory"  /* for HDCP */
+    OMX_IndexVendorNeedContigMemory             = 0x7F000004,
+#define EXYNOS_INDEX_CONFIG_GET_BUFFER_FD "OMX.SEC.index.GetBufferFD"           /* for HDCP */
+    OMX_IndexVendorGetBufferFD                  = 0x7F000005,
+#ifndef USE_ANDROID  // Porting exynos 9110
+#define EXYNOS_INDEX_PARAM_SET_DTS_MODE "OMX.SEC.index.enableTimestampReorder"
+#else
+#define EXYNOS_INDEX_PARAM_SET_DTS_MODE "OMX.SEC.index.SetDTSMode"
+#endif
+    OMX_IndexVendorSetDTSMode                   = 0x7F000006,
+#define EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL "OMX.SEC.index.enableThumbnailMode"
+    OMX_IndexParamEnableThumbnailMode           = 0x7F000007,
+#define EXYNOS_INDEX_PARAM_VIDEO_QPRANGE_TYPE "OMX.SEC.indexParam.VideoQPRange"
+    OMX_IndexParamVideoQPRange                  = 0x7F000008,
+#define EXYNOS_INDEX_CONFIG_VIDEO_QPRANGE_TYPE "OMX.SEC.indexConfig.VideoQPRange"
+    OMX_IndexConfigVideoQPRange                 = 0x7F000009,
+#define EXYNOS_INDEX_CONFIG_VIDEO_TEMPORALSVC "OMX.SEC.index.TemporalSVC"
+    OMX_IndexConfigVideoTemporalSVC             = 0x7F000010,
+#define EXYNOS_INDEX_PARAM_VIDEO_AVC_ENABLE_TEMPORALSVC "OMX.SEC.index.AVC.enableTemporalSVC"
+    OMX_IndexParamVideoAVCEnableTemporalSVC     = 0x7F000011,
+#define EXYNOS_INDEX_PARAM_ENABLE_BLUR_FILTER "OMX.SEC.indexParam.enableBlurFilter"
+    OMX_IndexParamEnableBlurFilter              = 0x7F000014,
+#define EXYNOS_INDEX_CONFIG_BLUR_INFO "OMX.SEC.indexConfig.BlurInfo"
+    OMX_IndexConfigBlurInfo                     = 0x7F000015,
+#define EXYNOS_INDEX_PARAM_VIDEO_HEVC_ENABLE_TEMPORALSVC "OMX.SEC.index.Hevc.enableTemporalSVC"
+    OMX_IndexParamVideoHevcEnableTemporalSVC    = 0x7F000016,
+#define EXYNOS_INDEX_CONFIG_VIDEO_ROIINFO "OMX.SEC.index.RoiInfo"
+    OMX_IndexConfigVideoRoiInfo                 = 0x7F000017,
+#define EXYNOS_INDEX_PARAM_VIDEO_ENABLE_ROIINFO "OMX.SEC.index.enableRoiInfo"
+    OMX_IndexParamVideoEnableRoiInfo            = 0x7F000018,
+#define EXYNOS_INDEX_PARAM_ROATION_INFO "OMX.SEC.indexParam.RotationInfo"
+    OMX_IndexParamRotationInfo                  = 0x7F000019,
+#define EXYNOS_INDEX_PARAM_ENABLE_PVC "OMX.SEC.indexParam.enablePVC"
+    OMX_IndexParamVideoEnablePVC                = 0x7F000020,
+#define EXYNOS_INDEX_CONFIG_BLACK_BAR_CROP_INFO "OMX.SEC.index.BlackBarCrop"
+    OMX_IndexConfigBlackBarCrop                 = 0x7F000021,
+#define EXYNOS_INDEX_CONFIG_SEARCH_BLACK_BAR "OMX.SEC.index.SearchBlackBar"
+    OMX_IndexConfigSearchBlackBar               = 0x7F000022,
+#define EXYNOS_CUSTOM_INDEX_PARAM_REORDER_MODE "OMX.SEC.CUSTOM.index.ReorderMode"
+    OMX_IndexExynosParamReorderMode             = 0x7F000023,
+#define EXYNOS_INDEX_CONFIG_IFRAME_RATIO "OMX.SEC.index.IFrameRatio"
+    OMX_IndexConfigIFrameRatio                  = 0x7F000024,
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// for extension codec spec
+////////////////////////////////////////////////////////////////////////////////////////////////
+    OMX_IndexExtensionStartUnused               = 0x7F020000,
+#ifdef USE_KHRONOS_OMX_HEADER
+#define EXYNOS_INDEX_PARAM_VIDEO_HEVC_TYPE "OMX.SEC.index.VideoHevcType"
+    OMX_IndexParamVideoHevc                     = 0x7F020000,
+#define EXYNOS_INDEX_PARAM_VIDEO_VP9_TYPE "OMX.SEC.index.VideoVp9Type"
+    OMX_IndexParamVideoVp9                      = 0x7F020001,
+#endif
+#ifndef USE_KHRONOS_OMX_1_2
+#define EXYNOS_INDEX_PARAM_VIDEO_VC1_TYPE "OMX.SEC.index.VideoVc1Type"
+    OMX_IndexParamVideoVC1                      = 0x7F021000,
+#endif
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// for android platform
+////////////////////////////////////////////////////////////////////////////////////////////////
+    OMX_IndexAndroidStartUnused                     = 0x7F030000,
+    /* query using get_extension_index */
+#define EXYNOS_INDEX_PARAM_USE_ANB "OMX.google.android.index.useAndroidNativeBuffer"        /* no more used */
+    OMX_IndexParamUseAndroidNativeBuffer            = 0x7F030001,
+#define EXYNOS_INDEX_PARAM_USE_ANB2 "OMX.google.android.index.useAndroidNativeBuffer2"      /* no more used */
+    OMX_IndexParamUseAndroidNativeBuffer2           = 0x7F030002,
+#define EXYNOS_INDEX_PARAM_GET_ANB "OMX.google.android.index.getAndroidNativeBufferUsage"
+    OMX_IndexParamGetAndroidNativeBuffer            = 0x7F030003,
+#define EXYNOS_INDEX_PARAM_ENABLE_ANB "OMX.google.android.index.enableAndroidNativeBuffers"
+    OMX_IndexParamEnableAndroidBuffers              = 0x7F030004,
+    /* for Android Store Metadata Inbuffer */
+#ifndef USE_ANDROID  // Porting exynos 9110
+#define EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER "OMX.SEC.index.enablePlatformSpecificBuffers"
+#else
+#define EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER "OMX.google.android.index.storeMetaDataInBuffers"
+#endif
+    OMX_IndexParamStoreMetaDataBuffer               = 0x7F030005,
+#define EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR "OMX.google.android.index.prependSPSPPSToIDRFrames"
+    OMX_IndexParamPrependSPSPPSToIDR                = 0x7F030006,
+#define EXYNOS_INDEX_PARAM_ALLOCATE_NATIVE_HANDLE "OMX.google.android.index.allocateNativeHandle"
+    OMX_IndexParamAllocateNativeHandle              = 0x7F030007,
+#define EXYNOS_INDEX_PARAM_DESCRIBE_COLOR_FORMAT "OMX.google.android.index.describeColorFormat"
+    OMX_IndexParamDescribeColorFormat               = 0x7F030008,
+#define EXYNOS_INDEX_CONFIG_VIDEO_HDR_STATIC_INFO "OMX.google.android.index.describeHDRStaticInfo"
+    OMX_IndexConfigVideoHdrStaticInfo               = 0x7F030009,
+#define EXYNOS_INDEX_CONFIG_VIDEO_COLOR_ASPECTS_INFO "OMX.google.android.index.describeColorAspects"
+    OMX_IndexConfigVideoColorAspects                = 0x7F030010,
+
+#ifdef USE_KHRONOS_OMX_HEADER
+    /* not query, just uses index */
+#define EXYNOS_INDEX_CONFIG_ANDROID_VENDOR_EXT "OMX.google.android.index.androidVendorExtension"
+    OMX_IndexConfigAndroidVendorExtension           = 0x7F031001,
+
+
+#define EXYNOS_INDEX_PARAM_VIDEO_ANDROID_VP8_ENCODER "OMX.SEC.index.VideoAndroidVP8Encoder"
+    OMX_IndexParamVideoAndroidVp8Encoder            = 0x7F032001,
+#define EXYNOS_INDEX_PARAM_SLICE_SEGMENTS "OMX.SEC.index.SliceSegments"                                 /* not supported yet */
+    OMX_IndexParamSliceSegments                     = 0x7F032002,
+#define EXYNOS_INDEX_CONFIG_ANDROID_INTRA_REFRESH "OMX.SEC.index.AndroidIntraRefresh"                   /* not supported yet */
+    OMX_IndexConfigAndroidIntraRefresh              = 0x7F032003,
+#define EXYNOS_INDEX_PARAM_ANDROID_VIDEO_TEMPORAL "OMX.SEC.index.param.TemporalLayering"
+    OMX_IndexParamAndroidVideoTemporalLayering      = 0x7F032004,
+#define EXYNOS_INDEX_CONFIG_ANDROID_VIDEO_TEMPORAL "OMX.SEC.index.config.TemporalLayering"
+    OMX_IndexConfigAndroidVideoTemporalLayering     = 0x7F032005,
+#define EXYNOS_INDEX_PARAM_MAX_FRAME_DURATION "OMX.SEC.index.maxDurationForBitratecontrol"              /* not supported yet */
+    OMX_IndexParamMaxFrameDurationForBitrateControl = 0x7F032006,
+#define EXYNOS_INDEX_PARAM_VIDEO_ANDROID_VP9_ENCODER "OMX.SEC.index.VideoAndroidVp9Encoder"             /* not supported yet */
+    OMX_IndexParamVideoAndroidVp9Encoder            = 0x7F032007,
+
+
+#define EXYNOS_INDEX_CONFIG_OPERATING_RATE "OMX.SEC.index.OperatingRate"
+    OMX_IndexConfigOperatingRate                    = 0x7F033001,
+#define EXYNOS_INDEX_PARAM_CONSUMER_USAGE_BITS "OMX.SEC.index.ConsumerUsageBits"
+    OMX_IndexParamConsumerUsageBits                 = 0x7F033002,
+#endif  // USE_KHRONOS_OMX_HEADER
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// for linux platform
+////////////////////////////////////////////////////////////////////////////////////////////////
+    OMX_IndexLinuxStartUnused                = 0x7F040000,
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// for custom component
+////////////////////////////////////////////////////////////////////////////////////////////////
+    OMX_IndexCustomStartUnused              = 0x7F050000,
+#define EXYNOS_CUSTOM_INDEX_CONFIG_PTS_MODE "OMX.SEC.CUSTOM.index.PTSMode"
+    OMX_IndexExynosConfigPTSMode            = 0x7F050001,
+#define EXYNOS_CUSTOM_INDEX_CONFIG_DISPLAY_DELAY "OMX.SEC.CUSTOM.index.DisplayDelay"
+    OMX_IndexExynosConfigDisplayDelay       = 0x7F050002,
+#define EXYNOS_CUSTOM_INDEX_PARAM_CORRUPTEDHEADER "OMX.SEC.CUSTOM.index.CorruptedHeader"
+    OMX_IndexExynosParamCorruptedHeader     = 0x7F050003,
+#define EXYNOS_CUSTOM_INDEX_PARAM_DISPLAY_DELAY "OMX.SEC.CUSTOM.index.DisplayDelay2"  /* Compatibility with OMX.SEC.CUSTOM.index.DisplayDelay */
+    OMX_IndexExynosParamDisplayDelay        = 0x7F050004,
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// for Skype HD
+////////////////////////////////////////////////////////////////////////////////////////////////
+    OMX_IndexSkypeStartUnused               = 0x7F060000,
+#define OMX_MS_SKYPE_PARAM_DRIVERVER "OMX.microsoft.skype.index.driverversion"
+    OMX_IndexSkypeParamDriverVersion        = 0x7F060001,
+#if 0
+#define OMX_MS_SKYPE_PARAM_DECODERSETTING "OMX.microsoft.skype.index.decodersetting"
+    OMX_IndexSkypeParamDecoderSetting       = 0x7F060002,
+#define OMX_MS_SKYPE_PARAM_DECODERCAP "OMX.microsoft.skype.index.decodercapability"
+    OMX_IndexSkypeParamDecoderCapability    = 0x7F060003,
+#define OMX_MS_SKYPE_PARAM_ENCODERSETTING "OMX.microsoft.skype.index.encodersetting"
+    OMX_IndexSkypeParamEncoderSetting       = 0x7F060004,
+#define OMX_MS_SKYPE_PARAM_ENCODERCAP "OMX.microsoft.skype.index.encodercapability"
+    OMX_IndexSkypeParamEncoderCapability    = 0x7F060005,
+#endif
+#define OMX_MS_SKYPE_CONFIG_MARKLTRFRAME "OMX.microsoft.skype.index.markltrframe"
+    OMX_IndexSkypeConfigMarkLTRFrame        = 0x7F060006,
+#define OMX_MS_SKYPE_CONFIG_USELTRFRAME "OMX.microsoft.skype.index.useltrframe"
+    OMX_IndexSkypeConfigUseLTRFrame         = 0x7F060007,
+#define OMX_MS_SKYPE_CONFIG_QP "OMX.microsoft.skype.index.qp"
+    OMX_IndexSkypeConfigQP                  = 0x7F060008,
+#if 0
+#define OMX_MS_SKYPE_CONFIG_TEMPORALLAYERCOUNT "OMX.microsoft.skype.index.temporallayercount"
+    OMX_IndexSkypeConfigTemporalLayerCount  = 0x7F060009,
+#endif
+#define OMX_MS_SKYPE_CONFIG_BASELAYERPID "OMX.microsoft.skype.index.basepid"
+    OMX_IndexSkypeConfigBasePid             = 0x7F06000a,
+
+    /* common */
+    OMX_IndexSkypeParamLowLatency           = 0x7F060010,
+
+    /* encoder */
+    OMX_IndexSkypeParamEncoderMaxTemporalLayerCount = 0x7F061000,
+    OMX_IndexSkypeParamEncoderMaxLTR                = 0x7F061001,
+    OMX_IndexSkypeParamEncoderLTR                   = 0x7F061002,
+    OMX_IndexSkypeParamEncoderPreprocess            = 0x7F061003,
+    OMX_IndexSkypeParamEncoderSar                   = 0x7F061004,
+    OMX_IndexSkypeParamEncoderInputControl          = 0x7F061005,
+    OMX_IndexSkypeConfigEncoderLTR                  = 0x7F061006,
+    OMX_IndexSkypeConfigEncoderInputTrigger         = 0x7F061007,
+
+    OMX_IndexExynosEndUnused                = 0x7F05FFFF,
+} EXYNOS_OMX_INDEXTYPE;
+
+typedef enum _EXYNOS_OMX_ERRORTYPE
+{
+    OMX_ErrorNoEOF              = (OMX_S32) 0x90000001,
+    OMX_ErrorInputDataDecodeYet = (OMX_S32) 0x90000002,
+    OMX_ErrorInputDataEncodeYet = (OMX_S32) 0x90000003,
+    OMX_ErrorCodecInit          = (OMX_S32) 0x90000004,
+    OMX_ErrorCodecDecode        = (OMX_S32) 0x90000005,
+    OMX_ErrorCodecEncode        = (OMX_S32) 0x90000006,
+    OMX_ErrorCodecFlush         = (OMX_S32) 0x90000007,
+    OMX_ErrorOutputBufferUseYet = (OMX_S32) 0x90000008,
+    OMX_ErrorCorruptedFrame     = (OMX_S32) 0x90000009,
+    OMX_ErrorNeedNextHeaderInfo = (OMX_S32) 0x90000010,
+    OMX_ErrorNoneSrcSetupFinish = (OMX_S32) 0x90000011,
+    OMX_ErrorCorruptedHeader    = (OMX_S32) 0x90000012,
+    OMX_ErrorNoneExpiration     = (OMX_S32) 0x90000013,
+} EXYNOS_OMX_ERRORTYPE;
+
+typedef enum _EXYNOS_OMX_COMMANDTYPE
+{
+    EXYNOS_OMX_CommandComponentDeInit = 0x7F000001,
+    EXYNOS_OMX_CommandEmptyBuffer,
+    EXYNOS_OMX_CommandFillBuffer,
+    EXYNOS_OMX_CommandFakeBuffer,
+    Exynos_OMX_CommandSendEvent,
+} EXYNOS_OMX_COMMANDTYPE;
+
+typedef enum _EXYNOS_OMX_TRANS_STATETYPE {
+    EXYNOS_OMX_TransStateInvalid,
+    EXYNOS_OMX_TransStateLoadedToIdle,
+    EXYNOS_OMX_TransStateIdleToExecuting,
+    EXYNOS_OMX_TransStateExecutingToIdle,
+    EXYNOS_OMX_TransStateIdleToLoaded,
+    EXYNOS_OMX_TransStateMax = 0X7FFFFFFF
+} EXYNOS_OMX_TRANS_STATETYPE;
+
+typedef enum _EXYNOS_OMX_PORT_STATETYPE {
+    EXYNOS_OMX_PortStateInvalid,
+    EXYNOS_OMX_PortStateFlushing,
+    EXYNOS_OMX_PortStateFlushingForDisable,
+    EXYNOS_OMX_PortStateDisabling,
+    EXYNOS_OMX_PortStateEnabling,
+    EXYNOS_OMX_PortStateIdle,
+    EXYNOS_OMX_PortStateLoaded,
+    EXYNOS_OMX_PortStateMax = 0X7FFFFFFF
+} EXYNOS_OMX_PORT_STATETYPE;
+
+typedef enum _EXYNOS_OMX_COLOR_FORMATTYPE {
+    OMX_SEC_COLOR_FormatNV12TPhysicalAddress        = 0x7F000001, /* unused */
+    OMX_SEC_COLOR_FormatNV12LPhysicalAddress        = 0x7F000002, /* unused */
+    OMX_SEC_COLOR_FormatNV12LVirtualAddress         = 0x7F000003, /* unused */
+
+    OMX_SEC_COLOR_FormatNV21LPhysicalAddress        = 0x7F000010, /* unused */
+    OMX_SEC_COLOR_FormatNV21Linear                  = 0x7F000011,
+    OMX_SEC_COLOR_FormatYVU420Planar                = 0x7F000012,
+    OMX_SEC_COLOR_Format32bitABGR8888               = 0x7F000013, /* unused */
+    OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace   = 0x7F000014, /* unused */
+    OMX_SEC_COLOR_Format10bitYUV420SemiPlanar       = 0x7F000015, /* P010 : Y/CbCr */
+    OMX_SEC_COLOR_FormatS10bitYUV420SemiPlanar      = 0x7F000016, /* S10B : Y/CbCr */
+    OMX_SEC_COLOR_Format10bitYVU420SemiPlanar       = 0x7F000017, /* P010 : Y/CrCb */
+    OMX_SEC_COLOR_FormatS10bitYVU420SemiPlanar      = 0x7F000018, /* S10B : Y/CrCb */
+
+    /* to copy a encoded data for drm component using gsc or fimc */
+    OMX_SEC_COLOR_FormatEncodedData                 = OMX_COLOR_FormatYCbYCr,
+#ifdef USE_KHRONOS_OMX_HEADER
+    OMX_COLOR_FormatAndroidOpaque                   = 0x7F000789,
+    OMX_COLOR_Format32BitRGBA8888                   = 0x7F00A000,
+    OMX_SEC_COLOR_FormatNV12Tiled                   = 0x7FC00002, /* unused */
+    OMX_COLOR_FormatYUV420Flexible                  = 0x7F420888,
+#endif
+}EXYNOS_OMX_COLOR_FORMATTYPE;
+
+typedef enum _EXYNOS_OMX_SUPPORTFORMAT_TYPE
+{
+    supportFormat_0 = 0x00,
+    supportFormat_1,
+    supportFormat_2,
+    supportFormat_3,
+    supportFormat_4,
+    supportFormat_5,
+    supportFormat_6,
+    supportFormat_7,
+} EXYNOS_OMX_SUPPORTFORMAT_TYPE;
+
+typedef enum _EXYNOS_OMX_BUFFERPROCESS_TYPE
+{
+    BUFFER_DEFAULT    = 0x00,
+    BUFFER_COPY       = 0x01,
+    BUFFER_SHARE      = 0x02,
+} EXYNOS_OMX_BUFFERPROCESS_TYPE;
+
+#ifdef USE_S3D_SUPPORT
+typedef enum _EXYNOS_OMX_FPARGMT_TYPE
+{
+    OMX_SEC_FPARGMT_INVALID           = -1,
+    OMX_SEC_FPARGMT_CHECKERBRD_INTERL = 0x00,
+    OMX_SEC_FPARGMT_COLUMN_INTERL     = 0x01,
+    OMX_SEC_FPARGMT_ROW_INTERL        = 0x02,
+    OMX_SEC_FPARGMT_SIDE_BY_SIDE      = 0x03,
+    OMX_SEC_FPARGMT_TOP_BOTTOM        = 0x04,
+    OMX_SEC_FPARGMT_TEMPORAL_INTERL   = 0x05,
+    OMX_SEC_FPARGMT_NONE              = 0x0A
+} EXYNOS_OMX_FPARGMT_TYPE;
+#endif
+
+typedef enum _EXYNOS_OMX_EVENTTYPE
+{
+   OMX_EventVendorStart    = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+#ifdef USE_KHRONOS_OMX_HEADER
+   OMX_EventDataSpaceChanged,
+#endif
+#ifdef USE_S3D_SUPPORT
+   OMX_EventS3DInformation,
+#endif
+} EXYNOS_OMX_EVENTTYPE;
+
+typedef enum __EVENT_COMMAD_TYPE {
+    EVENT_CMD_STATE_TO_LOAD_STATE,
+    EVENT_CMD_STATE_TO_IDLE_STATE,
+    EVENT_CMD_ENABLE_INPUT_PORT,
+    EVENT_CMD_ENABLE_OUTPUT_PORT,
+    EVENT_CMD_DISABLE_INPUT_PORT,
+    EVENT_CMD_DISABLE_OUTPUT_PORT,
+} EVENT_COMMAD_TYPE;
+
+typedef enum _EXYNOS_METADATA_TYPE {
+    METADATA_TYPE_DISABLED      = 0x0000,  /* 1. data buffer(ex: yuv, rgb) */
+    METADATA_TYPE_DATA          = 0x0001,  /* 2. uses meta struct(type, [fd|handle|id]) */
+    METADATA_TYPE_HANDLE        = 0x0002,  /* 3. naitve handle(fd) */
+
+    METADATA_TYPE_BUFFER_LOCK   = 0x0100,  /* need to lock to get va */
+    METADATA_TYPE_BUFFER_ID     = 0x1000,  /* need to get fd from id */
+
+    METADATA_TYPE_GRAPHIC           = (METADATA_TYPE_DATA | METADATA_TYPE_BUFFER_LOCK),                            /* 4. uses meta struct(type, handle) */
+    METADATA_TYPE_GRAPHIC_HANDLE    = (METADATA_TYPE_HANDLE | METADATA_TYPE_BUFFER_LOCK),                          /* 5. graphic buffer handle(fd) */
+    METADATA_TYPE_UBM_BUFFER        = (METADATA_TYPE_DATA | METADATA_TYPE_BUFFER_LOCK | METADATA_TYPE_BUFFER_ID),  /* 6. uses meta struct(type, id) */
+} EXYNOS_METADATA_TYPE;
+
+typedef enum _EXYNOS_OMX_VIDEO_CONTROLRATETYPE {
+    OMX_Video_ControlRateVendorStart    = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_Video_ControlRateConstantVTCall = 0x7F000001,
+} EXYNOS_OMX_VIDEO_CONTROLRATETYPE;
+
+typedef struct _EXYNOS_OMX_PRIORITYMGMTTYPE
+{
+    OMX_U32 nGroupPriority; /* the value 0 represents the highest priority */
+                            /* for a group of components                   */
+    OMX_U32 nGroupID;
+} EXYNOS_OMX_PRIORITYMGMTTYPE;
+
+typedef struct _EXYNOS_OMX_VIDEO_PROFILELEVEL
+{
+    OMX_S32  profile;
+    OMX_S32  level;
+} EXYNOS_OMX_VIDEO_PROFILELEVEL;
+
+typedef struct _EXYNOS_OMX_LOCK_RANGE
+{
+    OMX_U32              nWidth;
+    OMX_U32              nHeight;
+    OMX_COLOR_FORMATTYPE eColorFormat;
+} EXYNOS_OMX_LOCK_RANGE;
+
+typedef struct _EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32         nPortIndex;
+    OMX_BOOL        bNeedContigMem;
+} EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE;
+
+typedef struct _EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_PTR OMX_IN  pVirAddr;
+    OMX_S32 OMX_OUT fd;
+} EXYNOS_OMX_VIDEO_CONFIG_BUFFERINFO;
+
+typedef struct _EXYNOS_OMX_VIDEO_PARAM_DTSMODE {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL        bDTSMode;
+} EXYNOS_OMX_VIDEO_PARAM_DTSMODE;
+
+typedef struct _EXYNOS_OMX_VIDEO_THUMBNAILMODE {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32         nPortIndex;
+    OMX_BOOL        bEnable;
+} EXYNOS_OMX_VIDEO_THUMBNAILMODE;
+
+typedef struct _OMX_VIDEO_QPRANGE {
+    OMX_U32 nMinQP;
+    OMX_U32 nMaxQP;
+} OMX_VIDEO_QPRANGE;
+
+typedef struct _OMX_VIDEO_QPRANGETYPE {
+    OMX_U32             nSize;
+    OMX_VERSIONTYPE     nVersion;
+    OMX_U32             nPortIndex;
+    OMX_VIDEO_QPRANGE   qpRangeI;
+    OMX_VIDEO_QPRANGE   qpRangeP;
+    OMX_VIDEO_QPRANGE   qpRangeB;  /* H.264, HEVC, MPEG4 */
+} OMX_VIDEO_QPRANGETYPE;
+
+/* Temporal SVC */
+/* Maximum number of temporal layers */
+#define OMX_VIDEO_MAX_TEMPORAL_LAYERS 7
+#define OMX_VIDEO_MAX_TEMPORAL_LAYERS_WITH_LTR 3
+#define OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS 7
+#define OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS_FOR_B (OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS - 1)
+#define OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS 7
+#define OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS_FOR_B (OMX_VIDEO_MAX_HEVC_TEMPORAL_LAYERS - 1)
+
+typedef struct _EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32         nPortIndex;
+    OMX_BOOL        bEnableTemporalSVC;
+} EXYNOS_OMX_VIDEO_PARAM_ENABLE_TEMPORALSVC;
+
+typedef struct _EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32         nPortIndex;
+    OMX_U32         nKeyFrameInterval;
+    OMX_U32         nTemporalLayerCount;
+    OMX_U32         nTemporalLayerBitrateRatio[OMX_VIDEO_MAX_TEMPORAL_LAYERS];
+    OMX_U32         nMinQuantizer;
+    OMX_U32         nMaxQuantizer;
+} EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC;
+
+typedef enum _EXYNOS_OMX_BLUR_MODE
+{
+    BLUR_MODE_NONE          = 0x00,
+    BLUR_MODE_DOWNUP        = 0x01,
+    BLUR_MODE_COEFFICIENT   = 0x02,
+} EXYNOS_OMX_BLUR_MODE;
+
+typedef enum _EXYNOS_OMX_BLUR_RESOL
+{
+    BLUR_RESOL_240     = 426 * 240,   /* 426 x 240 */
+    BLUR_RESOL_480     = 854 * 480,   /* 854 x 480 */
+    BLUR_RESOL_720     = 1280 * 720,  /* 1280 x 720 */
+    BLUR_RESOL_960     = 1920 * 960,  /* 1920 x 960 */
+    BLUR_RESOL_1080    = 1920 * 1080, /* 1920 x 1080 */
+} EXYNOS_OMX_BLUR_RESOL;
+
+typedef struct _EXYNOS_OMX_VIDEO_PARAM_ENABLE_BLURFILTER {
+    OMX_U32                 nSize;
+    OMX_VERSIONTYPE         nVersion;
+    OMX_U32                 nPortIndex;
+    OMX_BOOL                bUseBlurFilter;
+} EXYNOS_OMX_VIDEO_PARAM_ENABLE_BLURFILTER;
+
+typedef struct _EXYNOS_OMX_VIDEO_CONFIG_BLURINFO {
+    OMX_U32                 nSize;
+    OMX_VERSIONTYPE         nVersion;
+    OMX_U32                 nPortIndex;
+    EXYNOS_OMX_BLUR_MODE    eBlurMode;
+    EXYNOS_OMX_BLUR_RESOL   eTargetResol;
+} EXYNOS_OMX_VIDEO_CONFIG_BLURINFO;
+/* ROI Information */
+
+typedef struct _EXYNOS_OMX_VIDEO_CONFIG_ROIINFO {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32         nPortIndex;
+    OMX_S32         nUpperQpOffset;
+    OMX_S32         nLowerQpOffset;
+    OMX_BOOL        bUseRoiInfo;
+    OMX_S32         nRoiMBInfoSize;
+    OMX_PTR         pRoiMBInfo;
+} EXYNOS_OMX_VIDEO_CONFIG_ROIINFO;
+
+typedef struct _EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32         nPortIndex;
+    OMX_BOOL        bEnableRoiInfo;
+} EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO;
+
+typedef enum _EXYNOS_OMX_ROTATION_TYPE
+{
+    ROTATE_0        = 0,
+    ROTATE_90       = 90,
+    ROTATE_180      = 180,
+    ROTATE_270      = 270,
+} EXYNOS_OMX_ROTATION_TYPE;
+
+typedef struct _EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO {
+    OMX_U32                     nSize;
+    OMX_VERSIONTYPE             nVersion;
+    OMX_U32                     nPortIndex;
+    EXYNOS_OMX_ROTATION_TYPE    eRotationType;
+} EXYNOS_OMX_VIDEO_PARAM_ROTATION_INFO;
+
+typedef struct _EXYNOS_OMX_VIDEO_PARAM_REORDERMODE {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL        bReorderMode;
+} EXYNOS_OMX_VIDEO_PARAM_REORDERMODE;
+
+
+
+// codec specific
+typedef enum _EXYNOS_OMX_VIDEO_CODINGTYPE {
+#ifdef USE_KHRONOS_OMX_HEADER
+    OMX_VIDEO_CodingVP9 = OMX_VIDEO_CodingVP8 + 1,  /**< Google VP9 */
+    OMX_VIDEO_CodingHEVC,                           /**< ITU H.265/HEVC */
+#endif
+    OMX_VIDEO_VendorCodingMAX  = 0x7FFFFFFF,
+} EXYNOS_OMX_VIDEO_CODINGTYPE;
+
+/* for AVC */
+typedef enum _EXYNOS_OMX_VIDEO_AVCPROFILETYPE {
+    OMX_VIDEO_AVCProfileConstrainedBaseline = 0x7F000001,
+    OMX_VIDEO_AVCProfileConstrainedHigh     = 0x7F000002,
+} EXYNOS_OMX_VIDEO_AVCPROFILETYPE;
+
+#ifdef USE_KHRONOS_OMX_HEADER
+typedef enum _EXYNOS_OMX_VIDEO_AVCLEVELTYPE {
+    OMX_VIDEO_AVCLevel52  = 0x10000,  /**< Level 5.2 */
+} EXYNOS_OMX_VIDEO_AVCLEVELTYPE;
+#endif
+
+typedef enum _EXYNOS_OMX_HIERARCHICAL_CODING_TYPE
+{
+    EXYNOS_OMX_Hierarchical_P = 0x00,
+    EXYNOS_OMX_Hierarchical_B,
+} EXYNOS_OMX_HIERARCHICAL_CODING_TYPE;
+// AVC end
+
+/* for Mpeg4 */
+#ifdef USE_KHRONOS_OMX_HEADER
+typedef enum _EXYNOS_OMX_VIDEO_MPEG4LEVELTYPE {
+    OMX_VIDEO_MPEG4Level3b  = 0x18,     /**< Level 3a */
+    OMX_VIDEO_MPEG4Level6   = 0x100,   /**< Level 6 */
+} EXYNOS_OMX_VIDEO_MPEG4LEVELTYPE;
+#endif
+// Mpeg4 end
+
+/* for Mpeg2 */
+#ifdef USE_KHRONOS_OMX_HEADER
+typedef enum _EXYNOS_OMX_VIDEO_MPEG2LEVELTYPE {
+    OMX_VIDEO_MPEG2LevelHP      = OMX_VIDEO_MPEG2LevelHL + 1,      /**< HighP Level */
+} EXYNOS_OMX_VIDEO_MPEG2LEVELTYPE;
+#endif
+// Mpeg2 end
+
+/* for HEVC */
+#ifdef USE_KHRONOS_OMX_HEADER
+typedef enum _OMX_VIDEO_HEVCPROFILETYPE {
+    OMX_VIDEO_HEVCProfileUnknown           = 0x0,
+    OMX_VIDEO_HEVCProfileMain              = 0x1,          /**< Main profile */
+    OMX_VIDEO_HEVCProfileMain10            = 0x2,          /**< Main 10 profile */
+    OMX_VIDEO_HEVCProfileMainStillPicture  = 0x4,          /**< Main Still Picture */
+    // Main10 profile with HDR SEI support.
+    OMX_VIDEO_HEVCProfileMain10HDR10       = 0x1000,        /**< Main10 profile with HDR SEI support */
+    OMX_VIDEO_HEVCProfileKhronosExtensions = 0x6F000000,    /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_HEVCProfileVendorStartUnused = 0x7F000000,    /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_HEVCProfileMax               = 0x7FFFFFFF
+} OMX_VIDEO_HEVCPROFILETYPE;
+
+/** HEVC Level enum type */
+typedef enum _OMX_VIDEO_HEVCLEVELTYPE {
+    OMX_VIDEO_HEVCLevelUnknown              = 0x00000000,
+    OMX_VIDEO_HEVCMainTierLevel1            = 0x00000001,   /**< Level 1 */
+    OMX_VIDEO_HEVCHighTierLevel1            = 0x00000002,
+    OMX_VIDEO_HEVCMainTierLevel2            = 0x00000004,   /**< Level 2 */
+    OMX_VIDEO_HEVCHighTierLevel2            = 0x00000008,
+    OMX_VIDEO_HEVCMainTierLevel21           = 0x00000010,   /**< Level 2.1 */
+    OMX_VIDEO_HEVCHighTierLevel21           = 0x00000020,
+    OMX_VIDEO_HEVCMainTierLevel3            = 0x00000040,   /**< Level 3 */
+    OMX_VIDEO_HEVCHighTierLevel3            = 0x00000080,
+    OMX_VIDEO_HEVCMainTierLevel31           = 0x00000100,   /**< Level 3.1 */
+    OMX_VIDEO_HEVCHighTierLevel31           = 0x00000200,
+    OMX_VIDEO_HEVCMainTierLevel4            = 0x00000400,   /**< Level 4 */
+    OMX_VIDEO_HEVCHighTierLevel4            = 0x00000800,
+    OMX_VIDEO_HEVCMainTierLevel41           = 0x00001000,   /**< Level 4.1 */
+    OMX_VIDEO_HEVCHighTierLevel41           = 0x00002000,
+    OMX_VIDEO_HEVCMainTierLevel5            = 0x00004000,   /**< Level 5 */
+    OMX_VIDEO_HEVCHighTierLevel5            = 0x00008000,
+    OMX_VIDEO_HEVCMainTierLevel51           = 0x00010000,   /**< Level 5.1 */
+    OMX_VIDEO_HEVCHighTierLevel51           = 0x00020000,
+    OMX_VIDEO_HEVCMainTierLevel52           = 0x00040000,   /**< Level 5.2 */
+    OMX_VIDEO_HEVCHighTierLevel52           = 0x00080000,
+    OMX_VIDEO_HEVCMainTierLevel6            = 0x00100000,   /**< Level 6 */
+    OMX_VIDEO_HEVCHighTierLevel6            = 0x00200000,
+    OMX_VIDEO_HEVCMainTierLevel61           = 0x00400000,   /**< Level 6.1 */
+    OMX_VIDEO_HEVCHighTierLevel61           = 0x00800000,
+    OMX_VIDEO_HEVCMainTierLevel62           = 0x01000000,   /**< Level 6.2 */
+    OMX_VIDEO_HEVCHighTierLevel62           = 0x02000000,
+    OMX_VIDEO_HEVCLevelKhronosExtensions    = 0x6F000000,   /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_HEVCLevelVendorStartUnused    = 0x7F000000,   /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_HEVCHighMAX                   = 0x7FFFFFFF
+} OMX_VIDEO_HEVCLEVELTYPE;
+
+/** Structure for controlling HEVC video encoding and decoding */
+typedef struct _OMX_VIDEO_PARAM_HEVCTYPE {
+    OMX_U32                     nSize;
+    OMX_VERSIONTYPE             nVersion;
+    OMX_U32                     nPortIndex;
+    OMX_VIDEO_HEVCPROFILETYPE   eProfile;
+    OMX_VIDEO_HEVCLEVELTYPE     eLevel;
+    OMX_U32                     nKeyFrameInterval;  // distance between consecutive I-frames (including one
+                                                    // of the I frames). 0 means interval is unspecified and
+                                                    // can be freely chosen by the codec. 1 means a stream of
+                                                    // only I frames.
+} OMX_VIDEO_PARAM_HEVCTYPE;
+#endif // hevc end
+
+/* for VP9 */
+#ifdef USE_KHRONOS_OMX_HEADER
+typedef enum _OMX_VIDEO_VP9PROFILETYPE {
+    OMX_VIDEO_VP9Profile0                   = 0x0,
+    OMX_VIDEO_VP9Profile1                   = 0x1,
+    OMX_VIDEO_VP9Profile2                   = 0x2,
+    OMX_VIDEO_VP9Profile3                   = 0x4,
+    // HDR profiles also support passing HDR metadata
+    OMX_VIDEO_VP9Profile2HDR                = 0x1000,
+    OMX_VIDEO_VP9Profile3HDR                = 0x2000,
+    OMX_VIDEO_VP9ProfileUnknown             = 0x6EFFFFFF,
+    OMX_VIDEO_VP9ProfileKhronosExtensions   = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_VP9ProfileVendorStartUnused   = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_VP9ProfileMax                 = 0x7FFFFFFF
+} OMX_VIDEO_VP9PROFILETYPE;
+
+    /* VP9 levels */
+typedef enum _OMX_VIDEO_VP9LEVELTYPE {
+    OMX_VIDEO_VP9Level1                     = 0x0,
+    OMX_VIDEO_VP9Level11                    = 0x1,
+    OMX_VIDEO_VP9Level2                     = 0x2,
+    OMX_VIDEO_VP9Level21                    = 0x4,
+    OMX_VIDEO_VP9Level3                     = 0x8,
+    OMX_VIDEO_VP9Level31                    = 0x10,
+    OMX_VIDEO_VP9Level4                     = 0x20,
+    OMX_VIDEO_VP9Level41                    = 0x40,
+    OMX_VIDEO_VP9Level5                     = 0x80,
+    OMX_VIDEO_VP9Level51                    = 0x100,
+    OMX_VIDEO_VP9Level52                    = 0x200,
+    OMX_VIDEO_VP9Level6                     = 0x400,
+    OMX_VIDEO_VP9Level61                    = 0x800,
+    OMX_VIDEO_VP9Level62                    = 0x1000,
+    OMX_VIDEO_VP9LevelUnknown               = 0x6EFFFFFF,
+    OMX_VIDEO_VP9LevelKhronosExtensions     = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_VP9LevelVendorStartUnused     = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_VP9LevelMax                   = 0x7FFFFFFF
+} OMX_VIDEO_VP9LEVELTYPE;
+
+typedef struct _OMX_VIDEO_PARAM_VP9TYPE {
+    OMX_U32                     nSize;
+    OMX_VERSIONTYPE             nVersion;
+    OMX_U32                     nPortIndex;
+    OMX_VIDEO_VP9PROFILETYPE    eProfile;
+    OMX_VIDEO_VP9LEVELTYPE      eLevel;
+    OMX_BOOL                    bErrorResilientMode;
+} OMX_VIDEO_PARAM_VP9TYPE;
+#endif // vp9 end
+#ifndef USE_KHRONOS_OMX_1_2
+/* WMV codec */
+/** WMV Profile enum type */
+typedef enum _OMX_VIDEO_WMVPROFILETYPE {
+    OMX_VIDEO_WMVProfileSimple = 0,
+    OMX_VIDEO_WMVProfileMain,
+    OMX_VIDEO_WMVProfileAdvanced,
+    OMX_VIDEO_WMVProfileUnknown           = 0x6EFFFFFF,
+    OMX_VIDEO_WMVProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_WMVProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+} OMX_VIDEO_WMVPROFILETYPE;
+
+/** WMV Level enum type */
+typedef enum _OMX_VIDEO_WMVLEVELTYPE {
+    OMX_VIDEO_WMVLevelLow = 0,
+    OMX_VIDEO_WMVLevelMedium,
+    OMX_VIDEO_WMVLevelHigh,
+    OMX_VIDEO_WMVLevelL0,
+    OMX_VIDEO_WMVLevelL1,
+    OMX_VIDEO_WMVLevelL2,
+    OMX_VIDEO_WMVLevelL3,
+    OMX_VIDEO_WMVLevelL4,
+    OMX_VIDEO_WMVLevelUnknown           = 0x6EFFFFFF,
+    OMX_VIDEO_WMVLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_WMVLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+} OMX_VIDEO_WMVLEVELTYPE;
+
+/* VC1 codec */
+/** VC1 Profile enum type */
+typedef enum _OMX_VIDEO_VC1PROFILETYPE {
+    OMX_VIDEO_VC1ProfileUnused = 0,
+    OMX_VIDEO_VC1ProfileSimple,
+    OMX_VIDEO_VC1ProfileMain,
+    OMX_VIDEO_VC1ProfileAdvanced,
+    OMX_VIDEO_VC1ProfileUnknown           = 0x6EFFFFFF,
+    OMX_VIDEO_VC1ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_VC1ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_VC1ProfileMax
+} OMX_VIDEO_VC1PROFILETYPE;
+
+/** VC1 Level enum type */
+typedef enum _OMX_VIDEO_VC1LEVELTYPE {
+    OMX_VIDEO_VC1LevelUnused = 0,
+    OMX_VIDEO_VC1LevelLow,
+    OMX_VIDEO_VC1LevelMedium,
+    OMX_VIDEO_VC1LevelHigh,
+    OMX_VIDEO_VC1Level0,
+    OMX_VIDEO_VC1Level1,
+    OMX_VIDEO_VC1Level2,
+    OMX_VIDEO_VC1Level3,
+    OMX_VIDEO_VC1Level4,
+    OMX_VIDEO_VC1LevelUnknown           = 0x6EFFFFFF,
+    OMX_VIDEO_VC1LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+    OMX_VIDEO_VC1LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_VC1LevelMax
+} OMX_VIDEO_VC1LEVELTYPE;
+
+/** Structure for controlling VC1 video encoding and decoding */
+typedef struct _OMX_VIDEO_PARAM_VC1TYPE {
+    OMX_U32                     nSize;
+    OMX_VERSIONTYPE             nVersion;
+    OMX_U32                     nPortIndex;
+    OMX_VIDEO_VC1PROFILETYPE    eProfile;
+    OMX_VIDEO_VC1LEVELTYPE      eLevel;
+} OMX_VIDEO_PARAM_VC1TYPE;
+#endif  // USE_KHRONOS_OMX_1_2
+// codec specific end
+
+
+
+// for android
+typedef struct _EXYNOS_OMX_VIDEO_PRIMARIES {
+    OMX_U16     x;
+    OMX_U16     y;
+} EXYNOS_OMX_VIDEO_PRIMARIES;
+
+typedef struct _EXYNOS_OMX_VIDEO_HDRSTATICINFO {
+    OMX_U32                      nMaxPicAverageLight;
+    OMX_U32                      nMaxContentLight;
+    OMX_U32                      nMaxDisplayLuminance;
+    OMX_U32                      nMinDisplayLuminance;
+
+    EXYNOS_OMX_VIDEO_PRIMARIES   red;
+    EXYNOS_OMX_VIDEO_PRIMARIES   green;
+    EXYNOS_OMX_VIDEO_PRIMARIES   blue;
+    EXYNOS_OMX_VIDEO_PRIMARIES   white;
+} EXYNOS_OMX_VIDEO_HDRSTATICINFO;
+
+typedef struct _EXYNOS_OMX_VIDEO_COLORASPECTS {
+    OMX_U32 nRangeType;
+    OMX_U32 nPrimaryType;
+    OMX_U32 nTransferType;
+    OMX_U32 nCoeffType;
+    OMX_U32 nDataSpace;
+} EXYNOS_OMX_VIDEO_COLORASPECTS;
+
+#ifdef USE_KHRONOS_OMX_HEADER
+/**
+ * Structure for configuring video compression intra refresh period
+ *
+ * STRUCT MEMBERS:
+ *  nSize               : Size of the structure in bytes
+ *  nVersion            : OMX specification version information
+ *  nPortIndex          : Port that this structure applies to
+ *  nRefreshPeriod      : Intra refreh period in frames. Value 0 means disable intra refresh
+*/
+typedef struct _OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32         nPortIndex;
+    OMX_U32         nRefreshPeriod;
+} OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE;
+
+/** Maximum number of VP8 temporal layers */
+#define OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS 3
+
+/** VP8 temporal layer patterns */
+typedef enum _OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE {
+    OMX_VIDEO_VPXTemporalLayerPatternNone   = 0,
+    OMX_VIDEO_VPXTemporalLayerPatternWebRTC = 1,
+    OMX_VIDEO_VPXTemporalLayerPatternMax    = 0x7FFFFFFF
+} OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE;
+
+/**
+ * Android specific VP8/VP9 encoder params
+ *
+ * STRUCT MEMBERS:
+ *  nSize                      : Size of the structure in bytes
+ *  nVersion                   : OMX specification version information
+ *  nPortIndex                 : Port that this structure applies to
+ *  nKeyFrameInterval          : Key frame interval in frames
+ *  eTemporalPattern           : Type of temporal layer pattern
+ *  nTemporalLayerCount        : Number of temporal coding layers
+ *  nTemporalLayerBitrateRatio : Bitrate ratio allocation between temporal
+ *                               streams in percentage
+ *  nMinQuantizer              : Minimum (best quality) quantizer
+ *  nMaxQuantizer              : Maximum (worst quality) quantizer
+ */
+typedef struct _OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32         nPortIndex;
+    OMX_U32         nKeyFrameInterval;      // distance between consecutive key_frames (including one
+                                            // of the key_frames). 0 means interval is unspecified and
+                                            // can be freely chosen by the codec. 1 means a stream of
+                                            // only key_frames.
+    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE eTemporalPattern;
+    OMX_U32         nTemporalLayerCount;
+    OMX_U32         nTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS];
+    OMX_U32         nMinQuantizer;
+    OMX_U32         nMaxQuantizer;
+} OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE;
+
+/** Structure to define if dependent slice segments should be used */
+typedef struct _OMX_VIDEO_SLICESEGMENTSTYPE {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32         nPortIndex;
+    OMX_BOOL        bDepedentSegments;
+    OMX_BOOL        bEnableLoopFilterAcrossSlices;
+} OMX_VIDEO_SLICESEGMENTSTYPE;
+
+#define OMX_MAX_STRINGVALUE_SIZE OMX_MAX_STRINGNAME_SIZE
+#define OMX_MAX_ANDROID_VENDOR_PARAMCOUNT 32
+
+typedef enum _OMX_ANDROID_VENDOR_VALUETYPE {
+    OMX_AndroidVendorValueInt32 = 0,   /*<< int32_t value */
+    OMX_AndroidVendorValueInt64,       /*<< int64_t value */
+    OMX_AndroidVendorValueString,      /*<< string value */
+    OMX_AndroidVendorValueEndUnused,
+} OMX_ANDROID_VENDOR_VALUETYPE;
+
+/**
+ * Structure describing a single value of an Android vendor extension.
+ *
+ * STRUCTURE MEMBERS:
+ *  cKey        : parameter value name.
+ *  eValueType  : parameter value type
+ *  bSet        : if false, the parameter is not set (for OMX_GetConfig) or is unset (OMX_SetConfig)
+ *                if true, the parameter is set to the corresponding value below
+ *  nInt64      : int64 value
+ *  cString     : string value
+ */
+typedef struct _OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE {
+    OMX_U8 cKey[OMX_MAX_STRINGNAME_SIZE];
+    OMX_ANDROID_VENDOR_VALUETYPE eValueType;
+    OMX_BOOL bSet;
+    union {
+        OMX_S32 nInt32;
+        OMX_S64 nInt64;
+        OMX_U8 cString[OMX_MAX_STRINGVALUE_SIZE];
+    };
+} OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE;
+
+/**
+ * OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE is the structure for an Android vendor extension
+ * supported by the component. This structure enumerates the various extension parameters and their
+ * values.
+ *
+ * Android vendor extensions have a name and one or more parameter values - each with a string key -
+ * that are set together. The values are exposed to Android applications via a string key that is
+ * the concatenation of 'vendor', the extension name and the parameter key, each separated by dot
+ * (.), with any trailing '.value' suffix(es) removed (though optionally allowed).
+ *
+ * Extension names and parameter keys are subject to the following rules:
+ *   - Each SHALL contain a set of lowercase alphanumeric (underscore allowed) tags separated by
+ *     dot (.) or dash (-).
+ *   - The first character of the first tag, and any tag following a dot SHALL not start with a
+ *     digit.
+ *   - Tags 'value', 'vendor', 'omx' and 'android' (even if trailed and/or followed by any number
+ *     of underscores) are prohibited in the extension name.
+ *   - Tags 'vendor', 'omx' and 'android' (even if trailed and/or followed by any number
+ *     of underscores) are prohibited in parameter keys.
+ *   - The tag 'value' (even if trailed and/or followed by any number
+ *     of underscores) is prohibited in parameter keys with the following exception:
+ *     the parameter key may be exactly 'value'
+ *   - The parameter key for extensions with a single parameter value SHALL be 'value'
+ *   - No two extensions SHALL have the same name
+ *   - No extension's name SHALL start with another extension's NAME followed by a dot (.)
+ *   - No two parameters of an extension SHALL have the same key
+ *
+ * This config can be used with both OMX_GetConfig and OMX_SetConfig. In the OMX_GetConfig
+ * case, the caller specifies nIndex and nParamSizeUsed. The component fills in cName,
+ * eDir and nParamCount. Additionally, if nParamSizeUsed is not less than nParamCount, the
+ * component fills out the parameter values (nParam) with the current values for each parameter
+ * of the vendor extension.
+ *
+ * The value of nIndex goes from 0 to N-1, where N is the number of Android vendor extensions
+ * supported by the component. The component does not need to report N as the caller can determine
+ * N by enumerating all extensions supported by the component. The component may not support any
+ * extensions. If there are no more extensions, OMX_GetParameter returns OMX_ErrorNoMore. The
+ * component supplies extensions in the order it wants clients to set them.
+ *
+ * The component SHALL return OMX_ErrorNone for all cases where nIndex is less than N (specifically
+ * even in the case of where nParamCount is greater than nParamSizeUsed).
+ *
+ * In the OMX_SetConfig case the field nIndex is ignored. If the component supports an Android
+ * vendor extension with the name in cName, it SHALL configure the parameter values for that
+ * extension according to the parameters in nParam. nParamCount is the number of valid parameters
+ * in the nParam array, and nParamSizeUsed is the size of the nParam array. (nParamSizeUsed
+ * SHALL be at least nParamCount) Parameters that are part of a vendor extension but are not
+ * in the nParam array are assumed to be unset (this is different from not changed).
+ * All parameter values SHALL have distinct keys in nParam (the component can assume that this
+ * is the case. Otherwise, the actual value for the parameters that are multiply defined can
+ * be any of the set values.)
+ *
+ * Return values in case of OMX_SetConfig:
+ *   OMX_ErrorUnsupportedIndex: the component does not support the extension specified by cName
+ *   OMX_ErrorUnsupportedSetting: the component does not support some or any of the parameters
+ *       (names) specified in nParam
+ *   OMX_ErrorBadParameter: the parameter is invalid (e.g. nParamCount is greater than
+ *       nParamSizeUsed, or some parameter value has invalid type)
+ *
+ * STRUCTURE MEMBERS:
+ *  nSize       : size of the structure in bytes
+ *  nVersion    : OMX specification version information
+ *  cName       : name of vendor extension
+ *  nParamCount : the number of parameter values that are part of this vendor extension
+ *  nParamSizeUsed : the size of nParam
+ *                (must be at least 1 and at most OMX_MAX_ANDROID_VENDOR_PARAMCOUNT)
+ *  param       : the parameter values
+ */
+typedef struct _OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nIndex;
+    OMX_U8  cName[OMX_MAX_STRINGNAME_SIZE];
+    OMX_DIRTYPE eDir;
+    OMX_U32 nParamCount;
+    OMX_U32 nParamSizeUsed;
+    OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE param[1];
+} OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE;
+
+/** Maximum number of temporal layers supported by AVC/HEVC */
+#define OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS 8
+
+/** temporal layer patterns */
+typedef enum OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE {
+    OMX_VIDEO_AndroidTemporalLayeringPatternNone = 0,
+    // pattern as defined by WebRTC
+    OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC = 1 << 0,
+    // pattern where frames in any layer other than the base layer only depend on at most the very
+    // last frame from each preceding layer (other than the base layer.)
+    OMX_VIDEO_AndroidTemporalLayeringPatternAndroid = 1 << 1,
+} OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE;
+
+/**
+ * Android specific param for configuration of temporal layering.
+ * Android only supports temporal layering where successive layers each double the
+ * previous layer's framerate.
+ * NOTE: Reading this parameter at run-time SHALL return actual run-time values.
+ *
+ *  nSize                      : Size of the structure in bytes
+ *  nVersion                   : OMX specification version information
+ *  nPortIndex                 : Port that this structure applies to (output port for encoders)
+ *  eSupportedPatterns         : A bitmask of supported layering patterns
+ *  nLayerCountMax             : Max number of temporal coding layers supported
+ *                               by the encoder (must be at least 1, 1 meaning temporal layering
+ *                               is NOT supported)
+ *  nBLayerCountMax            : Max number of layers that can contain B frames
+ *                               (0) to (nLayerCountMax - 1)
+ *  ePattern                   : Layering pattern.
+ *  nPLayerCountActual         : Number of temporal layers to be coded with non-B frames,
+ *                               starting from and including the base-layer.
+ *                               (1 to nLayerCountMax - nBLayerCountActual)
+ *                               If nPLayerCountActual is 1 and nBLayerCountActual is 0, temporal
+ *                               layering is disabled. Otherwise, it is enabled.
+ *  nBLayerCountActual         : Number of temporal layers to be coded with B frames,
+ *                               starting after non-B layers.
+ *                               (0 to nBLayerCountMax)
+ *  bBitrateRatiosSpecified    : Flag to indicate if layer-wise bitrate
+ *                               distribution is specified.
+ *  nBitrateRatios             : Bitrate ratio (100 based) per layer (index 0 is base layer).
+ *                               Honored if bBitrateRatiosSpecified is set.
+ *                               i.e for 4 layers with desired distribution (25% 25% 25% 25%),
+ *                               nBitrateRatio = {25, 50, 75, 100, ... }
+ *                               Values in indices not less than 'the actual number of layers
+ *                               minus 1' MAY be ignored and assumed to be 100.
+ */
+typedef struct OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE eSupportedPatterns;
+    OMX_U32 nLayerCountMax;
+    OMX_U32 nBLayerCountMax;
+    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern;
+    OMX_U32 nPLayerCountActual;
+    OMX_U32 nBLayerCountActual;
+    OMX_BOOL bBitrateRatiosSpecified;
+    OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+} OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE;
+
+/**
+ * Android specific config for changing the temporal-layer count or
+ * bitrate-distribution at run-time.
+ *
+ *  nSize                      : Size of the structure in bytes
+ *  nVersion                   : OMX specification version information
+ *  nPortIndex                 : Port that this structure applies to (output port for encoders)
+ *  ePattern                   : Layering pattern.
+ *  nPLayerCountActual         : Number of temporal layers to be coded with non-B frames.
+ *                               (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ *  nBLayerCountActual         : Number of temporal layers to be coded with B frames.
+ *                               (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ *  bBitrateRatiosSpecified    : Flag to indicate if layer-wise bitrate
+ *                               distribution is specified.
+ *  nBitrateRatios             : Bitrate ratio (100 based, Q16 values) per layer (0 is base layer).
+ *                               Honored if bBitrateRatiosSpecified is set.
+ *                               (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ */
+typedef struct OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern;
+    OMX_U32 nPLayerCountActual;
+    OMX_U32 nBLayerCountActual;
+    OMX_BOOL bBitrateRatiosSpecified;
+    OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+} OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE;
+
+#endif
+// android end
+
+
+
+// for custom component
+typedef struct _EXYNOS_OMX_VIDEO_PARAM_CORRUPTEDHEADER {
+    OMX_U32         nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL        bDiscardEvent;
+} EXYNOS_OMX_VIDEO_PARAM_CORRUPTEDHEADER;
+// custom component end
+
+
+
+// for Skype HD
+typedef struct OMX_VIDEO_PARAM_DRIVERVER {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U64 nDriverVersion;
+} OMX_VIDEO_PARAM_DRIVERVER;
+
+typedef struct OMX_VIDEO_CONFIG_MARKLTRFRAME {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nLongTermFrmIdx;
+} OMX_VIDEO_CONFIG_MARKLTRFRAME;
+
+typedef struct OMX_VIDEO_CONFIG_USELTRFRAME {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U16 nUsedLTRFrameBM;
+} OMX_VIDEO_CONFIG_USELTRFRAME;
+
+typedef struct OMX_VIDEO_CONFIG_QP {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nQP;
+} OMX_VIDEO_CONFIG_QP;
+
+typedef struct OMX_VIDEO_CONFIG_BASELAYERPID{
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nPID;
+} OMX_VIDEO_CONFIG_BASELAYERPID;
+
+typedef struct __OMX_PARAM_ENC_MAX_TEMPORALLAYER_COUNT {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nMaxCountP;
+    OMX_U32 nMaxCountB;
+} OMX_PARAM_ENC_MAX_TEMPORALLAYER_COUNT;
+
+typedef struct __OMX_PARAM_ENC_PREPROCESS {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nResize;
+    OMX_U32 nRotation;
+} OMX_PARAM_ENC_PREPROCESS;
+
+typedef struct __OMX_PARAM_ENC_SAR {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nWidth;
+    OMX_U32 nHeight;
+} OMX_PARAM_ENC_SAR;
+
+typedef struct __OMX_CONFIG_ENC_TRIGGER_TS {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S64 nTimestamp;
+} OMX_CONFIG_ENC_TRIGGER_TS;
+
+#ifndef __OMX_EXPORTS
+#define __OMX_EXPORTS
+#define EXYNOS_EXPORT_REF __attribute__((visibility("default")))
+#define EXYNOS_IMPORT_REF __attribute__((visibility("default")))
+#endif
+
+#endif
diff --git a/openmax/include/exynos/Exynos_OMX_Macros.h b/openmax/include/exynos/Exynos_OMX_Macros.h
new file mode 100755 (executable)
index 0000000..e92c526
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file    Exynos_OMX_Macros.h
+ * @brief   Macros
+ * @author  SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OMX_MACROS
+#define EXYNOS_OMX_MACROS
+
+#include "Exynos_OMX_Def.h"
+#include "Exynos_OSAL_Memory.h"
+
+
+/*
+ * MACROS
+ */
+#define ALIGN(x, a)       (((x) + (a) - 1) & ~((a) - 1))
+#define ALIGN_TO_16B(x)   ((((x) + (1 <<  4) - 1) >>  4) <<  4)
+#define ALIGN_TO_32B(x)   ((((x) + (1 <<  5) - 1) >>  5) <<  5)
+#define ALIGN_TO_128B(x)  ((((x) + (1 <<  7) - 1) >>  7) <<  7)
+#define ALIGN_TO_8KB(x)   ((((x) + (1 << 13) - 1) >> 13) << 13)
+
+/* This is for single FD support.
+ * data is not filled like as continuous padding area for satisfying H/W constraints.
+ */
+/* 8bit format */
+#define GET_Y_SIZE(w, h) (ALIGN(w, 16) * ALIGN(h, 16) + 256)
+#define GET_UV_SIZE(w, h) (ALIGN(((ALIGN(w, 16) * ALIGN(h, 16) / 2) + 256), 16))
+#define GET_CB_SIZE(w, h) (ALIGN(((ALIGN(w / 2, 16) * ALIGN(h, 16) / 2) + 256), 16))
+#define GET_CR_SIZE(w, h) (ALIGN(((ALIGN(w / 2, 16) * ALIGN(h, 16) / 2) + 256), 16))
+
+#define GET_UV_OFFSET(w, h) GET_Y_SIZE(w, h)
+#define GET_CB_OFFSET(w, h) GET_Y_SIZE(w, h)
+#define GET_CR_OFFSET(w, h) (GET_Y_SIZE(w, h) + GET_CB_SIZE(w, h))
+
+/* 10bit format */
+
+#ifndef S10B_FORMAT_8B_ALIGNMENT
+#define S10B_FORMAT_8B_ALIGNMENT 16
+#endif
+#define GET_8B_Y_SIZE(w, h) (ALIGN(w, S10B_FORMAT_8B_ALIGNMENT) * ALIGN(h, 16) + 256)
+#define GET_8B_UV_SIZE(w, h) (ALIGN(((ALIGN(w, S10B_FORMAT_8B_ALIGNMENT) * ALIGN(h, 16) / 2) + 256), 16))
+#define GET_8B_CB_SIZE(w, h) (ALIGN(((ALIGN(w / 2, S10B_FORMAT_8B_ALIGNMENT) * ALIGN(h, 16) / 2) + 256), 16))
+#define GET_8B_CR_SIZE(w, h) (ALIGN(((ALIGN(w / 2, S10B_FORMAT_8B_ALIGNMENT) * ALIGN(h, 16) / 2) + 256), 16))
+#define GET_2B_SIZE(w, h) (ALIGN(w / 4, 16) * ALIGN(h, 16) + 64)
+#define GET_10B_Y_SIZE(w, h) (GET_8B_Y_SIZE(w, h) + GET_2B_SIZE(w, h))
+#define GET_10B_UV_SIZE(w, h) (GET_8B_UV_SIZE(w, h) + GET_2B_SIZE(w, h / 2))
+#define GET_10B_CB_SIZE(w, h) (GET_8B_CB_SIZE(w, h) + GET_2B_SIZE(w, h / 2))
+#define GET_10B_CR_SIZE(w, h) (GET_8B_CR_SIZE(w, h) + GET_2B_SIZE(w, h / 2))
+
+#define GET_10B_UV_OFFSET(w, h) GET_10B_Y_SIZE(w, h)
+#define GET_10B_CB_OFFSET(w, h) GET_10B_Y_SIZE(w, h)
+#define GET_10B_CR_OFFSET(w, h) (GET_10B_Y_SIZE(w, h) + GET_10B_CB_SIZE(w, h))
+
+#define INIT_SET_SIZE_VERSION(_struct_, _structType_)               \
+    do {                                                            \
+        Exynos_OSAL_Memset((_struct_), 0, sizeof(_structType_));       \
+        (_struct_)->nSize = sizeof(_structType_);                   \
+        (_struct_)->nVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; \
+        (_struct_)->nVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; \
+        (_struct_)->nVersion.s.nRevision = REVISION_NUMBER;         \
+        (_struct_)->nVersion.s.nStep = STEP_NUMBER;                 \
+    } while (0)
+
+#define INIT_ARRAY_TO_VAL(array, value, size)   \
+    do {                                        \
+        int i;                                  \
+        for (i = 0; i < size; i++) {            \
+            array[i] = value;                   \
+        }                                       \
+    } while(0)
+
+/*
+ * Port Specific
+ */
+#define EXYNOS_TUNNEL_ESTABLISHED 0x0001
+#define EXYNOS_TUNNEL_IS_SUPPLIER 0x0002
+
+#define CHECK_PORT_BEING_FLUSHED(port)                 (((port)->portState == EXYNOS_OMX_PortStateFlushing) || ((port)->portState == EXYNOS_OMX_PortStateFlushingForDisable))
+#define CHECK_PORT_BEING_DISABLED(port)                ((port)->portState == EXYNOS_OMX_PortStateDisabling)
+#define CHECK_PORT_BEING_ENABLED(port)                 ((port)->portState == EXYNOS_OMX_PortStateEnabling)
+#define CHECK_PORT_ENABLED(port)                       ((port)->portDefinition.bEnabled == OMX_TRUE)
+#define CHECK_PORT_POPULATED(port)                     ((port)->portDefinition.bPopulated == OMX_TRUE)
+#define CHECK_PORT_TUNNELED(port)                      ((port)->tunnelFlags & EXYNOS_TUNNEL_ESTABLISHED)
+#define CHECK_PORT_BUFFER_SUPPLIER(port)               ((port)->tunnelFlags & EXYNOS_TUNNEL_IS_SUPPLIER)
+
+#endif
diff --git a/openmax/include/khronos/OMX_Audio.h b/openmax/include/khronos/OMX_Audio.h
new file mode 100755 (executable)
index 0000000..04f1a99
--- /dev/null
@@ -0,0 +1,1311 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc. 
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions: 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software. 
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ *
+ */
+
+/** @file OMX_Audio.h - OpenMax IL version 1.1.2
+ *  The structures needed by Audio components to exchange
+ *  parameters and configuration data with the componenmilts.
+ */
+
+#ifndef OMX_Audio_h
+#define OMX_Audio_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header must include all required header files to allow the
+ *  header to compile without errors.  The includes below are required
+ *  for this header file to compile successfully 
+ */
+
+#include <OMX_Core.h>
+
+/** @defgroup midi MIDI
+ * @ingroup audio
+ */
+/** @defgroup effects Audio effects
+ * @ingroup audio
+ */
+
+/** @defgroup audio OpenMAX IL Audio Domain
+ * Structures for OpenMAX IL Audio domain
+ * @{
+ */
+
+/** Enumeration used to define the possible audio codings.  
+ *  If "OMX_AUDIO_CodingUnused" is selected, the coding selection must 
+ *  be done in a vendor specific way.  Since this is for an audio 
+ *  processing element this enum is relevant.  However, for another 
+ *  type of component other enums would be in this area.
+ */
+typedef enum OMX_AUDIO_CODINGTYPE {
+    OMX_AUDIO_CodingUnused = 0,  /**< Placeholder value when coding is N/A  */
+    OMX_AUDIO_CodingAutoDetect,  /**< auto detection of audio format */
+    OMX_AUDIO_CodingPCM,         /**< Any variant of PCM coding */
+    OMX_AUDIO_CodingADPCM,       /**< Any variant of ADPCM encoded data */
+    OMX_AUDIO_CodingAMR,         /**< Any variant of AMR encoded data */
+    OMX_AUDIO_CodingGSMFR,       /**< Any variant of GSM fullrate (i.e. GSM610) */
+    OMX_AUDIO_CodingGSMEFR,      /**< Any variant of GSM Enhanced Fullrate encoded data*/
+    OMX_AUDIO_CodingGSMHR,       /**< Any variant of GSM Halfrate encoded data */
+    OMX_AUDIO_CodingPDCFR,       /**< Any variant of PDC Fullrate encoded data */
+    OMX_AUDIO_CodingPDCEFR,      /**< Any variant of PDC Enhanced Fullrate encoded data */
+    OMX_AUDIO_CodingPDCHR,       /**< Any variant of PDC Halfrate encoded data */
+    OMX_AUDIO_CodingTDMAFR,      /**< Any variant of TDMA Fullrate encoded data (TIA/EIA-136-420) */
+    OMX_AUDIO_CodingTDMAEFR,     /**< Any variant of TDMA Enhanced Fullrate encoded data (TIA/EIA-136-410) */
+    OMX_AUDIO_CodingQCELP8,      /**< Any variant of QCELP 8kbps encoded data */
+    OMX_AUDIO_CodingQCELP13,     /**< Any variant of QCELP 13kbps encoded data */
+    OMX_AUDIO_CodingEVRC,        /**< Any variant of EVRC encoded data */
+    OMX_AUDIO_CodingSMV,         /**< Any variant of SMV encoded data */
+    OMX_AUDIO_CodingG711,        /**< Any variant of G.711 encoded data */
+    OMX_AUDIO_CodingG723,        /**< Any variant of G.723 dot 1 encoded data */
+    OMX_AUDIO_CodingG726,        /**< Any variant of G.726 encoded data */
+    OMX_AUDIO_CodingG729,        /**< Any variant of G.729 encoded data */
+    OMX_AUDIO_CodingAAC,         /**< Any variant of AAC encoded data */
+    OMX_AUDIO_CodingMP3,         /**< Any variant of MP3 encoded data */
+    OMX_AUDIO_CodingSBC,         /**< Any variant of SBC encoded data */
+    OMX_AUDIO_CodingVORBIS,      /**< Any variant of VORBIS encoded data */
+    OMX_AUDIO_CodingWMA,         /**< Any variant of WMA encoded data */
+    OMX_AUDIO_CodingRA,          /**< Any variant of RA encoded data */
+    OMX_AUDIO_CodingMIDI,        /**< Any variant of MIDI encoded data */
+    OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_CodingMax = 0x7FFFFFFF
+} OMX_AUDIO_CODINGTYPE;
+
+
+/** The PortDefinition structure is used to define all of the parameters 
+ *  necessary for the compliant component to setup an input or an output audio 
+ *  path.  If additional information is needed to define the parameters of the
+ *  port (such as frequency), additional structures must be sent such as the
+ *  OMX_AUDIO_PARAM_PCMMODETYPE structure to supply the extra parameters for the port.
+ */
+typedef struct OMX_AUDIO_PORTDEFINITIONTYPE {
+    OMX_STRING cMIMEType;            /**< MIME type of data for the port */
+    OMX_NATIVE_DEVICETYPE pNativeRender; /** < platform specific reference
+                                               for an output device, 
+                                               otherwise this field is 0 */
+    OMX_BOOL bFlagErrorConcealment;  /**< Turns on error concealment if it is 
+                                          supported by the OMX component */
+    OMX_AUDIO_CODINGTYPE eEncoding;  /**< Type of data expected for this 
+                                          port (e.g. PCM, AMR, MP3, etc) */
+} OMX_AUDIO_PORTDEFINITIONTYPE;
+
+
+/**  Port format parameter.  This structure is used to enumerate
+  *  the various data input/output format supported by the port.
+  */
+typedef struct OMX_AUDIO_PARAM_PORTFORMATTYPE {
+    OMX_U32 nSize;                  /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
+    OMX_U32 nPortIndex;             /**< Indicates which port to set */
+    OMX_U32 nIndex;                 /**< Indicates the enumeration index for the format from 0x0 to N-1 */
+    OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this port (e.g. PCM, AMR, MP3, etc) */
+} OMX_AUDIO_PARAM_PORTFORMATTYPE;
+
+
+/** PCM mode type  */ 
+typedef enum OMX_AUDIO_PCMMODETYPE { 
+    OMX_AUDIO_PCMModeLinear = 0,  /**< Linear PCM encoded data */ 
+    OMX_AUDIO_PCMModeALaw,        /**< A law PCM encoded data (G.711) */ 
+    OMX_AUDIO_PCMModeMULaw,       /**< Mu law PCM encoded data (G.711)  */ 
+    OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_PCMModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_PCMModeMax = 0x7FFFFFFF 
+} OMX_AUDIO_PCMMODETYPE; 
+
+
+typedef enum OMX_AUDIO_CHANNELTYPE {
+    OMX_AUDIO_ChannelNone = 0x0,    /**< Unused or empty */
+    OMX_AUDIO_ChannelLF   = 0x1,    /**< Left front */
+    OMX_AUDIO_ChannelRF   = 0x2,    /**< Right front */
+    OMX_AUDIO_ChannelCF   = 0x3,    /**< Center front */
+    OMX_AUDIO_ChannelLS   = 0x4,    /**< Left surround */
+    OMX_AUDIO_ChannelRS   = 0x5,    /**< Right surround */
+    OMX_AUDIO_ChannelLFE  = 0x6,    /**< Low frequency effects */
+    OMX_AUDIO_ChannelCS   = 0x7,    /**< Back surround */
+    OMX_AUDIO_ChannelLR   = 0x8,    /**< Left rear. */
+    OMX_AUDIO_ChannelRR   = 0x9,    /**< Right rear. */
+    OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_ChannelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_ChannelMax  = 0x7FFFFFFF 
+} OMX_AUDIO_CHANNELTYPE;
+
+#define OMX_AUDIO_MAXCHANNELS 16  /**< maximum number distinct audio channels that a buffer may contain */
+#define OMX_MIN_PCMPAYLOAD_MSEC 5 /**< Minimum audio buffer payload size for uncompressed (PCM) audio */
+
+/** PCM format description */ 
+typedef struct OMX_AUDIO_PARAM_PCMMODETYPE { 
+    OMX_U32 nSize;                    /**< Size of this structure, in Bytes */ 
+    OMX_VERSIONTYPE nVersion;         /**< OMX specification version information */ 
+    OMX_U32 nPortIndex;               /**< port that this structure applies to */ 
+    OMX_U32 nChannels;                /**< Number of channels (e.g. 2 for stereo) */ 
+    OMX_NUMERICALDATATYPE eNumData;   /**< indicates PCM data as signed or unsigned */ 
+    OMX_ENDIANTYPE eEndian;           /**< indicates PCM data as little or big endian */ 
+    OMX_BOOL bInterleaved;            /**< True for normal interleaved data; false for 
+                                           non-interleaved data (e.g. block data) */ 
+    OMX_U32 nBitPerSample;            /**< Bit per sample */ 
+    OMX_U32 nSamplingRate;            /**< Sampling rate of the source data.  Use 0 for 
+                                           variable or unknown sampling rate. */ 
+    OMX_AUDIO_PCMMODETYPE ePCMMode;   /**< PCM mode enumeration */ 
+    OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS]; /**< Slot i contains channel defined by eChannelMap[i] */
+
+} OMX_AUDIO_PARAM_PCMMODETYPE; 
+
+
+/** Audio channel mode.  This is used by both AAC and MP3, although the names are more appropriate
+ * for the MP3.  For example, JointStereo for MP3 is CouplingChannels for AAC. 
+ */
+typedef enum OMX_AUDIO_CHANNELMODETYPE {
+    OMX_AUDIO_ChannelModeStereo = 0,  /**< 2 channels, the bitrate allocation between those 
+                                          two channels changes accordingly to each channel information */
+    OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between 
+                                           2 channels for higher compression gain */
+    OMX_AUDIO_ChannelModeDual,        /**< 2 mono-channels, each channel is encoded with half 
+                                           the bitrate of the overall bitrate */
+    OMX_AUDIO_ChannelModeMono,        /**< Mono channel mode */
+    OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_ChannelModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_ChannelModeMax = 0x7FFFFFFF
+} OMX_AUDIO_CHANNELMODETYPE;
+
+
+typedef enum OMX_AUDIO_MP3STREAMFORMATTYPE {
+    OMX_AUDIO_MP3StreamFormatMP1Layer3 = 0, /**< MP3 Audio MPEG 1 Layer 3 Stream format */
+    OMX_AUDIO_MP3StreamFormatMP2Layer3,     /**< MP3 Audio MPEG 2 Layer 3 Stream format */
+    OMX_AUDIO_MP3StreamFormatMP2_5Layer3,   /**< MP3 Audio MPEG2.5 Layer 3 Stream format */
+    OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_MP3StreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_MP3StreamFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_MP3STREAMFORMATTYPE;
+
+/** MP3 params */
+typedef struct OMX_AUDIO_PARAM_MP3TYPE {
+    OMX_U32 nSize;                 /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */
+    OMX_U32 nPortIndex;            /**< port that this structure applies to */
+    OMX_U32 nChannels;             /**< Number of channels */
+    OMX_U32 nBitRate;              /**< Bit rate of the input data.  Use 0 for variable
+                                        rate or unknown bit rates */
+    OMX_U32 nSampleRate;           /**< Sampling rate of the source data.  Use 0 for
+                                        variable or unknown sampling rate. */
+    OMX_U32 nAudioBandWidth;       /**< Audio band width (in Hz) to which an encoder should
+                                        limit the audio signal. Use 0 to let encoder decide */
+    OMX_AUDIO_CHANNELMODETYPE eChannelMode;   /**< Channel mode enumeration */
+    OMX_AUDIO_MP3STREAMFORMATTYPE eFormat;  /**< MP3 stream format */
+} OMX_AUDIO_PARAM_MP3TYPE;
+
+
+typedef enum OMX_AUDIO_AACSTREAMFORMATTYPE {
+    OMX_AUDIO_AACStreamFormatMP2ADTS = 0, /**< AAC Audio Data Transport Stream 2 format */
+    OMX_AUDIO_AACStreamFormatMP4ADTS,     /**< AAC Audio Data Transport Stream 4 format */
+    OMX_AUDIO_AACStreamFormatMP4LOAS,     /**< AAC Low Overhead Audio Stream format */
+    OMX_AUDIO_AACStreamFormatMP4LATM,     /**< AAC Low overhead Audio Transport Multiplex */
+    OMX_AUDIO_AACStreamFormatADIF,        /**< AAC Audio Data Interchange Format */
+    OMX_AUDIO_AACStreamFormatMP4FF,       /**< AAC inside MPEG-4/ISO File Format */
+    OMX_AUDIO_AACStreamFormatRAW,         /**< AAC Raw Format */
+    OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_AACStreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_AACStreamFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_AACSTREAMFORMATTYPE;
+
+
+/** AAC mode type.  Note that the term profile is used with the MPEG-2
+ * standard and the term object type and profile is used with MPEG-4 */
+typedef enum OMX_AUDIO_AACPROFILETYPE{
+  OMX_AUDIO_AACObjectNull = 0,      /**< Null, not used */
+  OMX_AUDIO_AACObjectMain = 1,      /**< AAC Main object */
+  OMX_AUDIO_AACObjectLC,            /**< AAC Low Complexity object (AAC profile) */
+  OMX_AUDIO_AACObjectSSR,           /**< AAC Scalable Sample Rate object */
+  OMX_AUDIO_AACObjectLTP,           /**< AAC Long Term Prediction object */
+  OMX_AUDIO_AACObjectHE,            /**< AAC High Efficiency (object type SBR, HE-AAC profile) */
+  OMX_AUDIO_AACObjectScalable,      /**< AAC Scalable object */
+  OMX_AUDIO_AACObjectERLC = 17,     /**< ER AAC Low Complexity object (Error Resilient AAC-LC) */
+  OMX_AUDIO_AACObjectLD = 23,       /**< AAC Low Delay object (Error Resilient) */
+  OMX_AUDIO_AACObjectHE_PS = 29,    /**< AAC High Efficiency with Parametric Stereo coding (HE-AAC v2, object type PS) */
+  OMX_AUDIO_AACObjectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+  OMX_AUDIO_AACObjectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+  OMX_AUDIO_AACObjectMax = 0x7FFFFFFF
+} OMX_AUDIO_AACPROFILETYPE;
+
+
+/** AAC tool usage (for nAACtools in OMX_AUDIO_PARAM_AACPROFILETYPE).
+ * Required for encoder configuration and optional as decoder info output.
+ * For MP3, OMX_AUDIO_CHANNELMODETYPE is sufficient. */
+#define OMX_AUDIO_AACToolNone 0x00000000 /**< no AAC tools allowed (encoder config) or active (decoder info output) */
+#define OMX_AUDIO_AACToolMS   0x00000001 /**< MS: Mid/side joint coding tool allowed or active */
+#define OMX_AUDIO_AACToolIS   0x00000002 /**< IS: Intensity stereo tool allowed or active */
+#define OMX_AUDIO_AACToolTNS  0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */
+#define OMX_AUDIO_AACToolPNS  0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */
+#define OMX_AUDIO_AACToolLTP  0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */
+#define OMX_AUDIO_AACToolAll  0x7FFFFFFF /**< all AAC tools allowed or active (*/
+
+/** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE).
+ * Required for ER encoder configuration and optional as decoder info output */
+#define OMX_AUDIO_AACERNone  0x00000000  /**< no AAC ER tools allowed/used */
+#define OMX_AUDIO_AACERVCB11 0x00000001  /**< VCB11: Virtual Code Books for AAC section data */
+#define OMX_AUDIO_AACERRVLC  0x00000002  /**< RVLC: Reversible Variable Length Coding */
+#define OMX_AUDIO_AACERHCR   0x00000004  /**< HCR: Huffman Codeword Reordering */
+#define OMX_AUDIO_AACERAll   0x7FFFFFFF  /**< all AAC ER tools allowed/used */
+
+
+/** AAC params */
+typedef struct OMX_AUDIO_PARAM_AACPROFILETYPE {
+    OMX_U32 nSize;                 /**< Size of this structure, in Bytes */
+    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */
+    OMX_U32 nPortIndex;            /**< Port that this structure applies to */
+    OMX_U32 nChannels;             /**< Number of channels */
+    OMX_U32 nSampleRate;           /**< Sampling rate of the source data.  Use 0 for
+                                        variable or unknown sampling rate. */
+    OMX_U32 nBitRate;              /**< Bit rate of the input data.  Use 0 for variable
+                                        rate or unknown bit rates */
+    OMX_U32 nAudioBandWidth;       /**< Audio band width (in Hz) to which an encoder should
+                                        limit the audio signal. Use 0 to let encoder decide */
+    OMX_U32 nFrameLength;          /**< Frame length (in audio samples per channel) of the codec.
+                                        Can be 1024 or 960 (AAC-LC), 2048 (HE-AAC), 480 or 512 (AAC-LD).
+                                        Use 0 to let encoder decide */
+    OMX_U32 nAACtools;             /**< AAC tool usage */
+    OMX_U32 nAACERtools;           /**< MPEG-4 AAC error resilience tool usage */
+    OMX_AUDIO_AACPROFILETYPE eAACProfile;   /**< AAC profile enumeration */
+    OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat; /**< AAC stream format enumeration */
+    OMX_AUDIO_CHANNELMODETYPE eChannelMode;   /**< Channel mode enumeration */
+} OMX_AUDIO_PARAM_AACPROFILETYPE;
+
+
+/** VORBIS params */
+typedef struct OMX_AUDIO_PARAM_VORBISTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U32 nChannels;        /**< Number of channels */
+    OMX_U32 nBitRate;         /**< Bit rate of the encoded data data.  Use 0 for variable
+                                   rate or unknown bit rates. Encoding is set to the
+                                   bitrate closest to specified  value (in bps) */
+    OMX_U32 nMinBitRate;      /**< Sets minimum bitrate (in bps). */
+    OMX_U32 nMaxBitRate;      /**< Sets maximum bitrate (in bps). */
+
+    OMX_U32 nSampleRate;      /**< Sampling rate of the source data.  Use 0 for
+                                   variable or unknown sampling rate. */
+    OMX_U32 nAudioBandWidth;  /**< Audio band width (in Hz) to which an encoder should
+                                   limit the audio signal. Use 0 to let encoder decide */
+    OMX_S32 nQuality;            /**< Sets encoding quality to n, between -1 (low) and 10 (high).
+                                   In the default mode of operation, teh quality level is 3.
+                                   Normal quality range is 0 - 10. */
+    OMX_BOOL bManaged;           /**< Set  bitrate  management  mode. This turns off the
+                                   normal VBR encoding, but allows hard or soft bitrate
+                                   constraints to be enforced by the encoder. This mode can
+                                   be slower, and may also be lower quality. It is
+                                   primarily useful for streaming. */
+    OMX_BOOL bDownmix;           /**< Downmix input from stereo to mono (has no effect on 
+                                   non-stereo streams). Useful for lower-bitrate encoding. */     
+} OMX_AUDIO_PARAM_VORBISTYPE;
+
+
+/** WMA Version */
+typedef enum OMX_AUDIO_WMAFORMATTYPE {
+  OMX_AUDIO_WMAFormatUnused = 0, /**< format unused or unknown */
+  OMX_AUDIO_WMAFormat7,          /**< Windows Media Audio format 7 */
+  OMX_AUDIO_WMAFormat8,          /**< Windows Media Audio format 8 */
+  OMX_AUDIO_WMAFormat9,          /**< Windows Media Audio format 9 */
+  OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+  OMX_AUDIO_WMAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+  OMX_AUDIO_WMAFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_WMAFORMATTYPE;
+
+
+/** WMA Profile */
+typedef enum OMX_AUDIO_WMAPROFILETYPE {
+  OMX_AUDIO_WMAProfileUnused = 0,  /**< profile unused or unknown */
+  OMX_AUDIO_WMAProfileL1,          /**< Windows Media audio version 9 profile L1 */
+  OMX_AUDIO_WMAProfileL2,          /**< Windows Media audio version 9 profile L2 */
+  OMX_AUDIO_WMAProfileL3,          /**< Windows Media audio version 9 profile L3 */
+  OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+  OMX_AUDIO_WMAProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+  OMX_AUDIO_WMAProfileMax = 0x7FFFFFFF
+} OMX_AUDIO_WMAPROFILETYPE;
+
+
+/** WMA params */
+typedef struct OMX_AUDIO_PARAM_WMATYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U16 nChannels;        /**< Number of channels */
+    OMX_U32 nBitRate;         /**< Bit rate of the input data.  Use 0 for variable
+                                   rate or unknown bit rates */
+    OMX_AUDIO_WMAFORMATTYPE eFormat; /**< Version of WMA stream / data */
+       OMX_AUDIO_WMAPROFILETYPE eProfile;  /**< Profile of WMA stream / data */
+    OMX_U32 nSamplingRate;    /**< Sampling rate of the source data */
+    OMX_U16 nBlockAlign;      /**< is the block alignment, or block size, in bytes of the audio codec */
+    OMX_U16 nEncodeOptions;   /**< WMA Type-specific data */
+    OMX_U32 nSuperBlockAlign; /**< WMA Type-specific data */
+} OMX_AUDIO_PARAM_WMATYPE;
+
+/** 
+ * RealAudio format
+ */
+typedef enum OMX_AUDIO_RAFORMATTYPE {
+    OMX_AUDIO_RAFormatUnused = 0, /**< Format unused or unknown */
+    OMX_AUDIO_RA8,                /**< RealAudio 8 codec */
+    OMX_AUDIO_RA9,                /**< RealAudio 9 codec */
+    OMX_AUDIO_RA10_AAC,           /**< MPEG-4 AAC codec for bitrates of more than 128kbps */
+    OMX_AUDIO_RA10_CODEC,         /**< RealAudio codec for bitrates less than 128 kbps */
+    OMX_AUDIO_RA10_LOSSLESS,      /**< RealAudio Lossless */
+    OMX_AUDIO_RA10_MULTICHANNEL,  /**< RealAudio Multichannel */
+    OMX_AUDIO_RA10_VOICE,         /**< RealAudio Voice for bitrates below 15 kbps */
+    OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_RAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_RAFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_RAFORMATTYPE;
+
+/** RA (Real Audio) params */ 
+typedef struct OMX_AUDIO_PARAM_RATYPE { 
+    OMX_U32 nSize;              /**< Size of this structure, in Bytes */ 
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */ 
+    OMX_U32 nPortIndex;         /**< Port that this structure applies to */ 
+    OMX_U32 nChannels;          /**< Number of channels */ 
+    OMX_U32 nSamplingRate;      /**< is the sampling rate of the source data */ 
+    OMX_U32 nBitsPerFrame;      /**< is the value for bits per frame  */ 
+    OMX_U32 nSamplePerFrame;    /**< is the value for samples per frame */ 
+    OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */ 
+    OMX_U32 nCouplingStartRegion;   /**< is the coupling start region in the stream  */ 
+    OMX_U32 nNumRegions;        /**< is the number of regions value */ 
+    OMX_AUDIO_RAFORMATTYPE eFormat; /**< is the RealAudio audio format */
+} OMX_AUDIO_PARAM_RATYPE; 
+
+
+/** SBC Allocation Method Type */
+typedef enum OMX_AUDIO_SBCALLOCMETHODTYPE {
+  OMX_AUDIO_SBCAllocMethodLoudness, /**< Loudness allocation method */
+  OMX_AUDIO_SBCAllocMethodSNR,      /**< SNR allocation method */
+  OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+  OMX_AUDIO_SBCAllocMethodVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+  OMX_AUDIO_SBCAllocMethodMax = 0x7FFFFFFF
+} OMX_AUDIO_SBCALLOCMETHODTYPE;
+
+
+/** SBC params */
+typedef struct OMX_AUDIO_PARAM_SBCTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_U32 nChannels;         /**< Number of channels */
+    OMX_U32 nBitRate;          /**< Bit rate of the input data.  Use 0 for variable
+                                    rate or unknown bit rates */
+    OMX_U32 nSampleRate;       /**< Sampling rate of the source data.  Use 0 for
+                                    variable or unknown sampling rate. */
+    OMX_U32 nBlocks;           /**< Number of blocks */
+    OMX_U32 nSubbands;         /**< Number of subbands */
+    OMX_U32 nBitPool;          /**< Bitpool value */
+    OMX_BOOL bEnableBitrate;   /**< Use bitrate value instead of bitpool */
+    OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */
+    OMX_AUDIO_SBCALLOCMETHODTYPE eSBCAllocType;   /**< SBC Allocation method type */
+} OMX_AUDIO_PARAM_SBCTYPE;
+
+
+/** ADPCM stream format parameters */ 
+typedef struct OMX_AUDIO_PARAM_ADPCMTYPE { 
+    OMX_U32 nSize;              /**< size of the structure in bytes */ 
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */ 
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */ 
+    OMX_U32 nChannels;          /**< Number of channels in the data stream (not 
+                                     necessarily the same as the number of channels 
+                                     to be rendered. */ 
+    OMX_U32 nBitsPerSample;     /**< Number of bits in each sample */ 
+    OMX_U32 nSampleRate;        /**< Sampling rate of the source data.  Use 0 for 
+                                    variable or unknown sampling rate. */ 
+} OMX_AUDIO_PARAM_ADPCMTYPE; 
+
+
+/** G723 rate */
+typedef enum OMX_AUDIO_G723RATE {
+    OMX_AUDIO_G723ModeUnused = 0,  /**< AMRNB Mode unused / unknown */
+    OMX_AUDIO_G723ModeLow,         /**< 5300 bps */
+    OMX_AUDIO_G723ModeHigh,        /**< 6300 bps */
+    OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_G723ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_G723ModeMax = 0x7FFFFFFF
+} OMX_AUDIO_G723RATE;
+
+
+/** G723 - Sample rate must be 8 KHz */
+typedef struct OMX_AUDIO_PARAM_G723TYPE { 
+    OMX_U32 nSize;                /**< size of the structure in bytes */ 
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */ 
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */ 
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not 
+                                       necessarily the same as the number of channels 
+                                       to be rendered. */ 
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */ 
+    OMX_AUDIO_G723RATE eBitRate;  /**< todo: Should this be moved to a config? */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */ 
+    OMX_BOOL bPostFilter;         /**< Enable Post Filter */ 
+} OMX_AUDIO_PARAM_G723TYPE; 
+
+
+/** ITU G726 (ADPCM) rate */
+typedef enum OMX_AUDIO_G726MODE {
+    OMX_AUDIO_G726ModeUnused = 0,  /**< G726 Mode unused / unknown */
+    OMX_AUDIO_G726Mode16,          /**< 16 kbps */
+    OMX_AUDIO_G726Mode24,          /**< 24 kbps */
+    OMX_AUDIO_G726Mode32,          /**< 32 kbps, most common rate, also G721 */
+    OMX_AUDIO_G726Mode40,          /**< 40 kbps */
+    OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_G726ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_G726ModeMax = 0x7FFFFFFF
+} OMX_AUDIO_G726MODE;
+
+
+/** G.726 stream format parameters - must be at 8KHz */ 
+typedef struct OMX_AUDIO_PARAM_G726TYPE { 
+    OMX_U32 nSize;              /**< size of the structure in bytes */ 
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */ 
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */ 
+    OMX_U32 nChannels;          /**< Number of channels in the data stream (not 
+                                     necessarily the same as the number of channels 
+                                     to be rendered. */ 
+     OMX_AUDIO_G726MODE eG726Mode;
+} OMX_AUDIO_PARAM_G726TYPE; 
+
+
+/** G729 coder type */
+typedef enum OMX_AUDIO_G729TYPE {
+    OMX_AUDIO_G729 = 0,           /**< ITU G.729  encoded data */
+    OMX_AUDIO_G729A,              /**< ITU G.729 annex A  encoded data */
+    OMX_AUDIO_G729B,              /**< ITU G.729 with annex B encoded data */
+    OMX_AUDIO_G729AB,             /**< ITU G.729 annexes A and B encoded data */
+    OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_G729VendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_G729Max = 0x7FFFFFFF
+} OMX_AUDIO_G729TYPE;
+
+
+/** G729 stream format parameters - fixed 6KHz sample rate */
+typedef struct OMX_AUDIO_PARAM_G729TYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U32 nChannels;        /**< Number of channels in the data stream (not
+                                   necessarily the same as the number of channels
+                                   to be rendered. */
+    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */
+    OMX_AUDIO_G729TYPE eBitType;
+} OMX_AUDIO_PARAM_G729TYPE;
+
+
+/** AMR Frame format */ 
+typedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE { 
+    OMX_AUDIO_AMRFrameFormatConformance = 0,  /**< Frame Format is AMR Conformance 
+                                                   (Standard) Format */ 
+    OMX_AUDIO_AMRFrameFormatIF1,              /**< Frame Format is AMR Interface 
+                                                   Format 1 */ 
+    OMX_AUDIO_AMRFrameFormatIF2,              /**< Frame Format is AMR Interface 
+                                                   Format 2*/ 
+    OMX_AUDIO_AMRFrameFormatFSF,              /**< Frame Format is AMR File Storage 
+                                                   Format */ 
+    OMX_AUDIO_AMRFrameFormatRTPPayload,       /**< Frame Format is AMR Real-Time 
+                                                   Transport Protocol Payload Format */ 
+    OMX_AUDIO_AMRFrameFormatITU,              /**< Frame Format is ITU Format (added at Motorola request) */ 
+    OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_AMRFrameFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF 
+} OMX_AUDIO_AMRFRAMEFORMATTYPE; 
+
+
+/** AMR band mode */
+typedef enum OMX_AUDIO_AMRBANDMODETYPE {
+    OMX_AUDIO_AMRBandModeUnused = 0,          /**< AMRNB Mode unused / unknown */
+    OMX_AUDIO_AMRBandModeNB0,                 /**< AMRNB Mode 0 =  4750 bps */
+    OMX_AUDIO_AMRBandModeNB1,                 /**< AMRNB Mode 1 =  5150 bps */
+    OMX_AUDIO_AMRBandModeNB2,                 /**< AMRNB Mode 2 =  5900 bps */ 
+    OMX_AUDIO_AMRBandModeNB3,                 /**< AMRNB Mode 3 =  6700 bps */
+    OMX_AUDIO_AMRBandModeNB4,                 /**< AMRNB Mode 4 =  7400 bps */
+    OMX_AUDIO_AMRBandModeNB5,                 /**< AMRNB Mode 5 =  7950 bps */
+    OMX_AUDIO_AMRBandModeNB6,                 /**< AMRNB Mode 6 = 10200 bps */
+    OMX_AUDIO_AMRBandModeNB7,                 /**< AMRNB Mode 7 = 12200 bps */
+    OMX_AUDIO_AMRBandModeWB0,                 /**< AMRWB Mode 0 =  6600 bps */
+    OMX_AUDIO_AMRBandModeWB1,                 /**< AMRWB Mode 1 =  8850 bps */
+    OMX_AUDIO_AMRBandModeWB2,                 /**< AMRWB Mode 2 = 12650 bps */ 
+    OMX_AUDIO_AMRBandModeWB3,                 /**< AMRWB Mode 3 = 14250 bps */ 
+    OMX_AUDIO_AMRBandModeWB4,                 /**< AMRWB Mode 4 = 15850 bps */
+    OMX_AUDIO_AMRBandModeWB5,                 /**< AMRWB Mode 5 = 18250 bps */
+    OMX_AUDIO_AMRBandModeWB6,                 /**< AMRWB Mode 6 = 19850 bps */
+    OMX_AUDIO_AMRBandModeWB7,                 /**< AMRWB Mode 7 = 23050 bps */
+    OMX_AUDIO_AMRBandModeWB8,                 /**< AMRWB Mode 8 = 23850 bps */      
+    OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_AMRBandModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_AMRBandModeMax = 0x7FFFFFFF
+} OMX_AUDIO_AMRBANDMODETYPE;
+     
+
+/** AMR Discontinuous Transmission mode */ 
+typedef enum OMX_AUDIO_AMRDTXMODETYPE { 
+    OMX_AUDIO_AMRDTXModeOff = 0,        /**< AMR Discontinuous Transmission Mode is disabled */ 
+    OMX_AUDIO_AMRDTXModeOnVAD1,         /**< AMR Discontinuous Transmission Mode using 
+                                             Voice Activity Detector 1 (VAD1) is enabled */ 
+    OMX_AUDIO_AMRDTXModeOnVAD2,         /**< AMR Discontinuous Transmission Mode using 
+                                             Voice Activity Detector 2 (VAD2) is enabled */       
+    OMX_AUDIO_AMRDTXModeOnAuto,         /**< The codec will automatically select between 
+                                             Off, VAD1 or VAD2 modes */ 
+
+    OMX_AUDIO_AMRDTXasEFR,             /**< DTX as EFR instead of AMR standard (3GPP 26.101, frame type =8,9,10) */
+
+    OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_AMRDTXModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF 
+} OMX_AUDIO_AMRDTXMODETYPE; 
+
+/** AMR params */
+typedef struct OMX_AUDIO_PARAM_AMRTYPE {
+    OMX_U32 nSize;                          /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;               /**< OMX specification version information */
+    OMX_U32 nPortIndex;                     /**< port that this structure applies to */
+    OMX_U32 nChannels;                      /**< Number of channels */
+    OMX_U32 nBitRate;                       /**< Bit rate read only field */
+    OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */ 
+    OMX_AUDIO_AMRDTXMODETYPE  eAMRDTXMode;  /**< AMR DTX Mode enumeration */
+    OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat; /**< AMR frame format enumeration */
+} OMX_AUDIO_PARAM_AMRTYPE;
+
+
+/** GSM_FR (ETSI 06.10, 3GPP 46.010) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_GSMFRTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;   /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_GSMFRTYPE;
+
+
+/** GSM-HR (ETSI 06.20, 3GPP 46.020) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_GSMHRTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;   /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_GSMHRTYPE;
+
+
+/** GSM-EFR (ETSI 06.60, 3GPP 46.060) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_GSMEFRTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_BOOL bDTX;            /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;   /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_GSMEFRTYPE;
+
+
+/** TDMA FR (TIA/EIA-136-420, VSELP 7.95kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_TDMAFRTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_TDMAFRTYPE;
+
+
+/** TDMA EFR (TIA/EIA-136-410, ACELP 7.4kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_TDMAEFRTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_TDMAEFRTYPE;
+
+
+/** PDC FR ( RCR-27, VSELP 6.7kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_PDCFRTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_PDCFRTYPE;
+
+
+/** PDC EFR ( RCR-27, ACELP 6.7kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_PDCEFRTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_PDCEFRTYPE;
+
+/** PDC HR ( RCR-27, PSI-CELP 3.45kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_PDCHRTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_BOOL bDTX;                /**< Enable Discontinuous Transmisssion */
+    OMX_BOOL bHiPassFilter;       /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_PDCHRTYPE;
+
+
+/** CDMA Rate types */
+typedef enum OMX_AUDIO_CDMARATETYPE {
+    OMX_AUDIO_CDMARateBlank = 0,          /**< CDMA encoded frame is blank */
+    OMX_AUDIO_CDMARateFull,               /**< CDMA encoded frame in full rate */
+    OMX_AUDIO_CDMARateHalf,               /**< CDMA encoded frame in half rate */
+    OMX_AUDIO_CDMARateQuarter,            /**< CDMA encoded frame in quarter rate */
+    OMX_AUDIO_CDMARateEighth,             /**< CDMA encoded frame in eighth rate (DTX)*/
+    OMX_AUDIO_CDMARateErasure,            /**< CDMA erasure frame */
+    OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_CDMARateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_CDMARateMax = 0x7FFFFFFF
+} OMX_AUDIO_CDMARATETYPE;
+
+
+/** QCELP8 (TIA/EIA-96, up to 8kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_QCELP8TYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_U32 nBitRate;             /**< Bit rate of the input data.  Use 0 for variable
+                                       rate or unknown bit rates */
+    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */
+    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 */
+    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 */
+} OMX_AUDIO_PARAM_QCELP8TYPE;
+
+
+/** QCELP13 ( CDMA, EIA/TIA-733, 13.3kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_QCELP13TYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */
+    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 */
+    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 */
+} OMX_AUDIO_PARAM_QCELP13TYPE;
+
+
+/** EVRC ( CDMA, EIA/TIA-127, RCELP up to 8.55kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_EVRCTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< actual Frame rate */
+    OMX_BOOL bRATE_REDUCon;       /**< RATE_REDUCtion is requested for this frame */
+    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 */
+    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 */
+    OMX_BOOL bHiPassFilter;       /**< Enable encoder's High Pass Filter */
+    OMX_BOOL bNoiseSuppressor;    /**< Enable encoder's noise suppressor pre-processing */
+    OMX_BOOL bPostFilter;         /**< Enable decoder's post Filter */
+} OMX_AUDIO_PARAM_EVRCTYPE;
+
+
+/** SMV ( up to 8.55kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_SMVTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_U32 nChannels;            /**< Number of channels in the data stream (not
+                                       necessarily the same as the number of channels
+                                       to be rendered. */
+    OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */
+    OMX_BOOL bRATE_REDUCon;           /**< RATE_REDUCtion is requested for this frame */
+    OMX_U32 nMinBitRate;          /**< minmal rate for the encoder = 1,2,3,4, default = 1 ??*/
+    OMX_U32 nMaxBitRate;          /**< maximal rate for the encoder = 1,2,3,4, default = 4 ??*/
+    OMX_BOOL bHiPassFilter;       /**< Enable encoder's High Pass Filter ??*/
+    OMX_BOOL bNoiseSuppressor;    /**< Enable encoder's noise suppressor pre-processing */
+    OMX_BOOL bPostFilter;         /**< Enable decoder's post Filter ??*/
+} OMX_AUDIO_PARAM_SMVTYPE;
+
+
+/** MIDI Format 
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDIFORMATTYPE
+{
+    OMX_AUDIO_MIDIFormatUnknown = 0, /**< MIDI Format unknown or don't care */
+    OMX_AUDIO_MIDIFormatSMF0,        /**< Standard MIDI File Type 0 */
+    OMX_AUDIO_MIDIFormatSMF1,        /**< Standard MIDI File Type 1 */
+    OMX_AUDIO_MIDIFormatSMF2,        /**< Standard MIDI File Type 2 */
+    OMX_AUDIO_MIDIFormatSPMIDI,      /**< SP-MIDI */
+    OMX_AUDIO_MIDIFormatXMF0,        /**< eXtensible Music Format type 0 */
+    OMX_AUDIO_MIDIFormatXMF1,        /**< eXtensible Music Format type 1 */
+    OMX_AUDIO_MIDIFormatMobileXMF,   /**< Mobile XMF (eXtensible Music Format type 2) */
+    OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_MIDIFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_MIDIFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDIFORMATTYPE;
+
+
+/** MIDI params 
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_PARAM_MIDITYPE {
+    OMX_U32 nSize;                 /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */
+    OMX_U32 nPortIndex;            /**< port that this structure applies to */
+    OMX_U32 nFileSize;             /**< size of the MIDI file in bytes, where the entire 
+                                        MIDI file passed in, otherwise if 0x0, the MIDI data 
+                                        is merged and streamed (instead of passed as an 
+                                        entire MIDI file) */
+    OMX_BU32 sMaxPolyphony;        /**< Specifies the maximum simultaneous polyphonic 
+                                        voices. A value of zero indicates that the default 
+                                        polyphony of the device is used  */                                    
+    OMX_BOOL bLoadDefaultSound;    /**< Whether to load default sound 
+                                        bank at initialization */
+    OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */                                                                           
+} OMX_AUDIO_PARAM_MIDITYPE;
+
+
+/** Type of the MIDI sound bank 
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDISOUNDBANKTYPE {
+    OMX_AUDIO_MIDISoundBankUnused = 0,           /**< unused/unknown soundbank type */
+    OMX_AUDIO_MIDISoundBankDLS1,                 /**< DLS version 1 */
+    OMX_AUDIO_MIDISoundBankDLS2,                 /**< DLS version 2 */
+    OMX_AUDIO_MIDISoundBankMobileDLSBase,        /**< Mobile DLS, using the base functionality */
+    OMX_AUDIO_MIDISoundBankMobileDLSPlusOptions, /**< Mobile DLS, using the specification-defined optional feature set */
+    OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_MIDISoundBankVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_MIDISoundBankMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDISOUNDBANKTYPE;
+
+
+/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank 
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE {
+   OMX_AUDIO_MIDISoundBankLayoutUnused = 0,   /**< unused/unknown soundbank type */
+   OMX_AUDIO_MIDISoundBankLayoutGM,           /**< GS layout (based on bank MSB 0x00) */
+   OMX_AUDIO_MIDISoundBankLayoutGM2,          /**< General MIDI 2 layout (using MSB 0x78/0x79, LSB 0x00) */
+   OMX_AUDIO_MIDISoundBankLayoutUser,         /**< Does not conform to any bank numbering standards */
+   OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+   OMX_AUDIO_MIDISoundBankLayoutVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+   OMX_AUDIO_MIDISoundBankLayoutMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE;
+
+
+/** MIDI params to load/unload user soundbank 
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */
+    OMX_U32 nDLSIndex;        /**< DLS file index to be loaded */
+    OMX_U32 nDLSSize;         /**< Size in bytes */
+    OMX_PTR pDLSData;         /**< Pointer to DLS file data */
+    OMX_AUDIO_MIDISOUNDBANKTYPE eMidiSoundBank;   /**< Midi sound bank type enumeration */
+    OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE eMidiSoundBankLayout; /**< Midi sound bank layout enumeration */
+} OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE;
+
+
+/** Structure for Live MIDI events and MIP messages. 
+ * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.) 
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex;       /**< Port that this structure applies to */
+    OMX_U32 nMidiEventSize;   /**< Size of immediate MIDI events or MIP message in bytes  */
+    OMX_U8 nMidiEvents[1];    /**< MIDI event array to be rendered immediately, or an
+                                   array for the MIP message buffer, where the size is 
+                                   indicated by nMidiEventSize */
+} OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE;
+
+
+/** MIDI sound bank/ program pair in a given channel 
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port that this structure applies to */
+    OMX_U32 nChannel;           /**< Valid channel values range from 1 to 16 */
+    OMX_U16 nIDProgram;         /**< Valid program ID range is 1 to 128 */
+    OMX_U16 nIDSoundBank;       /**< Sound bank ID */
+    OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks 
+                                     by index if multiple banks are present */
+} OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE;
+
+
+/** MIDI control 
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDICONTROLTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10 
+                                       format based on JAVA MMAPI (JSR-135) requirement */
+    OMX_BU32 sPlayBackRate;       /**< Relative playback rate, stored as Q14.17 fixed-point
+                                       number based on JSR-135 requirement */
+    OMX_BU32 sTempo ;             /**< Tempo in beats per minute (BPM), stored as Q22.10 
+                                       fixed-point number based on JSR-135 requirement */
+    OMX_U32 nMaxPolyphony;        /**< Specifies the maximum simultaneous polyphonic 
+                                       voices. A value of zero indicates that the default 
+                                       polyphony of the device is used  */
+    OMX_U32 nNumRepeat;           /**< Number of times to repeat playback */
+    OMX_U32 nStopTime;            /**< Time in milliseconds to indicate when playback 
+                                       will stop automatically.  Set to zero if not used */
+    OMX_U16 nChannelMuteMask;     /**< 16 bit mask for channel mute status */
+    OMX_U16 nChannelSoloMask;     /**< 16 bit mask for channel solo status */
+    OMX_U32 nTrack0031MuteMask;   /**< 32 bit mask for track mute status. Note: This is for tracks 0-31 */
+    OMX_U32 nTrack3263MuteMask;   /**< 32 bit mask for track mute status. Note: This is for tracks 32-63 */
+    OMX_U32 nTrack0031SoloMask;   /**< 32 bit mask for track solo status. Note: This is for tracks 0-31 */
+    OMX_U32 nTrack3263SoloMask;   /**< 32 bit mask for track solo status. Note: This is for tracks 32-63 */
+
+} OMX_AUDIO_CONFIG_MIDICONTROLTYPE;
+
+
+/** MIDI Playback States 
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDIPLAYBACKSTATETYPE {
+  OMX_AUDIO_MIDIPlayBackStateUnknown = 0,      /**< Unknown state or state does not map to 
+                                                                                                       other defined states */
+  OMX_AUDIO_MIDIPlayBackStateClosedEngaged,    /**< No MIDI resource is currently open. 
+                                                    The MIDI engine is currently processing 
+                                                    MIDI events. */
+  OMX_AUDIO_MIDIPlayBackStateParsing,          /**< A MIDI resource is open and is being 
+                                                    primed. The MIDI engine is currently 
+                                                    processing MIDI events. */
+  OMX_AUDIO_MIDIPlayBackStateOpenEngaged,      /**< A MIDI resource is open and primed but 
+                                                    not playing. The MIDI engine is currently
+                                                    processing MIDI events. The transition to
+                                                    this state is only possible from the 
+                                                    OMX_AUDIO_MIDIPlayBackStatePlaying state,
+                                                    when the 'playback head' reaches the end
+                                                    of media data or the playback stops due
+                                                    to stop time set.*/
+  OMX_AUDIO_MIDIPlayBackStatePlaying,          /**< A MIDI resource is open and currently
+                                                    playing. The MIDI engine is currently
+                                                    processing MIDI events.*/
+  OMX_AUDIO_MIDIPlayBackStatePlayingPartially, /**< Best-effort playback due to SP-MIDI/DLS
+                                                    resource constraints */
+  OMX_AUDIO_MIDIPlayBackStatePlayingSilently,  /**< Due to system resource constraints and
+                                                    SP-MIDI content constraints, there is
+                                                    no audible MIDI content during playback
+                                                    currently. The situation may change if
+                                                    resources are freed later.*/
+  OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+  OMX_AUDIO_MIDIPlayBackStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+  OMX_AUDIO_MIDIPlayBackStateMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDIPLAYBACKSTATETYPE;
+
+
+/** MIDI status 
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDISTATUSTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_U16 nNumTracks;         /**< Number of MIDI tracks in the file, read only field. 
+                                     NOTE: May not return a meaningful value until the entire 
+                                     file is parsed and buffered.  */
+    OMX_U32 nDuration;          /**< The length of the currently open MIDI resource 
+                                     in milliseconds. NOTE: May not return a meaningful value 
+                                     until the entire file is parsed and buffered.  */  
+    OMX_U32 nPosition;          /**< Current Position of the MIDI resource being played 
+                                     in milliseconds */
+    OMX_BOOL bVibra;            /**< Does Vibra track exist? NOTE: May not return a meaningful 
+                                     value until the entire file is parsed and buffered. */
+    OMX_U32 nNumMetaEvents;     /**< Total number of MIDI Meta Events in the currently 
+                                     open MIDI resource. NOTE: May not return a meaningful value 
+                                     until the entire file is parsed and buffered.  */
+    OMX_U32 nNumActiveVoices;   /**< Number of active voices in the currently playing 
+                                     MIDI resource. NOTE: May not return a meaningful value until 
+                                     the entire file is parsed and buffered. */
+    OMX_AUDIO_MIDIPLAYBACKSTATETYPE eMIDIPlayBackState;  /**< MIDI playback state enumeration, read only field */
+} OMX_AUDIO_CONFIG_MIDISTATUSTYPE;
+
+
+/** MIDI Meta Event structure one per Meta Event.
+ *  MIDI Meta Events are like audio metadata, except that they are interspersed 
+ *  with the MIDI content throughout the file and are not localized in the header. 
+ *  As such, it is necessary to retrieve information about these Meta Events from 
+ *  the engine, as it encounters these Meta Events within the MIDI content. 
+ *  For example, SMF files can have up to 14 types of MIDI Meta Events (copyright, 
+ *  author, default tempo, etc.) scattered throughout the file. 
+ *  @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE{ 
+    OMX_U32 nSize;            /**< size of the structure in bytes */ 
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ 
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */ 
+    OMX_U32 nIndex;           /**< Index of Meta Event */ 
+    OMX_U8 nMetaEventType;    /**< Meta Event Type, 7bits (i.e. 0 - 127) */ 
+    OMX_U32 nMetaEventSize;   /**< size of the Meta Event in bytes */ 
+    OMX_U32 nTrack;           /**< track number for the meta event */
+    OMX_U32 nPosition;        /**< Position of the meta-event in milliseconds */
+} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE; 
+
+
+/** MIDI Meta Event Data structure - one per Meta Event. 
+ * @ingroup midi
+ */ 
+typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE{ 
+    OMX_U32 nSize;            /**< size of the structure in bytes */ 
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ 
+    OMX_U32 nPortIndex;       /**< port that this structure applies to */ 
+    OMX_U32 nIndex;           /**< Index of Meta Event */ 
+    OMX_U32 nMetaEventSize;   /**< size of the Meta Event in bytes */ 
+    OMX_U8 nData[1];          /**< array of one or more bytes of meta data 
+                                   as indicated by the nMetaEventSize field */ 
+} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE; 
+
+
+/** Audio Volume adjustment for a port */
+typedef struct OMX_AUDIO_CONFIG_VOLUMETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to 
+                                     set.  Select the input port to set 
+                                     just that port's volume.  Select the 
+                                     output port to adjust the master 
+                                     volume. */
+    OMX_BOOL bLinear;           /**< Is the volume to be set in linear (0.100) 
+                                     or logarithmic scale (mB) */
+    OMX_BS32 sVolume;           /**< Volume linear setting in the 0..100 range, OR
+                                     Volume logarithmic setting for this port.  The values
+                                     for volume are in mB (millibels = 1/100 dB) relative
+                                     to a gain of 1 (e.g. the output is the same as the 
+                                     input level).  Values are in mB from nMax 
+                                     (maximum volume) to nMin mB (typically negative).
+                                     Since the volume is "voltage"
+                                     and not a "power", it takes a setting of
+                                     -600 mB to decrease the volume by 1/2.  If
+                                     a component cannot accurately set the 
+                                     volume to the requested value, it must
+                                     set the volume to the closest value BELOW
+                                     the requested value.  When getting the
+                                     volume setting, the current actual volume
+                                     must be returned. */
+} OMX_AUDIO_CONFIG_VOLUMETYPE;
+
+
+/** Audio Volume adjustment for a channel */
+typedef struct OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to 
+                                     set.  Select the input port to set 
+                                     just that port's volume.  Select the 
+                                     output port to adjust the master 
+                                     volume. */
+    OMX_U32 nChannel;           /**< channel to select from 0 to N-1, 
+                                     using OMX_ALL to apply volume settings
+                                     to all channels */
+    OMX_BOOL bLinear;           /**< Is the volume to be set in linear (0.100) or 
+                                     logarithmic scale (mB) */
+    OMX_BS32 sVolume;           /**< Volume linear setting in the 0..100 range, OR
+                                     Volume logarithmic setting for this port.  
+                                     The values for volume are in mB 
+                                     (millibels = 1/100 dB) relative to a gain
+                                     of 1 (e.g. the output is the same as the 
+                                     input level).  Values are in mB from nMax 
+                                     (maximum volume) to nMin mB (typically negative).  
+                                     Since the volume is "voltage"
+                                     and not a "power", it takes a setting of
+                                     -600 mB to decrease the volume by 1/2.  If
+                                     a component cannot accurately set the 
+                                     volume to the requested value, it must
+                                     set the volume to the closest value BELOW
+                                     the requested value.  When getting the
+                                     volume setting, the current actual volume
+                                     must be returned. */
+    OMX_BOOL bIsMIDI;           /**< TRUE if nChannel refers to a MIDI channel,
+                                     FALSE otherwise */
+} OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE;
+
+
+/** Audio balance setting */
+typedef struct OMX_AUDIO_CONFIG_BALANCETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to 
+                                     set.  Select the input port to set 
+                                     just that port's balance.  Select the 
+                                     output port to adjust the master 
+                                     balance. */
+    OMX_S32 nBalance;           /**< balance setting for this port 
+                                     (-100 to 100, where -100 indicates
+                                     all left, and no right */
+} OMX_AUDIO_CONFIG_BALANCETYPE;
+
+
+/** Audio Port mute */
+typedef struct OMX_AUDIO_CONFIG_MUTETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< Port index indicating which port to 
+                                     set.  Select the input port to set 
+                                     just that port's mute.  Select the 
+                                     output port to adjust the master 
+                                     mute. */
+    OMX_BOOL bMute;             /**< Mute setting for this port */
+} OMX_AUDIO_CONFIG_MUTETYPE;
+
+
+/** Audio Channel mute */
+typedef struct OMX_AUDIO_CONFIG_CHANNELMUTETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_U32 nChannel;           /**< channel to select from 0 to N-1, 
+                                     using OMX_ALL to apply mute settings
+                                     to all channels */
+    OMX_BOOL bMute;             /**< Mute setting for this channel */
+    OMX_BOOL bIsMIDI;           /**< TRUE if nChannel refers to a MIDI channel,
+                                     FALSE otherwise */ 
+} OMX_AUDIO_CONFIG_CHANNELMUTETYPE;
+
+
+
+/** Enable / Disable for loudness control, which boosts bass and to a 
+ *  smaller extent high end frequencies to compensate for hearing
+ *  ability at the extreme ends of the audio spectrum
+ */ 
+typedef struct OMX_AUDIO_CONFIG_LOUDNESSTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bLoudness;        /**< Enable/disable for loudness */
+} OMX_AUDIO_CONFIG_LOUDNESSTYPE;
+
+
+/** Enable / Disable for bass, which controls low frequencies
+ */ 
+typedef struct OMX_AUDIO_CONFIG_BASSTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bEnable;          /**< Enable/disable for bass control */
+    OMX_S32 nBass;             /**< bass setting for the port, as a 
+                                    continuous value from -100 to 100  
+                                    (0 means no change in bass level)*/
+} OMX_AUDIO_CONFIG_BASSTYPE;
+
+
+/** Enable / Disable for treble, which controls high frequencies tones
+ */ 
+typedef struct OMX_AUDIO_CONFIG_TREBLETYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bEnable;          /**< Enable/disable for treble control */
+    OMX_S32  nTreble;          /**< treble setting for the port, as a
+                                    continuous value from -100 to 100  
+                                    (0 means no change in treble level) */
+} OMX_AUDIO_CONFIG_TREBLETYPE;
+
+
+/** An equalizer is typically used for two reasons: to compensate for an 
+ *  sub-optimal frequency response of a system to make it sound more natural 
+ *  or to create intentionally some unnatural coloring to the sound to create
+ *  an effect.
+ *  @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_EQUALIZERTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bEnable;          /**< Enable/disable for equalizer */
+    OMX_BU32 sBandIndex;       /**< Band number to be set.  Upper Limit is 
+                                    N-1, where N is the number of bands, lower limit is 0 */
+    OMX_BU32 sCenterFreq;      /**< Center frequecies in Hz.  This is a
+                                    read only element and is used to determine 
+                                    the lower, center and upper frequency of 
+                                    this band.  */
+    OMX_BS32 sBandLevel;       /**< band level in millibels */
+} OMX_AUDIO_CONFIG_EQUALIZERTYPE;
+
+
+/** Stereo widening mode type 
+ * @ingroup effects
+ */ 
+typedef enum OMX_AUDIO_STEREOWIDENINGTYPE {
+    OMX_AUDIO_StereoWideningHeadphones,    /**< Stereo widening for loudspeakers */
+    OMX_AUDIO_StereoWideningLoudspeakers,  /**< Stereo widening for closely spaced loudspeakers */
+    OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_AUDIO_StereoWideningVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_AUDIO_StereoWideningMax = 0x7FFFFFFF
+} OMX_AUDIO_STEREOWIDENINGTYPE;
+
+
+/** Control for stereo widening, which is a special 2-channel
+ *  case of the audio virtualizer effect. For example, for 5.1-channel 
+ *  output, it translates to virtual surround sound. 
+ * @ingroup effects
+ */ 
+typedef struct OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bEnable;          /**< Enable/disable for stereo widening control */
+    OMX_AUDIO_STEREOWIDENINGTYPE eWideningType; /**< Stereo widening algorithm type */
+    OMX_U32  nStereoWidening;  /**< stereo widening setting for the port,
+                                    as a continuous value from 0 to 100  */
+} OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE;
+
+
+/** The chorus effect (or ``choralizer'') is any signal processor which makes
+ *  one sound source (such as a voice) sound like many such sources singing 
+ *  (or playing) in unison. Since performance in unison is never exact, chorus 
+ *  effects simulate this by making independently modified copies of the input 
+ *  signal. Modifications may include (1) delay, (2) frequency shift, and 
+ *  (3) amplitude modulation.
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_CHORUSTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bEnable;          /**< Enable/disable for chorus */
+    OMX_BU32 sDelay;           /**< average delay in milliseconds */
+    OMX_BU32 sModulationRate;  /**< rate of modulation in millihertz */
+    OMX_U32 nModulationDepth;  /**< depth of modulation as a percentage of 
+                                    delay (i.e. 0 to 100) */
+    OMX_BU32 nFeedback;        /**< Feedback from chorus output to input in percentage */
+} OMX_AUDIO_CONFIG_CHORUSTYPE;
+
+
+/** Reverberation is part of the reflected sound that follows the early 
+ *  reflections. In a typical room, this consists of a dense succession of 
+ *  echoes whose energy decays exponentially. The reverberation effect structure 
+ *  as defined here includes both (early) reflections as well as (late) reverberations. 
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_REVERBERATIONTYPE {
+    OMX_U32 nSize;                /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;     /**< OMX specification version information */
+    OMX_U32 nPortIndex;           /**< port that this structure applies to */
+    OMX_BOOL bEnable;             /**< Enable/disable for reverberation control */
+    OMX_BS32 sRoomLevel;          /**< Intensity level for the whole room effect 
+                                       (i.e. both early reflections and late 
+                                       reverberation) in millibels */
+    OMX_BS32 sRoomHighFreqLevel;  /**< Attenuation at high frequencies
+                                       relative to the intensity at low
+                                       frequencies in millibels */
+    OMX_BS32 sReflectionsLevel;   /**< Intensity level of early reflections
+                                       (relative to room value), in millibels */
+    OMX_BU32 sReflectionsDelay;   /**< Delay time of the first reflection relative 
+                                       to the direct path, in milliseconds */
+    OMX_BS32 sReverbLevel;        /**< Intensity level of late reverberation
+                                       relative to room level, in millibels */
+    OMX_BU32 sReverbDelay;        /**< Time delay from the first early reflection 
+                                       to the beginning of the late reverberation 
+                                       section, in milliseconds */
+    OMX_BU32 sDecayTime;          /**< Late reverberation decay time at low
+                                       frequencies, in milliseconds */
+    OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative 
+                                       to low frequency decay time in percent  */
+    OMX_U32 nDensity;             /**< Modal density in the late reverberation decay,
+                                       in percent (i.e. 0 - 100) */
+    OMX_U32 nDiffusion;           /**< Echo density in the late reverberation decay,
+                                       in percent (i.e. 0 - 100) */
+    OMX_BU32 sReferenceHighFreq;  /**< Reference high frequency in Hertz. This is 
+                                       the frequency used as the reference for all 
+                                       the high-frequency settings above */
+
+} OMX_AUDIO_CONFIG_REVERBERATIONTYPE;
+
+
+/** Possible settings for the Echo Cancelation structure to use 
+ * @ingroup effects
+ */
+typedef enum OMX_AUDIO_ECHOCANTYPE {
+   OMX_AUDIO_EchoCanOff = 0,    /**< Echo Cancellation is disabled */
+   OMX_AUDIO_EchoCanNormal,     /**< Echo Cancellation normal operation - 
+                                     echo from plastics and face */
+   OMX_AUDIO_EchoCanHFree,      /**< Echo Cancellation optimized for 
+                                     Hands Free operation */
+   OMX_AUDIO_EchoCanCarKit,    /**< Echo Cancellation optimized for 
+                                     Car Kit (longer echo) */
+   OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+   OMX_AUDIO_EchoCanVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+   OMX_AUDIO_EchoCanMax = 0x7FFFFFFF
+} OMX_AUDIO_ECHOCANTYPE;
+
+
+/** Enable / Disable for echo cancelation, which removes undesired echo's
+ *  from the audio
+ * @ingroup effects
+ */ 
+typedef struct OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_AUDIO_ECHOCANTYPE eEchoCancelation; /**< Echo cancelation settings */
+} OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE;
+
+
+/** Enable / Disable for noise reduction, which undesired noise from
+ * the audio
+ * @ingroup effects
+ */ 
+typedef struct OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_U32 nPortIndex;        /**< port that this structure applies to */
+    OMX_BOOL bNoiseReduction;  /**< Enable/disable for noise reduction */
+} OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
+
diff --git a/openmax/include/khronos/OMX_Component.h b/openmax/include/khronos/OMX_Component.h
new file mode 100755 (executable)
index 0000000..d595640
--- /dev/null
@@ -0,0 +1,579 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc. 
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions: 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software. 
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ *
+ */
+
+/** OMX_Component.h - OpenMax IL version 1.1.2
+ *  The OMX_Component header file contains the definitions used to define
+ *  the public interface of a component.  This header file is intended to
+ *  be used by both the application and the component.
+ */
+
+#ifndef OMX_Component_h
+#define OMX_Component_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+/* Each OMX header must include all required header files to allow the
+ *  header to compile without errors.  The includes below are required
+ *  for this header file to compile successfully 
+ */
+
+#include <OMX_Audio.h>
+#include <OMX_Video.h>
+#include <OMX_Image.h>
+#include <OMX_Other.h>
+
+/** @ingroup comp */
+typedef enum OMX_PORTDOMAINTYPE { 
+    OMX_PortDomainAudio, 
+    OMX_PortDomainVideo, 
+    OMX_PortDomainImage, 
+    OMX_PortDomainOther,
+    OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_PortDomainMax = 0x7ffffff
+} OMX_PORTDOMAINTYPE;
+
+/** @ingroup comp */
+typedef struct OMX_PARAM_PORTDEFINITIONTYPE {
+    OMX_U32 nSize;                 /**< Size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;      /**< OMX specification version information */
+    OMX_U32 nPortIndex;            /**< Port number the structure applies to */
+    OMX_DIRTYPE eDir;              /**< Direction (input or output) of this port */
+    OMX_U32 nBufferCountActual;    /**< The actual number of buffers allocated on this port */
+    OMX_U32 nBufferCountMin;       /**< The minimum number of buffers this port requires */
+    OMX_U32 nBufferSize;           /**< Size, in bytes, for buffers to be used for this channel */
+    OMX_BOOL bEnabled;             /**< Ports default to enabled and are enabled/disabled by
+                                        OMX_CommandPortEnable/OMX_CommandPortDisable.
+                                        When disabled a port is unpopulated. A disabled port
+                                        is not populated with buffers on a transition to IDLE. */
+    OMX_BOOL bPopulated;           /**< Port is populated with all of its buffers as indicated by
+                                        nBufferCountActual. A disabled port is always unpopulated. 
+                                        An enabled port is populated on a transition to OMX_StateIdle
+                                        and unpopulated on a transition to loaded. */
+    OMX_PORTDOMAINTYPE eDomain;    /**< Domain of the port. Determines the contents of metadata below. */
+    union {
+        OMX_AUDIO_PORTDEFINITIONTYPE audio;
+        OMX_VIDEO_PORTDEFINITIONTYPE video;
+        OMX_IMAGE_PORTDEFINITIONTYPE image;
+        OMX_OTHER_PORTDEFINITIONTYPE other;
+    } format;
+    OMX_BOOL bBuffersContiguous;
+    OMX_U32 nBufferAlignment;
+} OMX_PARAM_PORTDEFINITIONTYPE;
+
+/** @ingroup comp */
+typedef struct OMX_PARAM_U32TYPE { 
+    OMX_U32 nSize;                    /**< Size of this structure, in Bytes */ 
+    OMX_VERSIONTYPE nVersion;         /**< OMX specification version information */ 
+    OMX_U32 nPortIndex;               /**< port that this structure applies to */ 
+    OMX_U32 nU32;                     /**< U32 value */
+} OMX_PARAM_U32TYPE;
+
+/** @ingroup rpm */
+typedef enum OMX_SUSPENSIONPOLICYTYPE {
+    OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */
+    OMX_SuspensionEnabled,  /**< Suspension allowed */   
+    OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_SuspensionPolicyMax = 0x7fffffff
+} OMX_SUSPENSIONPOLICYTYPE;
+
+/** @ingroup rpm */
+typedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE {
+    OMX_U32 nSize;                  
+    OMX_VERSIONTYPE nVersion;        
+    OMX_SUSPENSIONPOLICYTYPE ePolicy;
+} OMX_PARAM_SUSPENSIONPOLICYTYPE;
+
+/** @ingroup rpm */
+typedef enum OMX_SUSPENSIONTYPE {
+    OMX_NotSuspended, /**< component is not suspended */
+    OMX_Suspended,    /**< component is suspended */
+    OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_SuspendMax = 0x7FFFFFFF
+} OMX_SUSPENSIONTYPE;
+
+/** @ingroup rpm */
+typedef struct OMX_PARAM_SUSPENSIONTYPE {
+    OMX_U32 nSize;                  
+    OMX_VERSIONTYPE nVersion;       
+    OMX_SUSPENSIONTYPE eType;             
+} OMX_PARAM_SUSPENSIONTYPE ;
+
+typedef struct OMX_CONFIG_BOOLEANTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL bEnabled;    
+} OMX_CONFIG_BOOLEANTYPE;
+
+/* Parameter specifying the content uri to use. */
+/** @ingroup cp */
+typedef struct OMX_PARAM_CONTENTURITYPE
+{
+    OMX_U32 nSize;                      /**< size of the structure in bytes, including
+                                             actual URI name */
+    OMX_VERSIONTYPE nVersion;           /**< OMX specification version information */
+    OMX_U8 contentURI[1];               /**< The URI name */
+} OMX_PARAM_CONTENTURITYPE;
+
+/* Parameter specifying the pipe to use. */
+/** @ingroup cp */
+typedef struct OMX_PARAM_CONTENTPIPETYPE
+{
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_HANDLETYPE hPipe;       /**< The pipe handle*/
+} OMX_PARAM_CONTENTPIPETYPE;
+
+/** @ingroup rpm */
+typedef struct OMX_RESOURCECONCEALMENTTYPE {
+    OMX_U32 nSize;             /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+    OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment 
+                                            methods (like degrading algorithm quality to 
+                                            lower resource consumption or functional bypass) 
+                                            on a component as a resolution to resource conflicts. */
+} OMX_RESOURCECONCEALMENTTYPE;
+
+
+/** @ingroup metadata */
+typedef enum OMX_METADATACHARSETTYPE {
+    OMX_MetadataCharsetUnknown = 0,
+    OMX_MetadataCharsetASCII,
+    OMX_MetadataCharsetBinary,
+    OMX_MetadataCharsetCodePage1252,
+    OMX_MetadataCharsetUTF8,
+    OMX_MetadataCharsetJavaConformantUTF8,
+    OMX_MetadataCharsetUTF7,
+    OMX_MetadataCharsetImapUTF7,
+    OMX_MetadataCharsetUTF16LE, 
+    OMX_MetadataCharsetUTF16BE,
+    OMX_MetadataCharsetGB12345,
+    OMX_MetadataCharsetHZGB2312,
+    OMX_MetadataCharsetGB2312,
+    OMX_MetadataCharsetGB18030,
+    OMX_MetadataCharsetGBK,
+    OMX_MetadataCharsetBig5,
+    OMX_MetadataCharsetISO88591,
+    OMX_MetadataCharsetISO88592,
+    OMX_MetadataCharsetISO88593,
+    OMX_MetadataCharsetISO88594,
+    OMX_MetadataCharsetISO88595,
+    OMX_MetadataCharsetISO88596,
+    OMX_MetadataCharsetISO88597,
+    OMX_MetadataCharsetISO88598,
+    OMX_MetadataCharsetISO88599,
+    OMX_MetadataCharsetISO885910,
+    OMX_MetadataCharsetISO885913,
+    OMX_MetadataCharsetISO885914,
+    OMX_MetadataCharsetISO885915,
+    OMX_MetadataCharsetShiftJIS,
+    OMX_MetadataCharsetISO2022JP,
+    OMX_MetadataCharsetISO2022JP1,
+    OMX_MetadataCharsetISOEUCJP,
+    OMX_MetadataCharsetSMS7Bit,
+    OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_MetadataCharsetTypeMax= 0x7FFFFFFF
+} OMX_METADATACHARSETTYPE;
+
+/** @ingroup metadata */
+typedef enum OMX_METADATASCOPETYPE
+{
+    OMX_MetadataScopeAllLevels,
+    OMX_MetadataScopeTopLevel,
+    OMX_MetadataScopePortLevel,
+    OMX_MetadataScopeNodeLevel,
+    OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_MetadataScopeTypeMax = 0x7fffffff
+} OMX_METADATASCOPETYPE;
+
+/** @ingroup metadata */
+typedef enum OMX_METADATASEARCHMODETYPE
+{
+    OMX_MetadataSearchValueSizeByIndex,
+    OMX_MetadataSearchItemByIndex,
+    OMX_MetadataSearchNextItemByKey,
+    OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_MetadataSearchTypeMax = 0x7fffffff
+} OMX_METADATASEARCHMODETYPE;
+/** @ingroup metadata */
+typedef struct OMX_CONFIG_METADATAITEMCOUNTTYPE
+{
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_METADATASCOPETYPE eScopeMode;
+    OMX_U32 nScopeSpecifier;
+    OMX_U32 nMetadataItemCount;
+} OMX_CONFIG_METADATAITEMCOUNTTYPE;
+
+/** @ingroup metadata */
+typedef struct OMX_CONFIG_METADATAITEMTYPE
+{
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_METADATASCOPETYPE eScopeMode;
+    OMX_U32 nScopeSpecifier;
+    OMX_U32 nMetadataItemIndex;  
+    OMX_METADATASEARCHMODETYPE eSearchMode;
+    OMX_METADATACHARSETTYPE eKeyCharset;
+    OMX_U8 nKeySizeUsed;
+    OMX_U8 nKey[128];
+    OMX_METADATACHARSETTYPE eValueCharset;
+    OMX_STRING sLanguageCountry;
+    OMX_U32 nValueMaxSize;
+    OMX_U32 nValueSizeUsed;
+    OMX_U8 nValue[1];
+} OMX_CONFIG_METADATAITEMTYPE;
+
+/* @ingroup metadata */
+typedef struct OMX_CONFIG_CONTAINERNODECOUNTTYPE
+{
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL bAllKeys;
+    OMX_U32 nParentNodeID;
+    OMX_U32 nNumNodes;
+} OMX_CONFIG_CONTAINERNODECOUNTTYPE;
+
+/** @ingroup metadata */
+typedef struct OMX_CONFIG_CONTAINERNODEIDTYPE
+{
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL bAllKeys;
+    OMX_U32 nParentNodeID;
+    OMX_U32 nNodeIndex; 
+    OMX_U32 nNodeID; 
+    OMX_STRING cNodeName;
+    OMX_BOOL bIsLeafType;
+} OMX_CONFIG_CONTAINERNODEIDTYPE;
+
+/** @ingroup metadata */
+typedef struct OMX_PARAM_METADATAFILTERTYPE 
+{ 
+    OMX_U32 nSize; 
+    OMX_VERSIONTYPE nVersion; 
+    OMX_BOOL bAllKeys; /* if true then this structure refers to all keys and 
+                         * the three key fields below are ignored */
+    OMX_METADATACHARSETTYPE eKeyCharset;
+    OMX_U32 nKeySizeUsed; 
+    OMX_U8   nKey [128]; 
+    OMX_U32 nLanguageCountrySizeUsed;
+    OMX_U8 nLanguageCountry[128];
+    OMX_BOOL bEnabled; /* if true then key is part of filter (e.g. 
+                         * retained for query later). If false then
+                         * key is not part of filter */
+} OMX_PARAM_METADATAFILTERTYPE; 
+
+/** The OMX_HANDLETYPE structure defines the component handle.  The component 
+ *  handle is used to access all of the component's public methods and also
+ *  contains pointers to the component's private data area.  The component
+ *  handle is initialized by the OMX core (with help from the component)
+ *  during the process of loading the component.  After the component is
+ *  successfully loaded, the application can safely access any of the
+ *  component's public functions (although some may return an error because
+ *  the state is inappropriate for the access).
+ * 
+ *  @ingroup comp
+ */
+typedef struct OMX_COMPONENTTYPE
+{
+    /** The size of this structure, in bytes.  It is the responsibility
+        of the allocator of this structure to fill in this value.  Since
+        this structure is allocated by the GetHandle function, this
+        function will fill in this value. */
+    OMX_U32 nSize;
+
+    /** nVersion is the version of the OMX specification that the structure 
+        is built against.  It is the responsibility of the creator of this 
+        structure to initialize this value and every user of this structure 
+        should verify that it knows how to use the exact version of 
+        this structure found herein. */
+    OMX_VERSIONTYPE nVersion;
+
+    /** pComponentPrivate is a pointer to the component private data area.  
+        This member is allocated and initialized by the component when the 
+        component is first loaded.  The application should not access this 
+        data area. */
+    OMX_PTR pComponentPrivate;
+
+    /** pApplicationPrivate is a pointer that is a parameter to the 
+        OMX_GetHandle method, and contains an application private value 
+        provided by the IL client.  This application private data is 
+        returned to the IL Client by OMX in all callbacks */
+    OMX_PTR pApplicationPrivate;
+
+    /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL 
+        specification for details on the GetComponentVersion method.
+     */
+    OMX_ERRORTYPE (*GetComponentVersion)(
+            OMX_IN  OMX_HANDLETYPE hComponent,
+            OMX_OUT OMX_STRING pComponentName,
+            OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
+            OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
+            OMX_OUT OMX_UUIDTYPE* pComponentUUID);
+
+    /** refer to OMX_SendCommand in OMX_core.h or the OMX IL 
+        specification for details on the SendCommand method.
+     */
+    OMX_ERRORTYPE (*SendCommand)(
+            OMX_IN  OMX_HANDLETYPE hComponent,
+            OMX_IN  OMX_COMMANDTYPE Cmd,
+            OMX_IN  OMX_U32 nParam1,
+            OMX_IN  OMX_PTR pCmdData);
+
+    /** refer to OMX_GetParameter in OMX_core.h or the OMX IL 
+        specification for details on the GetParameter method.
+     */
+    OMX_ERRORTYPE (*GetParameter)(
+            OMX_IN  OMX_HANDLETYPE hComponent, 
+            OMX_IN  OMX_INDEXTYPE nParamIndex,  
+            OMX_INOUT OMX_PTR pComponentParameterStructure);
+
+
+    /** refer to OMX_SetParameter in OMX_core.h or the OMX IL 
+        specification for details on the SetParameter method.
+     */
+    OMX_ERRORTYPE (*SetParameter)(
+            OMX_IN  OMX_HANDLETYPE hComponent, 
+            OMX_IN  OMX_INDEXTYPE nIndex,
+            OMX_IN  OMX_PTR pComponentParameterStructure);
+
+
+    /** refer to OMX_GetConfig in OMX_core.h or the OMX IL 
+        specification for details on the GetConfig method.
+     */
+    OMX_ERRORTYPE (*GetConfig)(
+            OMX_IN  OMX_HANDLETYPE hComponent,
+            OMX_IN  OMX_INDEXTYPE nIndex, 
+            OMX_INOUT OMX_PTR pComponentConfigStructure);
+
+
+    /** refer to OMX_SetConfig in OMX_core.h or the OMX IL 
+        specification for details on the SetConfig method.
+     */
+    OMX_ERRORTYPE (*SetConfig)(
+            OMX_IN  OMX_HANDLETYPE hComponent,
+            OMX_IN  OMX_INDEXTYPE nIndex, 
+            OMX_IN  OMX_PTR pComponentConfigStructure);
+
+
+    /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL 
+        specification for details on the GetExtensionIndex method.
+     */
+    OMX_ERRORTYPE (*GetExtensionIndex)(
+            OMX_IN  OMX_HANDLETYPE hComponent,
+            OMX_IN  OMX_STRING cParameterName,
+            OMX_OUT OMX_INDEXTYPE* pIndexType);
+
+
+    /** refer to OMX_GetState in OMX_core.h or the OMX IL 
+        specification for details on the GetState method.
+     */
+    OMX_ERRORTYPE (*GetState)(
+            OMX_IN  OMX_HANDLETYPE hComponent,
+            OMX_OUT OMX_STATETYPE* pState);
+
+    
+    /** The ComponentTunnelRequest method will interact with another OMX
+        component to determine if tunneling is possible and to setup the
+        tunneling.  The return codes for this method can be used to 
+        determine if tunneling is not possible, or if tunneling is not
+        supported.  
+        
+        Base profile components (i.e. non-interop) do not support this
+        method and should return OMX_ErrorNotImplemented 
+
+        The interop profile component MUST support tunneling to another 
+        interop profile component with a compatible port parameters.  
+        A component may also support proprietary communication.
+        
+        If proprietary communication is supported the negotiation of 
+        proprietary communication is done outside of OMX in a vendor 
+        specific way. It is only required that the proper result be 
+        returned and the details of how the setup is done is left 
+        to the component implementation.  
+    
+        When this method is invoked when nPort in an output port, the
+        component will:
+        1.  Populate the pTunnelSetup structure with the output port's 
+            requirements and constraints for the tunnel.
+
+        When this method is invoked when nPort in an input port, the
+        component will:
+        1.  Query the necessary parameters from the output port to 
+            determine if the ports are compatible for tunneling
+        2.  If the ports are compatible, the component should store
+            the tunnel step provided by the output port
+        3.  Determine which port (either input or output) is the buffer
+            supplier, and call OMX_SetParameter on the output port to
+            indicate this selection.
+        
+        The component will return from this call within 5 msec.
+    
+        @param [in] hComp
+            Handle of the component to be accessed.  This is the component
+            handle returned by the call to the OMX_GetHandle method.
+        @param [in] nPort
+            nPort is used to select the port on the component to be used
+            for tunneling.
+        @param [in] hTunneledComp
+            Handle of the component to tunnel with.  This is the component 
+            handle returned by the call to the OMX_GetHandle method.  When
+            this parameter is 0x0 the component should setup the port for
+            communication with the application / IL Client.
+        @param [in] nPortOutput
+            nPortOutput is used indicate the port the component should
+            tunnel with.
+        @param [in] pTunnelSetup
+            Pointer to the tunnel setup structure.  When nPort is an output port
+            the component should populate the fields of this structure.  When
+            When nPort is an input port the component should review the setup
+            provided by the component with the output port.
+        @return OMX_ERRORTYPE
+            If the command successfully executes, the return code will be
+            OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+        @ingroup tun
+    */
+
+    OMX_ERRORTYPE (*ComponentTunnelRequest)(
+        OMX_IN  OMX_HANDLETYPE hComp,
+        OMX_IN  OMX_U32 nPort,
+        OMX_IN  OMX_HANDLETYPE hTunneledComp,
+        OMX_IN  OMX_U32 nTunneledPort,
+        OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup); 
+
+    /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL 
+        specification for details on the UseBuffer method.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*UseBuffer)(
+            OMX_IN OMX_HANDLETYPE hComponent,
+            OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
+            OMX_IN OMX_U32 nPortIndex,
+            OMX_IN OMX_PTR pAppPrivate,
+            OMX_IN OMX_U32 nSizeBytes,
+            OMX_IN OMX_U8* pBuffer);
+
+    /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL 
+        specification for details on the AllocateBuffer method.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*AllocateBuffer)(
+            OMX_IN OMX_HANDLETYPE hComponent,
+            OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,
+            OMX_IN OMX_U32 nPortIndex,
+            OMX_IN OMX_PTR pAppPrivate,
+            OMX_IN OMX_U32 nSizeBytes);
+
+    /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL 
+        specification for details on the FreeBuffer method.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*FreeBuffer)(
+            OMX_IN  OMX_HANDLETYPE hComponent,
+            OMX_IN  OMX_U32 nPortIndex,
+            OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+
+    /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL 
+        specification for details on the EmptyThisBuffer method.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*EmptyThisBuffer)(
+            OMX_IN  OMX_HANDLETYPE hComponent,
+            OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+
+    /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL 
+        specification for details on the FillThisBuffer method.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*FillThisBuffer)(
+            OMX_IN  OMX_HANDLETYPE hComponent,
+            OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+
+    /** The SetCallbacks method is used by the core to specify the callback
+        structure from the application to the component.  This is a blocking
+        call.  The component will return from this call within 5 msec.
+        @param [in] hComponent
+            Handle of the component to be accessed.  This is the component
+            handle returned by the call to the GetHandle function.
+        @param [in] pCallbacks
+            pointer to an OMX_CALLBACKTYPE structure used to provide the 
+            callback information to the component
+        @param [in] pAppData
+            pointer to an application defined value.  It is anticipated that 
+            the application will pass a pointer to a data structure or a "this
+            pointer" in this area to allow the callback (in the application)
+            to determine the context of the call
+        @return OMX_ERRORTYPE
+            If the command successfully executes, the return code will be
+            OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+     */
+    OMX_ERRORTYPE (*SetCallbacks)(
+            OMX_IN  OMX_HANDLETYPE hComponent,
+            OMX_IN  OMX_CALLBACKTYPE* pCallbacks, 
+            OMX_IN  OMX_PTR pAppData);
+
+    /** ComponentDeInit method is used to deinitialize the component
+        providing a means to free any resources allocated at component
+        initialization.  NOTE:  After this call the component handle is
+        not valid for further use.
+        @param [in] hComponent
+            Handle of the component to be accessed.  This is the component
+            handle returned by the call to the GetHandle function.
+        @return OMX_ERRORTYPE
+            If the command successfully executes, the return code will be
+            OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+     */
+    OMX_ERRORTYPE (*ComponentDeInit)(
+            OMX_IN  OMX_HANDLETYPE hComponent);
+
+    /** @ingroup buf */
+    OMX_ERRORTYPE (*UseEGLImage)(
+            OMX_IN OMX_HANDLETYPE hComponent,
+            OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
+            OMX_IN OMX_U32 nPortIndex,
+            OMX_IN OMX_PTR pAppPrivate,
+            OMX_IN void* eglImage);
+
+    OMX_ERRORTYPE (*ComponentRoleEnum)(
+        OMX_IN OMX_HANDLETYPE hComponent,
+               OMX_OUT OMX_U8 *cRole,
+               OMX_IN OMX_U32 nIndex);
+
+} OMX_COMPONENTTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/openmax/include/khronos/OMX_ComponentExt.h b/openmax/include/khronos/OMX_ComponentExt.h
new file mode 100755 (executable)
index 0000000..3a5eeb5
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_ComponentExt.h - OpenMax IL version 1.1.2
+ * The OMX_ComponentExt header file contains extensions to the definitions used
+ * by both the application and the component to access common items.
+ */
+
+#ifndef OMX_ComponentExt_h
+#define OMX_ComponentExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header must include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully 
+ */
+#include <OMX_Types.h>
+
+
+/** Set/query the commit mode */
+typedef struct OMX_CONFIG_COMMITMODETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL bDeferred;
+} OMX_CONFIG_COMMITMODETYPE;
+
+/** Explicit commit */
+typedef struct OMX_CONFIG_COMMITTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+} OMX_CONFIG_COMMITTYPE;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_ComponentExt_h */
diff --git a/openmax/include/khronos/OMX_ContentPipe.h b/openmax/include/khronos/OMX_ContentPipe.h
new file mode 100755 (executable)
index 0000000..5f6310c
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc. 
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions: 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software. 
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ *
+ */
+
+/** OMX_ContentPipe.h - OpenMax IL version 1.1.2
+ *  The OMX_ContentPipe header file contains the definitions used to define
+ *  the public interface for content piples.  This header file is intended to
+ *  be used by the component.
+ */
+
+#ifndef OMX_CONTENTPIPE_H
+#define OMX_CONTENTPIPE_H
+
+#ifndef KD_EACCES
+/* OpenKODE error codes. CPResult values may be zero (indicating success
+   or one of the following values) */
+#define KD_EACCES (1)
+#define KD_EADDRINUSE (2)
+#define KD_EAGAIN (5)
+#define KD_EBADF (7)
+#define KD_EBUSY (8)
+#define KD_ECONNREFUSED (9)
+#define KD_ECONNRESET (10)
+#define KD_EDEADLK (11)
+#define KD_EDESTADDRREQ (12)
+#define KD_ERANGE (35)
+#define KD_EEXIST (13)
+#define KD_EFBIG (14)
+#define KD_EHOSTUNREACH (15)
+#define KD_EINVAL (17)
+#define KD_EIO (18)
+#define KD_EISCONN (20)
+#define KD_EISDIR (21)
+#define KD_EMFILE (22)
+#define KD_ENAMETOOLONG (23)
+#define KD_ENOENT (24)
+#define KD_ENOMEM (25)
+#define KD_ENOSPC (26)
+#define KD_ENOSYS (27)
+#define KD_ENOTCONN (28)
+#define KD_EPERM (33)
+#define KD_ETIMEDOUT (36)
+#define KD_EILSEQ (19)
+#endif
+
+/** Map types from OMX standard types only here so interface is as generic as possible. */
+typedef OMX_U32    CPresult;
+typedef char *     CPstring;  
+typedef void *     CPhandle;
+typedef OMX_U32    CPuint;
+typedef OMX_S32    CPint;  
+typedef char       CPbyte;  
+typedef OMX_BOOL   CPbool;
+
+/** enumeration of origin types used in the CP_PIPETYPE's Seek function 
+ * @ingroup cp
+ */
+typedef enum CP_ORIGINTYPE {
+    CP_OriginBegin,      
+    CP_OriginCur,      
+    CP_OriginEnd,      
+    CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    CP_OriginMax = 0X7FFFFFFF
+} CP_ORIGINTYPE;
+
+/** enumeration of contact access types used in the CP_PIPETYPE's Open function 
+ * @ingroup cp
+ */
+typedef enum CP_ACCESSTYPE {
+    CP_AccessRead,      
+    CP_AccessWrite,  
+    CP_AccessReadWrite ,  
+    CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    CP_AccessMax = 0X7FFFFFFF
+} CP_ACCESSTYPE;
+
+/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function 
+ * @ingroup cp
+ */
+typedef enum CP_CHECKBYTESRESULTTYPE
+{
+    CP_CheckBytesOk,                    /**< There are at least the request number 
+                                              of bytes available */
+    CP_CheckBytesNotReady,              /**< The pipe is still retrieving bytes 
+                                              and presently lacks sufficient bytes. 
+                                              Client will be called when they are 
+                                              sufficient bytes are available. */
+    CP_CheckBytesInsufficientBytes  ,     /**< The pipe has retrieved all bytes 
+                                              but those available are less than those 
+                                              requested */
+    CP_CheckBytesAtEndOfStream,         /**< The pipe has reached the end of stream
+                                              and no more bytes are available. */
+    CP_CheckBytesOutOfBuffers,          /**< All read/write buffers are currently in use. */
+    CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    CP_CheckBytesMax = 0X7FFFFFFF
+} CP_CHECKBYTESRESULTTYPE;
+
+/** enumeration of content pipe events sent to the client callback. 
+ * @ingroup cp
+ */
+typedef enum CP_EVENTTYPE{
+    CP_BytesAvailable,             /** bytes requested in a CheckAvailableBytes call are now available*/
+    CP_Overflow,                          /** enumeration of content pipe events sent to the client callback*/
+    CP_PipeDisconnected  ,                 /** enumeration of content pipe events sent to the client callback*/
+    CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    CP_EventMax = 0X7FFFFFFF
+} CP_EVENTTYPE;
+
+/** content pipe definition 
+ * @ingroup cp
+ */
+typedef struct CP_PIPETYPE
+{
+    /** Open a content stream for reading or writing. */ 
+    CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess );
+
+    /** Close a content stream. */ 
+    CPresult (*Close)( CPhandle hContent );
+
+    /** Create a content source and open it for writing. */ 
+    CPresult (*Create)( CPhandle *hContent, CPstring szURI );
+
+    /** Check the that specified number of bytes are available for reading or writing (depending on access type).*/
+    CPresult (*CheckAvailableBytes)( CPhandle hContent, CPuint nBytesRequested, CP_CHECKBYTESRESULTTYPE *eResult );
+
+    /** Seek to certain position in the content relative to the specified origin. */
+    CPresult (*SetPosition)( CPhandle  hContent, CPint nOffset, CP_ORIGINTYPE eOrigin);
+
+    /** Retrieve the current position relative to the start of the content. */
+    CPresult (*GetPosition)( CPhandle hContent, CPuint *pPosition);
+
+    /** Retrieve data of the specified size from the content stream (advance content pointer by size of data).
+       Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */
+    CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize); 
+
+    /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes. 
+       Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also
+       returns the size of the block actually read. Content pointer advances the by the returned size. 
+       Note: pipe provides pointer. This function is appropriate for large reads. The client must call 
+       ReleaseReadBuffer when done with buffer. 
+
+       In some cases the requested block may not reside in contiguous memory within the
+       pipe implementation. For instance if the pipe leverages a circular buffer then the requested 
+       block may straddle the boundary of the circular buffer. By default a pipe implementation 
+       performs a copy in this case to provide the block to the pipe client in one contiguous buffer.
+       If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory 
+       boundary. Here the client may retrieve the data in segments over successive calls. */
+    CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy);
+
+    /** Release a buffer obtained by ReadBuffer back to the pipe. */
+    CPresult (*ReleaseReadBuffer)(CPhandle hContent, CPbyte *pBuffer);
+
+    /** Write data of the specified size to the content (advance content pointer by size of data).
+       Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */
+    CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize); 
+
+    /** Retrieve a buffer allocated by the pipe used to write data to the content. 
+       Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate
+       for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/
+    CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize);
+
+    /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the 
+       the contents of the buffer to content and advance content pointer by the size of the buffer */
+    CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize);
+
+    /** Register a per-handle client callback with the content pipe. */
+    CPresult (*RegisterCallback)( CPhandle hContent, CPresult (*ClientCallback)(CP_EVENTTYPE eEvent, CPuint iParam));
+
+} CP_PIPETYPE;
+
+#endif
+
diff --git a/openmax/include/khronos/OMX_Core.h b/openmax/include/khronos/OMX_Core.h
new file mode 100755 (executable)
index 0000000..4ce240c
--- /dev/null
@@ -0,0 +1,1435 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc. 
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions: 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software. 
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ *
+ */
+
+/** OMX_Core.h - OpenMax IL version 1.1.2
+ *  The OMX_Core header file contains the definitions used by both the
+ *  application and the component to access common items.
+ */
+
+#ifndef OMX_Core_h
+#define OMX_Core_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header shall include all required header files to allow the
+ *  header to compile without errors.  The includes below are required
+ *  for this header file to compile successfully 
+ */
+
+#include <OMX_Index.h>
+
+
+/** The OMX_COMMANDTYPE enumeration is used to specify the action in the
+ *  OMX_SendCommand macro.  
+ *  @ingroup core
+ */
+typedef enum OMX_COMMANDTYPE
+{
+    OMX_CommandStateSet,    /**< Change the component state */
+    OMX_CommandFlush,       /**< Flush the data queue(s) of a component */
+    OMX_CommandPortDisable, /**< Disable a port on a component. */
+    OMX_CommandPortEnable,  /**< Enable a port on a component. */
+    OMX_CommandMarkBuffer,  /**< Mark a component/buffer for observation */
+    OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_CommandMax = 0X7FFFFFFF
+} OMX_COMMANDTYPE;
+
+
+
+/** The OMX_STATETYPE enumeration is used to indicate or change the component
+ *  state.  This enumeration reflects the current state of the component when
+ *  used with the OMX_GetState macro or becomes the parameter in a state change
+ *  command when used with the OMX_SendCommand macro.
+ *
+ *  The component will be in the Loaded state after the component is initially
+ *  loaded into memory.  In the Loaded state, the component is not allowed to
+ *  allocate or hold resources other than to build it's internal parameter
+ *  and configuration tables.  The application will send one or more
+ *  SetParameters/GetParameters and SetConfig/GetConfig commands to the
+ *  component and the component will record each of these parameter and
+ *  configuration changes for use later.  When the application sends the
+ *  Idle command, the component will acquire the resources needed for the
+ *  specified configuration and will transition to the idle state if the
+ *  allocation is successful.  If the component cannot successfully
+ *  transition to the idle state for any reason, the state of the component
+ *  shall be fully rolled back to the Loaded state (e.g. all allocated 
+ *  resources shall be released).  When the component receives the command
+ *  to go to the Executing state, it shall begin processing buffers by
+ *  sending all input buffers it holds to the application.  While
+ *  the component is in the Idle state, the application may also send the
+ *  Pause command.  If the component receives the pause command while in the
+ *  Idle state, the component shall send all input buffers it holds to the 
+ *  application, but shall not begin processing buffers.  This will allow the
+ *  application to prefill buffers.
+ * 
+ *  @ingroup comp
+ */
+
+typedef enum OMX_STATETYPE
+{
+    OMX_StateInvalid,      /**< component has detected that it's internal data 
+                                structures are corrupted to the point that
+                                it cannot determine it's state properly */
+    OMX_StateLoaded,      /**< component has been loaded but has not completed
+                                initialization.  The OMX_SetParameter macro
+                                and the OMX_GetParameter macro are the only 
+                                valid macros allowed to be sent to the 
+                                component in this state. */
+    OMX_StateIdle,        /**< component initialization has been completed
+                                successfully and the component is ready to
+                                to start. */
+    OMX_StateExecuting,   /**< component has accepted the start command and
+                                is processing data (if data is available) */
+    OMX_StatePause,       /**< component has received pause command */
+    OMX_StateWaitForResources, /**< component is waiting for resources, either after 
+                                preemption or before it gets the resources requested.
+                                See specification for complete details. */
+    OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_StateMax = 0X7FFFFFFF
+} OMX_STATETYPE;
+
+/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors.  These 
+ *  errors should cover most of the common failure cases.  However, 
+ *  vendors are free to add additional error messages of their own as 
+ *  long as they follow these rules:
+ *  1.  Vendor error messages shall be in the range of 0x90000000 to
+ *      0x9000FFFF.
+ *  2.  Vendor error messages shall be defined in a header file provided
+ *      with the component.  No error messages are allowed that are
+ *      not defined.
+ */
+typedef enum OMX_ERRORTYPE
+{
+  OMX_ErrorNone = 0,
+
+  /** There were insufficient resources to perform the requested operation */
+  OMX_ErrorInsufficientResources = (OMX_S32) 0x80001000,
+
+  /** There was an error, but the cause of the error could not be determined */
+  OMX_ErrorUndefined = (OMX_S32) 0x80001001,
+
+  /** The component name string was not valid */
+  OMX_ErrorInvalidComponentName = (OMX_S32) 0x80001002,
+
+  /** No component with the specified name string was found */
+  OMX_ErrorComponentNotFound = (OMX_S32) 0x80001003,
+
+  /** The component specified did not have a "OMX_ComponentInit" or
+      "OMX_ComponentDeInit entry point */
+  OMX_ErrorInvalidComponent = (OMX_S32) 0x80001004,
+
+  /** One or more parameters were not valid */
+  OMX_ErrorBadParameter = (OMX_S32) 0x80001005,
+
+  /** The requested function is not implemented */
+  OMX_ErrorNotImplemented = (OMX_S32) 0x80001006,
+
+  /** The buffer was emptied before the next buffer was ready */
+  OMX_ErrorUnderflow = (OMX_S32) 0x80001007,
+
+  /** The buffer was not available when it was needed */
+  OMX_ErrorOverflow = (OMX_S32) 0x80001008,
+
+  /** The hardware failed to respond as expected */
+  OMX_ErrorHardware = (OMX_S32) 0x80001009,
+
+  /** The component is in the state OMX_StateInvalid */
+  OMX_ErrorInvalidState = (OMX_S32) 0x8000100A,
+
+  /** Stream is found to be corrupt */
+  OMX_ErrorStreamCorrupt = (OMX_S32) 0x8000100B,
+
+  /** Ports being connected are not compatible */
+  OMX_ErrorPortsNotCompatible = (OMX_S32) 0x8000100C,
+
+  /** Resources allocated to an idle component have been
+      lost resulting in the component returning to the loaded state */
+  OMX_ErrorResourcesLost = (OMX_S32) 0x8000100D,
+
+  /** No more indicies can be enumerated */
+  OMX_ErrorNoMore = (OMX_S32) 0x8000100E,
+
+  /** The component detected a version mismatch */
+  OMX_ErrorVersionMismatch = (OMX_S32) 0x8000100F,
+
+  /** The component is not ready to return data at this time */
+  OMX_ErrorNotReady = (OMX_S32) 0x80001010,
+
+  /** There was a timeout that occurred */
+  OMX_ErrorTimeout = (OMX_S32) 0x80001011,
+
+  /** This error occurs when trying to transition into the state you are already in */
+  OMX_ErrorSameState = (OMX_S32) 0x80001012,
+
+  /** Resources allocated to an executing or paused component have been 
+      preempted, causing the component to return to the idle state */
+  OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013, 
+
+  /** A non-supplier port sends this error to the IL client (via the EventHandler callback) 
+      during the allocation of buffers (on a transition from the LOADED to the IDLE state or
+      on a port restart) when it deems that it has waited an unusually long time for the supplier 
+      to send it an allocated buffer via a UseBuffer call. */
+  OMX_ErrorPortUnresponsiveDuringAllocation = (OMX_S32) 0x80001014,
+
+  /** A non-supplier port sends this error to the IL client (via the EventHandler callback) 
+      during the deallocation of buffers (on a transition from the IDLE to LOADED state or 
+      on a port stop) when it deems that it has waited an unusually long time for the supplier 
+      to request the deallocation of a buffer header via a FreeBuffer call. */
+  OMX_ErrorPortUnresponsiveDuringDeallocation = (OMX_S32) 0x80001015,
+
+  /** A supplier port sends this error to the IL client (via the EventHandler callback) 
+      during the stopping of a port (either on a transition from the IDLE to LOADED 
+      state or a port stop) when it deems that it has waited an unusually long time for 
+      the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call. */
+  OMX_ErrorPortUnresponsiveDuringStop = (OMX_S32) 0x80001016,
+
+  /** Attempting a state transtion that is not allowed */
+  OMX_ErrorIncorrectStateTransition = (OMX_S32) 0x80001017,
+
+  /* Attempting a command that is not allowed during the present state. */
+  OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018, 
+
+  /** The values encapsulated in the parameter or config structure are not supported. */
+  OMX_ErrorUnsupportedSetting = (OMX_S32) 0x80001019,
+
+  /** The parameter or config indicated by the given index is not supported. */
+  OMX_ErrorUnsupportedIndex = (OMX_S32) 0x8000101A,
+
+  /** The port index supplied is incorrect. */
+  OMX_ErrorBadPortIndex = (OMX_S32) 0x8000101B,
+
+  /** The port has lost one or more of its buffers and it thus unpopulated. */
+  OMX_ErrorPortUnpopulated = (OMX_S32) 0x8000101C,
+
+  /** Component suspended due to temporary loss of resources */
+  OMX_ErrorComponentSuspended = (OMX_S32) 0x8000101D,
+
+  /** Component suspended due to an inability to acquire dynamic resources */
+  OMX_ErrorDynamicResourcesUnavailable = (OMX_S32) 0x8000101E,
+
+  /** When the macroblock error reporting is enabled the component returns new error 
+  for every frame that has errors */
+  OMX_ErrorMbErrorsInFrame = (OMX_S32) 0x8000101F,
+
+  /** A component reports this error when it cannot parse or determine the format of an input stream. */
+  OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020, 
+
+  /** The content open operation failed. */
+  OMX_ErrorContentPipeOpenFailed = (OMX_S32) 0x80001021,
+
+  /** The content creation operation failed. */
+  OMX_ErrorContentPipeCreationFailed = (OMX_S32) 0x80001022,
+
+  /** Separate table information is being used */
+  OMX_ErrorSeperateTablesUsed = (OMX_S32) 0x80001023,
+
+  /** Tunneling is unsupported by the component*/
+  OMX_ErrorTunnelingUnsupported = (OMX_S32) 0x80001024,
+
+  OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+  OMX_ErrorVendorStartUnused = (OMX_S32)0x90000000, /**< Reserved region for introducing Vendor Extensions */
+  OMX_ErrorMax = 0x7FFFFFFF
+} OMX_ERRORTYPE;
+
+/** @ingroup core */
+typedef OMX_ERRORTYPE (* OMX_COMPONENTINITTYPE)(OMX_IN  OMX_HANDLETYPE hComponent);
+
+/** @ingroup core */
+typedef struct OMX_COMPONENTREGISTERTYPE
+{
+  const char          * pName;       /* Component name, 128 byte limit (including '\0') applies */
+  OMX_COMPONENTINITTYPE pInitialize; /* Component instance initialization function */
+} OMX_COMPONENTREGISTERTYPE;
+
+/** @ingroup core */
+extern OMX_COMPONENTREGISTERTYPE OMX_ComponentRegistered[];
+
+/** @ingroup rpm */
+typedef struct OMX_PRIORITYMGMTTYPE {
+ OMX_U32 nSize;             /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;  /**< OMX specification version information */
+ OMX_U32 nGroupPriority;            /**< Priority of the component group */
+ OMX_U32 nGroupID;                  /**< ID of the component group */
+} OMX_PRIORITYMGMTTYPE;
+
+/* Component name and Role names are limited to 128 characters including the terminating '\0'. */
+#define OMX_MAX_STRINGNAME_SIZE 128
+
+/** @ingroup comp */
+typedef struct OMX_PARAM_COMPONENTROLETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U8 cRole[OMX_MAX_STRINGNAME_SIZE];  /**< name of standard component which defines component role */
+} OMX_PARAM_COMPONENTROLETYPE;
+
+/** End of Stream Buffer Flag: 
+  *
+  * A component sets EOS when it has no more data to emit on a particular 
+  * output port. Thus an output port shall set EOS on the last buffer it 
+  * emits. A component's determination of when an output port should 
+  * cease sending data is implemenation specific.
+  * @ingroup buf
+  */
+
+#define OMX_BUFFERFLAG_EOS 0x00000001 
+
+/** Start Time Buffer Flag: 
+ *
+ * The source of a stream (e.g. a demux component) sets the STARTTIME
+ * flag on the buffer that contains the starting timestamp for the
+ * stream. The starting timestamp corresponds to the first data that
+ * should be displayed at startup or after a seek.
+ * The first timestamp of the stream is not necessarily the start time.
+ * For instance, in the case of a seek to a particular video frame, 
+ * the target frame may be an interframe. Thus the first buffer of 
+ * the stream will be the intra-frame preceding the target frame and
+ * the starttime will occur with the target frame (with any other
+ * required frames required to reconstruct the target intervening).
+ *
+ * The STARTTIME flag is directly associated with the buffer's 
+ * timestamp ' thus its association to buffer data and its 
+ * propagation is identical to the timestamp's.
+ *
+ * When a Sync Component client receives a buffer with the 
+ * STARTTIME flag it shall perform a SetConfig on its sync port 
+ * using OMX_ConfigTimeClientStartTime and passing the buffer's
+ * timestamp.
+ * 
+ * @ingroup buf
+ */
+
+#define OMX_BUFFERFLAG_STARTTIME 0x00000002
+
+
+/** Decode Only Buffer Flag: 
+ *
+ * The source of a stream (e.g. a demux component) sets the DECODEONLY
+ * flag on any buffer that should shall be decoded but should not be
+ * displayed. This flag is used, for instance, when a source seeks to 
+ * a target interframe that requires the decode of frames preceding the 
+ * target to facilitate the target's reconstruction. In this case the 
+ * source would emit the frames preceding the target downstream 
+ * but mark them as decode only.
+ *
+ * The DECODEONLY is associated with buffer data and propagated in a 
+ * manner identical to the buffer timestamp.
+ *
+ * A component that renders data should ignore all buffers with 
+ * the DECODEONLY flag set.
+ * 
+ * @ingroup buf
+ */
+
+#define OMX_BUFFERFLAG_DECODEONLY 0x00000004
+
+
+/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt 
+ * @ingroup buf
+ */
+
+#define OMX_BUFFERFLAG_DATACORRUPT 0x00000008
+
+/* End of Frame: The buffer contains exactly one end of frame and no data
+ *  occurs after the end of frame. This flag is an optional hint. The absence
+ *  of this flag does not imply the absence of an end of frame within the buffer. 
+ * @ingroup buf
+*/
+#define OMX_BUFFERFLAG_ENDOFFRAME 0x00000010
+
+/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame ' 
+ *  a frame that has no dependency on any other frame information 
+ *  @ingroup buf
+ */
+#define OMX_BUFFERFLAG_SYNCFRAME 0x00000020
+
+/* Extra data present flag: there is extra data appended to the data stream
+ * residing in the buffer 
+ * @ingroup buf  
+ */
+#define OMX_BUFFERFLAG_EXTRADATA 0x00000040
+
+/** Codec Config Buffer Flag: 
+* OMX_BUFFERFLAG_CODECCONFIG is an optional flag that is set by an
+* output port when all bytes in the buffer form part or all of a set of
+* codec specific configuration data.  Examples include SPS/PPS nal units
+* for OMX_VIDEO_CodingAVC or AudioSpecificConfig data for
+* OMX_AUDIO_CodingAAC.  Any component that for a given stream sets 
+* OMX_BUFFERFLAG_CODECCONFIG shall not mix codec configuration bytes
+* with frame data in the same buffer, and shall send all buffers
+* containing codec configuration bytes before any buffers containing
+* frame data that those configurations bytes describe.
+* If the stream format for a particular codec has a frame specific
+* header at the start of each frame, for example OMX_AUDIO_CodingMP3 or
+* OMX_AUDIO_CodingAAC in ADTS mode, then these shall be presented as
+* normal without setting OMX_BUFFERFLAG_CODECCONFIG.
+ * @ingroup buf
+ */
+#define OMX_BUFFERFLAG_CODECCONFIG 0x00000080
+
+
+
+/** @ingroup buf */
+typedef struct OMX_BUFFERHEADERTYPE
+{
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U8* pBuffer;            /**< Pointer to actual block of memory 
+                                     that is acting as the buffer */
+    OMX_U32 nAllocLen;          /**< size of the buffer allocated, in bytes */
+    OMX_U32 nFilledLen;         /**< number of bytes currently in the 
+                                     buffer */
+    OMX_U32 nOffset;            /**< start offset of valid data in bytes from
+                                     the start of the buffer */
+    OMX_PTR pAppPrivate;        /**< pointer to any data the application
+                                     wants to associate with this buffer */
+    OMX_PTR pPlatformPrivate;   /**< pointer to any data the platform
+                                     wants to associate with this buffer */ 
+    OMX_PTR pInputPortPrivate;  /**< pointer to any data the input port
+                                     wants to associate with this buffer */
+    OMX_PTR pOutputPortPrivate; /**< pointer to any data the output port
+                                     wants to associate with this buffer */
+    OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a 
+                                              mark event upon processing this buffer. */
+    OMX_PTR pMarkData;          /**< Application specific data associated with 
+                                     the mark sent on a mark event to disambiguate 
+                                     this mark from others. */
+    OMX_U32 nTickCount;         /**< Optional entry that the component and
+                                     application can update with a tick count
+                                     when they access the component.  This
+                                     value should be in microseconds.  Since
+                                     this is a value relative to an arbitrary
+                                     starting point, this value cannot be used 
+                                     to determine absolute time.  This is an
+                                     optional entry and not all components
+                                     will update it.*/
+    OMX_TICKS nTimeStamp;       /**< Timestamp corresponding to the sample 
+                                     starting at the first logical sample 
+                                     boundary in the buffer. Timestamps of 
+                                     successive samples within the buffer may
+                                     be inferred by adding the duration of the 
+                                     of the preceding buffer to the timestamp
+                                     of the preceding buffer.*/
+    OMX_U32     nFlags;         /**< buffer specific flags */
+    OMX_U32 nOutputPortIndex;   /**< The index of the output port (if any) using 
+                                     this buffer */
+    OMX_U32 nInputPortIndex;    /**< The index of the input port (if any) using
+                                     this buffer */
+#ifdef TIZEN_OMXIL_COMMERCIAL_FEATURE
+    OMX_U32 output_width;
+    OMX_U32 output_height;
+#endif 
+} OMX_BUFFERHEADERTYPE;
+
+/** The OMX_EXTRADATATYPE enumeration is used to define the 
+ * possible extra data payload types.
+ * NB: this enum is binary backwards compatible with the previous
+ * OMX_EXTRADATA_QUANT define.  This should be replaced with
+ * OMX_ExtraDataQuantization.
+ */
+typedef enum OMX_EXTRADATATYPE
+{
+   OMX_ExtraDataNone = 0,                       /**< Indicates that no more extra data sections follow */        
+   OMX_ExtraDataQuantization,                   /**< The data payload contains quantization data */
+   OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+   OMX_ExtraDataVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+   OMX_ExtraDataMax = 0x7FFFFFFF
+} OMX_EXTRADATATYPE;
+
+
+typedef struct OMX_OTHER_EXTRADATATYPE  {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;               
+    OMX_U32 nPortIndex;
+    OMX_EXTRADATATYPE eType;       /* Extra Data type */
+    OMX_U32 nDataSize;   /* Size of the supporting data to follow */
+    OMX_U8  data[1];     /* Supporting data hint  */
+} OMX_OTHER_EXTRADATATYPE;
+
+/** @ingroup comp */
+typedef struct OMX_PORT_PARAM_TYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPorts;             /**< The number of ports for this component */
+    OMX_U32 nStartPortNumber;   /** first port number for this type of port */
+} OMX_PORT_PARAM_TYPE; 
+
+/** @ingroup comp */
+typedef enum OMX_EVENTTYPE
+{
+    OMX_EventCmdComplete,         /**< component has sucessfully completed a command */
+    OMX_EventError,               /**< component has detected an error condition */
+    OMX_EventMark,                /**< component has detected a buffer mark */
+    OMX_EventPortSettingsChanged, /**< component is reported a port settings change */
+    OMX_EventBufferFlag,          /**< component has detected an EOS */ 
+    OMX_EventResourcesAcquired,   /**< component has been granted resources and is
+                                       automatically starting the state change from
+                                       OMX_StateWaitForResources to OMX_StateIdle. */
+   OMX_EventComponentResumed,     /**< Component resumed due to reacquisition of resources */
+   OMX_EventDynamicResourcesAvailable, /**< Component has acquired previously unavailable dynamic resources */
+   OMX_EventPortFormatDetected,      /**< Component has detected a supported format. */
+   OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+   OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+   OMX_EventMax = 0x7FFFFFFF
+} OMX_EVENTTYPE;
+
+typedef struct OMX_CALLBACKTYPE
+{
+    /** The EventHandler method is used to notify the application when an
+        event of interest occurs.  Events are defined in the OMX_EVENTTYPE
+        enumeration.  Please see that enumeration for details of what will
+        be returned for each type of event. Callbacks should not return
+        an error to the component, so if an error occurs, the application 
+        shall handle it internally.  This is a blocking call.
+
+        The application should return from this call within 5 msec to avoid
+        blocking the component for an excessively long period of time.
+
+        @param hComponent
+            handle of the component to access.  This is the component
+            handle returned by the call to the GetHandle function.
+        @param pAppData
+            pointer to an application defined value that was provided in the 
+            pAppData parameter to the OMX_GetHandle method for the component.
+            This application defined value is provided so that the application 
+            can have a component specific context when receiving the callback.
+        @param eEvent
+            Event that the component wants to notify the application about.
+        @param nData1
+            nData will be the OMX_ERRORTYPE for an error event and will be 
+            an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event.
+         @param nData2
+            nData2 will hold further information related to the event. Can be OMX_STATETYPE for
+            a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event.
+            Default value is 0 if not used. )
+        @param pEventData
+            Pointer to additional event-specific data (see spec for meaning).
+      */
+
+   OMX_ERRORTYPE (*EventHandler)(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_IN OMX_PTR pAppData,
+        OMX_IN OMX_EVENTTYPE eEvent,
+        OMX_IN OMX_U32 nData1,
+        OMX_IN OMX_U32 nData2,
+        OMX_IN OMX_PTR pEventData);
+
+    /** The EmptyBufferDone method is used to return emptied buffers from an
+        input port back to the application for reuse.  This is a blocking call 
+        so the application should not attempt to refill the buffers during this
+        call, but should queue them and refill them in another thread.  There
+        is no error return, so the application shall handle any errors generated
+        internally.  
+        
+        The application should return from this call within 5 msec.
+        
+        @param hComponent
+            handle of the component to access.  This is the component
+            handle returned by the call to the GetHandle function.
+        @param pAppData
+            pointer to an application defined value that was provided in the 
+            pAppData parameter to the OMX_GetHandle method for the component.
+            This application defined value is provided so that the application 
+            can have a component specific context when receiving the callback.
+        @param pBuffer
+            pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+            or AllocateBuffer indicating the buffer that was emptied.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*EmptyBufferDone)(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_IN OMX_PTR pAppData,
+        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+    /** The FillBufferDone method is used to return filled buffers from an
+        output port back to the application for emptying and then reuse.  
+        This is a blocking call so the application should not attempt to 
+        empty the buffers during this call, but should queue the buffers 
+        and empty them in another thread.  There is no error return, so 
+        the application shall handle any errors generated internally.  The 
+        application shall also update the buffer header to indicate the
+        number of bytes placed into the buffer.  
+
+        The application should return from this call within 5 msec.
+        
+        @param hComponent
+            handle of the component to access.  This is the component
+            handle returned by the call to the GetHandle function.
+        @param pAppData
+            pointer to an application defined value that was provided in the 
+            pAppData parameter to the OMX_GetHandle method for the component.
+            This application defined value is provided so that the application 
+            can have a component specific context when receiving the callback.
+        @param pBuffer
+            pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+            or AllocateBuffer indicating the buffer that was filled.
+        @ingroup buf
+     */
+    OMX_ERRORTYPE (*FillBufferDone)(
+        OMX_OUT OMX_HANDLETYPE hComponent,
+        OMX_OUT OMX_PTR pAppData,
+        OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer);
+
+} OMX_CALLBACKTYPE;
+
+/** The OMX_BUFFERSUPPLIERTYPE enumeration is used to dictate port supplier
+    preference when tunneling between two ports.
+    @ingroup tun buf
+*/
+typedef enum OMX_BUFFERSUPPLIERTYPE
+{
+    OMX_BufferSupplyUnspecified = 0x0, /**< port supplying the buffers is unspecified,
+                                              or don't care */
+    OMX_BufferSupplyInput,             /**< input port supplies the buffers */
+    OMX_BufferSupplyOutput,            /**< output port supplies the buffers */
+    OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_BufferSupplyVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_BufferSupplyMax = 0x7FFFFFFF
+} OMX_BUFFERSUPPLIERTYPE;
+
+
+/** buffer supplier parameter 
+ * @ingroup tun
+ */
+typedef struct OMX_PARAM_BUFFERSUPPLIERTYPE {
+    OMX_U32 nSize; /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex; /**< port that this structure applies to */
+    OMX_BUFFERSUPPLIERTYPE eBufferSupplier; /**< buffer supplier */
+} OMX_PARAM_BUFFERSUPPLIERTYPE;
+
+
+/**< indicates that buffers received by an input port of a tunnel 
+     may not modify the data in the buffers 
+     @ingroup tun
+ */
+#define OMX_PORTTUNNELFLAG_READONLY 0x00000001 
+
+
+/** The OMX_TUNNELSETUPTYPE structure is used to pass data from an output
+    port to an input port as part the two ComponentTunnelRequest calls
+    resulting from a OMX_SetupTunnel call from the IL Client. 
+    @ingroup tun
+ */   
+typedef struct OMX_TUNNELSETUPTYPE
+{
+    OMX_U32 nTunnelFlags;             /**< bit flags for tunneling */
+    OMX_BUFFERSUPPLIERTYPE eSupplier; /**< supplier preference */
+} OMX_TUNNELSETUPTYPE; 
+
+/* OMX Component headers is included to enable the core to use
+   macros for functions into the component for OMX release 1.0.  
+   Developers should not access any structures or data from within
+   the component header directly */
+/* TO BE REMOVED - #include <OMX_Component.h> */
+
+/** GetComponentVersion will return information about the component.  
+    This is a blocking call.  This macro will go directly from the
+    application to the component (via a core macro).  The
+    component will return from this call within 5 msec.
+    @param [in] hComponent
+        handle of component to execute the command
+    @param [out] pComponentName
+        pointer to an empty string of length 128 bytes.  The component 
+        will write its name into this string.  The name will be 
+        terminated by a single zero byte.  The name of a component will 
+        be 127 bytes or less to leave room for the trailing zero byte.  
+        An example of a valid component name is "OMX.ABC.ChannelMixer\0".
+    @param [out] pComponentVersion
+        pointer to an OMX Version structure that the component will fill 
+        in.  The component will fill in a value that indicates the 
+        component version.  NOTE: the component version is NOT the same 
+        as the OMX Specification version (found in all structures).  The 
+        component version is defined by the vendor of the component and 
+        its value is entirely up to the component vendor.
+    @param [out] pSpecVersion
+        pointer to an OMX Version structure that the component will fill 
+        in.  The SpecVersion is the version of the specification that the 
+        component was built against.  Please note that this value may or 
+        may not match the structure's version.  For example, if the 
+        component was built against the 2.0 specification, but the 
+        application (which creates the structure is built against the 
+        1.0 specification the versions would be different.
+    @param [out] pComponentUUID
+        pointer to the UUID of the component which will be filled in by 
+        the component.  The UUID is a unique identifier that is set at 
+        RUN time for the component and is unique to each instantion of 
+        the component.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_GetComponentVersion(                            \
+        hComponent,                                         \
+        pComponentName,                                     \
+        pComponentVersion,                                  \
+        pSpecVersion,                                       \
+        pComponentUUID)                                     \
+    ((OMX_COMPONENTTYPE*)hComponent)->GetComponentVersion(  \
+        hComponent,                                         \
+        pComponentName,                                     \
+        pComponentVersion,                                  \
+        pSpecVersion,                                       \
+        pComponentUUID)                 /* Macro End */
+
+
+/** Send a command to the component.  This call is a non-blocking call.
+    The component should check the parameters and then queue the command
+    to the component thread to be executed.  The component thread shall 
+    send the EventHandler() callback at the conclusion of the command. 
+    This macro will go directly from the application to the component (via
+    a core macro).  The component will return from this call within 5 msec.
+    
+    When the command is "OMX_CommandStateSet" the component will queue a
+    state transition to the new state idenfied in nParam.
+    
+    When the command is "OMX_CommandFlush", to flush a port's buffer queues,
+    the command will force the component to return all buffers NOT CURRENTLY 
+    BEING PROCESSED to the application, in the order in which the buffers 
+    were received.
+    
+    When the command is "OMX_CommandPortDisable" or 
+    "OMX_CommandPortEnable", the component's port (given by the value of
+    nParam) will be stopped or restarted. 
+    
+    When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the
+    pCmdData will point to a OMX_MARKTYPE structure containing the component
+    handle of the component to examine the buffer chain for the mark.  nParam1
+    contains the index of the port on which the buffer mark is applied.
+
+    Specification text for more details. 
+    
+    @param [in] hComponent
+        handle of component to execute the command
+    @param [in] Cmd
+        Command for the component to execute
+    @param [in] nParam
+        Parameter for the command to be executed.  When Cmd has the value 
+        OMX_CommandStateSet, value is a member of OMX_STATETYPE.  When Cmd has 
+        the value OMX_CommandFlush, value of nParam indicates which port(s) 
+        to flush. -1 is used to flush all ports a single port index will 
+        only flush that port.  When Cmd has the value "OMX_CommandPortDisable"
+        or "OMX_CommandPortEnable", the component's port is given by 
+        the value of nParam.  When Cmd has the value "OMX_CommandMarkBuffer"
+        the components pot is given by the value of nParam.
+    @param [in] pCmdData
+        Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value
+        "OMX_CommandMarkBuffer".     
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_SendCommand(                                    \
+         hComponent,                                        \
+         Cmd,                                               \
+         nParam,                                            \
+         pCmdData)                                          \
+     ((OMX_COMPONENTTYPE*)hComponent)->SendCommand(         \
+         hComponent,                                        \
+         Cmd,                                               \
+         nParam,                                            \
+         pCmdData)                          /* Macro End */
+
+
+/** The OMX_GetParameter macro will get one of the current parameter 
+    settings from the component.  This macro cannot only be invoked when 
+    the component is in the OMX_StateInvalid state.  The nParamIndex
+    parameter is used to indicate which structure is being requested from
+    the component.  The application shall allocate the correct structure 
+    and shall fill in the structure size and version information before 
+    invoking this macro.  When the parameter applies to a port, the
+    caller shall fill in the appropriate nPortIndex value indicating the
+    port on which the parameter applies. If the component has not had 
+    any settings changed, then the component should return a set of 
+    valid DEFAULT  parameters for the component.  This is a blocking 
+    call.  
+    
+    The component should return from this call within 20 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] nParamIndex
+        Index of the structure to be filled.  This value is from the
+        OMX_INDEXTYPE enumeration.
+    @param [in,out] pComponentParameterStructure
+        Pointer to application allocated structure to be filled by the 
+        component.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_GetParameter(                                   \
+        hComponent,                                         \
+        nParamIndex,                                        \
+        pComponentParameterStructure)                        \
+    ((OMX_COMPONENTTYPE*)hComponent)->GetParameter(         \
+        hComponent,                                         \
+        nParamIndex,                                        \
+        pComponentParameterStructure)    /* Macro End */
+
+
+/** The OMX_SetParameter macro will send an initialization parameter
+    structure to a component.  Each structure shall be sent one at a time,
+    in a separate invocation of the macro.  This macro can only be
+    invoked when the component is in the OMX_StateLoaded state, or the
+    port is disabled (when the parameter applies to a port). The 
+    nParamIndex parameter is used to indicate which structure is being
+    passed to the component.  The application shall allocate the 
+    correct structure and shall fill in the structure size and version 
+    information (as well as the actual data) before invoking this macro.
+    The application is free to dispose of this structure after the call
+    as the component is required to copy any data it shall retain.  This 
+    is a blocking call.  
+    
+    The component should return from this call within 20 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] nIndex
+        Index of the structure to be sent.  This value is from the
+        OMX_INDEXTYPE enumeration.
+    @param [in] pComponentParameterStructure
+        pointer to application allocated structure to be used for
+        initialization by the component.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_SetParameter(                                   \
+        hComponent,                                         \
+        nParamIndex,                                        \
+        pComponentParameterStructure)                        \
+    ((OMX_COMPONENTTYPE*)hComponent)->SetParameter(         \
+        hComponent,                                         \
+        nParamIndex,                                        \
+        pComponentParameterStructure)    /* Macro End */
+
+
+/** The OMX_GetConfig macro will get one of the configuration structures 
+    from a component.  This macro can be invoked anytime after the 
+    component has been loaded.  The nParamIndex call parameter is used to 
+    indicate which structure is being requested from the component.  The 
+    application shall allocate the correct structure and shall fill in the 
+    structure size and version information before invoking this macro.  
+    If the component has not had this configuration parameter sent before, 
+    then the component should return a set of valid DEFAULT values for the 
+    component.  This is a blocking call.  
+    
+    The component should return from this call within 5 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] nIndex
+        Index of the structure to be filled.  This value is from the
+        OMX_INDEXTYPE enumeration.
+    @param [in,out] pComponentConfigStructure
+        pointer to application allocated structure to be filled by the 
+        component.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+*/        
+#define OMX_GetConfig(                                      \
+        hComponent,                                         \
+        nConfigIndex,                                       \
+        pComponentConfigStructure)                           \
+    ((OMX_COMPONENTTYPE*)hComponent)->GetConfig(            \
+        hComponent,                                         \
+        nConfigIndex,                                       \
+        pComponentConfigStructure)       /* Macro End */
+
+
+/** The OMX_SetConfig macro will send one of the configuration 
+    structures to a component.  Each structure shall be sent one at a time,
+    each in a separate invocation of the macro.  This macro can be invoked 
+    anytime after the component has been loaded.  The application shall 
+    allocate the correct structure and shall fill in the structure size 
+    and version information (as well as the actual data) before invoking 
+    this macro.  The application is free to dispose of this structure after 
+    the call as the component is required to copy any data it shall retain.  
+    This is a blocking call.  
+    
+    The component should return from this call within 5 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] nConfigIndex
+        Index of the structure to be sent.  This value is from the
+        OMX_INDEXTYPE enumeration above.
+    @param [in] pComponentConfigStructure
+        pointer to application allocated structure to be used for
+        initialization by the component.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_SetConfig(                                      \
+        hComponent,                                         \
+        nConfigIndex,                                       \
+        pComponentConfigStructure)                           \
+    ((OMX_COMPONENTTYPE*)hComponent)->SetConfig(            \
+        hComponent,                                         \
+        nConfigIndex,                                       \
+        pComponentConfigStructure)       /* Macro End */
+
+
+/** The OMX_GetExtensionIndex macro will invoke a component to translate 
+    a vendor specific configuration or parameter string into an OMX 
+    structure index.  There is no requirement for the vendor to support 
+    this command for the indexes already found in the OMX_INDEXTYPE 
+    enumeration (this is done to save space in small components).  The 
+    component shall support all vendor supplied extension indexes not found
+    in the master OMX_INDEXTYPE enumeration.  This is a blocking call.  
+    
+    The component should return from this call within 5 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the GetHandle function.
+    @param [in] cParameterName
+        OMX_STRING that shall be less than 128 characters long including
+        the trailing null byte.  This is the string that will get 
+        translated by the component into a configuration index.
+    @param [out] pIndexType
+        a pointer to a OMX_INDEXTYPE to receive the index value.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_GetExtensionIndex(                              \
+        hComponent,                                         \
+        cParameterName,                                     \
+        pIndexType)                                         \
+    ((OMX_COMPONENTTYPE*)hComponent)->GetExtensionIndex(    \
+        hComponent,                                         \
+        cParameterName,                                     \
+        pIndexType)                     /* Macro End */
+
+
+/** The OMX_GetState macro will invoke the component to get the current 
+    state of the component and place the state value into the location
+    pointed to by pState.  
+    
+    The component should return from this call within 5 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [out] pState
+        pointer to the location to receive the state.  The value returned
+        is one of the OMX_STATETYPE members 
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp
+ */
+#define OMX_GetState(                                       \
+        hComponent,                                         \
+        pState)                                             \
+    ((OMX_COMPONENTTYPE*)hComponent)->GetState(             \
+        hComponent,                                         \
+        pState)                         /* Macro End */
+
+
+/** The OMX_UseBuffer macro will request that the component use
+    a buffer (and allocate its own buffer header) already allocated 
+    by another component, or by the IL Client. This is a blocking 
+    call.
+    
+    The component should return from this call within 20 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [out] ppBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure used to receive the 
+        pointer to the buffer header
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */
+
+#define OMX_UseBuffer(                                      \
+           hComponent,                                      \
+           ppBufferHdr,                                     \
+           nPortIndex,                                      \
+           pAppPrivate,                                     \
+           nSizeBytes,                                      \
+           pBuffer)                                         \
+    ((OMX_COMPONENTTYPE*)hComponent)->UseBuffer(            \
+           hComponent,                                      \
+           ppBufferHdr,                                     \
+           nPortIndex,                                      \
+           pAppPrivate,                                     \
+           nSizeBytes,                                      \
+           pBuffer)
+
+
+/** The OMX_AllocateBuffer macro will request that the component allocate 
+    a new buffer and buffer header.  The component will allocate the 
+    buffer and the buffer header and return a pointer to the buffer 
+    header.  This is a blocking call.
+    
+    The component should return from this call within 5 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [out] ppBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure used to receive 
+        the pointer to the buffer header
+    @param [in] nPortIndex
+        nPortIndex is used to select the port on the component the buffer will
+        be used with.  The port can be found by using the nPortIndex
+        value as an index into the Port Definition array of the component.
+    @param [in] pAppPrivate
+        pAppPrivate is used to initialize the pAppPrivate member of the 
+        buffer header structure.
+    @param [in] nSizeBytes
+        size of the buffer to allocate.  Used when bAllocateNew is true.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */    
+#define OMX_AllocateBuffer(                                 \
+        hComponent,                                         \
+        ppBuffer,                                           \
+        nPortIndex,                                         \
+        pAppPrivate,                                        \
+        nSizeBytes)                                         \
+    ((OMX_COMPONENTTYPE*)hComponent)->AllocateBuffer(       \
+        hComponent,                                         \
+        ppBuffer,                                           \
+        nPortIndex,                                         \
+        pAppPrivate,                                        \
+        nSizeBytes)                     /* Macro End */
+
+
+/** The OMX_FreeBuffer macro will release a buffer header from the component
+    which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If  
+    the component allocated the buffer (see the OMX_UseBuffer macro) then 
+    the component shall free the buffer and buffer header. This is a 
+    blocking call. 
+    
+    The component should return from this call within 20 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] nPortIndex
+        nPortIndex is used to select the port on the component the buffer will
+        be used with.
+    @param [in] pBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+        or AllocateBuffer.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */
+#define OMX_FreeBuffer(                                     \
+        hComponent,                                         \
+        nPortIndex,                                         \
+        pBuffer)                                            \
+    ((OMX_COMPONENTTYPE*)hComponent)->FreeBuffer(           \
+        hComponent,                                         \
+        nPortIndex,                                         \
+        pBuffer)                        /* Macro End */
+
+
+/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an 
+    input port of a component.  The buffer will be emptied by the component
+    and returned to the application via the EmptyBufferDone call back.
+    This is a non-blocking call in that the component will record the buffer
+    and return immediately and then empty the buffer, later, at the proper 
+    time.  As expected, this macro may be invoked only while the component 
+    is in the OMX_StateExecuting.  If nPortIndex does not specify an input
+    port, the component shall return an error.  
+    
+    The component should return from this call within 5 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] pBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+        or AllocateBuffer.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */
+#define OMX_EmptyThisBuffer(                                \
+        hComponent,                                         \
+        pBuffer)                                            \
+    ((OMX_COMPONENTTYPE*)hComponent)->EmptyThisBuffer(      \
+        hComponent,                                         \
+        pBuffer)                        /* Macro End */
+
+
+/** The OMX_FillThisBuffer macro will send an empty buffer to an 
+    output port of a component.  The buffer will be filled by the component
+    and returned to the application via the FillBufferDone call back.
+    This is a non-blocking call in that the component will record the buffer
+    and return immediately and then fill the buffer, later, at the proper 
+    time.  As expected, this macro may be invoked only while the component 
+    is in the OMX_ExecutingState.  If nPortIndex does not specify an output
+    port, the component shall return an error.  
+    
+    The component should return from this call within 5 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [in] pBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+        or AllocateBuffer.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */
+#define OMX_FillThisBuffer(                                 \
+        hComponent,                                         \
+        pBuffer)                                            \
+    ((OMX_COMPONENTTYPE*)hComponent)->FillThisBuffer(       \
+        hComponent,                                         \
+        pBuffer)                        /* Macro End */
+
+
+
+/** The OMX_UseEGLImage macro will request that the component use
+    a EGLImage provided by EGL (and allocate its own buffer header)
+    This is a blocking call.
+    
+    The component should return from this call within 20 msec.
+    
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the OMX_GetHandle function.
+    @param [out] ppBuffer
+        pointer to an OMX_BUFFERHEADERTYPE structure used to receive the 
+        pointer to the buffer header.  Note that the memory location used
+        for this buffer is NOT visible to the IL Client.
+    @param [in] nPortIndex
+        nPortIndex is used to select the port on the component the buffer will
+        be used with.  The port can be found by using the nPortIndex
+        value as an index into the Port Definition array of the component.
+    @param [in] pAppPrivate
+        pAppPrivate is used to initialize the pAppPrivate member of the 
+        buffer header structure.
+    @param [in] eglImage
+        eglImage contains the handle of the EGLImage to use as a buffer on the
+        specified port.  The component is expected to validate properties of 
+        the EGLImage against the configuration of the port to ensure the component
+        can use the EGLImage as a buffer.          
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup comp buf
+ */
+#define OMX_UseEGLImage(                                    \
+           hComponent,                                      \
+           ppBufferHdr,                                     \
+           nPortIndex,                                      \
+           pAppPrivate,                                     \
+           eglImage)                                        \
+    ((OMX_COMPONENTTYPE*)hComponent)->UseEGLImage(          \
+           hComponent,                                      \
+           ppBufferHdr,                                     \
+           nPortIndex,                                      \
+           pAppPrivate,                                     \
+           eglImage)
+
+/** The OMX_Init method is used to initialize the OMX core.  It shall be the
+    first call made into OMX and it should only be executed one time without
+    an interviening OMX_Deinit call.  
+    
+    The core should return from this call within 20 msec.
+
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void);
+
+
+/** The OMX_Deinit method is used to deinitialize the OMX core.  It shall be 
+    the last call made into OMX. In the event that the core determines that 
+    thare are components loaded when this call is made, the core may return 
+    with an error rather than try to unload the components.
+        
+    The core should return from this call within 20 msec.
+    
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void);
+
+
+/** The OMX_ComponentNameEnum method will enumerate through all the names of
+    recognised valid components in the system. This function is provided
+    as a means to detect all the components in the system run-time. There is
+    no strict ordering to the enumeration order of component names, although
+    each name will only be enumerated once.  If the OMX core supports run-time
+    installation of new components, it is only requried to detect newly
+    installed components when the first call to enumerate component names
+    is made (i.e. when nIndex is 0x0).
+    
+    The core should return from this call in 20 msec.
+    
+    @param [out] cComponentName
+        pointer to a null terminated string with the component name.  The
+        names of the components are strings less than 127 bytes in length
+        plus the trailing null for a maximum size of 128 bytes.  An example 
+        of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0".  Names are 
+        assigned by the vendor, but shall start with "OMX." and then have 
+        the Vendor designation next.
+    @param [in] nNameLength
+        number of characters in the cComponentName string.  With all 
+        component name strings restricted to less than 128 characters 
+        (including the trailing null) it is recomended that the caller
+        provide a input string for the cComponentName of 128 characters.
+    @param [in] nIndex
+        number containing the enumeration index for the component. 
+        Multiple calls to OMX_ComponentNameEnum with increasing values
+        of nIndex will enumerate through the component names in the
+        system until OMX_ErrorNoMore is returned.  The value of nIndex
+        is 0 to (N-1), where N is the number of valid installed components
+        in the system.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  When the value of nIndex exceeds the number of 
+        components in the system minus 1, OMX_ErrorNoMore will be
+        returned. Otherwise the appropriate OMX error will be returned.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(
+    OMX_OUT OMX_STRING cComponentName,
+    OMX_IN  OMX_U32 nNameLength,
+    OMX_IN  OMX_U32 nIndex);
+
+
+/** The OMX_GetHandle method will locate the component specified by the
+    component name given, load that component into memory and then invoke
+    the component's methods to create an instance of the component.  
+    
+    The core should return from this call within 20 msec.
+    
+    @param [out] pHandle
+        pointer to an OMX_HANDLETYPE pointer to be filled in by this method.
+    @param [in] cComponentName
+        pointer to a null terminated string with the component name.  The
+        names of the components are strings less than 127 bytes in length
+        plus the trailing null for a maximum size of 128 bytes.  An example 
+        of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0".  Names are 
+        assigned by the vendor, but shall start with "OMX." and then have 
+        the Vendor designation next.
+    @param [in] pAppData
+        pointer to an application defined value that will be returned
+        during callbacks so that the application can identify the source
+        of the callback.
+    @param [in] pCallBacks
+        pointer to a OMX_CALLBACKTYPE structure that will be passed to the
+        component to initialize it with.  
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
+    OMX_OUT OMX_HANDLETYPE* pHandle, 
+    OMX_IN  OMX_STRING cComponentName,
+    OMX_IN  OMX_PTR pAppData,
+    OMX_IN  OMX_CALLBACKTYPE* pCallBacks);
+
+
+/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle 
+    method.  If the component reference count goes to zero, the component will
+    be unloaded from memory.  
+    
+    The core should return from this call within 20 msec when the component is 
+    in the OMX_StateLoaded state.
+
+    @param [in] hComponent
+        Handle of the component to be accessed.  This is the component
+        handle returned by the call to the GetHandle function.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
+    OMX_IN  OMX_HANDLETYPE hComponent);
+
+
+
+/** The OMX_SetupTunnel method will handle the necessary calls to the components
+    to setup the specified tunnel the two components.  NOTE: This is
+    an actual method (not a #define macro).  This method will make calls into
+    the component ComponentTunnelRequest method to do the actual tunnel 
+    connection.  
+
+    The ComponentTunnelRequest method on both components will be called. 
+    This method shall not be called unless the component is in the 
+    OMX_StateLoaded state except when the ports used for the tunnel are
+    disabled. In this case, the component may be in the OMX_StateExecuting,
+    OMX_StatePause, or OMX_StateIdle states. 
+
+    The core should return from this call within 20 msec.
+    
+    @param [in] hOutput
+        Handle of the component to be accessed.  Also this is the handle
+        of the component whose port, specified in the nPortOutput parameter
+        will be used the source for the tunnel. This is the component handle
+        returned by the call to the OMX_GetHandle function.  There is a 
+        requirement that hOutput be the source for the data when
+        tunelling (i.e. nPortOutput is an output port).  If 0x0, the component
+        specified in hInput will have it's port specified in nPortInput
+        setup for communication with the application / IL client.
+    @param [in] nPortOutput
+        nPortOutput is used to select the source port on component to be
+        used in the tunnel. 
+    @param [in] hInput
+        This is the component to setup the tunnel with. This is the handle
+        of the component whose port, specified in the nPortInput parameter
+        will be used the destination for the tunnel. This is the component handle
+        returned by the call to the OMX_GetHandle function.  There is a 
+        requirement that hInput be the destination for the data when
+        tunelling (i.e. nPortInut is an input port).   If 0x0, the component
+        specified in hOutput will have it's port specified in nPortPOutput
+        setup for communication with the application / IL client.
+    @param [in] nPortInput
+        nPortInput is used to select the destination port on component to be
+        used in the tunnel.
+    @return OMX_ERRORTYPE
+        If the command successfully executes, the return code will be
+        OMX_ErrorNone.  Otherwise the appropriate OMX error will be returned.
+        When OMX_ErrorNotImplemented is returned, one or both components is 
+        a non-interop component and does not support tunneling.
+        
+        On failure, the ports of both components are setup for communication
+        with the application / IL Client.
+    @ingroup core tun
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(
+    OMX_IN  OMX_HANDLETYPE hOutput,
+    OMX_IN  OMX_U32 nPortOutput,
+    OMX_IN  OMX_HANDLETYPE hInput,
+    OMX_IN  OMX_U32 nPortInput);
+    
+/** @ingroup cp */
+OMX_API OMX_ERRORTYPE   OMX_GetContentPipe(
+    OMX_OUT OMX_HANDLETYPE *hPipe,
+    OMX_IN OMX_STRING szURI);
+
+/** The OMX_GetComponentsOfRole method will return the number of components that support the given
+    role and (if the compNames field is non-NULL) the names of those components. The call will fail if 
+    an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the
+    client should:
+        * first call this function with the compNames field NULL to determine the number of component names
+        * second call this function with the compNames field pointing to an array of names allocated 
+          according to the number returned by the first call.
+
+    The core should return from this call within 5 msec.
+    
+    @param [in] role
+        This is generic standard component name consisting only of component class 
+        name and the type within that class (e.g. 'audio_decoder.aac').
+    @param [inout] pNumComps
+        This is used both as input and output. 
+        If compNames is NULL, the input is ignored and the output specifies how many components support
+        the given role.
+     
+        If compNames is not NULL, on input it bounds the size of the input structure and 
+        on output, it specifies the number of components string names listed within the compNames parameter.
+    @param [inout] compNames
+        If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts 
+        a list of the names of all physical components that implement the specified standard component name. 
+        Each name is NULL terminated. numComps indicates the number of names.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole ( 
+       OMX_IN      OMX_STRING role,
+    OMX_INOUT   OMX_U32 *pNumComps,
+    OMX_INOUT   OMX_U8  **compNames);
+
+/** The OMX_GetRolesOfComponent method will return the number of roles supported by the given
+    component and (if the roles field is non-NULL) the names of those roles. The call will fail if 
+    an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the
+    client should:
+        * first call this function with the roles field NULL to determine the number of role names
+        * second call this function with the roles field pointing to an array of names allocated 
+          according to the number returned by the first call.
+
+    The core should return from this call within 5 msec.
+
+    @param [in] compName
+        This is the name of the component being queried about.
+    @param [inout] pNumRoles
+        This is used both as input and output. 
+        If roles is NULL, the input is ignored and the output specifies how many roles the component supports.
+     
+        If compNames is not NULL, on input it bounds the size of the input structure and 
+        on output, it specifies the number of roles string names listed within the roles parameter.
+    @param [out] roles
+        If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings 
+        which accepts a list of the names of all standard components roles implemented on the 
+        specified component name. numComps indicates the number of names.
+    @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent ( 
+       OMX_IN      OMX_STRING compName, 
+    OMX_INOUT   OMX_U32 *pNumRoles,
+    OMX_OUT     OMX_U8 **roles);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
+
diff --git a/openmax/include/khronos/OMX_CoreExt.h b/openmax/include/khronos/OMX_CoreExt.h
new file mode 100755 (executable)
index 0000000..1241168
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2010 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_CoreExt.h - OpenMax IL version 1.1.2
+ * The OMX_CoreExt header file contains extensions to the definitions used
+ * by both the application and the component to access common items.
+ */
+
+#ifndef OMX_CoreExt_h
+#define OMX_CoreExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Core.h>
+
+/** Extensions to the standard IL errors. */ 
+typedef enum OMX_ERROREXTTYPE 
+{
+    OMX_ErrorInvalidMode = (OMX_S32) (OMX_ErrorKhronosExtensions + 0x00000001),
+    OMX_ErrorExtMax = 0x7FFFFFFF
+} OMX_ERROREXTTYPE;
+
+
+/** Event type extensions. */
+typedef enum OMX_EVENTEXTTYPE
+{
+    OMX_EventIndexSettingChanged = OMX_EventKhronosExtensions, /**< component signals the IL client of a change
+                                                                    in a param, config, or extension */
+    OMX_EventExtMax = 0x7FFFFFFF
+} OMX_EVENTEXTTYPE;
+
+
+/** Enable or disable a callback event. */
+typedef struct OMX_CONFIG_CALLBACKREQUESTTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_INDEXTYPE nIndex;       /**< the index the callback is requested for */
+    OMX_BOOL bEnable;           /**< enable (OMX_TRUE) or disable (OMX_FALSE) the callback */
+} OMX_CONFIG_CALLBACKREQUESTTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_CoreExt_h */
+/* File EOF */
diff --git a/openmax/include/khronos/OMX_IVCommon.h b/openmax/include/khronos/OMX_IVCommon.h
new file mode 100755 (executable)
index 0000000..4c4995c
--- /dev/null
@@ -0,0 +1,920 @@
+/**
+ * Copyright (c) 2008 The Khronos Group Inc. 
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions: 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software. 
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ *
+ */
+
+/** 
+ * @file OMX_IVCommon.h - OpenMax IL version 1.1.2
+ *  The structures needed by Video and Image components to exchange
+ *  parameters and configuration data with the components.
+ */
+#ifndef OMX_IVCommon_h
+#define OMX_IVCommon_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Each OMX header must include all required header files to allow the header
+ * to compile without errors.  The includes below are required for this header
+ * file to compile successfully 
+ */
+
+#include <OMX_Core.h>
+
+/** @defgroup iv OpenMAX IL Imaging and Video Domain
+ * Common structures for OpenMAX IL Imaging and Video domains
+ * @{
+ */
+
+
+/** 
+ * Enumeration defining possible uncompressed image/video formats. 
+ *
+ * ENUMS:
+ *  Unused                 : Placeholder value when format is N/A
+ *  Monochrome             : black and white
+ *  8bitRGB332             : Red 7:5, Green 4:2, Blue 1:0
+ *  12bitRGB444            : Red 11:8, Green 7:4, Blue 3:0
+ *  16bitARGB4444          : Alpha 15:12, Red 11:8, Green 7:4, Blue 3:0
+ *  16bitARGB1555          : Alpha 15, Red 14:10, Green 9:5, Blue 4:0
+ *  16bitRGB565            : Red 15:11, Green 10:5, Blue 4:0
+ *  16bitBGR565            : Blue 15:11, Green 10:5, Red 4:0
+ *  18bitRGB666            : Red 17:12, Green 11:6, Blue 5:0
+ *  18bitARGB1665          : Alpha 17, Red 16:11, Green 10:5, Blue 4:0
+ *  19bitARGB1666          : Alpha 18, Red 17:12, Green 11:6, Blue 5:0
+ *  24bitRGB888            : Red 24:16, Green 15:8, Blue 7:0
+ *  24bitBGR888            : Blue 24:16, Green 15:8, Red 7:0
+ *  24bitARGB1887          : Alpha 23, Red 22:15, Green 14:7, Blue 6:0
+ *  25bitARGB1888          : Alpha 24, Red 23:16, Green 15:8, Blue 7:0
+ *  32bitBGRA8888          : Blue 31:24, Green 23:16, Red 15:8, Alpha 7:0
+ *  32bitARGB8888          : Alpha 31:24, Red 23:16, Green 15:8, Blue 7:0
+ *  YUV411Planar           : U,Y are subsampled by a factor of 4 horizontally
+ *  YUV411PackedPlanar     : packed per payload in planar slices
+ *  YUV420Planar           : Three arrays Y,U,V.
+ *  YUV420PackedPlanar     : packed per payload in planar slices
+ *  YUV420SemiPlanar       : Two arrays, one is all Y, the other is U and V
+ *  YUV422Planar           : Three arrays Y,U,V.
+ *  YUV422PackedPlanar     : packed per payload in planar slices
+ *  YUV422SemiPlanar       : Two arrays, one is all Y, the other is U and V
+ *  YCbYCr                 : Organized as 16bit YUYV (i.e. YCbYCr)
+ *  YCrYCb                 : Organized as 16bit YVYU (i.e. YCrYCb)
+ *  CbYCrY                 : Organized as 16bit UYVY (i.e. CbYCrY)
+ *  CrYCbY                 : Organized as 16bit VYUY (i.e. CrYCbY)
+ *  YUV444Interleaved      : Each pixel contains equal parts YUV
+ *  RawBayer8bit           : SMIA camera output format
+ *  RawBayer10bit          : SMIA camera output format
+ *  RawBayer8bitcompressed : SMIA camera output format
+ */
+typedef enum OMX_COLOR_FORMATTYPE {
+    OMX_COLOR_FormatUnused,
+    OMX_COLOR_FormatMonochrome,
+    OMX_COLOR_Format8bitRGB332,
+    OMX_COLOR_Format12bitRGB444,
+    OMX_COLOR_Format16bitARGB4444,
+    OMX_COLOR_Format16bitARGB1555,
+    OMX_COLOR_Format16bitRGB565,
+    OMX_COLOR_Format16bitBGR565,
+    OMX_COLOR_Format18bitRGB666,
+    OMX_COLOR_Format18bitARGB1665,
+    OMX_COLOR_Format19bitARGB1666, 
+    OMX_COLOR_Format24bitRGB888,
+    OMX_COLOR_Format24bitBGR888,
+    OMX_COLOR_Format24bitARGB1887,
+    OMX_COLOR_Format25bitARGB1888,
+    OMX_COLOR_Format32bitBGRA8888,
+    OMX_COLOR_Format32bitARGB8888,
+    OMX_COLOR_FormatYUV411Planar,
+    OMX_COLOR_FormatYUV411PackedPlanar,
+    OMX_COLOR_FormatYUV420Planar,
+    OMX_COLOR_FormatYUV420PackedPlanar,
+    OMX_COLOR_FormatYUV420SemiPlanar,
+    OMX_COLOR_FormatYUV422Planar,
+    OMX_COLOR_FormatYUV422PackedPlanar,
+    OMX_COLOR_FormatYUV422SemiPlanar,
+    OMX_COLOR_FormatYCbYCr,
+    OMX_COLOR_FormatYCrYCb,
+    OMX_COLOR_FormatCbYCrY,
+    OMX_COLOR_FormatCrYCbY,
+    OMX_COLOR_FormatYUV444Interleaved,
+    OMX_COLOR_FormatRawBayer8bit,
+    OMX_COLOR_FormatRawBayer10bit,
+    OMX_COLOR_FormatRawBayer8bitcompressed,
+    OMX_COLOR_FormatL2, 
+    OMX_COLOR_FormatL4, 
+    OMX_COLOR_FormatL8, 
+    OMX_COLOR_FormatL16, 
+    OMX_COLOR_FormatL24, 
+    OMX_COLOR_FormatL32,
+    OMX_COLOR_FormatYUV420PackedSemiPlanar,
+    OMX_COLOR_FormatYUV422PackedSemiPlanar,
+    OMX_COLOR_Format18BitBGR666,
+    OMX_COLOR_Format24BitARGB6666,
+    OMX_COLOR_Format24BitABGR6666,
+    OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_COLOR_FormatMax = 0x7FFFFFFF
+} OMX_COLOR_FORMATTYPE;
+
+
+/** 
+ * Defines the matrix for conversion from RGB to YUV or vice versa.
+ * iColorMatrix should be initialized with the fixed point values 
+ * used in converting between formats.
+ */
+typedef struct OMX_CONFIG_COLORCONVERSIONTYPE {
+    OMX_U32 nSize;              /**< Size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version info */ 
+    OMX_U32 nPortIndex;         /**< Port that this struct applies to */
+    OMX_S32 xColorMatrix[3][3]; /**< Stored in signed Q16 format */
+    OMX_S32 xColorOffset[4];    /**< Stored in signed Q16 format */
+}OMX_CONFIG_COLORCONVERSIONTYPE;
+
+
+/** 
+ * Structure defining percent to scale each frame dimension.  For example:  
+ * To make the width 50% larger, use fWidth = 1.5 and to make the width
+ * 1/2 the original size, use fWidth = 0.5
+ */
+typedef struct OMX_CONFIG_SCALEFACTORTYPE {
+    OMX_U32 nSize;            /**< Size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ 
+    OMX_U32 nPortIndex;       /**< Port that this struct applies to */
+    OMX_S32 xWidth;           /**< Fixed point value stored as Q16 */
+    OMX_S32 xHeight;          /**< Fixed point value stored as Q16 */
+}OMX_CONFIG_SCALEFACTORTYPE;
+
+
+/** 
+ * Enumeration of possible image filter types 
+ */
+typedef enum OMX_IMAGEFILTERTYPE {
+    OMX_ImageFilterNone,
+    OMX_ImageFilterNoise,
+    OMX_ImageFilterEmboss,
+    OMX_ImageFilterNegative,
+    OMX_ImageFilterSketch,
+    OMX_ImageFilterOilPaint,
+    OMX_ImageFilterHatch,
+    OMX_ImageFilterGpen,
+    OMX_ImageFilterAntialias, 
+    OMX_ImageFilterDeRing,       
+    OMX_ImageFilterSolarize,
+    OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_ImageFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_ImageFilterMax = 0x7FFFFFFF
+} OMX_IMAGEFILTERTYPE;
+
+
+/** 
+ * Image filter configuration 
+ *
+ * STRUCT MEMBERS:
+ *  nSize        : Size of the structure in bytes       
+ *  nVersion     : OMX specification version information
+ *  nPortIndex   : Port that this structure applies to 
+ *  eImageFilter : Image filter type enumeration      
+ */
+typedef struct OMX_CONFIG_IMAGEFILTERTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_IMAGEFILTERTYPE eImageFilter;
+} OMX_CONFIG_IMAGEFILTERTYPE;
+
+
+/** 
+ * Customized U and V for color enhancement 
+ *
+ * STRUCT MEMBERS:
+ *  nSize             : Size of the structure in bytes
+ *  nVersion          : OMX specification version information 
+ *  nPortIndex        : Port that this structure applies to
+ *  bColorEnhancement : Enable/disable color enhancement
+ *  nCustomizedU      : Practical values: 16-240, range: 0-255, value set for 
+ *                      U component
+ *  nCustomizedV      : Practical values: 16-240, range: 0-255, value set for 
+ *                      V component
+ */
+typedef struct OMX_CONFIG_COLORENHANCEMENTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion; 
+    OMX_U32 nPortIndex;
+    OMX_BOOL bColorEnhancement;
+    OMX_U8 nCustomizedU;
+    OMX_U8 nCustomizedV;
+} OMX_CONFIG_COLORENHANCEMENTTYPE;
+
+
+/** 
+ * Define color key and color key mask 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information 
+ *  nPortIndex : Port that this structure applies to
+ *  nARGBColor : 32bit Alpha, Red, Green, Blue Color
+ *  nARGBMask  : 32bit Mask for Alpha, Red, Green, Blue channels
+ */
+typedef struct OMX_CONFIG_COLORKEYTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nARGBColor;
+    OMX_U32 nARGBMask;
+} OMX_CONFIG_COLORKEYTYPE;
+
+
+/** 
+ * List of color blend types for pre/post processing 
+ *
+ * ENUMS:
+ *  None          : No color blending present
+ *  AlphaConstant : Function is (alpha_constant * src) + 
+ *                  (1 - alpha_constant) * dst)
+ *  AlphaPerPixel : Function is (alpha * src) + (1 - alpha) * dst)
+ *  Alternate     : Function is alternating pixels from src and dst
+ *  And           : Function is (src & dst)
+ *  Or            : Function is (src | dst)
+ *  Invert        : Function is ~src
+ */
+typedef enum OMX_COLORBLENDTYPE {
+    OMX_ColorBlendNone,
+    OMX_ColorBlendAlphaConstant,
+    OMX_ColorBlendAlphaPerPixel,
+    OMX_ColorBlendAlternate,
+    OMX_ColorBlendAnd,
+    OMX_ColorBlendOr,
+    OMX_ColorBlendInvert,
+    OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_ColorBlendVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_ColorBlendMax = 0x7FFFFFFF
+} OMX_COLORBLENDTYPE;
+
+
+/** 
+ * Color blend configuration 
+ *
+ * STRUCT MEMBERS:
+ *  nSize             : Size of the structure in bytes                        
+ *  nVersion          : OMX specification version information                
+ *  nPortIndex        : Port that this structure applies to                   
+ *  nRGBAlphaConstant : Constant global alpha values when global alpha is used
+ *  eColorBlend       : Color blend type enumeration                         
+ */
+typedef struct OMX_CONFIG_COLORBLENDTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nRGBAlphaConstant;
+    OMX_COLORBLENDTYPE  eColorBlend;
+} OMX_CONFIG_COLORBLENDTYPE;
+
+
+/** 
+ * Hold frame dimension
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes      
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to     
+ *  nWidth     : Frame width in pixels                 
+ *  nHeight    : Frame height in pixels                
+ */
+typedef struct OMX_FRAMESIZETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nWidth;
+    OMX_U32 nHeight;
+} OMX_FRAMESIZETYPE;
+
+
+/**
+ * Rotation configuration 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes             
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nRotation  : +/- integer rotation value               
+ */
+typedef struct OMX_CONFIG_ROTATIONTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nRotation; 
+} OMX_CONFIG_ROTATIONTYPE;
+
+
+/** 
+ * Possible mirroring directions for pre/post processing 
+ *
+ * ENUMS:
+ *  None       : No mirroring                         
+ *  Vertical   : Vertical mirroring, flip on X axis   
+ *  Horizontal : Horizontal mirroring, flip on Y axis  
+ *  Both       : Both vertical and horizontal mirroring
+ */
+typedef enum OMX_MIRRORTYPE {
+    OMX_MirrorNone = 0,
+    OMX_MirrorVertical,
+    OMX_MirrorHorizontal,
+    OMX_MirrorBoth, 
+    OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_MirrorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_MirrorMax = 0x7FFFFFFF   
+} OMX_MIRRORTYPE;
+
+
+/** 
+ * Mirroring configuration 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes      
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to  
+ *  eMirror    : Mirror type enumeration              
+ */
+typedef struct OMX_CONFIG_MIRRORTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion; 
+    OMX_U32 nPortIndex;
+    OMX_MIRRORTYPE  eMirror;
+} OMX_CONFIG_MIRRORTYPE;
+
+
+/** 
+ * Position information only 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes               
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nX         : X coordinate for the point                     
+ *  nY         : Y coordinate for the point 
+ */                      
+typedef struct OMX_CONFIG_POINTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nX;
+    OMX_S32 nY;
+} OMX_CONFIG_POINTTYPE;
+
+
+/** 
+ * Frame size plus position 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes                    
+ *  nVersion   : OMX specification version information      
+ *  nPortIndex : Port that this structure applies to    
+ *  nLeft      : X Coordinate of the top left corner of the rectangle
+ *  nTop       : Y Coordinate of the top left corner of the rectangle
+ *  nWidth     : Width of the rectangle                              
+ *  nHeight    : Height of the rectangle                             
+ */
+typedef struct OMX_CONFIG_RECTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;  
+    OMX_U32 nPortIndex; 
+    OMX_S32 nLeft; 
+    OMX_S32 nTop;
+    OMX_U32 nWidth;
+    OMX_U32 nHeight;
+} OMX_CONFIG_RECTTYPE;
+
+
+/** 
+ * Deblocking state; it is required to be set up before starting the codec 
+ *
+ * STRUCT MEMBERS:
+ *  nSize       : Size of the structure in bytes      
+ *  nVersion    : OMX specification version information 
+ *  nPortIndex  : Port that this structure applies to
+ *  bDeblocking : Enable/disable deblocking mode    
+ */
+typedef struct OMX_PARAM_DEBLOCKINGTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bDeblocking;
+} OMX_PARAM_DEBLOCKINGTYPE;
+
+
+/** 
+ * Stabilization state 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes          
+ *  nVersion   : OMX specification version information    
+ *  nPortIndex : Port that this structure applies to   
+ *  bStab      : Enable/disable frame stabilization state
+ */
+typedef struct OMX_CONFIG_FRAMESTABTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bStab;
+} OMX_CONFIG_FRAMESTABTYPE;
+
+
+/** 
+ * White Balance control type 
+ *
+ * STRUCT MEMBERS:
+ *  SunLight : Referenced in JSR-234
+ *  Flash    : Optimal for device's integrated flash
+ */
+typedef enum OMX_WHITEBALCONTROLTYPE {
+    OMX_WhiteBalControlOff = 0,
+    OMX_WhiteBalControlAuto,
+    OMX_WhiteBalControlSunLight,
+    OMX_WhiteBalControlCloudy,
+    OMX_WhiteBalControlShade,
+    OMX_WhiteBalControlTungsten,
+    OMX_WhiteBalControlFluorescent,
+    OMX_WhiteBalControlIncandescent,
+    OMX_WhiteBalControlFlash,
+    OMX_WhiteBalControlHorizon,
+    OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_WhiteBalControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_WhiteBalControlMax = 0x7FFFFFFF
+} OMX_WHITEBALCONTROLTYPE;
+
+
+/** 
+ * White Balance control configuration 
+ *
+ * STRUCT MEMBERS:
+ *  nSize            : Size of the structure in bytes       
+ *  nVersion         : OMX specification version information
+ *  nPortIndex       : Port that this structure applies to                 
+ *  eWhiteBalControl : White balance enumeration            
+ */
+typedef struct OMX_CONFIG_WHITEBALCONTROLTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_WHITEBALCONTROLTYPE eWhiteBalControl;
+} OMX_CONFIG_WHITEBALCONTROLTYPE;
+
+
+/** 
+ * Exposure control type 
+ */
+typedef enum OMX_EXPOSURECONTROLTYPE {
+    OMX_ExposureControlOff = 0,
+    OMX_ExposureControlAuto,
+    OMX_ExposureControlNight,
+    OMX_ExposureControlBackLight,
+    OMX_ExposureControlSpotLight,
+    OMX_ExposureControlSports,
+    OMX_ExposureControlSnow,
+    OMX_ExposureControlBeach,
+    OMX_ExposureControlLargeAperture,
+    OMX_ExposureControlSmallApperture,
+    OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_ExposureControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_ExposureControlMax = 0x7FFFFFFF
+} OMX_EXPOSURECONTROLTYPE;
+
+
+/** 
+ * White Balance control configuration 
+ *
+ * STRUCT MEMBERS:
+ *  nSize            : Size of the structure in bytes      
+ *  nVersion         : OMX specification version information
+ *  nPortIndex       : Port that this structure applies to                
+ *  eExposureControl : Exposure control enumeration         
+ */
+typedef struct OMX_CONFIG_EXPOSURECONTROLTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_EXPOSURECONTROLTYPE eExposureControl;
+} OMX_CONFIG_EXPOSURECONTROLTYPE;
+
+
+/** 
+ * Defines sensor supported mode. 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes           
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to 
+ *  nFrameRate : Single shot mode is indicated by a 0     
+ *  bOneShot   : Enable for single shot, disable for streaming
+ *  sFrameSize : Framesize                                          
+ */
+typedef struct OMX_PARAM_SENSORMODETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nFrameRate;
+    OMX_BOOL bOneShot;
+    OMX_FRAMESIZETYPE sFrameSize;
+} OMX_PARAM_SENSORMODETYPE;
+
+
+/** 
+ * Defines contrast level 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes                              
+ *  nVersion   : OMX specification version information                
+ *  nPortIndex : Port that this structure applies to                 
+ *  nContrast  : Values allowed for contrast -100 to 100, zero means no change
+ */
+typedef struct OMX_CONFIG_CONTRASTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nContrast;
+} OMX_CONFIG_CONTRASTTYPE;
+
+
+/** 
+ * Defines brightness level 
+ *
+ * STRUCT MEMBERS:
+ *  nSize       : Size of the structure in bytes          
+ *  nVersion    : OMX specification version information 
+ *  nPortIndex  : Port that this structure applies to 
+ *  nBrightness : 0-100%        
+ */
+typedef struct OMX_CONFIG_BRIGHTNESSTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nBrightness;
+} OMX_CONFIG_BRIGHTNESSTYPE;
+
+
+/** 
+ * Defines backlight level configuration for a video sink, e.g. LCD panel 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information 
+ *  nPortIndex : Port that this structure applies to
+ *  nBacklight : Values allowed for backlight 0-100%
+ *  nTimeout   : Number of milliseconds before backlight automatically turns 
+ *               off.  A value of 0x0 disables backight timeout 
+ */
+typedef struct OMX_CONFIG_BACKLIGHTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nBacklight;
+    OMX_U32 nTimeout;
+} OMX_CONFIG_BACKLIGHTTYPE;
+
+
+/** 
+ * Defines setting for Gamma 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information 
+ *  nPortIndex : Port that this structure applies to
+ *  nGamma     : Values allowed for gamma -100 to 100, zero means no change
+ */
+typedef struct OMX_CONFIG_GAMMATYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nGamma;
+} OMX_CONFIG_GAMMATYPE;
+
+
+/** 
+ * Define for setting saturation 
+ * 
+ * STRUCT MEMBERS:
+ *  nSize       : Size of the structure in bytes
+ *  nVersion    : OMX specification version information
+ *  nPortIndex  : Port that this structure applies to
+ *  nSaturation : Values allowed for saturation -100 to 100, zero means 
+ *                no change
+ */
+typedef struct OMX_CONFIG_SATURATIONTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nSaturation;
+} OMX_CONFIG_SATURATIONTYPE;
+
+
+/** 
+ * Define for setting Lightness 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nLightness : Values allowed for lightness -100 to 100, zero means no 
+ *               change
+ */
+typedef struct OMX_CONFIG_LIGHTNESSTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_S32 nLightness;
+} OMX_CONFIG_LIGHTNESSTYPE;
+
+
+/** 
+ * Plane blend configuration 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes 
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Index of input port associated with the plane.
+ *  nDepth     : Depth of the plane in relation to the screen. Higher 
+ *               numbered depths are "behind" lower number depths.  
+ *               This number defaults to the Port Index number.
+ *  nAlpha     : Transparency blending component for the entire plane.  
+ *               See blending modes for more detail.
+ */
+typedef struct OMX_CONFIG_PLANEBLENDTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nDepth;
+    OMX_U32 nAlpha;
+} OMX_CONFIG_PLANEBLENDTYPE;
+
+
+/** 
+ * Define interlace type
+ *
+ * STRUCT MEMBERS:
+ *  nSize                 : Size of the structure in bytes 
+ *  nVersion              : OMX specification version information 
+ *  nPortIndex            : Port that this structure applies to
+ *  bEnable               : Enable control variable for this functionality 
+ *                          (see below)
+ *  nInterleavePortIndex  : Index of input or output port associated with  
+ *                          the interleaved plane. 
+ *  pPlanarPortIndexes[4] : Index of input or output planar ports.
+ */
+typedef struct OMX_PARAM_INTERLEAVETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bEnable;
+    OMX_U32 nInterleavePortIndex;
+} OMX_PARAM_INTERLEAVETYPE;
+
+
+/** 
+ * Defines the picture effect used for an input picture 
+ */
+typedef enum OMX_TRANSITIONEFFECTTYPE {
+    OMX_EffectNone,
+    OMX_EffectFadeFromBlack,
+    OMX_EffectFadeToBlack,
+    OMX_EffectUnspecifiedThroughConstantColor,
+    OMX_EffectDissolve,
+    OMX_EffectWipe,
+    OMX_EffectUnspecifiedMixOfTwoScenes,
+    OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_EffectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_EffectMax = 0x7FFFFFFF
+} OMX_TRANSITIONEFFECTTYPE;
+
+
+/** 
+ * Structure used to configure current transition effect 
+ *
+ * STRUCT MEMBERS:
+ * nSize      : Size of the structure in bytes
+ * nVersion   : OMX specification version information 
+ * nPortIndex : Port that this structure applies to
+ * eEffect    : Effect to enable
+ */
+typedef struct OMX_CONFIG_TRANSITIONEFFECTTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_TRANSITIONEFFECTTYPE eEffect;
+} OMX_CONFIG_TRANSITIONEFFECTTYPE;
+
+
+/** 
+ * Defines possible data unit types for encoded video data. The data unit 
+ * types are used both for encoded video input for playback as well as
+ * encoded video output from recording. 
+ */
+typedef enum OMX_DATAUNITTYPE {
+    OMX_DataUnitCodedPicture,
+    OMX_DataUnitVideoSegment,
+    OMX_DataUnitSeveralSegments,
+    OMX_DataUnitArbitraryStreamSection,
+    OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_DataUnitVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_DataUnitMax = 0x7FFFFFFF
+} OMX_DATAUNITTYPE;
+
+
+/** 
+ * Defines possible encapsulation types for coded video data unit. The 
+ * encapsulation information is used both for encoded video input for 
+ * playback as well as encoded video output from recording. 
+ */
+typedef enum OMX_DATAUNITENCAPSULATIONTYPE {
+    OMX_DataEncapsulationElementaryStream,
+    OMX_DataEncapsulationGenericPayload,
+    OMX_DataEncapsulationRtpPayload,
+    OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_DataEncapsulationVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_DataEncapsulationMax = 0x7FFFFFFF
+} OMX_DATAUNITENCAPSULATIONTYPE;
+
+
+/** 
+ * Structure used to configure the type of being decoded/encoded 
+ */
+typedef struct OMX_PARAM_DATAUNITTYPE {
+    OMX_U32 nSize;            /**< Size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ 
+    OMX_U32 nPortIndex;       /**< Port that this structure applies to */
+    OMX_DATAUNITTYPE eUnitType;
+    OMX_DATAUNITENCAPSULATIONTYPE eEncapsulationType;
+} OMX_PARAM_DATAUNITTYPE;
+
+
+/**
+ * Defines dither types 
+ */
+typedef enum OMX_DITHERTYPE {
+    OMX_DitherNone,
+    OMX_DitherOrdered,
+    OMX_DitherErrorDiffusion,
+    OMX_DitherOther,
+    OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_DitherVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_DitherMax = 0x7FFFFFFF
+} OMX_DITHERTYPE;
+
+
+/** 
+ * Structure used to configure current type of dithering 
+ */
+typedef struct OMX_CONFIG_DITHERTYPE {
+    OMX_U32 nSize;            /**< Size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ 
+    OMX_U32 nPortIndex;       /**< Port that this structure applies to */
+    OMX_DITHERTYPE eDither;   /**< Type of dithering to use */
+} OMX_CONFIG_DITHERTYPE;
+
+typedef struct OMX_CONFIG_CAPTUREMODETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;     /**< Port that this structure applies to */
+    OMX_BOOL bContinuous;   /**< If true then ignore frame rate and emit capture 
+                             *   data as fast as possible (otherwise obey port's frame rate). */
+    OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the 
+                             *   specified number of frames (otherwise the port does not 
+                             *   terminate the capture until instructed to do so by the client). 
+                             *   Even if set, the client may manually terminate the capture prior 
+                             *   to reaching the limit. */
+    OMX_U32 nFrameLimit;      /**< Limit on number of frames emitted during a capture (only
+                               *   valid if bFrameLimited is set). */
+} OMX_CONFIG_CAPTUREMODETYPE;
+
+typedef enum OMX_METERINGTYPE {
+    OMX_MeteringModeAverage,     /**< Center-weighted average metering. */
+    OMX_MeteringModeSpot,            /**< Spot (partial) metering. */
+    OMX_MeteringModeMatrix,      /**< Matrix or evaluative metering. */
+    OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_MeteringVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_EVModeMax = 0x7fffffff
+} OMX_METERINGTYPE;
+typedef struct OMX_CONFIG_EXPOSUREVALUETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_METERINGTYPE eMetering;
+    OMX_S32 xEVCompensation;      /**< Fixed point value stored as Q16 */
+    OMX_U32 nApertureFNumber;     /**< e.g. nApertureFNumber = 2 implies "f/2" - Q16 format */
+    OMX_BOOL bAutoAperture;            /**< Whether aperture number is defined automatically */
+    OMX_U32 nShutterSpeedMsec;    /**< Shutterspeed in milliseconds */ 
+    OMX_BOOL bAutoShutterSpeed;        /**< Whether shutter speed is defined automatically */ 
+    OMX_U32 nSensitivity;         /**< e.g. nSensitivity = 100 implies "ISO 100" */
+    OMX_BOOL bAutoSensitivity; /**< Whether sensitivity is defined automatically */
+} OMX_CONFIG_EXPOSUREVALUETYPE;
+
+/** 
+ * Focus region configuration 
+ *
+ * STRUCT MEMBERS:
+ *  nSize           : Size of the structure in bytes
+ *  nVersion        : OMX specification version information
+ *  nPortIndex      : Port that this structure applies to
+ *  bCenter         : Use center region as focus region of interest
+ *  bLeft           : Use left region as focus region of interest
+ *  bRight          : Use right region as focus region of interest
+ *  bTop            : Use top region as focus region of interest
+ *  bBottom         : Use bottom region as focus region of interest
+ *  bTopLeft        : Use top left region as focus region of interest
+ *  bTopRight       : Use top right region as focus region of interest
+ *  bBottomLeft     : Use bottom left region as focus region of interest
+ *  bBottomRight    : Use bottom right region as focus region of interest
+ */
+typedef struct OMX_CONFIG_FOCUSREGIONTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bCenter;
+    OMX_BOOL bLeft;
+    OMX_BOOL bRight;
+    OMX_BOOL bTop;
+    OMX_BOOL bBottom;
+    OMX_BOOL bTopLeft;
+    OMX_BOOL bTopRight;
+    OMX_BOOL bBottomLeft;
+    OMX_BOOL bBottomRight;
+} OMX_CONFIG_FOCUSREGIONTYPE;
+
+/** 
+ * Focus Status type 
+ */
+typedef enum OMX_FOCUSSTATUSTYPE {
+    OMX_FocusStatusOff = 0,
+    OMX_FocusStatusRequest,
+    OMX_FocusStatusReached,
+    OMX_FocusStatusUnableToReach,
+    OMX_FocusStatusLost,
+    OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_FocusStatusVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_FocusStatusMax = 0x7FFFFFFF
+} OMX_FOCUSSTATUSTYPE;
+
+/** 
+ * Focus status configuration 
+ *
+ * STRUCT MEMBERS:
+ *  nSize               : Size of the structure in bytes
+ *  nVersion            : OMX specification version information
+ *  nPortIndex          : Port that this structure applies to
+ *  eFocusStatus        : Specifies the focus status
+ *  bCenterStatus       : Use center region as focus region of interest
+ *  bLeftStatus         : Use left region as focus region of interest
+ *  bRightStatus        : Use right region as focus region of interest
+ *  bTopStatus          : Use top region as focus region of interest
+ *  bBottomStatus       : Use bottom region as focus region of interest
+ *  bTopLeftStatus      : Use top left region as focus region of interest
+ *  bTopRightStatus     : Use top right region as focus region of interest
+ *  bBottomLeftStatus   : Use bottom left region as focus region of interest
+ *  bBottomRightStatus  : Use bottom right region as focus region of interest
+ */
+typedef struct OMX_PARAM_FOCUSSTATUSTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_FOCUSSTATUSTYPE eFocusStatus;
+    OMX_BOOL bCenterStatus;
+    OMX_BOOL bLeftStatus;
+    OMX_BOOL bRightStatus;
+    OMX_BOOL bTopStatus;
+    OMX_BOOL bBottomStatus;
+    OMX_BOOL bTopLeftStatus;
+    OMX_BOOL bTopRightStatus;
+    OMX_BOOL bBottomLeftStatus;
+    OMX_BOOL bBottomRightStatus;
+} OMX_PARAM_FOCUSSTATUSTYPE;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/openmax/include/khronos/OMX_Image.h b/openmax/include/khronos/OMX_Image.h
new file mode 100755 (executable)
index 0000000..a6d4666
--- /dev/null
@@ -0,0 +1,328 @@
+/**
+ * Copyright (c) 2008 The Khronos Group Inc. 
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions: 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software. 
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ */
+
+/** 
+ * @file OMX_Image.h - OpenMax IL version 1.1.2
+ * The structures needed by Image components to exchange parameters and 
+ * configuration data with the components.
+ */
+#ifndef OMX_Image_h
+#define OMX_Image_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/**
+ * Each OMX header must include all required header files to allow the 
+ * header to compile without errors.  The includes below are required  
+ * for this header file to compile successfully 
+ */
+
+#include <OMX_IVCommon.h>
+
+/** @defgroup imaging OpenMAX IL Imaging Domain
+ * @ingroup iv
+ * Structures for OpenMAX IL Imaging domain
+ * @{
+ */
+
+/** 
+ * Enumeration used to define the possible image compression coding. 
+ */
+typedef enum OMX_IMAGE_CODINGTYPE {
+    OMX_IMAGE_CodingUnused,      /**< Value when format is N/A */
+    OMX_IMAGE_CodingAutoDetect,  /**< Auto detection of image format */
+    OMX_IMAGE_CodingJPEG,        /**< JPEG/JFIF image format */
+    OMX_IMAGE_CodingJPEG2K,      /**< JPEG 2000 image format */
+    OMX_IMAGE_CodingEXIF,        /**< EXIF image format */
+    OMX_IMAGE_CodingTIFF,        /**< TIFF image format */
+    OMX_IMAGE_CodingGIF,         /**< Graphics image format */
+    OMX_IMAGE_CodingPNG,         /**< PNG image format */
+    OMX_IMAGE_CodingLZW,         /**< LZW image format */
+    OMX_IMAGE_CodingBMP,         /**< Windows Bitmap format */
+    OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_IMAGE_CodingMax = 0x7FFFFFFF
+} OMX_IMAGE_CODINGTYPE;
+
+
+/**
+ * Data structure used to define an image path. The number of image paths 
+ * for input and output will vary by type of the image component.  
+ * 
+ *  Input (aka Source) : Zero Inputs, one Output,
+ *  Splitter           : One Input, 2 or more Outputs,
+ *  Processing Element : One Input, one output,
+ *  Mixer              : 2 or more inputs, one output,
+ *  Output (aka Sink)  : One Input, zero outputs.
+ * 
+ * The PortDefinition structure is used to define all of the parameters 
+ * necessary for the compliant component to setup an input or an output  
+ * image path.  If additional vendor specific data is required, it should  
+ * be transmitted to the component using the CustomCommand function.   
+ * Compliant components will prepopulate this structure with optimal  
+ * values during the OMX_GetParameter() command.
+ *
+ * STRUCT MEMBERS:
+ *  cMIMEType             : MIME type of data for the port
+ *  pNativeRender         : Platform specific reference for a display if a 
+ *                          sync, otherwise this field is 0
+ *  nFrameWidth           : Width of frame to be used on port if 
+ *                          uncompressed format is used.  Use 0 for 
+ *                          unknown, don't care or variable
+ *  nFrameHeight          : Height of frame to be used on port if 
+ *                          uncompressed format is used. Use 0 for 
+ *                          unknown, don't care or variable
+ *  nStride               : Number of bytes per span of an image (i.e. 
+ *                          indicates the number of bytes to get from
+ *                          span N to span N+1, where negative stride 
+ *                          indicates the image is bottom up
+ *  nSliceHeight          : Height used when encoding in slices
+ *  bFlagErrorConcealment : Turns on error concealment if it is supported by 
+ *                          the OMX component
+ *  eCompressionFormat    : Compression format used in this instance of  
+ *                          the component. When OMX_IMAGE_CodingUnused is 
+ *                          specified, eColorFormat is valid
+ *  eColorFormat          : Decompressed format used by this component
+ *  pNativeWindow         : Platform specific reference for a window object if a 
+ *                          display sink , otherwise this field is 0x0. 
+ */
+typedef struct OMX_IMAGE_PORTDEFINITIONTYPE {
+    OMX_STRING cMIMEType;
+    OMX_NATIVE_DEVICETYPE pNativeRender;
+    OMX_U32 nFrameWidth; 
+    OMX_U32 nFrameHeight;
+    OMX_S32 nStride;     
+    OMX_U32 nSliceHeight;
+    OMX_BOOL bFlagErrorConcealment;
+    OMX_IMAGE_CODINGTYPE eCompressionFormat;
+    OMX_COLOR_FORMATTYPE eColorFormat;
+    OMX_NATIVE_WINDOWTYPE pNativeWindow;
+} OMX_IMAGE_PORTDEFINITIONTYPE;
+
+
+/**  
+ * Port format parameter.  This structure is used to enumerate the various 
+ * data input/output format supported by the port.
+ * 
+ * STRUCT MEMBERS:
+ *  nSize              : Size of the structure in bytes
+ *  nVersion           : OMX specification version information
+ *  nPortIndex         : Indicates which port to set
+ *  nIndex             : Indicates the enumeration index for the format from 
+ *                       0x0 to N-1
+ *  eCompressionFormat : Compression format used in this instance of the 
+ *                       component. When OMX_IMAGE_CodingUnused is specified, 
+ *                       eColorFormat is valid
+ *  eColorFormat       : Decompressed format used by this component
+ */
+typedef struct OMX_IMAGE_PARAM_PORTFORMATTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nIndex;
+    OMX_IMAGE_CODINGTYPE eCompressionFormat;
+    OMX_COLOR_FORMATTYPE eColorFormat;
+} OMX_IMAGE_PARAM_PORTFORMATTYPE;
+
+
+/** 
+ * Flash control type 
+ *
+ * ENUMS
+ *  Torch : Flash forced constantly on
+ */
+typedef enum OMX_IMAGE_FLASHCONTROLTYPE {
+    OMX_IMAGE_FlashControlOn = 0,
+    OMX_IMAGE_FlashControlOff,
+    OMX_IMAGE_FlashControlAuto,
+    OMX_IMAGE_FlashControlRedEyeReduction,
+    OMX_IMAGE_FlashControlFillin,
+    OMX_IMAGE_FlashControlTorch,
+    OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_IMAGE_FlashControlMax = 0x7FFFFFFF
+} OMX_IMAGE_FLASHCONTROLTYPE;
+
+
+/** 
+ * Flash control configuration 
+ *
+ * STRUCT MEMBERS:
+ *  nSize         : Size of the structure in bytes
+ *  nVersion      : OMX specification version information
+ *  nPortIndex    : Port that this structure applies to
+ *  eFlashControl : Flash control type
+ */
+typedef struct OMX_IMAGE_PARAM_FLASHCONTROLTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_IMAGE_FLASHCONTROLTYPE eFlashControl;
+} OMX_IMAGE_PARAM_FLASHCONTROLTYPE;
+
+
+/** 
+ * Focus control type 
+ */
+typedef enum OMX_IMAGE_FOCUSCONTROLTYPE {
+    OMX_IMAGE_FocusControlOn = 0,
+    OMX_IMAGE_FocusControlOff,
+    OMX_IMAGE_FocusControlAuto,
+    OMX_IMAGE_FocusControlAutoLock,
+    OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_IMAGE_FocusControlMax = 0x7FFFFFFF
+} OMX_IMAGE_FOCUSCONTROLTYPE;
+
+/** 
+ * Focus control configuration 
+ *
+ * STRUCT MEMBERS:
+ *  nSize           : Size of the structure in bytes
+ *  nVersion        : OMX specification version information
+ *  nPortIndex      : Port that this structure applies to
+ *  eFocusControl   : Focus control
+ *  nFocusSteps     : Focus can take on values from 0 mm to infinity. 
+ *                    Interest is only in number of steps over this range.
+ *  nFocusStepIndex : Current focus step index
+ */
+typedef struct OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_IMAGE_FOCUSCONTROLTYPE eFocusControl;
+    OMX_U32 nFocusSteps;
+    OMX_U32 nFocusStepIndex;
+} OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE;
+
+
+/** 
+ * Q Factor for JPEG compression, which controls the tradeoff between image
+ * quality and size.  Q Factor provides a more simple means of controlling
+ * JPEG compression quality, without directly programming Quantization
+ * tables for chroma and luma 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes         
+ *  nVersion   : OMX specification version information 
+ *  nPortIndex : Port that this structure applies to 
+ *  nQFactor   : JPEG Q factor value in the range of 1-100. A factor of 1 
+ *               produces the smallest, worst quality images, and a factor 
+ *               of 100 produces the largest, best quality images.  A 
+ *               typical default is 75 for small good quality images               
+ */
+typedef struct OMX_IMAGE_PARAM_QFACTORTYPE {
+    OMX_U32 nSize;            
+    OMX_VERSIONTYPE nVersion; 
+    OMX_U32 nPortIndex;       
+    OMX_U32 nQFactor;                                        
+} OMX_IMAGE_PARAM_QFACTORTYPE;
+
+/** 
+ * Quantization table type 
+ */
+
+typedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE {
+    OMX_IMAGE_QuantizationTableLuma = 0,
+    OMX_IMAGE_QuantizationTableChroma,
+    OMX_IMAGE_QuantizationTableChromaCb,
+    OMX_IMAGE_QuantizationTableChromaCr,
+    OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF
+} OMX_IMAGE_QUANTIZATIONTABLETYPE;
+
+/** 
+ * JPEG quantization tables are used to determine DCT compression for
+ * YUV data, as an alternative to specifying Q factor, providing exact 
+ * control of compression 
+ *
+ * STRUCT MEMBERS:
+ *  nSize                   : Size of the structure in bytes
+ *  nVersion                : OMX specification version information 
+ *  nPortIndex              : Port that this structure applies to
+ *  eQuantizationTable      : Quantization table type
+ *  nQuantizationMatrix[64] : JPEG quantization table of coefficients stored 
+ *                            in increasing columns then by rows of data (i.e. 
+ *                            row 1, ... row 8). Quantization values are in 
+ *                            the range 0-255 and stored in linear order
+ *                            (i.e. the component will zig-zag the 
+ *                            quantization table data if required internally) 
+ */
+typedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_IMAGE_QUANTIZATIONTABLETYPE eQuantizationTable;
+    OMX_U8 nQuantizationMatrix[64];
+} OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE;
+
+
+/** 
+ * Huffman table type, the same Huffman table is applied for chroma and 
+ * luma component 
+ */
+typedef enum OMX_IMAGE_HUFFMANTABLETYPE {
+    OMX_IMAGE_HuffmanTableAC = 0,
+    OMX_IMAGE_HuffmanTableDC,
+    OMX_IMAGE_HuffmanTableACLuma,
+    OMX_IMAGE_HuffmanTableACChroma,
+    OMX_IMAGE_HuffmanTableDCLuma,
+    OMX_IMAGE_HuffmanTableDCChroma,
+    OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF
+} OMX_IMAGE_HUFFMANTABLETYPE;
+
+/** 
+ * JPEG Huffman table 
+ *
+ * STRUCT MEMBERS:
+ *  nSize                            : Size of the structure in bytes
+ *  nVersion                         : OMX specification version information
+ *  nPortIndex                       : Port that this structure applies to
+ *  eHuffmanTable                    : Huffman table type
+ *  nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each 
+ *                                     possible length
+ *  nHuffmanTable[256]               : 0-255, the size used for AC and DC 
+ *                                     HuffmanTable are 16 and 162 
+ */
+typedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_IMAGE_HUFFMANTABLETYPE eHuffmanTable;
+    OMX_U8 nNumberOfHuffmanCodeOfLength[16];
+    OMX_U8 nHuffmanTable[256];
+}OMX_IMAGE_PARAM_HUFFMANTTABLETYPE;
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/openmax/include/khronos/OMX_ImageExt.h b/openmax/include/khronos/OMX_ImageExt.h
new file mode 100755 (executable)
index 0000000..664a084
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_ImageExt.h - OpenMax IL version 1.1.2
+ * The OMX_ImageExt header file contains extensions to the
+ * definitions used by both the application and the component to
+ * access image items.
+ */
+
+#ifndef OMX_ImageExt_h
+#define OMX_ImageExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Core.h>
+
+/** Enum for standard image codingtype extensions */
+typedef enum OMX_IMAGE_CODINGEXTTYPE {
+    OMX_IMAGE_CodingExtUnused = OMX_IMAGE_CodingKhronosExtensions,
+    OMX_IMAGE_CodingWEBP,         /**< WebP image format */
+} OMX_IMAGE_CODINGEXTTYPE;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_ImageExt_h */
+/* File EOF */
diff --git a/openmax/include/khronos/OMX_Index.h b/openmax/include/khronos/OMX_Index.h
new file mode 100755 (executable)
index 0000000..44d4ea7
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc. 
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions: 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software. 
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ *
+ */
+
+/** @file OMX_Index.h - OpenMax IL version 1.1.2
+ *  The OMX_Index header file contains the definitions for both applications
+ *  and components .
+ */
+
+
+#ifndef OMX_Index_h
+#define OMX_Index_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header must include all required header files to allow the
+ *  header to compile without errors.  The includes below are required
+ *  for this header file to compile successfully 
+ */
+#include <OMX_Types.h>
+
+
+/** The OMX_INDEXTYPE enumeration is used to select a structure when either
+ *  getting or setting parameters and/or configuration data.  Each entry in 
+ *  this enumeration maps to an OMX specified structure.  When the 
+ *  OMX_GetParameter, OMX_SetParameter, OMX_GetConfig or OMX_SetConfig methods
+ *  are used, the second parameter will always be an entry from this enumeration
+ *  and the third entry will be the structure shown in the comments for the entry.
+ *  For example, if the application is initializing a cropping function, the 
+ *  OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter 
+ *  and would send a pointer to an initialized OMX_RECTTYPE structure as the 
+ *  third parameter.
+ *  
+ *  The enumeration entries named with the OMX_Config prefix are sent using
+ *  the OMX_SetConfig command and the enumeration entries named with the
+ *  OMX_PARAM_ prefix are sent using the OMX_SetParameter command.
+ */
+typedef enum OMX_INDEXTYPE {
+
+    OMX_IndexComponentStartUnused = 0x01000000,
+    OMX_IndexParamPriorityMgmt,             /**< reference: OMX_PRIORITYMGMTTYPE */
+    OMX_IndexParamAudioInit,                /**< reference: OMX_PORT_PARAM_TYPE */
+    OMX_IndexParamImageInit,                /**< reference: OMX_PORT_PARAM_TYPE */
+    OMX_IndexParamVideoInit,                /**< reference: OMX_PORT_PARAM_TYPE */
+    OMX_IndexParamOtherInit,                /**< reference: OMX_PORT_PARAM_TYPE */
+    OMX_IndexParamNumAvailableStreams,      /**< reference: OMX_PARAM_U32TYPE */
+    OMX_IndexParamActiveStream,             /**< reference: OMX_PARAM_U32TYPE */
+    OMX_IndexParamSuspensionPolicy,         /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */
+    OMX_IndexParamComponentSuspended,       /**< reference: OMX_PARAM_SUSPENSIONTYPE */
+    OMX_IndexConfigCapturing,               /**< reference: OMX_CONFIG_BOOLEANTYPE */ 
+    OMX_IndexConfigCaptureMode,             /**< reference: OMX_CONFIG_CAPTUREMODETYPE */ 
+    OMX_IndexAutoPauseAfterCapture,         /**< reference: OMX_CONFIG_BOOLEANTYPE */ 
+    OMX_IndexParamContentURI,               /**< reference: OMX_PARAM_CONTENTURITYPE */
+    OMX_IndexParamCustomContentPipe,        /**< reference: OMX_PARAM_CONTENTPIPETYPE */ 
+    OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */
+    OMX_IndexConfigMetadataItemCount,       /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */
+    OMX_IndexConfigContainerNodeCount,      /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */
+    OMX_IndexConfigMetadataItem,            /**< reference: OMX_CONFIG_METADATAITEMTYPE */
+    OMX_IndexConfigCounterNodeID,           /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */
+    OMX_IndexParamMetadataFilterType,       /**< reference: OMX_PARAM_METADATAFILTERTYPE */
+    OMX_IndexParamMetadataKeyFilter,        /**< reference: OMX_PARAM_METADATAFILTERTYPE */
+    OMX_IndexConfigPriorityMgmt,            /**< reference: OMX_PRIORITYMGMTTYPE */
+    OMX_IndexParamStandardComponentRole,    /**< reference: OMX_PARAM_COMPONENTROLETYPE */
+
+    OMX_IndexPortStartUnused = 0x02000000,
+    OMX_IndexParamPortDefinition,           /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */
+    OMX_IndexParamCompBufferSupplier,       /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */ 
+    OMX_IndexReservedStartUnused = 0x03000000,
+
+    /* Audio parameters and configurations */
+    OMX_IndexAudioStartUnused = 0x04000000,
+    OMX_IndexParamAudioPortFormat,          /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */
+    OMX_IndexParamAudioPcm,                 /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */
+    OMX_IndexParamAudioAac,                 /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */
+    OMX_IndexParamAudioRa,                  /**< reference: OMX_AUDIO_PARAM_RATYPE */
+    OMX_IndexParamAudioMp3,                 /**< reference: OMX_AUDIO_PARAM_MP3TYPE */
+    OMX_IndexParamAudioAdpcm,               /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */
+    OMX_IndexParamAudioG723,                /**< reference: OMX_AUDIO_PARAM_G723TYPE */
+    OMX_IndexParamAudioG729,                /**< reference: OMX_AUDIO_PARAM_G729TYPE */
+    OMX_IndexParamAudioAmr,                 /**< reference: OMX_AUDIO_PARAM_AMRTYPE */
+    OMX_IndexParamAudioWma,                 /**< reference: OMX_AUDIO_PARAM_WMATYPE */
+    OMX_IndexParamAudioSbc,                 /**< reference: OMX_AUDIO_PARAM_SBCTYPE */
+    OMX_IndexParamAudioMidi,                /**< reference: OMX_AUDIO_PARAM_MIDITYPE */
+    OMX_IndexParamAudioGsm_FR,              /**< reference: OMX_AUDIO_PARAM_GSMFRTYPE */
+    OMX_IndexParamAudioMidiLoadUserSound,   /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */
+    OMX_IndexParamAudioG726,                /**< reference: OMX_AUDIO_PARAM_G726TYPE */
+    OMX_IndexParamAudioGsm_EFR,             /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */
+    OMX_IndexParamAudioGsm_HR,              /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */
+    OMX_IndexParamAudioPdc_FR,              /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */
+    OMX_IndexParamAudioPdc_EFR,             /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */
+    OMX_IndexParamAudioPdc_HR,              /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */
+    OMX_IndexParamAudioTdma_FR,             /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */
+    OMX_IndexParamAudioTdma_EFR,            /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */
+    OMX_IndexParamAudioQcelp8,              /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */
+    OMX_IndexParamAudioQcelp13,             /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */
+    OMX_IndexParamAudioEvrc,                /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */
+    OMX_IndexParamAudioSmv,                 /**< reference: OMX_AUDIO_PARAM_SMVTYPE */
+    OMX_IndexParamAudioVorbis,              /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */
+
+    OMX_IndexConfigAudioMidiImmediateEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE */
+    OMX_IndexConfigAudioMidiControl,        /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */
+    OMX_IndexConfigAudioMidiSoundBankProgram, /**< reference: OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE */
+    OMX_IndexConfigAudioMidiStatus,         /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */
+    OMX_IndexConfigAudioMidiMetaEvent,      /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */
+    OMX_IndexConfigAudioMidiMetaEventData,  /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */
+    OMX_IndexConfigAudioVolume,             /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */
+    OMX_IndexConfigAudioBalance,            /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */
+    OMX_IndexConfigAudioChannelMute,        /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */
+    OMX_IndexConfigAudioMute,               /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */
+    OMX_IndexConfigAudioLoudness,           /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */
+    OMX_IndexConfigAudioEchoCancelation,    /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */
+    OMX_IndexConfigAudioNoiseReduction,     /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */
+    OMX_IndexConfigAudioBass,               /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */
+    OMX_IndexConfigAudioTreble,             /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */
+    OMX_IndexConfigAudioStereoWidening,     /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */
+    OMX_IndexConfigAudioChorus,             /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */
+    OMX_IndexConfigAudioEqualizer,          /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */
+    OMX_IndexConfigAudioReverberation,      /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */
+    OMX_IndexConfigAudioChannelVolume,      /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */
+
+    /* Image specific parameters and configurations */
+    OMX_IndexImageStartUnused = 0x05000000,
+    OMX_IndexParamImagePortFormat,          /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */
+    OMX_IndexParamFlashControl,             /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */
+    OMX_IndexConfigFocusControl,            /**< reference: OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE */
+    OMX_IndexParamQFactor,                  /**< reference: OMX_IMAGE_PARAM_QFACTORTYPE */
+    OMX_IndexParamQuantizationTable,        /**< reference: OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE */
+    OMX_IndexParamHuffmanTable,             /**< reference: OMX_IMAGE_PARAM_HUFFMANTTABLETYPE */
+    OMX_IndexConfigFlashControl,            /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */
+
+    /* Video specific parameters and configurations */
+    OMX_IndexVideoStartUnused = 0x06000000,
+    OMX_IndexParamVideoPortFormat,          /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */
+    OMX_IndexParamVideoQuantization,        /**< reference: OMX_VIDEO_PARAM_QUANTIZATIONTYPE */
+    OMX_IndexParamVideoFastUpdate,          /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */
+    OMX_IndexParamVideoBitrate,             /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */
+    OMX_IndexParamVideoMotionVector,        /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */
+    OMX_IndexParamVideoIntraRefresh,        /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */
+    OMX_IndexParamVideoErrorCorrection,     /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */
+    OMX_IndexParamVideoVBSMC,               /**< reference: OMX_VIDEO_PARAM_VBSMCTYPE */
+    OMX_IndexParamVideoMpeg2,               /**< reference: OMX_VIDEO_PARAM_MPEG2TYPE */
+    OMX_IndexParamVideoMpeg4,               /**< reference: OMX_VIDEO_PARAM_MPEG4TYPE */
+    OMX_IndexParamVideoWmv,                 /**< reference: OMX_VIDEO_PARAM_WMVTYPE */
+    OMX_IndexParamVideoRv,                  /**< reference: OMX_VIDEO_PARAM_RVTYPE */
+    OMX_IndexParamVideoAvc,                 /**< reference: OMX_VIDEO_PARAM_AVCTYPE */
+    OMX_IndexParamVideoH263,                /**< reference: OMX_VIDEO_PARAM_H263TYPE */
+    OMX_IndexParamVideoProfileLevelQuerySupported, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */
+    OMX_IndexParamVideoProfileLevelCurrent, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */
+    OMX_IndexConfigVideoBitrate,            /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */
+    OMX_IndexConfigVideoFramerate,          /**< reference: OMX_CONFIG_FRAMERATETYPE */
+    OMX_IndexConfigVideoIntraVOPRefresh,    /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */
+    OMX_IndexConfigVideoIntraMBRefresh,     /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */
+    OMX_IndexConfigVideoMBErrorReporting,   /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */
+    OMX_IndexParamVideoMacroblocksPerFrame, /**< reference: OMX_PARAM_MACROBLOCKSTYPE */
+    OMX_IndexConfigVideoMacroBlockErrorMap, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */
+    OMX_IndexParamVideoSliceFMO,            /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */
+    OMX_IndexConfigVideoAVCIntraPeriod,     /**< reference: OMX_VIDEO_CONFIG_AVCINTRAPERIOD */
+    OMX_IndexConfigVideoNalSize,            /**< reference: OMX_VIDEO_CONFIG_NALSIZE */
+
+    /* Image & Video common Configurations */
+    OMX_IndexCommonStartUnused = 0x07000000,
+    OMX_IndexParamCommonDeblocking,         /**< reference: OMX_PARAM_DEBLOCKINGTYPE */
+    OMX_IndexParamCommonSensorMode,         /**< reference: OMX_PARAM_SENSORMODETYPE */
+    OMX_IndexParamCommonInterleave,         /**< reference: OMX_PARAM_INTERLEAVETYPE */
+    OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */
+    OMX_IndexConfigCommonScale,             /**< reference: OMX_CONFIG_SCALEFACTORTYPE */
+    OMX_IndexConfigCommonImageFilter,       /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */
+    OMX_IndexConfigCommonColorEnhancement,  /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */
+    OMX_IndexConfigCommonColorKey,          /**< reference: OMX_CONFIG_COLORKEYTYPE */
+    OMX_IndexConfigCommonColorBlend,        /**< reference: OMX_CONFIG_COLORBLENDTYPE */
+    OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */
+    OMX_IndexConfigCommonRotate,            /**< reference: OMX_CONFIG_ROTATIONTYPE */
+    OMX_IndexConfigCommonMirror,            /**< reference: OMX_CONFIG_MIRRORTYPE */
+    OMX_IndexConfigCommonOutputPosition,    /**< reference: OMX_CONFIG_POINTTYPE */
+    OMX_IndexConfigCommonInputCrop,         /**< reference: OMX_CONFIG_RECTTYPE */
+    OMX_IndexConfigCommonOutputCrop,        /**< reference: OMX_CONFIG_RECTTYPE */
+    OMX_IndexConfigCommonDigitalZoom,       /**< reference: OMX_CONFIG_SCALEFACTORTYPE */
+    OMX_IndexConfigCommonOpticalZoom,       /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/
+    OMX_IndexConfigCommonWhiteBalance,      /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */
+    OMX_IndexConfigCommonExposure,          /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */
+    OMX_IndexConfigCommonContrast,          /**< reference: OMX_CONFIG_CONTRASTTYPE */
+    OMX_IndexConfigCommonBrightness,        /**< reference: OMX_CONFIG_BRIGHTNESSTYPE */
+    OMX_IndexConfigCommonBacklight,         /**< reference: OMX_CONFIG_BACKLIGHTTYPE */
+    OMX_IndexConfigCommonGamma,             /**< reference: OMX_CONFIG_GAMMATYPE */
+    OMX_IndexConfigCommonSaturation,        /**< reference: OMX_CONFIG_SATURATIONTYPE */
+    OMX_IndexConfigCommonLightness,         /**< reference: OMX_CONFIG_LIGHTNESSTYPE */
+    OMX_IndexConfigCommonExclusionRect,     /**< reference: OMX_CONFIG_RECTTYPE */
+    OMX_IndexConfigCommonDithering,         /**< reference: OMX_CONFIG_DITHERTYPE */
+    OMX_IndexConfigCommonPlaneBlend,        /**< reference: OMX_CONFIG_PLANEBLENDTYPE */
+    OMX_IndexConfigCommonExposureValue,     /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */
+    OMX_IndexConfigCommonOutputSize,        /**< reference: OMX_FRAMESIZETYPE */
+    OMX_IndexParamCommonExtraQuantData,     /**< reference: OMX_OTHER_EXTRADATATYPE */
+    OMX_IndexConfigCommonFocusRegion,       /**< reference: OMX_CONFIG_FOCUSREGIONTYPE */
+    OMX_IndexConfigCommonFocusStatus,       /**< reference: OMX_PARAM_FOCUSSTATUSTYPE */
+    OMX_IndexConfigCommonTransitionEffect,  /**< reference: OMX_CONFIG_TRANSITIONEFFECTTYPE */
+
+    /* Reserved Configuration range */
+    OMX_IndexOtherStartUnused = 0x08000000,
+    OMX_IndexParamOtherPortFormat,          /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */
+    OMX_IndexConfigOtherPower,              /**< reference: OMX_OTHER_CONFIG_POWERTYPE */
+    OMX_IndexConfigOtherStats,              /**< reference: OMX_OTHER_CONFIG_STATSTYPE */
+
+
+    /* Reserved Time range */
+    OMX_IndexTimeStartUnused = 0x09000000,
+    OMX_IndexConfigTimeScale,               /**< reference: OMX_TIME_CONFIG_SCALETYPE */
+    OMX_IndexConfigTimeClockState,          /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */
+    OMX_IndexConfigTimeActiveRefClock,      /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */
+    OMX_IndexConfigTimeCurrentMediaTime,    /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */
+    OMX_IndexConfigTimeCurrentWallTime,     /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */
+    OMX_IndexConfigTimeCurrentAudioReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */
+    OMX_IndexConfigTimeCurrentVideoReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */
+    OMX_IndexConfigTimeMediaTimeRequest,    /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */
+    OMX_IndexConfigTimeClientStartTime,     /**<reference:  OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */
+    OMX_IndexConfigTimePosition,            /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE */
+    OMX_IndexConfigTimeSeekMode,            /**< reference: OMX_TIME_CONFIG_SEEKMODETYPE */
+
+
+    OMX_IndexKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    /* Vendor specific area */
+    OMX_IndexVendorStartUnused = 0x7F000000,
+    /* Vendor specific structures should be in the range of 0x7F000000 
+       to 0x7FFFFFFE.  This range is not broken out by vendor, so
+       private indexes are not guaranteed unique and therefore should
+       only be sent to the appropriate component. */
+
+    OMX_IndexMax = 0x7FFFFFFF
+
+} OMX_INDEXTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/openmax/include/khronos/OMX_IndexExt.h b/openmax/include/khronos/OMX_IndexExt.h
new file mode 100755 (executable)
index 0000000..6245f58
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010 The Khronos Group Inc. 
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions: 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software. 
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ *
+ */
+
+/** @file OMX_IndexExt.h - OpenMax IL version 1.1.2
+ * The OMX_IndexExt header file contains extensions to the definitions 
+ * for both applications and components .
+ */
+
+#ifndef OMX_IndexExt_h
+#define OMX_IndexExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Index.h>
+
+
+/** Khronos standard extension indices.
+
+This enum lists the current Khronos extension indices to OpenMAX IL.
+*/
+typedef enum OMX_INDEXEXTTYPE {
+
+    /* Component parameters and configurations */
+    OMX_IndexExtComponentStartUnused = OMX_IndexKhronosExtensions + 0x00100000,
+    OMX_IndexConfigCallbackRequest,                 /**< reference: OMX_CONFIG_CALLBACKREQUESTTYPE */
+    OMX_IndexConfigCommitMode,                      /**< reference: OMX_CONFIG_COMMITMODETYPE */
+    OMX_IndexConfigCommit,                          /**< reference: OMX_CONFIG_COMMITTYPE */
+
+    /* Port parameters and configurations */
+    OMX_IndexExtPortStartUnused = OMX_IndexKhronosExtensions + 0x00200000,
+
+    /* Audio parameters and configurations */
+    OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000,
+
+    /* Image parameters and configurations */
+    OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000,
+
+    /* Video parameters and configurations */
+    OMX_IndexExtVideoStartUnused = OMX_IndexKhronosExtensions + 0x00600000,
+    OMX_IndexParamNalStreamFormatSupported,         /**< reference: OMX_NALSTREAMFORMATTYPE */
+    OMX_IndexParamNalStreamFormat,                  /**< reference: OMX_NALSTREAMFORMATTYPE */
+    OMX_IndexParamNalStreamFormatSelect,            /**< reference: OMX_NALSTREAMFORMATTYPE */
+    OMX_IndexParamVideoVp8,                         /**< reference: OMX_VIDEO_PARAM_VP8TYPE */
+    OMX_IndexConfigVideoVp8ReferenceFrame,          /**< reference: OMX_VIDEO_VP8REFERENCEFRAMETYPE */
+    OMX_IndexConfigVideoVp8ReferenceFrameType,      /**< reference: OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE */
+
+    /* Image & Video common configurations */
+    OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000,
+
+    /* Other configurations */
+    OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000,
+
+    /* Time configurations */
+    OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000,
+
+    OMX_IndexExtMax = 0x7FFFFFFF
+} OMX_INDEXEXTTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_IndexExt_h */
+/* File EOF */
diff --git a/openmax/include/khronos/OMX_Other.h b/openmax/include/khronos/OMX_Other.h
new file mode 100755 (executable)
index 0000000..caf7f38
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc. 
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions: 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software. 
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ *
+ */
+
+/** @file OMX_Other.h - OpenMax IL version 1.1.2
+ *  The structures needed by Other components to exchange
+ *  parameters and configuration data with the components.
+ */
+
+#ifndef OMX_Other_h
+#define OMX_Other_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header must include all required header files to allow the
+ *  header to compile without errors.  The includes below are required
+ *  for this header file to compile successfully 
+ */
+
+#include <OMX_Core.h>
+
+
+/** 
+ * Enumeration of possible data types which match to multiple domains or no
+ * domain at all.  For types which are vendor specific, a value above
+ * OMX_OTHER_VENDORTSTART should be used.
+ */
+typedef enum OMX_OTHER_FORMATTYPE {
+    OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time, 
+                                   time deltas, etc */
+    OMX_OTHER_FormatPower,    /**< Perhaps used for enabling/disabling power 
+                                   management, setting clocks? */
+    OMX_OTHER_FormatStats,    /**< Could be things such as frame rate, frames 
+                                   dropped, etc */
+    OMX_OTHER_FormatBinary,   /**< Arbitrary binary data */
+    OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific 
+                                                formats */
+
+    OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_OTHER_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_OTHER_FormatMax = 0x7FFFFFFF
+} OMX_OTHER_FORMATTYPE;
+
+/** 
+ * Enumeration of seek modes.
+ */
+typedef enum OMX_TIME_SEEKMODETYPE {
+    OMX_TIME_SeekModeFast = 0, /**< Prefer seeking to an approximation
+                                * of the requested seek position over   
+                                * the actual seek position if it
+                                * results in a faster seek. */
+    OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek 
+                                * position over an approximation
+                                * of the requested seek position even
+                                * if it results in a slower seek. */
+    OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_TIME_SeekModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_TIME_SeekModeMax = 0x7FFFFFFF
+} OMX_TIME_SEEKMODETYPE;
+
+/* Structure representing the seekmode of the component */
+typedef struct OMX_TIME_CONFIG_SEEKMODETYPE {
+    OMX_U32 nSize;                  /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
+    OMX_TIME_SEEKMODETYPE eType;    /**< The seek mode */
+} OMX_TIME_CONFIG_SEEKMODETYPE;
+
+/** Structure representing a time stamp used with the following configs 
+ * on the Clock Component (CC):
+ * 
+ * OMX_IndexConfigTimeCurrentWallTime: query of the CC\92s current wall  
+ *     time
+ * OMX_IndexConfigTimeCurrentMediaTime: query of the CC\92s current media
+ *     time
+ * OMX_IndexConfigTimeCurrentAudioReference and  
+ * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference 
+ *     clock sending SC its reference time
+ * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends 
+ *     this structure to the Clock Component via a SetConfig on its 
+ *     client port when it receives a buffer with
+ *     OMX_BUFFERFLAG_STARTTIME set. It must use the timestamp
+ *     specified by that buffer for nStartTimestamp. 
+ *
+ * It\92s also used with the following config on components in general:
+ *
+ * OMX_IndexConfigTimePosition: IL client querying component position 
+ * (GetConfig) or commanding a component to seek to the given location
+ * (SetConfig)
+ */    
+typedef struct OMX_TIME_CONFIG_TIMESTAMPTYPE {
+    OMX_U32 nSize;               /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;    /**< OMX specification version
+                                  *   information */
+    OMX_U32 nPortIndex;     /**< port that this structure applies to */
+    OMX_TICKS nTimestamp;           /**< timestamp .*/ 
+} OMX_TIME_CONFIG_TIMESTAMPTYPE;  
+
+/** Enumeration of possible reference clocks to the media time. */
+typedef enum OMX_TIME_UPDATETYPE {
+      OMX_TIME_UpdateRequestFulfillment,    /**< Update is the fulfillment of a media time request. */
+      OMX_TIME_UpdateScaleChanged,             /**< Update was generated because the scale chagned. */
+      OMX_TIME_UpdateClockStateChanged,     /**< Update was generated because the clock state changed. */
+      OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+      OMX_TIME_UpdateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+      OMX_TIME_UpdateMax = 0x7FFFFFFF
+} OMX_TIME_UPDATETYPE;
+
+/** Enumeration of possible reference clocks to the media time. */
+typedef enum OMX_TIME_REFCLOCKTYPE {
+      OMX_TIME_RefClockNone,    /**< Use no references. */
+      OMX_TIME_RefClockAudio,  /**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */
+      OMX_TIME_RefClockVideo,   /**< Use references sent through OMX_IndexConfigTimeCurrentVideoReference */
+      OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+      OMX_TIME_RefClockVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+      OMX_TIME_RefClockMax = 0x7FFFFFFF
+} OMX_TIME_REFCLOCKTYPE;
+
+/** Enumeration of clock states. */
+typedef enum OMX_TIME_CLOCKSTATE {
+      OMX_TIME_ClockStateRunning,             /**< Clock running. */
+      OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the 
+                                               *   prescribed clients emit their
+                                               *   start time. */
+      OMX_TIME_ClockStateStopped,             /**< Clock stopped. */
+      OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+      OMX_TIME_ClockStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+      OMX_TIME_ClockStateMax = 0x7FFFFFFF
+} OMX_TIME_CLOCKSTATE;
+
+/** Structure representing a media time request to the clock component.
+ *
+ *  A client component sends this structure to the Clock Component via a SetConfig
+ *  on its client port to specify a media timestamp the Clock Component
+ *  should emit.  The Clock Component should fulfill the request by sending a
+ *  OMX_TIME_MEDIATIMETYPE when its media clock matches the requested 
+ *  timestamp.
+ *
+ *  The client may require a media time request be fulfilled slightly
+ *  earlier than the media time specified. In this case the client specifies 
+ *  an offset which is equal to the difference between wall time corresponding 
+ *  to the requested media time and the wall time when it will be 
+ *  fulfilled. 
+ *
+ *  A client component may uses these requests and the OMX_TIME_MEDIATIMETYPE to
+ *  time events according to timestamps. If a client must perform an operation O at
+ *  a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a 
+ *  media time request at T (perhaps specifying an offset to ensure the request fulfillment
+ *  is a little early). When the clock component passes the resulting OMX_TIME_MEDIATIMETYPE
+ *  structure back to the client component, the client may perform operation O (perhaps having
+ *  to wait a slight amount more time itself as specified by the return values).
+ */
+
+typedef struct OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_PTR pClientPrivate;     /**< Client private data to disabiguate this media time 
+                                 *   from others (e.g. the number of the frame to deliver). 
+                                 *   Duplicated in the media time structure that fulfills 
+                                 *   this request. A value of zero is reserved for time scale 
+                                 *   updates. */
+    OMX_TICKS nMediaTimestamp;  /**< Media timestamp requested.*/ 
+    OMX_TICKS nOffset;          /**< Amount of wall clock time by which this
+                                 *   request should be fulfilled early */
+} OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE;
+
+/**< Structure sent from the clock component client either when fulfilling 
+ *   a media time request or when the time scale has changed. 
+ *
+ *   In the former case the Clock Component fills this structure and times its emission 
+ *   to a client component (via the client port) according to the corresponding media 
+ *   time request sent by the client. The Clock Component should time the emission to occur
+ *   when the requested timestamp matches the Clock Component's media time but also the 
+ *   prescribed offset early. 
+ *
+ *   Upon scale changes the clock component clears the nClientPrivate data, sends the current
+ *   media time and sets the nScale to the new scale via the client port. It emits a 
+ *   OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to 
+ *   alter processing to accomodate scaling. For instance a video component might skip inter-frames 
+ *   in the case of extreme fastforward. Likewise an audio component might add or remove samples 
+ *   from an audio frame to scale audio data. 
+ *
+ *   It is expected that some clock components may not be able to fulfill requests
+ *   at exactly the prescribed time. This is acceptable so long as the request is 
+ *   fulfilled at least as early as described and not later. This structure provides 
+ *   fields the client may use to wait for the remaining time.
+ *
+ *   The client may use either the nOffset or nWallTimeAtMedia fields to determine the 
+ *   wall time until the nMediaTimestamp actually occurs. In the latter case the
+ *   client can get a more accurate value for offset by getting the current wall
+ *   from the cloc component and subtracting it from nWallTimeAtMedia. 
+ */
+
+typedef struct OMX_TIME_MEDIATIMETYPE {
+    OMX_U32 nSize;                  /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
+    OMX_U32 nClientPrivate;         /**< Client private data to disabiguate this media time 
+                                     *   from others. Copied from the media time request. 
+                                     *   A value of zero is reserved for time scale updates. */
+    OMX_TIME_UPDATETYPE eUpdateType; /**< Reason for the update */
+    OMX_TICKS nMediaTimestamp;      /**< Media time requested. If no media time was 
+                                     *   requested then this is the current media time. */ 
+    OMX_TICKS nOffset;              /**< Amount of wall clock time by which this
+                                     *   request was actually fulfilled early */
+
+    OMX_TICKS nWallTimeAtMediaTime; /**< Wall time corresponding to nMediaTimeStamp.
+                                     *   A client may compare this value to current
+                                     *   media time obtained from the Clock Component to determine
+                                     *   the wall time until the media timestamp is really
+                                     *   current. */
+    OMX_S32 xScale;                 /**< Current media time scale in Q16 format. */
+    OMX_TIME_CLOCKSTATE eState;     /* Seeking Change. Added 7/12.*/
+                                    /**< State of the media time. */
+} OMX_TIME_MEDIATIMETYPE;  
+
+/** Structure representing the current media time scale factor. Applicable only to clock 
+ *  component, other components see scale changes via OMX_TIME_MEDIATIMETYPE buffers sent via
+ *  the clock component client ports. Upon recieving this config the clock component changes 
+ *  the rate by which the media time increases or decreases effectively implementing trick modes. 
+ */ 
+typedef struct OMX_TIME_CONFIG_SCALETYPE {
+    OMX_U32 nSize;                  /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
+    OMX_S32 xScale;                 /**< This is a value in Q16 format which is used for
+                                     * scaling the media time */
+} OMX_TIME_CONFIG_SCALETYPE;
+/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPE\92s nWaitMask field */
+#define OMX_CLOCKPORT0 0x00000001
+#define OMX_CLOCKPORT1 0x00000002
+#define OMX_CLOCKPORT2 0x00000004
+#define OMX_CLOCKPORT3 0x00000008
+#define OMX_CLOCKPORT4 0x00000010
+#define OMX_CLOCKPORT5 0x00000020
+#define OMX_CLOCKPORT6 0x00000040
+#define OMX_CLOCKPORT7 0x00000080
+
+/** Structure representing the current mode of the media clock. 
+ *  IL Client uses this config to change or query the mode of the 
+ *  media clock of the clock component. Applicable only to clock
+ *  component. 
+ *  
+ *  On a SetConfig if eState is OMX_TIME_ClockStateRunning media time
+ *  starts immediately at the prescribed start time. If
+ *  OMX_TIME_ClockStateWaitingForStartTime the Clock Component ignores
+ *  the given nStartTime and waits for all clients specified in the 
+ *  nWaitMask to send starttimes (via 
+ *  OMX_IndexConfigTimeClientStartTime). The Clock Component then starts 
+ *  the media clock using the earliest start time supplied. */    
+typedef struct OMX_TIME_CONFIG_CLOCKSTATETYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version 
+                                 *   information */
+    OMX_TIME_CLOCKSTATE eState; /**< State of the media time. */
+    OMX_TICKS nStartTime;       /**< Start time of the media time. */
+    OMX_TICKS nOffset;          /**< Time to offset the media time by 
+                                 * (e.g. preroll). Media time will be
+                                 * reported to be nOffset ticks earlier.     
+                                 */
+    OMX_U32 nWaitMask;          /**< Mask of OMX_CLOCKPORT values. */
+} OMX_TIME_CONFIG_CLOCKSTATETYPE;
+
+/** Structure representing the reference clock currently being used to
+ *  compute media time. IL client uses this config to change or query the 
+ *  clock component's active reference clock */
+typedef struct OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE {
+    OMX_U32 nSize;                  /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;       /**< OMX specification version information */
+    OMX_TIME_REFCLOCKTYPE eClock;   /**< Reference clock used to compute media time */                        
+} OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE;
+
+/** Descriptor for setting specifics of power type.
+ *  Note: this structure is listed for backwards compatibility. */
+typedef struct OMX_OTHER_CONFIG_POWERTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_BOOL bEnablePM;       /**< Flag to enable Power Management */
+} OMX_OTHER_CONFIG_POWERTYPE;
+
+
+/** Descriptor for setting specifics of stats type.
+ *  Note: this structure is listed for backwards compatibility. */
+typedef struct OMX_OTHER_CONFIG_STATSTYPE {
+    OMX_U32 nSize;            /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    /* what goes here */
+} OMX_OTHER_CONFIG_STATSTYPE;
+
+
+/**
+ * The PortDefinition structure is used to define all of the parameters 
+ * necessary for the compliant component to setup an input or an output other 
+ * path.
+ */
+typedef struct OMX_OTHER_PORTDEFINITIONTYPE {
+    OMX_OTHER_FORMATTYPE eFormat;  /**< Type of data expected for this channel */
+} OMX_OTHER_PORTDEFINITIONTYPE;
+
+/**  Port format parameter.  This structure is used to enumerate
+  *  the various data input/output format supported by the port.
+  */
+typedef struct OMX_OTHER_PARAM_PORTFORMATTYPE {
+    OMX_U32 nSize; /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+    OMX_U32 nPortIndex; /**< Indicates which port to set */
+    OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */
+    OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */
+} OMX_OTHER_PARAM_PORTFORMATTYPE; 
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/openmax/include/khronos/OMX_Types.h b/openmax/include/khronos/OMX_Types.h
new file mode 100755 (executable)
index 0000000..8698358
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc. 
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions: 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software. 
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ *
+ */
+
+/** OMX_Types.h - OpenMax IL version 1.1.2
+ *  The OMX_Types header file contains the primitive type definitions used by 
+ *  the core, the application and the component.  This file may need to be
+ *  modified to be used on systems that do not have "char" set to 8 bits, 
+ *  "short" set to 16 bits and "long" set to 32 bits.
+ */
+
+#ifndef OMX_Types_h
+#define OMX_Types_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** The OMX_API and OMX_APIENTRY are platform specific definitions used
+ *  to declare OMX function prototypes.  They are modified to meet the
+ *  requirements for a particular platform */
+#ifdef __SYMBIAN32__   
+#   ifdef __OMX_EXPORTS
+#       define OMX_API __declspec(dllexport)
+#   else
+#       ifdef _WIN32
+#           define OMX_API __declspec(dllexport) 
+#       else
+#           define OMX_API __declspec(dllimport)
+#       endif
+#   endif
+#else
+#   ifdef _WIN32
+#      ifdef __OMX_EXPORTS
+#          define OMX_API __declspec(dllexport)
+#      else
+#          define OMX_API __declspec(dllimport)
+#      endif
+#   else
+#      ifdef __OMX_EXPORTS
+#          define OMX_API
+#      else
+#          define OMX_API extern
+#      endif
+#   endif
+#endif
+
+#ifndef OMX_APIENTRY
+#define OMX_APIENTRY 
+#endif 
+
+/** OMX_IN is used to identify inputs to an OMX function.  This designation 
+    will also be used in the case of a pointer that points to a parameter 
+    that is used as an output. */
+#ifndef OMX_IN
+#define OMX_IN
+#endif
+
+/** OMX_OUT is used to identify outputs from an OMX function.  This 
+    designation will also be used in the case of a pointer that points 
+    to a parameter that is used as an input. */
+#ifndef OMX_OUT
+#define OMX_OUT
+#endif
+
+
+/** OMX_INOUT is used to identify parameters that may be either inputs or
+    outputs from an OMX function at the same time.  This designation will 
+    also be used in the case of a pointer that  points to a parameter that 
+    is used both as an input and an output. */
+#ifndef OMX_INOUT
+#define OMX_INOUT
+#endif
+
+/** OMX_ALL is used to as a wildcard to select all entities of the same type
+ *  when specifying the index, or referring to a object by an index.  (i.e.
+ *  use OMX_ALL to indicate all N channels). When used as a port index
+ *  for a config or parameter this OMX_ALL denotes that the config or
+ *  parameter applies to the entire component not just one port. */
+#define OMX_ALL 0xFFFFFFFF
+
+/** In the following we define groups that help building doxygen documentation */
+
+/** @defgroup core OpenMAX IL core
+ * Functions and structure related to the OMX IL core
+ */
+ /** @defgroup comp OpenMAX IL component
+ * Functions and structure related to the OMX IL component
+ */
+/** @defgroup rpm Resource and Policy Management 
+ * Structures for resource and policy management of components
+ */
+
+/** @defgroup buf Buffer Management
+ * Buffer handling functions and structures
+ */
+  
+/** @defgroup tun Tunneling
+ * @ingroup core comp
+ * Structures and functions to manage tunnels among component ports
+ */
+/** @defgroup cp Content Pipes
+ *  @ingroup core
+ */
+ /** @defgroup metadata Metadata handling
+  * 
+  */ 
+
+/** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */
+typedef unsigned char OMX_U8;
+
+/** OMX_S8 is an 8 bit signed quantity that is byte aligned */
+typedef signed char OMX_S8;
+
+/** OMX_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */
+typedef unsigned short OMX_U16;
+
+/** OMX_S16 is a 16 bit signed quantity that is 16 bit word aligned */
+typedef signed short OMX_S16;
+
+/** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */
+typedef unsigned long OMX_U32;
+
+/** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */
+typedef signed long OMX_S32;
+
+
+/* Users with compilers that cannot accept the "long long" designation should
+   define the OMX_SKIP64BIT macro.  It should be noted that this may cause 
+   some components to fail to compile if the component was written to require
+   64 bit integral types.  However, these components would NOT compile anyway
+   since the compiler does not support the way the component was written.
+*/
+#ifndef OMX_SKIP64BIT
+#ifdef __SYMBIAN32__
+/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
+typedef unsigned long long OMX_U64;
+
+/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */
+typedef signed long long OMX_S64;
+
+#elif defined(WIN32)
+
+/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */   
+typedef unsigned __int64  OMX_U64;
+
+/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */
+typedef signed   __int64  OMX_S64;
+
+#else /* WIN32 */
+
+/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
+typedef unsigned long long OMX_U64;
+
+/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */
+typedef signed long long OMX_S64;
+
+#endif /* WIN32 */
+#endif
+
+
+/** The OMX_BOOL type is intended to be used to represent a true or a false 
+    value when passing parameters to and from the OMX core and components.  The
+    OMX_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary.
+ */
+typedef enum OMX_BOOL {
+    OMX_FALSE = 0,
+    OMX_TRUE = !OMX_FALSE,
+    OMX_BOOL_MAX = 0x7FFFFFFF
+} OMX_BOOL; 
+/** The OMX_PTR type is intended to be used to pass pointers between the OMX
+    applications and the OMX Core and components.  This is a 32 bit pointer and
+    is aligned on a 32 bit boundary.
+ */
+typedef void* OMX_PTR;
+
+/** The OMX_STRING type is intended to be used to pass "C" type strings between
+    the application and the core and component.  The OMX_STRING type is a 32 
+    bit pointer to a zero terminated string.  The  pointer is word aligned and 
+    the string is byte aligned.  
+ */
+typedef char* OMX_STRING;
+
+/** The OMX_BYTE type is intended to be used to pass arrays of bytes such as
+    buffers between the application and the component and core.  The OMX_BYTE 
+    type is a 32 bit pointer to a zero terminated string.  The  pointer is word
+    aligned and the string is byte aligned.
+ */
+typedef unsigned char* OMX_BYTE;
+
+/** OMX_UUIDTYPE is a very long unique identifier to uniquely identify
+    at runtime.  This identifier should be generated by a component in a way
+    that guarantees that every instance of the identifier running on the system
+    is unique. */
+typedef unsigned char OMX_UUIDTYPE[128];
+
+/** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or
+    an output port.  This enumeration is common across all component types.    
+ */
+typedef enum OMX_DIRTYPE
+{
+    OMX_DirInput,              /**< Port is an input port */
+    OMX_DirOutput,             /**< Port is an output port */
+    OMX_DirMax = 0x7FFFFFFF
+} OMX_DIRTYPE;
+
+/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering 
+    for numerical data (i.e. big endian, or little endian).    
+ */
+typedef enum OMX_ENDIANTYPE
+{
+    OMX_EndianBig, /**< big endian */
+    OMX_EndianLittle, /**< little endian */
+    OMX_EndianMax = 0x7FFFFFFF
+} OMX_ENDIANTYPE;
+
+
+/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data 
+    is signed or unsigned
+ */
+typedef enum OMX_NUMERICALDATATYPE
+{
+    OMX_NumericalDataSigned, /**< signed data */
+    OMX_NumericalDataUnsigned, /**< unsigned data */
+    OMX_NumercialDataMax = 0x7FFFFFFF
+} OMX_NUMERICALDATATYPE;
+
+
+/** Unsigned bounded value type */
+typedef struct OMX_BU32 {
+    OMX_U32 nValue; /**< actual value */
+    OMX_U32 nMin;   /**< minimum for value (i.e. nValue >= nMin) */
+    OMX_U32 nMax;   /**< maximum for value (i.e. nValue <= nMax) */
+} OMX_BU32;
+
+
+/** Signed bounded value type */
+typedef struct OMX_BS32 {
+    OMX_S32 nValue; /**< actual value */
+    OMX_S32 nMin;   /**< minimum for value (i.e. nValue >= nMin) */
+    OMX_S32 nMax;   /**< maximum for value (i.e. nValue <= nMax) */
+} OMX_BS32;
+
+
+/** Structure representing some time or duration in microseconds. This structure
+  *  must be interpreted as a signed 64 bit value. The quantity is signed to accommodate 
+  *  negative deltas and preroll scenarios. The quantity is represented in microseconds 
+  *  to accomodate high resolution timestamps (e.g. DVD presentation timestamps based
+  *  on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g. 
+  *  individual audio samples delivered at 192 kHz). The quantity is 64 bit to 
+  *  accommodate a large dynamic range (signed 32 bit values would allow only for plus
+  *  or minus 35 minutes).
+  *
+  *  Implementations with limited precision may convert the signed 64 bit value to 
+  *  a signed 32 bit value internally but risk loss of precision.  
+  */
+#ifndef OMX_SKIP64BIT
+typedef OMX_S64 OMX_TICKS;
+#else
+typedef struct OMX_TICKS
+{
+    OMX_U32 nLowPart;    /** low bits of the signed 64 bit tick value */
+    OMX_U32 nHighPart;   /** high bits of the signed 64 bit tick value */
+} OMX_TICKS;
+#endif
+#define OMX_TICKS_PER_SECOND 1000000
+
+/** Define the public interface for the OMX Handle.  The core will not use
+    this value internally, but the application should only use this value.
+ */
+typedef void* OMX_HANDLETYPE;
+
+typedef struct OMX_MARKTYPE
+{
+    OMX_HANDLETYPE hMarkTargetComponent;   /**< The component that will 
+                                                generate a mark event upon 
+                                                processing the mark. */
+    OMX_PTR pMarkData;   /**< Application specific data associated with 
+                              the mark sent on a mark event to disambiguate 
+                              this mark from others. */
+} OMX_MARKTYPE;
+
+
+/** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the
+ *  platform & operating specific object used to reference the display 
+ *  or can be used by a audio port for native audio rendering */
+typedef void* OMX_NATIVE_DEVICETYPE;
+
+/** OMX_NATIVE_WINDOWTYPE is used to map a OMX video port to the
+ *  platform & operating specific object used to reference the window */
+typedef void* OMX_NATIVE_WINDOWTYPE;
+
+
+/** Define the OMX IL version that corresponds to this set of header files.
+ *  We also define a combined version that can be used to write or compare
+ *  values of the 32bit nVersion field, assuming a little endian architecture */
+#define OMX_VERSION_MAJOR 1
+#define OMX_VERSION_MINOR 1
+#define OMX_VERSION_REVISION 2
+#define OMX_VERSION_STEP 0
+
+#define OMX_VERSION ((OMX_VERSION_STEP<<24) | (OMX_VERSION_REVISION<<16) | (OMX_VERSION_MINOR<<8) | OMX_VERSION_MAJOR)
+
+
+/** The OMX_VERSIONTYPE union is used to specify the version for
+    a structure or component.  For a component, the version is entirely
+    specified by the component vendor.  Components doing the same function
+    from different vendors may or may not have the same version.  For 
+    structures, the version shall be set by the entity that allocates the
+    structure.  For structures specified in the OMX 1.1 specification, the
+    value of the version shall be set to 1.1.0.0 in all cases.  Access to the
+    OMX_VERSIONTYPE can be by a single 32 bit access (e.g. by nVersion) or
+    by accessing one of the structure elements to, for example, check only
+    the Major revision.
+ */
+typedef union OMX_VERSIONTYPE
+{
+    struct
+    {
+        OMX_U8 nVersionMajor;   /**< Major version accessor element */
+        OMX_U8 nVersionMinor;   /**< Minor version accessor element */
+        OMX_U8 nRevision;       /**< Revision version accessor element */
+        OMX_U8 nStep;           /**< Step version accessor element */
+    } s;
+    OMX_U32 nVersion;           /**< 32 bit value to make accessing the
+                                    version easily done in a single word
+                                    size copy/compare operation */
+} OMX_VERSIONTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/openmax/include/khronos/OMX_Video.h b/openmax/include/khronos/OMX_Video.h
new file mode 100755 (executable)
index 0000000..163e450
--- /dev/null
@@ -0,0 +1,1060 @@
+/**
+ * Copyright (c) 2008 The Khronos Group Inc. 
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions: 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software. 
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+ *
+ */
+
+/** 
+ *  @file OMX_Video.h - OpenMax IL version 1.1.2
+ *  The structures is needed by Video components to exchange parameters 
+ *  and configuration data with OMX components.
+ */
+#ifndef OMX_Video_h
+#define OMX_Video_h
+
+/** @defgroup video OpenMAX IL Video Domain
+ * @ingroup iv
+ * Structures for OpenMAX IL Video domain
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/**
+ * Each OMX header must include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully 
+ */
+
+#include <OMX_IVCommon.h>
+
+
+/**
+ * Enumeration used to define the possible video compression codings.  
+ * NOTE:  This essentially refers to file extensions. If the coding is 
+ *        being used to specify the ENCODE type, then additional work 
+ *        must be done to configure the exact flavor of the compression 
+ *        to be used.  For decode cases where the user application can 
+ *        not differentiate between MPEG-4 and H.264 bit streams, it is 
+ *        up to the codec to handle this.
+ */
+typedef enum OMX_VIDEO_CODINGTYPE {
+    OMX_VIDEO_CodingUnused,     /**< Value when coding is N/A */
+    OMX_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */
+    OMX_VIDEO_CodingMPEG2,      /**< AKA: H.262 */
+    OMX_VIDEO_CodingH263,       /**< H.263 */
+    OMX_VIDEO_CodingMPEG4,      /**< MPEG-4 */
+    OMX_VIDEO_CodingWMV,        /**< all versions of Windows Media Video */
+    OMX_VIDEO_CodingRV,         /**< all versions of Real Video */
+    OMX_VIDEO_CodingAVC,        /**< H.264/AVC */
+    OMX_VIDEO_CodingMJPEG,      /**< Motion JPEG */
+    OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_CodingMax = 0x7FFFFFFF
+} OMX_VIDEO_CODINGTYPE;
+
+
+/**
+ * Data structure used to define a video path.  The number of Video paths for 
+ * input and output will vary by type of the Video component.  
+ * 
+ *    Input (aka Source) : zero Inputs, one Output,
+ *    Splitter           : one Input, 2 or more Outputs,
+ *    Processing Element : one Input, one output,
+ *    Mixer              : 2 or more inputs, one output,
+ *    Output (aka Sink)  : one Input, zero outputs.
+ * 
+ * The PortDefinition structure is used to define all of the parameters 
+ * necessary for the compliant component to setup an input or an output video 
+ * path.  If additional vendor specific data is required, it should be 
+ * transmitted to the component using the CustomCommand function.  Compliant 
+ * components will prepopulate this structure with optimal values during the 
+ * GetDefaultInitParams command.
+ *
+ * STRUCT MEMBERS:
+ *  cMIMEType             : MIME type of data for the port
+ *  pNativeRender         : Platform specific reference for a display if a 
+ *                          sync, otherwise this field is 0
+ *  nFrameWidth           : Width of frame to be used on channel if 
+ *                          uncompressed format is used.  Use 0 for unknown,
+ *                          don't care or variable
+ *  nFrameHeight          : Height of frame to be used on channel if 
+ *                          uncompressed format is used. Use 0 for unknown,
+ *                          don't care or variable
+ *  nStride               : Number of bytes per span of an image 
+ *                          (i.e. indicates the number of bytes to get
+ *                          from span N to span N+1, where negative stride
+ *                          indicates the image is bottom up
+ *  nSliceHeight          : Height used when encoding in slices
+ *  nBitrate              : Bit rate of frame to be used on channel if 
+ *                          compressed format is used. Use 0 for unknown, 
+ *                          don't care or variable
+ *  xFramerate            : Frame rate to be used on channel if uncompressed 
+ *                          format is used. Use 0 for unknown, don't care or 
+ *                          variable.  Units are Q16 frames per second.
+ *  bFlagErrorConcealment : Turns on error concealment if it is supported by 
+ *                          the OMX component
+ *  eCompressionFormat    : Compression format used in this instance of the 
+ *                          component. When OMX_VIDEO_CodingUnused is 
+ *                          specified, eColorFormat is used
+ *  eColorFormat : Decompressed format used by this component
+ *  pNativeWindow : Platform specific reference for a window object if a 
+ *                          display sink , otherwise this field is 0x0. 
+ */
+typedef struct OMX_VIDEO_PORTDEFINITIONTYPE {
+    OMX_STRING cMIMEType;
+    OMX_NATIVE_DEVICETYPE pNativeRender;
+    OMX_U32 nFrameWidth;
+    OMX_U32 nFrameHeight;
+    OMX_S32 nStride;
+    OMX_U32 nSliceHeight;
+    OMX_U32 nBitrate;
+    OMX_U32 xFramerate;
+    OMX_BOOL bFlagErrorConcealment;
+    OMX_VIDEO_CODINGTYPE eCompressionFormat;
+    OMX_COLOR_FORMATTYPE eColorFormat;
+    OMX_NATIVE_WINDOWTYPE pNativeWindow;
+} OMX_VIDEO_PORTDEFINITIONTYPE;
+
+/**  
+ * Port format parameter.  This structure is used to enumerate the various 
+ * data input/output format supported by the port.
+ * 
+ * STRUCT MEMBERS:
+ *  nSize              : Size of the structure in bytes
+ *  nVersion           : OMX specification version information
+ *  nPortIndex         : Indicates which port to set
+ *  nIndex             : Indicates the enumeration index for the format from 
+ *                       0x0 to N-1
+ *  eCompressionFormat : Compression format used in this instance of the 
+ *                       component. When OMX_VIDEO_CodingUnused is specified, 
+ *                       eColorFormat is used 
+ *  eColorFormat       : Decompressed format used by this component
+ *  xFrameRate         : Indicates the video frame rate in Q16 format
+ */
+typedef struct OMX_VIDEO_PARAM_PORTFORMATTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nIndex;
+    OMX_VIDEO_CODINGTYPE eCompressionFormat; 
+    OMX_COLOR_FORMATTYPE eColorFormat;
+    OMX_U32 xFramerate;
+} OMX_VIDEO_PARAM_PORTFORMATTYPE;
+
+
+/**
+ * This is a structure for configuring video compression quantization 
+ * parameter values.  Codecs may support different QP values for different
+ * frame types.
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version info
+ *  nPortIndex : Port that this structure applies to
+ *  nQpI       : QP value to use for index frames
+ *  nQpP       : QP value to use for P frames
+ *  nQpB       : QP values to use for bidirectional frames 
+ */
+typedef struct OMX_VIDEO_PARAM_QUANTIZATIONTYPE {
+    OMX_U32 nSize;            
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nQpI;
+    OMX_U32 nQpP;
+    OMX_U32 nQpB;
+} OMX_VIDEO_PARAM_QUANTIZATIONTYPE;
+
+
+/** 
+ * Structure for configuration of video fast update parameters. 
+ *  
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version info 
+ *  nPortIndex : Port that this structure applies to
+ *  bEnableVFU : Enable/Disable video fast update
+ *  nFirstGOB  : Specifies the number of the first macroblock row
+ *  nFirstMB   : specifies the first MB relative to the specified first GOB
+ *  nNumMBs    : Specifies the number of MBs to be refreshed from nFirstGOB 
+ *               and nFirstMB
+ */
+typedef struct OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE {
+    OMX_U32 nSize;            
+    OMX_VERSIONTYPE nVersion; 
+    OMX_U32 nPortIndex;       
+    OMX_BOOL bEnableVFU;      
+    OMX_U32 nFirstGOB;                            
+    OMX_U32 nFirstMB;                            
+    OMX_U32 nNumMBs;                                  
+} OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE;
+
+
+/** 
+ * Enumeration of possible bitrate control types 
+ */
+typedef enum OMX_VIDEO_CONTROLRATETYPE {
+    OMX_Video_ControlRateDisable,
+    OMX_Video_ControlRateVariable,
+    OMX_Video_ControlRateConstant,
+    OMX_Video_ControlRateVariableSkipFrames,
+    OMX_Video_ControlRateConstantSkipFrames,
+    OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_Video_ControlRateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_Video_ControlRateMax = 0x7FFFFFFF
+} OMX_VIDEO_CONTROLRATETYPE;
+
+
+/** 
+ * Structure for configuring bitrate mode of a codec. 
+ *
+ * STRUCT MEMBERS:
+ *  nSize          : Size of the struct in bytes
+ *  nVersion       : OMX spec version info
+ *  nPortIndex     : Port that this struct applies to
+ *  eControlRate   : Control rate type enum
+ *  nTargetBitrate : Target bitrate to encode with
+ */
+typedef struct OMX_VIDEO_PARAM_BITRATETYPE {
+    OMX_U32 nSize;                          
+    OMX_VERSIONTYPE nVersion;               
+    OMX_U32 nPortIndex;                     
+    OMX_VIDEO_CONTROLRATETYPE eControlRate; 
+    OMX_U32 nTargetBitrate;                 
+} OMX_VIDEO_PARAM_BITRATETYPE;
+
+
+/** 
+ * Enumeration of possible motion vector (MV) types 
+ */
+typedef enum OMX_VIDEO_MOTIONVECTORTYPE {
+    OMX_Video_MotionVectorPixel,
+    OMX_Video_MotionVectorHalfPel,
+    OMX_Video_MotionVectorQuarterPel,
+    OMX_Video_MotionVectorEighthPel,
+    OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_Video_MotionVectorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_Video_MotionVectorMax = 0x7FFFFFFF
+} OMX_VIDEO_MOTIONVECTORTYPE;
+
+
+/**
+ * Structure for configuring the number of motion vectors used as well
+ * as their accuracy.
+ * 
+ * STRUCT MEMBERS:
+ *  nSize            : Size of the struct in bytes
+ *  nVersion         : OMX spec version info
+ *  nPortIndex       : port that this structure applies to
+ *  eAccuracy        : Enumerated MV accuracy
+ *  bUnrestrictedMVs : Allow unrestricted MVs
+ *  bFourMV          : Allow use of 4 MVs
+ *  sXSearchRange    : Search range in horizontal direction for MVs
+ *  sYSearchRange    : Search range in vertical direction for MVs
+ */
+typedef struct OMX_VIDEO_PARAM_MOTIONVECTORTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_MOTIONVECTORTYPE eAccuracy;
+    OMX_BOOL bUnrestrictedMVs;
+    OMX_BOOL bFourMV;
+    OMX_S32 sXSearchRange;
+    OMX_S32 sYSearchRange;
+} OMX_VIDEO_PARAM_MOTIONVECTORTYPE;
+
+
+/** 
+ * Enumeration of possible methods to use for Intra Refresh 
+ */
+typedef enum OMX_VIDEO_INTRAREFRESHTYPE {
+    OMX_VIDEO_IntraRefreshCyclic,
+    OMX_VIDEO_IntraRefreshAdaptive,
+    OMX_VIDEO_IntraRefreshBoth,
+    OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_IntraRefreshVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_IntraRefreshMax = 0x7FFFFFFF
+} OMX_VIDEO_INTRAREFRESHTYPE;
+
+
+/**
+ * Structure for configuring intra refresh mode 
+ * 
+ * STRUCT MEMBERS:
+ *  nSize        : Size of the structure in bytes
+ *  nVersion     : OMX specification version information
+ *  nPortIndex   : Port that this structure applies to
+ *  eRefreshMode : Cyclic, Adaptive, or Both
+ *  nAirMBs      : Number of intra macroblocks to refresh in a frame when 
+ *                 AIR is enabled
+ *  nAirRef      : Number of times a motion marked macroblock has to be  
+ *                 intra coded
+ *  nCirMBs      : Number of consecutive macroblocks to be coded as "intra"  
+ *                 when CIR is enabled
+ */
+typedef struct OMX_VIDEO_PARAM_INTRAREFRESHTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_INTRAREFRESHTYPE eRefreshMode;
+    OMX_U32 nAirMBs;
+    OMX_U32 nAirRef;
+    OMX_U32 nCirMBs;
+} OMX_VIDEO_PARAM_INTRAREFRESHTYPE;
+
+
+/**
+ * Structure for enabling various error correction methods for video 
+ * compression.
+ *
+ * STRUCT MEMBERS:
+ *  nSize                   : Size of the structure in bytes
+ *  nVersion                : OMX specification version information 
+ *  nPortIndex              : Port that this structure applies to 
+ *  bEnableHEC              : Enable/disable header extension codes (HEC)
+ *  bEnableResync           : Enable/disable resynchronization markers
+ *  nResynchMarkerSpacing   : Resynch markers interval (in bits) to be 
+ *                            applied in the stream 
+ *  bEnableDataPartitioning : Enable/disable data partitioning 
+ *  bEnableRVLC             : Enable/disable reversible variable length 
+ *                            coding
+ */
+typedef struct OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bEnableHEC;
+    OMX_BOOL bEnableResync;
+    OMX_U32  nResynchMarkerSpacing;
+    OMX_BOOL bEnableDataPartitioning;
+    OMX_BOOL bEnableRVLC;
+} OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE;
+
+
+/** 
+ * Configuration of variable block-size motion compensation (VBSMC) 
+ * 
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information 
+ *  nPortIndex : Port that this structure applies to
+ *  b16x16     : Enable inter block search 16x16
+ *  b16x8      : Enable inter block search 16x8
+ *  b8x16      : Enable inter block search 8x16
+ *  b8x8       : Enable inter block search 8x8
+ *  b8x4       : Enable inter block search 8x4
+ *  b4x8       : Enable inter block search 4x8
+ *  b4x4       : Enable inter block search 4x4
+ */
+typedef struct OMX_VIDEO_PARAM_VBSMCTYPE {
+    OMX_U32 nSize; 
+    OMX_VERSIONTYPE nVersion; 
+    OMX_U32 nPortIndex;       
+    OMX_BOOL b16x16; 
+    OMX_BOOL b16x8; 
+    OMX_BOOL b8x16;
+    OMX_BOOL b8x8;
+    OMX_BOOL b8x4;
+    OMX_BOOL b4x8;
+    OMX_BOOL b4x4;
+} OMX_VIDEO_PARAM_VBSMCTYPE;
+
+
+/** 
+ * H.263 profile types, each profile indicates support for various 
+ * performance bounds and different annexes.
+ *
+ * ENUMS:
+ *  Baseline           : Baseline Profile: H.263 (V1), no optional modes                                                    
+ *  H320 Coding        : H.320 Coding Efficiency Backward Compatibility 
+ *                       Profile: H.263+ (V2), includes annexes I, J, L.4
+ *                       and T
+ *  BackwardCompatible : Backward Compatibility Profile: H.263 (V1), 
+ *                       includes annex F                                    
+ *  ISWV2              : Interactive Streaming Wireless Profile: H.263+ 
+ *                       (V2), includes annexes I, J, K and T                 
+ *  ISWV3              : Interactive Streaming Wireless Profile: H.263++  
+ *                       (V3), includes profile 3 and annexes V and W.6.3.8   
+ *  HighCompression    : Conversational High Compression Profile: H.263++  
+ *                       (V3), includes profiles 1 & 2 and annexes D and U   
+ *  Internet           : Conversational Internet Profile: H.263++ (V3),  
+ *                       includes profile 5 and annex K                       
+ *  Interlace          : Conversational Interlace Profile: H.263++ (V3),  
+ *                       includes profile 5 and annex W.6.3.11               
+ *  HighLatency        : High Latency Profile: H.263++ (V3), includes  
+ *                       profile 6 and annexes O.1 and P.5                       
+ */
+typedef enum OMX_VIDEO_H263PROFILETYPE {
+    OMX_VIDEO_H263ProfileBaseline            = 0x01,        
+    OMX_VIDEO_H263ProfileH320Coding          = 0x02,          
+    OMX_VIDEO_H263ProfileBackwardCompatible  = 0x04,  
+    OMX_VIDEO_H263ProfileISWV2               = 0x08,               
+    OMX_VIDEO_H263ProfileISWV3               = 0x10,               
+    OMX_VIDEO_H263ProfileHighCompression     = 0x20,     
+    OMX_VIDEO_H263ProfileInternet            = 0x40,            
+    OMX_VIDEO_H263ProfileInterlace           = 0x80,           
+    OMX_VIDEO_H263ProfileHighLatency         = 0x100,         
+    OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_H263ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_H263ProfileMax                 = 0x7FFFFFFF  
+} OMX_VIDEO_H263PROFILETYPE;
+
+
+/** 
+ * H.263 level types, each level indicates support for various frame sizes, 
+ * bit rates, decoder frame rates.
+ */
+typedef enum OMX_VIDEO_H263LEVELTYPE {
+    OMX_VIDEO_H263Level10  = 0x01,  
+    OMX_VIDEO_H263Level20  = 0x02,      
+    OMX_VIDEO_H263Level30  = 0x04,      
+    OMX_VIDEO_H263Level40  = 0x08,      
+    OMX_VIDEO_H263Level45  = 0x10,      
+    OMX_VIDEO_H263Level50  = 0x20,      
+    OMX_VIDEO_H263Level60  = 0x40,      
+    OMX_VIDEO_H263Level70  = 0x80, 
+    OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_H263LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_H263LevelMax = 0x7FFFFFFF  
+} OMX_VIDEO_H263LEVELTYPE;
+
+
+/** 
+ * Specifies the picture type. These values should be OR'd to signal all 
+ * pictures types which are allowed.
+ *
+ * ENUMS:
+ *  Generic Picture Types:          I, P and B
+ *  H.263 Specific Picture Types:   SI and SP
+ *  H.264 Specific Picture Types:   EI and EP
+ *  MPEG-4 Specific Picture Types:  S
+ */
+typedef enum OMX_VIDEO_PICTURETYPE {
+    OMX_VIDEO_PictureTypeI   = 0x01,
+    OMX_VIDEO_PictureTypeP   = 0x02,
+    OMX_VIDEO_PictureTypeB   = 0x04,
+    OMX_VIDEO_PictureTypeSI  = 0x08,
+    OMX_VIDEO_PictureTypeSP  = 0x10,
+    OMX_VIDEO_PictureTypeEI  = 0x11,
+    OMX_VIDEO_PictureTypeEP  = 0x12,
+    OMX_VIDEO_PictureTypeS   = 0x14,
+    OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_PictureTypeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_PictureTypeMax = 0x7FFFFFFF
+} OMX_VIDEO_PICTURETYPE;
+
+
+/** 
+ * H.263 Params 
+ *
+ * STRUCT MEMBERS:
+ *  nSize                    : Size of the structure in bytes
+ *  nVersion                 : OMX specification version information 
+ *  nPortIndex               : Port that this structure applies to
+ *  nPFrames                 : Number of P frames between each I frame
+ *  nBFrames                 : Number of B frames between each I frame
+ *  eProfile                 : H.263 profile(s) to use
+ *  eLevel                   : H.263 level(s) to use
+ *  bPLUSPTYPEAllowed        : Indicating that it is allowed to use PLUSPTYPE 
+ *                             (specified in the 1998 version of H.263) to 
+ *                             indicate custom picture sizes or clock 
+ *                             frequencies 
+ *  nAllowedPictureTypes     : Specifies the picture types allowed in the 
+ *                             bitstream
+ *  bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is 
+ *                             not constrained. It is recommended to change 
+ *                             the value of the RTYPE bit for each reference 
+ *                             picture in error-free communication
+ *  nPictureHeaderRepetition : Specifies the frequency of picture header 
+ *                             repetition
+ *  nGOBHeaderInterval       : Specifies the interval of non-empty GOB  
+ *                             headers in units of GOBs
+ */
+typedef struct OMX_VIDEO_PARAM_H263TYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nPFrames;
+    OMX_U32 nBFrames;
+    OMX_VIDEO_H263PROFILETYPE eProfile;
+       OMX_VIDEO_H263LEVELTYPE eLevel;
+    OMX_BOOL bPLUSPTYPEAllowed;
+    OMX_U32 nAllowedPictureTypes;
+    OMX_BOOL bForceRoundingTypeToZero;
+    OMX_U32 nPictureHeaderRepetition;
+    OMX_U32 nGOBHeaderInterval;
+} OMX_VIDEO_PARAM_H263TYPE;
+
+
+/** 
+ * MPEG-2 profile types, each profile indicates support for various 
+ * performance bounds and different annexes.
+ */
+typedef enum OMX_VIDEO_MPEG2PROFILETYPE {
+    OMX_VIDEO_MPEG2ProfileSimple = 0,  /**< Simple Profile */
+    OMX_VIDEO_MPEG2ProfileMain,        /**< Main Profile */
+    OMX_VIDEO_MPEG2Profile422,         /**< 4:2:2 Profile */
+    OMX_VIDEO_MPEG2ProfileSNR,         /**< SNR Profile */
+    OMX_VIDEO_MPEG2ProfileSpatial,     /**< Spatial Profile */
+    OMX_VIDEO_MPEG2ProfileHigh,        /**< High Profile */
+    OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_MPEG2ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF  
+} OMX_VIDEO_MPEG2PROFILETYPE;
+
+
+/** 
+ * MPEG-2 level types, each level indicates support for various frame 
+ * sizes, bit rates, decoder frame rates.  No need 
+ */
+typedef enum OMX_VIDEO_MPEG2LEVELTYPE {
+    OMX_VIDEO_MPEG2LevelLL = 0,  /**< Low Level */ 
+    OMX_VIDEO_MPEG2LevelML,      /**< Main Level */ 
+    OMX_VIDEO_MPEG2LevelH14,     /**< High 1440 */ 
+    OMX_VIDEO_MPEG2LevelHL,      /**< High Level */   
+    OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_MPEG2LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF  
+} OMX_VIDEO_MPEG2LEVELTYPE;
+
+
+/** 
+ * MPEG-2 params 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nPFrames   : Number of P frames between each I frame
+ *  nBFrames   : Number of B frames between each I frame
+ *  eProfile   : MPEG-2 profile(s) to use
+ *  eLevel     : MPEG-2 levels(s) to use
+ */
+typedef struct OMX_VIDEO_PARAM_MPEG2TYPE {
+    OMX_U32 nSize;           
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;      
+    OMX_U32 nPFrames;        
+    OMX_U32 nBFrames;        
+    OMX_VIDEO_MPEG2PROFILETYPE eProfile;
+       OMX_VIDEO_MPEG2LEVELTYPE eLevel;   
+} OMX_VIDEO_PARAM_MPEG2TYPE;
+
+
+/** 
+ * MPEG-4 profile types, each profile indicates support for various 
+ * performance bounds and different annexes.
+ * 
+ * ENUMS:
+ *  - Simple Profile, Levels 1-3
+ *  - Simple Scalable Profile, Levels 1-2
+ *  - Core Profile, Levels 1-2
+ *  - Main Profile, Levels 2-4
+ *  - N-bit Profile, Level 2
+ *  - Scalable Texture Profile, Level 1
+ *  - Simple Face Animation Profile, Levels 1-2
+ *  - Simple Face and Body Animation (FBA) Profile, Levels 1-2
+ *  - Basic Animated Texture Profile, Levels 1-2
+ *  - Hybrid Profile, Levels 1-2
+ *  - Advanced Real Time Simple Profiles, Levels 1-4
+ *  - Core Scalable Profile, Levels 1-3
+ *  - Advanced Coding Efficiency Profile, Levels 1-4
+ *  - Advanced Core Profile, Levels 1-2
+ *  - Advanced Scalable Texture, Levels 2-3
+ */
+typedef enum OMX_VIDEO_MPEG4PROFILETYPE {
+    OMX_VIDEO_MPEG4ProfileSimple           = 0x01,        
+    OMX_VIDEO_MPEG4ProfileSimpleScalable   = 0x02,    
+    OMX_VIDEO_MPEG4ProfileCore             = 0x04,              
+    OMX_VIDEO_MPEG4ProfileMain             = 0x08,             
+    OMX_VIDEO_MPEG4ProfileNbit             = 0x10,              
+    OMX_VIDEO_MPEG4ProfileScalableTexture  = 0x20,   
+    OMX_VIDEO_MPEG4ProfileSimpleFace       = 0x40,        
+    OMX_VIDEO_MPEG4ProfileSimpleFBA        = 0x80,         
+    OMX_VIDEO_MPEG4ProfileBasicAnimated    = 0x100,     
+    OMX_VIDEO_MPEG4ProfileHybrid           = 0x200,            
+    OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400,  
+    OMX_VIDEO_MPEG4ProfileCoreScalable     = 0x800,      
+    OMX_VIDEO_MPEG4ProfileAdvancedCoding   = 0x1000,    
+    OMX_VIDEO_MPEG4ProfileAdvancedCore     = 0x2000,      
+    OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000,
+    OMX_VIDEO_MPEG4ProfileAdvancedSimple   = 0x8000,
+    OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_MPEG4ProfileMax              = 0x7FFFFFFF  
+} OMX_VIDEO_MPEG4PROFILETYPE;
+
+
+/** 
+ * MPEG-4 level types, each level indicates support for various frame 
+ * sizes, bit rates, decoder frame rates.  No need 
+ */
+typedef enum OMX_VIDEO_MPEG4LEVELTYPE {
+    OMX_VIDEO_MPEG4Level0  = 0x01,   /**< Level 0 */   
+    OMX_VIDEO_MPEG4Level0b = 0x02,   /**< Level 0b */   
+    OMX_VIDEO_MPEG4Level1  = 0x04,   /**< Level 1 */ 
+    OMX_VIDEO_MPEG4Level2  = 0x08,   /**< Level 2 */ 
+    OMX_VIDEO_MPEG4Level3  = 0x10,   /**< Level 3 */ 
+    OMX_VIDEO_MPEG4Level4  = 0x20,   /**< Level 4 */  
+    OMX_VIDEO_MPEG4Level4a = 0x40,   /**< Level 4a */  
+    OMX_VIDEO_MPEG4Level5  = 0x80,   /**< Level 5 */  
+    OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF  
+} OMX_VIDEO_MPEG4LEVELTYPE;
+
+
+/** 
+ * MPEG-4 configuration.  This structure handles configuration options
+ * which are specific to MPEG4 algorithms
+ *
+ * STRUCT MEMBERS:
+ *  nSize                : Size of the structure in bytes
+ *  nVersion             : OMX specification version information
+ *  nPortIndex           : Port that this structure applies to
+ *  nSliceHeaderSpacing  : Number of macroblocks between slice header (H263+ 
+ *                         Annex K). Put zero if not used
+ *  bSVH                 : Enable Short Video Header mode
+ *  bGov                 : Flag to enable GOV
+ *  nPFrames             : Number of P frames between each I frame (also called 
+ *                         GOV period)
+ *  nBFrames             : Number of B frames between each I frame
+ *  nIDCVLCThreshold     : Value of intra DC VLC threshold
+ *  bACPred              : Flag to use ac prediction
+ *  nMaxPacketSize       : Maximum size of packet in bytes.
+ *  nTimeIncRes          : Used to pass VOP time increment resolution for MPEG4. 
+ *                         Interpreted as described in MPEG4 standard.
+ *  eProfile             : MPEG-4 profile(s) to use.
+ *  eLevel               : MPEG-4 level(s) to use.
+ *  nAllowedPictureTypes : Specifies the picture types allowed in the bitstream
+ *  nHeaderExtension     : Specifies the number of consecutive video packet
+ *                         headers within a VOP
+ *  bReversibleVLC       : Specifies whether reversible variable length coding 
+ *                         is in use
+ */
+typedef struct OMX_VIDEO_PARAM_MPEG4TYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nSliceHeaderSpacing;
+    OMX_BOOL bSVH;
+    OMX_BOOL bGov;
+    OMX_U32 nPFrames;
+    OMX_U32 nBFrames;
+    OMX_U32 nIDCVLCThreshold;
+    OMX_BOOL bACPred;
+    OMX_U32 nMaxPacketSize;
+    OMX_U32 nTimeIncRes;
+    OMX_VIDEO_MPEG4PROFILETYPE eProfile;
+    OMX_VIDEO_MPEG4LEVELTYPE eLevel;
+    OMX_U32 nAllowedPictureTypes;
+    OMX_U32 nHeaderExtension;
+    OMX_BOOL bReversibleVLC;
+} OMX_VIDEO_PARAM_MPEG4TYPE;
+
+
+/** 
+ * WMV Versions 
+ */
+typedef enum OMX_VIDEO_WMVFORMATTYPE {
+    OMX_VIDEO_WMVFormatUnused = 0x01,   /**< Format unused or unknown */
+    OMX_VIDEO_WMVFormat7      = 0x02,   /**< Windows Media Video format 7 */
+    OMX_VIDEO_WMVFormat8      = 0x04,   /**< Windows Media Video format 8 */
+    OMX_VIDEO_WMVFormat9      = 0x08,   /**< Windows Media Video format 9 */
+    OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_WMFFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_WMVFormatMax    = 0x7FFFFFFF
+} OMX_VIDEO_WMVFORMATTYPE;
+
+
+/** 
+ * WMV Params 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  eFormat    : Version of WMV stream / data
+ */
+typedef struct OMX_VIDEO_PARAM_WMVTYPE {
+    OMX_U32 nSize; 
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_WMVFORMATTYPE eFormat;
+} OMX_VIDEO_PARAM_WMVTYPE;
+
+
+/** 
+ * Real Video Version 
+ */
+typedef enum OMX_VIDEO_RVFORMATTYPE {
+    OMX_VIDEO_RVFormatUnused = 0, /**< Format unused or unknown */
+    OMX_VIDEO_RVFormat8,          /**< Real Video format 8 */
+    OMX_VIDEO_RVFormat9,          /**< Real Video format 9 */
+    OMX_VIDEO_RVFormatG2,         /**< Real Video Format G2 */
+    OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_RVFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_RVFormatMax = 0x7FFFFFFF
+} OMX_VIDEO_RVFORMATTYPE;
+
+
+/** 
+ * Real Video Params 
+ *
+ * STUCT MEMBERS:
+ *  nSize              : Size of the structure in bytes
+ *  nVersion           : OMX specification version information 
+ *  nPortIndex         : Port that this structure applies to
+ *  eFormat            : Version of RV stream / data
+ *  nBitsPerPixel      : Bits per pixel coded in the frame
+ *  nPaddedWidth       : Padded width in pixel of a video frame
+ *  nPaddedHeight      : Padded Height in pixels of a video frame
+ *  nFrameRate         : Rate of video in frames per second
+ *  nBitstreamFlags    : Flags which internal information about the bitstream
+ *  nBitstreamVersion  : Bitstream version
+ *  nMaxEncodeFrameSize: Max encoded frame size
+ *  bEnablePostFilter  : Turn on/off post filter
+ *  bEnableTemporalInterpolation : Turn on/off temporal interpolation
+ *  bEnableLatencyMode : When enabled, the decoder does not display a decoded 
+ *                       frame until it has detected that no enhancement layer 
+ *                                      frames or dependent B frames will be coming. This 
+ *                                      detection usually occurs when a subsequent non-B 
+ *                                      frame is encountered 
+ */
+typedef struct OMX_VIDEO_PARAM_RVTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_RVFORMATTYPE eFormat;
+    OMX_U16 nBitsPerPixel;
+    OMX_U16 nPaddedWidth;
+    OMX_U16 nPaddedHeight;
+    OMX_U32 nFrameRate;
+    OMX_U32 nBitstreamFlags;
+    OMX_U32 nBitstreamVersion;
+    OMX_U32 nMaxEncodeFrameSize;
+    OMX_BOOL bEnablePostFilter;
+    OMX_BOOL bEnableTemporalInterpolation;
+    OMX_BOOL bEnableLatencyMode;
+} OMX_VIDEO_PARAM_RVTYPE;
+
+
+/** 
+ * AVC profile types, each profile indicates support for various 
+ * performance bounds and different annexes.
+ */
+typedef enum OMX_VIDEO_AVCPROFILETYPE {
+    OMX_VIDEO_AVCProfileBaseline = 0x01,   /**< Baseline profile */
+    OMX_VIDEO_AVCProfileMain     = 0x02,   /**< Main profile */
+    OMX_VIDEO_AVCProfileExtended = 0x04,   /**< Extended profile */
+    OMX_VIDEO_AVCProfileHigh     = 0x08,   /**< High profile */
+    OMX_VIDEO_AVCProfileHigh10   = 0x10,   /**< High 10 profile */
+    OMX_VIDEO_AVCProfileHigh422  = 0x20,   /**< High 4:2:2 profile */
+    OMX_VIDEO_AVCProfileHigh444  = 0x40,   /**< High 4:4:4 profile */
+    OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_AVCProfileMax      = 0x7FFFFFFF  
+} OMX_VIDEO_AVCPROFILETYPE;
+
+
+/** 
+ * AVC level types, each level indicates support for various frame sizes, 
+ * bit rates, decoder frame rates.  No need 
+ */
+typedef enum OMX_VIDEO_AVCLEVELTYPE {
+    OMX_VIDEO_AVCLevel1   = 0x01,     /**< Level 1 */
+    OMX_VIDEO_AVCLevel1b  = 0x02,     /**< Level 1b */
+    OMX_VIDEO_AVCLevel11  = 0x04,     /**< Level 1.1 */
+    OMX_VIDEO_AVCLevel12  = 0x08,     /**< Level 1.2 */
+    OMX_VIDEO_AVCLevel13  = 0x10,     /**< Level 1.3 */
+    OMX_VIDEO_AVCLevel2   = 0x20,     /**< Level 2 */
+    OMX_VIDEO_AVCLevel21  = 0x40,     /**< Level 2.1 */
+    OMX_VIDEO_AVCLevel22  = 0x80,     /**< Level 2.2 */
+    OMX_VIDEO_AVCLevel3   = 0x100,    /**< Level 3 */
+    OMX_VIDEO_AVCLevel31  = 0x200,    /**< Level 3.1 */
+    OMX_VIDEO_AVCLevel32  = 0x400,    /**< Level 3.2 */
+    OMX_VIDEO_AVCLevel4   = 0x800,    /**< Level 4 */
+    OMX_VIDEO_AVCLevel41  = 0x1000,   /**< Level 4.1 */
+    OMX_VIDEO_AVCLevel42  = 0x2000,   /**< Level 4.2 */
+    OMX_VIDEO_AVCLevel5   = 0x4000,   /**< Level 5 */
+    OMX_VIDEO_AVCLevel51  = 0x8000,   /**< Level 5.1 */
+    OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF  
+} OMX_VIDEO_AVCLEVELTYPE;
+
+
+/** 
+ * AVC loop filter modes 
+ *
+ * OMX_VIDEO_AVCLoopFilterEnable               : Enable
+ * OMX_VIDEO_AVCLoopFilterDisable              : Disable
+ * OMX_VIDEO_AVCLoopFilterDisableSliceBoundary : Disabled on slice boundaries
+ */
+typedef enum OMX_VIDEO_AVCLOOPFILTERTYPE {
+    OMX_VIDEO_AVCLoopFilterEnable = 0,
+    OMX_VIDEO_AVCLoopFilterDisable,
+    OMX_VIDEO_AVCLoopFilterDisableSliceBoundary,
+    OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_AVCLoopFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_AVCLoopFilterMax = 0x7FFFFFFF
+} OMX_VIDEO_AVCLOOPFILTERTYPE;
+
+
+/** 
+ * AVC params 
+ *
+ * STRUCT MEMBERS:
+ *  nSize                     : Size of the structure in bytes
+ *  nVersion                  : OMX specification version information
+ *  nPortIndex                : Port that this structure applies to
+ *  nSliceHeaderSpacing       : Number of macroblocks between slice header, put  
+ *                              zero if not used
+ *  nPFrames                  : Number of P frames between each I frame
+ *  nBFrames                  : Number of B frames between each I frame
+ *  bUseHadamard              : Enable/disable Hadamard transform
+ *  nRefFrames                : Max number of reference frames to use for inter
+ *                              motion search (1-16)
+ *  nRefIdxTrailing           : Pic param set ref frame index (index into ref
+ *                              frame buffer of trailing frames list), B frame
+ *                              support
+ *  nRefIdxForward            : Pic param set ref frame index (index into ref
+ *                              frame buffer of forward frames list), B frame
+ *                              support
+ *  bEnableUEP                : Enable/disable unequal error protection. This 
+ *                              is only valid of data partitioning is enabled.
+ *  bEnableFMO                : Enable/disable flexible macroblock ordering
+ *  bEnableASO                : Enable/disable arbitrary slice ordering
+ *  bEnableRS                 : Enable/disable sending of redundant slices
+ *  eProfile                  : AVC profile(s) to use
+ *  eLevel                    : AVC level(s) to use
+ *  nAllowedPictureTypes      : Specifies the picture types allowed in the 
+ *                              bitstream
+ *  bFrameMBsOnly             : specifies that every coded picture of the 
+ *                              coded video sequence is a coded frame 
+ *                              containing only frame macroblocks
+ *  bMBAFF                    : Enable/disable switching between frame and 
+ *                              field macroblocks within a picture
+ *  bEntropyCodingCABAC       : Entropy decoding method to be applied for the 
+ *                              syntax elements for which two descriptors appear 
+ *                              in the syntax tables
+ *  bWeightedPPrediction      : Enable/disable weighted prediction shall not 
+ *                              be applied to P and SP slices
+ *  nWeightedBipredicitonMode : Default weighted prediction is applied to B 
+ *                              slices 
+ *  bconstIpred               : Enable/disable intra prediction
+ *  bDirect8x8Inference       : Specifies the method used in the derivation 
+ *                              process for luma motion vectors for B_Skip, 
+ *                              B_Direct_16x16 and B_Direct_8x8 as specified 
+ *                              in subclause 8.4.1.2 of the AVC spec 
+ *  bDirectSpatialTemporal    : Flag indicating spatial or temporal direct
+ *                              mode used in B slice coding (related to 
+ *                              bDirect8x8Inference) . Spatial direct mode is 
+ *                              more common and should be the default.
+ *  nCabacInitIdx             : Index used to init CABAC contexts
+ *  eLoopFilterMode           : Enable/disable loop filter
+ */
+typedef struct OMX_VIDEO_PARAM_AVCTYPE {
+    OMX_U32 nSize;                 
+    OMX_VERSIONTYPE nVersion;      
+    OMX_U32 nPortIndex;            
+    OMX_U32 nSliceHeaderSpacing;  
+    OMX_U32 nPFrames;     
+    OMX_U32 nBFrames;     
+    OMX_BOOL bUseHadamard;
+    OMX_U32 nRefFrames;  
+       OMX_U32 nRefIdx10ActiveMinus1;
+       OMX_U32 nRefIdx11ActiveMinus1;
+    OMX_BOOL bEnableUEP;  
+    OMX_BOOL bEnableFMO;  
+    OMX_BOOL bEnableASO;  
+    OMX_BOOL bEnableRS;   
+    OMX_VIDEO_AVCPROFILETYPE eProfile;
+       OMX_VIDEO_AVCLEVELTYPE eLevel; 
+    OMX_U32 nAllowedPictureTypes;  
+       OMX_BOOL bFrameMBsOnly;                                                                         
+    OMX_BOOL bMBAFF;               
+    OMX_BOOL bEntropyCodingCABAC;  
+    OMX_BOOL bWeightedPPrediction; 
+    OMX_U32 nWeightedBipredicitonMode; 
+    OMX_BOOL bconstIpred ;
+    OMX_BOOL bDirect8x8Inference;  
+       OMX_BOOL bDirectSpatialTemporal;
+       OMX_U32 nCabacInitIdc;
+       OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode;
+} OMX_VIDEO_PARAM_AVCTYPE;
+
+typedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE {
+   OMX_U32 nSize;                 
+   OMX_VERSIONTYPE nVersion;      
+   OMX_U32 nPortIndex;            
+   OMX_U32 eProfile;      /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE, 
+                                 or OMX_VIDEO_MPEG4PROFILETYPE depending on context */
+   OMX_U32 eLevel;        /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE, 
+                                 or OMX_VIDEO_MPEG4PROFILETYPE depending on context */
+   OMX_U32 nProfileIndex; /**< Used to query for individual profile support information,
+                               This parameter is valid only for 
+                               OMX_IndexParamVideoProfileLevelQuerySupported index,
+                               For all other indices this parameter is to be ignored. */
+} OMX_VIDEO_PARAM_PROFILELEVELTYPE;
+
+/** 
+ * Structure for dynamically configuring bitrate mode of a codec. 
+ *
+ * STRUCT MEMBERS:
+ *  nSize          : Size of the struct in bytes
+ *  nVersion       : OMX spec version info
+ *  nPortIndex     : Port that this struct applies to
+ *  nEncodeBitrate : Target average bitrate to be generated in bps
+ */
+typedef struct OMX_VIDEO_CONFIG_BITRATETYPE {
+    OMX_U32 nSize;                          
+    OMX_VERSIONTYPE nVersion;               
+    OMX_U32 nPortIndex;                     
+    OMX_U32 nEncodeBitrate;                 
+} OMX_VIDEO_CONFIG_BITRATETYPE;
+
+/** 
+ * Defines Encoder Frame Rate setting
+ *
+ * STRUCT MEMBERS:
+ *  nSize            : Size of the structure in bytes
+ *  nVersion         : OMX specification version information 
+ *  nPortIndex       : Port that this structure applies to
+ *  xEncodeFramerate : Encoding framerate represented in Q16 format
+ */
+typedef struct OMX_CONFIG_FRAMERATETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 xEncodeFramerate; /* Q16 format */
+} OMX_CONFIG_FRAMERATETYPE;
+
+typedef struct OMX_CONFIG_INTRAREFRESHVOPTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL IntraRefreshVOP;
+} OMX_CONFIG_INTRAREFRESHVOPTYPE;
+
+typedef struct OMX_CONFIG_MACROBLOCKERRORMAPTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nErrMapSize;           /* Size of the Error Map in bytes */
+    OMX_U8  ErrMap[1];             /* Error map hint */
+} OMX_CONFIG_MACROBLOCKERRORMAPTYPE;
+
+typedef struct OMX_CONFIG_MBERRORREPORTINGTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bEnabled;
+} OMX_CONFIG_MBERRORREPORTINGTYPE;
+
+typedef struct OMX_PARAM_MACROBLOCKSTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nMacroblocks;
+} OMX_PARAM_MACROBLOCKSTYPE;
+
+/** 
+ * AVC Slice Mode modes 
+ *
+ * OMX_VIDEO_SLICEMODE_AVCDefault   : Normal frame encoding, one slice per frame
+ * OMX_VIDEO_SLICEMODE_AVCMBSlice   : NAL mode, number of MBs per frame
+ * OMX_VIDEO_SLICEMODE_AVCByteSlice : NAL mode, number of bytes per frame
+ */
+typedef enum OMX_VIDEO_AVCSLICEMODETYPE {
+    OMX_VIDEO_SLICEMODE_AVCDefault = 0,
+    OMX_VIDEO_SLICEMODE_AVCMBSlice,
+    OMX_VIDEO_SLICEMODE_AVCByteSlice,
+    OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
+    OMX_VIDEO_SLICEMODE_AVCVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+    OMX_VIDEO_SLICEMODE_AVCLevelMax = 0x7FFFFFFF
+} OMX_VIDEO_AVCSLICEMODETYPE;
+
+/** 
+ * AVC FMO Slice Mode Params 
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nNumSliceGroups : Specifies the number of slice groups
+ *  nSliceGroupMapType : Specifies the type of slice groups
+ *  eSliceMode : Specifies the type of slice
+ */
+typedef struct OMX_VIDEO_PARAM_AVCSLICEFMO {
+    OMX_U32 nSize; 
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U8 nNumSliceGroups;
+    OMX_U8 nSliceGroupMapType;
+    OMX_VIDEO_AVCSLICEMODETYPE eSliceMode;
+} OMX_VIDEO_PARAM_AVCSLICEFMO;
+
+/** 
+ * AVC IDR Period Configs
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nIDRPeriod : Specifies periodicity of IDR frames
+ *  nPFrames : Specifies internal of coding Intra frames
+ */
+typedef struct OMX_VIDEO_CONFIG_AVCINTRAPERIOD {
+    OMX_U32 nSize; 
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nIDRPeriod;
+    OMX_U32 nPFrames;
+} OMX_VIDEO_CONFIG_AVCINTRAPERIOD;
+
+/** 
+ * AVC NAL Size Configs
+ *
+ * STRUCT MEMBERS:
+ *  nSize      : Size of the structure in bytes
+ *  nVersion   : OMX specification version information
+ *  nPortIndex : Port that this structure applies to
+ *  nNaluBytes : Specifies the NAL unit size
+ */
+typedef struct OMX_VIDEO_CONFIG_NALSIZE {
+    OMX_U32 nSize; 
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nNaluBytes;
+} OMX_VIDEO_CONFIG_NALSIZE;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
+
diff --git a/openmax/include/khronos/OMX_VideoExt.h b/openmax/include/khronos/OMX_VideoExt.h
new file mode 100755 (executable)
index 0000000..c5a338a
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2010 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_VideoExt.h - OpenMax IL version 1.1.2
+ * The OMX_VideoExt header file contains extensions to the
+ * definitions used by both the application and the component to
+ * access video items.
+ */
+
+#ifndef OMX_VideoExt_h
+#define OMX_VideoExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Core.h>
+
+/** NALU Formats */
+typedef enum OMX_NALUFORMATSTYPE {
+    OMX_NaluFormatStartCodes = 1,
+    OMX_NaluFormatOneNaluPerBuffer = 2,
+    OMX_NaluFormatOneByteInterleaveLength = 4,
+    OMX_NaluFormatTwoByteInterleaveLength = 8,
+    OMX_NaluFormatFourByteInterleaveLength = 16,
+    OMX_NaluFormatCodingMax = 0x7FFFFFFF
+} OMX_NALUFORMATSTYPE;
+
+/** NAL Stream Format */
+typedef struct OMX_NALSTREAMFORMATTYPE{
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_NALUFORMATSTYPE eNaluFormat;
+} OMX_NALSTREAMFORMATTYPE;
+
+/** Enum for standard video codingtype extensions */
+typedef enum OMX_VIDEO_CODINGEXTTYPE {
+    OMX_VIDEO_ExtCodingUnused = OMX_VIDEO_CodingKhronosExtensions,
+    OMX_VIDEO_CodingVP8,        /**< VP8/WebM */ 
+} OMX_VIDEO_CODINGEXTTYPE;
+
+/** VP8 profiles */
+typedef enum OMX_VIDEO_VP8PROFILETYPE {
+    OMX_VIDEO_VP8ProfileMain = 0x01,
+    OMX_VIDEO_VP8ProfileUnknown = 0x6EFFFFFF,
+    OMX_VIDEO_VP8ProfileMax = 0x7FFFFFFF
+} OMX_VIDEO_VP8PROFILETYPE;
+
+/** VP8 levels */
+typedef enum OMX_VIDEO_VP8LEVELTYPE {
+    OMX_VIDEO_VP8Level_Version0 = 0x01,
+    OMX_VIDEO_VP8Level_Version1 = 0x02,
+    OMX_VIDEO_VP8Level_Version2 = 0x04,
+    OMX_VIDEO_VP8Level_Version3 = 0x08,
+    OMX_VIDEO_VP8LevelUnknown = 0x6EFFFFFF,
+    OMX_VIDEO_VP8LevelMax = 0x7FFFFFFF
+} OMX_VIDEO_VP8LEVELTYPE;
+
+/** VP8 Param */
+typedef struct OMX_VIDEO_PARAM_VP8TYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_VP8PROFILETYPE eProfile;
+    OMX_VIDEO_VP8LEVELTYPE eLevel;
+    OMX_U32 nDCTPartitions;
+    OMX_BOOL bErrorResilientMode;
+} OMX_VIDEO_PARAM_VP8TYPE;
+
+/** Structure for configuring VP8 reference frames */
+typedef struct OMX_VIDEO_VP8REFERENCEFRAMETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bPreviousFrameRefresh;
+    OMX_BOOL bGoldenFrameRefresh;
+    OMX_BOOL bAlternateFrameRefresh;
+    OMX_BOOL bUsePreviousFrame;
+    OMX_BOOL bUseGoldenFrame;
+    OMX_BOOL bUseAlternateFrame;
+} OMX_VIDEO_VP8REFERENCEFRAMETYPE;
+
+/** Structure for querying VP8 reference frame type */
+typedef struct OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_BOOL bIsIntraFrame;
+    OMX_BOOL bIsGoldenOrAlternateFrame;
+} OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_VideoExt_h */
+/* File EOF */
diff --git a/openmax/include/skype/OMX_Video_Extensions.h b/openmax/include/skype/OMX_Video_Extensions.h
new file mode 100755 (executable)
index 0000000..eef2193
--- /dev/null
@@ -0,0 +1,187 @@
+/*@@@+++@@@@******************************************************************
+
+ Microsoft Skype Engineering
+ Copyright (C) 2014 Microsoft Corporation. 
+
+MIT License 
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+*@@@---@@@@******************************************************************/
+
+
+#ifndef __OMX_VIDEO_EXTENSIONS_H__
+#define __OMX_VIDEO_EXTENSIONS_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <OMX_Core.h>
+#define OMX_VIDEO_MajorVersion 2
+#define OMX_VIDEO_MinorVersion 0
+#pragma pack(push, 1)
+
+typedef enum OMX_VIDEO_SliceControlMode
+{
+    OMX_VIDEO_SliceControlModeNone        = 0,
+    OMX_VIDEO_SliceControlModeMB          = 1,
+    OMX_VIDEO_SliceControlModeByte        = 2,
+    OMX_VIDEO_SliceControlModMBRow        = 3,
+} OMX_VIDEO_SliceControlMode;
+
+typedef enum OMX_VIDEO_DownScaleFactor
+{
+    OMX_VIDEO_DownScaleFactor_1_1         = 0,
+    OMX_VIDEO_DownScaleFactor_Equal_AR    = 1,
+    OMX_VIDEO_DownScaleFactor_Any         = 2,
+} OMX_VIDEO_DownScaleFactor;
+
+typedef enum OMX_VIDEO_HierarType
+{
+    OMX_VIDEO_HierarType_P                = 0x01,
+    OMX_VIDEO_HierarType_B                = 0x02,
+} OMX_VIDEO_HierarType;
+
+typedef enum OMX_VIDEO_EXTENSION_AVCPROFILETYPE
+{
+    OMX_VIDEO_EXT_AVCProfileConstrainedBaseline = 0x01,
+    OMX_VIDEO_EXT_AVCProfileConstrainedHigh     = 0x02,
+} OMX_VIDEO_EXTENSION_AVCPROFILETYPE;
+
+typedef struct OMX_VIDEO_ENCODERPARAMS {
+    OMX_BOOL bLowLatency;
+    OMX_BOOL bUseExtendedProfile;
+    OMX_BOOL bSequenceHeaderWithIDR;
+    OMX_VIDEO_EXTENSION_AVCPROFILETYPE eProfile;
+    OMX_U32 nLTRFrames;
+    OMX_VIDEO_HierarType eHierarType;
+    OMX_U32 nMaxTemporalLayerCount;
+    OMX_VIDEO_SliceControlMode eSliceControlMode;
+    OMX_U32 nSarIndex;
+    OMX_U32 nSarWidth;
+    OMX_U32 nSarHeight;
+} OMX_VIDEO_ENCODERPARAMS;
+
+typedef struct OMX_VIDEO_ENCODERCAP {
+    OMX_BOOL bLowLatency;
+    OMX_U32 nMaxFrameWidth;
+    OMX_U32 nMaxFrameHeight;
+    OMX_U32 nMaxInstances;
+    OMX_U32 nMaxTemporaLayerCount;
+    OMX_U32 nMaxRefFrames;
+    OMX_U32 nMaxLTRFrames;
+    OMX_VIDEO_AVCLEVELTYPE nMaxLevel;
+    OMX_U32 nSliceControlModesBM;
+    OMX_U32 nMaxMacroblockProcessingRate;
+    OMX_VIDEO_DownScaleFactor nResize;
+    OMX_U32 xMinScaleFactor;
+} OMX_VIDEO_ENCODERCAP;
+
+typedef struct OMX_VIDEO_PARAM_ENCODERSETTING {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_ENCODERPARAMS stEncParam;
+} OMX_VIDEO_PARAM_ENCODERSETTING;
+
+typedef struct OMX_VIDEO_PARAM_ENCODERCAP {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_ENCODERCAP stEncCap;
+} OMX_VIDEO_PARAM_ENCODERCAP;
+
+typedef struct OMX_VIDEO_CONFIG_MARKLTRFRAME {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nLongTermFrmIdx;
+} OMX_VIDEO_CONFIG_MARKLTRFRAME;
+
+typedef struct OMX_VIDEO_CONFIG_USELTRFRAME {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U16 nUsedLTRFrameBM;
+} OMX_VIDEO_CONFIG_USELTRFRAME;
+
+typedef struct OMX_VIDEO_CONFIG_QP {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nQP;
+} OMX_VIDEO_CONFIG_QP;
+
+typedef struct OMX_VIDEO_CONFIG_TEMPORALLAYERCOUNT {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nTemporalLayerCount;
+} OMX_VIDEO_CONFIG_TEMPORALLAYERCOUNT;
+
+typedef struct OMX_VIDEO_CONFIG_BASELAYERPID{
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U32 nPID;
+} OMX_VIDEO_CONFIG_BASELAYERPID;
+
+typedef struct OMX_VIDEO_DECODERPARAMS {
+    OMX_BOOL bLowLatency;
+} OMX_VIDEO_DECODERPARAMS;
+
+typedef struct OMX_VIDEO_DECODERCAP {
+    OMX_BOOL bLowLatency;
+    OMX_U32 nMaxFrameWidth;
+    OMX_U32 nMaxFrameHeight;
+    OMX_U32 nMaxInstances;
+    OMX_VIDEO_AVCLEVELTYPE nMaxLevel;
+    OMX_U32 nMaxMacroblockProcessingRate;
+} OMX_VIDEO_DECODERCAP;
+
+typedef struct OMX_VIDEO_PARAM_DECODERSETTING {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_DECODERPARAMS stDecParam;
+} OMX_VIDEO_PARAM_DECODERSETTING;
+
+typedef struct OMX_VIDEO_PARAM_DECODERCAP {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_VIDEO_DECODERCAP stDecoderCap;
+} OMX_VIDEO_PARAM_DECODERCAP;
+
+typedef struct OMX_VIDEO_PARAM_DRIVERVER {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPortIndex;
+    OMX_U64 nDriverVersion;
+} OMX_VIDEO_PARAM_DRIVERVER;
+
+#pragma pack(pop)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/osal/Exynos_OSAL_ETC.c b/openmax/osal/Exynos_OSAL_ETC.c
new file mode 100755 (executable)
index 0000000..993ba28
--- /dev/null
@@ -0,0 +1,1203 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_ETC.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#ifdef USE_ANDROID
+#include <system/graphics.h>
+#include <cutils/properties.h>
+#else
+#include <system/graphics.h>
+#endif
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OMX_Macros.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_VIDEO_OSAL"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+#ifdef PERFORMANCE_DEBUG
+#include <time.h>
+#include "Exynos_OSAL_Mutex.h"
+
+#define INPUT_PORT_INDEX    0
+#define OUTPUT_PORT_INDEX   1
+#endif
+
+#include "ExynosVideoApi.h"
+#include "exynos_format.h"
+#include "csc.h"
+
+static struct timeval perfStart[PERF_ID_MAX+1], perfStop[PERF_ID_MAX+1];
+static unsigned long perfTime[PERF_ID_MAX+1], totalPerfTime[PERF_ID_MAX+1];
+static unsigned int perfFrameCount[PERF_ID_MAX+1], perfOver30ms[PERF_ID_MAX+1];
+
+size_t Exynos_OSAL_Strcpy(OMX_PTR dest, OMX_PTR src)
+{
+#ifdef USE_ANDROID
+    size_t len = (size_t)(strlen((const char *)src) + 1);
+
+    return strlcpy(dest, src, len);
+#else
+    // This fix is to safely copy a null-termination string.
+    //return strlen(strncpy(dest, src, strlen((const char *)src)));
+    size_t lengthSrc = strlen((const char *)src);
+    size_t lengthTotal = strlen(strncpy(dest, src, lengthSrc+1));
+    return lengthTotal;
+#endif
+}
+
+size_t Exynos_OSAL_Strncpy(OMX_PTR dest, OMX_PTR src, size_t num)
+{
+#ifdef USE_ANDROID
+    return strlcpy(dest, src, (size_t)(num + 1));
+#else
+    return strlen(strncpy(dest, src, num));
+#endif
+}
+
+OMX_S32 Exynos_OSAL_Strcmp(OMX_PTR str1, OMX_PTR str2)
+{
+    return strcmp(str1, str2);
+}
+
+OMX_S32 Exynos_OSAL_Strncmp(OMX_PTR str1, OMX_PTR str2, size_t num)
+{
+    return strncmp(str1, str2, num);
+}
+
+const char* Exynos_OSAL_Strstr(const char *str1, const char *str2)
+{
+    return strstr(str1, str2);
+}
+
+size_t Exynos_OSAL_Strcat(OMX_PTR dest, OMX_PTR src)
+{
+#ifdef USE_ANDROID
+    return strlcat(dest, src, (size_t)(strlen((const char *)dest) + strlen((const char *)src) + 1));
+#else
+    return strlen(strncat(dest, src, strlen((const char *)src)));
+#endif
+}
+
+size_t Exynos_OSAL_Strncat(OMX_PTR dest, OMX_PTR src, size_t num)
+{
+    size_t len = num;
+
+#ifdef USE_ANDROID
+    /* caution : num should be a size of dest buffer */
+    return strlcat(dest, src, (size_t)(strlen((const char *)dest) + strlen((const char *)src) + 1));
+#else
+    return strlen(strncat(dest, src, len));
+#endif
+}
+
+size_t Exynos_OSAL_Strlen(const char *str)
+{
+    return strlen(str);
+}
+
+static OMX_S32 Exynos_OSAL_MeasureTime(struct timeval *start, struct timeval *stop)
+{
+    signed long sec, usec, time;
+
+    sec = stop->tv_sec - start->tv_sec;
+    if (stop->tv_usec >= start->tv_usec) {
+        usec = (signed long)stop->tv_usec - (signed long)start->tv_usec;
+    } else {
+        usec = (signed long)stop->tv_usec + 1000000 - (signed long)start->tv_usec;
+        sec--;
+    }
+
+    time = sec * 1000000 + (usec);
+
+    return time;
+}
+
+void Exynos_OSAL_PerfInit(PERF_ID_TYPE id)
+{
+    Exynos_OSAL_Memset(&perfStart[id], 0, sizeof(perfStart[id]));
+    Exynos_OSAL_Memset(&perfStop[id], 0, sizeof(perfStop[id]));
+    perfTime[id] = 0;
+    totalPerfTime[id] = 0;
+    perfFrameCount[id] = 0;
+    perfOver30ms[id] = 0;
+}
+
+void Exynos_OSAL_PerfStart(PERF_ID_TYPE id)
+{
+    gettimeofday(&perfStart[id], NULL);
+}
+
+void Exynos_OSAL_PerfStop(PERF_ID_TYPE id)
+{
+    gettimeofday(&perfStop[id], NULL);
+
+    perfTime[id] = Exynos_OSAL_MeasureTime(&perfStart[id], &perfStop[id]);
+    totalPerfTime[id] += perfTime[id];
+    perfFrameCount[id]++;
+
+    if (perfTime[id] > 30000)
+        perfOver30ms[id]++;
+}
+
+OMX_U32 Exynos_OSAL_PerfFrame(PERF_ID_TYPE id)
+{
+    return perfTime[id];
+}
+
+OMX_U32 Exynos_OSAL_PerfTotal(PERF_ID_TYPE id)
+{
+    return totalPerfTime[id];
+}
+
+OMX_U32 Exynos_OSAL_PerfFrameCount(PERF_ID_TYPE id)
+{
+    return perfFrameCount[id];
+}
+
+int Exynos_OSAL_PerfOver30ms(PERF_ID_TYPE id)
+{
+    return perfOver30ms[id];
+}
+
+void Exynos_OSAL_PerfPrint(OMX_STRING prefix, PERF_ID_TYPE id)
+{
+    OMX_U32 perfTotal;
+    int frameCount;
+
+    frameCount = Exynos_OSAL_PerfFrameCount(id);
+    perfTotal = Exynos_OSAL_PerfTotal(id);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%s][%s] Frame Count: %d", __FUNCTION__, prefix, frameCount);
+    Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%s][%s] Avg Time: %.2f ms, Over 30ms: %d",
+                prefix, (float)perfTotal / (float)(frameCount * 1000),
+                Exynos_OSAL_PerfOver30ms(id));
+}
+
+unsigned int Exynos_OSAL_GetPlaneCount(
+    OMX_COLOR_FORMATTYPE eOMXFormat,
+    PLANE_TYPE           ePlaneType)
+{
+    unsigned int nPlaneCnt = 0;
+
+    switch ((int)eOMXFormat) {
+    case OMX_COLOR_FormatYCbYCr:
+    case OMX_COLOR_FormatYUV420Planar:
+    case OMX_SEC_COLOR_FormatYVU420Planar:
+        nPlaneCnt = 3;
+        break;
+    case OMX_COLOR_FormatYUV420SemiPlanar:
+    case OMX_SEC_COLOR_FormatS10bitYUV420SemiPlanar:
+    case OMX_SEC_COLOR_Format10bitYUV420SemiPlanar:
+    case OMX_SEC_COLOR_FormatNV21Linear:
+    case OMX_SEC_COLOR_FormatS10bitYVU420SemiPlanar:
+    case OMX_SEC_COLOR_Format10bitYVU420SemiPlanar:
+    case OMX_SEC_COLOR_FormatNV12Tiled:
+        nPlaneCnt = 2;
+        break;
+    case OMX_COLOR_Format32bitARGB8888:
+    case OMX_COLOR_Format32bitBGRA8888:
+    case OMX_COLOR_Format32BitRGBA8888:
+        nPlaneCnt = 1;
+        break;
+    default:
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported color format(0x%x).", __FUNCTION__, eOMXFormat);
+        nPlaneCnt = 0;
+        break;
+    }
+
+    if ((ePlaneType & PLANE_SINGLE) &&
+        (nPlaneCnt > 0)) {
+        nPlaneCnt = 1;
+    }
+
+    return nPlaneCnt;
+}
+
+void Exynos_OSAL_GetPlaneSize(
+    OMX_COLOR_FORMATTYPE    eColorFormat,
+    PLANE_TYPE              ePlaneType,
+    OMX_U32                 nWidth,
+    OMX_U32                 nHeight,
+    unsigned int            nDataLen[MAX_BUFFER_PLANE],
+    unsigned int            nAllocLen[MAX_BUFFER_PLANE])
+{
+    switch ((int)eColorFormat) {
+    case OMX_COLOR_FormatYUV420Planar:
+    case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar:
+        if (ePlaneType == PLANE_SINGLE) {
+            nDataLen[0] = (nWidth * nHeight) * 3 / 2;
+            nDataLen[1] = 0;
+            nDataLen[2] = 0;
+
+            nAllocLen[0] = (ALIGN(nWidth, 16) * ALIGN(nHeight, 16) + 256) +
+                           (ALIGN((ALIGN(nWidth >> 1, 16) * ALIGN((ALIGN(nHeight, 16) >> 1), CHROMA_VALIGN) + 256), 16) * 2);
+        } else {
+            nDataLen[0] = nWidth * nHeight;
+            nDataLen[1] = nDataLen[0] >> 2;
+            nDataLen[2] = nDataLen[1];
+
+            nAllocLen[0] = ALIGN(ALIGN(nWidth, 16) * ALIGN(nHeight, 16), 256);
+            nAllocLen[1] = ALIGN(ALIGN(nWidth >> 1, 16) * ALIGN((ALIGN(nHeight, 16) >> 1), CHROMA_VALIGN), 256);
+            nAllocLen[2] = nAllocLen[1];
+        }
+        break;
+    case OMX_COLOR_FormatYUV420SemiPlanar:
+    case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear:
+    case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled:
+        if (ePlaneType == PLANE_SINGLE) {
+            nDataLen[0] = (nWidth * nHeight) * 3 / 2;
+            nDataLen[1] = 0;
+            nDataLen[2] = 0;
+
+            nAllocLen[0] = (ALIGN(nWidth, 16) * ALIGN(nHeight, 16) + 256) +
+                           (ALIGN((ALIGN(nWidth, 16) * ALIGN((ALIGN(nHeight, 16) >> 1), CHROMA_VALIGN) + 256), 16));
+        } else {
+            nDataLen[0] = nWidth * nHeight;
+            nDataLen[1] = nDataLen[0] >> 1;
+            nDataLen[2] = 0;
+
+            nAllocLen[0] = ALIGN(ALIGN(nWidth, 16) * ALIGN(nHeight, 16), 256);
+            nAllocLen[1] = ALIGN(ALIGN(nWidth, 16) * ALIGN((ALIGN(nHeight, 16) >> 1), CHROMA_VALIGN), 256);
+        }
+        break;
+    case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatS10bitYUV420SemiPlanar:
+    case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatS10bitYVU420SemiPlanar:
+        if (ePlaneType == PLANE_SINGLE) {
+            nDataLen[0] = (nWidth * nHeight) * 3 / 2;
+            nDataLen[1] = 0;
+            nDataLen[2] = 0;
+
+            nAllocLen[0] = ((ALIGN(nWidth, S10B_FORMAT_8B_ALIGNMENT) * ALIGN(nHeight, 16) + 256) +  /* Y 8bit */
+                            (ALIGN(nWidth / 4, 16) * ALIGN(nHeight, 16) + 64)) +                   /* Y 2bit */
+                           ((ALIGN((ALIGN(nWidth, S10B_FORMAT_8B_ALIGNMENT) * ALIGN((ALIGN(nHeight, 16) >> 1), CHROMA_VALIGN) + 256), 16)) +  /* CbCr 8bit */
+                            (ALIGN(nWidth / 4, 16) * ALIGN((ALIGN(nHeight, 16) >> 1), CHROMA_VALIGN) + 64));                                 /* CbCr 2bit */
+        } else {
+            nDataLen[0] = nWidth * nHeight;
+            nDataLen[1] = nWidth * (nHeight / 2);
+            nDataLen[2] = 0;
+
+            nAllocLen[0] = ALIGN((ALIGN(nWidth, S10B_FORMAT_8B_ALIGNMENT) * ALIGN(nHeight, 16) + 256) +  /* Y 8bit */
+                                 (ALIGN(nWidth / 4, 16) * ALIGN(nHeight, 16) + 256), 256);              /* Y 2bit */
+            nAllocLen[1] = ALIGN((ALIGN(nWidth, S10B_FORMAT_8B_ALIGNMENT) * ALIGN((ALIGN(nHeight, 16) >> 1), CHROMA_VALIGN) + 256) +  /* CbCr 8bit */
+                                 (ALIGN(nWidth / 4, 16) * ALIGN((ALIGN(nHeight, 16) >> 1), CHROMA_VALIGN) + 256), 256);              /* CbCr 2bit */
+        }
+        break;
+    case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_Format10bitYUV420SemiPlanar:
+    case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_Format10bitYVU420SemiPlanar:
+        if (ePlaneType == PLANE_SINGLE) {
+            nDataLen[0] = ((nWidth * 2) * nHeight) * 3 / 2;
+            nDataLen[1] = 0;
+            nDataLen[2] = 0;
+
+            nAllocLen[0] = (ALIGN((nWidth * 2), 16) * ALIGN(nHeight, 16) + 256) +                                           /* Y 10bit */
+                           (ALIGN((ALIGN((nWidth * 2), 16) * ALIGN((ALIGN(nHeight, 16) >> 1), CHROMA_VALIGN) + 256), 16));  /* CbCr 10bit */
+        } else {
+            nDataLen[0] = (nWidth * 2) * nHeight;
+            nDataLen[1] = nDataLen[0] >> 1;
+            nDataLen[2] = 0;
+
+            nAllocLen[0] = ALIGN(ALIGN(nWidth * 2, 16) * ALIGN(nHeight, 16), 256);
+            nAllocLen[1] = ALIGN(ALIGN(nWidth * 2, 16) * ALIGN((ALIGN(nHeight, 16) >> 1), CHROMA_VALIGN), 256);
+        }
+        break;
+    case OMX_COLOR_Format32bitARGB8888:
+    case OMX_COLOR_Format32bitBGRA8888:
+    case OMX_COLOR_Format32BitRGBA8888:
+        nDataLen[0] = nWidth * nHeight * 4;
+        nDataLen[1] = 0;
+        nDataLen[2] = 0;
+
+        nAllocLen[0] = ALIGN(ALIGN(nWidth, 16) * ALIGN(nHeight, 16) * 4, 256);
+        break;
+    default:
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported color format(0x%x).", __FUNCTION__, eColorFormat);
+        break;
+    }
+}
+
+static struct {
+    ExynosVideoColorFormatType  eVideoFormat[2];  /* multi-FD, single-FD(H/W) */
+    OMX_COLOR_FORMATTYPE        eOMXFormat;
+} VIDEO_COLORFORMAT_MAP[] = {
+{{VIDEO_COLORFORMAT_NV12M, VIDEO_COLORFORMAT_NV12}, OMX_COLOR_FormatYUV420SemiPlanar},
+{{VIDEO_COLORFORMAT_NV12M_S10B, VIDEO_COLORFORMAT_NV12_S10B}, (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatS10bitYUV420SemiPlanar},
+{{VIDEO_COLORFORMAT_NV12M_P010, 0 /* not supported */ }, (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_Format10bitYUV420SemiPlanar},
+{{VIDEO_COLORFORMAT_NV12M_TILED, VIDEO_COLORFORMAT_NV12_TILED}, (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled},
+{{VIDEO_COLORFORMAT_NV21M, 0 /* not supported */}, (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear},
+{{VIDEO_COLORFORMAT_NV21M_S10B, 0 /* not supported */}, (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatS10bitYVU420SemiPlanar},
+{{VIDEO_COLORFORMAT_NV21M_P010, 0 /* not supported */}, (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_Format10bitYVU420SemiPlanar},
+{{VIDEO_COLORFORMAT_I420M, VIDEO_COLORFORMAT_I420}, OMX_COLOR_FormatYUV420Planar},
+{{VIDEO_COLORFORMAT_YV12M, 0 /* not supported */}, (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar},
+{{VIDEO_COLORFORMAT_ARGB8888, VIDEO_COLORFORMAT_ARGB8888}, OMX_COLOR_Format32bitBGRA8888},
+{{VIDEO_COLORFORMAT_BGRA8888, VIDEO_COLORFORMAT_BGRA8888}, OMX_COLOR_Format32bitARGB8888},
+{{VIDEO_COLORFORMAT_RGBA8888, VIDEO_COLORFORMAT_RGBA8888}, (OMX_COLOR_FORMATTYPE)OMX_COLOR_Format32BitRGBA8888},
+};
+
+int Exynos_OSAL_OMX2VideoFormat(
+    OMX_COLOR_FORMATTYPE    eColorFormat,
+    PLANE_TYPE              ePlaneType)
+{
+    ExynosVideoColorFormatType nVideoFormat = VIDEO_COLORFORMAT_UNKNOWN;
+    int nVideoFormats = (int)(sizeof(VIDEO_COLORFORMAT_MAP)/sizeof(VIDEO_COLORFORMAT_MAP[0]));
+    int i;
+
+    for (i = 0; i < nVideoFormats; i++) {
+        if (VIDEO_COLORFORMAT_MAP[i].eOMXFormat == eColorFormat) {
+            nVideoFormat = VIDEO_COLORFORMAT_MAP[i].eVideoFormat[(ePlaneType & 0x10)? 1:0];
+            break;
+        }
+    }
+
+    if (nVideoFormat == VIDEO_COLORFORMAT_UNKNOWN) {
+        Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%s] color format(0x%x)/plane type(0x%x) is not supported",
+                                        __FUNCTION__, eColorFormat, ePlaneType);
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] color format(0x%x)/plane type(0x%x) -> video format(0x%x)",
+                                        __FUNCTION__, eColorFormat, ePlaneType, nVideoFormat);
+
+EXIT:
+
+    return (int)nVideoFormat;
+}
+
+OMX_COLOR_FORMATTYPE Exynos_OSAL_Video2OMXFormat(
+    int nVideoFormat)
+{
+    OMX_COLOR_FORMATTYPE eOMXFormat = OMX_COLOR_FormatUnused;
+    int nVideoFormats = (int)(sizeof(VIDEO_COLORFORMAT_MAP)/sizeof(VIDEO_COLORFORMAT_MAP[0]));
+    int i;
+
+    for (i = 0; i < nVideoFormats; i++) {
+        if (((int)VIDEO_COLORFORMAT_MAP[i].eVideoFormat[0] == nVideoFormat) ||
+            ((int)VIDEO_COLORFORMAT_MAP[i].eVideoFormat[1] == nVideoFormat)) {
+            eOMXFormat = VIDEO_COLORFORMAT_MAP[i].eOMXFormat;
+            break;
+        }
+    }
+
+    if (eOMXFormat == OMX_COLOR_FormatUnused) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] video format(0x%x) is not supported", __FUNCTION__, nVideoFormat);
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] video format(0x%x) -> color format(0x%x)", __FUNCTION__, nVideoFormat, eOMXFormat);
+
+EXIT:
+
+
+    return eOMXFormat;
+}
+
+static struct {
+    unsigned int         nHALFormat[PLANE_MAX_NUM];  /* multi-FD, single-FD(H/W), sigle-FD(general) */
+    OMX_COLOR_FORMATTYPE eOMXFormat;
+} HAL_COLORFORMAT_MAP[] = {
+/* NV12 format */
+#ifdef USE_PRIV_FORMAT
+{{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP},
+     OMX_COLOR_FormatYUV420SemiPlanar},
+#endif
+{{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP},
+     OMX_COLOR_FormatYUV420SemiPlanar},
+
+{{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP},
+ (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatS10bitYUV420SemiPlanar},
+
+{{0 /* not implemented */, 0 /* not implemented */, 0 /* not implemented */},
+ (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_Format10bitYUV420SemiPlanar},
+
+/* NV12T format */
+{{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_TILED, 0 /* not implemented */},
+ (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled},
+
+/* NV21 format */
+{{HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, 0 /* not implemented */, HAL_PIXEL_FORMAT_YCrCb_420_SP},
+ (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear},
+
+{{0 /* not implemented */, 0 /* not implemented */, 0 /* not implemented */},
+ (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatS10bitYVU420SemiPlanar},
+
+{{0 /* not implemented */, 0 /* not implemented */, 0 /* not implemented */},
+ (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_Format10bitYVU420SemiPlanar},
+
+/* I420P format */
+{{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P},
+ OMX_COLOR_FormatYUV420Planar},
+
+/* YV12 format */
+{{HAL_PIXEL_FORMAT_EXYNOS_YV12_M, 0 /* not implemented */, HAL_PIXEL_FORMAT_YV12},
+ (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar},
+
+/* RGB format */
+{{HAL_PIXEL_FORMAT_RGBA_8888, HAL_PIXEL_FORMAT_RGBA_8888, HAL_PIXEL_FORMAT_RGBA_8888},
+ (OMX_COLOR_FORMATTYPE)OMX_COLOR_Format32BitRGBA8888},
+
+{{HAL_PIXEL_FORMAT_EXYNOS_ARGB_8888, HAL_PIXEL_FORMAT_EXYNOS_ARGB_8888, HAL_PIXEL_FORMAT_EXYNOS_ARGB_8888},
+ OMX_COLOR_Format32bitBGRA8888},
+
+{{HAL_PIXEL_FORMAT_BGRA_8888, HAL_PIXEL_FORMAT_BGRA_8888, HAL_PIXEL_FORMAT_BGRA_8888},
+ OMX_COLOR_Format32bitARGB8888},
+};
+
+OMX_COLOR_FORMATTYPE Exynos_OSAL_HAL2OMXColorFormat(
+    unsigned int nHALFormat)
+{
+    OMX_COLOR_FORMATTYPE eOMXFormat = OMX_COLOR_FormatUnused;
+    int nHALFormats = (int)(sizeof(HAL_COLORFORMAT_MAP)/sizeof(HAL_COLORFORMAT_MAP[0]));
+    int i;
+
+    for (i = 0; i < nHALFormats; i++) {
+        if ((HAL_COLORFORMAT_MAP[i].nHALFormat[0] == nHALFormat) ||
+            (HAL_COLORFORMAT_MAP[i].nHALFormat[1] == nHALFormat)
+#if 0
+            || (HAL_COLORFORMAT_MAP[i].nHALFormat[2] == nHALFormat)  /* userspace format : not used in vendor scenario */
+#endif
+            ) {
+            eOMXFormat = HAL_COLORFORMAT_MAP[i].eOMXFormat;
+            break;
+        }
+    }
+
+    if (eOMXFormat == OMX_COLOR_FormatUnused) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] HAL format(0x%x) is not supported", __FUNCTION__, nHALFormat);
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] HAL format(0x%x) -> color format(0x%x)", __FUNCTION__, nHALFormat, eOMXFormat);
+
+EXIT:
+
+    return eOMXFormat;
+}
+
+unsigned int Exynos_OSAL_OMX2HALPixelFormat(
+    OMX_COLOR_FORMATTYPE eOMXFormat,
+    PLANE_TYPE           ePlaneType)
+{
+    unsigned int nHALFormat = 0;
+    int nHALFormats = (int)(sizeof(HAL_COLORFORMAT_MAP)/sizeof(HAL_COLORFORMAT_MAP[0]));
+    int i;
+
+    for (i = 0; i < nHALFormats; i++) {
+        if (HAL_COLORFORMAT_MAP[i].eOMXFormat == eOMXFormat) {
+            nHALFormat = HAL_COLORFORMAT_MAP[i].nHALFormat[ePlaneType & 0xF];
+            break;
+        }
+    }
+
+    if (nHALFormat == 0)
+        goto EXIT;
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] color format(0x%x)/plane type(0x%x) -> HAL format(0x%x)",
+                                        __FUNCTION__, eOMXFormat, ePlaneType, nHALFormat);
+
+EXIT:
+
+    return nHALFormat;
+}
+
+int Exynos_OSAL_DataSpaceToColorSpace(int nDataSpace)
+{
+    int nColorSpace = CSC_EQ_COLORSPACE_SMPTE170M;
+
+#ifdef USE_ANDROID
+    switch (nDataSpace) {
+    case (HAL_DATASPACE_RANGE_LIMITED | HAL_DATASPACE_TRANSFER_HLG | HAL_DATASPACE_STANDARD_BT2020):
+    case (HAL_DATASPACE_RANGE_LIMITED | HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_STANDARD_BT2020):
+    case (HAL_DATASPACE_RANGE_LIMITED | HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_STANDARD_BT2020):
+    case HAL_DATASPACE_BT2020:
+    case HAL_DATASPACE_BT2020_PQ:
+        nColorSpace = CSC_EQ_COLORSPACE_BT2020;
+#ifndef USE_BT2020_SUPPORT
+        nColorSpace = CSC_EQ_COLORSPACE_REC709;  /* GPU(BT.709) : default about BT.2020 */
+#ifndef USE_BT709_SUPPORT
+        nColorSpace = CSC_EQ_COLORSPACE_SMPTE170M;  /* GPU(BT.601 only) : default */
+#endif
+#endif
+        break;
+    case (HAL_DATASPACE_RANGE_FULL | HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_STANDARD_BT709):
+    case HAL_DATASPACE_BT709:
+    case HAL_DATASPACE_V0_BT709:
+        nColorSpace = CSC_EQ_COLORSPACE_REC709;  /* BT.709 */
+#ifndef USE_BT709_SUPPORT
+        nColorSpace = CSC_EQ_COLORSPACE_SMPTE170M;  /* GPU(BT.601 only) : default */
+#endif
+        break;
+    case (HAL_DATASPACE_RANGE_FULL | HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_STANDARD_BT601_625):
+    case HAL_DATASPACE_BT601_625:
+    case HAL_DATASPACE_V0_BT601_625:
+    case (HAL_DATASPACE_RANGE_FULL | HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_STANDARD_BT601_525):
+    case HAL_DATASPACE_BT601_525:
+    case HAL_DATASPACE_V0_BT601_525:
+    default:
+        nColorSpace = CSC_EQ_COLORSPACE_SMPTE170M;  /* BT.601 */
+        break;
+    };
+#endif
+
+#ifdef USE_ANDROID
+    {
+        /* frameworks/native
+         * related commit // 6a236b8 libgui: synchronize yuv_info for supporting dataspace
+         * The GLConsumer don't apply changed dataspace to the GPU.
+         * Above commit resolves this problem.
+         * However, there is still a problem with AOSP aka GSI(Generic System Image).
+         * So, have to use BT.601 if the following property is not set.
+         */
+        char prop[PROPERTY_VALUE_MAX] = { 0, };
+
+        if ((property_get("ro.exynos.vendor.cscsupported", prop, NULL) <= 0) ||
+            (Exynos_OSAL_Strncmp(prop, "1", 1))) {
+            nColorSpace = CSC_EQ_COLORSPACE_SMPTE170M;  /* BT.601 */
+        }
+    }
+#endif
+
+    return nColorSpace;
+}
+
+#ifdef PERFORMANCE_DEBUG
+
+typedef enum _DEBUG_LEVEL
+{
+    PERF_LOG_OFF,
+    PERF_LOG_ON,
+} EXYNOS_DEBUG_LEVEL;
+
+static int gPerfLevel = PERF_LOG_OFF;
+
+void Exynos_OSAL_Get_Perf_Property()
+{
+    char perfProp[PROPERTY_VALUE_MAX] = { 0, };
+
+    if (property_get("debug.omx.perf", perfProp, NULL) > 0) {
+        if(!(Exynos_OSAL_Strncmp(perfProp, "1", 1)))
+            gPerfLevel = PERF_LOG_ON;
+        else
+            gPerfLevel = PERF_LOG_OFF;
+    }
+}
+
+typedef struct _BUFFER_INFO
+{
+    OMX_BUFFERHEADERTYPE *pBufferHeader;
+    OMX_TICKS             timestamp;            /* given from framework */
+    struct timeval        currentTime;          /* system time */
+    OMX_TICKS             previousTimeStamp;
+    struct timeval        previousTime;
+    OMX_S32               nCountInOMX;
+
+
+    struct timeval        queueTime;            /* system time : VL42 qbuf */
+    struct timeval        dequeueTime;          /* system time : V4L2 dqbuf */
+    OMX_S32               nCountInV4L2;
+} BUFFER_INFO;
+
+typedef struct _EXYNOS_OMX_PERF_INFO
+{
+    OMX_HANDLETYPE mutex;
+
+    OMX_S32        nCountInOMX;
+    OMX_S32        nCountInV4L2;
+
+    OMX_S32        nCurSlotIndex;
+    OMX_S32        nNextSlotIndex;
+    BUFFER_INFO    sBufferTime[MAX_TIMESTAMP];
+
+    OMX_TICKS      latestOutTimestamp;
+} EXYNOS_OMX_PERF_INFO;
+
+OMX_ERRORTYPE Exynos_OSAL_CountCreate(OMX_HANDLETYPE *hPerfInfo)
+{
+    OMX_ERRORTYPE           ret         = OMX_ErrorNone;
+    EXYNOS_OMX_PERF_INFO   *pPerfInfo   = NULL;
+
+    if (hPerfInfo == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    /* it only works when perperty is enabled */
+    if (gPerfLevel == PERF_LOG_OFF) {
+        (*hPerfInfo) = NULL;
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
+    pPerfInfo = (EXYNOS_OMX_PERF_INFO *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_PERF_INFO));
+    if (pPerfInfo == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to malloc", __FUNCTION__);
+        (*hPerfInfo) = NULL;
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Memset((OMX_PTR)pPerfInfo, 0, sizeof(EXYNOS_OMX_PERF_INFO));
+
+    ret = Exynos_OSAL_MutexCreate(&(pPerfInfo->mutex));
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to MutexCreate", __FUNCTION__);
+        Exynos_OSAL_Free(pPerfInfo);
+        (*hPerfInfo) = NULL;
+        goto EXIT;
+    }
+
+    (*hPerfInfo) = pPerfInfo;
+
+EXIT:
+
+    return ret;
+}
+
+void Exynos_OSAL_CountTerminate(OMX_HANDLETYPE *hPerfInfo)
+{
+    EXYNOS_OMX_PERF_INFO *pPerfInfo = (EXYNOS_OMX_PERF_INFO *)(*hPerfInfo);
+
+    if (pPerfInfo == NULL)
+        return;
+
+    Exynos_OSAL_MutexTerminate(pPerfInfo->mutex);
+    Exynos_OSAL_Free(pPerfInfo);
+    (*pPerfInfo) = NULL;
+
+    return;
+}
+
+OMX_S32 Exynos_OSAL_CountIncrease(
+    OMX_HANDLETYPE          *hPerfInfo,
+    OMX_BUFFERHEADERTYPE    *pBufferHeader,
+    int                      nPortIndex)
+{
+    OMX_S32                  nCountInOMX   = 0;
+    EXYNOS_OMX_PERF_INFO    *pPerfInfo     = (EXYNOS_OMX_PERF_INFO *)hPerfInfo;
+
+    struct timeval   currentTime;
+    struct tm       *ptm  = NULL;
+    char time_string[40] = { 0, };
+
+    int nSlotIndex = 0;
+    int i;
+
+    if (pPerfInfo == NULL)
+        return 0;
+
+    if (pBufferHeader == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] bufferHeader is NULL", __FUNCTION__);
+        return pPerfInfo->nCountInOMX;
+    }
+
+    Exynos_OSAL_MutexLock(pPerfInfo->mutex);
+
+    pPerfInfo->nCountInOMX++;  /* queued to OMX's port */
+    nCountInOMX = pPerfInfo->nCountInOMX;
+
+    nSlotIndex = pPerfInfo->nNextSlotIndex;
+
+    /* if could not find an empty slot at the past */
+    if (nSlotIndex < 0) {
+        /* re-try to find an empty slot */
+        nSlotIndex = (pPerfInfo->nCurSlotIndex + 1) % MAX_TIMESTAMP;
+        for (i = 0; i < MAX_TIMESTAMP; i++) {
+            if (pPerfInfo->sBufferTime[nSlotIndex].pBufferHeader == NULL)
+                break;
+
+            nSlotIndex = (nSlotIndex + 1) % MAX_TIMESTAMP;
+        }
+
+        if (i >= MAX_TIMESTAMP) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Can not find a empty slot", __FUNCTION__);
+        } else {
+            pPerfInfo->sBufferTime[nSlotIndex].previousTimeStamp = pPerfInfo->sBufferTime[pPerfInfo->nCurSlotIndex].timestamp;
+            Exynos_OSAL_Memcpy(&pPerfInfo->sBufferTime[nSlotIndex].previousTime,
+                               &pPerfInfo->sBufferTime[pPerfInfo->nCurSlotIndex].timestamp, sizeof(struct timeval));
+            pPerfInfo->nNextSlotIndex = nSlotIndex;
+        }
+    }
+
+    /* save buffer header and timestamp */
+    pPerfInfo->sBufferTime[nSlotIndex].pBufferHeader    = pBufferHeader;
+    pPerfInfo->sBufferTime[nSlotIndex].timestamp        = pBufferHeader->nTimeStamp;
+
+    /* get currnet system time and save this for performance measurement */
+    gettimeofday(&(currentTime), NULL);
+    Exynos_OSAL_Memcpy(&pPerfInfo->sBufferTime[nSlotIndex].currentTime, &currentTime, sizeof(currentTime));
+    pPerfInfo->sBufferTime[nSlotIndex].nCountInOMX = pPerfInfo->nCountInOMX;
+    pPerfInfo->nCurSlotIndex = nSlotIndex;
+
+    /* find an empty slot for next */
+    nSlotIndex = (pPerfInfo->nCurSlotIndex + 1) % MAX_TIMESTAMP;
+    for (i = 0; i < MAX_TIMESTAMP; i++) {
+        if (pPerfInfo->sBufferTime[nSlotIndex].pBufferHeader == NULL)
+            break;
+
+        nSlotIndex = (nSlotIndex + 1) % MAX_TIMESTAMP;
+    }
+
+    if (i >= MAX_TIMESTAMP) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Can not find a empty slot", __FUNCTION__);
+    } else {
+        /* save cur info to next slot that will have future info */
+        pPerfInfo->sBufferTime[nSlotIndex].previousTimeStamp = pPerfInfo->sBufferTime[pPerfInfo->nCurSlotIndex].timestamp;
+        Exynos_OSAL_Memcpy(&pPerfInfo->sBufferTime[nSlotIndex].previousTime,
+                           &pPerfInfo->sBufferTime[pPerfInfo->nCurSlotIndex].timestamp, sizeof(struct timeval));
+        pPerfInfo->nNextSlotIndex = nSlotIndex;
+    }
+
+    ptm = localtime(&currentTime.tv_sec);
+    strftime(time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s] %s time = %s.%03ld, header:0x%x, OMX Count:%d", __FUNCTION__,
+                                            (nPortIndex == INPUT_PORT_INDEX)? "ETB":"FTB",
+                                            time_string, (currentTime.tv_usec / 1000), pBufferHeader, nCountInOMX);
+
+    Exynos_OSAL_MutexUnlock(pPerfInfo->mutex);
+
+    return nCountInOMX;
+}
+
+OMX_S32 Exynos_OSAL_CountDecrease(
+    OMX_HANDLETYPE          *hPerfInfo,
+    OMX_BUFFERHEADERTYPE    *pBufferHeader,
+    int                      nPortIndex)
+{
+    OMX_S32                  nCountInOMX   = 0;
+    EXYNOS_OMX_PERF_INFO    *pPerfInfo     = (EXYNOS_OMX_PERF_INFO *)hPerfInfo;
+
+    struct timeval   currentTime;
+    struct tm       *ptm  = NULL;
+    char time_string[40] = { 0, };
+
+    int nSlotIndex = 0;
+    int i;
+
+    if (pPerfInfo == NULL)
+        return 0;
+
+    if (pBufferHeader == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] bufferHeader is NULL", __FUNCTION__);
+        return pPerfInfo->nCountInOMX;
+    }
+
+    Exynos_OSAL_MutexLock(pPerfInfo->mutex);
+
+    /* find a buffer */
+    for (i = 0; i < MAX_TIMESTAMP; i++) {
+        if (pPerfInfo->sBufferTime[i].pBufferHeader == pBufferHeader) {
+            /* clear info */
+            pPerfInfo->sBufferTime[i].pBufferHeader = NULL;
+
+            if (nPortIndex == OUTPUT_PORT_INDEX)
+                pPerfInfo->latestOutTimestamp = pPerfInfo->sBufferTime[i].timestamp;
+
+            nSlotIndex = i;
+            break;
+        }
+    }
+
+    if (i >= MAX_TIMESTAMP) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Can not find %p in slot", __FUNCTION__, pBufferHeader);
+        Exynos_OSAL_MutexUnlock(pPerfInfo->mutex);
+        return pPerfInfo->nCountInOMX;
+    }
+
+    pPerfInfo->nCountInOMX--;  /* dequeued to OMX's port */
+    nCountInOMX = pPerfInfo->nCountInOMX;
+
+    gettimeofday(&(currentTime), NULL);
+    ptm = localtime(&currentTime.tv_sec);
+    strftime(time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s] %s time = %s.%03ld, header:0x%x, OMX Count:%d", __FUNCTION__,
+                                            (nPortIndex == INPUT_PORT_INDEX)? "EBD":"FBD",
+                                            time_string, (currentTime.tv_usec / 1000), pBufferHeader, nCountInOMX);
+
+    Exynos_OSAL_MutexUnlock(pPerfInfo->mutex);
+
+    return nCountInOMX;
+}
+
+OMX_S32 Exynos_OSAL_V4L2CountIncrease(
+    OMX_HANDLETYPE          *hPerfInfo,
+    OMX_BUFFERHEADERTYPE    *pBufferHeader,
+    int                      nPortIndex)
+{
+    OMX_S32                  nCountInV4L2  = 0;
+    EXYNOS_OMX_PERF_INFO    *pPerfInfo     = (EXYNOS_OMX_PERF_INFO *)hPerfInfo;
+
+    struct timeval   currentTime;
+    struct tm       *ptm  = NULL;
+    char time_string[40] = { 0, };
+
+    int nSlotIndex = 0;
+    int i;
+
+    if (pPerfInfo == NULL)
+        return 0;
+
+    if (pBufferHeader == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] bufferHeader is NULL", __FUNCTION__);
+        return pPerfInfo->nCountInV4L2;
+    }
+
+    Exynos_OSAL_MutexLock(pPerfInfo->mutex);
+
+    for (i = 0; i < MAX_TIMESTAMP; i++) {
+        if (pPerfInfo->sBufferTime[i].pBufferHeader == pBufferHeader) {
+            nSlotIndex = i;
+            break;
+        }
+    }
+
+    if (i >= MAX_TIMESTAMP) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Can not find %p in slot", __FUNCTION__, pBufferHeader);
+        Exynos_OSAL_MutexUnlock(pPerfInfo->mutex);
+        return pPerfInfo->nCountInOMX;
+    }
+
+    pPerfInfo->nCountInV4L2++;  /* queued to MFC */
+
+    gettimeofday(&(currentTime), NULL);
+    Exynos_OSAL_Memcpy(&pPerfInfo->sBufferTime[nSlotIndex].queueTime, &currentTime, sizeof(currentTime));
+    pPerfInfo->sBufferTime[nSlotIndex].nCountInV4L2 = pPerfInfo->nCountInV4L2;
+    nCountInV4L2 = pPerfInfo->V4L2QCount;
+
+
+    ptm = localtime(&pPerfInfo->sBufferTime[nSlotIndex].queueTime.tv_sec);
+    strftime(time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s] V4L2 %s time = %s.%03ld, header:0x%x, V4L2 Count:%d", __FUNCTION__,
+                                            (nPortIndex == INPUT_PORT_INDEX)? "SRC Q":"DST Q",
+                                            time_string, (currentTime.tv_usec / 1000), pBufferHeader, nCountInV4L2);
+
+    Exynos_OSAL_MutexUnlock(pPerfInfo->mutex);
+
+    return nCountInV4L2;
+}
+
+OMX_S32 Exynos_OSAL_V4L2CountDecrease(
+    OMX_HANDLETYPE          *hPerfInfo,
+    OMX_BUFFERHEADERTYPE    *pBufferHeader,
+    int                      nPortIndex)
+{
+    OMX_S32                  nCountInV4L2  = 0;
+    EXYNOS_OMX_PERF_INFO    *pPerfInfo     = (EXYNOS_OMX_PERF_INFO *)hPerfInfo;
+
+    struct timeval   currentTime;
+    struct tm       *ptm  = NULL;
+    char time_string[40] = { 0, };
+
+    int nSlotIndex = 0;
+    int i;
+
+    if (pPerfInfo == NULL)
+        return 0;
+
+    if (pBufferHeader == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] bufferHeader is NULL", __FUNCTION__);
+        return pPerfInfo->nCountInV4L2;
+    }
+
+    Exynos_OSAL_MutexLock(pPerfInfo->mutex);
+
+    for (i = 0; i < MAX_TIMESTAMP; i++) {
+        if (pPerfInfo->sBufferTime[i].pBufferHeader == pBufferHeader) {
+            nSlotIndex = i;
+            break;
+        }
+    }
+
+    if (i >= MAX_TIMESTAMP) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Can not find %p in slot", __FUNCTION__, pBufferHeader);
+        Exynos_OSAL_MutexUnlock(pPerfInfo->mutex);
+        return pPerfInfo->nCountInOMX;
+    }
+
+    pPerfInfo->nCountInV4L2--;  /* dequeued to MFC */
+
+    gettimeofday(&(currentTime), NULL);
+    Exynos_OSAL_Memcpy(&pPerfInfo->sBufferTime[nSlotIndex].queueTime, &currentTime, sizeof(currentTime));
+    pPerfInfo->sBufferTime[nSlotIndex].nCountInV4L2 = pPerfInfo->nCountInV4L2;
+    nCountInV4L2 = pPerfInfo->V4L2QCount;
+
+    if (nPortIndex == OUTPUT_PORT_INDEX) {
+        pPerfInfo->sBufferTime[nSlotIndex].timestamp            = pBufferHeader->nTimeStamp;
+        pPerfInfo->sBufferTime[nSlotIndex].previousTimeStamp    = pPerfInfo->latestOutTimestamp;
+    }
+
+    ptm = localtime(&pPerfInfo->sBufferTime[index].dequeueTime.tv_sec);
+    strftime(time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s] V4L2 %s time = %s.%03ld, header:0x%x, V4L2 Count:%d", __FUNCTION__,
+                                            (nPortIndex == INPUT_PORT_INDEX)? "SRC DQ":"DST DQ",
+                                            time_string, (currentTime.tv_usec / 1000), pBufferHeader, nCountInV4L2);
+
+    Exynos_OSAL_MutexUnlock(pPerfInfo->mutex);
+
+    return nCountInV4L2;
+}
+
+void Exynos_OSAL_CountReset(OMX_HANDLETYPE *hPerfInfo)
+{
+    EXYNOS_OMX_PERF_INFO *pPerfInfo = (EXYNOS_OMX_PERF_INFO *)hPerfInfo;
+
+    if (pPerfInfo == NULL)
+        return;
+
+    Exynos_OSAL_MutexLock(pPerfInfo->mutex);
+
+    pPerfInfo->nCountInOMX = 0;
+    pPerfInfo->nCountInV4L2 = 0;
+
+    pPerfInfo->nCurSlotIndex = 0;
+    pPerfInfo->nNextSlotIndex = 1;
+    Exynos_OSAL_Memset(&pPerfInfo->sBufferTime, 0, sizeof(sBufferTime));
+
+    pPerfInfo->latestOutTimestamp = 0;
+
+    Exynos_OSAL_MutexUnlock(pPerfInfo->mutex);
+
+    return;
+}
+
+#if 0
+OMX_ERRORTYPE Exynos_OSAL_GetCountInfoUseOMXBuffer(OMX_HANDLETYPE *hPerfInfo, OMX_BUFFERHEADERTYPE *OMXBufferHeader, BUFFER_TIME *pBufferInfo)
+{
+    OMX_ERRORTYPE     ret         = OMX_ErrorNone;
+    EXYNOS_OMX_PERF_INFO *countHandle = (EXYNOS_OMX_PERF_INFO *)hCountHandle;
+    OMX_U32 i = 0;
+
+    if ((countHandle == NULL) ||
+        (OMXBufferHeader == NULL) ||
+        (pBufferInfo == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Error : OMX_ErrorBadParameter");
+        return OMX_ErrorBadParameter;
+    }
+
+    if (OMX_ErrorNone == Exynos_OSAL_MutexLock(countHandle->mutex)) {
+        for (i = 0; i < MAX_TIMESTAMP; i++) {
+            if (countHandle->sBufferTime[i].pBufferHeader == OMXBufferHeader) {
+                Exynos_OSAL_Memcpy(pBufferInfo, &(countHandle->sBufferTime[i]), sizeof(BUFFER_TIME));
+                break;
+            }
+        }
+        Exynos_OSAL_MutexUnlock(countHandle->mutex);
+        if (i >= MAX_TIMESTAMP) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "can not find a bufferHeader !!");
+            ret = OMX_ErrorNoMore;
+        }
+    }
+    return ret;
+}
+#endif
+
+static OMX_ERRORTYPE Exynos_OSAL_GetPerfInfoUseTimestamp(
+    OMX_HANDLETYPE  *hPerfInfo,
+    OMX_TICKS        timestamp,
+    BUFFER_INFO     *pBufferInfo)
+{
+    OMX_ERRORTYPE            ret        = OMX_ErrorNone;
+    EXYNOS_OMX_PERF_INFO    *pPerfInfo  = (EXYNOS_OMX_PERF_INFO *)hCountHandle;
+    OMX_U32 i = 0;
+
+
+    if ((pPerfInfo == NULL) ||
+        (pBufferInfo == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret =  OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_MutexLock(pPerfInfo->mutex);
+
+    for (i = 0; i < MAX_TIMESTAMP; i++) {
+        if (pPerfInfo->sBufferTime[i].timestamp == timestamp) {
+            Exynos_OSAL_Memcpy(pBufferInfo, &(pPerfInfo->sBufferTime[i]), sizeof(BUFFER_INFO));
+            break;
+        }
+    }
+
+    if (i >= MAX_TIMESTAMP) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Can not find %p in slot", __FUNCTION__, pBufferHeader);
+        ret = OMX_ErrorNoMore;
+    }
+
+    Exynos_OSAL_MutexUnlock(pPerfInfo->mutex);
+
+EXIT:
+    return ret;
+}
+
+void Exynos_OSAL_PrintCountInfo(
+    OMX_HANDLETYPE          *hSrcPerfInfo,
+    OMX_HANDLETYPE          *hDstPerfInfo,
+    OMX_BUFFERHEADERTYPE    *pBufferHeader)
+{
+    OMX_ERRORTYPE         ret          = OMX_ErrorNone;
+    EXYNOS_OMX_PERF_INFO *pSrcPerfInfo = (EXYNOS_OMX_PERF_INFO *)hSrcPerfInfo;
+    EXYNOS_OMX_PERF_INFO *pDstPerfInfo = (EXYNOS_OMX_PERF_INFO *)hDstPerfInfo;
+
+    BUFFER_INFO srcBufferInfo, dstBufferInfo;
+
+    struct timeval   currentTime;
+    struct tm       *ptm  = NULL;
+    char time_string[40] = { 0, };
+    long milliseconds;
+
+    OMX_S32 srcOMXtoV4L2 = 0;
+    OMX_S32 srcV4L2toOMX = 0;
+    OMX_S32 dstOMXtoV4L2 = 0;
+    OMX_S32 dstV4L2toOMX = 0;
+
+    OMX_S32 ETBFTB = 0;
+    OMX_S32 ETBFBD = 0;
+    OMX_S32 FTBFBD = 0;
+
+    OMX_S32 srcQdstQ = 0;
+    OMX_S32 srcQdstDQ = 0;
+    OMX_S32 dstQdstDQ = 0;
+
+    Exynos_OSAL_Memset(&srcBufferInfo, 0, sizeof(srcBufferInfo));
+    Exynos_OSAL_Memset(&dstBufferInfo, 0, sizeof(dstBufferInfo));
+
+    ret = Exynos_OSAL_GetPerfInfoUseTimestamp(hSrcPerfInfo, pBufferHeader->nTimeStamp, &srcBufferInfo);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Failed to GetPerfInfoUseTimestamp about src", __FUNCTION__);
+        return;
+    }
+
+    ret = Exynos_OSAL_GetPerfInfoUseTimestamp(hDstPerfInfo, pBufferHeader->nTimeStamp, &dstBufferInfo);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Failed to GetPerfInfoUseTimestamp about dst", __FUNCTION__);
+        return;
+    }
+
+    /* internal */
+    {
+        gettimeofday(&currentTime, NULL);
+
+        srcOMXtoV4L2 = Exynos_OSAL_MeasureTime(&(srcBufferInfo.currentTime), &(srcBufferInfo.queueTime)) / 1000;
+        //srcV4L2toOMX = Exynos_OSAL_MeasureTime(&(srcBufferInfo.queueTime), &(srcBufferInfo.?????????????????)) / 1000;
+
+        dstOMXtoV4L2 = Exynos_OSAL_MeasureTime(&(dstBufferInfo.currentTime), &(dstBufferInfo.queueTime)) / 1000;
+        dstV4L2toOMX = Exynos_OSAL_MeasureTime(&(dstBufferInfo.dequeueTime), &currentTime) / 1000;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s] INTERNAL: srcOMXtoV4L2:%d, srcV4L2toOMX:%d, dstOMXtoV4L2:%d, dstV4L2toOMX:%d",
+                                            __FUNCTION__, srcOMXtoV4L2, srcV4L2toOMX, dstOMXtoV4L2, dstV4L2toOMX);
+    }
+
+    /* vl42 */
+    {
+        srcQdstQ = Exynos_OSAL_MeasureTime(&(srcBufferInfo.queueTime), &(dstBufferInfo.queueTime)) / 1000;
+        srcQdstDQ = Exynos_OSAL_MeasureTime(&(srcBufferInfo.queueTime), &(dstBufferInfo.dequeueTime)) / 1000;
+        dstQdstDQ = Exynos_OSAL_MeasureTime(&(dstBufferInfo.queueTime), &(dstBufferInfo.dequeueTime)) / 1000;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s] V4L2: srcQdstQ:%d, srcQdstDQ:%d, dstQdstDQ:%d, src-V4L2QBufferCount:%d, dst-V4L2QBufferCount:%d",
+                                            __FUNCTION__, srcQdstQ, srcQdstDQ, dstQdstDQ, srcBufferInfo.nCountInV4L2, dstBufferInfo.nCountInV4L2);
+    }
+
+    /* buffer rotation */
+    {
+        ETBFTB = Exynos_OSAL_MeasureTime(&(srcBufferInfo.currentTime), &(dstBufferInfo.currentTime)) / 1000;
+        ETBFBD = Exynos_OSAL_MeasureTime(&(srcBufferInfo.currentTime), &currentTime) / 1000;
+        FTBFBD = Exynos_OSAL_MeasureTime(&(dstBufferInfo.currentTime), &currentTime) / 1000;
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s] BUFFER: ETBFTB:%d, ETBFBD:%d, FTBFBD:%d, src-OMXQBufferCount:%d, dst-OMXQBufferCount:%d",
+                                            __FUNCTION__, ETBFTB, ETBFBD, FTBFBD, srcBufferInfo.nCountInOMX, dstBufferInfo.nCountInOMX);
+
+        if (ETBFTB > 0) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] BUFFER: OUTPUT is slow!! real decode time:%d",
+                                                __FUNCTION__, FTBFBD / dstBufferInfo.nCountInOMX);
+        } else if (ETBFTB < 0) {
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] BUFFER: INPUT is slow!! real decode time:%d",
+                                                __FUNCTION__, ETBFBD / srcBufferInfo.nCountInOMX);
+        } else {
+            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%s] BUFFER: real decode time:%d or %d",
+                                                __FUNCTION__, ETBFBD / srcBufferInfo.nCountInOMX, FTBFBD / dstBufferInfo.nCountInOMX);
+        }
+    }
+
+    /* buffer interval */
+    {
+        OMX_S32 srcBufferInterval;
+        OMX_S32 dstBufferInterval;
+
+        srcBufferInterval = Exynos_OSAL_MeasureTime(&(srcBufferInfo.previousIncomingTime), &(srcBufferInfo.currentIncomingTime)) / 1000;
+        dstBufferInterval = Exynos_OSAL_MeasureTime(&(dstBufferInfo.previousIncomingTime), &(dstBufferInfo.currentIncomingTime)) / 1000;
+
+        if ((srcBufferInterval / (srcBufferInfo.OMXQBufferCount - 1)) > ((dstBufferInfo.timestamp - dstBufferInfo.previousTimeStamp) / 1000))
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PERFORM:: SLOW: Warning!! src buffer slow. srcBuffer Interval:%d, correct interval:%d, OMXQBufferCount:%d",
+                            srcBufferInterval,
+                            (srcBufferInfo.OMXQBufferCount == 1) ? srcBufferInterval : (srcBufferInterval / (srcBufferInfo.OMXQBufferCount - 1)),
+                            srcBufferInfo.OMXQBufferCount);
+        if ((dstBufferInterval / (dstBufferInfo.OMXQBufferCount - 1)) > ((dstBufferInfo.timestamp - dstBufferInfo.previousTimeStamp) / 1000))
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PERFORM:: SLOW: Warning!! dst buffer slow. dstBuffer Interval:%d, correct interval:%d, OMXQBufferCount:%d",
+                            dstBufferInterval,
+                            (dstBufferInfo.OMXQBufferCount == 1) ? dstBufferInterval : (dstBufferInterval / (dstBufferInfo.OMXQBufferCount - 1)),
+                            dstBufferInfo.OMXQBufferCount);
+    }
+
+    {
+        OMX_S32 srcTimestampInterval;
+        OMX_S32 dstTimestampInterval;
+
+        srcTimestampInterval = ((OMX_S32)(srcBufferInfo.timestamp - srcBufferInfo.previousTimeStamp)) / 1000;
+        dstTimestampInterval = ((OMX_S32)(dstBufferInfo.timestamp - dstBufferInfo.previousTimeStamp)) / 1000;
+
+        if ((srcTimestampInterval > 0) && (dstTimestampInterval > 0))
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PERFORM:: TYPE: Normal timestamp contents");
+        else if ((srcTimestampInterval < 0) && (dstTimestampInterval > 0))
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "PERFORM:: TYPE: PTS timestamp contents");
+        else if ((srcTimestampInterval > 0) && (dstTimestampInterval < 0))
+            Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "PERFORM:: TYPE: DTS timestamp contents");
+        else
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PERFORM:: TYPE: Timestamp is strange!!");
+    }
+
+/*
+    ptm = localtime (&srcBufferInfo.currentIncomingTime.tv_sec);
+    strftime (time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
+    milliseconds = srcBufferInfo.currentIncomingTime.tv_usec / 1000;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ETB time = %s.%03ld\n", time_string, milliseconds);
+
+    ptm = localtime (&dstBufferInfo.currentIncomingTime.tv_sec);
+    strftime (time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
+    milliseconds = dstBufferInfo.currentIncomingTime.tv_usec / 1000;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FTB time = %s.%03ld\n", time_string, milliseconds);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "return time = %d ms",
+                            Exynos_OSAL_MeasureTime(&(srcBufferInfo.currentIncomingTime), &(dstBufferInfo.currentIncomingTime)) / 1000);
+*/
+
+    return;
+}
+#endif
diff --git a/openmax/osal/Exynos_OSAL_ETC.h b/openmax/osal/Exynos_OSAL_ETC.h
new file mode 100755 (executable)
index 0000000..ff42181
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_ETC.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef Exynos_OSAL_ETC
+#define Exynos_OSAL_ETC
+
+#include "OMX_Types.h"
+#include "Exynos_OMX_Def.h"
+
+#ifdef PERFORMANCE_DEBUG
+#include <sys/time.h>
+#endif
+
+#define INT_TO_PTR(var) ((void *)(unsigned long)var)
+#define PTR_TO_INT(var) ((int)(unsigned long)var)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+size_t Exynos_OSAL_Strcpy(OMX_PTR dest, OMX_PTR src);
+OMX_S32 Exynos_OSAL_Strncmp(OMX_PTR str1, OMX_PTR str2, size_t num);
+OMX_S32 Exynos_OSAL_Strcmp(OMX_PTR str1, OMX_PTR str2);
+const char* Exynos_OSAL_Strstr(const char *str1, const char *str2);
+size_t Exynos_OSAL_Strcat(OMX_PTR dest, OMX_PTR src);
+size_t Exynos_OSAL_Strlen(const char *str);
+
+/* perf */
+typedef enum _PERF_ID_TYPE {
+    PERF_ID_CSC = 0,
+    PERF_ID_DEC,
+    PERF_ID_ENC,
+    PERF_ID_USER,
+    PERF_ID_MAX,
+} PERF_ID_TYPE;
+
+void Exynos_OSAL_PerfInit(PERF_ID_TYPE id);
+void Exynos_OSAL_PerfStart(PERF_ID_TYPE id);
+void Exynos_OSAL_PerfStop(PERF_ID_TYPE id);
+OMX_U32 Exynos_OSAL_PerfFrame(PERF_ID_TYPE id);
+OMX_U32 Exynos_OSAL_PerfTotal(PERF_ID_TYPE id);
+OMX_U32 Exynos_OSAL_PerfFrameCount(PERF_ID_TYPE id);
+int Exynos_OSAL_PerfOver30ms(PERF_ID_TYPE id);
+void Exynos_OSAL_PerfPrint(OMX_STRING prefix, PERF_ID_TYPE id);
+
+unsigned int Exynos_OSAL_GetPlaneCount(OMX_COLOR_FORMATTYPE eOMXFormat, PLANE_TYPE ePlaneType);
+void Exynos_OSAL_GetPlaneSize(OMX_COLOR_FORMATTYPE eColorFormat, PLANE_TYPE ePlaneType, OMX_U32 nWidth, OMX_U32 nHeight, unsigned int nDataLen[MAX_BUFFER_PLANE], unsigned int nAllocLen[MAX_BUFFER_PLANE]);
+
+int Exynos_OSAL_OMX2VideoFormat(OMX_COLOR_FORMATTYPE eColorFormat, PLANE_TYPE ePlaneType);
+OMX_COLOR_FORMATTYPE Exynos_OSAL_Video2OMXFormat(int nVideoFormat);
+
+OMX_COLOR_FORMATTYPE Exynos_OSAL_HAL2OMXColorFormat(unsigned int nHALFormat);
+unsigned int Exynos_OSAL_OMX2HALPixelFormat(OMX_COLOR_FORMATTYPE eOMXFormat, PLANE_TYPE ePlaneType);
+
+int Exynos_OSAL_DataSpaceToColorSpace(int nDataSpace);
+
+inline static const char *stateString(OMX_STATETYPE i) {
+     switch (i) {
+         case OMX_StateInvalid:                 return "OMX_StateInvaild";
+         case OMX_StateLoaded:                  return "OMX_StateLoaded";
+         case OMX_StateIdle:                    return "OMX_StateIdle";
+         case OMX_StateExecuting:               return "OMX_StateExecuting";
+         case OMX_StatePause:                   return "OMX_StatePause";
+         case OMX_StateWaitForResources:        return "OMX_StateWaitForResources";
+         default:                               return "??";
+     }
+}
+
+#ifdef PERFORMANCE_DEBUG
+void Exynos_OSAL_Get_Perf_Property();
+
+OMX_ERRORTYPE Exynos_OSAL_CountCreate(OMX_HANDLETYPE *hPerfInfo);
+void Exynos_OSAL_CountTerminate(OMX_HANDLETYPE *hPerfInfo);
+
+OMX_S32 Exynos_OSAL_CountIncrease(OMX_HANDLETYPE *hPerfInfo, OMX_BUFFERHEADERTYPE *pBufferHeader, int nPortIndex);
+OMX_S32 Exynos_OSAL_CountDecrease(OMX_HANDLETYPE *hPerfInfo, OMX_BUFFERHEADERTYPE *pBufferHeader, int nPortIndex);
+
+OMX_S32 Exynos_OSAL_V4L2CountIncrease(OMX_HANDLETYPE *hPerfInfo, OMX_BUFFERHEADERTYPE *pBufferHeader, int nPortIndex);
+OMX_S32 Exynos_OSAL_V4L2CountDecrease(OMX_HANDLETYPE *hPerfInfo, OMX_BUFFERHEADERTYPE *pBufferHeader, int nPortIndex);
+
+void Exynos_OSAL_CountReset(OMX_HANDLETYPE *hPerfInfo);
+
+void Exynos_OSAL_PrintPerfInfo(OMX_HANDLETYPE *hSrcPerfInfo, OMX_HANDLETYPE *hDstPerfInfo, OMX_BUFFERHEADERTYPE *pBufferHeader);
+//void Exynos_OSAL_PrintCountInfo(OMX_PTR *pStartHandle, BUFFER_TIME dstBufferInfo);
+//OMX_ERRORTYPE Exynos_OSAL_GetCountInfoUseOMXBuffer(OMX_HANDLETYPE hCountHandle, OMX_BUFFERHEADERTYPE *OMXBufferHeader, BUFFER_TIME *pBufferInfo);
+
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/osal/Exynos_OSAL_Event.c b/openmax/osal/Exynos_OSAL_Event.c
new file mode 100755 (executable)
index 0000000..88bdc88
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+*/
+
+/*
+ * @file        Exynos_OSAL_Event.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OSAL_Event.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "Exynos_OSAL_EVENT"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+OMX_ERRORTYPE Exynos_OSAL_SignalCreate(OMX_HANDLETYPE *eventHandle)
+{
+    Exynos_OSAL_THREADEVENT *event;
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    event = (Exynos_OSAL_THREADEVENT *)Exynos_OSAL_Malloc(sizeof(Exynos_OSAL_THREADEVENT));
+    if (!event) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Memset(event, 0, sizeof(Exynos_OSAL_THREADEVENT));
+    event->signal = OMX_FALSE;
+
+    ret = Exynos_OSAL_MutexCreate(&event->mutex);
+    if (ret != OMX_ErrorNone) {
+        Exynos_OSAL_Free(event);
+        goto EXIT;
+    }
+
+    if (pthread_cond_init(&event->condition, NULL)) {
+        Exynos_OSAL_MutexTerminate(event->mutex);
+        Exynos_OSAL_Free(event);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    *eventHandle = (OMX_HANDLETYPE)event;
+    ret = OMX_ErrorNone;
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SignalTerminate(OMX_HANDLETYPE eventHandle)
+{
+    Exynos_OSAL_THREADEVENT *event = (Exynos_OSAL_THREADEVENT *)eventHandle;
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if (!event) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_MutexLock(event->mutex);
+    if (ret != OMX_ErrorNone) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (pthread_cond_destroy(&event->condition)) {
+        Exynos_OSAL_MutexUnlock(event->mutex);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_MutexUnlock(event->mutex);
+    if (ret != OMX_ErrorNone) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_MutexTerminate(event->mutex);
+    if (ret != OMX_ErrorNone) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Free(event);
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SignalReset(OMX_HANDLETYPE eventHandle)
+{
+    Exynos_OSAL_THREADEVENT *event = (Exynos_OSAL_THREADEVENT *)eventHandle;
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if (!event) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_MutexLock(event->mutex);
+    if (ret != OMX_ErrorNone) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    event->signal = OMX_FALSE;
+
+    Exynos_OSAL_MutexUnlock(event->mutex);
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SignalSet(OMX_HANDLETYPE eventHandle)
+{
+    Exynos_OSAL_THREADEVENT *event = (Exynos_OSAL_THREADEVENT *)eventHandle;
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if (!event) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    ret = Exynos_OSAL_MutexLock(event->mutex);
+    if (ret != OMX_ErrorNone) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    event->signal = OMX_TRUE;
+    pthread_cond_signal(&event->condition);
+
+    Exynos_OSAL_MutexUnlock(event->mutex);
+
+EXIT:
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SignalWait(OMX_HANDLETYPE eventHandle, OMX_U32 ms)
+{
+    Exynos_OSAL_THREADEVENT *event = (Exynos_OSAL_THREADEVENT *)eventHandle;
+    OMX_ERRORTYPE         ret = OMX_ErrorNone;
+    struct timespec       timeout;
+    struct timeval        now;
+    int                   funcret = 0;
+    long tv_us, tv_ns;
+
+    FunctionIn();
+
+    if (!event) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    gettimeofday(&now, NULL);
+
+    tv_us = now.tv_usec + (ms * 1000);
+    timeout.tv_sec = now.tv_sec + (tv_us / 1000000);
+    tv_ns = (tv_us % 1000000) * 1000;
+    timeout.tv_nsec = tv_ns;
+
+    ret = Exynos_OSAL_MutexLock(event->mutex);
+    if (ret != OMX_ErrorNone) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (ms == 0) {
+        if (!event->signal)
+            ret = OMX_ErrorTimeout;
+    } else if (ms == DEF_MAX_WAIT_TIME) {
+        while (!event->signal)
+            pthread_cond_wait(&event->condition, (pthread_mutex_t *)(event->mutex));
+        ret = OMX_ErrorNone;
+    } else {
+        while (!event->signal) {
+            funcret = pthread_cond_timedwait(&event->condition, (pthread_mutex_t *)(event->mutex), &timeout);
+            if ((!event->signal) && (funcret == ETIMEDOUT)) {
+                ret = OMX_ErrorTimeout;
+                break;
+            }
+        }
+    }
+
+    Exynos_OSAL_MutexUnlock(event->mutex);
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
diff --git a/openmax/osal/Exynos_OSAL_Event.h b/openmax/osal/Exynos_OSAL_Event.h
new file mode 100755 (executable)
index 0000000..f7ccd89
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Event.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef Exynos_OSAL_EVENT
+#define Exynos_OSAL_EVENT
+
+#include <pthread.h>
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+
+
+#define DEF_MAX_WAIT_TIME 0xFFFFFFFF
+
+typedef struct _Exynos_OSAL_THREADEVENT
+{
+    OMX_BOOL       signal;
+    OMX_HANDLETYPE mutex;
+    pthread_cond_t condition;
+} Exynos_OSAL_THREADEVENT;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+OMX_ERRORTYPE Exynos_OSAL_SignalCreate(OMX_HANDLETYPE *eventHandle);
+OMX_ERRORTYPE Exynos_OSAL_SignalTerminate(OMX_HANDLETYPE eventHandle);
+OMX_ERRORTYPE Exynos_OSAL_SignalReset(OMX_HANDLETYPE eventHandle);
+OMX_ERRORTYPE Exynos_OSAL_SignalSet(OMX_HANDLETYPE eventHandle);
+OMX_ERRORTYPE Exynos_OSAL_SignalWait(OMX_HANDLETYPE eventHandle, OMX_U32 ms);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/osal/Exynos_OSAL_Library.c b/openmax/osal/Exynos_OSAL_Library.c
new file mode 100755 (executable)
index 0000000..87fef61
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Library.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <sys/utsname.h>
+
+#include "Exynos_OSAL_Library.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Memory.h"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG  "EXYNOS_OSAL_LIB"
+#include "Exynos_OSAL_Log.h"
+
+void *Exynos_OSAL_dlopen(const char *filename, int flag)
+{
+    return dlopen(filename, flag);
+}
+
+void *Exynos_OSAL_dlsym(void *handle, const char *symbol)
+{
+    return dlsym(handle, symbol);
+}
+
+int Exynos_OSAL_dlclose(void *handle)
+{
+    return dlclose(handle);
+}
+
+const char *Exynos_OSAL_dlerror(void)
+{
+    return dlerror();
+}
+
+const char *Exynos_OSAL_GetLibPath(void)
+{
+#ifdef USE_ANDROID
+    const char *LIB_INSTALL_PATH    = "/vendor/lib/omx/";
+    const char *LIB64_INSTALL_PATH  = "/vendor/lib64/omx/";
+#else
+    const char *LIB_INSTALL_PATH     = "/usr/lib/omx/";
+    const char *LIB64_INSTALL_PATH   = "/usr/lib/omx/";
+#endif
+
+    return (IS_64BIT_OS)? LIB64_INSTALL_PATH:LIB_INSTALL_PATH;
+}
+
+int Exynos_OSAL_CheckLibName(char *pLibName)
+{
+    if (pLibName == NULL)
+        return -1;
+
+    /* it should be started as "libOMX.Exynos." */
+    if (Exynos_OSAL_Strncmp(pLibName, "libOMX.Exynos.", Exynos_OSAL_Strlen("libOMX.Exynos.")) == 0) {
+        /* it should be delimited as ".so" */
+        char *pExtPosit =(((char *)pLibName) + (Exynos_OSAL_Strlen(pLibName) - 3));
+        if (Exynos_OSAL_Strncmp(pExtPosit, ".so", Exynos_OSAL_Strlen(".so")) == 0)
+            return 0;
+    }
+
+    return -1;
+}
diff --git a/openmax/osal/Exynos_OSAL_Library.h b/openmax/osal/Exynos_OSAL_Library.h
new file mode 100755 (executable)
index 0000000..62c5c89
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file       Exynos_OSAL_Library.h
+ * @brief
+ * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *    2012.02.20 : Create
+ */
+
+#ifndef Exynos_OSAL_LIBRARY
+#define Exynos_OSAL_LIBRARY
+
+#include "OMX_Types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *Exynos_OSAL_dlopen(const char *filename, int flag);
+void *Exynos_OSAL_dlsym(void *handle, const char *symbol);
+int   Exynos_OSAL_dlclose(void *handle);
+const char *Exynos_OSAL_dlerror(void);
+const char *Exynos_OSAL_GetLibPath(void);
+int Exynos_OSAL_CheckLibName(char *pLibName);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/osal/Exynos_OSAL_Log.c b/openmax/osal/Exynos_OSAL_Log.c
new file mode 100755 (executable)
index 0000000..376d8bc
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Log.c
+ * @brief
+ * @author      Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+//#include <utils/Log.h>
+//#include <cutils/properties.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Exynos_OSAL_Log.h"
+#include "Exynos_OSAL_ETC.h"
+
+#ifdef USE_DLOG
+#include <dlog.h>
+#else
+#define SLOG_VA(level, tag, msg, ...) vprintf(msg, __VA_ARGS__)
+#endif
+
+/* =======TAG=========
+EXYNOS_RM
+EXYNOS_LOG
+EXYNOS_COMP_REGS
+EXYNOS_OMX_CORE
+EXYNOS_LOG_THREAD
+EXYNOS_LOG_SEMA
+Exynos_OSAL_SkypeHD
+Exynos_OSAL_Android
+Exynos_OSAL_EVENT
+EXYNOS_BASE_COMP
+EXYNOS_BASE_PORT
+EXYNOS_VIDEO_DEC
+EXYNOS_VIDEO_DECCONTROL
+EXYNOS_H264_DEC
+EXYNOS_HEVC_DEC
+EXYNOS_MPEG2_DEC
+EXYNOS_MPEG4_DEC
+EXYNOS_WMV_DEC
+EXYNOS_VP8_DEC
+EXYNOS_VP9_DEC
+EXYNOS_VIDEO_ENC
+EXYNOS_VIDEO_ENCCONTROL
+EXYNOS_HEVC_ENC
+EXYNOS_H264_ENC
+EXYNOS_MPEG4_ENC
+EXYNOS_VP8_ENC
+EXYNOS_VP9_ENC
+======================*/
+static char debugProp[PROPERTY_VALUE_MAX];
+typedef enum _DEBUG_LEVEL
+{
+    LOG_LEVEL_ALL = EXYNOS_LOG_FUNC_TRACE,
+    LOG_LEVEL2    = EXYNOS_LOG_TRACE,
+    LOG_LEVEL1    = EXYNOS_LOG_ESSENTIAL,
+    LOG_DEFAULT   = EXYNOS_LOG_INFO,
+    LOG_LEVELTAG,
+} EXYNOS_DEBUG_LEVEL;
+
+static unsigned int log_prop = LOG_DEFAULT;
+
+void Exynos_OSAL_Get_Log_Property()
+{
+#ifdef USE_ANDROID
+    if (property_get("debug.omx.level", debugProp, NULL) > 0) {
+#else
+    if (getenv("OMX_DEBUG") != NULL) {
+        Exynos_OSAL_Memset(debugProp, 0, sizeof(debugProp));
+        Exynos_OSAL_Strcpy(debugProp, getenv("OMX_DEBUG"));
+#endif
+        if(!(Exynos_OSAL_Strncmp(debugProp, "0", 1))) {
+            log_prop = LOG_DEFAULT;
+        } else if (!(Exynos_OSAL_Strncmp(debugProp, "1", 1))) {
+            log_prop = LOG_LEVEL1;
+        } else if (!(Exynos_OSAL_Strncmp(debugProp, "2", 1))) {
+            log_prop = LOG_LEVEL2;
+        } else if (!(Exynos_OSAL_Strncmp(debugProp, "3", 1))) {
+            log_prop = LOG_LEVEL_ALL;
+        } else {
+            log_prop = LOG_LEVELTAG;
+        }
+    }
+}
+
+void _Exynos_OSAL_Log(EXYNOS_LOG_LEVEL logLevel, const char *tag, const char *msg, ...)
+{
+    va_list argptr;
+#ifdef EXYNOS_LOG
+    if (log_prop == LOG_LEVELTAG) {
+        if(!Exynos_OSAL_Strstr(debugProp, tag))
+            return;
+    } else if (logLevel < log_prop)
+        return;
+#endif
+    va_start(argptr, msg);
+
+    switch (logLevel) {
+    case EXYNOS_LOG_FUNC_TRACE:
+        SLOG_VA(LOG_DEBUG, EXYNOS_LOG_TAG, msg, argptr);
+        break;
+    case EXYNOS_LOG_TRACE:
+        SLOG_VA(LOG_DEBUG, EXYNOS_LOG_TAG, msg, argptr);
+        break;
+    case EXYNOS_LOG_ESSENTIAL:
+    case EXYNOS_LOG_INFO:
+        SLOG_VA(LOG_INFO, EXYNOS_LOG_TAG, msg, argptr);
+        break;
+    case EXYNOS_LOG_WARNING:
+        SLOG_VA(LOG_WARN, EXYNOS_LOG_TAG, msg, argptr);
+        break;
+    case EXYNOS_LOG_ERROR:
+        SLOG_VA(LOG_ERROR, EXYNOS_LOG_TAG, msg, argptr);
+        break;
+    default:
+        SLOG_VA(LOG_DEBUG, EXYNOS_LOG_TAG, msg, argptr);
+    }
+
+    va_end(argptr);
+}
diff --git a/openmax/osal/Exynos_OSAL_Log.h b/openmax/osal/Exynos_OSAL_Log.h
new file mode 100755 (executable)
index 0000000..6df44e8
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Log.h
+ * @brief
+ * @author      Yunji Kim (yunji.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ *   2012.8.27 : Add trace function
+ */
+
+#ifndef EXYNOS_OSAL_LOG
+#define EXYNOS_OSAL_LOG
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef EXYNOS_LOG_OFF
+#define EXYNOS_LOG
+#endif
+
+#ifndef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "OMX_LOG"
+#endif
+
+#define EXYNOS_TRACE_FUNCTION_INFO
+
+#ifndef USE_ANDROID
+#define PROPERTY_KEY_MAX 32
+#define PROPERTY_VALUE_MAX 92
+#endif
+
+typedef enum _LOG_LEVEL
+{
+    EXYNOS_LOG_FUNC_TRACE,
+    EXYNOS_LOG_TRACE,
+    EXYNOS_LOG_ESSENTIAL,
+    EXYNOS_LOG_INFO,
+    EXYNOS_LOG_WARNING,
+    EXYNOS_LOG_ERROR
+} EXYNOS_LOG_LEVEL;
+
+#ifdef EXYNOS_LOG
+#define Exynos_OSAL_Log(a, ...)    ((void)_Exynos_OSAL_Log(a, EXYNOS_LOG_TAG, __VA_ARGS__))
+#else
+#define Exynos_OSAL_Log(a, ...)                                                \
+    do {                                                                \
+        if ((a == EXYNOS_LOG_ERROR) ||                                  \
+            (a == EXYNOS_LOG_WARNING))                                  \
+            ((void)_Exynos_OSAL_Log(a, EXYNOS_LOG_TAG, __VA_ARGS__)); \
+    } while (0)
+#endif
+
+#ifdef EXYNOS_TRACE_FUNCTION_INFO
+#define FunctionIn() _Exynos_OSAL_Log(EXYNOS_LOG_FUNC_TRACE, EXYNOS_LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__)
+#define FunctionOut() _Exynos_OSAL_Log(EXYNOS_LOG_FUNC_TRACE, EXYNOS_LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__)
+#else
+#define FunctionIn() ((void *)0)
+#define FunctionOut() ((void *)0)
+#endif
+
+void Exynos_OSAL_Get_Log_Property();
+void _Exynos_OSAL_Log(EXYNOS_LOG_LEVEL logLevel, const char *tag, const char *msg, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/osal/Exynos_OSAL_Memory.c b/openmax/osal/Exynos_OSAL_Memory.c
new file mode 100755 (executable)
index 0000000..28006a6
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Memory.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include "Exynos_OSAL_Memory.h"
+
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+static int mem_cnt = 0;
+
+OMX_PTR Exynos_OSAL_Malloc(OMX_U32 size)
+{
+    OMX_PTR addr = NULL;
+
+    addr = (OMX_PTR)malloc(size);
+    if (addr != NULL) {
+        mem_cnt++;
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, mem_cnt);
+    }
+
+    return addr;
+}
+
+void Exynos_OSAL_Free(OMX_PTR addr)
+{
+    if (addr) {
+        free(addr);
+        mem_cnt--;
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, mem_cnt);
+    }
+
+    return;
+}
+
+OMX_PTR Exynos_OSAL_Memset(OMX_PTR dest, OMX_S32 c, OMX_S32 n)
+{
+    return memset(dest, c, n);
+}
+
+OMX_PTR Exynos_OSAL_Memcpy(OMX_PTR dest, OMX_PTR src, OMX_S32 n)
+{
+    return memcpy(dest, src, n);
+}
+
+OMX_PTR Exynos_OSAL_Memmove(OMX_PTR dest, OMX_PTR src, OMX_S32 n)
+{
+    return memmove(dest, src, n);
+}
+
+OMX_S32 Exynos_OSAL_Memcmp(OMX_PTR dest, OMX_PTR src, OMX_S32 n)
+{
+    return memcmp(dest, src, n);
+}
+
+OMX_PTR Exynos_OSAL_Mmap(OMX_PTR addr, size_t length, OMX_S32 prot, OMX_S32 flags, unsigned long fd, off_t offset)
+{
+    return mmap(addr, length, prot, flags, fd, offset);
+}
+
+OMX_S32 Exynos_OSAL_Munmap(OMX_PTR addr, size_t length)
+{
+    return munmap(addr, length);
+}
diff --git a/openmax/osal/Exynos_OSAL_Memory.h b/openmax/osal/Exynos_OSAL_Memory.h
new file mode 100755 (executable)
index 0000000..73cae7d
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Memory.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef Exynos_OSAL_MEMORY
+#define Exynos_OSAL_MEMORY
+
+#include "OMX_Types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_PTR Exynos_OSAL_Malloc(OMX_U32 size);
+void    Exynos_OSAL_Free(OMX_PTR addr);
+OMX_PTR Exynos_OSAL_Memset(OMX_PTR dest, OMX_S32 c, OMX_S32 n);
+OMX_PTR Exynos_OSAL_Memcpy(OMX_PTR dest, OMX_PTR src, OMX_S32 n);
+OMX_PTR Exynos_OSAL_Memmove(OMX_PTR dest, OMX_PTR src, OMX_S32 n);
+OMX_S32 Exynos_OSAL_Memcmp(OMX_PTR dest, OMX_PTR src, OMX_S32 n);
+OMX_PTR Exynos_OSAL_Mmap(OMX_PTR addr, size_t length, OMX_S32 prot, OMX_S32 flags, unsigned long fd, off_t offset);
+OMX_S32 Exynos_OSAL_Munmap(OMX_PTR addr, size_t length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/openmax/osal/Exynos_OSAL_Mutex.c b/openmax/osal/Exynos_OSAL_Mutex.c
new file mode 100755 (executable)
index 0000000..511a715
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Mutex.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_Mutex.h"
+
+OMX_ERRORTYPE Exynos_OSAL_MutexCreate(OMX_HANDLETYPE *mutexHandle)
+{
+    pthread_mutex_t *mutex;
+
+    mutex = (pthread_mutex_t *)Exynos_OSAL_Malloc(sizeof(pthread_mutex_t));
+    if (!mutex)
+        return OMX_ErrorInsufficientResources;
+
+    if (pthread_mutex_init(mutex, NULL) != 0) {
+        Exynos_OSAL_Free(mutex);
+        return OMX_ErrorUndefined;
+    }
+
+    *mutexHandle = (OMX_HANDLETYPE)mutex;
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_MutexTerminate(OMX_HANDLETYPE mutexHandle)
+{
+    pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle;
+
+    if (mutex == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (pthread_mutex_destroy(mutex) != 0)
+        return OMX_ErrorUndefined;
+
+    Exynos_OSAL_Free(mutex);
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_MutexLock(OMX_HANDLETYPE mutexHandle)
+{
+    pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle;
+
+    if (mutex == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (pthread_mutex_lock(mutex) != 0)
+        return OMX_ErrorUndefined;
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_MutexUnlock(OMX_HANDLETYPE mutexHandle)
+{
+    pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle;
+
+    if (mutex == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (pthread_mutex_unlock(mutex) != 0)
+        return OMX_ErrorUndefined;
+
+    return OMX_ErrorNone;
+}
diff --git a/openmax/osal/Exynos_OSAL_Mutex.h b/openmax/osal/Exynos_OSAL_Mutex.h
new file mode 100755 (executable)
index 0000000..d8875ed
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Mutex.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+*/
+
+#ifndef Exynos_OSAL_MUTEX
+#define Exynos_OSAL_MUTEX
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_ERRORTYPE Exynos_OSAL_MutexCreate(OMX_HANDLETYPE *mutexHandle);
+OMX_ERRORTYPE Exynos_OSAL_MutexTerminate(OMX_HANDLETYPE mutexHandle);
+OMX_ERRORTYPE Exynos_OSAL_MutexLock(OMX_HANDLETYPE mutexHandle);
+OMX_ERRORTYPE Exynos_OSAL_MutexUnlock(OMX_HANDLETYPE mutexHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/osal/Exynos_OSAL_Platform.h b/openmax/osal/Exynos_OSAL_Platform.h
new file mode 100755 (executable)
index 0000000..9901134
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2016 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Platform.h
+ * @brief
+ * @author      Taehwan Kim (t_h.kim@samsung.com)
+ * @version     1.0.0
+ * @history
+ *   2016.07.06 : Create
+ */
+
+#ifndef Exynos_OSAL_PLATFORM
+#define Exynos_OSAL_PLATFORM
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+#include "OMX_Index.h"
+#include "Exynos_OSAL_SharedMemory.h"
+
+#include "Exynos_OSAL_Tizen.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+OMX_ERRORTYPE Exynos_OSAL_GetParameter(OMX_IN OMX_HANDLETYPE hComponent,
+                                       OMX_IN OMX_INDEXTYPE nIndex,
+                                       OMX_INOUT OMX_PTR pComponentParameterStructure);
+OMX_ERRORTYPE Exynos_OSAL_SetParameter(OMX_IN OMX_HANDLETYPE hComponent,
+                                       OMX_IN OMX_INDEXTYPE nIndex,
+                                       OMX_IN OMX_PTR pComponentParameterStructure);
+
+#ifdef USE_ANDROID  // Addition for non-used functions in Tizen
+OMX_ERRORTYPE Exynos_OSAL_GetConfig(OMX_IN OMX_HANDLETYPE hComponent,
+                                    OMX_IN OMX_INDEXTYPE nIndex,
+                                    OMX_INOUT OMX_PTR pComponentConfigStructure);
+OMX_ERRORTYPE Exynos_OSAL_SetConfig(OMX_IN OMX_HANDLETYPE hComponent,
+                                    OMX_IN OMX_INDEXTYPE nIndex,
+                                    OMX_IN OMX_PTR pComponentConfigStructure);
+#endif //USE_ANDROID
+
+OMX_ERRORTYPE Exynos_OSAL_LockMetaData(OMX_IN OMX_PTR pBuffer,
+                                       OMX_IN EXYNOS_OMX_LOCK_RANGE range,
+                                       OMX_OUT OMX_U32 *pStride,
+                                       OMX_OUT EXYNOS_OMX_MULTIPLANE_BUFFER *pBufferInfo,
+                                       OMX_IN EXYNOS_METADATA_TYPE eMetaType);
+OMX_ERRORTYPE Exynos_OSAL_UnlockMetaData(OMX_IN OMX_PTR pBuffer,
+                                         OMX_IN EXYNOS_METADATA_TYPE eMetaType);
+
+OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(OMX_IN OMX_PTR pBuffer, OMX_OUT EXYNOS_OMX_MULTIPLANE_BUFFER *pBufferInfo, OMX_IN EXYNOS_METADATA_TYPE eMetaDataType);
+
+OMX_PTR Exynos_OSAL_AllocMetaDataBuffer(OMX_HANDLETYPE hSharedMemory, EXYNOS_METADATA_TYPE eMetaDataType, OMX_U32 nSizeBytes, MEMORY_TYPE eMemoryType);
+OMX_ERRORTYPE Exynos_OSAL_FreeMetaDataBuffer(OMX_HANDLETYPE hSharedMemory, EXYNOS_METADATA_TYPE eMetaDataType, OMX_PTR pTempBuffer);
+
+// Porting exynos 9110, code from SM-R765(7270), But not used
+OMX_ERRORTYPE Exynos_OSAL_SetDataLengthToMetaData(OMX_IN OMX_BYTE pBuffer, OMX_IN OMX_U32 dataLength, OMX_IN EXYNOS_METADATA_TYPE eMetaDataType);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openmax/osal/Exynos_OSAL_Queue.c b/openmax/osal/Exynos_OSAL_Queue.c
new file mode 100755 (executable)
index 0000000..024111c
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Queue.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OSAL_Queue.h"
+
+
+OMX_ERRORTYPE Exynos_OSAL_QueueCreate(EXYNOS_QUEUE *queueHandle, int maxNumElem)
+{
+    int i = 0;
+    EXYNOS_QElem *newqelem = NULL;
+    EXYNOS_QElem *currentqelem = NULL;
+    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
+
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if (!queue)
+        return OMX_ErrorBadParameter;
+
+    ret = Exynos_OSAL_MutexCreate(&queue->qMutex);
+    if (ret != OMX_ErrorNone)
+        return ret;
+
+    queue->first = (EXYNOS_QElem *)Exynos_OSAL_Malloc(sizeof(EXYNOS_QElem));
+    if (queue->first == NULL)
+        return OMX_ErrorInsufficientResources;
+
+    Exynos_OSAL_Memset(queue->first, 0, sizeof(EXYNOS_QElem));
+    currentqelem = queue->last = queue->first;
+    queue->numElem = 0;
+    queue->maxNumElem = maxNumElem;
+    for (i = 0; i < (queue->maxNumElem - 2); i++) {
+        newqelem = (EXYNOS_QElem *)Exynos_OSAL_Malloc(sizeof(EXYNOS_QElem));
+        if (newqelem == NULL) {
+            while (queue->first != NULL) {
+                currentqelem = queue->first->qNext;
+                Exynos_OSAL_Free((OMX_PTR)queue->first);
+                queue->first = currentqelem;
+            }
+            return OMX_ErrorInsufficientResources;
+        } else {
+            Exynos_OSAL_Memset(newqelem, 0, sizeof(EXYNOS_QElem));
+            currentqelem->qNext = newqelem;
+            currentqelem = newqelem;
+        }
+    }
+
+    currentqelem->qNext = queue->first;
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_QueueTerminate(EXYNOS_QUEUE *queueHandle)
+{
+    int i = 0;
+    EXYNOS_QElem *currentqelem = NULL;
+    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    if (!queue)
+        return OMX_ErrorBadParameter;
+
+    for ( i = 0; i < (queue->maxNumElem - 2); i++) {
+        if (queue->first == NULL)
+            goto EXIT;
+        currentqelem = queue->first->qNext;
+        Exynos_OSAL_Free(queue->first);
+        queue->first = currentqelem;
+    }
+
+    if(queue->first) {
+        Exynos_OSAL_Free(queue->first);
+        queue->first = NULL;
+    }
+
+EXIT:
+    ret = Exynos_OSAL_MutexTerminate(queue->qMutex);
+    queue->qMutex = NULL;
+
+    return ret;
+}
+
+int Exynos_OSAL_Queue(EXYNOS_QUEUE *queueHandle, void *data)
+{
+    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
+    if (queue == NULL)
+        return -1;
+
+    Exynos_OSAL_MutexLock(queue->qMutex);
+
+    if ((queue->last == NULL) ||
+        (queue->last->data != NULL) ||
+        (queue->numElem >= queue->maxNumElem)) {
+        Exynos_OSAL_MutexUnlock(queue->qMutex);
+        return -1;
+    }
+    queue->last->data = data;
+    queue->last = queue->last->qNext;
+    queue->numElem++;
+
+    Exynos_OSAL_MutexUnlock(queue->qMutex);
+    return 0;
+}
+
+void *Exynos_OSAL_Dequeue(EXYNOS_QUEUE *queueHandle)
+{
+    void *data = NULL;
+    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
+    if (queue == NULL)
+        return NULL;
+
+    Exynos_OSAL_MutexLock(queue->qMutex);
+
+    if ((queue->first->data == NULL) || (queue->numElem <= 0)) {
+        Exynos_OSAL_MutexUnlock(queue->qMutex);
+        return NULL;
+    }
+    data = queue->first->data;
+    queue->first->data = NULL;
+    queue->first = queue->first->qNext;
+    queue->numElem--;
+
+    Exynos_OSAL_MutexUnlock(queue->qMutex);
+    return data;
+}
+
+int Exynos_OSAL_GetElemNum(EXYNOS_QUEUE *queueHandle)
+{
+    int ElemNum = 0;
+    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
+    if (queue == NULL)
+        return -1;
+
+    Exynos_OSAL_MutexLock(queue->qMutex);
+    ElemNum = queue->numElem;
+    Exynos_OSAL_MutexUnlock(queue->qMutex);
+    return ElemNum;
+}
+
+int Exynos_OSAL_SetElemNum(EXYNOS_QUEUE *queueHandle, int ElemNum)
+{
+    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
+    if (queue == NULL)
+        return -1;
+
+    Exynos_OSAL_MutexLock(queue->qMutex);
+    queue->numElem = ElemNum;
+    Exynos_OSAL_MutexUnlock(queue->qMutex);
+    return ElemNum;
+}
+
+int Exynos_OSAL_ResetQueue(EXYNOS_QUEUE *queueHandle)
+{
+    EXYNOS_QUEUE *queue = (EXYNOS_QUEUE *)queueHandle;
+    EXYNOS_QElem *currentqelem = NULL;
+
+    if (queue == NULL)
+        return -1;
+
+    Exynos_OSAL_MutexLock(queue->qMutex);
+    queue->first->data = NULL;
+    currentqelem = queue->first->qNext;
+    while (currentqelem != queue->first) {
+        currentqelem->data = NULL;
+        currentqelem = currentqelem->qNext;
+    }
+    queue->last = queue->first;
+    queue->numElem = 0x00;
+    Exynos_OSAL_MutexUnlock(queue->qMutex);
+
+    return 0;
+}
diff --git a/openmax/osal/Exynos_OSAL_Queue.h b/openmax/osal/Exynos_OSAL_Queue.h
new file mode 100755 (executable)
index 0000000..6300b45
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file    Exynos_OSAL_Queue.h
+ * @brief
+ * @author    SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version    2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OSAL_QUEUE
+#define EXYNOS_OSAL_QUEUE
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+
+#define QUEUE_ELEMENTS        10
+#define MAX_QUEUE_ELEMENTS    40
+
+typedef struct _EXYNOS_QElem
+{
+    void             *data;
+    struct _EXYNOS_QElem *qNext;
+} EXYNOS_QElem;
+
+typedef struct _EXYNOS_QUEUE
+{
+    EXYNOS_QElem     *first;
+    EXYNOS_QElem     *last;
+    int            numElem;
+    int            maxNumElem;
+    OMX_HANDLETYPE qMutex;
+} EXYNOS_QUEUE;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_ERRORTYPE Exynos_OSAL_QueueCreate(EXYNOS_QUEUE *queueHandle, int maxNumElem);
+OMX_ERRORTYPE Exynos_OSAL_QueueTerminate(EXYNOS_QUEUE *queueHandle);
+int           Exynos_OSAL_Queue(EXYNOS_QUEUE *queueHandle, void *data);
+void         *Exynos_OSAL_Dequeue(EXYNOS_QUEUE *queueHandle);
+int           Exynos_OSAL_GetElemNum(EXYNOS_QUEUE *queueHandle);
+int           Exynos_OSAL_SetElemNum(EXYNOS_QUEUE *queueHandle, int ElemNum);
+int           Exynos_OSAL_ResetQueue(EXYNOS_QUEUE *queueHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/osal/Exynos_OSAL_Semaphore.c b/openmax/osal/Exynos_OSAL_Semaphore.c
new file mode 100755 (executable)
index 0000000..d454730
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Semaphore.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_Thread.h"
+#include "Exynos_OSAL_Semaphore.h"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_LOG_SEMA"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+OMX_ERRORTYPE Exynos_OSAL_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle)
+{
+    sem_t *sema;
+
+    sema = (sem_t *)Exynos_OSAL_Malloc(sizeof(sem_t));
+    if (!sema)
+        return OMX_ErrorInsufficientResources;
+
+    if (sem_init(sema, 0, 0) != 0) {
+        Exynos_OSAL_Free(sema);
+        return OMX_ErrorUndefined;
+    }
+
+    *semaphoreHandle = (OMX_HANDLETYPE)sema;
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_destroy(sema) != 0)
+        return OMX_ErrorUndefined;
+
+    Exynos_OSAL_Free(sema);
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+
+    FunctionIn();
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_wait(sema) != 0)
+        return OMX_ErrorUndefined;
+
+    FunctionOut();
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SemaphoreTryWait(OMX_HANDLETYPE semaphoreHandle)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+
+    FunctionIn();
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_trywait(sema) != 0)
+        return OMX_ErrorUndefined;
+
+    FunctionOut();
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SemaphorePost(OMX_HANDLETYPE semaphoreHandle)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+
+    FunctionIn();
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_post(sema) != 0)
+        return OMX_ErrorUndefined;
+
+    FunctionOut();
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val)
+{
+    if (semaphoreHandle == NULL)
+        return OMX_ErrorBadParameter;
+
+    while (semaphoreHandle != NULL) {
+        OMX_S32 cnt = 0;
+        Exynos_OSAL_Get_SemaphoreCount(semaphoreHandle, &cnt);
+
+        if (cnt == val)
+            break;
+        else if (cnt > val)
+            Exynos_OSAL_SemaphoreWait(semaphoreHandle);
+        else if (cnt < val)
+            Exynos_OSAL_SemaphorePost(semaphoreHandle);
+
+        Exynos_OSAL_SleepMillisec(0);
+    }
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+    int semaVal = 0;
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_getvalue(sema, &semaVal) != 0)
+        return OMX_ErrorUndefined;
+
+    *val = (OMX_S32)semaVal;
+
+    return OMX_ErrorNone;
+}
diff --git a/openmax/osal/Exynos_OSAL_Semaphore.h b/openmax/osal/Exynos_OSAL_Semaphore.h
new file mode 100755 (executable)
index 0000000..8618407
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Semaphore.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef Exynos_OSAL_SEMAPHORE
+#define Exynos_OSAL_SEMAPHORE
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_ERRORTYPE Exynos_OSAL_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle);
+OMX_ERRORTYPE Exynos_OSAL_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle);
+OMX_ERRORTYPE Exynos_OSAL_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle);
+OMX_ERRORTYPE Exynos_OSAL_SemaphoreTryWait(OMX_HANDLETYPE semaphoreHandle);
+OMX_ERRORTYPE Exynos_OSAL_SemaphorePost(OMX_HANDLETYPE semaphoreHandle);
+OMX_ERRORTYPE Exynos_OSAL_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val);
+OMX_ERRORTYPE Exynos_OSAL_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/osal/Exynos_OSAL_SharedMemory.c b/openmax/osal/Exynos_OSAL_SharedMemory.c
new file mode 100755 (executable)
index 0000000..1d338b2
--- /dev/null
@@ -0,0 +1,550 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_SharedMemory.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Jinsung Yang (jsgood.yang@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <pthread.h>
+#ifdef USE_ANDROID
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#endif
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include <../libion/kernel-headers/linux/ion.h>
+#include "exynos_ion.h"
+
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_SharedMemory.h"
+
+#include "Exynos_OSAL_ETC.h"
+
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+static int mem_cnt = 0;
+static int map_cnt = 0;
+
+struct EXYNOS_SHAREDMEM_LIST;
+typedef struct _EXYNOS_SHAREDMEM_LIST
+{
+    unsigned long                  IONBuffer;
+    OMX_PTR                        mapAddr;
+    OMX_U32                        allocSize;
+    OMX_BOOL                       owner;
+    struct _EXYNOS_SHAREDMEM_LIST *pNextMemory;
+} EXYNOS_SHAREDMEM_LIST;
+
+typedef struct _EXYNOS_SHARED_MEMORY
+{
+    unsigned long          hIONHandle;
+    EXYNOS_SHAREDMEM_LIST *pAllocMemory;
+    OMX_HANDLETYPE         hSMMutex;
+} EXYNOS_SHARED_MEMORY;
+
+
+OMX_HANDLETYPE Exynos_OSAL_SharedMemory_Open()
+{
+    EXYNOS_SHARED_MEMORY *pHandle   = NULL;
+    long                  IONClient = -1;
+
+    pHandle = (EXYNOS_SHARED_MEMORY *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHARED_MEMORY));
+    if (pHandle == NULL)
+        goto EXIT;
+    Exynos_OSAL_Memset(pHandle, 0, sizeof(EXYNOS_SHARED_MEMORY));
+
+    IONClient = (long)ion_open();
+    if (IONClient < 0) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_open is failed: %d", IONClient);
+        Exynos_OSAL_Free((void *)pHandle);
+        pHandle = NULL;
+        goto EXIT;
+    }
+
+    pHandle->hIONHandle = (unsigned long)IONClient;
+
+    if (OMX_ErrorNone != Exynos_OSAL_MutexCreate(&pHandle->hSMMutex)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_MutexCreate", __FUNCTION__);
+        /* free a ion_client */
+        ion_close(pHandle->hIONHandle);
+        pHandle->hIONHandle = 0;
+
+        Exynos_OSAL_Free((void *)pHandle);
+        pHandle = NULL;
+    }
+
+EXIT:
+    return (OMX_HANDLETYPE)pHandle;
+}
+
+void Exynos_OSAL_SharedMemory_Close(OMX_HANDLETYPE handle)
+{
+    EXYNOS_SHARED_MEMORY  *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
+    EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
+    EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
+    EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL;
+
+    if (pHandle == NULL)
+        goto EXIT;
+
+    Exynos_OSAL_MutexLock(pHandle->hSMMutex);
+    pCurrentElement = pSMList = pHandle->pAllocMemory;
+
+    while (pCurrentElement != NULL) {
+        pDeleteElement = pCurrentElement;
+        pCurrentElement = pCurrentElement->pNextMemory;
+
+        /* if mmap was not called, mapAddr is same as IONBuffer */
+        if (pDeleteElement->mapAddr != (void *)pDeleteElement->IONBuffer) {
+            if (Exynos_OSAL_Munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize))
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Munmap", __FUNCTION__);
+        }
+
+        pDeleteElement->mapAddr = NULL;
+        pDeleteElement->allocSize = 0;
+
+        if (pDeleteElement->owner) {
+            /* free a ion_buffer */
+            ion_close(pDeleteElement->IONBuffer);
+            mem_cnt--;
+        }
+        pDeleteElement->IONBuffer = 0;
+
+        Exynos_OSAL_Free(pDeleteElement);
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, mem_cnt);
+    }
+
+    pHandle->pAllocMemory = pSMList = NULL;
+    Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+
+    Exynos_OSAL_MutexTerminate(pHandle->hSMMutex);
+    pHandle->hSMMutex = NULL;
+
+    /* free a ion_client */
+    ion_close(pHandle->hIONHandle);
+    pHandle->hIONHandle = 0;
+
+    Exynos_OSAL_Free(pHandle);
+
+EXIT:
+    return;
+}
+
+OMX_PTR Exynos_OSAL_SharedMemory_Alloc(OMX_HANDLETYPE handle, OMX_U32 size, MEMORY_TYPE memoryType)
+{
+    EXYNOS_SHARED_MEMORY  *pHandle         = (EXYNOS_SHARED_MEMORY *)handle;
+    EXYNOS_SHAREDMEM_LIST *pSMList         = NULL;
+    EXYNOS_SHAREDMEM_LIST *pElement        = NULL;
+    EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
+    unsigned long          IONBuffer       = 0;
+    OMX_PTR                pBuffer         = NULL;
+    unsigned int mask;
+    unsigned int flag;
+
+    if (pHandle == NULL)
+        goto EXIT;
+
+    pElement = (EXYNOS_SHAREDMEM_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHAREDMEM_LIST));
+    if (pElement == NULL)
+        goto EXIT;
+    Exynos_OSAL_Memset(pElement, 0, sizeof(EXYNOS_SHAREDMEM_LIST));
+    pElement->owner = OMX_TRUE;
+
+    /* priority is like as EXT > SECURE > CONTIG > CACHED > NORMAL */
+    switch ((int)memoryType) {
+    case (EXT_MEMORY | SECURE_MEMORY | CONTIG_MEMORY | CACHED_MEMORY):  /* EXTRA */
+    case (EXT_MEMORY | SECURE_MEMORY | CONTIG_MEMORY):
+    case (EXT_MEMORY | SECURE_MEMORY | CACHED_MEMORY):
+    case (EXT_MEMORY | SECURE_MEMORY):
+        mask = ION_HEAP_EXYNOS_CONTIG_MASK;
+        flag = ION_EXYNOS_VIDEO_EXT_MASK | ION_FLAG_PROTECTED;
+        break;
+    case (EXT_MEMORY | CONTIG_MEMORY | CACHED_MEMORY):
+    case (EXT_MEMORY | CONTIG_MEMORY):
+    case (EXT_MEMORY | CACHED_MEMORY):
+    case EXT_MEMORY:
+        mask = ION_HEAP_EXYNOS_CONTIG_MASK;
+        flag = ION_EXYNOS_VIDEO_EXT_MASK;
+        break;
+    case (SECURE_MEMORY | CONTIG_MEMORY | CACHED_MEMORY):  /* SECURE */
+    case (SECURE_MEMORY | CONTIG_MEMORY):
+    case (SECURE_MEMORY | CACHED_MEMORY):
+    case SECURE_MEMORY:
+        mask = ION_HEAP_EXYNOS_CONTIG_MASK;
+        flag = ION_EXYNOS_MFC_INPUT_MASK | ION_FLAG_PROTECTED;
+        break;
+    case (CONTIG_MEMORY | CACHED_MEMORY):  /* CONTIG */
+    case CONTIG_MEMORY:
+        mask = ION_HEAP_EXYNOS_CONTIG_MASK;
+        flag = ION_EXYNOS_MFC_INPUT_MASK;
+        break;
+    case CACHED_MEMORY:  /* CACHED */
+        mask = ION_HEAP_SYSTEM_MASK;
+        flag = ION_FLAG_CACHED;
+        break;
+    default:  /* NORMAL */
+        mask = ION_HEAP_SYSTEM_MASK;
+        flag = ION_FLAG_CACHED;
+        break;
+    }
+
+    if (flag & ION_FLAG_CACHED)  /* use improved cache oprs */
+        flag |= ION_FLAG_CACHED_NEEDS_SYNC;
+
+    if (ion_alloc_fd(pHandle->hIONHandle, size, 0, mask, flag, (void *)&IONBuffer) < 0) {
+        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Failed to ion_alloc_fd(mask:%x, flag:%x)", __FUNCTION__, mask, flag);
+        if (memoryType == CONTIG_MEMORY) {
+            /* retry at normal area */
+            flag = 0;
+            if (ion_alloc_fd(pHandle->hIONHandle, size, 0, mask, flag, (void *)&IONBuffer) < 0) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] retry: Failed to ion_alloc_fd(mask:%x, flag:%x)", __FUNCTION__, mask, flag);
+                IONBuffer = 0;
+            }
+        }
+    }
+
+    if (IONBuffer == 0) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] FD(%d) is wrong", __FUNCTION__, IONBuffer);
+        Exynos_OSAL_Free((OMX_PTR)pElement);
+        goto EXIT;
+    }
+
+    if (flag & ION_FLAG_PROTECTED) {
+        /* in case of DRM, do not call mmap. so set a fd instead of vaddr */
+        pBuffer = (OMX_PTR)IONBuffer;
+    } else {
+        pBuffer = Exynos_OSAL_Mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, IONBuffer, 0);
+        if (pBuffer == MAP_FAILED) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Mmap(size:%d)", __FUNCTION__, size);
+            /* free a ion_buffer */
+            ion_close(IONBuffer);
+            Exynos_OSAL_Free((OMX_PTR)pElement);
+            pBuffer = NULL;
+            goto EXIT;
+        }
+    }
+
+    pElement->IONBuffer = IONBuffer;
+    pElement->mapAddr = pBuffer;
+    pElement->allocSize = size;
+    pElement->pNextMemory = NULL;
+
+    Exynos_OSAL_MutexLock(pHandle->hSMMutex);
+    pSMList = pHandle->pAllocMemory;
+    if (pSMList == NULL) {
+        pHandle->pAllocMemory = pSMList = pElement;
+    } else {
+        pCurrentElement = pSMList;
+        while (pCurrentElement->pNextMemory != NULL) {
+            pCurrentElement = pCurrentElement->pNextMemory;
+        }
+        pCurrentElement->pNextMemory = pElement;
+    }
+    Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+
+    mem_cnt++;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, mem_cnt);
+
+EXIT:
+    return pBuffer;
+}
+
+void Exynos_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
+{
+    EXYNOS_SHARED_MEMORY  *pHandle         = (EXYNOS_SHARED_MEMORY *)handle;
+    EXYNOS_SHAREDMEM_LIST *pSMList         = NULL;
+    EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
+    EXYNOS_SHAREDMEM_LIST *pDeleteElement  = NULL;
+
+    if (pHandle == NULL)
+        goto EXIT;
+
+    Exynos_OSAL_MutexLock(pHandle->hSMMutex);
+    pSMList = pHandle->pAllocMemory;
+    if (pSMList == NULL) {
+        Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+        goto EXIT;
+    }
+
+    pCurrentElement = pSMList;
+    if (pSMList->mapAddr == pBuffer) {
+        pDeleteElement = pSMList;
+        pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
+    } else {
+        while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
+               (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
+            pCurrentElement = pCurrentElement->pNextMemory;
+
+        if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
+            (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
+            pDeleteElement = pCurrentElement->pNextMemory;
+            pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
+        } else {
+            Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] can't find a buffer(%p) in list", __FUNCTION__, pBuffer);
+            goto EXIT;
+        }
+    }
+    Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+
+    if (pDeleteElement->mapAddr != (void *)pDeleteElement->IONBuffer) {
+        if (Exynos_OSAL_Munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Munmap", __FUNCTION__);
+            goto EXIT;
+        }
+    }
+
+    pDeleteElement->mapAddr = NULL;
+    pDeleteElement->allocSize = 0;
+
+    if (pDeleteElement->owner) {
+        /* free a ion_buffer */
+        ion_close(pDeleteElement->IONBuffer);
+        mem_cnt--;
+    }
+    pDeleteElement->IONBuffer = 0;
+
+    Exynos_OSAL_Free(pDeleteElement);
+
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, mem_cnt);
+
+EXIT:
+    return;
+}
+
+OMX_PTR Exynos_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, unsigned long ionfd)
+{
+    EXYNOS_SHARED_MEMORY  *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
+    EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
+    EXYNOS_SHAREDMEM_LIST *pElement = NULL;
+    EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
+    OMX_S32 IONBuffer = 0;
+    OMX_PTR pBuffer = NULL;
+
+    if (pHandle == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    pElement = (EXYNOS_SHAREDMEM_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHAREDMEM_LIST));
+    if (pElement == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Malloc()", __FUNCTION__);
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Memset(pElement, 0, sizeof(EXYNOS_SHAREDMEM_LIST));
+
+    IONBuffer = (OMX_S32)ionfd;
+
+    if (IONBuffer <= 0) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] FD(%u) is wrong", __FUNCTION__, IONBuffer);
+        Exynos_OSAL_Free((void*)pElement);
+        goto EXIT;
+    }
+
+    pBuffer = Exynos_OSAL_Mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, IONBuffer, 0);
+    if (pBuffer == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Mmap(size:%d)", __FUNCTION__, size);
+        /* free a ion_buffer */
+        ion_close(IONBuffer);
+        Exynos_OSAL_Free((void*)pElement);
+        goto EXIT;
+    }
+
+    pElement->IONBuffer = IONBuffer;
+    pElement->mapAddr = pBuffer;
+    pElement->allocSize = size;
+    pElement->pNextMemory = NULL;
+
+    Exynos_OSAL_MutexLock(pHandle->hSMMutex);
+    pSMList = pHandle->pAllocMemory;
+    if (pSMList == NULL) {
+        pHandle->pAllocMemory = pSMList = pElement;
+    } else {
+        pCurrentElement = pSMList;
+        while (pCurrentElement->pNextMemory != NULL) {
+            pCurrentElement = pCurrentElement->pNextMemory;
+        }
+        pCurrentElement->pNextMemory = pElement;
+    }
+    Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+
+    map_cnt++;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, map_cnt);
+
+EXIT:
+    return pBuffer;
+}
+
+void Exynos_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, unsigned long ionfd)
+{
+    EXYNOS_SHARED_MEMORY  *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
+    EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
+    EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
+    EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL;
+
+    if (pHandle == NULL)
+        goto EXIT;
+
+    Exynos_OSAL_MutexLock(pHandle->hSMMutex);
+    pSMList = pHandle->pAllocMemory;
+    if (pSMList == NULL) {
+        Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+        goto EXIT;
+    }
+
+    pCurrentElement = pSMList;
+    if (pSMList->IONBuffer == ionfd) {
+        pDeleteElement = pSMList;
+        pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
+    } else {
+        while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
+               (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer != ionfd))
+            pCurrentElement = pCurrentElement->pNextMemory;
+
+        if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
+            (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer == ionfd)) {
+            pDeleteElement = pCurrentElement->pNextMemory;
+            pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
+        } else {
+            Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] can't find a buffer(%u) in list", __FUNCTION__, ionfd);
+            goto EXIT;
+        }
+    }
+    Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+
+    if (Exynos_OSAL_Munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Munmap", __FUNCTION__);
+        goto EXIT;
+    }
+    pDeleteElement->mapAddr = NULL;
+    pDeleteElement->allocSize = 0;
+    pDeleteElement->IONBuffer = 0;
+
+    Exynos_OSAL_Free(pDeleteElement);
+
+    map_cnt--;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, map_cnt);
+
+EXIT:
+    return;
+}
+
+unsigned long Exynos_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
+{
+    EXYNOS_SHARED_MEMORY  *pHandle         = (EXYNOS_SHARED_MEMORY *)handle;
+    EXYNOS_SHAREDMEM_LIST *pSMList         = NULL;
+    EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
+    EXYNOS_SHAREDMEM_LIST *pFindElement    = NULL;
+
+    unsigned long ion_addr = 0;
+
+    if (pHandle == NULL || pBuffer == NULL)
+        goto EXIT;
+
+    Exynos_OSAL_MutexLock(pHandle->hSMMutex);
+    pSMList = pHandle->pAllocMemory;
+    if (pSMList == NULL) {
+        Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+        goto EXIT;
+    }
+
+    pCurrentElement = pSMList;
+    if (pSMList->mapAddr == pBuffer) {
+        pFindElement = pSMList;
+    } else {
+        while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
+               (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
+            pCurrentElement = pCurrentElement->pNextMemory;
+
+        if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
+            (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
+            pFindElement = pCurrentElement->pNextMemory;
+        } else {
+            Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] can't find a buffer(%p) in list", __FUNCTION__, pBuffer);
+            goto EXIT;
+        }
+    }
+    Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+
+    ion_addr = pFindElement->IONBuffer;
+
+EXIT:
+    return ion_addr;
+}
+
+OMX_PTR Exynos_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, unsigned long ionfd)
+{
+    EXYNOS_SHARED_MEMORY  *pHandle         = (EXYNOS_SHARED_MEMORY *)handle;
+    EXYNOS_SHAREDMEM_LIST *pSMList         = NULL;
+    EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
+    EXYNOS_SHAREDMEM_LIST *pFindElement    = NULL;
+
+    OMX_PTR pBuffer = NULL;
+
+    if (pHandle == NULL || ionfd == 0)
+        goto EXIT;
+
+    Exynos_OSAL_MutexLock(pHandle->hSMMutex);
+    pSMList = pHandle->pAllocMemory;
+    if (pSMList == NULL) {
+        Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+        goto EXIT;
+    }
+
+    pCurrentElement = pSMList;
+    if (pSMList->IONBuffer == ionfd) {
+        pFindElement = pSMList;
+    } else {
+        while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
+               (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer != ionfd))
+            pCurrentElement = pCurrentElement->pNextMemory;
+
+        if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
+            (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer == ionfd)) {
+            pFindElement = pCurrentElement->pNextMemory;
+        } else {
+            Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] can't find a buffer(%u) in list", __FUNCTION__, ionfd);
+            goto EXIT;
+        }
+    }
+    Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+
+    pBuffer = pFindElement->mapAddr;
+
+EXIT:
+    return pBuffer;
+}
diff --git a/openmax/osal/Exynos_OSAL_SharedMemory.h b/openmax/osal/Exynos_OSAL_SharedMemory.h
new file mode 100755 (executable)
index 0000000..78fd969
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_SharedMemory.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ *              Taehwan Kim (t_h.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef EXYNOS_OSAL_SHAREDMEMORY
+#define EXYNOS_OSAL_SHAREDMEMORY
+
+#include "OMX_Types.h"
+
+typedef enum _MEMORY_TYPE
+{
+    NORMAL_MEMORY   = 0x00,
+    CACHED_MEMORY   = 0x01,  /* cached */
+    CONTIG_MEMORY   = 0x02,  /* continuos */
+    SECURE_MEMORY   = 0x04,  /* secure */
+    EXT_MEMORY      = 0x08,  /* ext area */
+} MEMORY_TYPE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_HANDLETYPE Exynos_OSAL_SharedMemory_Open();
+void Exynos_OSAL_SharedMemory_Close(OMX_HANDLETYPE handle);
+OMX_PTR Exynos_OSAL_SharedMemory_Alloc(OMX_HANDLETYPE handle, OMX_U32 size, MEMORY_TYPE memoryType);
+void Exynos_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle, OMX_PTR pBuffer);
+unsigned long Exynos_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer);
+OMX_PTR Exynos_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, unsigned long ionfd);
+
+OMX_PTR Exynos_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, unsigned long ionfd);
+void Exynos_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, unsigned long ionfd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/openmax/osal/Exynos_OSAL_SkypeHD.c b/openmax/osal/Exynos_OSAL_SkypeHD.c
new file mode 100755 (executable)
index 0000000..734310e
--- /dev/null
@@ -0,0 +1,979 @@
+/*
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_SkypeHD.cpp
+ * @brief
+ * @author      Seungbeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2015.04.27 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OSAL_SkypeHD.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OMX_Def.h"
+#include "exynos_format.h"
+
+#include "ExynosVideoApi.h"
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "Exynos_OSAL_SkypeHD"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+#include "Exynos_OSAL_SkypeHD.h"
+
+/* ENCODE_ONLY */
+#ifdef BUILD_ENC
+#include "Exynos_OMX_Venc.h"
+#include "Exynos_OMX_H264enc.h"
+#endif
+
+/* DECODE_ONLY */
+#ifdef BUILD_DEC
+#include "Exynos_OMX_Vdec.h"
+#include "Exynos_OMX_H264dec.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ENCODE_ONLY */
+#ifdef BUILD_ENC
+/* video enc */
+OMX_ERRORTYPE Exynos_H264Enc_GetParameter_SkypeHD(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    switch ((int)nParamIndex) {
+    case OMX_IndexSkypeParamDriverVersion:
+    {
+        OMX_VIDEO_PARAM_DRIVERVER *pDriverVer = (OMX_VIDEO_PARAM_DRIVERVER *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDriverVer, sizeof(OMX_VIDEO_PARAM_DRIVERVER));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDriverVer->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDriverVer->nDriverVersion = (OMX_U64)(pH264Enc->hMFCH264Handle.videoInstInfo.SwVersion);
+    }
+        break;
+    case OMX_IndexSkypeParamLowLatency:
+    {
+        OMX_PARAM_U32TYPE *pLowLatency = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pLowLatency, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pLowLatency->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pLowLatency->nU32 = (pH264Enc->hMFCH264Handle.bLowLatency == OMX_TRUE)? 1:0;
+    }
+        break;
+    case OMX_IndexSkypeParamEncoderMaxTemporalLayerCount:
+    {
+        OMX_PARAM_ENC_MAX_TEMPORALLAYER_COUNT *pTemporalLayer = (OMX_PARAM_ENC_MAX_TEMPORALLAYER_COUNT *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pTemporalLayer, sizeof(OMX_PARAM_ENC_MAX_TEMPORALLAYER_COUNT));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pTemporalLayer->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pTemporalLayer->nMaxCountP = OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS;
+        pTemporalLayer->nMaxCountB = (OMX_VIDEO_MAX_AVC_TEMPORAL_LAYERS - 1);
+    }
+        break;
+    case OMX_IndexSkypeParamEncoderMaxLTR:
+    {
+        OMX_PARAM_U32TYPE *pLTR = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pLTR, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pLTR->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pLTR->nU32 = OMX_VIDEO_MAX_LTR_FRAMES;
+    }
+        break;
+    case OMX_IndexSkypeParamEncoderLTR:
+    {
+        OMX_PARAM_U32TYPE *pLTR = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pLTR, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pLTR->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pLTR->nU32 = pH264Enc->hMFCH264Handle.nLTRFrames;
+    }
+        break;
+    case OMX_IndexSkypeParamEncoderPreprocess:
+    {
+        OMX_PARAM_ENC_PREPROCESS *pPreprocess = (OMX_PARAM_ENC_PREPROCESS *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pPreprocess, sizeof(OMX_PARAM_ENC_PREPROCESS));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pPreprocess->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pPreprocess->nResize   = 0;  /* 1:1 */
+        pPreprocess->nRotation = 0;  /* not supported */
+    }
+        break;
+    case OMX_IndexSkypeParamEncoderSar:
+    {
+        OMX_PARAM_ENC_SAR *pSar = (OMX_PARAM_ENC_SAR *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSar, sizeof(OMX_PARAM_ENC_SAR));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSar->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pSar->nWidth  = pH264Enc->hMFCH264Handle.stSarParam.SarWidth;
+        pSar->nHeight = pH264Enc->hMFCH264Handle.stSarParam.SarHeight;
+    }
+        break;
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_SetParameter_SkypeHD(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
+    EXYNOS_H264ENC_HANDLE           *pH264Enc           = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    switch ((int)nIndex) {
+    case OMX_IndexSkypeParamLowLatency:
+    {
+        OMX_PARAM_U32TYPE *pLowLatency = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pLowLatency, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pLowLatency->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pH264Enc->hMFCH264Handle.bLowLatency = (pLowLatency->nU32 == 0)? OMX_FALSE:OMX_TRUE;
+    }
+        break;
+    case OMX_IndexSkypeParamEncoderLTR:
+    {
+        OMX_PARAM_U32TYPE *pLTR = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pLTR, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pLTR->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pLTR->nU32 > OMX_VIDEO_MAX_LTR_FRAMES) {
+            ret = OMX_ErrorBadParameter;
+            goto EXIT;
+        }
+
+        pH264Enc->hMFCH264Handle.nLTRFrames = pLTR->nU32;
+    }
+        break;
+    case OMX_IndexSkypeParamEncoderSar:
+    {
+        OMX_PARAM_ENC_SAR *pSar = (OMX_PARAM_ENC_SAR *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pSar, sizeof(OMX_PARAM_ENC_SAR));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pSar->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pH264Enc->hMFCH264Handle.stSarParam.SarEnable = OMX_TRUE;
+        pH264Enc->hMFCH264Handle.stSarParam.SarIndex  = 0xFF;  /* depends on width/height info */
+        pH264Enc->hMFCH264Handle.stSarParam.SarWidth  = pSar->nWidth;
+        pH264Enc->hMFCH264Handle.stSarParam.SarHeight = pSar->nHeight;
+    }
+        break;
+    case OMX_IndexSkypeParamEncoderInputControl:
+    {
+        OMX_PARAM_U32TYPE *pInputControl = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pInputControl, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pInputControl->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if (pInputControl->nU32 > 0) {
+            pH264Enc->hMFCH264Handle.bEnableSkypeHD = OMX_TRUE;
+        } else {
+            pH264Enc->hMFCH264Handle.bEnableSkypeHD = OMX_FALSE;
+        }
+    }
+        break;
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_GetConfig_SkypeHD(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc         = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc  = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    switch ((int)nIndex) {
+    case OMX_IndexSkypeConfigBasePid:
+    {
+        OMX_VIDEO_CONFIG_BASELAYERPID *pBaseLayerPid = (OMX_VIDEO_CONFIG_BASELAYERPID *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pBaseLayerPid, sizeof(OMX_VIDEO_CONFIG_BASELAYERPID));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pBaseLayerPid->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pBaseLayerPid->nPID = pH264Enc->hMFCH264Handle.nBaseLayerPid;
+    }
+        break;
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Enc_SetConfig_SkypeHD(
+    OMX_HANDLETYPE  hComponent,
+    OMX_INDEXTYPE   nIndex,
+    OMX_PTR         pComponentConfigStructure)
+{
+    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
+    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc         = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentConfigStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoEnc->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Enc  = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+    switch ((int)nIndex) {
+    case OMX_IndexSkypeConfigMarkLTRFrame:
+    {
+        OMX_VIDEO_CONFIG_MARKLTRFRAME *pMarkLTRFrame = (OMX_VIDEO_CONFIG_MARKLTRFRAME *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pMarkLTRFrame, sizeof(OMX_VIDEO_CONFIG_MARKLTRFRAME));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pMarkLTRFrame->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexSkypeConfigUseLTRFrame:
+    {
+        OMX_VIDEO_CONFIG_USELTRFRAME *pUseLTRFrame = (OMX_VIDEO_CONFIG_USELTRFRAME *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pUseLTRFrame, sizeof(OMX_VIDEO_CONFIG_USELTRFRAME));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pUseLTRFrame->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+    }
+        break;
+    case OMX_IndexSkypeConfigQP:
+    {
+        OMX_VIDEO_CONFIG_QP *pConfigQp = (OMX_VIDEO_CONFIG_QP *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pConfigQp, sizeof(OMX_VIDEO_CONFIG_QP));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pConfigQp->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pVideoEnc->quantization.nQpI = pConfigQp->nQP;
+        pVideoEnc->quantization.nQpP = pConfigQp->nQP;
+        pVideoEnc->quantization.nQpB = pConfigQp->nQP;
+    }
+        break;
+    case OMX_IndexSkypeConfigBasePid:
+    {
+        OMX_VIDEO_CONFIG_BASELAYERPID *pBaseLayerPid = (OMX_VIDEO_CONFIG_BASELAYERPID *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pBaseLayerPid, sizeof(OMX_VIDEO_CONFIG_BASELAYERPID));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pBaseLayerPid->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pH264Enc->hMFCH264Handle.nBaseLayerPid = pBaseLayerPid->nPID;
+    }
+        break;
+    case OMX_IndexSkypeConfigEncoderInputTrigger:
+    {
+        OMX_CONFIG_ENC_TRIGGER_TS *pTriggerTS = (OMX_CONFIG_ENC_TRIGGER_TS *)pComponentConfigStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pTriggerTS, sizeof(OMX_CONFIG_ENC_TRIGGER_TS));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pTriggerTS->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+    }
+        break;
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Change_H264Enc_SkypeHDParam(
+    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent,
+    OMX_PTR                     pDynamicConfigCMD)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = NULL;
+    EXYNOS_H264ENC_HANDLE         *pH264Enc          = NULL;
+    EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle    = NULL;
+    OMX_PTR                        pConfigData       = NULL;
+    OMX_S32                        nCmdIndex         = 0;
+    ExynosVideoEncOps             *pEncOps           = NULL;
+    int                            nValue            = 0;
+
+    int i;
+
+    FunctionIn();
+
+    pVideoEnc       = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+    pH264Enc        = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+    pMFCH264Handle  = &pH264Enc->hMFCH264Handle;
+    pEncOps         = pMFCH264Handle->pEncOps;
+
+    if (pDynamicConfigCMD == NULL)
+        goto EXIT;
+
+    nCmdIndex   = *(OMX_S32 *)pDynamicConfigCMD;
+    pConfigData = (OMX_PTR)((OMX_U8 *)pDynamicConfigCMD + sizeof(OMX_S32));
+
+    switch ((int)nCmdIndex) {
+    case OMX_IndexSkypeConfigMarkLTRFrame:
+    {
+        OMX_VIDEO_CONFIG_MARKLTRFRAME *pMarkLTRFrame = (OMX_VIDEO_CONFIG_MARKLTRFRAME *)pConfigData;
+
+        ret = Exynos_OMX_Check_SizeVersion(pMarkLTRFrame, sizeof(OMX_VIDEO_CONFIG_MARKLTRFRAME));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pMarkLTRFrame->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Mark LTR : index(%d)",
+                                            pExynosComponent, __FUNCTION__, pMarkLTRFrame->nLongTermFrmIdx + 1);
+
+        pEncOps->Set_MarkLTRFrame(pMFCH264Handle->hMFCHandle, pMarkLTRFrame->nLongTermFrmIdx + 1);
+    }
+        break;
+    case OMX_IndexSkypeConfigUseLTRFrame:
+    {
+        OMX_VIDEO_CONFIG_USELTRFRAME *pUseLTRFrame = (OMX_VIDEO_CONFIG_USELTRFRAME *)pConfigData;
+
+        ret = Exynos_OMX_Check_SizeVersion(pUseLTRFrame, sizeof(OMX_VIDEO_CONFIG_USELTRFRAME));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pUseLTRFrame->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Use LTR : BM(%x)",
+                                            pExynosComponent, __FUNCTION__, pUseLTRFrame->nUsedLTRFrameBM);
+
+        pEncOps->Set_UsedLTRFrame(pMFCH264Handle->hMFCHandle, pUseLTRFrame->nUsedLTRFrameBM);
+    }
+        break;
+    case OMX_IndexSkypeConfigQP:
+    {
+        OMX_VIDEO_CONFIG_QP *pConfigQp = (OMX_VIDEO_CONFIG_QP *)pConfigData;
+
+        ret = Exynos_OMX_Check_SizeVersion(pConfigQp, sizeof(OMX_VIDEO_CONFIG_QP));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pConfigQp->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] QP : %d", pExynosComponent, __FUNCTION__, pConfigQp->nQP);
+
+        pEncOps->Set_DynamicQpControl(pMFCH264Handle->hMFCHandle, pConfigQp->nQP);
+    }
+        break;
+    case OMX_IndexSkypeConfigBasePid:
+    {
+        OMX_VIDEO_CONFIG_BASELAYERPID *pBaseLayerPid = (OMX_VIDEO_CONFIG_BASELAYERPID *)pConfigData;
+
+        ret = Exynos_OMX_Check_SizeVersion(pBaseLayerPid, sizeof(OMX_VIDEO_CONFIG_BASELAYERPID));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pBaseLayerPid->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] BasePID : %d", pExynosComponent, __FUNCTION__, pBaseLayerPid->nPID);
+
+        pEncOps->Set_BasePID(pMFCH264Handle->hMFCHandle, pBaseLayerPid->nPID);
+    }
+        break;
+    case OMX_IndexSkypeConfigEncoderInputTrigger:
+    {
+        OMX_CONFIG_ENC_TRIGGER_TS *pTriggerTS = (OMX_CONFIG_ENC_TRIGGER_TS *)pConfigData;
+        EXYNOS_OMX_BASEPORT       *pInputPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]);
+
+        ret = Exynos_OMX_Check_SizeVersion(pTriggerTS, sizeof(OMX_CONFIG_ENC_TRIGGER_TS));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pTriggerTS->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pMFCH264Handle->nTriggerTS = pTriggerTS->nTimestamp;
+
+        if (pInputPort->processData.timeStamp == pMFCH264Handle->nTriggerTS) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input trigger is matched input timestamp : %lld",
+                                                    pExynosComponent, __FUNCTION__, pTriggerTS->nTimestamp);
+            ret = OMX_ErrorNoMore;
+            goto EXIT;
+        }
+
+        if (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) <= 0) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] no more input trigger", pExynosComponent, __FUNCTION__);
+            ret = OMX_ErrorNoMore;
+            goto EXIT;
+        }
+    }
+        break;
+    default:
+        break;
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+#endif
+
+
+/* DECODE_ONLY */
+#ifdef BUILD_DEC
+/* video dec */
+OMX_ERRORTYPE Exynos_H264Dec_GetParameter_SkypeHD(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec          = NULL;
+
+    FunctionIn();
+
+    if ((hComponent == NULL) ||
+        (pComponentParameterStructure == NULL)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                            pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    switch ((int)nParamIndex) {
+    case OMX_IndexSkypeParamDriverVersion:
+    {
+        OMX_VIDEO_PARAM_DRIVERVER *pDriverVer = (OMX_VIDEO_PARAM_DRIVERVER *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pDriverVer, sizeof(OMX_VIDEO_PARAM_DRIVERVER));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pDriverVer->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pDriverVer->nDriverVersion = (OMX_U64)(pH264Dec->hMFCH264Handle.videoInstInfo.SwVersion);
+    }
+        break;
+    case OMX_IndexSkypeParamLowLatency:
+    {
+        OMX_PARAM_U32TYPE *pLowLatency = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pLowLatency, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pLowLatency->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pLowLatency->nU32 = (pH264Dec->hMFCH264Handle.bLowLatency == OMX_TRUE)? 1:0;
+    }
+        break;
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_H264Dec_SetParameter_SkypeHD(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
+    OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec         = NULL;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec          = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL || pComponentParameterStructure == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone) {
+        goto EXIT;
+    }
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] invalid state(0x%x)",
+                                                    pExynosComponent, __FUNCTION__, pExynosComponent->currentState);
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pExynosComponent->hComponentHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+    if (pVideoDec->hCodecHandle == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+    switch ((int)nIndex) {
+    case OMX_IndexSkypeParamLowLatency:
+    {
+        OMX_PARAM_U32TYPE *pLowLatency = (OMX_PARAM_U32TYPE *)pComponentParameterStructure;
+
+        ret = Exynos_OMX_Check_SizeVersion(pLowLatency, sizeof(OMX_PARAM_U32TYPE));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (pLowLatency->nPortIndex > OUTPUT_PORT_INDEX) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        pH264Dec->hMFCH264Handle.bLowLatency = (pLowLatency->nU32 == 0)? OMX_FALSE:OMX_TRUE;
+    }
+        break;
+    default:
+        ret = OMX_ErrorUnsupportedIndex;
+        break;
+
+    }
+
+EXIT:
+
+    FunctionOut();
+
+    return ret;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/openmax/osal/Exynos_OSAL_SkypeHD.h b/openmax/osal/Exynos_OSAL_SkypeHD.h
new file mode 100755 (executable)
index 0000000..69e8a01
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_SkypeHD.h
+ * @brief
+ * @author      Seungbeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2015.04.27 : Create
+ */
+
+#ifndef Exynos_OSAL_SKYPEHD
+#define Exynos_OSAL_SKYPEHD
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+#include "OMX_Index.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef BUILD_ENC
+/* ENCODE_ONLY */
+OMX_ERRORTYPE Exynos_H264Enc_GetParameter_SkypeHD(OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex, OMX_INOUT OMX_PTR pComponentParameterStructure);
+OMX_ERRORTYPE Exynos_H264Enc_SetParameter_SkypeHD(OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex, OMX_IN OMX_PTR pComponentParameterStructure);
+OMX_ERRORTYPE Exynos_H264Enc_GetConfig_SkypeHD(OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex, OMX_PTR pComponentConfigStructure);
+OMX_ERRORTYPE Exynos_H264Enc_SetConfig_SkypeHD(OMX_HANDLETYPE hComponent,
+    OMX_INDEXTYPE nIndex, OMX_PTR pComponentConfigStructure);
+OMX_ERRORTYPE Change_H264Enc_SkypeHDParam(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR pDynamicConfigCMD);
+#endif
+
+#ifdef BUILD_DEC
+/* DECODE_ONLY */
+OMX_ERRORTYPE Exynos_H264Dec_GetParameter_SkypeHD(OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nParamIndex, OMX_INOUT OMX_PTR pComponentParameterStructure);
+OMX_ERRORTYPE Exynos_H264Dec_SetParameter_SkypeHD(OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex, OMX_IN OMX_PTR pComponentParameterStructure);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/osal/Exynos_OSAL_Thread.c b/openmax/osal/Exynos_OSAL_Thread.c
new file mode 100755 (executable)
index 0000000..617e94a
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Thread.c
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "Exynos_OSAL_Memory.h"
+#include "Exynos_OSAL_Thread.h"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "EXYNOS_LOG_THREAD"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+typedef struct _EXYNOS_THREAD_HANDLE_TYPE
+{
+    pthread_t          pthread;
+    pthread_attr_t     attr;
+    struct sched_param schedparam;
+    int                stack_size;
+} EXYNOS_THREAD_HANDLE_TYPE;
+
+
+OMX_ERRORTYPE Exynos_OSAL_ThreadCreate(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument)
+{
+    FunctionIn();
+
+    int result = 0;
+    int detach_ret = 0;
+    EXYNOS_THREAD_HANDLE_TYPE *thread;
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    thread = Exynos_OSAL_Malloc(sizeof(EXYNOS_THREAD_HANDLE_TYPE));
+    if (thread == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Memset(thread, 0, sizeof(EXYNOS_THREAD_HANDLE_TYPE));
+
+    pthread_attr_init(&thread->attr);
+    if (thread->stack_size != 0)
+        pthread_attr_setstacksize(&thread->attr, thread->stack_size);
+
+    /* set priority */
+    if (thread->schedparam.sched_priority != 0)
+        pthread_attr_setschedparam(&thread->attr, &thread->schedparam);
+
+    detach_ret = pthread_attr_setdetachstate(&thread->attr, PTHREAD_CREATE_JOINABLE);
+    if (detach_ret != 0) {
+        Exynos_OSAL_Free(thread);
+        *threadHandle = NULL;
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    result = pthread_create(&thread->pthread, &thread->attr, function_name, (void *)argument);
+    /* pthread_setschedparam(thread->pthread, SCHED_RR, &thread->schedparam); */
+
+    switch (result) {
+    case 0:
+        *threadHandle = (OMX_HANDLETYPE)thread;
+        ret = OMX_ErrorNone;
+        break;
+    case EAGAIN:
+        Exynos_OSAL_Free(thread);
+        *threadHandle = NULL;
+        ret = OMX_ErrorInsufficientResources;
+        break;
+    default:
+        Exynos_OSAL_Free(thread);
+        *threadHandle = NULL;
+        ret = OMX_ErrorUndefined;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_ThreadTerminate(OMX_HANDLETYPE threadHandle)
+{
+    FunctionIn();
+
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+    EXYNOS_THREAD_HANDLE_TYPE *thread = (EXYNOS_THREAD_HANDLE_TYPE *)threadHandle;
+
+    if (!thread) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (pthread_join(thread->pthread, NULL) != 0) {
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Free(thread);
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_ThreadDetach(OMX_HANDLETYPE threadHandle)
+{
+    EXYNOS_THREAD_HANDLE_TYPE *thread = (EXYNOS_THREAD_HANDLE_TYPE *)threadHandle;
+
+    if (!thread)
+        return OMX_ErrorBadParameter;
+
+    if (pthread_detach(thread->pthread) != 0)
+        return OMX_ErrorUndefined;
+
+    Exynos_OSAL_Free(thread);
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_ThreadCancel(OMX_HANDLETYPE threadHandle)
+{
+    EXYNOS_THREAD_HANDLE_TYPE *thread = (EXYNOS_THREAD_HANDLE_TYPE *)threadHandle;
+
+    if (!thread)
+        return OMX_ErrorBadParameter;
+
+    /* android doesn't support this function */
+    //pthread_cancel(thread->pthread);
+
+    Exynos_OSAL_Free(thread);
+    return OMX_ErrorNone;
+}
+
+void Exynos_OSAL_ThreadExit(void *value_ptr)
+{
+    pthread_exit(value_ptr);
+    return;
+}
+
+void Exynos_OSAL_SleepMillisec(OMX_U32 ms)
+{
+    if (ms == 0) {
+        sched_yield();
+    } else {
+        struct timespec time;
+        time.tv_sec  = (time_t)(ms / 1000);
+        time.tv_nsec = (long)(ms % 1000) * 1000000;
+        nanosleep(&time, NULL);
+    }
+    return;
+}
diff --git a/openmax/osal/Exynos_OSAL_Thread.h b/openmax/osal/Exynos_OSAL_Thread.h
new file mode 100755 (executable)
index 0000000..856797d
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2012 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Thread.h
+ * @brief
+ * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version     2.0.0
+ * @history
+ *   2012.02.20 : Create
+ */
+
+#ifndef Exynos_OSAL_THREAD
+#define Exynos_OSAL_THREAD
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_ERRORTYPE Exynos_OSAL_ThreadCreate(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument);
+OMX_ERRORTYPE Exynos_OSAL_ThreadTerminate(OMX_HANDLETYPE threadHandle);
+OMX_ERRORTYPE Exynos_OSAL_ThreadDetach(OMX_HANDLETYPE threadHandle);
+OMX_ERRORTYPE Exynos_OSAL_ThreadCancel(OMX_HANDLETYPE threadHandle);
+void          Exynos_OSAL_ThreadExit(void *value_ptr);
+void          Exynos_OSAL_SleepMillisec(OMX_U32 ms);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/osal/Exynos_OSAL_Tizen.c b/openmax/osal/Exynos_OSAL_Tizen.c
new file mode 100755 (executable)
index 0000000..d959bc1
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+ * Copyright 2016 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Tizen.c
+ * @brief
+ * @author      Taehwan Kim (t_h.kim@samsung.com)
+ * @version     1.0.0
+ * @history
+ *   2016.06.13 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OMX_Baseport.h"
+#include "Exynos_OMX_Basecomponent.h"
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OSAL_Platform.h"
+#include "Exynos_OSAL_ETC.h"
+#include "exynos_format.h"
+
+#include "ExynosVideoApi.h"
+
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+
+#undef  EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG    "Exynos_OSAL_Tizen"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct __EnableGemBuffersParams
+{
+  OMX_U32           nSize;
+  OMX_VERSIONTYPE   nVersion;
+  OMX_U32           nPortIndex;
+  OMX_BOOL          bStoreMetaData;
+} EnableGemBuffersParams;
+
+static OMX_ERRORTYPE setBufferProcessTypeForDecoder(EXYNOS_OMX_BASEPORT *pExynosPort)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (pExynosPort == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    if ((pExynosPort->bufferProcessType == BUFFER_COPY) &&
+        (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+        int i;
+        if (pExynosPort->supportFormat == NULL) {
+            ret = OMX_ErrorUndefined;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] supported format is empty", __FUNCTION__);
+            goto EXIT;
+        }
+
+        pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+        /* check to support NV12T format */
+        for (i = 0; pExynosPort->supportFormat[i] != OMX_COLOR_FormatUnused; i++) {
+            /* prefer to use NV12T */
+            if (pExynosPort->supportFormat[i] == (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled) {
+                pExynosPort->portDefinition.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
+                break;
+            }
+        }
+        pExynosPort->bufferProcessType = BUFFER_SHARE;
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s] output buffer sharing mode is on (%x)",
+                                                __FUNCTION__, pExynosPort->portDefinition.format.video.eColorFormat);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+static void resetBufferProcessTypeForDecoder(EXYNOS_OMX_BASEPORT *pExynosPort)
+{
+    FunctionIn();
+
+    if (pExynosPort == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        goto EXIT;
+    }
+
+    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+
+EXIT:
+    FunctionOut();
+
+    return;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_GetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_INOUT OMX_PTR     pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pComponentParameterStructure == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    switch ((int)nIndex) {
+    case OMX_IndexParamPortDefinition:
+    {
+        OMX_PARAM_PORTDEFINITIONTYPE    *pPortDef       = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
+        EXYNOS_OMX_BASEPORT             *pExynosPort    = &pExynosComponent->pExynosPort[pPortDef->nPortIndex];
+
+        if (pExynosPort->eMetaDataType == METADATA_TYPE_DATA)
+            pPortDef->nBufferSize = (ALIGN(pExynosPort->portDefinition.format.video.nFrameWidth, 16) *
+                                     ALIGN(pExynosPort->portDefinition.format.video.nFrameHeight, 16) * 3) / 2;
+    }
+        break;
+    default:
+    {
+        ret = OMX_ErrorUnsupportedIndex;
+        goto EXIT;
+    }
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SetParameter(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_IN OMX_INDEXTYPE  nIndex,
+    OMX_IN OMX_PTR        pComponentParameterStructure)
+{
+    OMX_ERRORTYPE                ret                = OMX_ErrorNone;
+    OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
+    EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
+
+    FunctionIn();
+
+    if (hComponent == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
+    if (ret != OMX_ErrorNone)
+        goto EXIT;
+
+    if (pOMXComponent->pComponentPrivate == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    if (pExynosComponent->currentState == OMX_StateInvalid) {
+        ret = OMX_ErrorInvalidState;
+        goto EXIT;
+    }
+
+    if (pComponentParameterStructure == NULL) {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] index = 0x%x", pExynosComponent, __FUNCTION__, nIndex);
+    switch ((int)nIndex) {
+    case OMX_IndexParamStoreMetaDataBuffer:
+    {
+        EnableGemBuffersParams *pGBParams   = (EnableGemBuffersParams *)pComponentParameterStructure;
+        OMX_U32                 nPortIndex  = pGBParams->nPortIndex;
+        EXYNOS_OMX_BASEPORT    *pExynosPort = NULL;
+
+        ret = Exynos_OMX_Check_SizeVersion(pGBParams, sizeof(EnableGemBuffersParams));
+        if (ret != OMX_ErrorNone) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s] Failed to Check_SizeVersion", pExynosComponent, __FUNCTION__);
+            goto EXIT;
+        }
+
+        if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) ||
+            (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC)) {
+            /* decoder */
+            if (nPortIndex != OUTPUT_PORT_INDEX) {
+                ret = OMX_ErrorNotImplemented;
+                goto EXIT;
+            }
+        } else {
+            /* encoder */
+            if (nPortIndex != INPUT_PORT_INDEX) {
+                ret = OMX_ErrorNotImplemented;
+                goto EXIT;
+            }
+        }
+
+        pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+        if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+            ret = OMX_ErrorBadPortIndex;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s][META] %s port: metadata mode(%x) -> %s",
+                                        pExynosComponent, __FUNCTION__,
+                                        (nPortIndex == INPUT_PORT_INDEX)? "input":"output",
+                                        pExynosPort->eMetaDataType,
+                                        (pGBParams->bStoreMetaData == OMX_TRUE)? "enable":"disable");
+
+        if ((pGBParams->bStoreMetaData == OMX_TRUE) &&
+            (pExynosPort->eMetaDataType == METADATA_TYPE_DISABLED)) {
+            pExynosPort->eMetaDataType = METADATA_TYPE_DATA;
+        }
+
+        /* in case of decoder output */
+        if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+            ((pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) ||
+                (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC))) {
+            if (pGBParams->bStoreMetaData == OMX_TRUE) {
+                ret = setBufferProcessTypeForDecoder(pExynosPort);
+                if (ret != OMX_ErrorNone)
+                    goto EXIT;
+            } else if ((pGBParams->bStoreMetaData == OMX_FALSE) &&
+                       (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+                resetBufferProcessTypeForDecoder(pExynosPort);
+            }
+        }
+
+        if ((pGBParams->bStoreMetaData == OMX_FALSE) &&
+            (pExynosPort->eMetaDataType != METADATA_TYPE_DISABLED)) {
+            pExynosPort->eMetaDataType = METADATA_TYPE_DISABLED;
+        }
+    }
+        break;
+    default:
+    {
+        ret = OMX_ErrorUnsupportedIndex;
+        goto EXIT;
+    }
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+/*
+ * meta data contains the following data format.
+ * 1) METADATA_TYPE_DATA
+ * --------------------------------------------------------------------
+ * | MMVideoBuffer                                                    | [DEC] out, [ENC] in
+ * --------------------------------------------------------------------
+ */
+OMX_ERRORTYPE Exynos_OSAL_LockMetaData(
+    OMX_IN OMX_PTR                          pBuffer,
+    OMX_IN EXYNOS_OMX_LOCK_RANGE            range,
+    OMX_OUT OMX_U32                        *pStride,
+    OMX_OUT EXYNOS_OMX_MULTIPLANE_BUFFER   *pBufferInfo,
+    OMX_IN EXYNOS_METADATA_TYPE             eMetaType)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (pBuffer == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    /* not used yet */
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_UnlockMetaData(
+    OMX_IN OMX_PTR              pBuffer,
+    OMX_IN EXYNOS_METADATA_TYPE eMetaType)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (pBuffer == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    /* not used yet */
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(
+    OMX_IN OMX_PTR                          pBuffer,
+    OMX_OUT EXYNOS_OMX_MULTIPLANE_BUFFER   *pBufferInfo,
+    OMX_IN EXYNOS_METADATA_TYPE             eMetaDataType)
+{
+    OMX_ERRORTYPE    ret            = OMX_ErrorNone;
+    tbm_surface_h surface;
+    tbm_bo bo[2];
+    int i;
+
+    FunctionIn();
+
+    if ((pBuffer == NULL) ||
+        (pBufferInfo == NULL) ||
+        (eMetaDataType == METADATA_TYPE_DISABLED)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    if (eMetaDataType == METADATA_TYPE_DATA) {
+        surface = (tbm_surface_h)pBuffer;
+
+        bo[0] = tbm_surface_internal_get_bo(surface, 0);
+        bo[1] = tbm_surface_internal_get_bo(surface, 1);
+
+        for (i = 0; i < 2; i++) {
+            pBufferInfo->fd[i]   = (unsigned long)(tbm_bo_get_handle (bo[i], TBM_DEVICE_MM).u32);
+            pBufferInfo->addr[i] = (OMX_PTR)(tbm_bo_get_handle (bo[i], TBM_DEVICE_CPU).ptr);
+
+            Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%s] Plane[%d]: FD(%u), VA(%p)",
+                                                    __FUNCTION__, i, pBufferInfo->fd[i], pBufferInfo->addr[i]);
+        }
+    } else {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] not implemented yet(meta type:0x%x)", __FUNCTION__, eMetaDataType);
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+// Porting exynos 9110, code from SM-R765(7270), But not used
+OMX_ERRORTYPE Exynos_OSAL_SetDataLengthToMetaData(
+    OMX_IN OMX_BYTE             pBuffer,
+    OMX_IN OMX_U32              dataLength,
+    OMX_IN EXYNOS_METADATA_TYPE eMetaDataType)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (pBuffer == NULL) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+    /* not used yet */
+    /* This is for that MetaData is configured by component */
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_PTR Exynos_OSAL_AllocMetaDataBuffer(
+    OMX_HANDLETYPE          hSharedMemory,
+    EXYNOS_METADATA_TYPE    eMetaDataType,
+    OMX_U32                 nSizeBytes,
+    MEMORY_TYPE             eMemoryType)
+{
+    OMX_PTR pBuffer = NULL;
+
+    FunctionIn();
+
+    if (eMetaDataType == METADATA_TYPE_DATA) {
+        pBuffer = Exynos_OSAL_Malloc(sizeof(tbm_surface_h));
+
+        if (pBuffer == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to allocate metadata buffer", __FUNCTION__);
+            goto EXIT;
+        }
+    } else {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] not implemented yet(meta type:0x%x)", __FUNCTION__, eMetaDataType);
+    }
+
+EXIT:
+    FunctionOut();
+
+    return pBuffer;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_FreeMetaDataBuffer(
+    OMX_HANDLETYPE          hSharedMemory,
+    EXYNOS_METADATA_TYPE    eMetaDataType,
+    OMX_PTR                 pTempBuffer)
+{
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    FunctionIn();
+
+    if (eMetaDataType == METADATA_TYPE_DATA) {
+        Exynos_OSAL_Free(pTempBuffer);
+        ret = OMX_ErrorNone;
+    } else {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] not implemented yet(meta type:0x%x)", __FUNCTION__, eMetaDataType);
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    }
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/openmax/osal/Exynos_OSAL_Tizen.h b/openmax/osal/Exynos_OSAL_Tizen.h
new file mode 100755 (executable)
index 0000000..e283d54
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file        Exynos_OSAL_Tizen.h
+ * @brief
+ * @author      Taehwan Kim (t_h.kim@samsung.com)
+ * @version     1.0.0
+ * @history
+ *   2016.06.13 : Create
+ */
+
+#ifndef Exynos_OSAL_TIZEN
+#define Exynos_OSAL_TIZEN
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+#include "OMX_Index.h"
+
+#include "Exynos_OSAL_SharedMemory.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openmax/osal/Makefile.am b/openmax/osal/Makefile.am
new file mode 100755 (executable)
index 0000000..ba32311
--- /dev/null
@@ -0,0 +1,30 @@
+lib_LTLIBRARIES = libExynosOMX_OSAL.la
+
+libExynosOMX_OSAL_la_SOURCES = Exynos_OSAL_Event.c \
+                               Exynos_OSAL_Queue.c \
+                               Exynos_OSAL_ETC.c \
+                               Exynos_OSAL_Mutex.c \
+                               Exynos_OSAL_Thread.c \
+                               Exynos_OSAL_Memory.c \
+                               Exynos_OSAL_Semaphore.c \
+                               Exynos_OSAL_Library.c \
+                               Exynos_OSAL_Log.c \
+                               Exynos_OSAL_Tizen.c \
+                               Exynos_OSAL_SharedMemory.c
+
+libExynosOMX_OSAL_la_LIBADD = $(top_builddir)/exynos/libvideocodec/libExynosVideoApi.la \
+                              $(TBM_LIBS)
+
+libExynosOMX_OSAL_la_CFLAGS = -I$(top_srcdir)/openmax/include/khronos \
+                              -I$(top_srcdir)/openmax/include/exynos \
+                              -I$(top_srcdir)/openmax/core \
+                              -I$(top_srcdir)/openmax/osal \
+                              -I$(top_srcdir)/openmax/component/common \
+                              -I$(top_srcdir)/exynos/libvideocodec/include
+libExynosOMX_OSAL_la_CFLAGS += -DUSE_KHRONOS_OMX_HEADER -DUSE_DMA_BUF -DCHROMA_VALIGN=1
+libExynosOMX_OSAL_la_CFLAGS += -Wno-unused-label
+
+if USE_DLOG
+libExynosOMX_OSAL_la_CFLAGS += $(DLOG_CFLAGS) -DUSE_DLOG
+libExynosOMX_OSAL_la_LIBADD += $(DLOG_LIBS)
+endif
diff --git a/openmax/osal/NOTICE b/openmax/osal/NOTICE
new file mode 100755 (executable)
index 0000000..316b4eb
--- /dev/null
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2014, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/packaging/libomxil-e9110-v4l2.spec b/packaging/libomxil-e9110-v4l2.spec
new file mode 100755 (executable)
index 0000000..02d4a5c
--- /dev/null
@@ -0,0 +1,75 @@
+Name: libomxil-e9110-v4l2
+Summary: OpenMAX IL for e9110-v4l2
+Version: 0.0.2
+License: Apache-2.0
+Group: Development/Libraries
+Release: 3
+ExclusiveArch: %arm
+Source: %{name}-%{version}.tar.gz
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+#!BuildIgnore: linux-glibc-devel
+BuildRequires:  kernel-headers-exynos9110-tw3
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(exynos-common)
+BuildRequires:  pkgconfig(libtbm)
+
+%description
+implementation of OpenMAX IL for e9110-v4l2 for TW3
+
+%package devel
+Summary: OpenMAX IL for e9110-v4l2 (Developement)
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+development package for libomxil-e9110-v4l2
+
+%prep
+%setup -q
+
+%build
+./autogen.sh
+
+export CFLAGS+=" -mfpu=neon\
+ -DUSE_DLOG\
+ -DTIZEN_OMXIL_COMMERCIAL_FEATURE\
+ -DGST_EXT_TIME_ANALYSIS"
+
+LDFLAGS+="-Wl,--rpath=%{_prefix}/lib -Wl,--hash-style=both -Wl,--as-needed"; export LDFLAGS
+%configure --prefix=%{_prefix} --disable-static --enable-dlog --enable-exynos9110
+
+#make %{?jobs:-j%jobs}
+make
+
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+%make_install
+
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+%files
+%manifest libomxil-e9110-v4l2.manifest
+/usr/lib/*.so*
+/usr/lib/omx/libOMX.Exynos.AVC.Decoder.so
+/usr/lib/omx/libOMX.Exynos.AVC.Encoder.so
+/usr/lib/omx/libOMX.Exynos.MPEG4.Decoder.so
+/usr/lib/omx/libOMX.Exynos.MPEG4.Encoder.so
+/usr/lib/omx/libOMX.Exynos.MPEG2.Decoder.so
+/usr/lib/omx/libOMX.Exynos.WMV.Decoder.so
+/usr/lib/omx/libOMX.Exynos.HEVC.Decoder.so
+/usr/lib/omx/libOMX.Exynos.HEVC.Encoder.so
+/usr/lib/omx/libOMX.Exynos.VP8.Decoder.so
+/usr/lib/omx/libOMX.Exynos.VP8.Encoder.so
+%license COPYING
+
+%files devel
+/usr/include/*
+/usr/lib/pkgconfig/*
+
diff --git a/srp.pc.in b/srp.pc.in
new file mode 100755 (executable)
index 0000000..2dc20c3
--- /dev/null
+++ b/srp.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+libdir=@prefix@/lib
+includedir=@prefix@/include
+
+Name: Samsung RP package
+Description: Samsung RP API
+Version: @VERSION@
+Requires:
+Libs: -L${libdir} -lsrp
+
+Cflags: -I${includedir}/srp -DSLP_PLATFORM
+