--- /dev/null
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+BOARD_USE_ANDROID := true
+BOARD_USE_SKYPE_HD := true
+
+# Set to false to use Android's OMX header files
+BOARD_USE_KHRONOS_OMX_HEADER := false
+
+ifeq ($(BOARD_USE_ANDROID), true)
+BOARD_USE_ANB := true
+BOARD_USE_ANDROIDOPAQUE := true
+ANDROID_MEDIA_INC := $(TOP)/frameworks/native/include/media
+else
+BOARD_USE_METADATABUFFERTYPE := false
+BOARD_USE_KHRONOS_OMX_HEADER := true
+endif
+
+EXYNOS_OMX_SUPPORT_TUNNELING := false
+EXYNOS_OMX_SUPPORT_EGL_IMAGE := false
+
+EXYNOS_OMX_TOP := $(LOCAL_PATH)
+
+EXYNOS_OMX_INC := $(EXYNOS_OMX_TOP)/include
+EXYNOS_OMX_COMPONENT := $(EXYNOS_OMX_TOP)/component
+
+EXYNOS_VIDEO_CODEC := \
+ hardware/samsung_slsi/exynos/libvideocodec
+ifeq ($(BOARD_USE_ALP_AUDIO), true)
+ ifeq ($(BOARD_USE_SEIREN_AUDIO), true)
+ EXYNOS_AUDIO_CODEC += \
+ hardware/samsung_slsi/exynos/libseiren
+ else
+ EXYNOS_AUDIO_CODEC += \
+ hardware/samsung_slsi/exynos/libsrp
+ endif
+endif
+
+include $(EXYNOS_OMX_TOP)/osal/Android.mk
+include $(EXYNOS_OMX_TOP)/core/Android.mk
+
+include $(EXYNOS_OMX_COMPONENT)/common/Android.mk
+include $(EXYNOS_OMX_COMPONENT)/video/dec/Android.mk
+include $(EXYNOS_OMX_COMPONENT)/video/dec/h264/Android.mk
+include $(EXYNOS_OMX_COMPONENT)/video/dec/mpeg4/Android.mk
+include $(EXYNOS_OMX_COMPONENT)/video/dec/vp8/Android.mk
+include $(EXYNOS_OMX_COMPONENT)/video/dec/mpeg2/Android.mk
+include $(EXYNOS_OMX_COMPONENT)/video/dec/vc1/Android.mk
+
+include $(EXYNOS_OMX_COMPONENT)/video/enc/Android.mk
+include $(EXYNOS_OMX_COMPONENT)/video/enc/h264/Android.mk
+include $(EXYNOS_OMX_COMPONENT)/video/enc/mpeg4/Android.mk
+
+ifeq ($(BOARD_USE_VP8ENC_SUPPORT), true)
+include $(EXYNOS_OMX_COMPONENT)/video/enc/vp8/Android.mk
+endif
+ifeq ($(BOARD_USE_HEVCDEC_SUPPORT), true)
+include $(EXYNOS_OMX_COMPONENT)/video/dec/hevc/Android.mk
+endif
+ifeq ($(BOARD_USE_HEVCENC_SUPPORT), true)
+include $(EXYNOS_OMX_COMPONENT)/video/enc/hevc/Android.mk
+endif
+ifeq ($(BOARD_USE_VP9DEC_SUPPORT), true)
+include $(EXYNOS_OMX_COMPONENT)/video/dec/vp9/Android.mk
+endif
+ifeq ($(BOARD_USE_VP9ENC_SUPPORT), true)
+include $(EXYNOS_OMX_COMPONENT)/video/enc/vp9/Android.mk
+endif
+
+ifeq ($(BOARD_USE_ALP_AUDIO), true)
+ ifeq ($(BOARD_USE_SEIREN_AUDIO), true)
+ include $(EXYNOS_OMX_COMPONENT)/audio/seiren_dec/Android.mk
+ include $(EXYNOS_OMX_COMPONENT)/audio/seiren_dec/mp3/Android.mk
+ include $(EXYNOS_OMX_COMPONENT)/audio/seiren_dec/aac/Android.mk
+ include $(EXYNOS_OMX_COMPONENT)/audio/seiren_dec/flac/Android.mk
+ else
+ include $(EXYNOS_OMX_COMPONENT)/audio/dec/Android.mk
+ include $(EXYNOS_OMX_COMPONENT)/audio/dec/mp3/Android.mk
+ endif
+endif
+
+ifeq ($(BOARD_USE_WMA_CODEC), true)
+include $(EXYNOS_OMX_COMPONENT)/audio/dec/wma/Android.mk
+endif
--- /dev/null
+
+ 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
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Adec.c
+
+LOCAL_MODULE := libExynosOMX_Adec
+LOCAL_ARM_MODE := arm
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_LIBRARIES := libsrpapi
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/audio/dec \
+ $(EXYNOS_AUDIO_CODEC)/alp/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_STATIC_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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_Adec.c
+ * @brief
+ * @author Yunji Kim (yunji.kim@samsung.com)
+ *
+ * @version 1.1.0
+ * @history
+ * 2012.02.28 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OMX_Adec.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 "srp_api.h"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG "EXYNOS_AUDIO_DEC"
+#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) {
+ 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;
+
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+ if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+ if (pExynosPort->portState != OMX_StateIdle) {
+ 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) {
+ 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++;
+ if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+ pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ }
+ *ppBufferHdr = temp_bufferHeader;
+ ret = OMX_ErrorNone;
+ 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_BASEPORT *pExynosPort = NULL;
+ OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL;
+ OMX_U8 *temp_buffer = NULL;
+ OMX_U32 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;
+
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+ if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+/*
+ if (pExynosPort->portState != OMX_StateIdle ) {
+ ret = OMX_ErrorIncorrectStateOperation;
+ goto EXIT;
+ }
+*/
+ if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ temp_buffer = Exynos_OSAL_Malloc(sizeof(OMX_U8) * nSizeBytes);
+ if (temp_buffer == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
+ if (temp_bufferHeader == NULL) {
+ Exynos_OSAL_Free(temp_buffer);
+ temp_buffer = NULL;
+ 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_ALLOCATED | HEADER_STATE_ALLOCATED);
+ INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE);
+ 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++;
+ if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+ pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ }
+ *ppBuffer = temp_bufferHeader;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(temp_bufferHeader);
+ Exynos_OSAL_Free(temp_buffer);
+ 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_BASEPORT *pExynosPort = NULL;
+ OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL;
+ OMX_U8 *temp_buffer = NULL;
+ OMX_U32 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;
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+ if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pExynosPort->portState != OMX_StateLoaded) && (pExynosPort->portState != OMX_StateInvalid)) {
+ (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent,
+ pExynosComponent->callbackData,
+ (OMX_U32)OMX_EventError,
+ (OMX_U32)OMX_ErrorPortUnpopulated,
+ nPortIndex, NULL);
+ }
+
+ for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+ if (((pExynosPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pExynosPort->extendBufferHeader[i].OMXBufferHeader != NULL)) {
+ if (pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer == pBufferHdr->pBuffer) {
+ if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) {
+ Exynos_OSAL_Free(pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer);
+ pExynosPort->extendBufferHeader[i].OMXBufferHeader->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(pExynosPort->extendBufferHeader[i].OMXBufferHeader);
+ 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 == 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosPort->unloadedResource signal set");
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->unloadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ pExynosPort->portDefinition.bPopulated = OMX_FALSE;
+ }
+ }
+
+ FunctionOut();
+
+ return ret;
+}
+
+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;
+}
+
+OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+ if ((pExynosComponent->currentState == OMX_StateExecuting) &&
+ (pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portState == OMX_StateIdle) &&
+ (pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portState == OMX_StateIdle) &&
+ (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+ (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
+ return OMX_TRUE;
+ } else {
+ return OMX_FALSE;
+ }
+}
+
+OMX_ERRORTYPE Exynos_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_OMX_DATABUFFER *dataBuffer = &exynosOMXInputPort->way.port1WayDataBuffer.dataBuffer;
+ OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader;
+
+ FunctionIn();
+
+ if (bufferHeader != NULL) {
+ if (exynosOMXInputPort->markType.hMarkTargetComponent != NULL ) {
+ bufferHeader->hMarkTargetComponent = exynosOMXInputPort->markType.hMarkTargetComponent;
+ bufferHeader->pMarkData = exynosOMXInputPort->markType.pMarkData;
+ exynosOMXInputPort->markType.hMarkTargetComponent = NULL;
+ exynosOMXInputPort->markType.pMarkData = NULL;
+ }
+
+ if (bufferHeader->hMarkTargetComponent != NULL) {
+ if (bufferHeader->hMarkTargetComponent == pOMXComponent) {
+ pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventMark,
+ 0, 0, bufferHeader->pMarkData);
+ } else {
+ pExynosComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent;
+ pExynosComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData;
+ }
+ }
+
+ bufferHeader->nFilledLen = 0;
+ Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader);
+ }
+
+ if ((pExynosComponent->currentState == OMX_StatePause) &&
+ ((!CHECK_PORT_BEING_FLUSHED(exynosOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(exynosOMXOutputPort)))) {
+ Exynos_OSAL_SignalWait(pExynosComponent->pauseEvent, DEF_MAX_WAIT_TIME);
+ Exynos_OSAL_SignalReset(pExynosComponent->pauseEvent);
+ }
+
+ dataBuffer->dataValid = OMX_FALSE;
+ dataBuffer->dataLen = 0;
+ dataBuffer->remainDataLen = 0;
+ dataBuffer->usedDataLen = 0;
+ dataBuffer->bufferHeader = NULL;
+ dataBuffer->nFlags = 0;
+ dataBuffer->timeStamp = 0;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_InputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ EXYNOS_OMX_DATABUFFER *dataBuffer = NULL;
+ EXYNOS_OMX_MESSAGE *message = NULL;
+
+ FunctionIn();
+
+ pExynosPort= &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ dataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer;
+
+ if (pExynosComponent->currentState != OMX_StateExecuting) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ } else {
+ Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+ Exynos_OSAL_MutexLock(dataBuffer->bufferMutex);
+ if (dataBuffer->dataValid != OMX_TRUE) {
+ message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (message == NULL) {
+ ret = OMX_ErrorUndefined;
+ Exynos_OSAL_MutexUnlock(dataBuffer->bufferMutex);
+ goto EXIT;
+ }
+
+ dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
+ dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen;
+ dataBuffer->dataLen = dataBuffer->bufferHeader->nFilledLen;
+ dataBuffer->remainDataLen = dataBuffer->dataLen;
+ dataBuffer->usedDataLen = 0;
+ dataBuffer->dataValid = OMX_TRUE;
+ dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags;
+ dataBuffer->timeStamp = dataBuffer->bufferHeader->nTimeStamp;
+
+ Exynos_OSAL_Free(message);
+
+ if (dataBuffer->allocSize <= dataBuffer->dataLen)
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", dataBuffer->allocSize, dataBuffer->dataLen);
+ } else {
+ Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
+ }
+ Exynos_OSAL_MutexUnlock(dataBuffer->bufferMutex);
+ ret = OMX_ErrorNone;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_OMX_DATABUFFER *dataBuffer = &exynosOMXOutputPort->way.port1WayDataBuffer.dataBuffer;
+ OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader;
+
+ FunctionIn();
+
+ if (bufferHeader != NULL) {
+ bufferHeader->nFilledLen = dataBuffer->remainDataLen;
+ bufferHeader->nOffset = 0;
+ bufferHeader->nFlags = dataBuffer->nFlags;
+ bufferHeader->nTimeStamp = dataBuffer->timeStamp;
+
+ if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) {
+ bufferHeader->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent;
+ bufferHeader->pMarkData = pExynosComponent->propagateMarkType.pMarkData;
+ pExynosComponent->propagateMarkType.hMarkTargetComponent = NULL;
+ pExynosComponent->propagateMarkType.pMarkData = NULL;
+ }
+
+ if (bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventBufferFlag,
+ OUTPUT_PORT_INDEX,
+ bufferHeader->nFlags, NULL);
+ }
+
+ Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader);
+ }
+
+ if ((pExynosComponent->currentState == OMX_StatePause) &&
+ ((!CHECK_PORT_BEING_FLUSHED(exynosOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(exynosOMXOutputPort)))) {
+ Exynos_OSAL_SignalWait(pExynosComponent->pauseEvent, DEF_MAX_WAIT_TIME);
+ Exynos_OSAL_SignalReset(pExynosComponent->pauseEvent);
+ }
+
+ /* reset dataBuffer */
+ dataBuffer->dataValid = OMX_FALSE;
+ dataBuffer->dataLen = 0;
+ dataBuffer->remainDataLen = 0;
+ dataBuffer->usedDataLen = 0;
+ dataBuffer->bufferHeader = NULL;
+ dataBuffer->nFlags = 0;
+ dataBuffer->timeStamp = 0;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OutputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ EXYNOS_OMX_DATABUFFER *dataBuffer = NULL;
+ EXYNOS_OMX_MESSAGE *message = NULL;
+
+ FunctionIn();
+
+ pExynosPort= &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ dataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer;
+
+ if (pExynosComponent->currentState != OMX_StateExecuting) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ } else {
+ Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+ Exynos_OSAL_MutexLock(dataBuffer->bufferMutex);
+ if (dataBuffer->dataValid != OMX_TRUE) {
+ message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (message == NULL) {
+ ret = OMX_ErrorUndefined;
+ Exynos_OSAL_MutexUnlock(dataBuffer->bufferMutex);
+ goto EXIT;
+ }
+
+ dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
+ dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen;
+ dataBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen;
+ dataBuffer->remainDataLen = dataBuffer->dataLen;
+ dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset;
+ dataBuffer->dataValid = OMX_TRUE;
+ /* dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; */
+ /* dataBuffer->nTimeStamp = dataBuffer->bufferHeader->nTimeStamp; */
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = dataBuffer->bufferHeader->pBuffer;
+ pExynosPort->processData.allocSize = dataBuffer->bufferHeader->nAllocLen;
+
+ Exynos_OSAL_Free(message);
+ } else {
+ Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
+ }
+ Exynos_OSAL_MutexUnlock(dataBuffer->bufferMutex);
+ ret = OMX_ErrorNone;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+
+}
+
+OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_BOOL ret = OMX_FALSE;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port1WayDataBuffer.dataBuffer;
+ EXYNOS_OMX_DATA *inputData = &exynosInputPort->processData;
+ OMX_U32 copySize = 0;
+ OMX_BYTE checkInputStream = NULL;
+ OMX_U32 checkInputStreamLen = 0;
+ OMX_U32 checkedSize = 0;
+ OMX_BOOL flagEOF = OMX_FALSE;
+ OMX_BOOL previousFrameEOF = OMX_FALSE;
+
+ FunctionIn();
+
+ if (inputUseBuffer->dataValid == OMX_TRUE) {
+ checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
+ checkInputStreamLen = inputUseBuffer->remainDataLen;
+
+ if (inputData->dataLen == 0) {
+ previousFrameEOF = OMX_TRUE;
+ } else {
+ previousFrameEOF = OMX_FALSE;
+ }
+
+ /* Audio extractor should parse into frame units. */
+ flagEOF = OMX_TRUE;
+ checkedSize = checkInputStreamLen;
+ copySize = checkedSize;
+
+ if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)
+ pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+
+ if (((inputData->allocSize) - (inputData->dataLen)) >= copySize) {
+ if (copySize > 0)
+ Exynos_OSAL_Memcpy((char*)inputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] + inputData->dataLen, checkInputStream, copySize);
+
+ inputUseBuffer->dataLen -= copySize;
+ inputUseBuffer->remainDataLen -= copySize;
+ inputUseBuffer->usedDataLen += copySize;
+
+ inputData->dataLen += copySize;
+ inputData->remainDataLen += copySize;
+
+ if (previousFrameEOF == OMX_TRUE) {
+ inputData->timeStamp = inputUseBuffer->timeStamp;
+ inputData->nFlags = inputUseBuffer->nFlags;
+ }
+
+ if (pExynosComponent->bUseFlagEOF == OMX_TRUE) {
+ if (pExynosComponent->bSaveFlagEOS == OMX_TRUE) {
+ inputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ flagEOF = OMX_TRUE;
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ } else {
+ inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS));
+ }
+ } else {
+ if ((checkedSize == checkInputStreamLen) && (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+ if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) &&
+ ((inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ||
+ (inputData->dataLen == 0))) {
+ inputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ flagEOF = OMX_TRUE;
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ } else if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) &&
+ (!(inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) &&
+ (inputData->dataLen != 0)) {
+ inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS));
+ flagEOF = OMX_TRUE;
+ pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+ }
+ } else {
+ inputData->nFlags = (inputUseBuffer->nFlags & (~OMX_BUFFERFLAG_EOS));
+ }
+ }
+ } else {
+ /*????????????????????????????????? Error ?????????????????????????????????*/
+ Exynos_ResetCodecData(inputData);
+ flagEOF = OMX_FALSE;
+ }
+
+ if ((inputUseBuffer->remainDataLen == 0) ||
+ (CHECK_PORT_BEING_FLUSHED(exynosInputPort)))
+ Exynos_InputBufferReturn(pOMXComponent);
+ else
+ inputUseBuffer->dataValid = OMX_TRUE;
+ }
+
+ if (flagEOF == OMX_TRUE) {
+ if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
+ /* Flush SRP buffers */
+ SRP_Flush();
+ pAudioDec->outFrames = 0;
+ pAudioDec->baseTime = 0;
+ pAudioDec->bFirstFrame = OMX_TRUE;
+
+ pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
+ pExynosComponent->checkTimeStamp.startTimeStamp = inputData->timeStamp;
+ pExynosComponent->checkTimeStamp.nStartFlags = inputData->nFlags;
+ pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
+ inputData->timeStamp, inputData->timeStamp / 1E6);
+ }
+
+ ret = OMX_TRUE;
+ } else {
+ ret = OMX_FALSE;
+ }
+
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ 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.port1WayDataBuffer.dataBuffer;
+ EXYNOS_OMX_DATA *outputData = &exynosOutputPort->processData;
+ OMX_U32 copySize = 0;
+
+ FunctionIn();
+
+ if (outputUseBuffer->dataValid == OMX_TRUE) {
+ if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) {
+ if (pExynosComponent->checkTimeStamp.startTimeStamp == outputData->timeStamp) {
+ pExynosComponent->checkTimeStamp.startTimeStamp = RESET_TIMESTAMP_VAL;
+ pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
+ pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+ pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
+ } else {
+ Exynos_ResetCodecData(outputData);
+ ret = OMX_TRUE;
+ goto EXIT;
+ }
+ } else if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
+ Exynos_ResetCodecData(outputData);
+ ret = OMX_TRUE;
+ goto EXIT;
+ }
+
+ if (outputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) {
+ copySize = outputData->remainDataLen;
+
+ outputUseBuffer->dataLen += copySize;
+ outputUseBuffer->remainDataLen += copySize;
+ outputUseBuffer->nFlags = outputData->nFlags;
+ outputUseBuffer->timeStamp = outputData->timeStamp;
+
+ ret = OMX_TRUE;
+
+ /* reset outputData */
+ Exynos_ResetCodecData(outputData);
+
+ if ((outputUseBuffer->remainDataLen > 0) ||
+ (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) ||
+ (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))
+ Exynos_OutputBufferReturn(pOMXComponent);
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than decoded data size Out Length");
+
+ ret = OMX_FALSE;
+
+ /* reset outputData */
+ Exynos_ResetCodecData(outputData);
+ }
+ } else {
+ ret = OMX_FALSE;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BufferProcess(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_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port1WayDataBuffer.dataBuffer;
+ EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port1WayDataBuffer.dataBuffer;
+ EXYNOS_OMX_DATA *inputData = &exynosInputPort->processData;
+ EXYNOS_OMX_DATA *outputData = &exynosOutputPort->processData;
+ OMX_U32 copySize = 0;
+
+ pExynosComponent->reInputData = OMX_FALSE;
+
+ FunctionIn();
+
+ while (!pAudioDec->bExitBufferProcessThread) {
+ Exynos_OSAL_SleepMillisec(0);
+
+ 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(exynosInputPort) && !CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))) {
+ Exynos_OSAL_SignalWait(pExynosComponent->pauseEvent, DEF_MAX_WAIT_TIME);
+ Exynos_OSAL_SignalReset(pExynosComponent->pauseEvent);
+ }
+
+ while ((Exynos_Check_BufferProcess_State(pExynosComponent)) && (!pAudioDec->bExitBufferProcessThread)) {
+ Exynos_OSAL_SleepMillisec(0);
+
+ Exynos_OSAL_MutexLock(outputUseBuffer->bufferMutex);
+ if ((outputUseBuffer->dataValid != OMX_TRUE) &&
+ (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+ Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex);
+ ret = Exynos_OutputBufferGetQueue(pExynosComponent);
+ if ((ret == OMX_ErrorUndefined) ||
+ (exynosInputPort->portState != OMX_StateIdle) ||
+ (exynosOutputPort->portState != OMX_StateIdle)) {
+ break;
+ }
+ } else {
+ Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex);
+ }
+
+ if (pExynosComponent->reInputData == OMX_FALSE) {
+ Exynos_OSAL_MutexLock(inputUseBuffer->bufferMutex);
+ if ((Exynos_Preprocessor_InputData(pOMXComponent) == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
+ Exynos_OSAL_MutexUnlock(inputUseBuffer->bufferMutex);
+ ret = Exynos_InputBufferGetQueue(pExynosComponent);
+ break;
+ }
+
+ Exynos_OSAL_MutexUnlock(inputUseBuffer->bufferMutex);
+ }
+
+ Exynos_OSAL_MutexLock(inputUseBuffer->bufferMutex);
+ Exynos_OSAL_MutexLock(outputUseBuffer->bufferMutex);
+ ret = pAudioDec->exynos_codec_bufferProcess(pOMXComponent, inputData, outputData);
+ Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex);
+ Exynos_OSAL_MutexUnlock(inputUseBuffer->bufferMutex);
+
+ if (ret == (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet)
+ pExynosComponent->reInputData = OMX_TRUE;
+ else
+ pExynosComponent->reInputData = OMX_FALSE;
+
+ Exynos_OSAL_MutexLock(outputUseBuffer->bufferMutex);
+ Exynos_Postprocess_OutputData(pOMXComponent);
+ Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex);
+ }
+ }
+
+EXIT:
+
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_GetFlushBuffer(EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_DATABUFFER **pDataBuffer)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ FunctionIn();
+
+ if (pExynosPort->portWayType == WAY2_PORT) {
+ *pDataBuffer = NULL;
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ *pDataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ EXYNOS_OMX_DATABUFFER *flushPortBuffer = NULL;
+ OMX_BUFFERHEADERTYPE *bufferHeader = NULL;
+ EXYNOS_OMX_MESSAGE *message = NULL;
+ OMX_U32 flushNum = 0;
+ OMX_S32 semValue = 0;
+
+ FunctionIn();
+
+ 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) {
+ bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData;
+ bufferHeader->nFilledLen = 0;
+
+ if (portIndex == OUTPUT_PORT_INDEX) {
+ Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader);
+ } else {
+ Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader);
+ }
+
+ Exynos_OSAL_Free(message);
+ message = NULL;
+ }
+ }
+
+ Exynos_OMX_GetFlushBuffer(pExynosPort, &flushPortBuffer);
+ if (flushPortBuffer != NULL) {
+ if (flushPortBuffer->dataValid == OMX_TRUE) {
+ if (portIndex == INPUT_PORT_INDEX)
+ Exynos_InputBufferReturn(pOMXComponent);
+ else if (portIndex == OUTPUT_PORT_INDEX)
+ Exynos_OutputBufferReturn(pOMXComponent);
+ }
+ }
+
+ while(1) {
+ OMX_S32 cnt = 0;
+ Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &cnt);
+ if (cnt <= 0)
+ break;
+ Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[portIndex].bufferSemID);
+ }
+ Exynos_OSAL_SetElemNum(&pExynosPort->bufferQ, 0);
+
+ pExynosPort->processData.dataLen = 0;
+ pExynosPort->processData.nFlags = 0;
+ pExynosPort->processData.remainDataLen = 0;
+ pExynosPort->processData.timeStamp = 0;
+ pExynosPort->processData.usedDataLen = 0;
+
+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_AUDIODEC_COMPONENT *pAudioDec = NULL;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ EXYNOS_OMX_DATABUFFER *flushPortBuffer = NULL;
+ 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;
+ pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+ Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
+
+ pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_TRUE;
+
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+ Exynos_OMX_GetFlushBuffer(pExynosPort, &flushPortBuffer);
+
+ Exynos_OSAL_MutexLock(flushPortBuffer->bufferMutex);
+ ret = Exynos_OMX_FlushPort(pOMXComponent, nPortIndex);
+ Exynos_OSAL_MutexUnlock(flushPortBuffer->bufferMutex);
+
+ pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_FALSE;
+
+ if (bEvent == OMX_TRUE && ret == OMX_ErrorNone) {
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventCmdComplete,
+ OMX_CommandFlush, nPortIndex, NULL);
+ }
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE;
+ pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
+ 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->reInputData = OMX_FALSE;
+ }
+
+EXIT:
+ if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__);
+ pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError,
+ ret, 0, NULL);
+ }
+
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetParameter(
+ 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_BASEPORT *pExynosPort = 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 (ComponentParameterStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ switch (nParamIndex) {
+ case OMX_IndexParamAudioInit:
+ {
+ 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) {
+ goto EXIT;
+ }
+
+ portParam->nPorts = pExynosComponent->portParam.nPorts;
+ portParam->nStartPortNumber = pExynosComponent->portParam.nStartPortNumber;
+ ret = OMX_ErrorNone;
+ }
+ break;
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+ OMX_U32 portIndex = portFormat->nPortIndex;
+ OMX_U32 index = portFormat->nIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL;
+ OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */
+
+ ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if ((portIndex >= pExynosComponent->portParam.nPorts)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+
+ if (portIndex == INPUT_PORT_INDEX) {
+ supportFormatNum = INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1;
+ if (index > supportFormatNum) {
+ ret = OMX_ErrorNoMore;
+ goto EXIT;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ portDefinition = &pExynosPort->portDefinition;
+
+ portFormat->eEncoding = portDefinition->format.audio.eEncoding;
+ } else if (portIndex == OUTPUT_PORT_INDEX) {
+ supportFormatNum = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1;
+ if (index > supportFormatNum) {
+ ret = OMX_ErrorNoMore;
+ goto EXIT;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ portDefinition = &pExynosPort->portDefinition;
+
+ portFormat->eEncoding = portDefinition->format.audio.eEncoding;
+ }
+ ret = OMX_ErrorNone;
+ }
+ break;
+ default:
+ {
+ ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
+ }
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeSetParameter(
+ 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_BASEPORT *pExynosPort = 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 (ComponentParameterStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+ OMX_U32 portIndex = portFormat->nPortIndex;
+ OMX_U32 index = portFormat->nIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL;
+ OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */
+
+ ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if ((portIndex >= pExynosComponent->portParam.nPorts)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+ portDefinition = &pExynosPort->portDefinition;
+
+ portDefinition->format.audio.eEncoding = portFormat->eEncoding;
+ ret = OMX_ErrorNone;
+ }
+ break;
+ default:
+ {
+ ret = Exynos_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure);
+ }
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetConfig(
+ OMX_HANDLETYPE hComponent,
+ OMX_INDEXTYPE nIndex,
+ OMX_PTR pComponentConfigStructure)
+{
+ 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 (pComponentConfigStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ default:
+ ret = Exynos_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeSetConfig(
+ OMX_HANDLETYPE hComponent,
+ OMX_INDEXTYPE nIndex,
+ OMX_PTR pComponentConfigStructure)
+{
+ 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 (pComponentConfigStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ case OMX_IndexConfigAudioMute:
+ {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_IndexConfigAudioMute");
+ ret = OMX_ErrorUnsupportedIndex;
+ }
+ break;
+ case OMX_IndexConfigAudioVolume:
+ {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_IndexConfigAudioVolume");
+ ret = OMX_ErrorUnsupportedIndex;
+ }
+ break;
+ default:
+ ret = Exynos_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetExtensionIndex(
+ 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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_BufferProcessThread(OMX_PTR threadData)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ OMX_COMPONENTTYPE *pOMXComponent = NULL;
+ EXYNOS_OMX_BASECOMPONENT *pSECComponent = NULL;
+ EXYNOS_OMX_MESSAGE *message = 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;
+ }
+ pSECComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ Exynos_OMX_BufferProcess(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_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+ FunctionIn();
+
+ pAudioDec->bExitBufferProcessThread = OMX_FALSE;
+
+ ret = Exynos_OSAL_ThreadCreate(&pAudioDec->hBufferProcessThread,
+ Exynos_OMX_BufferProcessThread,
+ 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_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ OMX_S32 countValue = 0;
+ unsigned int i = 0;
+
+ FunctionIn();
+
+ pAudioDec->bExitBufferProcessThread = OMX_TRUE;
+
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[i].bufferSemID, &countValue);
+ if (countValue == 0)
+ Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID);
+ }
+
+ Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
+ Exynos_OSAL_ThreadTerminate(pAudioDec->hBufferProcessThread);
+ pAudioDec->hBufferProcessThread = NULL;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeComponentInit(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_AUDIODEC_COMPONENT *pAudioDec = 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) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_Port_Constructor(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ pAudioDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_AUDIODEC_COMPONENT));
+ if (pAudioDec == NULL) {
+ Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Memset(pAudioDec, 0, sizeof(EXYNOS_OMX_AUDIODEC_COMPONENT));
+ pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pAudioDec;
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pExynosComponent->bMultiThreadProcess = OMX_FALSE;
+ pAudioDec->bFirstFrame = OMX_TRUE;
+
+ /* Input port */
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosPort->portDefinition.nBufferCountActual = MAX_AUDIO_INPUTBUFFER_NUM;
+ pExynosPort->portDefinition.nBufferCountMin = MAX_AUDIO_INPUTBUFFER_NUM;
+ pExynosPort->portDefinition.nBufferSize = DEFAULT_AUDIO_INPUT_BUFFER_SIZE;
+ pExynosPort->portDefinition.eDomain = OMX_PortDomainAudio;
+
+ pExynosPort->portDefinition.format.audio.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingUnused;
+
+ /* Output port */
+ pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ pExynosPort->portDefinition.nBufferCountActual = MAX_AUDIO_OUTPUTBUFFER_NUM;
+ pExynosPort->portDefinition.nBufferCountMin = MAX_AUDIO_OUTPUTBUFFER_NUM;
+ pExynosPort->portDefinition.nBufferSize = DEFAULT_AUDIO_OUTPUT_BUFFER_SIZE;
+ pExynosPort->portDefinition.eDomain = OMX_PortDomainAudio;
+
+ pExynosPort->portDefinition.format.audio.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingUnused;
+
+
+ pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer;
+ pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer;
+ pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer;
+ pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
+
+#ifdef TUNNELING_SUPPORT
+ 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_AudioDecodeComponentDeinit(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_AUDIODEC_COMPONENT *pAudioDec = 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;
+
+ pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ Exynos_OSAL_Free(pAudioDec);
+ pExynosComponent->hComponentHandle = pAudioDec = NULL;
+
+ for(i = 0; i < ALL_PORT_NUM; i++) {
+ pExynosPort = &pExynosComponent->pExynosPort[i];
+ Exynos_OSAL_Free(pExynosPort->portDefinition.format.audio.cMIMEType);
+ pExynosPort->portDefinition.format.audio.cMIMEType = NULL;
+ }
+
+ ret = Exynos_OMX_Port_Destructor(pOMXComponent);
+
+ ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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_Adec.h
+ * @brief
+ * @author Yunji Kim (yunji.kim@samsung.com)
+ *
+ * @version 1.1.0
+ * @history
+ * 2012.02.28 : Create
+ */
+
+#ifndef EXYNOS_OMX_AUDIO_DECODE
+#define EXYNOS_OMX_AUDIO_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"
+
+#define MAX_AUDIO_INPUTBUFFER_NUM 2
+#define MAX_AUDIO_OUTPUTBUFFER_NUM 2
+
+#define DEFAULT_AUDIO_INPUT_BUFFER_SIZE (16 * 1024)
+#define DEFAULT_AUDIO_OUTPUT_BUFFER_SIZE (32 * 1024)
+
+#define DEFAULT_AUDIO_SAMPLING_FREQ 44100
+#define DEFAULT_AUDIO_CHANNELS_NUM 2
+#define DEFAULT_AUDIO_BIT_PER_SAMPLE 16
+
+#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 1
+#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 1
+
+#define AUDIO_DATA_PLANE 0
+
+
+typedef struct _SRP_DEC_INPUT_BUFFER
+{
+ void *PhyAddr; // physical address
+ void *VirAddr; // virtual address
+ int bufferSize; // input buffer alloc size
+ int dataSize; // Data length
+} SRP_DEC_INPUT_BUFFER;
+
+typedef struct _EXYNOS_OMX_AUDIODEC_COMPONENT
+{
+ OMX_HANDLETYPE hCodecHandle;
+
+ OMX_BOOL bFirstFrame;
+ OMX_PTR pInputBuffer;
+ SRP_DEC_INPUT_BUFFER SRPDecInputBuffer[MAX_AUDIO_INPUTBUFFER_NUM];
+ OMX_U32 indexInputBuffer;
+ OMX_TICKS outFrames;
+ OMX_TICKS baseTime;
+
+ /* Buffer Process */
+ OMX_BOOL bExitBufferProcessThread;
+ OMX_HANDLETYPE hBufferProcessThread;
+
+ OMX_ERRORTYPE (*exynos_codec_bufferProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData);
+
+ int (*exynos_checkInputFrame)(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame);
+} EXYNOS_OMX_AUDIODEC_COMPONENT;
+
+
+#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);
+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);
+OMX_ERRORTYPE Exynos_OMX_BufferProcess(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetParameter(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nParamIndex,
+ OMX_INOUT OMX_PTR ComponentParameterStructure);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeSetParameter(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_IN OMX_PTR ComponentParameterStructure);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetConfig(
+ OMX_HANDLETYPE hComponent,
+ OMX_INDEXTYPE nIndex,
+ OMX_PTR pComponentConfigStructure);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeSetConfig(
+ OMX_HANDLETYPE hComponent,
+ OMX_INDEXTYPE nIndex,
+ OMX_PTR pComponentConfigStructure);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetExtensionIndex(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_STRING cParameterName,
+ OMX_OUT OMX_INDEXTYPE *pIndexType);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EXYNOS_OMX_AUDIO_DECODE */
--- /dev/null
+
+ 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
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Mp3dec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.MP3.Decoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Adec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libsrpapi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/audio/dec \
+ $(EXYNOS_AUDIO_CODEC)/alp/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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_Mp3dec.c
+ * @brief
+ * @author Yunji Kim (yunji.kim@samsung.com)
+ * @version 1.1.0
+ * @history
+ * 2012.02.28 : 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_Adec.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Mp3dec.h"
+#include "srp_api.h"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG "EXYNOS_MP3_DEC"
+#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+//#define SRP_DUMP_TO_FILE
+#ifdef SRP_DUMP_TO_FILE
+#include "stdio.h"
+
+FILE *inFile;
+FILE *outFile;
+#endif
+
+OMX_ERRORTYPE Exynos_SRP_Mp3Dec_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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nParamIndex) {
+ case OMX_IndexParamAudioMp3:
+ {
+ OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
+ OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = NULL;
+ EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstMp3Param->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pSrcMp3Param = &pMp3Dec->mp3Param;
+
+ Exynos_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
+ }
+ break;
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
+ OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = NULL;
+ EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstPcmParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pSrcPcmParam = &pMp3Dec->pcmParam;
+
+ Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ }
+ 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) {
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE);
+ }
+ break;
+ default:
+ ret = Exynos_OMX_AudioDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+ break;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_SRP_Mp3Dec_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 || 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ case OMX_IndexParamAudioMp3:
+ {
+ OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = NULL;
+ OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
+ EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcMp3Param->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pDstMp3Param = &pMp3Dec->mp3Param;
+
+ Exynos_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
+ }
+ break;
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = NULL;
+ OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
+ EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcPcmParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pDstPcmParam = &pMp3Dec->pcmParam;
+
+ Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ }
+ 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) {
+ 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_MP3_DEC_ROLE)) {
+ pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
+ } else {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ }
+ break;
+ default:
+ ret = Exynos_OMX_AudioDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+ break;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_SRP_Mp3Dec_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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ default:
+ ret = Exynos_OMX_AudioDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_SRP_Mp3Dec_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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ default:
+ ret = Exynos_OMX_AudioDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_SRP_Mp3Dec_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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_AudioDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_SRP_Mp3Dec_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;
+ }
+
+ Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_SRP_Mp3Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_MP3_HANDLE *pMp3Dec = (EXYNOS_MP3_HANDLE *)pAudioDec->hCodecHandle;
+
+ FunctionIn();
+
+ INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+ Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+ pExynosComponent->bUseFlagEOF = OMX_TRUE; /* Mp3 extractor should parse into frame unit. */
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pMp3Dec->hSRPMp3Handle.bConfiguredSRP = OMX_FALSE;
+ pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE;
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+#ifdef SRP_DUMP_TO_FILE
+ inFile = fopen("/data/InFile.mp3", "w+");
+ outFile = fopen("/data/OutFile.pcm", "w+");
+#endif
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_SRP_Mp3Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ FunctionIn();
+
+#ifdef SRP_DUMP_TO_FILE
+ fclose(inFile);
+ fclose(outFile);
+#endif
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_SRP_Mp3_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_MP3_HANDLE *pMp3Dec = (EXYNOS_MP3_HANDLE *)pAudioDec->hCodecHandle;
+ struct srp_dec_info codecDecInfo;
+ OMX_S32 returnCodec = 0;
+ unsigned long isSRPStopped = 0;
+ OMX_PTR dataBuffer = NULL;
+ unsigned int dataLen = 0;
+ OMX_BOOL isSRPIbufOverflow = OMX_FALSE;
+
+ FunctionIn();
+
+#ifdef SRP_DUMP_TO_FILE
+ if (pExynosComponent->reInputData == OMX_FALSE) {
+ fwrite(pInputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], pInputData->dataLen, 1, inFile);
+ }
+#endif
+
+ /* Save timestamp and flags of input data */
+ if (pAudioDec->bFirstFrame) {
+ pOutputData->timeStamp = pInputData->timeStamp;
+ pAudioDec->baseTime = pInputData->timeStamp;
+ pAudioDec->bFirstFrame = OMX_FALSE;
+ }
+ pOutputData->nFlags = pInputData->nFlags & (~OMX_BUFFERFLAG_EOS);
+
+ /* Decoding mp3 frames by SRP */
+ if (pExynosComponent->getAllDelayBuffer == OMX_FALSE) {
+ returnCodec = SRP_Decode(pInputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], pInputData->dataLen);
+
+ if (returnCodec >= 0) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
+ SRP_Send_EOS();
+ pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_TRUE;
+ }
+ } else if (returnCodec == SRP_ERROR_IBUF_OVERFLOW) {
+ isSRPIbufOverflow = OMX_TRUE;
+ ret = OMX_ErrorInputDataDecodeYet;
+ }
+ }
+
+ if (pMp3Dec->hSRPMp3Handle.bConfiguredSRP == OMX_FALSE) {
+ if ((pInputData->dataLen <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ returnCodec = SRP_Get_Dec_Info(&codecDecInfo);
+ if (returnCodec < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Get_Dec_Info failed: %d", returnCodec);
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+
+ if (!codecDecInfo.sample_rate || !codecDecInfo.channels) {
+ if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) {
+ pOutputData->dataLen = 0;
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ ret = OMX_ErrorInputDataDecodeYet;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ if (isSRPIbufOverflow)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+ }
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "numChannels(%d), samplingRate(%d)",
+ codecDecInfo.channels, codecDecInfo.sample_rate);
+
+ if (pMp3Dec->pcmParam.nChannels != codecDecInfo.channels ||
+ pMp3Dec->pcmParam.nSamplingRate != codecDecInfo.sample_rate) {
+ /* Change channel count and sampling rate information */
+ pMp3Dec->pcmParam.nChannels = codecDecInfo.channels;
+ pMp3Dec->pcmParam.nSamplingRate = codecDecInfo.sample_rate;
+
+ /* 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);
+ }
+
+ pMp3Dec->hSRPMp3Handle.bConfiguredSRP = OMX_TRUE;
+
+ if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) {
+ pOutputData->dataLen = 0;
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ ret = OMX_ErrorInputDataDecodeYet;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ if (isSRPIbufOverflow)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+ }
+ goto EXIT;
+ }
+
+ /* Get decoded data from SRP */
+ returnCodec = SRP_Get_PCM(&dataBuffer, &dataLen);
+ if (pMp3Dec->hSRPMp3Handle.bConfiguredSRP == OMX_TRUE) {
+ pOutputData->timeStamp = pAudioDec->baseTime + pAudioDec->outFrames * 1000 * 1000 / (OMX_TICKS)pMp3Dec->pcmParam.nSamplingRate;
+ int frames = dataLen / pMp3Dec->pcmParam.nChannels / 2;
+ pAudioDec->outFrames += frames;
+ }
+ if (dataLen > 0) {
+ pOutputData->dataLen = dataLen;
+ Exynos_OSAL_Memcpy(pOutputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], dataBuffer, dataLen);
+ } else {
+ pOutputData->dataLen = 0;
+ }
+
+#ifdef SRP_DUMP_TO_FILE
+ if (pOutputData->dataLen > 0)
+ fwrite(pOutputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], pOutputData->dataLen, 1, outFile);
+#endif
+
+ /* Delay EOS signal until all the PCM is returned from the SRP driver. */
+ if (pMp3Dec->hSRPMp3Handle.bSRPSendEOS == OMX_TRUE) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
+ returnCodec = SRP_GetParams(SRP_STOP_EOS_STATE, &isSRPStopped);
+ if (returnCodec != 0)
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail SRP_STOP_EOS_STATE");
+ if (isSRPStopped == 1) {
+ pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE; /* for repeating one song */
+ ret = OMX_ErrorNone;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ ret = OMX_ErrorInputDataDecodeYet;
+ }
+ } else { /* Flush after EOS */
+ pMp3Dec->hSRPMp3Handle.bSRPSendEOS = OMX_FALSE;
+ }
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_SRP_Mp3Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
+{
+ 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();
+
+ if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) ||
+ (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+
+ goto EXIT;
+ }
+ if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent)) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+
+ goto EXIT;
+ }
+
+ ret = Exynos_SRP_Mp3_Decode_Block(pOMXComponent, pInputData, pOutputData);
+
+ if (ret != OMX_ErrorNone) {
+ if (ret == (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet) {
+ pOutputData->usedDataLen = 0;
+ pOutputData->remainDataLen = pOutputData->dataLen;
+ } else {
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, ret, 0, NULL);
+ }
+ } else {
+ pInputData->usedDataLen += pInputData->dataLen;
+ pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen;
+ pInputData->dataLen -= pInputData->usedDataLen;
+ pInputData->usedDataLen = 0;
+
+ pOutputData->usedDataLen = 0;
+ pOutputData->remainDataLen = pOutputData->dataLen;
+ }
+
+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_AUDIODEC_COMPONENT *pAudioDec = NULL;
+ EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
+ OMX_PTR pInputBuffer = NULL;
+ OMX_PTR pOutputBuffer = NULL;
+ unsigned int inputBufferSize = 0;
+ unsigned int inputBufferNum = 0;
+ unsigned int outputBufferSize = 0;
+ unsigned int outputBufferNum = 0;
+ OMX_S32 returnCodec;
+ int i = 0;
+
+ FunctionIn();
+
+ if ((hComponent == NULL) || (componentName == NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MP3_DEC, componentName) != 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_AudioDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_AudioDecodeComponentInit error, ret: %X", __FUNCTION__, ret);
+ goto EXIT;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ pExynosComponent->codecType = HW_AUDIO_DEC_CODEC;
+
+ pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+ if (pExynosComponent->componentName == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_1;
+ }
+ Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+ Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MP3_DEC);
+
+ pMp3Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MP3_HANDLE));
+ if (pMp3Dec == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: EXYNOS_MP3_HANDLE alloc error, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_2;
+ }
+ Exynos_OSAL_Memset(pMp3Dec, 0, sizeof(EXYNOS_MP3_HANDLE));
+ pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pAudioDec->hCodecHandle = (OMX_HANDLETYPE)pMp3Dec;
+
+ /* Create and Init SRP */
+ pMp3Dec->hSRPMp3Handle.bSRPLoaded = OMX_FALSE;
+ returnCodec = SRP_Create(SRP_INIT_BLOCK_MODE);
+ if (returnCodec < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Create failed: %d", returnCodec);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_3;
+ }
+ pMp3Dec->hSRPMp3Handle.hSRPHandle = returnCodec; /* SRP's fd */
+
+ returnCodec = SRP_Init();
+ if (returnCodec < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Init failed: %d", returnCodec);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_4;
+ }
+ pMp3Dec->hSRPMp3Handle.bSRPLoaded = OMX_TRUE;
+
+ /* Get input buffer info from SRP */
+ returnCodec = SRP_Get_Ibuf_Info(&pInputBuffer, &inputBufferSize, &inputBufferNum);
+ if (returnCodec < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Get_Ibuf_Info failed: %d", returnCodec);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_5;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosPort->processData.allocSize = inputBufferSize;
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = Exynos_OSAL_Malloc(inputBufferSize);
+ if (pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Input data buffer alloc failed");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_5;
+ }
+
+ /* Get output buffer info from SRP */
+ returnCodec = SRP_Get_Obuf_Info(&pOutputBuffer, &outputBufferSize, &outputBufferNum);
+ if (returnCodec < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SRP_Get_Obuf_Info failed: %d", returnCodec);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_6;
+ }
+
+ /* 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.nBufferCountActual = inputBufferNum;
+ pExynosPort->portDefinition.nBufferCountMin = inputBufferNum;
+ pExynosPort->portDefinition.nBufferSize = inputBufferSize;
+ pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+ Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/mpeg");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
+ pExynosPort->portWayType = WAY1_PORT;
+
+ /* Output port */
+ pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ pExynosPort->portDefinition.nBufferCountActual = outputBufferNum;
+ pExynosPort->portDefinition.nBufferCountMin = outputBufferNum;
+ pExynosPort->portDefinition.nBufferSize = outputBufferSize;
+ pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+ Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+ pExynosPort->portWayType = WAY1_PORT;
+
+ /* Default values for Mp3 audio param */
+ INIT_SET_SIZE_VERSION(&pMp3Dec->mp3Param, OMX_AUDIO_PARAM_MP3TYPE);
+ pMp3Dec->mp3Param.nPortIndex = INPUT_PORT_INDEX;
+ pMp3Dec->mp3Param.nChannels = DEFAULT_AUDIO_CHANNELS_NUM;
+ pMp3Dec->mp3Param.nBitRate = 0;
+ pMp3Dec->mp3Param.nSampleRate = DEFAULT_AUDIO_SAMPLING_FREQ;
+ pMp3Dec->mp3Param.nAudioBandWidth = 0;
+ pMp3Dec->mp3Param.eChannelMode = OMX_AUDIO_ChannelModeStereo;
+ pMp3Dec->mp3Param.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3;
+
+ /* Default values for PCM audio param */
+ INIT_SET_SIZE_VERSION(&pMp3Dec->pcmParam, OMX_AUDIO_PARAM_PCMMODETYPE);
+ pMp3Dec->pcmParam.nPortIndex = OUTPUT_PORT_INDEX;
+ pMp3Dec->pcmParam.nChannels = DEFAULT_AUDIO_CHANNELS_NUM;
+ pMp3Dec->pcmParam.eNumData = OMX_NumericalDataSigned;
+ pMp3Dec->pcmParam.eEndian = OMX_EndianLittle;
+ pMp3Dec->pcmParam.bInterleaved = OMX_TRUE;
+ pMp3Dec->pcmParam.nBitPerSample = DEFAULT_AUDIO_BIT_PER_SAMPLE;
+ pMp3Dec->pcmParam.nSamplingRate = DEFAULT_AUDIO_SAMPLING_FREQ;
+ pMp3Dec->pcmParam.ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pMp3Dec->pcmParam.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pMp3Dec->pcmParam.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ pOMXComponent->GetParameter = &Exynos_SRP_Mp3Dec_GetParameter;
+ pOMXComponent->SetParameter = &Exynos_SRP_Mp3Dec_SetParameter;
+ pOMXComponent->GetConfig = &Exynos_SRP_Mp3Dec_GetConfig;
+ pOMXComponent->SetConfig = &Exynos_SRP_Mp3Dec_SetConfig;
+ pOMXComponent->GetExtensionIndex = &Exynos_SRP_Mp3Dec_GetExtensionIndex;
+ pOMXComponent->ComponentRoleEnum = &Exynos_SRP_Mp3Dec_ComponentRoleEnum;
+ pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
+
+ /* ToDo: Change the function name associated with a specific codec */
+ pExynosComponent->exynos_codec_componentInit = &Exynos_SRP_Mp3Dec_Init;
+ pExynosComponent->exynos_codec_componentTerminate = &Exynos_SRP_Mp3Dec_Terminate;
+ pAudioDec->exynos_codec_bufferProcess = &Exynos_SRP_Mp3Dec_bufferProcess;
+ pAudioDec->exynos_checkInputFrame = NULL;
+
+ pExynosComponent->currentState = OMX_StateLoaded;
+
+ ret = OMX_ErrorNone;
+ goto EXIT; /* This function is performed successfully. */
+
+EXIT_ERROR_6:
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ Exynos_OSAL_Free(pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE]);
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = NULL;
+ pExynosPort->processData.allocSize = 0;
+EXIT_ERROR_5:
+ SRP_Deinit();
+EXIT_ERROR_4:
+ SRP_Terminate();
+EXIT_ERROR_3:
+ Exynos_OSAL_Free(pMp3Dec);
+ pAudioDec->hCodecHandle = NULL;
+EXIT_ERROR_2:
+ Exynos_OSAL_Free(pExynosComponent->componentName);
+ pExynosComponent->componentName = NULL;
+EXIT_ERROR_1:
+ Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
+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_MP3_HANDLE *pMp3Dec = NULL;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+ FunctionIn();
+
+ if (hComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ Exynos_OSAL_Free(pExynosComponent->componentName);
+ pExynosComponent->componentName = NULL;
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ if (pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE]) {
+ Exynos_OSAL_Free(pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE]);
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = NULL;
+ pExynosPort->processData.allocSize = 0;
+ }
+
+ pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ if (pMp3Dec != NULL) {
+ if (pMp3Dec->hSRPMp3Handle.bSRPLoaded == OMX_TRUE) {
+ SRP_Deinit();
+ SRP_Terminate();
+ }
+ Exynos_OSAL_Free(pMp3Dec);
+ ((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ }
+
+ ret = Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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_Mp3dec.h
+ * @brief
+ * @author Yunji Kim (yunji.kim@samsung.com)
+ * @version 1.1.0
+ * @history
+ * 2012.02.28 : Create
+ */
+
+#ifndef EXYNOS_OMX_MP3_DEC_COMPONENT
+#define EXYNOS_OMX_MP3_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+
+typedef struct _EXYNOS_SRP_MP3_HANDLE
+{
+ OMX_U32 hSRPHandle;
+ OMX_BOOL bConfiguredSRP;
+ OMX_BOOL bSRPLoaded;
+ OMX_BOOL bSRPSendEOS;
+ OMX_S32 returnCodec;
+} EXYNOS_SRP_MP3_HANDLE;
+
+typedef struct _EXYNOS_MP3_HANDLE
+{
+ /* OMX Codec specific */
+ OMX_AUDIO_PARAM_MP3TYPE mp3Param;
+ OMX_AUDIO_PARAM_PCMMODETYPE pcmParam;
+
+ /* SEC SRP Codec specific */
+ EXYNOS_SRP_MP3_HANDLE hSRPMp3Handle;
+} EXYNOS_MP3_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 /* EXYNOS_OMX_MP3_DEC_COMPONENT */
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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 1.1.0
+ * @history
+ * 2012.02.28 : 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_MP3_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 - audio decoder MP3 */
+ Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_MP3_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE);
+ ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+ FunctionOut();
+ return MAX_COMPONENT_NUM;
+}
+
--- /dev/null
+/*
+ *
+ * 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 1.1.0
+ * @history
+ * 2012.02.28 : Create
+ */
+
+#ifndef EXYNOS_OMX_MP3_DEC_REG
+#define EXYNOS_OMX_MP3_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
+
+/* MP3 */
+#define EXYNOS_OMX_COMPONENT_MP3_DEC "OMX.Exynos.MP3.Decoder"
+#define EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE "audio_decoder.mp3"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* EXYNOS_OMX_MP3_DEC_REG */
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Wmadec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.WMA.Decoder
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/omx
+
+LOCAL_CFLAGS :=
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Adec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libsrpapi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libffmpegapi\
+
+LOCAL_C_INCLUDES := $(EXYNOS_OMX_INC)/khronos \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/audio/dec \
+ $(EXYNOS_AUDIO_CODEC)/alp/include \
+ $(EXYNOS_AUDIO_CODEC)/ffmpeg/include
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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_Wmadec.c
+ * @brief
+ * @author Sungyeon Kim (sy85.kim@samsung.com)
+ * @version 1.0.0
+ * @history
+ * 2012.09.07 : 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_Adec.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Wmadec.h"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG "EXYNOS_WMA_DEC"
+#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+
+OMX_ERRORTYPE Exynos_FFMPEG_WmaDec_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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nParamIndex) {
+ case OMX_IndexParamAudioWma:
+ {
+ OMX_AUDIO_PARAM_WMATYPE *pDstWmaParam = (OMX_AUDIO_PARAM_WMATYPE *)pComponentParameterStructure;
+ OMX_AUDIO_PARAM_WMATYPE *pSrcWmaParam = NULL;
+ EXYNOS_WMA_HANDLE *pWmaDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstWmaParam, sizeof(OMX_AUDIO_PARAM_WMATYPE));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pDstWmaParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pWmaDec = (EXYNOS_WMA_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pSrcWmaParam = &pWmaDec->wmaParam;
+
+ Exynos_OSAL_Memcpy(pDstWmaParam, pSrcWmaParam, sizeof(OMX_AUDIO_PARAM_WMATYPE));
+ }
+ break;
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
+ OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = NULL;
+ EXYNOS_WMA_HANDLE *pWmaDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pDstPcmParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pWmaDec = (EXYNOS_WMA_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pSrcPcmParam = &pWmaDec->pcmParam;
+
+ Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ }
+ 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)
+ goto EXIT;
+
+ Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_WMA_DEC_ROLE);
+ }
+ break;
+ default:
+ ret = Exynos_OMX_AudioDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+ break;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_FFMPEG_WmaDec_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 || 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ case OMX_IndexParamAudioWma:
+ {
+ OMX_AUDIO_PARAM_WMATYPE *pDstWmaParam = NULL;
+ OMX_AUDIO_PARAM_WMATYPE *pSrcWmaParam = (OMX_AUDIO_PARAM_WMATYPE *)pComponentParameterStructure;
+ EXYNOS_WMA_HANDLE *pWmaDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcWmaParam, sizeof(OMX_AUDIO_PARAM_WMATYPE));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pSrcWmaParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pWmaDec = (EXYNOS_WMA_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pDstWmaParam = &pWmaDec->wmaParam;
+
+ Exynos_OSAL_Memcpy(pDstWmaParam, pSrcWmaParam, sizeof(OMX_AUDIO_PARAM_WMATYPE));
+ }
+ break;
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = NULL;
+ OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
+ EXYNOS_WMA_HANDLE *pWmaDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pSrcPcmParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pWmaDec = (EXYNOS_WMA_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pDstPcmParam = &pWmaDec->pcmParam;
+
+ Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ }
+ 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)
+ 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_WMA_DEC_ROLE)) {
+ pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingWMA;
+ } else {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ }
+ break;
+ default:
+ ret = Exynos_OMX_AudioDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+ break;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_FFMPEG_WmaDec_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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ /* TODO : Support for various OMX_INDEXTYPE */
+ default:
+ ret = Exynos_OMX_AudioDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_FFMPEG_WmaDec_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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ /* TODO : Support for various OMX_INDEXTYPE */
+ default:
+ ret = Exynos_OMX_AudioDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_FFMPEG_WmaDec_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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_AudioDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_FFMPEG_WmaDec_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;
+ }
+
+ Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_WMA_DEC_ROLE);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_FFMPEG_WmaDec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_WMA_HANDLE *pWmaDec = (EXYNOS_WMA_HANDLE *)pAudioDec->hCodecHandle;
+
+ FunctionIn();
+
+ INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+ Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+ pExynosComponent->bUseFlagEOF = OMX_TRUE; /* Wma extractor should parse into frame unit. */
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+ FFmpeg_Init(&pWmaDec->ffmpeg);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_FFMPEG_WmaDec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_WMA_HANDLE *pWmaDec = (EXYNOS_WMA_HANDLE *)pAudioDec->hCodecHandle;
+
+ FunctionIn();
+
+ FFmpeg_DeInit(&pWmaDec->ffmpeg);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_FFMPEG_WmaDec_codecConfigure(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData)
+{
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_WMA_HANDLE *pWmaDec = (EXYNOS_WMA_HANDLE *)pAudioDec->hCodecHandle;
+
+ const int codec_info_size = 18;
+
+ FFmpeg *ffmpeg = &pWmaDec->ffmpeg;
+ CodecInfoHhr codecInfo;
+ char extra_data[10];
+
+ Exynos_OSAL_Memcpy(&codecInfo, pInputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], codec_info_size);
+ Exynos_OSAL_Memcpy(extra_data, ((char*)pInputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE]) + codec_info_size,
+ codecInfo.codecSpecificDataSize);
+
+ return FFmpeg_CodecOpen(ffmpeg, codecInfo.codecID, codecInfo.averageNumberOfbytesPerSecond * 8,
+ extra_data, codecInfo.codecSpecificDataSize, codecInfo.sampleRates,
+ codecInfo.numberOfChannels, codecInfo.blockAlignment);
+}
+
+OMX_ERRORTYPE Exynos_FFMPEG_WmaDec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_WMA_HANDLE *pWmaDec = (EXYNOS_WMA_HANDLE *)pAudioDec->hCodecHandle;
+ EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ FunctionIn();
+
+ if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) ||
+ (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+
+ goto EXIT;
+ }
+ if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent)) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+
+ goto EXIT;
+ }
+ if (pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ ret = Exynos_FFMPEG_WmaDec_codecConfigure(pOMXComponent, pInputData);
+ } else {
+ /* Save timestamp and flags of input data */
+ pOutputData->timeStamp = pInputData->timeStamp;
+ pOutputData->nFlags = pInputData->nFlags & (~OMX_BUFFERFLAG_EOS);
+
+ /* WARNING IT DOESNT GUARANTEE WORKING WELL TO MULTIPLE FRAMES */
+ pInputData->dataLen = pInputData->allocSize;
+ pOutputData->dataLen = pOutputData->allocSize;
+ ret = FFmpeg_Decode(&pWmaDec->ffmpeg,
+ pInputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], (int*)&pInputData->dataLen,
+ pOutputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], (int*)&pOutputData->dataLen);
+ }
+
+ if (ret != OMX_ErrorNone) {
+ if (ret == OMX_ErrorInputDataDecodeYet) {
+ pOutputData->usedDataLen = 0;
+ pOutputData->remainDataLen = pOutputData->dataLen;
+ } else {
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, ret, 0, NULL);
+ }
+ } else {
+ pInputData->usedDataLen += pInputData->dataLen;
+ pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen;
+ pInputData->dataLen -= pInputData->usedDataLen;
+ pInputData->usedDataLen = 0;
+
+ pOutputData->usedDataLen = 0;
+ pOutputData->remainDataLen = pOutputData->dataLen;
+
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ }
+
+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_AUDIODEC_COMPONENT *pAudioDec = NULL;
+ EXYNOS_WMA_HANDLE *pWmaDec = NULL;
+ OMX_PTR pInputBuffer = NULL;
+ OMX_PTR pOutputBuffer = NULL;
+ unsigned int inputBufferSize = AUDIO_INBUF_SIZE;
+ unsigned int inputBufferNum = 1;
+ unsigned int outputBufferSize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
+ unsigned int outputBufferNum = 1;
+ OMX_S32 returnCodec;
+ int i = 0;
+
+ FunctionIn();
+
+ if ((hComponent == NULL) || (componentName == NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_WMA_DEC, componentName) != 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_AudioDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_AudioDecodeComponentInit error, ret: %X", __FUNCTION__, ret);
+ goto EXIT;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ pExynosComponent->codecType = HW_AUDIO_DEC_CODEC;
+
+ pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+ if (pExynosComponent->componentName == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_1;
+ }
+ Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+ Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_WMA_DEC);
+
+ pWmaDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_WMA_HANDLE));
+ if (pWmaDec == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: EXYNOS_WMA_HANDLE alloc error, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_2;
+ }
+ Exynos_OSAL_Memset(pWmaDec, 0, sizeof(EXYNOS_WMA_HANDLE));
+ pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pAudioDec->hCodecHandle = (OMX_HANDLETYPE)pWmaDec;
+
+ /* Get input buffer info */
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = Exynos_OSAL_Malloc(inputBufferSize);
+ if (pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Input data buffer alloc failed");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_3;
+ }
+ pExynosPort->processData.allocSize = inputBufferSize;
+
+ /* 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.nBufferCountActual = inputBufferNum;
+ pExynosPort->portDefinition.nBufferCountMin = inputBufferNum;
+ pExynosPort->portDefinition.nBufferSize = inputBufferSize;
+ pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+ Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/x-ms-wma");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingWMA;
+ pExynosPort->portWayType = WAY1_PORT;
+
+ /* Output port */
+ pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ pExynosPort->portDefinition.nBufferCountActual = outputBufferNum;
+ pExynosPort->portDefinition.nBufferCountMin = outputBufferNum;
+ pExynosPort->portDefinition.nBufferSize = outputBufferSize;
+ pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+ Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+ pExynosPort->portWayType = WAY1_PORT;
+
+ /* Default values for Wma audio param */
+ INIT_SET_SIZE_VERSION(&pWmaDec->wmaParam, OMX_AUDIO_PARAM_WMATYPE);
+ pWmaDec->wmaParam.nPortIndex = INPUT_PORT_INDEX;
+ pWmaDec->wmaParam.nChannels = DEFAULT_AUDIO_CHANNELS_NUM;
+ pWmaDec->wmaParam.nBitRate = 0;
+ pWmaDec->wmaParam.nSamplingRate = DEFAULT_AUDIO_SAMPLING_FREQ;
+ pWmaDec->wmaParam.eFormat = OMX_AUDIO_WMAFormat9;
+
+ /* Default values for PCM audio param */
+ INIT_SET_SIZE_VERSION(&pWmaDec->pcmParam, OMX_AUDIO_PARAM_PCMMODETYPE);
+ pWmaDec->pcmParam.nPortIndex = OUTPUT_PORT_INDEX;
+ pWmaDec->pcmParam.nChannels = DEFAULT_AUDIO_CHANNELS_NUM;
+ pWmaDec->pcmParam.eNumData = OMX_NumericalDataSigned;
+ pWmaDec->pcmParam.eEndian = OMX_EndianLittle;
+ pWmaDec->pcmParam.bInterleaved = OMX_TRUE;
+ pWmaDec->pcmParam.nBitPerSample = DEFAULT_AUDIO_BIT_PER_SAMPLE;
+ pWmaDec->pcmParam.nSamplingRate = DEFAULT_AUDIO_SAMPLING_FREQ;
+ pWmaDec->pcmParam.ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pWmaDec->pcmParam.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pWmaDec->pcmParam.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ pOMXComponent->GetParameter = &Exynos_FFMPEG_WmaDec_GetParameter;
+ pOMXComponent->SetParameter = &Exynos_FFMPEG_WmaDec_SetParameter;
+ pOMXComponent->GetConfig = &Exynos_FFMPEG_WmaDec_GetConfig;
+ pOMXComponent->SetConfig = &Exynos_FFMPEG_WmaDec_SetConfig;
+ pOMXComponent->GetExtensionIndex = &Exynos_FFMPEG_WmaDec_GetExtensionIndex;
+ pOMXComponent->ComponentRoleEnum = &Exynos_FFMPEG_WmaDec_ComponentRoleEnum;
+ pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
+
+ /* ToDo: Change the function name associated with a specific codec */
+ pExynosComponent->exynos_codec_componentInit = &Exynos_FFMPEG_WmaDec_Init;
+ pExynosComponent->exynos_codec_componentTerminate = &Exynos_FFMPEG_WmaDec_Terminate;
+ pAudioDec->exynos_codec_bufferProcess = &Exynos_FFMPEG_WmaDec_bufferProcess;
+ pAudioDec->exynos_checkInputFrame = NULL;
+
+ pExynosComponent->currentState = OMX_StateLoaded;
+
+ ret = OMX_ErrorNone;
+ goto EXIT; /* This function is performed successfully. */
+
+EXIT_ERROR_3:
+ Exynos_OSAL_Free(pWmaDec);
+ pAudioDec->hCodecHandle = NULL;
+EXIT_ERROR_2:
+ Exynos_OSAL_Free(pExynosComponent->componentName);
+ pExynosComponent->componentName = NULL;
+EXIT_ERROR_1:
+ Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
+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_WMA_HANDLE *pWmaDec = NULL;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+ FunctionIn();
+
+ if (hComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ Exynos_OSAL_Free(pExynosComponent->componentName);
+ pExynosComponent->componentName = NULL;
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ if (pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE]) {
+ Exynos_OSAL_Free(pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE]);
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = NULL;
+ pExynosPort->processData.allocSize = 0;
+ }
+
+ pWmaDec = (EXYNOS_WMA_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ if (pWmaDec != NULL) {
+ Exynos_OSAL_Free(pWmaDec);
+ ((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ }
+
+ ret = Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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_Wmadec.h
+ * @brief
+ * @author Sungyeon Kim (sy85.kim@samsung.com)
+ * @version 1.0.0
+ * @history
+ * 2012.09.07 : Create
+ */
+
+#ifndef EXYNOS_OMX_WMA_DEC_COMPONENT
+#define EXYNOS_OMX_WMA_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "ffmpeg_api.h"
+
+/*
+ * This structure is the same as BitmapInfoHhr struct in pv_avifile_typedefs.h file
+ */
+typedef struct _CodecInfoHhr
+{
+ OMX_U16 codecID;
+ OMX_U16 numberOfChannels;
+ OMX_U32 sampleRates;
+ OMX_U32 averageNumberOfbytesPerSecond;
+ OMX_U16 blockAlignment;
+ OMX_U16 bitsPerSample;
+ OMX_U16 codecSpecificDataSize;
+} CodecInfoHhr;
+
+typedef struct _EXYNOS_WMA_HANDLE
+{
+ /* OMX Codec specific */
+ OMX_AUDIO_PARAM_WMATYPE wmaParam;
+ OMX_AUDIO_PARAM_PCMMODETYPE pcmParam;
+
+ FFmpeg ffmpeg;
+} EXYNOS_WMA_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 /* EXYNOS_OMX_WMA_DEC_COMPONENT */
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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 Sungyeon Kim (sy85.kim@samsung.com)
+ * @version 1.0.0
+ * @history
+ * 2012.09.07 : 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_WMA_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 - audio decoder WMA */
+ Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_WMA_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_WMA_DEC_ROLE);
+ ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+ FunctionOut();
+ return MAX_COMPONENT_NUM;
+}
--- /dev/null
+/*
+ *
+ * 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 Sungyeon Kim (sy85.kim@samsung.com)
+ * @version 1.0.0
+ * @history
+ * 2012.09.07 : Create
+ */
+
+#ifndef EXYNOS_OMX_WMA_DEC_REG
+#define EXYNOS_OMX_WMA_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
+
+/* WMA */
+#define EXYNOS_OMX_COMPONENT_WMA_DEC "OMX.Exynos.WMA.Decoder"
+#define EXYNOS_OMX_COMPONENT_WMA_DEC_ROLE "audio_decoder.wma"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* EXYNOS_OMX_WMA_DEC_REG */
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Adec.c
+
+LOCAL_MODULE := libExynosOMX_Adec
+LOCAL_ARM_MODE := arm
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_LIBRARIES := libseirenhw
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/audio/seiren_dec \
+ $(EXYNOS_AUDIO_CODEC)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+
+include $(BUILD_STATIC_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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_Adec.c
+ * @brief
+ * @author Yunji Kim (yunji.kim@samsung.com)
+ *
+ * @version 1.1.0
+ * @history
+ * 2012.02.28 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "Exynos_OMX_Macros.h"
+#include "Exynos_OSAL_Event.h"
+#include "Exynos_OMX_Adec.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"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG "EXYNOS_AUDIO_DEC"
+#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) {
+ 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;
+
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+ if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+ if (pExynosPort->portState != OMX_StateIdle) {
+ 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) {
+ 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++;
+ if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+ pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ }
+ *ppBufferHdr = temp_bufferHeader;
+ ret = OMX_ErrorNone;
+ 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_BASEPORT *pExynosPort = NULL;
+ OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL;
+ OMX_U8 *temp_buffer = NULL;
+ OMX_U32 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;
+
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+ if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+/*
+ if (pExynosPort->portState != OMX_StateIdle ) {
+ ret = OMX_ErrorIncorrectStateOperation;
+ goto EXIT;
+ }
+*/
+ if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ temp_buffer = Exynos_OSAL_Malloc(sizeof(OMX_U8) * nSizeBytes);
+ if (temp_buffer == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
+ if (temp_bufferHeader == NULL) {
+ Exynos_OSAL_Free(temp_buffer);
+ temp_buffer = NULL;
+ 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_ALLOCATED | HEADER_STATE_ALLOCATED);
+ INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE);
+ 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++;
+ if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+ pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ }
+ *ppBuffer = temp_bufferHeader;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(temp_bufferHeader);
+ Exynos_OSAL_Free(temp_buffer);
+ 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_BASEPORT *pExynosPort = NULL;
+ OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL;
+ OMX_U8 *temp_buffer = NULL;
+ OMX_U32 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;
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+ if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pExynosPort->portState != OMX_StateLoaded) && (pExynosPort->portState != OMX_StateInvalid)) {
+ (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent,
+ pExynosComponent->callbackData,
+ (OMX_U32)OMX_EventError,
+ (OMX_U32)OMX_ErrorPortUnpopulated,
+ nPortIndex, NULL);
+ }
+
+ for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
+ if (((pExynosPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pExynosPort->extendBufferHeader[i].OMXBufferHeader != NULL)) {
+ if (pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer == pBufferHdr->pBuffer) {
+ if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) {
+ Exynos_OSAL_Free(pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer);
+ pExynosPort->extendBufferHeader[i].OMXBufferHeader->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(pExynosPort->extendBufferHeader[i].OMXBufferHeader);
+ 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 == 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosPort->unloadedResource signal set");
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->unloadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ pExynosPort->portDefinition.bPopulated = OMX_FALSE;
+ }
+ }
+
+ FunctionOut();
+
+ return ret;
+}
+
+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;
+}
+
+OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+ if ((pExynosComponent->currentState == OMX_StateExecuting) &&
+ (pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portState == OMX_StateIdle) &&
+ (pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portState == OMX_StateIdle) &&
+ (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+ (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
+ return OMX_TRUE;
+ } else {
+ return OMX_FALSE;
+ }
+}
+
+OMX_ERRORTYPE Exynos_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_OMX_DATABUFFER *dataBuffer = &exynosOMXInputPort->way.port1WayDataBuffer.dataBuffer;
+ OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader;
+
+ FunctionIn();
+
+ if (bufferHeader != NULL) {
+ if (exynosOMXInputPort->markType.hMarkTargetComponent != NULL ) {
+ bufferHeader->hMarkTargetComponent = exynosOMXInputPort->markType.hMarkTargetComponent;
+ bufferHeader->pMarkData = exynosOMXInputPort->markType.pMarkData;
+ exynosOMXInputPort->markType.hMarkTargetComponent = NULL;
+ exynosOMXInputPort->markType.pMarkData = NULL;
+ }
+
+ if (bufferHeader->hMarkTargetComponent != NULL) {
+ if (bufferHeader->hMarkTargetComponent == pOMXComponent) {
+ pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventMark,
+ 0, 0, bufferHeader->pMarkData);
+ } else {
+ pExynosComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent;
+ pExynosComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData;
+ }
+ }
+
+ bufferHeader->nFilledLen = 0;
+ Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader);
+ }
+
+ if ((pExynosComponent->currentState == OMX_StatePause) &&
+ ((!CHECK_PORT_BEING_FLUSHED(exynosOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(exynosOMXOutputPort)))) {
+ Exynos_OSAL_SignalWait(pExynosComponent->pauseEvent, DEF_MAX_WAIT_TIME);
+ Exynos_OSAL_SignalReset(pExynosComponent->pauseEvent);
+ }
+
+ dataBuffer->dataValid = OMX_FALSE;
+ dataBuffer->dataLen = 0;
+ dataBuffer->remainDataLen = 0;
+ dataBuffer->usedDataLen = 0;
+ dataBuffer->bufferHeader = NULL;
+ dataBuffer->nFlags = 0;
+ dataBuffer->timeStamp = 0;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_InputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ EXYNOS_OMX_DATABUFFER *dataBuffer = NULL;
+ EXYNOS_OMX_MESSAGE *message = NULL;
+
+ FunctionIn();
+
+ pExynosPort= &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ dataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer;
+
+ if (pExynosComponent->currentState != OMX_StateExecuting) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ } else {
+ Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+ Exynos_OSAL_MutexLock(dataBuffer->bufferMutex);
+ if (dataBuffer->dataValid != OMX_TRUE) {
+ message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (message == NULL) {
+ ret = OMX_ErrorUndefined;
+ Exynos_OSAL_MutexUnlock(dataBuffer->bufferMutex);
+ goto EXIT;
+ }
+
+ dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
+ dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen;
+ dataBuffer->dataLen = dataBuffer->bufferHeader->nFilledLen;
+ dataBuffer->remainDataLen = dataBuffer->dataLen;
+ dataBuffer->usedDataLen = 0;
+ dataBuffer->dataValid = OMX_TRUE;
+ dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags;
+ dataBuffer->timeStamp = dataBuffer->bufferHeader->nTimeStamp;
+
+ Exynos_OSAL_Free(message);
+
+ if (dataBuffer->allocSize <= dataBuffer->dataLen)
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", dataBuffer->allocSize, dataBuffer->dataLen);
+ }
+ Exynos_OSAL_MutexUnlock(dataBuffer->bufferMutex);
+ ret = OMX_ErrorNone;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_OMX_DATABUFFER *dataBuffer = &exynosOMXOutputPort->way.port1WayDataBuffer.dataBuffer;
+ OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader;
+
+ FunctionIn();
+
+ if (bufferHeader != NULL) {
+ bufferHeader->nFilledLen = dataBuffer->remainDataLen;
+ bufferHeader->nOffset = 0;
+ bufferHeader->nFlags = dataBuffer->nFlags;
+ bufferHeader->nTimeStamp = dataBuffer->timeStamp;
+
+ if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) {
+ bufferHeader->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent;
+ bufferHeader->pMarkData = pExynosComponent->propagateMarkType.pMarkData;
+ pExynosComponent->propagateMarkType.hMarkTargetComponent = NULL;
+ pExynosComponent->propagateMarkType.pMarkData = NULL;
+ }
+
+ if (bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventBufferFlag,
+ OUTPUT_PORT_INDEX,
+ bufferHeader->nFlags, NULL);
+ }
+
+ Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader);
+ }
+
+ if ((pExynosComponent->currentState == OMX_StatePause) &&
+ ((!CHECK_PORT_BEING_FLUSHED(exynosOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(exynosOMXOutputPort)))) {
+ Exynos_OSAL_SignalWait(pExynosComponent->pauseEvent, DEF_MAX_WAIT_TIME);
+ Exynos_OSAL_SignalReset(pExynosComponent->pauseEvent);
+ }
+
+ /* reset dataBuffer */
+ dataBuffer->dataValid = OMX_FALSE;
+ dataBuffer->dataLen = 0;
+ dataBuffer->remainDataLen = 0;
+ dataBuffer->usedDataLen = 0;
+ dataBuffer->bufferHeader = NULL;
+ dataBuffer->nFlags = 0;
+ dataBuffer->timeStamp = 0;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OutputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ EXYNOS_OMX_DATABUFFER *dataBuffer = NULL;
+ EXYNOS_OMX_MESSAGE *message = NULL;
+
+ FunctionIn();
+
+ pExynosPort= &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ dataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer;
+
+ if (pExynosComponent->currentState != OMX_StateExecuting) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ } else {
+ Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+ Exynos_OSAL_MutexLock(dataBuffer->bufferMutex);
+ if (dataBuffer->dataValid != OMX_TRUE) {
+ message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (message == NULL) {
+ ret = OMX_ErrorUndefined;
+ Exynos_OSAL_MutexUnlock(dataBuffer->bufferMutex);
+ goto EXIT;
+ }
+
+ dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
+ dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen;
+ dataBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen;
+ dataBuffer->remainDataLen = dataBuffer->dataLen;
+ dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset;
+ dataBuffer->dataValid = OMX_TRUE;
+ /* dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; */
+ /* dataBuffer->nTimeStamp = dataBuffer->bufferHeader->nTimeStamp; */
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = dataBuffer->bufferHeader->pBuffer;
+ pExynosPort->processData.allocSize = dataBuffer->bufferHeader->nAllocLen;
+
+ Exynos_OSAL_Free(message);
+ }
+ Exynos_OSAL_MutexUnlock(dataBuffer->bufferMutex);
+ ret = OMX_ErrorNone;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+
+}
+
+OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_BOOL ret = OMX_FALSE;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port1WayDataBuffer.dataBuffer;
+ EXYNOS_OMX_DATA *inputData = &exynosInputPort->processData;
+ OMX_U32 copySize = 0;
+ OMX_BYTE checkInputStream = NULL;
+ OMX_U32 checkInputStreamLen = 0;
+ OMX_U32 checkedSize = 0;
+ OMX_BOOL flagEOF = OMX_FALSE;
+ OMX_BOOL previousFrameEOF = OMX_FALSE;
+
+ FunctionIn();
+
+ if (inputUseBuffer->dataValid == OMX_TRUE) {
+ checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
+ checkInputStreamLen = inputUseBuffer->remainDataLen;
+
+ if (inputData->dataLen == 0) {
+ previousFrameEOF = OMX_TRUE;
+ } else {
+ previousFrameEOF = OMX_FALSE;
+ }
+
+ /* Audio extractor should parse into frame units. */
+ flagEOF = OMX_TRUE;
+ checkedSize = checkInputStreamLen;
+ copySize = checkedSize;
+
+ if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)
+ pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+
+ if (((inputData->allocSize) - (inputData->dataLen)) >= copySize) {
+ if (copySize > 0)
+ Exynos_OSAL_Memcpy((char*)inputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] + inputData->dataLen, checkInputStream, copySize);
+
+ inputUseBuffer->dataLen -= copySize;
+ inputUseBuffer->remainDataLen -= copySize;
+ inputUseBuffer->usedDataLen += copySize;
+
+ inputData->dataLen += copySize;
+ inputData->remainDataLen += copySize;
+
+ if (previousFrameEOF == OMX_TRUE) {
+ inputData->timeStamp = inputUseBuffer->timeStamp;
+ inputData->nFlags = inputUseBuffer->nFlags;
+ }
+
+ if (pExynosComponent->bUseFlagEOF == OMX_TRUE) {
+ if (pExynosComponent->bSaveFlagEOS == OMX_TRUE) {
+ inputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ flagEOF = OMX_TRUE;
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ } else {
+ inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS));
+ }
+ } else {
+ if ((checkedSize == checkInputStreamLen) && (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+ if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) &&
+ ((inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ||
+ (inputData->dataLen == 0))) {
+ inputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ flagEOF = OMX_TRUE;
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ } else if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) &&
+ (!(inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) &&
+ (inputData->dataLen != 0)) {
+ inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS));
+ flagEOF = OMX_TRUE;
+ pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+ }
+ } else {
+ inputData->nFlags = (inputUseBuffer->nFlags & (~OMX_BUFFERFLAG_EOS));
+ }
+ }
+ } else {
+ /*????????????????????????????????? Error ?????????????????????????????????*/
+ Exynos_ResetCodecData(inputData);
+ flagEOF = OMX_FALSE;
+ }
+
+ if ((inputUseBuffer->remainDataLen == 0) ||
+ (CHECK_PORT_BEING_FLUSHED(exynosInputPort)))
+ Exynos_InputBufferReturn(pOMXComponent);
+ else
+ inputUseBuffer->dataValid = OMX_TRUE;
+ }
+
+ if (flagEOF == OMX_TRUE) {
+ if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
+ /* Flush seiren buffers */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EOFFFFFFFF!!!!!!!!OMX_FLUSH_SEIREN");
+
+ pAudioDec->exynos_codec_flushSeiren(pOMXComponent, PORT_OUT);
+ //ADec_Flush(NULL, PORT_OUT);
+
+ pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
+ pExynosComponent->checkTimeStamp.startTimeStamp = inputData->timeStamp;
+ pExynosComponent->checkTimeStamp.nStartFlags = inputData->nFlags;
+ pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
+ inputData->timeStamp, inputData->timeStamp / 1E6);
+ }
+
+ ret = OMX_TRUE;
+ } else {
+ ret = OMX_FALSE;
+ }
+
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ 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.port1WayDataBuffer.dataBuffer;
+ EXYNOS_OMX_DATA *outputData = &exynosOutputPort->processData;
+ OMX_U32 copySize = 0;
+
+ FunctionIn();
+
+ if (outputUseBuffer->dataValid == OMX_TRUE) {
+ if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) {
+ if (pExynosComponent->checkTimeStamp.startTimeStamp == outputData->timeStamp) {
+ pExynosComponent->checkTimeStamp.startTimeStamp = RESET_TIMESTAMP_VAL;
+ pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
+ pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+ pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
+ } else {
+ Exynos_ResetCodecData(outputData);
+ ret = OMX_TRUE;
+ goto EXIT;
+ }
+ } else if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
+ Exynos_ResetCodecData(outputData);
+ ret = OMX_TRUE;
+ goto EXIT;
+ }
+
+ if (outputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) {
+ copySize = outputData->remainDataLen;
+
+ outputUseBuffer->dataLen += copySize;
+ outputUseBuffer->remainDataLen += copySize;
+ outputUseBuffer->nFlags = outputData->nFlags;
+ outputUseBuffer->timeStamp = outputData->timeStamp;
+
+ ret = OMX_TRUE;
+
+ /* reset outputData */
+ Exynos_ResetCodecData(outputData);
+
+ if ((outputUseBuffer->remainDataLen > 0) ||
+ (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) ||
+ (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))
+ Exynos_OutputBufferReturn(pOMXComponent);
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than decoded data size Out Length");
+
+ ret = OMX_FALSE;
+
+ /* reset outputData */
+ Exynos_ResetCodecData(outputData);
+ }
+ } else {
+ ret = OMX_FALSE;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_BufferProcess(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_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port1WayDataBuffer.dataBuffer;
+ EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port1WayDataBuffer.dataBuffer;
+ EXYNOS_OMX_DATA *inputData = &exynosInputPort->processData;
+ EXYNOS_OMX_DATA *outputData = &exynosOutputPort->processData;
+ OMX_U32 copySize = 0;
+
+ pExynosComponent->reInputData = OMX_FALSE;
+
+ FunctionIn();
+
+ while (!pAudioDec->bExitBufferProcessThread) {
+ 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(exynosInputPort) && !CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))) {
+ Exynos_OSAL_SignalWait(pExynosComponent->pauseEvent, DEF_MAX_WAIT_TIME);
+ Exynos_OSAL_SignalReset(pExynosComponent->pauseEvent);
+ }
+
+ while ((Exynos_Check_BufferProcess_State(pExynosComponent)) && (!pAudioDec->bExitBufferProcessThread)) {
+ Exynos_OSAL_MutexLock(outputUseBuffer->bufferMutex);
+ if ((outputUseBuffer->dataValid != OMX_TRUE) &&
+ (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+ Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex);
+ ret = Exynos_OutputBufferGetQueue(pExynosComponent);
+ if ((ret == OMX_ErrorUndefined) ||
+ (exynosInputPort->portState != OMX_StateIdle) ||
+ (exynosOutputPort->portState != OMX_StateIdle)) {
+ break;
+ }
+ } else {
+ Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex);
+ }
+
+ if (pExynosComponent->reInputData == OMX_FALSE) {
+ Exynos_OSAL_MutexLock(inputUseBuffer->bufferMutex);
+ if ((Exynos_Preprocessor_InputData(pOMXComponent) == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
+ Exynos_OSAL_MutexUnlock(inputUseBuffer->bufferMutex);
+ ret = Exynos_InputBufferGetQueue(pExynosComponent);
+ break;
+ }
+
+ Exynos_OSAL_MutexUnlock(inputUseBuffer->bufferMutex);
+ }
+
+ Exynos_OSAL_MutexLock(inputUseBuffer->bufferMutex);
+ Exynos_OSAL_MutexLock(outputUseBuffer->bufferMutex);
+ if ((outputUseBuffer->dataValid == OMX_TRUE) && ((inputData->dataLen > 0) || (inputData->nFlags & OMX_BUFFERFLAG_EOS)))
+ ret = pAudioDec->exynos_codec_bufferProcess(pOMXComponent, inputData, outputData);
+ else {
+ ret = OMX_ErrorNone;
+ Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex);
+ Exynos_OSAL_MutexUnlock(inputUseBuffer->bufferMutex);
+ break;
+ }
+ Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex);
+ Exynos_OSAL_MutexUnlock(inputUseBuffer->bufferMutex);
+
+ if (ret == (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet)
+ pExynosComponent->reInputData = OMX_TRUE;
+ else
+ pExynosComponent->reInputData = OMX_FALSE;
+
+ Exynos_OSAL_MutexLock(outputUseBuffer->bufferMutex);
+ Exynos_Postprocess_OutputData(pOMXComponent);
+ Exynos_OSAL_MutexUnlock(outputUseBuffer->bufferMutex);
+ }
+ }
+
+EXIT:
+
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_GetFlushBuffer(EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_DATABUFFER **pDataBuffer)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ FunctionIn();
+
+ if (pExynosPort->portWayType == WAY2_PORT) {
+ *pDataBuffer = NULL;
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ *pDataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ EXYNOS_OMX_DATABUFFER *flushPortBuffer = NULL;
+ OMX_BUFFERHEADERTYPE *bufferHeader = NULL;
+ EXYNOS_OMX_MESSAGE *message = NULL;
+ OMX_U32 flushNum = 0;
+ OMX_S32 semValue = 0;
+
+ FunctionIn();
+
+ pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+ while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
+ message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (message != NULL) {
+ bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData;
+ bufferHeader->nFilledLen = 0;
+
+ if (portIndex == OUTPUT_PORT_INDEX) {
+ Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader);
+ } else {
+ Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader);
+ }
+
+ Exynos_OSAL_Free(message);
+ message = NULL;
+ }
+ }
+
+ Exynos_OMX_GetFlushBuffer(pExynosPort, &flushPortBuffer);
+ if (flushPortBuffer != NULL) {
+ if (flushPortBuffer->dataValid == OMX_TRUE) {
+ if (portIndex == INPUT_PORT_INDEX)
+ Exynos_InputBufferReturn(pOMXComponent);
+ else if (portIndex == OUTPUT_PORT_INDEX)
+ Exynos_OutputBufferReturn(pOMXComponent);
+ }
+ }
+
+ while(1) {
+ OMX_S32 cnt = 0;
+ Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &cnt);
+ if (cnt <= 0)
+ break;
+ if (Exynos_OSAL_SemaphoreTryWait(pExynosComponent->pExynosPort[portIndex].bufferSemID) == OMX_ErrorUndefined)
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Cannot be happened");
+ }
+ Exynos_OSAL_SetElemNum(&pExynosPort->bufferQ, 0);
+
+ pExynosPort->processData.dataLen = 0;
+ pExynosPort->processData.nFlags = 0;
+ pExynosPort->processData.remainDataLen = 0;
+ pExynosPort->processData.timeStamp = 0;
+ pExynosPort->processData.usedDataLen = 0;
+
+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_AUDIODEC_COMPONENT *pAudioDec = NULL;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ EXYNOS_OMX_DATABUFFER *flushPortBuffer = NULL;
+ 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;
+ pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+ Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
+
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+ Exynos_OMX_GetFlushBuffer(pExynosPort, &flushPortBuffer);
+
+ Exynos_OSAL_MutexLock(flushPortBuffer->bufferMutex);
+ ret = Exynos_OMX_FlushPort(pOMXComponent, nPortIndex);
+ Exynos_OSAL_MutexUnlock(flushPortBuffer->bufferMutex);
+
+ pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_FALSE;
+
+ if (bEvent == OMX_TRUE && ret == OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bEVENT!!!!!!OMX_FLUSH_SEIREN");
+ pAudioDec->exynos_codec_flushSeiren(pOMXComponent, nPortIndex);
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventCmdComplete,
+ OMX_CommandFlush, nPortIndex, NULL);
+ }
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE;
+ pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
+ 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->reInputData = OMX_FALSE;
+ }
+
+EXIT:
+ if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__);
+ pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError,
+ ret, 0, NULL);
+ }
+
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetParameter(
+ 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_BASEPORT *pExynosPort = 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 (ComponentParameterStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ switch (nParamIndex) {
+ case OMX_IndexParamAudioInit:
+ {
+ 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) {
+ goto EXIT;
+ }
+
+ portParam->nPorts = pExynosComponent->portParam.nPorts;
+ portParam->nStartPortNumber = pExynosComponent->portParam.nStartPortNumber;
+ ret = OMX_ErrorNone;
+ }
+ break;
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+ OMX_U32 portIndex = portFormat->nPortIndex;
+ OMX_U32 index = portFormat->nIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL;
+ OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */
+
+ ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if ((portIndex >= pExynosComponent->portParam.nPorts)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+
+ if (portIndex == INPUT_PORT_INDEX) {
+ supportFormatNum = INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1;
+ if (index > supportFormatNum) {
+ ret = OMX_ErrorNoMore;
+ goto EXIT;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ portDefinition = &pExynosPort->portDefinition;
+
+ portFormat->eEncoding = portDefinition->format.audio.eEncoding;
+ } else if (portIndex == OUTPUT_PORT_INDEX) {
+ supportFormatNum = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1;
+ if (index > supportFormatNum) {
+ ret = OMX_ErrorNoMore;
+ goto EXIT;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ portDefinition = &pExynosPort->portDefinition;
+
+ portFormat->eEncoding = portDefinition->format.audio.eEncoding;
+ }
+ ret = OMX_ErrorNone;
+ }
+ break;
+ default:
+ {
+ ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
+ }
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeSetParameter(
+ 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_BASEPORT *pExynosPort = 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 (ComponentParameterStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+ OMX_U32 portIndex = portFormat->nPortIndex;
+ OMX_U32 index = portFormat->nIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL;
+ OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */
+
+ ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if ((portIndex >= pExynosComponent->portParam.nPorts)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+ portDefinition = &pExynosPort->portDefinition;
+
+ portDefinition->format.audio.eEncoding = portFormat->eEncoding;
+ ret = OMX_ErrorNone;
+ }
+ break;
+ default:
+ {
+ ret = Exynos_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure);
+ }
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetConfig(
+ OMX_HANDLETYPE hComponent,
+ OMX_INDEXTYPE nIndex,
+ OMX_PTR pComponentConfigStructure)
+{
+ 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 (pComponentConfigStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ default:
+ ret = Exynos_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeSetConfig(
+ OMX_HANDLETYPE hComponent,
+ OMX_INDEXTYPE nIndex,
+ OMX_PTR pComponentConfigStructure)
+{
+ 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 (pComponentConfigStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ case OMX_IndexConfigAudioMute:
+ {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_IndexConfigAudioMute");
+ ret = OMX_ErrorUnsupportedIndex;
+ }
+ break;
+ case OMX_IndexConfigAudioVolume:
+ {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_IndexConfigAudioVolume");
+ ret = OMX_ErrorUnsupportedIndex;
+ }
+ break;
+ default:
+ ret = Exynos_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetExtensionIndex(
+ 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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+static OMX_ERRORTYPE Exynos_OMX_BufferProcessThread(OMX_PTR threadData)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ OMX_COMPONENTTYPE *pOMXComponent = NULL;
+ EXYNOS_OMX_BASECOMPONENT *pSECComponent = NULL;
+ EXYNOS_OMX_MESSAGE *message = 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;
+ }
+ pSECComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ Exynos_OMX_BufferProcess(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_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+ FunctionIn();
+
+ pAudioDec->bExitBufferProcessThread = OMX_FALSE;
+
+ ret = Exynos_OSAL_ThreadCreate(&pAudioDec->hBufferProcessThread,
+ Exynos_OMX_BufferProcessThread,
+ 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_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ OMX_S32 countValue = 0;
+ unsigned int i = 0;
+
+ FunctionIn();
+
+ pAudioDec->bExitBufferProcessThread = OMX_TRUE;
+
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[i].bufferSemID, &countValue);
+ if (countValue == 0)
+ Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID);
+ }
+
+ Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
+ Exynos_OSAL_ThreadTerminate(pAudioDec->hBufferProcessThread);
+ pAudioDec->hBufferProcessThread = NULL;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeComponentInit(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_AUDIODEC_COMPONENT *pAudioDec = 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) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_Port_Constructor(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ pAudioDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_AUDIODEC_COMPONENT));
+ if (pAudioDec == NULL) {
+ Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Memset(pAudioDec, 0, sizeof(EXYNOS_OMX_AUDIODEC_COMPONENT));
+ pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pAudioDec;
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pExynosComponent->bMultiThreadProcess = OMX_FALSE;
+
+ /* Input port */
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosPort->portDefinition.nBufferCountActual = MAX_AUDIO_INPUTBUFFER_NUM;
+ pExynosPort->portDefinition.nBufferCountMin = MAX_AUDIO_INPUTBUFFER_NUM;
+ pExynosPort->portDefinition.nBufferSize = DEFAULT_AUDIO_INPUT_BUFFER_SIZE;
+ pExynosPort->portDefinition.eDomain = OMX_PortDomainAudio;
+
+ pExynosPort->portDefinition.format.audio.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingUnused;
+
+ /* Output port */
+ pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ pExynosPort->portDefinition.nBufferCountActual = MAX_AUDIO_OUTPUTBUFFER_NUM;
+ pExynosPort->portDefinition.nBufferCountMin = MAX_AUDIO_OUTPUTBUFFER_NUM;
+ pExynosPort->portDefinition.nBufferSize = DEFAULT_AUDIO_OUTPUT_BUFFER_SIZE;
+ pExynosPort->portDefinition.eDomain = OMX_PortDomainAudio;
+
+ pExynosPort->portDefinition.format.audio.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingUnused;
+
+
+ pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer;
+ pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer;
+ pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer;
+ pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
+
+#ifdef TUNNELING_SUPPORT
+ 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_AudioDecodeComponentDeinit(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_AUDIODEC_COMPONENT *pAudioDec = 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;
+
+ pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ Exynos_OSAL_Free(pAudioDec);
+ pExynosComponent->hComponentHandle = pAudioDec = NULL;
+
+ for(i = 0; i < ALL_PORT_NUM; i++) {
+ pExynosPort = &pExynosComponent->pExynosPort[i];
+ Exynos_OSAL_Free(pExynosPort->portDefinition.format.audio.cMIMEType);
+ pExynosPort->portDefinition.format.audio.cMIMEType = NULL;
+ }
+
+ ret = Exynos_OMX_Port_Destructor(pOMXComponent);
+
+ ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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_Adec.h
+ * @brief
+ * @author Yunji Kim (yunji.kim@samsung.com)
+ *
+ * @version 1.1.0
+ * @history
+ * 2012.02.28 : Create
+ */
+
+#ifndef EXYNOS_OMX_AUDIO_DECODE
+#define EXYNOS_OMX_AUDIO_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 "seiren_hw.h"
+
+#define MAX_AUDIO_INPUTBUFFER_NUM 2
+#define MAX_AUDIO_OUTPUTBUFFER_NUM 2
+
+#define DEFAULT_AUDIO_INPUT_BUFFER_SIZE (16 * 1024)
+#define DEFAULT_AUDIO_OUTPUT_BUFFER_SIZE (32 * 1024)
+
+#define DEFAULT_AUDIO_SAMPLING_FREQ 44100
+#define DEFAULT_AUDIO_CHANNELS_NUM 2
+#define DEFAULT_AUDIO_BIT_PER_SAMPLE 16
+
+#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 1
+#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 1
+
+#define AUDIO_DATA_PLANE 0
+
+typedef struct _SRP_DEC_INPUT_BUFFER
+{
+ void *PhyAddr; // physical address
+ void *VirAddr; // virtual address
+ int bufferSize; // input buffer alloc size
+ int dataSize; // Data length
+} SRP_DEC_INPUT_BUFFER;
+
+typedef struct _EXYNOS_OMX_AUDIODEC_COMPONENT
+{
+ OMX_HANDLETYPE hCodecHandle;
+
+ OMX_BOOL bFirstFrame;
+ OMX_PTR pInputBuffer;
+ SRP_DEC_INPUT_BUFFER SRPDecInputBuffer[MAX_AUDIO_INPUTBUFFER_NUM];
+ OMX_U32 indexInputBuffer;
+
+ /* Buffer Process */
+ OMX_BOOL bExitBufferProcessThread;
+ OMX_HANDLETYPE hBufferProcessThread;
+
+ OMX_ERRORTYPE (*exynos_codec_bufferProcess) (OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData);
+ OMX_ERRORTYPE (*exynos_codec_flushSeiren) (OMX_COMPONENTTYPE *pOMXComponent, SEIREN_PORTTYPE type);
+
+ int (*exynos_checkInputFrame)(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame);
+} EXYNOS_OMX_AUDIODEC_COMPONENT;
+
+
+#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);
+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);
+OMX_ERRORTYPE Exynos_OMX_BufferProcess(OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetParameter(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nParamIndex,
+ OMX_INOUT OMX_PTR ComponentParameterStructure);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeSetParameter(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_IN OMX_PTR ComponentParameterStructure);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetConfig(
+ OMX_HANDLETYPE hComponent,
+ OMX_INDEXTYPE nIndex,
+ OMX_PTR pComponentConfigStructure);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeSetConfig(
+ OMX_HANDLETYPE hComponent,
+ OMX_INDEXTYPE nIndex,
+ OMX_PTR pComponentConfigStructure);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeGetExtensionIndex(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_STRING cParameterName,
+ OMX_OUT OMX_INDEXTYPE *pIndexType);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_AudioDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EXYNOS_OMX_AUDIO_DECODE */
--- /dev/null
+
+ 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
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Aacdec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.AAC.Decoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Adec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libseirenhw
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/audio/seiren_dec \
+ $(EXYNOS_AUDIO_CODEC)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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_Aacdec.c
+ * @brief
+ * @author Sungyeon Kim (sy85.kim@samsung.com)
+ * @version 1.0.0
+ * @history
+ * 2012.12.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_Adec.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Aacdec.h"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG "EXYNOS_AAC_DEC"
+#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+//#define Seiren_DUMP_TO_FILE
+#ifdef Seiren_DUMP_TO_FILE
+#include "stdio.h"
+
+FILE *inFile;
+FILE *outFile;
+#endif
+
+OMX_ERRORTYPE Exynos_Seiren_AacDec_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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nParamIndex) {
+ case OMX_IndexParamAudioAac:
+ {
+ OMX_AUDIO_PARAM_AACPROFILETYPE *pDstAacParam = (OMX_AUDIO_PARAM_AACPROFILETYPE *)pComponentParameterStructure;
+ OMX_AUDIO_PARAM_AACPROFILETYPE *pSrcAacParam = NULL;
+ EXYNOS_AAC_HANDLE *pAacDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstAacParam, sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstAacParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pAacDec = (EXYNOS_AAC_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pSrcAacParam = &pAacDec->aacParam;
+
+ Exynos_OSAL_Memcpy(pDstAacParam, pSrcAacParam, sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE));
+ }
+ break;
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
+ OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = NULL;
+ EXYNOS_AAC_HANDLE *pAacDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstPcmParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pAacDec = (EXYNOS_AAC_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pSrcPcmParam = &pAacDec->pcmParam;
+
+ Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ }
+ 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) {
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_AAC_DEC_ROLE);
+ }
+ break;
+ default:
+ ret = Exynos_OMX_AudioDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+ break;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_AacDec_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 || 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ case OMX_IndexParamAudioAac:
+ {
+ OMX_AUDIO_PARAM_AACPROFILETYPE *pDstAacParam = NULL;
+ OMX_AUDIO_PARAM_AACPROFILETYPE *pSrcAacParam = (OMX_AUDIO_PARAM_AACPROFILETYPE *)pComponentParameterStructure;
+ EXYNOS_AAC_HANDLE *pAacDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcAacParam, sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcAacParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pAacDec = (EXYNOS_AAC_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pDstAacParam = &pAacDec->aacParam;
+
+ Exynos_OSAL_Memcpy(pDstAacParam, pSrcAacParam, sizeof(OMX_AUDIO_PARAM_AACPROFILETYPE));
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nSize : %d \e[0m", pDstAacParam->nSize);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nPortIndex : %d \e[0m", pDstAacParam->nPortIndex);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nChannels : %d \e[0m", pDstAacParam->nChannels);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nSampleRate : %d \e[0m", pDstAacParam->nSampleRate);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nBitRate : %d \e[0m", pDstAacParam->nBitRate);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nAudioBandWidth : %d \e[0m", pDstAacParam->nAudioBandWidth);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nFrameLength : %d \e[0m", pDstAacParam->nFrameLength);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nAACtools : %d \e[0m", pDstAacParam->nAACtools);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nAACERtools : %d \e[0m", pDstAacParam->nAACERtools);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m eAACProfile : %d \e[0m", pDstAacParam->eAACProfile);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m eAACStreamFormat : %d \e[0m", pDstAacParam->eAACStreamFormat);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m eChannelMode : %d \e[0m", pDstAacParam->eChannelMode);
+ }
+ break;
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = NULL;
+ OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
+ EXYNOS_AAC_HANDLE *pAacDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcPcmParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pAacDec = (EXYNOS_AAC_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pDstPcmParam = &pAacDec->pcmParam;
+
+ Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ }
+ 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) {
+ 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_AAC_DEC_ROLE)) {
+ pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
+ } else {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ }
+ break;
+ default:
+ ret = Exynos_OMX_AudioDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+ break;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_AacDec_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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ default:
+ ret = Exynos_OMX_AudioDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_AacDec_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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ default:
+ ret = Exynos_OMX_AudioDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_AacDec_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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_AudioDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_AacDec_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;
+ }
+
+ Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_AAC_DEC_ROLE);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_AacDec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_AAC_HANDLE *pAacDec = (EXYNOS_AAC_HANDLE *)pAudioDec->hCodecHandle;
+
+ FunctionIn();
+
+ INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+ Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+ pExynosComponent->bUseFlagEOF = OMX_TRUE; /* Aac extractor should parse into frame unit. */
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pAacDec->hSeirenAacHandle.bConfiguredSeiren = OMX_FALSE;
+ pAacDec->hSeirenAacHandle.bSeirenSendEOS = OMX_FALSE;
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+#ifdef Seiren_DUMP_TO_FILE
+ inFile = fopen("/data/InFile.aac", "w+");
+ outFile = fopen("/data/OutFile.pcm", "w+");
+#endif
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_AacDec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ FunctionIn();
+
+#ifdef Seiren_DUMP_TO_FILE
+ fclose(inFile);
+ fclose(outFile);
+#endif
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Aac_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_AAC_HANDLE *pAacDec = (EXYNOS_AAC_HANDLE *)pAudioDec->hCodecHandle;
+ int returnCodec = 0;
+ unsigned long isSeirenStopped = 0;
+ OMX_BOOL isSeirenIbufOverflow = OMX_FALSE;
+
+ u32 fd = pAacDec->hSeirenAacHandle.hSeirenHandle;
+ audio_mem_info_t input_mem_pool = pAacDec->hSeirenAacHandle.input_mem_pool;
+ audio_mem_info_t output_mem_pool = pAacDec->hSeirenAacHandle.output_mem_pool;
+ unsigned long sample_rate, channels;
+ int consumed_size = 0;
+ sample_rate = channels = 0;
+
+ FunctionIn();
+
+#ifdef Seiren_DUMP_TO_FILE
+ if (pExynosComponent->reInputData == OMX_FALSE) {
+ fwrite(pInputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], pInputData->dataLen, 1, inFile);
+ }
+#endif
+
+ /* Save timestamp and flags of input data */
+ pOutputData->timeStamp = pInputData->timeStamp;
+ pOutputData->nFlags = pInputData->nFlags & (~OMX_BUFFERFLAG_EOS);
+
+ /* Decoding aac frames by Seiren */
+ if (pExynosComponent->getAllDelayBuffer == OMX_FALSE) {
+ input_mem_pool.data_size = pInputData->dataLen;
+ char* pt = input_mem_pool.virt_addr;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33m %02X %02X %02X %02X %02X %02X %lld \e[0m", *pt,*(pt+1),*(pt+2),*(pt+3),*(pt+4), *(pt+5), pInputData->timeStamp);
+
+ if (pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ if (pAacDec->hSeirenAacHandle.bConfiguredSeiren == OMX_TRUE)
+ goto EXIT;
+
+ ADec_ConfigSignal(fd);
+ unsigned char sample_rate_index = ((*(pt+1)) >> 7 & 0x01) |
+ ((*pt) << 1 & 0x0e);
+ unsigned char num_of_channel = ((*(pt+1)) >> 3 & 0x07);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "index %x ", sample_rate_index);
+ ADec_SetParams(fd, PCM_PARAM_SAMPLE_RATE, aac_sample_rates[sample_rate_index]);
+ ADec_SetParams(fd, PCM_PARAM_NUM_OF_CH, num_of_channel);
+
+ /* AAC setup-data(or DSI) could be various length. But it only needs 2byte */
+ input_mem_pool.data_size = 2;
+ ADec_SendStream(fd, &input_mem_pool, &consumed_size);
+ goto EXIT;
+ }
+ returnCodec = ADec_SendStream(fd, &input_mem_pool, &consumed_size);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ProcessedSize : %d return : %d", consumed_size, returnCodec);
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EOS!!");
+ if (returnCodec >= 0) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
+ ADec_SendEOS(fd);
+ pAacDec->hSeirenAacHandle.bSeirenSendEOS = OMX_TRUE;
+ }
+ } else if (returnCodec < 0) {
+ ret = OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ if (pAacDec->hSeirenAacHandle.bConfiguredSeiren == OMX_FALSE) {
+ if ((pInputData->dataLen <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pAacDec->hSeirenAacHandle.bSeirenSendEOS = OMX_FALSE;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ returnCodec = ADec_GetParams(fd, PCM_PARAM_SAMPLE_RATE, &sample_rate);
+ returnCodec = returnCodec | ADec_GetParams(fd, PCM_PARAM_NUM_OF_CH, &channels);
+
+ if (returnCodec < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_ADec_GetParams failed: %d", returnCodec);
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+
+ if (!sample_rate || !channels) {
+ if (pAacDec->hSeirenAacHandle.bSeirenSendEOS == OMX_TRUE) {
+ pOutputData->dataLen = 0;
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ }
+ ret = OMX_ErrorNone;
+ goto EXIT;//
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "numChannels(%d), samplingRate(%d)",
+ channels, sample_rate);
+
+ if (pAacDec->pcmParam.nChannels != channels ||
+ pAacDec->pcmParam.nSamplingRate != sample_rate) {
+ /* Change channel count and sampling rate information */
+ pAacDec->pcmParam.nChannels = channels;
+ pAacDec->pcmParam.nSamplingRate = sample_rate;
+
+ /* 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);
+ }
+
+ pAacDec->hSeirenAacHandle.bConfiguredSeiren = OMX_TRUE;
+
+ if (pAacDec->hSeirenAacHandle.bSeirenSendEOS == OMX_TRUE) {
+ pOutputData->dataLen = 0;
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ ret = OMX_ErrorInputDataDecodeYet;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ ret = OMX_ErrorNone;
+ }
+ goto EXIT;
+ }
+
+ /* Get decoded data from Seiren */
+ ADec_RecvPCM(fd, &output_mem_pool);
+ if (output_mem_pool.data_size > 0) {
+ pOutputData->dataLen = output_mem_pool.data_size;
+ Exynos_OSAL_Memcpy(pOutputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE],
+ output_mem_pool.virt_addr, output_mem_pool.data_size);
+ } else {
+ pOutputData->dataLen = 0;
+ }
+
+#ifdef Seiren_DUMP_TO_FILE
+ if (pOutputData->dataLen > 0)
+ fwrite(pOutputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], pOutputData->dataLen, 1, outFile);
+#endif
+
+ /* Delay EOS signal until all the PCM is returned from the Seiren driver. */
+ if (pAacDec->hSeirenAacHandle.bSeirenSendEOS == OMX_TRUE) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
+ returnCodec = ADec_GetParams(fd, ADEC_PARAM_GET_OUTPUT_STATUS, &isSeirenStopped);
+ if (returnCodec != 0)
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail Seiren_STOP_EOS_STATE");
+ if (isSeirenStopped == 1) {
+ pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ pAacDec->hSeirenAacHandle.bSeirenSendEOS = OMX_FALSE; /* for repeating one song */
+ ret = OMX_ErrorNone;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ ret = OMX_ErrorInputDataDecodeYet;
+ }
+ } else { /* Flush after EOS */
+ pAacDec->hSeirenAacHandle.bSeirenSendEOS = OMX_FALSE;
+ }
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_AacDec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
+{
+ 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();
+
+ if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) ||
+ (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+
+ goto EXIT;
+ }
+ if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent)) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+
+ goto EXIT;
+ }
+
+ ret = Exynos_Seiren_Aac_Decode_Block(pOMXComponent, pInputData, pOutputData);
+
+ if (ret != OMX_ErrorNone) {
+ if (ret == (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet) {
+ pOutputData->usedDataLen = 0;
+ pOutputData->remainDataLen = pOutputData->dataLen;
+ } else {
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, ret, 0, NULL);
+ }
+ } else {
+ pInputData->usedDataLen += pInputData->dataLen;
+ pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen;
+ pInputData->dataLen -= pInputData->usedDataLen;
+ pInputData->usedDataLen = 0;
+
+ pOutputData->usedDataLen = 0;
+ pOutputData->remainDataLen = pOutputData->dataLen;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_AacDec_flushSeiren(OMX_COMPONENTTYPE *pOMXComponent, SEIREN_PORTTYPE type)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_AAC_HANDLE *pAacDec = (EXYNOS_AAC_HANDLE *)pAudioDec->hCodecHandle;
+
+ int fd = pAacDec->hSeirenAacHandle.hSeirenHandle;
+ return ADec_Flush(fd, type);
+}
+
+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_AUDIODEC_COMPONENT *pAudioDec = NULL;
+ EXYNOS_AAC_HANDLE *pAacDec = NULL;
+ audio_mem_info_t input_mem_pool;
+ audio_mem_info_t output_mem_pool;
+ OMX_S32 fd;
+
+ int i = 0;
+
+ FunctionIn();
+
+ if ((hComponent == NULL) || (componentName == NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_AAC_DEC, componentName) != 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_AudioDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_AudioDecodeComponentInit error, ret: %X", __FUNCTION__, ret);
+ goto EXIT;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ pExynosComponent->codecType = HW_AUDIO_DEC_CODEC;
+
+ pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+ if (pExynosComponent->componentName == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_1;
+ }
+ Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+ Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_AAC_DEC);
+
+ pAacDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_AAC_HANDLE));
+ if (pAacDec == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: EXYNOS_AAC_HANDLE alloc error, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_2;
+ }
+ Exynos_OSAL_Memset(pAacDec, 0, sizeof(EXYNOS_AAC_HANDLE));
+ pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pAudioDec->hCodecHandle = (OMX_HANDLETYPE)pAacDec;
+
+ /* Create and Init Seiren */
+ pAacDec->hSeirenAacHandle.bSeirenLoaded = OMX_FALSE;
+ fd = ADec_Create(0, ADEC_AAC, NULL);
+
+ if (fd < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_ADec_Create failed: %d", fd);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_3;
+ }
+ pAacDec->hSeirenAacHandle.hSeirenHandle = fd; /* Seiren's fd */
+ pAacDec->hSeirenAacHandle.bSeirenLoaded = OMX_TRUE;
+
+ /* Get input buffer info from Seiren */
+ Exynos_OSAL_Memset(&pAacDec->hSeirenAacHandle.input_mem_pool, 0, sizeof(audio_mem_info_t));
+ ADec_GetIMemPoolInfo(fd, &pAacDec->hSeirenAacHandle.input_mem_pool);
+ input_mem_pool = pAacDec->hSeirenAacHandle.input_mem_pool;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "eiren_Adec_GetIMemPoolInfo : %d", input_mem_pool.mem_size);
+
+ if (input_mem_pool.virt_addr == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_Adec_GetIMemPoolInfo failed: %d", fd);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_5;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosPort->processData.allocSize = input_mem_pool.mem_size;
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = input_mem_pool.virt_addr;
+
+ /* Get output buffer info from Seiren */
+ Exynos_OSAL_Memset(&pAacDec->hSeirenAacHandle.output_mem_pool, 0, sizeof(audio_mem_info_t));
+ ADec_GetOMemPoolInfo(fd, &pAacDec->hSeirenAacHandle.output_mem_pool);
+ output_mem_pool = pAacDec->hSeirenAacHandle.output_mem_pool;
+ if (output_mem_pool.virt_addr == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_ADec_GetOMemPoolInfo failed: %d", fd);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_6;
+ }
+
+ /* 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.nBufferCountActual = input_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferCountMin = input_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferSize = input_mem_pool.mem_size;
+ pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+ Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/aac");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
+ pExynosPort->portWayType = WAY1_PORT;
+
+ /* Output port */
+ pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ pExynosPort->portDefinition.nBufferCountActual = output_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferCountMin = output_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferSize = output_mem_pool.mem_size;
+ pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+ Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+ pExynosPort->portWayType = WAY1_PORT;
+
+ /* Default values for Aac audio param */
+ INIT_SET_SIZE_VERSION(&pAacDec->aacParam, OMX_AUDIO_PARAM_AACPROFILETYPE);
+ pAacDec->aacParam.nPortIndex = INPUT_PORT_INDEX;
+ pAacDec->aacParam.nChannels = DEFAULT_AUDIO_CHANNELS_NUM;
+ pAacDec->aacParam.nBitRate = 0;
+ pAacDec->aacParam.nSampleRate = DEFAULT_AUDIO_SAMPLING_FREQ;
+ pAacDec->aacParam.nAudioBandWidth = 0;
+ pAacDec->aacParam.eChannelMode = OMX_AUDIO_ChannelModeStereo;
+ pAacDec->aacParam.eAACProfile = OMX_AUDIO_AACObjectNull;
+ pAacDec->aacParam.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP2ADTS;
+
+ /* Default values for PCM audio param */
+ INIT_SET_SIZE_VERSION(&pAacDec->pcmParam, OMX_AUDIO_PARAM_PCMMODETYPE);
+ pAacDec->pcmParam.nPortIndex = OUTPUT_PORT_INDEX;
+ pAacDec->pcmParam.nChannels = DEFAULT_AUDIO_CHANNELS_NUM;
+ pAacDec->pcmParam.eNumData = OMX_NumericalDataSigned;
+ pAacDec->pcmParam.eEndian = OMX_EndianLittle;
+ pAacDec->pcmParam.bInterleaved = OMX_TRUE;
+ pAacDec->pcmParam.nBitPerSample = DEFAULT_AUDIO_BIT_PER_SAMPLE;
+ pAacDec->pcmParam.nSamplingRate = DEFAULT_AUDIO_SAMPLING_FREQ;
+ pAacDec->pcmParam.ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pAacDec->pcmParam.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pAacDec->pcmParam.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ pOMXComponent->GetParameter = &Exynos_Seiren_AacDec_GetParameter;
+ pOMXComponent->SetParameter = &Exynos_Seiren_AacDec_SetParameter;
+ pOMXComponent->GetConfig = &Exynos_Seiren_AacDec_GetConfig;
+ pOMXComponent->SetConfig = &Exynos_Seiren_AacDec_SetConfig;
+ pOMXComponent->GetExtensionIndex = &Exynos_Seiren_AacDec_GetExtensionIndex;
+ pOMXComponent->ComponentRoleEnum = &Exynos_Seiren_AacDec_ComponentRoleEnum;
+ pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
+
+ /* ToDo: Change the function name associated with a specific codec */
+ pExynosComponent->exynos_codec_componentInit = &Exynos_Seiren_AacDec_Init;
+ pExynosComponent->exynos_codec_componentTerminate = &Exynos_Seiren_AacDec_Terminate;
+ pAudioDec->exynos_codec_bufferProcess = &Exynos_Seiren_AacDec_bufferProcess;
+ pAudioDec->exynos_codec_flushSeiren = &Exynos_Seiren_AacDec_flushSeiren;
+ pAudioDec->exynos_checkInputFrame = NULL;
+
+ pExynosComponent->currentState = OMX_StateLoaded;
+
+ ret = OMX_ErrorNone;
+ goto EXIT; /* This function is performed successfully. */
+
+EXIT_ERROR_6:
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = NULL;
+ pExynosPort->processData.allocSize = 0;
+EXIT_ERROR_5:
+EXIT_ERROR_4:
+ ADec_Destroy(pAacDec->hSeirenAacHandle.hSeirenHandle);
+EXIT_ERROR_3:
+ Exynos_OSAL_Free(pAacDec);
+ pAudioDec->hCodecHandle = NULL;
+EXIT_ERROR_2:
+ Exynos_OSAL_Free(pExynosComponent->componentName);
+ pExynosComponent->componentName = NULL;
+EXIT_ERROR_1:
+ Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
+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_AAC_HANDLE *pAacDec = NULL;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+ FunctionIn();
+
+ if (hComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ Exynos_OSAL_Free(pExynosComponent->componentName);
+ pExynosComponent->componentName = NULL;
+
+ pAacDec = (EXYNOS_AAC_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ if (pAacDec != NULL) {
+ if (pAacDec->hSeirenAacHandle.bSeirenLoaded == OMX_TRUE) {
+ ADec_Destroy(pAacDec->hSeirenAacHandle.hSeirenHandle);
+ }
+ Exynos_OSAL_Free(pAacDec);
+ ((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ }
+
+ ret = Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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_Aacdec.h
+ * @brief
+ * @author Sungyeon Kim (sy85.kim@samsung.com)
+ * @version 1.0.0
+ * @history
+ * 2012.12.22 : Create
+ */
+
+#ifndef EXYNOS_OMX_AAC_DEC_COMPONENT
+#define EXYNOS_OMX_AAC_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "seiren_hw.h"
+
+static const uint32_t aac_sample_rates[] =
+{
+ 96000, 88200, 64000, 48000, 44100, 32000,
+ 24000, 22050, 16000, 12000, 11025, 8000
+};
+
+typedef struct _EXYNOS_Seiren_AAC_HANDLE
+{
+ OMX_U32 hSeirenHandle;
+ OMX_BOOL bConfiguredSeiren;
+ OMX_BOOL bSeirenLoaded;
+ OMX_BOOL bSeirenSendEOS;
+ OMX_S32 returnCodec;
+ audio_mem_info_t input_mem_pool;
+ audio_mem_info_t output_mem_pool;
+} EXYNOS_Seiren_AAC_HANDLE;
+
+typedef struct _EXYNOS_AAC_HANDLE
+{
+ /* OMX Codec specific */
+ OMX_AUDIO_PARAM_AACPROFILETYPE aacParam;
+ OMX_AUDIO_PARAM_PCMMODETYPE pcmParam;
+
+ /* SEC Seiren Codec specific */
+ EXYNOS_Seiren_AAC_HANDLE hSeirenAacHandle;
+} EXYNOS_AAC_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 /* EXYNOS_OMX_AAC_DEC_COMPONENT */
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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 1.1.0
+ * @history
+ * 2012.02.28 : 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_AAC_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 - audio decoder AAC */
+ Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_AAC_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_AAC_DEC_ROLE);
+ ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+ FunctionOut();
+ return MAX_COMPONENT_NUM;
+}
+
--- /dev/null
+/*
+ *
+ * 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 1.1.0
+ * @history
+ * 2012.02.28 : Create
+ */
+
+#ifndef EXYNOS_OMX_AAC_DEC_REG
+#define EXYNOS_OMX_AAC_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
+
+/* AAC */
+#define EXYNOS_OMX_COMPONENT_AAC_DEC "OMX.Exynos.AAC.Decoder"
+#define EXYNOS_OMX_COMPONENT_AAC_DEC_ROLE "audio_decoder.aac"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* EXYNOS_OMX_AAC_DEC_REG */
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Flacdec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.FLAC.Decoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Adec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libseirenhw
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/audio/seiren_dec \
+ $(EXYNOS_AUDIO_CODEC)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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_Flacdec.c
+ * @brief
+ * @author Sungyeon Kim (sy85.kim@samsung.com)
+ * @version 1.0.0
+ * @history
+ * 2012.12.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_Adec.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Flacdec.h"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG "EXYNOS_FLAC_DEC"
+#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+//#define Seiren_DUMP_TO_FILE
+#ifdef Seiren_DUMP_TO_FILE
+#include "stdio.h"
+
+FILE *inFile;
+FILE *outFile;
+#endif
+
+OMX_ERRORTYPE Exynos_Seiren_FlacDec_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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nParamIndex) {
+ case OMX_IndexParamAudioFlac:
+ {
+ OMX_AUDIO_PARAM_FLACTYPE *pDstFlacParam = (OMX_AUDIO_PARAM_FLACTYPE *)pComponentParameterStructure;
+ OMX_AUDIO_PARAM_FLACTYPE *pSrcFlacParam = NULL;
+ EXYNOS_FLAC_HANDLE *pFlacDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstFlacParam, sizeof(OMX_AUDIO_PARAM_FLACTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstFlacParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pFlacDec = (EXYNOS_FLAC_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pSrcFlacParam = &pFlacDec->flacParam;
+
+ Exynos_OSAL_Memcpy(pDstFlacParam, pSrcFlacParam, sizeof(OMX_AUDIO_PARAM_FLACTYPE));
+ }
+ break;
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
+ OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = NULL;
+ EXYNOS_FLAC_HANDLE *pFlacDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstPcmParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pFlacDec = (EXYNOS_FLAC_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pSrcPcmParam = &pFlacDec->pcmParam;
+
+ Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ }
+ 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) {
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_FLAC_DEC_ROLE);
+ }
+ break;
+ default:
+ ret = Exynos_OMX_AudioDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+ break;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_FlacDec_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 || 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ case OMX_IndexParamAudioFlac:
+ {
+ OMX_AUDIO_PARAM_FLACTYPE *pDstFlacParam = NULL;
+ OMX_AUDIO_PARAM_FLACTYPE *pSrcFlacParam = (OMX_AUDIO_PARAM_FLACTYPE *)pComponentParameterStructure;
+ EXYNOS_FLAC_HANDLE *pFlacDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcFlacParam, sizeof(OMX_AUDIO_PARAM_FLACTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcFlacParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pFlacDec = (EXYNOS_FLAC_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pDstFlacParam = &pFlacDec->flacParam;
+
+ Exynos_OSAL_Memcpy(pDstFlacParam, pSrcFlacParam, sizeof(OMX_AUDIO_PARAM_FLACTYPE));
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nSize : %d \e[0m", pDstFlacParam->nSize);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nPortIndex : %d \e[0m", pDstFlacParam->nPortIndex);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nChannels : %d \e[0m", pDstFlacParam->nChannels);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nSampleRate : %d \e[0m", pDstFlacParam->nSampleRate);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33;46m nCompressionLevel : %d \e[0m", pDstFlacParam->nCompressionLevel);
+ }
+ break;
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = NULL;
+ OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
+ EXYNOS_FLAC_HANDLE *pFlacDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcPcmParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pFlacDec = (EXYNOS_FLAC_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pDstPcmParam = &pFlacDec->pcmParam;
+
+ Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ }
+ 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) {
+ 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_FLAC_DEC_ROLE)) {
+ pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingFLAC;
+ } else {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ }
+ break;
+ default:
+ ret = Exynos_OMX_AudioDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+ break;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_FlacDec_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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ default:
+ ret = Exynos_OMX_AudioDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_FlacDec_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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ default:
+ ret = Exynos_OMX_AudioDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_FlacDec_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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_AudioDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_FlacDec_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;
+ }
+
+ Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_FLAC_DEC_ROLE);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_FlacDec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_FLAC_HANDLE *pFlacDec = (EXYNOS_FLAC_HANDLE *)pAudioDec->hCodecHandle;
+
+ FunctionIn();
+
+ INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+ Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+ pExynosComponent->bUseFlagEOF = OMX_TRUE; /* Flac extractor should parse into frame unit. */
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pFlacDec->hSeirenFlacHandle.bConfiguredSeiren = OMX_FALSE;
+ pFlacDec->hSeirenFlacHandle.bSeirenSendEOS = OMX_FALSE;
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+#ifdef Seiren_DUMP_TO_FILE
+ inFile = fopen("/data/InFile.flac", "w+");
+ outFile = fopen("/data/OutFile.pcm", "w+");
+#endif
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_FlacDec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ FunctionIn();
+
+#ifdef Seiren_DUMP_TO_FILE
+ fclose(inFile);
+ fclose(outFile);
+#endif
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Flac_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_FLAC_HANDLE *pFlacDec = (EXYNOS_FLAC_HANDLE *)pAudioDec->hCodecHandle;
+ int returnCodec = 0;
+ unsigned long isSeirenStopped = 0;
+ OMX_BOOL isSeirenIbufOverflow = OMX_FALSE;
+ unsigned char* pt;
+
+ u32 fd = pFlacDec->hSeirenFlacHandle.hSeirenHandle;
+ audio_mem_info_t input_mem_pool = pFlacDec->hSeirenFlacHandle.input_mem_pool;
+ audio_mem_info_t output_mem_pool = pFlacDec->hSeirenFlacHandle.output_mem_pool;
+ unsigned long sample_rate, channels;
+ int consumed_size = 0;
+ sample_rate = channels = 0;
+
+ FunctionIn();
+
+#ifdef Seiren_DUMP_TO_FILE
+ if (pExynosComponent->reInputData == OMX_FALSE) {
+ fwrite(pInputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], pInputData->dataLen, 1, inFile);
+ }
+#endif
+
+ /* Save timestamp and flags of input data */
+ pOutputData->timeStamp = pInputData->timeStamp;
+ pOutputData->nFlags = pInputData->nFlags & (~OMX_BUFFERFLAG_EOS);
+
+ /* Decoding flac frames by Seiren */
+ if (pExynosComponent->getAllDelayBuffer == OMX_FALSE) {
+ input_mem_pool.data_size = pInputData->dataLen;
+ pt = (unsigned char*)input_mem_pool.virt_addr;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33m %02X %02X %02X %02X %02X %02X %lld \e[0m", *pt,*(pt+1),*(pt+2),*(pt+3),*(pt+4), *(pt+5), pInputData->timeStamp);
+
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
+ ADec_SendEOS(fd);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EOS!!");
+ }
+ if (pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
+ ADec_ConfigSignal(fd);
+
+ returnCodec = ADec_SendStream(fd, &input_mem_pool, &consumed_size);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ProcessedSize : %d return : %d", consumed_size, returnCodec);
+ if (returnCodec >= 0) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
+ pFlacDec->hSeirenFlacHandle.bSeirenSendEOS = OMX_TRUE;
+ }
+ } else if (returnCodec < 0) {
+ ret = OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ if (pFlacDec->hSeirenFlacHandle.bConfiguredSeiren == OMX_FALSE) {
+ if ((pInputData->dataLen <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pFlacDec->hSeirenFlacHandle.bSeirenSendEOS = OMX_FALSE;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ returnCodec = ADec_GetParams(fd, PCM_PARAM_SAMPLE_RATE, &sample_rate);
+ returnCodec = returnCodec | ADec_GetParams(fd, PCM_PARAM_NUM_OF_CH, &channels);
+
+ if (returnCodec < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_ADec_GetParams failed: %d", returnCodec);
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+
+ if (!sample_rate || !channels) {
+ if (pFlacDec->hSeirenFlacHandle.bSeirenSendEOS == OMX_TRUE) {
+ pOutputData->dataLen = 0;
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ }
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "numChannels(%d), samplingRate(%d)",
+ channels, sample_rate);
+
+ if (pFlacDec->pcmParam.nChannels != channels ||
+ pFlacDec->pcmParam.nSamplingRate != sample_rate) {
+ /* Change channel count and sampling rate information */
+ pFlacDec->pcmParam.nChannels = channels;
+ pFlacDec->pcmParam.nSamplingRate = sample_rate;
+
+ /* 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);
+ }
+
+ pFlacDec->hSeirenFlacHandle.bConfiguredSeiren = OMX_TRUE;
+
+ if (pFlacDec->hSeirenFlacHandle.bSeirenSendEOS == OMX_TRUE) {
+ pOutputData->dataLen = 0;
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ ret = OMX_ErrorInputDataDecodeYet;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ ret = OMX_ErrorNone;
+ }
+ goto EXIT;
+ }
+
+ /* Get decoded data from Seiren */
+ ADec_RecvPCM(fd, &output_mem_pool);
+ if (output_mem_pool.data_size > 0) {
+ pOutputData->dataLen = output_mem_pool.data_size;
+ Exynos_OSAL_Memcpy(pOutputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE],
+ output_mem_pool.virt_addr, output_mem_pool.data_size);
+ } else {
+ pOutputData->dataLen = 0;
+ }
+
+#ifdef Seiren_DUMP_TO_FILE
+ if (pOutputData->dataLen > 0)
+ fwrite(pOutputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], pOutputData->dataLen, 1, outFile);
+#endif
+
+ /* Delay EOS signal until all the PCM is returned from the Seiren driver. */
+ if (pFlacDec->hSeirenFlacHandle.bSeirenSendEOS == OMX_TRUE) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
+ returnCodec = ADec_GetParams(fd, ADEC_PARAM_GET_OUTPUT_STATUS, &isSeirenStopped);
+ if (returnCodec != 0)
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail Seiren_STOP_EOS_STATE");
+ if (isSeirenStopped == 1) {
+ pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ pFlacDec->hSeirenFlacHandle.bSeirenSendEOS = OMX_FALSE; /* for repeating one song */
+ ret = OMX_ErrorNone;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ ret = OMX_ErrorInputDataDecodeYet;
+ }
+ } else { /* Flush after EOS */
+ pFlacDec->hSeirenFlacHandle.bSeirenSendEOS = OMX_FALSE;
+ }
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_FlacDec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
+{
+ 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();
+
+ if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) ||
+ (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+
+ goto EXIT;
+ }
+ if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent)) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+
+ goto EXIT;
+ }
+
+ ret = Exynos_Seiren_Flac_Decode_Block(pOMXComponent, pInputData, pOutputData);
+
+ if (ret != OMX_ErrorNone) {
+ if (ret == (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet) {
+ pOutputData->usedDataLen = 0;
+ pOutputData->remainDataLen = pOutputData->dataLen;
+ } else {
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, ret, 0, NULL);
+ }
+ } else {
+ pInputData->usedDataLen += pInputData->dataLen;
+ pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen;
+ pInputData->dataLen -= pInputData->usedDataLen;
+ pInputData->usedDataLen = 0;
+
+ pOutputData->usedDataLen = 0;
+ pOutputData->remainDataLen = pOutputData->dataLen;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_FlacDec_flushSeiren(OMX_COMPONENTTYPE *pOMXComponent, SEIREN_PORTTYPE type)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_FLAC_HANDLE *pFlacDec = (EXYNOS_FLAC_HANDLE *)pAudioDec->hCodecHandle;
+
+ if (type == 1)
+ return 0;
+ int fd = pFlacDec->hSeirenFlacHandle.hSeirenHandle;
+ return ADec_Flush(fd, type);
+}
+
+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_AUDIODEC_COMPONENT *pAudioDec = NULL;
+ EXYNOS_FLAC_HANDLE *pFlacDec = NULL;
+ audio_mem_info_t input_mem_pool;
+ audio_mem_info_t output_mem_pool;
+ OMX_S32 fd;
+
+ int i = 0;
+
+ FunctionIn();
+
+ if ((hComponent == NULL) || (componentName == NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_FLAC_DEC, componentName) != 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_AudioDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_AudioDecodeComponentInit error, ret: %X", __FUNCTION__, ret);
+ goto EXIT;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ pExynosComponent->codecType = HW_AUDIO_DEC_CODEC;
+
+ pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+ if (pExynosComponent->componentName == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_1;
+ }
+ Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+ Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_FLAC_DEC);
+
+ pFlacDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_FLAC_HANDLE));
+ if (pFlacDec == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: EXYNOS_FLAC_HANDLE alloc error, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_2;
+ }
+ Exynos_OSAL_Memset(pFlacDec, 0, sizeof(EXYNOS_FLAC_HANDLE));
+ pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pAudioDec->hCodecHandle = (OMX_HANDLETYPE)pFlacDec;
+
+ /* Create and Init Seiren */
+ pFlacDec->hSeirenFlacHandle.bSeirenLoaded = OMX_FALSE;
+ fd = ADec_Create(0, ADEC_FLAC, NULL);
+
+ if (fd < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_ADec_Create failed: %d", fd);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_3;
+ }
+ pFlacDec->hSeirenFlacHandle.hSeirenHandle = fd; /* Seiren's fd */
+ pFlacDec->hSeirenFlacHandle.bSeirenLoaded = OMX_TRUE;
+
+ /* Get input buffer info from Seiren */
+ Exynos_OSAL_Memset(&pFlacDec->hSeirenFlacHandle.input_mem_pool, 0, sizeof(audio_mem_info_t));
+ ADec_GetIMemPoolInfo(fd, &pFlacDec->hSeirenFlacHandle.input_mem_pool);
+ input_mem_pool = pFlacDec->hSeirenFlacHandle.input_mem_pool;
+
+ if (input_mem_pool.virt_addr == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_Adec_GetIMemPoolInfo failed: %d", fd);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_5;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosPort->processData.allocSize = input_mem_pool.mem_size;
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = input_mem_pool.virt_addr;
+
+ /* Get output buffer info from Seiren */
+ Exynos_OSAL_Memset(&pFlacDec->hSeirenFlacHandle.output_mem_pool, 0, sizeof(audio_mem_info_t));
+ ADec_GetOMemPoolInfo(fd, &pFlacDec->hSeirenFlacHandle.output_mem_pool);
+ output_mem_pool = pFlacDec->hSeirenFlacHandle.output_mem_pool;
+ if (output_mem_pool.virt_addr == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_ADec_GetOMemPoolInfo failed: %d", fd);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_6;
+ }
+
+ /* 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.nBufferCountActual = input_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferCountMin = input_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferSize = input_mem_pool.mem_size;
+ pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+ Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/flac");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingFLAC;
+ pExynosPort->portWayType = WAY1_PORT;
+
+ /* Output port */
+ pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ pExynosPort->portDefinition.nBufferCountActual = output_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferCountMin = output_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferSize = output_mem_pool.mem_size;
+ pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+ Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+ pExynosPort->portWayType = WAY1_PORT;
+
+ /* Default values for Flac audio param */
+ INIT_SET_SIZE_VERSION(&pFlacDec->flacParam, OMX_AUDIO_PARAM_FLACTYPE);
+ pFlacDec->flacParam.nPortIndex = INPUT_PORT_INDEX;
+ pFlacDec->flacParam.nChannels = DEFAULT_AUDIO_CHANNELS_NUM;
+ pFlacDec->flacParam.nSampleRate = DEFAULT_AUDIO_SAMPLING_FREQ;
+
+ /* Default values for PCM audio param */
+ INIT_SET_SIZE_VERSION(&pFlacDec->pcmParam, OMX_AUDIO_PARAM_PCMMODETYPE);
+ pFlacDec->pcmParam.nPortIndex = OUTPUT_PORT_INDEX;
+ pFlacDec->pcmParam.nChannels = DEFAULT_AUDIO_CHANNELS_NUM;
+ pFlacDec->pcmParam.eNumData = OMX_NumericalDataSigned;
+ pFlacDec->pcmParam.eEndian = OMX_EndianLittle;
+ pFlacDec->pcmParam.bInterleaved = OMX_TRUE;
+ pFlacDec->pcmParam.nBitPerSample = DEFAULT_AUDIO_BIT_PER_SAMPLE;
+ pFlacDec->pcmParam.nSamplingRate = DEFAULT_AUDIO_SAMPLING_FREQ;
+ pFlacDec->pcmParam.ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pFlacDec->pcmParam.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pFlacDec->pcmParam.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ pOMXComponent->GetParameter = &Exynos_Seiren_FlacDec_GetParameter;
+ pOMXComponent->SetParameter = &Exynos_Seiren_FlacDec_SetParameter;
+ pOMXComponent->GetConfig = &Exynos_Seiren_FlacDec_GetConfig;
+ pOMXComponent->SetConfig = &Exynos_Seiren_FlacDec_SetConfig;
+ pOMXComponent->GetExtensionIndex = &Exynos_Seiren_FlacDec_GetExtensionIndex;
+ pOMXComponent->ComponentRoleEnum = &Exynos_Seiren_FlacDec_ComponentRoleEnum;
+ pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
+
+ /* ToDo: Change the function name associated with a specific codec */
+ pExynosComponent->exynos_codec_componentInit = &Exynos_Seiren_FlacDec_Init;
+ pExynosComponent->exynos_codec_componentTerminate = &Exynos_Seiren_FlacDec_Terminate;
+ pAudioDec->exynos_codec_bufferProcess = &Exynos_Seiren_FlacDec_bufferProcess;
+ pAudioDec->exynos_codec_flushSeiren = &Exynos_Seiren_FlacDec_flushSeiren;
+ pAudioDec->exynos_checkInputFrame = NULL;
+
+ pExynosComponent->currentState = OMX_StateLoaded;
+
+ ret = OMX_ErrorNone;
+ goto EXIT; /* This function is performed successfully. */
+
+EXIT_ERROR_6:
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = NULL;
+ pExynosPort->processData.allocSize = 0;
+EXIT_ERROR_5:
+EXIT_ERROR_4:
+ ADec_Destroy(pFlacDec->hSeirenFlacHandle.hSeirenHandle);
+EXIT_ERROR_3:
+ Exynos_OSAL_Free(pFlacDec);
+ pAudioDec->hCodecHandle = NULL;
+EXIT_ERROR_2:
+ Exynos_OSAL_Free(pExynosComponent->componentName);
+ pExynosComponent->componentName = NULL;
+EXIT_ERROR_1:
+ Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
+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_FLAC_HANDLE *pFlacDec = NULL;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+ FunctionIn();
+
+ if (hComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ Exynos_OSAL_Free(pExynosComponent->componentName);
+ pExynosComponent->componentName = NULL;
+
+ pFlacDec = (EXYNOS_FLAC_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ if (pFlacDec != NULL) {
+ if (pFlacDec->hSeirenFlacHandle.bSeirenLoaded == OMX_TRUE) {
+ ADec_Destroy(pFlacDec->hSeirenFlacHandle.hSeirenHandle);
+ }
+ Exynos_OSAL_Free(pFlacDec);
+ ((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ }
+
+ ret = Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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_Flacdec.h
+ * @brief
+ * @author Sungyeon Kim (sy85.kim@samsung.com)
+ * @version 1.0.0
+ * @history
+ * 2012.12.22 : Create
+ */
+
+#ifndef EXYNOS_OMX_FLAC_DEC_COMPONENT
+#define EXYNOS_OMX_FLAC_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "seiren_hw.h"
+
+static const uint32_t flac_sample_rates[] =
+{
+ 0, 88200, 176400, 192000, 8000, 16000, 22050, 24000,
+ 32000, 44100, 48000, 96000, 0, 0, 0, 0
+};
+static const uint32_t flac_channels[] =
+{
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 2, 2, 2, 0, 0, 0, 0, 0
+};
+
+typedef struct _EXYNOS_Seiren_FLAC_HANDLE
+{
+ OMX_U32 hSeirenHandle;
+ OMX_BOOL bConfiguredSeiren;
+ OMX_BOOL bSeirenLoaded;
+ OMX_BOOL bSeirenSendEOS;
+ OMX_S32 returnCodec;
+ audio_mem_info_t input_mem_pool;
+ audio_mem_info_t output_mem_pool;
+} EXYNOS_Seiren_FLAC_HANDLE;
+
+typedef struct _EXYNOS_FLAC_HANDLE
+{
+ /* OMX Codec specific */
+ OMX_AUDIO_PARAM_FLACTYPE flacParam;
+ OMX_AUDIO_PARAM_PCMMODETYPE pcmParam;
+
+ /* SEC Seiren Codec specific */
+ EXYNOS_Seiren_FLAC_HANDLE hSeirenFlacHandle;
+} EXYNOS_FLAC_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 /* EXYNOS_OMX_FLAC_DEC_COMPONENT */
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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 1.1.0
+ * @history
+ * 2012.02.28 : 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_FLAC_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 - audio decoder FLAC */
+ Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_FLAC_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_FLAC_DEC_ROLE);
+ ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+ FunctionOut();
+ return MAX_COMPONENT_NUM;
+}
+
--- /dev/null
+/*
+ *
+ * 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 1.1.0
+ * @history
+ * 2012.02.28 : Create
+ */
+
+#ifndef EXYNOS_OMX_FLAC_DEC_REG
+#define EXYNOS_OMX_FLAC_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
+
+/* FLAC */
+#define EXYNOS_OMX_COMPONENT_FLAC_DEC "OMX.Exynos.FLAC.Decoder"
+#define EXYNOS_OMX_COMPONENT_FLAC_DEC_ROLE "audio_decoder.flac"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* EXYNOS_OMX_FLAC_DEC_REG */
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Mp3dec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.MP3.Decoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Adec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libseirenhw
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/audio/seiren_dec \
+ $(EXYNOS_AUDIO_CODEC)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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_Mp3dec.c
+ * @brief
+ * @author Sungyeon Kim (sy85.kim@samsung.com)
+ * @version 1.0.0
+ * @history
+ * 2012.12.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_Adec.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Thread.h"
+#include "library_register.h"
+#include "Exynos_OMX_Mp3dec.h"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG "EXYNOS_MP3_DEC"
+#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+//#define Seiren_DUMP_TO_FILE
+#ifdef Seiren_DUMP_TO_FILE
+#include "stdio.h"
+
+FILE *inFile;
+FILE *outFile;
+#endif
+
+OMX_ERRORTYPE Exynos_Seiren_Mp3Dec_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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nParamIndex) {
+ case OMX_IndexParamAudioMp3:
+ {
+ OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
+ OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = NULL;
+ EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstMp3Param->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pSrcMp3Param = &pMp3Dec->mp3Param;
+
+ Exynos_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
+ }
+ break;
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
+ OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = NULL;
+ EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstPcmParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pSrcPcmParam = &pMp3Dec->pcmParam;
+
+ Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ }
+ 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) {
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE);
+ }
+ break;
+ default:
+ ret = Exynos_OMX_AudioDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+ break;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Mp3Dec_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 || 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ case OMX_IndexParamAudioMp3:
+ {
+ OMX_AUDIO_PARAM_MP3TYPE *pDstMp3Param = NULL;
+ OMX_AUDIO_PARAM_MP3TYPE *pSrcMp3Param = (OMX_AUDIO_PARAM_MP3TYPE *)pComponentParameterStructure;
+ EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcMp3Param->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pDstMp3Param = &pMp3Dec->mp3Param;
+
+ Exynos_OSAL_Memcpy(pDstMp3Param, pSrcMp3Param, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
+ }
+ break;
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pDstPcmParam = NULL;
+ OMX_AUDIO_PARAM_PCMMODETYPE *pSrcPcmParam = (OMX_AUDIO_PARAM_PCMMODETYPE *)pComponentParameterStructure;
+ EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcPcmParam->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ pDstPcmParam = &pMp3Dec->pcmParam;
+
+ Exynos_OSAL_Memcpy(pDstPcmParam, pSrcPcmParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ }
+ 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) {
+ goto EXIT;
+ }
+
+ if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+ ret = OMX_ErrorIncorrectStateOperation;
+ goto EXIT;
+ }
+
+ if (!Exynos_OSAL_Strncmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE, 16)) {
+ pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
+ } else {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ }
+ break;
+ default:
+ ret = Exynos_OMX_AudioDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
+ break;
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Mp3Dec_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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ default:
+ ret = Exynos_OMX_AudioDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Mp3Dec_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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ default:
+ ret = Exynos_OMX_AudioDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Mp3Dec_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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_AudioDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Mp3Dec_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;
+ }
+
+ Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Mp3Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_MP3_HANDLE *pMp3Dec = (EXYNOS_MP3_HANDLE *)pAudioDec->hCodecHandle;
+
+ FunctionIn();
+
+ INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
+ Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
+ pExynosComponent->bUseFlagEOF = OMX_TRUE; /* Mp3 extractor should parse into frame unit. */
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pMp3Dec->hSeirenMp3Handle.bConfiguredSeiren = OMX_FALSE;
+ pMp3Dec->hSeirenMp3Handle.bSeirenSendEOS = OMX_FALSE;
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+
+#ifdef Seiren_DUMP_TO_FILE
+ inFile = fopen("/data/InFile.mp3", "w+");
+ outFile = fopen("/data/OutFile.pcm", "w+");
+#endif
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Mp3Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ FunctionIn();
+
+#ifdef Seiren_DUMP_TO_FILE
+ fclose(inFile);
+ fclose(outFile);
+#endif
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Mp3_Decode_Block(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_MP3_HANDLE *pMp3Dec = (EXYNOS_MP3_HANDLE *)pAudioDec->hCodecHandle;
+ int returnCodec = 0;
+ unsigned long isSeirenStopped = 0;
+ OMX_BOOL isSeirenIbufOverflow = OMX_FALSE;
+
+ u32 fd = pMp3Dec->hSeirenMp3Handle.hSeirenHandle;
+ audio_mem_info_t input_mem_pool = pMp3Dec->hSeirenMp3Handle.input_mem_pool;
+ audio_mem_info_t output_mem_pool = pMp3Dec->hSeirenMp3Handle.output_mem_pool;
+ unsigned long sample_rate, channels;
+ int consumed_size = 0;
+ unsigned char* pt = NULL;
+ sample_rate = channels = 0;
+
+ FunctionIn();
+
+#ifdef Seiren_DUMP_TO_FILE
+ if (pExynosComponent->reInputData == OMX_FALSE) {
+ fwrite(pInputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], pInputData->dataLen, 1, inFile);
+ }
+#endif
+
+ /* Save timestamp and flags of input data */
+ pOutputData->timeStamp = pInputData->timeStamp;
+ pOutputData->nFlags = pInputData->nFlags & (~OMX_BUFFERFLAG_EOS);
+
+ /* Decoding mp3 frames by Seiren */
+ if (pExynosComponent->getAllDelayBuffer == OMX_FALSE) {
+ input_mem_pool.data_size = pInputData->dataLen;
+ pt = (unsigned char*)input_mem_pool.virt_addr;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "\e[1;33m %02X %02X %02X %02X %02X %02X %lld \e[0m", *pt,*(pt+1),*(pt+2),*(pt+3),*(pt+4), *(pt+5), pInputData->timeStamp);
+ returnCodec = ADec_SendStream(fd, &input_mem_pool, &consumed_size);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ProcessedSize : %d return : %d", consumed_size, returnCodec);
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EOS!!");
+ if (returnCodec >= 0) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
+ ADec_SendEOS(fd);
+ pMp3Dec->hSeirenMp3Handle.bSeirenSendEOS = OMX_TRUE;
+ }
+ } else if (returnCodec < 0) {
+ ret = OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ if (pMp3Dec->hSeirenMp3Handle.bConfiguredSeiren == OMX_FALSE) {
+ if ((pInputData->dataLen <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pMp3Dec->hSeirenMp3Handle.bSeirenSendEOS = OMX_FALSE;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ returnCodec = ADec_GetParams(fd, PCM_PARAM_SAMPLE_RATE, &sample_rate);
+ returnCodec = returnCodec | ADec_GetParams(fd, PCM_PARAM_NUM_OF_CH, &channels);
+
+ if (returnCodec < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_ADec_GetParams failed: %d", returnCodec);
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+
+ if (!sample_rate || !channels) {
+ if (pMp3Dec->hSeirenMp3Handle.bSeirenSendEOS == OMX_TRUE) {
+ pOutputData->dataLen = 0;
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ }
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "numChannels(%d), samplingRate(%d)",
+ channels, sample_rate);
+
+ if (pMp3Dec->pcmParam.nChannels != channels ||
+ pMp3Dec->pcmParam.nSamplingRate != sample_rate) {
+ /* Change channel count and sampling rate information */
+ pMp3Dec->pcmParam.nChannels = channels;
+ pMp3Dec->pcmParam.nSamplingRate = sample_rate;
+
+ /* 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);
+ }
+
+ pMp3Dec->hSeirenMp3Handle.bConfiguredSeiren = OMX_TRUE;
+
+ if (pMp3Dec->hSeirenMp3Handle.bSeirenSendEOS == OMX_TRUE) {
+ pOutputData->dataLen = 0;
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ ret = OMX_ErrorInputDataDecodeYet;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ ret = OMX_ErrorNone;
+ }
+ goto EXIT;
+ }
+
+ /* Get decoded data from Seiren */
+ ADec_RecvPCM(fd, &output_mem_pool);
+
+ pt = (unsigned char*)output_mem_pool.virt_addr;
+ /* Trim first samples for MP3 gapless CTS test */
+ if (pAudioDec->bFirstFrame) {
+ pAudioDec->bFirstFrame = OMX_FALSE;
+ const int gapless_frames = 529;
+ const int gapless_bytes = gapless_frames * pMp3Dec->pcmParam.nChannels * sizeof(OMX_S16);
+ pt += gapless_bytes;
+ output_mem_pool.data_size -= gapless_bytes;
+ }
+
+ if (output_mem_pool.data_size > 0) {
+ pOutputData->dataLen = output_mem_pool.data_size;
+ Exynos_OSAL_Memcpy(pOutputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE],
+ pt, output_mem_pool.data_size);
+ } else {
+ pOutputData->dataLen = 0;
+ }
+
+#ifdef Seiren_DUMP_TO_FILE
+ if (pOutputData->dataLen > 0)
+ fwrite(pOutputData->multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE], pOutputData->dataLen, 1, outFile);
+#endif
+
+ /* Delay EOS signal until all the PCM is returned from the Seiren driver. */
+ if (pMp3Dec->hSeirenMp3Handle.bSeirenSendEOS == OMX_TRUE) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS) {
+ returnCodec = ADec_GetParams(fd, ADEC_PARAM_GET_OUTPUT_STATUS, &isSeirenStopped);
+ if (returnCodec != 0)
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail Seiren_STOP_EOS_STATE");
+ if (isSeirenStopped == 1) {
+ pOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pExynosComponent->getAllDelayBuffer = OMX_FALSE;
+ pMp3Dec->hSeirenMp3Handle.bSeirenSendEOS = OMX_FALSE; /* for repeating one song */
+ ret = OMX_ErrorNone;
+ } else {
+ pExynosComponent->getAllDelayBuffer = OMX_TRUE;
+ ret = OMX_ErrorInputDataDecodeYet;
+ }
+ } else { /* Flush after EOS */
+ pMp3Dec->hSeirenMp3Handle.bSeirenSendEOS = OMX_FALSE;
+ }
+ }
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Mp3Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pInputData, EXYNOS_OMX_DATA *pOutputData)
+{
+ 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();
+
+ if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) ||
+ (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+
+ goto EXIT;
+ }
+ if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent)) {
+ if (pInputData->nFlags & OMX_BUFFERFLAG_EOS)
+ ret = OMX_ErrorInputDataDecodeYet;
+ else
+ ret = OMX_ErrorNone;
+
+ goto EXIT;
+ }
+
+ ret = Exynos_Seiren_Mp3_Decode_Block(pOMXComponent, pInputData, pOutputData);
+
+ if (ret != OMX_ErrorNone) {
+ if (ret == (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet) {
+ pOutputData->usedDataLen = 0;
+ pOutputData->remainDataLen = pOutputData->dataLen;
+ } else {
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, ret, 0, NULL);
+ }
+ } else {
+ pInputData->usedDataLen += pInputData->dataLen;
+ pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen;
+ pInputData->dataLen -= pInputData->usedDataLen;
+ pInputData->usedDataLen = 0;
+
+ pOutputData->usedDataLen = 0;
+ pOutputData->remainDataLen = pOutputData->dataLen;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Seiren_Mp3Dec_flushSeiren(OMX_COMPONENTTYPE *pOMXComponent, SEIREN_PORTTYPE type)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_AUDIODEC_COMPONENT *pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_MP3_HANDLE *pMp3Dec = (EXYNOS_MP3_HANDLE *)pAudioDec->hCodecHandle;
+
+ int fd = pMp3Dec->hSeirenMp3Handle.hSeirenHandle;
+ return ADec_Flush(fd, type);
+}
+
+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_AUDIODEC_COMPONENT *pAudioDec = NULL;
+ EXYNOS_MP3_HANDLE *pMp3Dec = NULL;
+ audio_mem_info_t input_mem_pool;
+ audio_mem_info_t output_mem_pool;
+ OMX_S32 fd;
+ OMX_S32 codec_type = CODEC_TYPE_MAX;
+
+ int i = 0;
+
+ FunctionIn();
+
+ if ((hComponent == NULL) || (componentName == NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MP3_DEC, componentName) == 0) {
+ codec_type = CODEC_TYPE_MP3;
+ } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MP1_DEC, componentName) == 0) {
+ codec_type = CODEC_TYPE_MP1;
+ } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MP2_DEC, componentName) == 0) {
+ codec_type = CODEC_TYPE_MP2;
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_AudioDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_AudioDecodeComponentInit error, ret: %X", __FUNCTION__, ret);
+ goto EXIT;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ pExynosComponent->codecType = HW_AUDIO_DEC_CODEC;
+
+ pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
+ if (pExynosComponent->componentName == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_1;
+ }
+ Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
+ Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MP3_DEC);
+
+ pMp3Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MP3_HANDLE));
+ if (pMp3Dec == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: EXYNOS_MP3_HANDLE alloc error, ret: %X", __FUNCTION__, ret);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT_ERROR_2;
+ }
+ Exynos_OSAL_Memset(pMp3Dec, 0, sizeof(EXYNOS_MP3_HANDLE));
+ pAudioDec = (EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pAudioDec->hCodecHandle = (OMX_HANDLETYPE)pMp3Dec;
+ pAudioDec->bFirstFrame = OMX_TRUE;
+
+ /* Create and Init Seiren */
+ pMp3Dec->hSeirenMp3Handle.bSeirenLoaded = OMX_FALSE;
+ fd = ADec_Create(0, ADEC_MP3, NULL);
+
+ if (fd < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_ADec_Create failed: %d", fd);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_3;
+ }
+ pMp3Dec->hSeirenMp3Handle.hSeirenHandle = fd; /* Seiren's fd */
+ pMp3Dec->hSeirenMp3Handle.bSeirenLoaded = OMX_TRUE;
+
+ /* Get input buffer info from Seiren */
+ Exynos_OSAL_Memset(&pMp3Dec->hSeirenMp3Handle.input_mem_pool, 0, sizeof(audio_mem_info_t));
+ ADec_GetIMemPoolInfo(fd, &pMp3Dec->hSeirenMp3Handle.input_mem_pool);
+ input_mem_pool = pMp3Dec->hSeirenMp3Handle.input_mem_pool;
+
+ if (input_mem_pool.virt_addr == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_Adec_GetIMemPoolInfo failed: %d", fd);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_5;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosPort->processData.allocSize = input_mem_pool.mem_size;
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = input_mem_pool.virt_addr;
+
+ /* Get output buffer info from Seiren */
+ Exynos_OSAL_Memset(&pMp3Dec->hSeirenMp3Handle.output_mem_pool, 0, sizeof(audio_mem_info_t));
+ ADec_GetOMemPoolInfo(fd, &pMp3Dec->hSeirenMp3Handle.output_mem_pool);
+ output_mem_pool = pMp3Dec->hSeirenMp3Handle.output_mem_pool;
+ if (output_mem_pool.virt_addr == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Seiren_ADec_GetOMemPoolInfo failed: %d", fd);
+ ret = OMX_ErrorHardware;
+ goto EXIT_ERROR_6;
+ }
+
+ /* 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.nBufferCountActual = input_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferCountMin = input_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferSize = input_mem_pool.mem_size;
+ pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+ Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+ if (codec_type == CODEC_TYPE_MP3)
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/mpeg");
+ else if (codec_type == CODEC_TYPE_MP1)
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/mpeg-L1");
+ else
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/mpeg-L2");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
+ pExynosPort->portWayType = WAY1_PORT;
+
+ /* Output port */
+ pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ pExynosPort->portDefinition.nBufferCountActual = output_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferCountMin = output_mem_pool.block_count;
+ pExynosPort->portDefinition.nBufferSize = output_mem_pool.mem_size;
+ pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+ Exynos_OSAL_Memset(pExynosPort->portDefinition.format.audio.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
+ Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.audio.cMIMEType, "audio/raw");
+ pExynosPort->portDefinition.format.audio.pNativeRender = 0;
+ pExynosPort->portDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pExynosPort->portDefinition.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+ pExynosPort->portWayType = WAY1_PORT;
+
+ /* Default values for Mp3 audio param */
+ INIT_SET_SIZE_VERSION(&pMp3Dec->mp3Param, OMX_AUDIO_PARAM_MP3TYPE);
+ pMp3Dec->mp3Param.nPortIndex = INPUT_PORT_INDEX;
+ pMp3Dec->mp3Param.nChannels = DEFAULT_AUDIO_CHANNELS_NUM;
+ pMp3Dec->mp3Param.nBitRate = 0;
+ pMp3Dec->mp3Param.nSampleRate = DEFAULT_AUDIO_SAMPLING_FREQ;
+ pMp3Dec->mp3Param.nAudioBandWidth = 0;
+ pMp3Dec->mp3Param.eChannelMode = OMX_AUDIO_ChannelModeStereo;
+ pMp3Dec->mp3Param.eFormat = OMX_AUDIO_MP3StreamFormatMP1Layer3;
+
+ /* Default values for PCM audio param */
+ INIT_SET_SIZE_VERSION(&pMp3Dec->pcmParam, OMX_AUDIO_PARAM_PCMMODETYPE);
+ pMp3Dec->pcmParam.nPortIndex = OUTPUT_PORT_INDEX;
+ pMp3Dec->pcmParam.nChannels = DEFAULT_AUDIO_CHANNELS_NUM;
+ pMp3Dec->pcmParam.eNumData = OMX_NumericalDataSigned;
+ pMp3Dec->pcmParam.eEndian = OMX_EndianLittle;
+ pMp3Dec->pcmParam.bInterleaved = OMX_TRUE;
+ pMp3Dec->pcmParam.nBitPerSample = DEFAULT_AUDIO_BIT_PER_SAMPLE;
+ pMp3Dec->pcmParam.nSamplingRate = DEFAULT_AUDIO_SAMPLING_FREQ;
+ pMp3Dec->pcmParam.ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pMp3Dec->pcmParam.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pMp3Dec->pcmParam.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ pOMXComponent->GetParameter = &Exynos_Seiren_Mp3Dec_GetParameter;
+ pOMXComponent->SetParameter = &Exynos_Seiren_Mp3Dec_SetParameter;
+ pOMXComponent->GetConfig = &Exynos_Seiren_Mp3Dec_GetConfig;
+ pOMXComponent->SetConfig = &Exynos_Seiren_Mp3Dec_SetConfig;
+ pOMXComponent->GetExtensionIndex = &Exynos_Seiren_Mp3Dec_GetExtensionIndex;
+ pOMXComponent->ComponentRoleEnum = &Exynos_Seiren_Mp3Dec_ComponentRoleEnum;
+ pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
+
+ /* ToDo: Change the function name associated with a specific codec */
+ pExynosComponent->exynos_codec_componentInit = &Exynos_Seiren_Mp3Dec_Init;
+ pExynosComponent->exynos_codec_componentTerminate = &Exynos_Seiren_Mp3Dec_Terminate;
+ pAudioDec->exynos_codec_bufferProcess = &Exynos_Seiren_Mp3Dec_bufferProcess;
+ pAudioDec->exynos_codec_flushSeiren = &Exynos_Seiren_Mp3Dec_flushSeiren;
+ pAudioDec->exynos_checkInputFrame = NULL;
+
+ pExynosComponent->currentState = OMX_StateLoaded;
+
+ ret = OMX_ErrorNone;
+ goto EXIT; /* This function is performed successfully. */
+
+EXIT_ERROR_6:
+ pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosPort->processData.multiPlaneBuffer.dataBuffer[AUDIO_DATA_PLANE] = NULL;
+ pExynosPort->processData.allocSize = 0;
+EXIT_ERROR_5:
+EXIT_ERROR_4:
+ ADec_Destroy(pMp3Dec->hSeirenMp3Handle.hSeirenHandle);
+EXIT_ERROR_3:
+ Exynos_OSAL_Free(pMp3Dec);
+ pAudioDec->hCodecHandle = NULL;
+EXIT_ERROR_2:
+ Exynos_OSAL_Free(pExynosComponent->componentName);
+ pExynosComponent->componentName = NULL;
+EXIT_ERROR_1:
+ Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
+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_MP3_HANDLE *pMp3Dec = NULL;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+ FunctionIn();
+
+ if (hComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ Exynos_OSAL_Free(pExynosComponent->componentName);
+ pExynosComponent->componentName = NULL;
+
+ pMp3Dec = (EXYNOS_MP3_HANDLE *)((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ if (pMp3Dec != NULL) {
+ if (pMp3Dec->hSeirenMp3Handle.bSeirenLoaded == OMX_TRUE) {
+ ADec_Destroy(pMp3Dec->hSeirenMp3Handle.hSeirenHandle);
+ }
+ Exynos_OSAL_Free(pMp3Dec);
+ ((EXYNOS_OMX_AUDIODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ }
+
+ ret = Exynos_OMX_AudioDecodeComponentDeinit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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_Mp3dec.h
+ * @brief
+ * @author Sungyeon Kim (sy85.kim@samsung.com)
+ * @version 1.0.0
+ * @history
+ * 2012.12.22 : Create
+ */
+
+#ifndef EXYNOS_OMX_MP3_DEC_COMPONENT
+#define EXYNOS_OMX_MP3_DEC_COMPONENT
+
+#include "Exynos_OMX_Def.h"
+#include "OMX_Component.h"
+#include "seiren_hw.h"
+
+typedef enum _CODEC_TYPE
+{
+ CODEC_TYPE_MP1,
+ CODEC_TYPE_MP2,
+ CODEC_TYPE_MP3,
+ CODEC_TYPE_MAX
+} CODEC_TYPE;
+
+typedef struct _EXYNOS_Seiren_MP3_HANDLE
+{
+ OMX_U32 hSeirenHandle;
+ OMX_BOOL bConfiguredSeiren;
+ OMX_BOOL bSeirenLoaded;
+ OMX_BOOL bSeirenSendEOS;
+ OMX_S32 returnCodec;
+ audio_mem_info_t input_mem_pool;
+ audio_mem_info_t output_mem_pool;
+} EXYNOS_Seiren_MP3_HANDLE;
+
+typedef struct _EXYNOS_MP3_HANDLE
+{
+ /* OMX Codec specific */
+ OMX_AUDIO_PARAM_MP3TYPE mp3Param;
+ OMX_AUDIO_PARAM_PCMMODETYPE pcmParam;
+
+ /* SEC Seiren Codec specific */
+ EXYNOS_Seiren_MP3_HANDLE hSeirenMp3Handle;
+} EXYNOS_MP3_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 /* EXYNOS_OMX_MP3_DEC_COMPONENT */
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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 1.1.0
+ * @history
+ * 2012.02.28 : 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_MP3_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 - audio decoder MP3 */
+ Exynos_OSAL_Strcpy(ppExynosComponent[0]->componentName, EXYNOS_OMX_COMPONENT_MP3_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[0]->roles[0], EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE);
+ ppExynosComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+ /* component 2 - audio decoder MP3 Layer 1 */
+ Exynos_OSAL_Strcpy(ppExynosComponent[1]->componentName, EXYNOS_OMX_COMPONENT_MP1_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[1]->roles[0], EXYNOS_OMX_COMPONENT_MP1_DEC_ROLE);
+ ppExynosComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+ /* component 3 - audio decoder MP3 Layer 2 */
+ Exynos_OSAL_Strcpy(ppExynosComponent[2]->componentName, EXYNOS_OMX_COMPONENT_MP2_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[2]->roles[0], EXYNOS_OMX_COMPONENT_MP2_DEC_ROLE);
+ ppExynosComponent[2]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+EXIT:
+ FunctionOut();
+ return MAX_COMPONENT_NUM;
+}
+
--- /dev/null
+/*
+ *
+ * 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 1.1.0
+ * @history
+ * 2012.02.28 : Create
+ */
+
+#ifndef EXYNOS_OMX_MP3_DEC_REG
+#define EXYNOS_OMX_MP3_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
+
+/* MP3 */
+#define EXYNOS_OMX_COMPONENT_MP3_DEC "OMX.Exynos.MP3.Decoder"
+#define EXYNOS_OMX_COMPONENT_MP3_DEC_ROLE "audio_decoder.mp3"
+
+#define EXYNOS_OMX_COMPONENT_MP1_DEC "OMX.Exynos.MP1.Decoder"
+#define EXYNOS_OMX_COMPONENT_MP1_DEC_ROLE "audio_decoder.mp1"
+
+#define EXYNOS_OMX_COMPONENT_MP2_DEC "OMX.Exynos.MP2.Decoder"
+#define EXYNOS_OMX_COMPONENT_MP2_DEC_ROLE "audio_decoder.mp2"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **ppExynosComponent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* EXYNOS_OMX_MP3_DEC_REG */
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Basecomponent.c \
+ Exynos_OMX_Baseport.c
+
+LOCAL_MODULE := libExynosOMX_Basecomponent
+
+LOCAL_CFLAGS :=
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_OSAL
+LOCAL_SHARED_LIBRARIES := libcutils libutils
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+ifeq ($(EXYNOS_OMX_SUPPORT_EGL_IMAGE), true)
+LOCAL_CFLAGS += -DEGL_IMAGE_SUPPORT
+endif
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Resourcemanager.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libExynosOMX_Resourcemanager
+
+LOCAL_CFLAGS :=
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_OSAL
+LOCAL_SHARED_LIBRARIES := libcutils libutils
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+ifeq ($(EXYNOS_OMX_SUPPORT_TUNNELING), true)
+LOCAL_CFLAGS += -DTUNNELING_SUPPORT
+endif
+
+ifneq ($(BOARD_NOT_SUPPORT_DCPP), true)
+LOCAL_CFLAGS += -DUSE_SECURE_WITH_NONSECURE
+endif
+
+ifeq ($(BOARD_USE_SINGLE_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_DRM
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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)
+ * 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 <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"
+
+
+/* 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_TRACE, "nVersionMajor:%d, nVersionMinor:%d", 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_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_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 messageParam)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_MESSAGE *message;
+ OMX_STATETYPE destState = messageParam;
+ OMX_STATETYPE currentState = pExynosComponent->currentState;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ OMX_S32 countValue = 0;
+ unsigned int i = 0, j = 0;
+ int k = 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:
+ 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++) {
+ 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;
+ }
+ Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
+ pExynosComponent->pExynosPort[i].hPortMutex = NULL;
+ }
+
+ if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
+ Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent);
+ pExynosComponent->pauseEvent = NULL;
+ } else {
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
+ pExynosComponent->pExynosPort[i].pauseEvent = NULL;
+ if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) {
+ Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
+ pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL;
+ }
+ }
+ }
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
+ pExynosComponent->pExynosPort[i].bufferSemID = NULL;
+ }
+ if (pExynosComponent->exynos_codec_componentTerminate != NULL)
+ pExynosComponent->exynos_codec_componentTerminate(pOMXComponent);
+
+ ret = OMX_ErrorInvalidState;
+ break;
+ default:
+ ret = OMX_ErrorInvalidState;
+ break;
+ }
+ break;
+ case OMX_StateLoaded:
+ switch (currentState) {
+ case OMX_StateIdle:
+ ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent);
+
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ 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;
+ }
+ Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
+ pExynosComponent->pExynosPort[i].hPortMutex = NULL;
+ }
+ if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
+ Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent);
+ pExynosComponent->pauseEvent = NULL;
+ } else {
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
+ pExynosComponent->pExynosPort[i].pauseEvent = NULL;
+ if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) {
+ Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
+ pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL;
+ }
+ }
+ }
+ 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);
+
+ for (i = 0; i < (pExynosComponent->portParam.nPorts); i++) {
+ pExynosPort = (pExynosComponent->pExynosPort + i);
+#ifdef TUNNELING_SUPPORT
+ if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
+ message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (message != NULL)
+ Exynos_OSAL_Free(message);
+ }
+ ret = pExynosComponent->exynos_FreeTunnelBuffer(pExynosPort, i);
+ if (OMX_ErrorNone != ret) {
+ goto EXIT;
+ }
+ } else
+#endif
+ {
+ if (CHECK_PORT_ENABLED(pExynosPort)) {
+ if (pExynosPort->assignedBufferNum > 0)
+ Exynos_OSAL_SemaphoreWait(pExynosPort->unloadedResource);
+ while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
+ message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (message != NULL)
+ Exynos_OSAL_Free(message);
+ }
+ pExynosPort->portDefinition.bPopulated = OMX_FALSE;
+ }
+ }
+ }
+ pExynosComponent->currentState = OMX_StateLoaded;
+ break;
+ 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 < pExynosComponent->portParam.nPorts; i++) {
+ pExynosPort = (pExynosComponent->pExynosPort + i);
+#ifdef TUNNELING_SUPPORT
+ if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ if (CHECK_PORT_ENABLED(pExynosPort)) {
+ ret = pExynosComponent->exynos_AllocateTunnelBuffer(pExynosPort, i);
+ if (ret!=OMX_ErrorNone)
+ goto EXIT;
+ }
+ } else
+#endif
+ {
+ if (CHECK_PORT_ENABLED(pExynosPort)) {
+ Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[i].loadedResource);
+ if (pExynosComponent->abendState == OMX_TRUE) {
+ Exynos_OSAL_SignalSet(pExynosComponent->abendStateEvent);
+ goto EXIT;
+ }
+ pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+ }
+ }
+ }
+ Exynos_OSAL_Get_Log_Property(); // For debuging, Function called when GetHandle function is success
+ ret = pExynosComponent->exynos_codec_componentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+#ifdef TUNNELING_SUPPORT
+ /*
+ * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
+ */
+#endif
+ Exynos_OSAL_SignalSet(pExynosComponent->abendStateEvent);
+ goto EXIT;
+ }
+ if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
+ Exynos_OSAL_SignalCreate(&pExynosComponent->pauseEvent);
+ } else {
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].pauseEvent);
+ if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE)
+ Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
+ }
+ }
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->pExynosPort[i].bufferSemID);
+ if (ret != OMX_ErrorNone) {
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ }
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
+ ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
+ if (ret != OMX_ErrorNone) {
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
+ ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
+ if (ret != OMX_ErrorNone) {
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
+ if (ret != OMX_ErrorNone) {
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ }
+ ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].hPortMutex);
+ if (ret != OMX_ErrorNone) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ }
+
+ ret = pExynosComponent->exynos_BufferProcessCreate(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+#ifdef TUNNELING_SUPPORT
+ /*
+ * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
+ */
+#endif
+ if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
+ Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent);
+ pExynosComponent->pauseEvent = NULL;
+ } else {
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
+ pExynosComponent->pExynosPort[i].pauseEvent = NULL;
+ if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) {
+ Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
+ pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL;
+ }
+ }
+ }
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ 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;
+ }
+ Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
+ pExynosComponent->pExynosPort[i].hPortMutex = NULL;
+ }
+ 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;
+ }
+ pExynosComponent->currentState = OMX_StateIdle;
+ break;
+ case OMX_StateExecuting:
+ case OMX_StatePause:
+ 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:
+ 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);
+ }
+ }
+ }
+
+ pExynosComponent->transientState = EXYNOS_OMX_TransStateMax;
+ pExynosComponent->currentState = OMX_StateExecuting;
+ if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
+ Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
+ } else {
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent);
+ }
+ }
+ break;
+ case OMX_StatePause:
+ 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 (k = 0; k < cnt; k++) {
+ Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID);
+ }
+ }
+ }
+ }
+
+ pExynosComponent->currentState = OMX_StateExecuting;
+ if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
+ Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
+ } else {
+ 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]:%d OMX_EventCmdComplete", pExynosComponent, __FUNCTION__, __LINE__);
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventCmdComplete, OMX_CommandStateSet,
+ destState, NULL);
+ }
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]:%d ret = %d", pExynosComponent, __FUNCTION__, __LINE__, ret);
+ if (pExynosComponent->pCallbacks != NULL) {
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, ret, 0, NULL);
+ }
+ }
+ FunctionOut();
+
+ 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;
+ EXYNOS_OMX_MESSAGE *message = NULL;
+ OMX_U32 messageType = 0, portIndex = 0;
+
+ 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;
+ }
+
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ while (pExynosComponent->bExitMessageHandlerThread == OMX_FALSE) {
+ Exynos_OSAL_SemaphoreWait(pExynosComponent->msgSemaphoreHandle);
+ message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosComponent->messageQ);
+ if (message != NULL) {
+ messageType = message->messageType;
+ switch (messageType) {
+ case OMX_CommandStateSet:
+ ret = Exynos_OMX_ComponentStateSet(pOMXComponent, message->messageParam);
+ break;
+ case OMX_CommandFlush:
+ ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, message->messageParam, OMX_TRUE);
+ break;
+ case OMX_CommandPortDisable:
+ ret = Exynos_OMX_PortDisableProcess(pOMXComponent, message->messageParam);
+ break;
+ case OMX_CommandPortEnable:
+ ret = Exynos_OMX_PortEnableProcess(pOMXComponent, message->messageParam);
+ break;
+ case OMX_CommandMarkBuffer:
+ portIndex = message->messageParam;
+ pExynosComponent->pExynosPort[portIndex].markType.hMarkTargetComponent = ((OMX_MARKTYPE *)message->pCmdData)->hMarkTargetComponent;
+ pExynosComponent->pExynosPort[portIndex].markType.pMarkData = ((OMX_MARKTYPE *)message->pCmdData)->pMarkData;
+ break;
+ case (OMX_COMMANDTYPE)EXYNOS_OMX_CommandComponentDeInit:
+ pExynosComponent->bExitMessageHandlerThread = OMX_TRUE;
+ break;
+ default:
+ break;
+ }
+ Exynos_OSAL_Free(message);
+ message = NULL;
+ }
+ }
+
+ Exynos_OSAL_ThreadExit(NULL);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+static 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)) {
+ pExynosComponent->transientState = EXYNOS_OMX_TransStateLoadedToIdle;
+ for(i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+ pExynosComponent->pExynosPort[i].portState = OMX_StateIdle;
+ }
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateIdle");
+ } else if ((destState == OMX_StateLoaded) && (pExynosComponent->currentState == OMX_StateIdle)) {
+ pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToLoaded;
+ for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+ pExynosComponent->pExynosPort[i].portState = OMX_StateLoaded;
+ }
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateLoaded");
+ } else if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StateExecuting)) {
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+ pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]);
+ if ((pExynosPort->portDefinition.bEnabled == OMX_FALSE) &&
+ (pExynosPort->portState == OMX_StateIdle)) {
+ pExynosPort->exceptionFlag = INVALID_STATE;
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ }
+
+ pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
+ if ((pExynosPort->portDefinition.bEnabled == OMX_FALSE) &&
+ (pExynosPort->portState == OMX_StateIdle)) {
+ pExynosPort->exceptionFlag = INVALID_STATE;
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ }
+
+ pExynosComponent->transientState = EXYNOS_OMX_TransStateExecutingToIdle;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateIdle");
+ } else if ((destState == OMX_StateExecuting) && (pExynosComponent->currentState == OMX_StateIdle)) {
+ pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToExecuting;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateExecuting");
+ } else if (destState == OMX_StateInvalid) {
+ for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
+ pExynosComponent->pExynosPort[i].portState = OMX_StateInvalid;
+ }
+ }
+
+ return OMX_ErrorNone;
+}
+
+static OMX_ERRORTYPE Exynos_SetPortFlush(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ OMX_S32 portIndex = nParam;
+ OMX_U16 i = 0, cnt = 0, index = 0;
+
+
+ if ((pExynosComponent->currentState == OMX_StateExecuting) ||
+ (pExynosComponent->currentState == OMX_StatePause)) {
+ if ((portIndex != ALL_PORT_INDEX) &&
+ ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ /*********************
+ * need flush event set ?????
+ **********************/
+ cnt = (portIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1;
+ for (i = 0; i < cnt; i++) {
+ if (portIndex == ALL_PORT_INDEX)
+ index = i;
+ else
+ index = portIndex;
+ pExynosComponent->pExynosPort[index].bIsPortFlushed = OMX_TRUE;
+ }
+ } else {
+ ret = OMX_ErrorIncorrectStateOperation;
+ goto EXIT;
+ }
+ ret = OMX_ErrorNone;
+
+EXIT:
+ 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_S32 portIndex = nParam;
+ OMX_U16 i = 0, cnt = 0;
+
+ FunctionIn();
+
+ if ((portIndex != ALL_PORT_INDEX) &&
+ ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if (portIndex == 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->portState = OMX_StateIdle;
+ }
+ }
+ } else {
+ pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+ if (CHECK_PORT_ENABLED(pExynosPort)) {
+ ret = OMX_ErrorIncorrectStateOperation;
+ goto EXIT;
+ } else {
+ pExynosPort->portState = OMX_StateIdle;
+ }
+ }
+ 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_S32 portIndex = nParam;
+ OMX_U16 i = 0, cnt = 0;
+
+ FunctionIn();
+
+ if ((portIndex != ALL_PORT_INDEX) &&
+ ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if (portIndex == 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 = OMX_StateLoaded;
+ pExynosPort->bIsPortDisabled = OMX_TRUE;
+ }
+ } else {
+ pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+ pExynosPort->portState = OMX_StateLoaded;
+ pExynosPort->bIsPortDisabled = OMX_TRUE;
+ }
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+static OMX_ERRORTYPE Exynos_SetMarkBuffer(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ OMX_U32 portIndex = nParam;
+ OMX_U16 i = 0, cnt = 0;
+
+
+ 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_OMX_CommandQueue(
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
+ OMX_COMMANDTYPE Cmd,
+ OMX_U32 nParam,
+ OMX_PTR pCmdData)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_MESSAGE *command = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
+
+ if (command == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ command->messageType = (OMX_U32)Cmd;
+ command->messageParam = nParam;
+ command->pCmdData = pCmdData;
+
+ ret = Exynos_OSAL_Queue(&pExynosComponent->messageQ, (void *)command);
+ if (ret != 0) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+ ret = Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
+
+EXIT:
+ 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;
+ EXYNOS_OMX_MESSAGE *message = 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_TRACE, "Command: OMX_CommandStateSet");
+ Exynos_StateSet(pExynosComponent, nParam);
+ break;
+ case OMX_CommandFlush :
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandFlush");
+ ret = Exynos_SetPortFlush(pExynosComponent, nParam);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+ break;
+ case OMX_CommandPortDisable :
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortDisable");
+ ret = Exynos_SetPortDisable(pExynosComponent, nParam);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+ break;
+ case OMX_CommandPortEnable :
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortEnable");
+ ret = Exynos_SetPortEnable(pExynosComponent, nParam);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+ break;
+ case OMX_CommandMarkBuffer :
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandMarkBuffer");
+ ret = Exynos_SetMarkBuffer(pExynosComponent, nParam);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+ break;
+ default:
+ break;
+ }
+
+ ret = Exynos_OMX_CommandQueue(pExynosComponent, Cmd, nParam, pCmdData);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_GetParameter(
+ 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;
+
+ 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 (ComponentParameterStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ 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 *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
+ 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_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+ OMX_U32 portIndex = portDefinition->nPortIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ /* 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);
+ }
+ break;
+ case OMX_IndexParamPriorityMgmt:
+ {
+ OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure;
+
+ 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 *)ComponentParameterStructure;
+ 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_OMX_SetParameter(
+ 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;
+
+ 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 (ComponentParameterStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ case OMX_IndexParamAudioInit:
+ case OMX_IndexParamVideoInit:
+ case OMX_IndexParamImageInit:
+ case OMX_IndexParamOtherInit:
+ {
+ 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) {
+ 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_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+ OMX_U32 portIndex = portDefinition->nPortIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ /* 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];
+
+ if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+ if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
+ ret = OMX_ErrorIncorrectStateOperation;
+ goto EXIT;
+ }
+ }
+ if (portDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Memcpy(((char *)&pExynosPort->portDefinition) + nOffset,
+ ((char *)portDefinition) + nOffset,
+ portDefinition->nSize - nOffset);
+ }
+ break;
+ case OMX_IndexParamPriorityMgmt:
+ {
+ OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure;
+
+ 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 *)ComponentParameterStructure;
+ 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_PTR Exynos_OMX_MakeDynamicConfigCMD(
+ OMX_INDEXTYPE nIndex,
+ OMX_PTR pComponentConfigStructure)
+{
+ OMX_PTR ret = NULL;
+ OMX_S32 nConfigStructureSize = 0;
+
+ switch ((int)nIndex) {
+ case OMX_IndexConfigVideoIntraPeriod:
+ {
+ nConfigStructureSize = sizeof(OMX_U32);
+ ret = Exynos_OSAL_Malloc(sizeof(OMX_U32) + nConfigStructureSize);
+ }
+ break;
+ case OMX_IndexConfigVideoRoiInfo:
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *pRoiInfo = (EXYNOS_OMX_VIDEO_CONFIG_ROIINFO *)pComponentConfigStructure;
+ OMX_S32 nRoiMBInfoSize = 0;
+ nConfigStructureSize = *(OMX_U32 *)pComponentConfigStructure;
+ if (pRoiInfo->bUseRoiInfo == OMX_TRUE)
+ nRoiMBInfoSize = pRoiInfo->nRoiMBInfoSize;
+ ret = Exynos_OSAL_Malloc(sizeof(OMX_U32) + nConfigStructureSize + nRoiMBInfoSize);
+ if (ret != NULL)
+ Exynos_OSAL_Memcpy((OMX_PTR)((OMX_U8 *)ret + sizeof(OMX_U32) + nConfigStructureSize), pRoiInfo->pRoiMBInfo, nRoiMBInfoSize);
+ }
+ break;
+ default:
+ nConfigStructureSize = *(OMX_U32 *)pComponentConfigStructure;
+ ret = Exynos_OSAL_Malloc(sizeof(OMX_U32) + nConfigStructureSize);
+ break;
+ }
+
+ if (ret != NULL) {
+ *((OMX_S32 *)ret) = (OMX_S32)nIndex;
+ Exynos_OSAL_Memcpy((OMX_PTR)((OMX_U8 *)ret + sizeof(OMX_U32)), pComponentConfigStructure, nConfigStructureSize);
+ }
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_GetConfig(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_INOUT OMX_PTR pComponentConfigStructure)
+{
+ 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 (pComponentConfigStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ default:
+ ret = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_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;
+
+ 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 (pComponentConfigStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ 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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorBadParameter;
+
+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;
+}
+
+#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
+
+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, "lib version is %s", IS_64BIT_OS? "64bit":"32bit");
+
+ if (hComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ Exynos_OSAL_Memset(pExynosComponent, 0, sizeof(EXYNOS_OMX_BASECOMPONENT));
+ pOMXComponent->pComponentPrivate = (OMX_PTR)pExynosComponent;
+
+ ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->msgSemaphoreHandle);
+ if (ret != OMX_ErrorNone) {
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ ret = Exynos_OSAL_MutexCreate(&pExynosComponent->compMutex);
+ if (ret != OMX_ErrorNone) {
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ ret = Exynos_OSAL_SignalCreate(&pExynosComponent->abendStateEvent);
+ if (ret != OMX_ErrorNone) {
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_QueueCreate(&pExynosComponent->dynamicConfigQ, MAX_QUEUE_ELEMENTS);
+
+ pExynosComponent->bMultiThreadProcess = OMX_FALSE;
+
+ 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, EXYNOS_OMX_CommandComponentDeInit, 0, NULL);
+ Exynos_OSAL_SleepMillisec(0);
+ Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->msgSemaphoreHandle, &semaValue);
+ if (semaValue == 0)
+ Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
+ Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
+
+ Exynos_OSAL_ThreadTerminate(pExynosComponent->hMessageHandler);
+ pExynosComponent->hMessageHandler = NULL;
+
+ Exynos_OSAL_SignalTerminate(pExynosComponent->abendStateEvent);
+ pExynosComponent->abendStateEvent = NULL;
+ Exynos_OSAL_MutexTerminate(pExynosComponent->compMutex);
+ pExynosComponent->compMutex = NULL;
+ Exynos_OSAL_SemaphoreTerminate(pExynosComponent->msgSemaphoreHandle);
+ pExynosComponent->msgSemaphoreHandle = NULL;
+ Exynos_OSAL_QueueTerminate(&pExynosComponent->messageQ);
+
+ Exynos_OSAL_Free(pExynosComponent);
+ pExynosComponent = NULL;
+
+ ret = OMX_ErrorNone;
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+
--- /dev/null
+/*
+ *
+ * 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)
+ * Yunji Kim (yunji.kim@samsung.com)
+ * @version 2.0.0
+ * @history
+ * 2012.02.20 : Create
+ */
+
+#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 messageType;
+ OMX_U32 messageParam;
+ 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;
+ OMX_HANDLETYPE abendStateEvent;
+
+ EXYNOS_CODEC_TYPE codecType;
+ EXYNOS_OMX_PRIORITYMGMTTYPE compPriority;
+ OMX_MARKTYPE propagateMarkType;
+ OMX_HANDLETYPE compMutex;
+
+ OMX_HANDLETYPE hComponentHandle;
+
+ /* Message Handler */
+ OMX_BOOL bExitMessageHandlerThread;
+ OMX_HANDLETYPE hMessageHandler;
+ OMX_HANDLETYPE msgSemaphoreHandle;
+ EXYNOS_QUEUE messageQ;
+ EXYNOS_QUEUE dynamicConfigQ;
+
+ /* Port */
+ OMX_PORT_PARAM_TYPE portParam;
+ EXYNOS_OMX_BASEPORT *pExynosPort;
+
+ OMX_HANDLETYPE pauseEvent;
+
+ /* 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. */
+
+ /* Check for Old & New OMX Process type switch */
+ OMX_BOOL bMultiThreadProcess;
+
+ 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_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nParamIndex,
+ OMX_INOUT OMX_PTR ComponentParameterStructure);
+
+OMX_ERRORTYPE Exynos_OMX_SetParameter(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_IN OMX_PTR ComponentParameterStructure);
+
+OMX_PTR Exynos_OMX_MakeDynamicConfigCMD(
+ OMX_INDEXTYPE nIndex,
+ OMX_PTR pComponentConfigStructure);
+
+OMX_ERRORTYPE Exynos_OMX_GetConfig(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_INOUT OMX_PTR pComponentConfigStructure);
+
+OMX_ERRORTYPE Exynos_OMX_SetConfig(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_IN OMX_PTR pComponentConfigStructure);
+
+OMX_ERRORTYPE Exynos_OMX_GetExtensionIndex(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_STRING cParameterName,
+ OMX_OUT OMX_INDEXTYPE *pIndexType);
+
+OMX_ERRORTYPE Exynos_OMX_BaseComponent_Constructor(OMX_IN OMX_HANDLETYPE hComponent);
+OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor(OMX_IN OMX_HANDLETYPE hComponent);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ OMX_ERRORTYPE Exynos_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size);
+
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
--- /dev/null
+/*
+ *
+ * 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)
+ * HyeYeon Chung (hyeon.chung@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_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Mutex.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
+
+
+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, "Trying to return the input buffer without ownership!!");
+ }
+ }
+ }
+
+#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->EmptyBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bufferHeader: %p", pOMXComponent, __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, "Trying to return the output buffer without ownership!!");
+ }
+ }
+ }
+
+#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->FillBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bufferHeader: %p", pOMXComponent, __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 portIndex = 0;
+ EXYNOS_OMX_DATABUFFER *flushPortBuffer[2] = {NULL, NULL};
+ 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)
+ portIndex = i;
+ else
+ portIndex = nPortIndex;
+
+ pExynosComponent->exynos_BufferFlush(pOMXComponent, portIndex, bEvent);
+ }
+
+EXIT:
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__);
+
+ 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 portIndex)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ OMX_U32 i = 0, cnt = 0;
+
+ FunctionIn();
+
+ pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+
+ if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: Port($d) is waiting for loadedResource", __func__, portIndex);
+ Exynos_OSAL_SemaphoreWait(pExynosPort->loadedResource);
+
+ if (pExynosPort->exceptionFlag == INVALID_STATE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: Port(%d) is in the INVALID_STATE", __func__, portIndex);
+ pExynosPort->exceptionFlag = NEED_PORT_DISABLE;
+ goto EXIT;
+ }
+ pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+ }
+ pExynosPort->exceptionFlag = GENERAL_STATE;
+ pExynosPort->portDefinition.bEnabled = OMX_TRUE;
+
+ if ((pExynosComponent->bMultiThreadProcess == OMX_TRUE) &&
+ (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;
+ OMX_S32 portIndex = 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)
+ portIndex = i;
+ else
+ portIndex = nPortIndex;
+
+ ret = Exynos_OMX_EnablePort(pOMXComponent, portIndex);
+ if (ret == OMX_ErrorNone) {
+ pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventCmdComplete,
+ OMX_CommandPortEnable, portIndex, NULL);
+ }
+ }
+
+EXIT:
+ if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != 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 portIndex)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ OMX_U32 i = 0, elemNum = 0;
+ EXYNOS_OMX_MESSAGE *message;
+
+ FunctionIn();
+
+ pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+
+ if (!CHECK_PORT_ENABLED(pExynosPort)) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (pExynosComponent->currentState != OMX_StateLoaded) {
+ if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
+ message = (EXYNOS_OMX_MESSAGE*)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ Exynos_OSAL_Free(message);
+ }
+ }
+ pExynosPort->portDefinition.bPopulated = OMX_FALSE;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: Port(%d) is waiting for unloadedResource", __func__, portIndex);
+ Exynos_OSAL_SemaphoreWait(pExynosPort->unloadedResource);
+ }
+ 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 portIndex = 0;
+ OMX_U32 i = 0, cnt = 0;
+ EXYNOS_OMX_DATABUFFER *flushPortBuffer[2] = {NULL, NULL};
+
+ 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)
+ portIndex = i;
+ else
+ portIndex = nPortIndex;
+
+ Exynos_OMX_BufferFlushProcess(pOMXComponent, portIndex, OMX_FALSE);
+ }
+ }
+
+ for(i = 0; i < cnt; i++) {
+ if (nPortIndex == ALL_PORT_INDEX)
+ portIndex = i;
+ else
+ portIndex = nPortIndex;
+
+ ret = Exynos_OMX_DisablePort(pOMXComponent, portIndex);
+ pExynosComponent->pExynosPort[portIndex].bIsPortDisabled = OMX_FALSE;
+ if (ret == OMX_ErrorNone) {
+ pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventCmdComplete,
+ OMX_CommandPortDisable, portIndex, NULL);
+ }
+ }
+
+EXIT:
+ if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != 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)))) {
+ 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, "input buffer(%p) was already entered!", pBuffer);
+ }
+ }
+ }
+
+ if (bFindBuffer == OMX_FALSE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "EmptyThisBuffer is failed : %p", 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->messageType = EXYNOS_OMX_CommandEmptyBuffer;
+ message->messageParam = (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", pOMXComponent, __FUNCTION__, pBuffer, pBuffer->nAllocLen, pBuffer->nFilledLen, pBuffer->nOffset);
+
+ 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)))) {
+ 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, "output buffer(%p) was already entered!", pBuffer);
+ }
+ }
+ }
+
+ if (bFindBuffer == OMX_FALSE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "FillThisBuffer is failed : %p", 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->messageType = EXYNOS_OMX_CommandFillBuffer;
+ message->messageParam = (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", pOMXComponent, __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)))) {
+ 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, "output buffer(%p) is firstly entered!", pBuffer);
+ }
+ }
+ }
+
+ if (bFindBuffer == OMX_FALSE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "FillThisBufferAgain is failed : %p", 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->messageType = EXYNOS_OMX_CommandFillBuffer;
+ message->messageParam = (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, "OMX_ErrorBadParameter, Line:%d", __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, "OMX_ErrorBadParameter, Line:%d", __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, "OMX_ErrorInsufficientResources, Line:%d", __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, "OMX_ErrorInsufficientResources, Line:%d", __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, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ Exynos_OSAL_Memset(pExynosInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM);
+
+ pExynosInputPort->bufferSemID = NULL;
+ pExynosInputPort->assignedBufferNum = 0;
+ pExynosInputPort->portState = OMX_StateMax;
+ pExynosInputPort->bIsPortFlushed = OMX_FALSE;
+ pExynosInputPort->bIsPortDisabled = OMX_FALSE;
+ pExynosInputPort->tunneledComponent = NULL;
+ pExynosInputPort->tunneledPort = 0;
+ pExynosInputPort->tunnelBufferNum = 0;
+ pExynosInputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
+ pExynosInputPort->tunnelFlags = 0;
+ pExynosInputPort->supportFormat = NULL;
+ pExynosInputPort->bNeedContigMem = OMX_FALSE;
+ pExynosInputPort->bDynamicDPBMode = OMX_FALSE;
+ pExynosInputPort->latestTimeStamp = DEFAULT_TIMESTAMP_VAL;
+
+ ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->loadedResource);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->unloadedResource);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ 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, "OMX_ErrorInsufficientResources, Line:%d", __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, "OMX_ErrorInsufficientResources, Line:%d", __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, "OMX_ErrorInsufficientResources, Line:%d", __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 = OMX_StateMax;
+ pExynosOutputPort->bIsPortFlushed = OMX_FALSE;
+ pExynosOutputPort->bIsPortDisabled = OMX_FALSE;
+ pExynosOutputPort->tunneledComponent = NULL;
+ pExynosOutputPort->tunneledPort = 0;
+ pExynosOutputPort->tunnelBufferNum = 0;
+ pExynosOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
+ pExynosOutputPort->tunnelFlags = 0;
+ pExynosOutputPort->supportFormat = NULL;
+ pExynosOutputPort->bNeedContigMem = OMX_FALSE;
+ pExynosOutputPort->bDynamicDPBMode = OMX_FALSE;
+ pExynosOutputPort->latestTimeStamp = DEFAULT_TIMESTAMP_VAL;
+
+ ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->loadedResource);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->unloadedResource);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ 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, "OMX_ErrorInsufficientResources, Line:%d", __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_SemaphoreTerminate(pExynosPort->loadedResource);
+ pExynosPort->loadedResource = NULL;
+ Exynos_OSAL_SemaphoreTerminate(pExynosPort->unloadedResource);
+ pExynosPort->unloadedResource = 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;
+
+ OMX_S32 countValue = 0;
+ 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;
+
+ if (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) {
+ pExynosComponent->abendState = OMX_TRUE;
+ for (i = 0; i < ALL_PORT_NUM; i++) {
+ pExynosPort = &pExynosComponent->pExynosPort[i];
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ }
+ Exynos_OSAL_SignalWait(pExynosComponent->abendStateEvent, DEF_MAX_WAIT_TIME);
+ Exynos_OSAL_SignalReset(pExynosComponent->abendStateEvent);
+ }
+
+ 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_SemaphoreTerminate(pExynosPort->loadedResource);
+ pExynosPort->loadedResource = NULL;
+ Exynos_OSAL_SemaphoreTerminate(pExynosPort->unloadedResource);
+ pExynosPort->unloadedResource = 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;
+ }
+
+ pData->dataLen = 0;
+ pData->usedDataLen = 0;
+ pData->remainDataLen = 0;
+ pData->nFlags = 0;
+ pData->timeStamp = 0;
+ pData->pPrivate = NULL;
+ pData->bufferHeader = NULL;
+
+EXIT:
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Shared_BufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_PLANE nPlane)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ if (nPlane == ONE_PLANE) {
+ /* Case of Shared Buffer, Only support singlePlaneBuffer */
+ pData->multiPlaneBuffer.dataBuffer[0] = pUseBuffer->bufferHeader->pBuffer;
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not support plane");
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+
+ 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:
+ return ret;
+}
+
+int Exynos_GetPlaneFromPort(EXYNOS_OMX_BASEPORT *pPort)
+{
+ int ret = 0;
+
+ if (pPort == NULL)
+ goto EXIT;
+
+ ret = pPort->processData.multiPlaneBuffer.validPlaneNum;
+
+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.multiPlaneBuffer.validPlaneNum = nPlaneNum;
+
+EXIT:
+ return ret;
+}
+
--- /dev/null
+/*
+ *
+ * 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)
+ * HyeYeon Chung (hyeon.chung@samsung.com)
+ * @version 2.0.0
+ * @history
+ * 2012.02.20 : Create
+ */
+
+#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 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];
+ int 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_DATA
+{
+ OMX_U32 validPlaneNum;
+ OMX_PTR dataBuffer[MAX_BUFFER_PLANE];
+ int fd[MAX_BUFFER_PLANE];
+} EXYNOS_OMX_MULTIPLANE_DATA;
+
+typedef struct _EXYNOS_OMX_DATA
+{
+ EXYNOS_OMX_MULTIPLANE_DATA multiPlaneBuffer;
+ 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;
+ OMX_STATETYPE portState;
+ OMX_HANDLETYPE loadedResource;
+ OMX_HANDLETYPE unloadedResource;
+ OMX_HANDLETYPE semWaitPortEnable[ALL_WAY_NUM];
+
+ OMX_BOOL bIsPortFlushed;
+ OMX_BOOL bIsPortDisabled;
+ 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;
+ OMX_BOOL bIsANBEnabled;
+ EXYNOS_ANB_TYPE eANBType;
+ OMX_BOOL bStoreMetaData;
+ OMX_BOOL bNeedContigMem;
+ OMX_BOOL bDynamicDPBMode;
+ 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;
+
+ /* for flush of Shared buffer scheme */
+ OMX_HANDLETYPE hAllCodecBufferReturnEvent;
+ OMX_HANDLETYPE hPortMutex;
+ EXYNOS_OMX_EXCEPTION_STATE exceptionFlag;
+
+ OMX_PARAM_PORTDEFINITIONTYPE newPortDefinition;
+ OMX_CONFIG_RECTTYPE newCropRectangle;
+ 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_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex);
+OMX_ERRORTYPE Exynos_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex);
+OMX_ERRORTYPE Exynos_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent);
+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);
+OMX_ERRORTYPE Exynos_Shared_BufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_PLANE nPlane);
+OMX_ERRORTYPE Exynos_OMX_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE *bufferHeader);
+OMX_ERRORTYPE Exynos_OMX_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE *bufferHeader);
+int Exynos_GetPlaneFromPort(EXYNOS_OMX_BASEPORT *pPort);
+OMX_ERRORTYPE Exynos_SetPlaneFromPort(EXYNOS_OMX_BASEPORT *pPort, int nPlaneNum);
+OMX_ERRORTYPE Exynos_SetPlaneToPort(EXYNOS_OMX_BASEPORT *pPort, int nPlaneNum);
+OMX_ERRORTYPE Exynos_OMX_FillThisBuffer(OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
+OMX_ERRORTYPE Exynos_OMX_FillThisBufferAgain(OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
+
+#ifdef __cplusplus
+};
+#endif
+
+
+#endif
--- /dev/null
+/*
+ *
+ * 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, "[%s][%s] can't use secure with non-secure",
+ __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, "[%s][%s] can't use secure with non-secure",
+ __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, "[%s][%s] has got a resource", __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;
+
+ 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;
+ }
+
+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;
+}
+
--- /dev/null
+/*
+ *
+ * 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
--- /dev/null
+
+ 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
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_VdecControl.c \
+ Exynos_OMX_Vdec.c
+
+LOCAL_MODULE := libExynosOMX_Vdec
+LOCAL_ARM_MODE := arm
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/dec \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+LOCAL_STATIC_LIBRARIES := libExynosVideoApi
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+ifeq ($(BOARD_USE_ANB), true)
+LOCAL_STATIC_LIBRARIES += libExynosOMX_OSAL
+LOCAL_CFLAGS += -DUSE_ANB
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_QOS_CTRL), true)
+LOCAL_CFLAGS += -DUSE_QOS_CTRL
+endif
+
+ifeq ($(BOARD_USE_STOREMETADATA), true)
+LOCAL_CFLAGS += -DUSE_STOREMETADATA
+endif
+
+ifeq ($(EXYNOS_OMX_SUPPORT_TUNNELING), true)
+LOCAL_CFLAGS += -DTUNNELING_SUPPORT
+endif
+
+include $(BUILD_STATIC_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+#ifdef USE_ANB
+#include "Exynos_OSAL_Android.h"
+#endif
+
+#include "csc.h"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG "EXYNOS_VIDEO_DEC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+inline 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];
+
+ 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;
+
+ switch((int)exynosOutputPort->portDefinition.format.video.eColorFormat) {
+ case OMX_COLOR_FormatYUV420Planar:
+ case OMX_COLOR_FormatYUV420SemiPlanar:
+ case OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace:
+ case OMX_SEC_COLOR_Format10bitYUV420SemiPlanar:
+ case OMX_SEC_COLOR_FormatNV12Tiled:
+ case OMX_SEC_COLOR_FormatYVU420Planar:
+ case OMX_SEC_COLOR_FormatNV21Linear:
+ if (width && height)
+ exynosOutputPort->portDefinition.nBufferSize = (ALIGN(width, 16) * ALIGN(height, 16) * 3) / 2;
+ break;
+ default:
+ if (width && height)
+ exynosOutputPort->portDefinition.nBufferSize = ALIGN(width, 16) * ALIGN(height, 16) * 2;
+ break;
+ }
+ }
+
+ return;
+}
+
+void Exynos_Output_SetSupportFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+ OMX_COLOR_FORMATTYPE ret = OMX_COLOR_FormatUnused;
+ 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. */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s, custom?:(%d)",pExynosComponent->componentName, IS_CUSTOM_COMPONENT(pExynosComponent->componentName));
+ 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;
+ }
+
+ /* 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_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, "Support Format[%d] : 0x%x", i, pOutputPort->supportFormat[i]);
+
+ pOutputPort->supportFormat[nLastIndex] = OMX_COLOR_FormatUnused;
+ }
+
+ return ;
+}
+
+OMX_ERRORTYPE Exynos_ResolutionUpdate(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 *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ pOutputPort->cropRectangle.nTop = pOutputPort->newCropRectangle.nTop;
+ pOutputPort->cropRectangle.nLeft = pOutputPort->newCropRectangle.nLeft;
+ pOutputPort->cropRectangle.nWidth = pOutputPort->newCropRectangle.nWidth;
+ pOutputPort->cropRectangle.nHeight = pOutputPort->newCropRectangle.nHeight;
+
+ pInputPort->portDefinition.format.video.nFrameWidth = pInputPort->newPortDefinition.format.video.nFrameWidth;
+ pInputPort->portDefinition.format.video.nFrameHeight = pInputPort->newPortDefinition.format.video.nFrameHeight;
+ pInputPort->portDefinition.format.video.nStride = pInputPort->newPortDefinition.format.video.nStride;
+ pInputPort->portDefinition.format.video.nSliceHeight = pInputPort->newPortDefinition.format.video.nSliceHeight;
+
+ pOutputPort->portDefinition.nBufferCountActual = pOutputPort->newPortDefinition.nBufferCountActual;
+ pOutputPort->portDefinition.nBufferCountMin = pOutputPort->newPortDefinition.nBufferCountMin;
+
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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);
+
+ return ret;
+}
+
+void Exynos_Free_CodecBuffers(
+ 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;
+ 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_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, "Failed to Alloc codec buffer");
+ 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, "Failed to Alloc plane");
+ 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_TRACE, "PORT[%d]: pMFCCodecBuffer[%d]->pVirAddr[%d]: 0x%x", nPortIndex, i, j, ppCodecBuffer[i]->pVirAddr[j]);
+ }
+
+ ppCodecBuffer[i]->dataSize = 0;
+ }
+
+ 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, "OMX_ErrorBadParameter : pExynosComponent(%p), nIndex(%p)", pExynosComponent, nIndex);
+ return;
+ }
+
+ /* 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_ERROR, "Can not find empty slot of timestamp. Timestamp slot is full.");
+
+ pExynosComponent->timeStamp[*nIndex] = timeStamp;
+ pExynosComponent->nFlags[*nIndex] = nFlags;
+ pExynosComponent->bTimestampSlotUsed[*nIndex] = OMX_TRUE;
+
+ 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, "OMX_ErrorBadParameter : pExynosComponent(%p), sCurrentTimestamp(%p)", pExynosComponent, sCurrentTimestamp);
+ return;
+ }
+
+ 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_ESSENTIAL, "[%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))) {
+ 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 old timestamp index for I-frame sync", pExynosComponent, __FUNCTION__);
+ }
+ }
+ }
+
+ if (sCurrentTimestamp->timeStamp == DEFAULT_TIMESTAMP_VAL)
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "the index of frame(%d) about I-frame is wrong", 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, "sCurrentTimestamp(%lld) is smaller than latestTimeStamp(%lld), uses latestTimeStamp",
+ sCurrentTimestamp->timeStamp, pExynosOutputPort->latestTimeStamp);
+ sCurrentTimestamp->timeStamp = pExynosOutputPort->latestTimeStamp;
+ }
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "uses latestTimeStamp(%lld)", pExynosOutputPort->latestTimeStamp);
+ sCurrentTimestamp->timeStamp = pExynosOutputPort->latestTimeStamp;
+ }
+
+ 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 == OMX_StateIdle) &&
+ (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];
+
+ /* 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;
+ 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 | BUFFER_ANBSHARE;
+#ifdef USE_ANB
+ pOutputPort->bIsANBEnabled = OMX_FALSE;
+#ifdef USE_STOREMETADATA
+ pOutputPort->bStoreMetaData = OMX_FALSE;
+#endif
+#endif
+ 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;
+
+ 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->multiPlaneBuffer.dataBuffer[i] = pCodecBuffer->pVirAddr[i];
+ pData->multiPlaneBuffer.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 *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ 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_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME);
+ 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 *dstOutputData)
+{
+ 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 *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_U32 copySize = 0;
+ DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
+ OMX_COLOR_FORMATTYPE eColorFormat = exynosOutputPort->portDefinition.format.video.eColorFormat;
+
+ FunctionIn();
+
+ void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
+ void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, };
+ void *pYUVBuf[MAX_BUFFER_PLANE] = {NULL, };
+
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+
+ unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+ unsigned int nDataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+
+ OMX_U32 nFrameWidth = 0, nFrameHeight = 0;
+ OMX_U32 nImageWidth = 0, nImageHeight = 0, stride = 0;
+
+ CSC_MEMTYPE csc_memType = CSC_MEMORY_USERPTR;
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+ CSC_ERRORCODE cscRet = CSC_ErrorNone;
+ unsigned int srcCacheable = 1, dstCacheable = 1;
+
+ pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
+
+ nFrameWidth = pBufferInfo->imageStride;
+ nFrameHeight = exynosOutputPort->portDefinition.format.video.nSliceHeight;
+
+ /* If crop info is used, width & height will be info about frame */
+ nImageWidth = pBufferInfo->imageWidth;
+ nImageHeight = pBufferInfo->imageHeight;
+
+ pSrcBuf[0] = dstOutputData->multiPlaneBuffer.dataBuffer[0];
+ pSrcBuf[1] = dstOutputData->multiPlaneBuffer.dataBuffer[1];
+ pSrcBuf[2] = dstOutputData->multiPlaneBuffer.dataBuffer[2];
+
+ if (exynosOutputPort->ePlaneType == PLANE_SINGLE) { /* from H/W. only Y addr is valid */
+ /* get a count of color plane */
+ int nPlaneCnt = Exynos_OSAL_GetPlaneCount(pBufferInfo->ColorFormat, PLANE_MULTIPLE);
+
+ if (nPlaneCnt == 2) { /* Semi-Planar : interleaved */
+ pSrcBuf[1] = (void *)(((char *)pSrcBuf[0]) +
+ ((pVideoDec->b10bitData == OMX_TRUE)? GET_10B_UV_OFFSET(nImageWidth, nImageHeight):GET_UV_OFFSET(nImageWidth, nImageHeight)));
+ } else if (nPlaneCnt == 3) { /* Planar */
+ pSrcBuf[1] = (void *)(((char *)pSrcBuf[0]) +
+ ((pVideoDec->b10bitData == OMX_TRUE)? GET_10B_CB_OFFSET(nImageWidth, nImageHeight):GET_CB_OFFSET(nImageWidth, nImageHeight)));
+ pSrcBuf[2] = (void *)(((char *)pSrcBuf[0]) +
+ ((pVideoDec->b10bitData == OMX_TRUE)? GET_10B_CR_OFFSET(nImageWidth, nImageHeight):GET_CR_OFFSET(nImageWidth, nImageHeight)));
+ }
+ }
+
+ /* calculate each plane info for the application */
+ Exynos_OSAL_GetPlaneSize(eColorFormat, PLANE_MULTIPLE, nImageWidth, nImageHeight, nDataLen, nAllocLen);
+
+ pYUVBuf[0] = (void *)((char *)pOutputBuf);
+ pYUVBuf[1] = (void *)((char *)pOutputBuf + nDataLen[0]);
+ pYUVBuf[2] = (void *)((char *)pOutputBuf + nDataLen[0] + nDataLen[1]);
+
+#ifdef USE_ANB
+ if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) {
+ if (OMX_ErrorNone != Exynos_OSAL_LockANBHandle(pOutputBuf, nImageWidth, nImageHeight, eColorFormat, &stride, planes)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OSAL_LockANBHandle() failed", __FUNCTION__);
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+
+ nImageWidth = stride;
+ outputUseBuffer->dataLen = sizeof(void *);
+
+ pYUVBuf[0] = (void *)planes[0].addr;
+ pYUVBuf[1] = (void *)planes[1].addr;
+ pYUVBuf[2] = (void *)planes[2].addr;
+ }
+#ifdef USE_STOREMETADATA
+ else if (exynosOutputPort->bStoreMetaData == OMX_TRUE) {
+ if (OMX_ErrorNone != Exynos_OSAL_LockMetaData(pOutputBuf, nImageWidth, nImageHeight, eColorFormat, &stride, planes)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OSAL_LockMetaData() failed", __FUNCTION__);
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+
+ nImageWidth = stride;
+ outputUseBuffer->dataLen = sizeof(void *);
+
+ pYUVBuf[0] = (void *)planes[0].addr;
+ pYUVBuf[1] = (void *)planes[1].addr;
+ pYUVBuf[2] = (void *)planes[2].addr;
+ }
+#endif
+#endif
+
+ if (pVideoDec->exynos_codec_checkFormatSupport(pExynosComponent, eColorFormat) == OMX_TRUE) {
+ csc_memType = CSC_MEMORY_MFC; /* to remove stride value */
+ if (pVideoDec->csc_set_format == OMX_FALSE) {
+ csc_set_method(pVideoDec->csc_handle, CSC_METHOD_SW);
+ csc_set_src_format(
+ pVideoDec->csc_handle, /* handle */
+ nFrameWidth, /* width */
+ nFrameHeight, /* height */
+ 0, /* crop_left */
+ 0, /* crop_right */
+ nImageWidth, /* crop_width */
+ nImageHeight, /* crop_height */
+ Exynos_OSAL_OMX2HALPixelFormat(
+ pBufferInfo->ColorFormat, exynosOutputPort->ePlaneType), /* color_format */
+ srcCacheable); /* cacheable */
+ }
+ } else {
+ csc_get_method(pVideoDec->csc_handle, &csc_method);
+ if (csc_method == CSC_METHOD_HW) {
+ srcCacheable = 0;
+ dstCacheable = 0;
+ }
+
+#ifdef USE_DMA_BUF
+ if (csc_method == CSC_METHOD_HW) {
+ csc_memType = CSC_MEMORY_DMABUF;
+
+ pSrcBuf[0] = INT_TO_PTR(dstOutputData->multiPlaneBuffer.fd[0]);
+ pSrcBuf[1] = INT_TO_PTR(dstOutputData->multiPlaneBuffer.fd[1]);
+ pSrcBuf[2] = INT_TO_PTR(dstOutputData->multiPlaneBuffer.fd[2]);
+
+#ifdef USE_ANB
+ if ((exynosOutputPort->bIsANBEnabled == OMX_TRUE) ||
+ (exynosOutputPort->bStoreMetaData == OMX_TRUE)) {
+ pYUVBuf[0] = INT_TO_PTR(planes[0].fd);
+ pYUVBuf[1] = INT_TO_PTR(planes[1].fd);
+ pYUVBuf[2] = INT_TO_PTR(planes[2].fd);
+ } else {
+ pYUVBuf[0] = INT_TO_PTR(Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf));
+ pYUVBuf[1] = NULL;
+ pYUVBuf[2] = NULL;
+ }
+#else
+ pYUVBuf[0] = INT_TO_PTR(Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf));
+ pYUVBuf[1] = NULL;
+ pYUVBuf[2] = NULL;
+#endif
+ }
+#endif
+
+ if (pVideoDec->csc_set_format == OMX_FALSE) {
+ csc_set_src_format(
+ pVideoDec->csc_handle, /* handle */
+ nFrameWidth, /* width */
+ nFrameHeight, /* height */
+ 0, /* crop_left */
+ 0, /* crop_right */
+ nImageWidth, /* crop_width */
+ nImageHeight, /* crop_height */
+ Exynos_OSAL_OMX2HALPixelFormat(
+ pBufferInfo->ColorFormat, exynosOutputPort->ePlaneType), /* color_format */
+ srcCacheable); /* cacheable */
+ }
+ }
+
+ if (pVideoDec->csc_set_format == OMX_FALSE) {
+ unsigned int pixelFormat = Exynos_OSAL_OMX2HALPixelFormat(eColorFormat, PLANE_SINGLE_USER);
+
+ if ((IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) &&
+ (nFrameWidth != nImageWidth) &&
+ (csc_method == CSC_METHOD_HW)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "H/W CSC isn't supported by the constraint (w:%d/h:%d)", nImageWidth, nImageHeight);
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+
+#ifdef USE_ANB
+ if (exynosOutputPort->bIsANBEnabled == OMX_TRUE)
+ pixelFormat = Exynos_OSAL_OMX2HALPixelFormat(eColorFormat, exynosOutputPort->ePlaneType);
+#ifdef USE_STOREMETADATA
+ else if (exynosOutputPort->bStoreMetaData == OMX_TRUE)
+ pixelFormat = Exynos_OSAL_OMX2HALPixelFormat(eColorFormat, exynosOutputPort->ePlaneType);
+#endif
+#endif
+
+ csc_set_dst_format(
+ pVideoDec->csc_handle, /* handle */
+ nImageWidth, /* width */
+ nImageHeight, /* height */
+ 0, /* crop_left */
+ 0, /* crop_right */
+ nImageWidth, /* crop_width */
+ nImageHeight, /* crop_height */
+ pixelFormat, /* color_format */
+ dstCacheable); /* 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;
+ }
+
+ csc_set_src_buffer(
+ pVideoDec->csc_handle, /* handle */
+ pSrcBuf,
+ csc_memType); /* YUV Addr or FD */
+ csc_set_dst_buffer(
+ pVideoDec->csc_handle, /* handle */
+ pYUVBuf,
+ csc_memType); /* YUV Addr or FD */
+ cscRet = csc_convert(pVideoDec->csc_handle);
+ if (cscRet != CSC_ErrorNone)
+ ret = OMX_FALSE;
+ else
+ ret = OMX_TRUE;
+
+#ifdef USE_ANB
+ if (exynosOutputPort->bIsANBEnabled == OMX_TRUE)
+ Exynos_OSAL_UnlockANBHandle(pOutputBuf);
+#ifdef USE_STOREMETADATA
+ else if (exynosOutputPort->bStoreMetaData == OMX_TRUE)
+ Exynos_OSAL_UnlockMetaData(pOutputBuf);
+#endif
+#endif
+
+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_U32 copySize = 0;
+ OMX_BYTE checkInputStream = NULL;
+ OMX_U32 checkInputStreamLen = 0;
+
+ FunctionIn();
+
+ if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+ if ((srcInputData->multiPlaneBuffer.dataBuffer[0] == NULL) ||
+ (srcInputData->pPrivate == NULL)) {
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+ }
+
+ if (inputUseBuffer->dataValid == OMX_TRUE) {
+ if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE);
+
+ if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) {
+ int ionFD = -1;
+ OMX_PTR dataBuffer = NULL;
+
+ /* caution : data loss */
+ ionFD = PTR_TO_INT(srcInputData->multiPlaneBuffer.dataBuffer[0]);
+
+ dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, ionFD);
+ if (dataBuffer == NULL) {
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+
+ srcInputData->multiPlaneBuffer.fd[0] = ionFD;
+ srcInputData->multiPlaneBuffer.dataBuffer[0] = dataBuffer;
+ } else {
+ srcInputData->multiPlaneBuffer.fd[0] =
+ Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
+ srcInputData->multiPlaneBuffer.dataBuffer[0]);
+ }
+
+ /* reset dataBuffer */
+ Exynos_ResetDataBuffer(inputUseBuffer);
+ } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+ checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
+ checkInputStreamLen = inputUseBuffer->remainDataLen;
+
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+
+ copySize = checkInputStreamLen;
+
+ if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
+ if (copySize > 0) {
+ Exynos_OSAL_Memcpy((OMX_PTR)((char *)srcInputData->multiPlaneBuffer.dataBuffer[0] + srcInputData->dataLen),
+ checkInputStream, 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;
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ ret = OMX_FALSE;
+ }
+
+ Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
+ }
+
+ if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] bSaveFlagEOS : OMX_TRUE", pExynosComponent, __FUNCTION__);
+ if (srcInputData->dataLen != 0)
+ pExynosComponent->bBehaviorEOS = OMX_TRUE;
+ }
+
+ 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, srcInputData->timeStamp / 1E6);
+ }
+
+ ret = OMX_TRUE;
+ }
+
+EXIT:
+
+ 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_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_U32 copySize = 0;
+ DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
+
+ FunctionIn();
+
+ if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+#ifdef USE_ANB
+ if ((exynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
+ (exynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone)
+ outputUseBuffer->dataValid = OMX_TRUE;
+ } else {
+ if (Exynos_Shared_DataToANBBuffer(dstOutputData, outputUseBuffer, exynosOutputPort) == OMX_ErrorNone) {
+ outputUseBuffer->dataValid = OMX_TRUE;
+ } else {
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+ }
+#else
+ if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone)
+ outputUseBuffer->dataValid = OMX_TRUE;
+#endif
+ }
+
+ if (outputUseBuffer->dataValid == OMX_TRUE) {
+ if ((pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) &&
+ ((dstOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
+ if ((pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp) &&
+ (pExynosComponent->checkTimeStamp.nStartFlags ==
+ (dstOutputData->nFlags & ~(OMX_BUFFERFLAG_SYNCFRAME | OMX_BUFFERFLAG_DATACORRUPT)))) {
+ 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", pExynosComponent, __FUNCTION__);
+ 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 timestame after seeking", pExynosComponent, __FUNCTION__);
+ goto EXIT;
+ }
+
+ if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) &&
+ (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+ copySize = dstOutputData->remainDataLen;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"copySize: %d", copySize);
+
+ outputUseBuffer->dataLen += copySize;
+ outputUseBuffer->remainDataLen += copySize;
+ outputUseBuffer->nFlags = dstOutputData->nFlags;
+ outputUseBuffer->timeStamp = dstOutputData->timeStamp;
+
+ if (outputUseBuffer->remainDataLen > 0) {
+ ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData);
+ } else {
+ ret = OMX_TRUE;
+ }
+
+ if (ret == OMX_TRUE) {
+ if ((outputUseBuffer->remainDataLen > 0) ||
+ ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
+ (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+ Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
+ }
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "csc_convert Error");
+ 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, "output buffer is smaller than decoded data size Out Length");
+ 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) == 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;
+ OMX_BOOL bValidCodecData = 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_SemaphoreWait(exynosInputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
+ continue;
+ }
+
+ while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
+ (!pVideoDec->bExitBufferProcessThread)) {
+ Exynos_OSAL_SleepMillisec(0);
+
+ if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort)) ||
+ ((exynosOutputPort->exceptionFlag != GENERAL_STATE) &&
+ (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorInputDataDecodeYet) ||
+ ((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorNoneSrcSetupFinish))) ||
+ (exynosOutputPort->exceptionFlag == INVALID_STATE))
+ break;
+ if (exynosInputPort->portState != OMX_StateIdle)
+ break;
+
+ Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
+ if ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) {
+ if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+ OMX_PTR codecBuffer;
+ if ((pSrcInputData->multiPlaneBuffer.dataBuffer[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)) {
+ 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_SemaphoreWait(exynosInputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
+ 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(&srcOutputData, srcOutputUseBuffer);
+ 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_SemaphoreWait(exynosOutputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
+ continue;
+ }
+
+ while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
+ (!pVideoDec->bExitBufferProcessThread)) {
+ Exynos_OSAL_SleepMillisec(0);
+
+ if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
+ (!CHECK_PORT_POPULATED(exynosOutputPort)) ||
+ (exynosOutputPort->exceptionFlag != GENERAL_STATE))
+ break;
+ if (exynosOutputPort->portState != OMX_StateIdle)
+ 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;
+ }
+#ifdef USE_ANB
+ if ((exynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
+ (exynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE);
+ } else {
+ ret = Exynos_Shared_ANBBufferToData(dstInputUseBuffer, &dstInputData, exynosOutputPort);
+ if (ret != OMX_ErrorNone) {
+ dstInputUseBuffer->dataValid = OMX_FALSE;
+ Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+ break;
+ }
+
+ OMX_PTR pANBHandle = NULL;
+#ifdef USE_STOREMETADATA
+ if (exynosOutputPort->bStoreMetaData == OMX_TRUE) {
+ OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL};
+
+ ret = Exynos_OSAL_GetInfoFromMetaData(dstInputData.bufferHeader->pBuffer, ppBuf);
+ if (ret != OMX_ErrorNone) {
+ /* actually, the error will be happen at ANBBufferToData, if metadata is invalid. */
+ dstInputUseBuffer->dataValid = OMX_FALSE;
+ Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+ break;
+ }
+
+ pANBHandle = ppBuf[0];
+ } else
+#endif
+ {
+ pANBHandle = dstInputData.bufferHeader->pBuffer;
+ }
+
+ Exynos_OSAL_RefANB_Increase(pVideoDec->hRefHandle, pANBHandle, exynosOutputPort->ePlaneType);
+ }
+#else
+ Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE);
+#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_SemaphoreWait(exynosOutputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
+ 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_ANB
+ 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 > -1) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "decRefCnt-FD:%d", pBufferInfo->PDSB.dpbFD[i].fd);
+ Exynos_OSAL_RefANB_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;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+ EXYNOS_OMX_MESSAGE *message = 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;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ 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;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+ EXYNOS_OMX_MESSAGE *message = 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;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ 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;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+ EXYNOS_OMX_MESSAGE *message = 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;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ 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;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+ EXYNOS_OMX_MESSAGE *message = 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;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ 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;
+ unsigned int i = 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_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);
+
+ pVideoDec->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
+ pVideoDec->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(pVideoDec->hSrcOutputThread);
+ pVideoDec->hSrcOutputThread = NULL;
+ Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX], 0);
+
+ pVideoDec->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
+ pVideoDec->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(pVideoDec->hDstOutputThread);
+ pVideoDec->hDstOutputThread = NULL;
+ Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX], 0);
+
+ 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;
+
+ 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) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_Port_Constructor(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ pVideoDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
+ if (pVideoDec == NULL) {
+ Exynos_OMX_Port_Destructor(pOMXComponent);
+ Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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->b10bitData = OMX_FALSE;
+ pVideoDec->bQosChanged = OMX_FALSE;
+ pVideoDec->nQosRatio = 0;
+ pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec;
+
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ pExynosComponent->bMultiThreadProcess = OMX_TRUE;
+
+ /* 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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));
+ Exynos_OSAL_Memset(((char *)pExynosPort->processData.extInfo), 0, sizeof(DECODE_CODEC_EXTRA_BUFFERINFO));
+
+ int i = 0;
+ DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
+ pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)(pExynosPort->processData.extInfo);
+ for (i = 0; i < VIDEO_BUFFER_MAX_NUM; i++) {
+ pBufferInfo->PDSB.dpbFD[i].fd = -1;
+ pBufferInfo->PDSB.dpbFD[i].fd1 = -1;
+ pBufferInfo->PDSB.dpbFD[i].fd2 = -1;
+ }
+
+ 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_ANB
+ pVideoDec->hRefHandle = Exynos_OSAL_RefANB_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) {
+ 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;
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+#ifdef USE_ANB
+ Exynos_OSAL_RefANB_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;
+}
--- /dev/null
+/*
+ *
+ * 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 1
+#define MAX_VIDEO_OUTPUTBUFFER_NUM 2
+
+#define DEFAULT_FRAME_WIDTH 176
+#define DEFAULT_FRAME_HEIGHT 144
+
+#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
+#define DEFAULT_MFC_INPUT_BUFFER_SIZE MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2
+
+/* 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 * 1080 * 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 2 /* I420P, NV12 */
+#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 */
+ int fd[MAX_BUFFER_PLANE]; /* buffer FD */
+ int dataSize; /* total data length */
+} CODEC_DEC_BUFFER;
+
+typedef struct _DECODE_CODEC_EXTRA_BUFFERINFO
+{
+ /* For Decode Output */
+ OMX_U32 imageWidth;
+ OMX_U32 imageHeight;
+ OMX_U32 imageStride;
+ 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 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 */
+ OMX_BOOL b10bitData; /* true: 10bit decoding, false: 8bit decoding */
+ OMX_BOOL bQosChanged;
+ OMX_U32 nQosRatio;
+ 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);
+
+#if 0 /* unused code */
+ int (*exynos_checkInputFrame) (OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag,
+ OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame);
+ OMX_ERRORTYPE (*exynos_codec_getCodecInputPrivateData) (OMX_PTR codecBuffer, OMX_PTR *addr, OMX_U32 *size);
+#endif
+ 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
+
+inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent);
+void Exynos_Output_SetSupportFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent);
+OMX_ERRORTYPE Exynos_ResolutionUpdate(OMX_COMPONENTTYPE *pOMXComponent);
+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
--- /dev/null
+/*
+ *
+ * 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)
+ * @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_Thread.h"
+#include "Exynos_OSAL_Semaphore.h"
+#include "Exynos_OSAL_Mutex.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_SharedMemory.h"
+
+#ifdef USE_ANB
+#include "Exynos_OSAL_Android.h"
+#endif
+
+#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) {
+ 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;
+
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+ if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+ if (pExynosPort->portState != OMX_StateIdle) {
+ ret = OMX_ErrorIncorrectStateOperation;
+ goto EXIT;
+ }
+
+ if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+#ifdef USE_ANB
+ if (pExynosPort->bIsANBEnabled == OMX_TRUE) {
+ OMX_U32 nAllocLen;
+ OMX_U32 width, height;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "useAndroidNativeBuffer2");
+ pExynosPort->eANBType = NATIVE_GRAPHIC_BUFFER2;
+
+ width = pExynosPort->portDefinition.format.video.nFrameWidth;
+ height = pExynosPort->portDefinition.format.video.nFrameHeight;
+
+ nAllocLen = ALIGN(width, 16) * ALIGN(height, 16) + \
+ ALIGN(width / 2, 16) * ALIGN(height / 2, 16) * 2;
+
+ ret = useAndroidNativeBuffer(pExynosPort, ppBufferHdr, nPortIndex, pAppPrivate, nAllocLen, pBuffer);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: useAndroidNativeBuffer2 is failed: err=0x%x", __func__, ret);
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ } else
+#endif
+ {
+ temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
+ if (temp_bufferHeader == NULL) {
+ 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++;
+ if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+ pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ }
+ *ppBufferHdr = temp_bufferHeader;
+ ret = OMX_ErrorNone;
+ 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;
+ int temp_buffer_fd = -1;
+ OMX_U32 i = 0;
+ MEMORY_TYPE mem_type = NORMAL_MEMORY;
+
+ 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;
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+ if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+/*
+ if (pExynosPort->portState != OMX_StateIdle ) {
+ 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;
+
+ temp_buffer = Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nSizeBytes, mem_type);
+ if (temp_buffer == NULL) {
+ 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_SharedMemory_Free(pVideoDec->hSharedMemory, temp_buffer);
+ 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)
+ temp_bufferHeader->pBuffer = INT_TO_PTR(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++;
+ if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+ pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ }
+ *ppBuffer = temp_bufferHeader;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(temp_bufferHeader);
+ Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, temp_buffer);
+
+ 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_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL;
+ OMX_U8 *temp_buffer = NULL;
+ OMX_U32 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;
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+ if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if (((pExynosPort->portState != OMX_StateLoaded) &&
+ (pExynosPort->portState != OMX_StateInvalid)) &&
+ (pExynosPort->portDefinition.bEnabled != OMX_FALSE)) {
+ (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent,
+ pExynosComponent->callbackData,
+ (OMX_U32)OMX_EventError,
+ (OMX_U32)OMX_ErrorPortUnpopulated,
+ nPortIndex, NULL);
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ for (i = 0; i < /*pExynosPort->portDefinition.nBufferCountActual*/MAX_BUFFER_NUM; i++) {
+ if (((pExynosPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pExynosPort->extendBufferHeader[i].OMXBufferHeader != NULL)) {
+ if (pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer == pBufferHdr->pBuffer) {
+ if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) {
+ if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) &&
+ (nPortIndex == INPUT_PORT_INDEX)) {
+ /* caution : data loss */
+ int ionFD = PTR_TO_INT(pExynosPort->extendBufferHeader[i].OMXBufferHeader->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, pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer);
+ }
+ pExynosPort->extendBufferHeader[i].OMXBufferHeader->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(pExynosPort->extendBufferHeader[i].OMXBufferHeader);
+ 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 == 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosPort->unloadedResource signal set");
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->unloadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ pExynosPort->portDefinition.bPopulated = OMX_FALSE;
+ }
+ }
+
+ 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;
+
+ FunctionIn();
+
+ *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);
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
+{
+ 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 = NULL;
+ OMX_BUFFERHEADERTYPE *bufferHeader = NULL;
+ EXYNOS_OMX_DATABUFFER *pDataPortBuffer[2] = {NULL, NULL};
+ EXYNOS_OMX_MESSAGE *message = NULL;
+ OMX_U32 flushNum = 0;
+ OMX_S32 semValue = 0;
+ int i = 0;
+ FunctionIn();
+
+ 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->messageType != 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 (pExynosComponent->bMultiThreadProcess == OMX_TRUE) {
+ 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) {
+#ifdef USE_ANB
+ if (pExynosPort->bIsANBEnabled == OMX_TRUE)
+ Exynos_OSAL_UnlockANBHandle(pExynosPort->processData.bufferHeader->pBuffer);
+#ifdef USE_STOREMETADATA
+ else if (pExynosPort->bStoreMetaData == OMX_TRUE)
+ Exynos_OSAL_UnlockMetaData(pExynosPort->processData.bufferHeader->pBuffer);
+#endif
+#endif
+ 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) {
+#ifdef USE_ANB
+ if (pExynosPort->bIsANBEnabled == OMX_TRUE)
+ Exynos_OSAL_UnlockANBHandle(pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer);
+#ifdef USE_STOREMETADATA
+ else if (pExynosPort->bStoreMetaData == OMX_TRUE)
+ Exynos_OSAL_UnlockMetaData(pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer);
+#endif
+#endif
+ Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->extendBufferHeader[i].OMXBufferHeader);
+ } else if (portIndex == INPUT_PORT_INDEX) {
+ Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->extendBufferHeader[i].OMXBufferHeader);
+ }
+ }
+ }
+ }
+ } else {
+ Exynos_ResetCodecData(&pExynosPort->processData);
+ }
+
+#ifdef USE_ANB
+ if ((pExynosPort->bufferProcessType == BUFFER_SHARE) &&
+ (portIndex == OUTPUT_PORT_INDEX))
+ Exynos_OSAL_RefANB_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->multiPlaneBuffer.dataBuffer[0] == 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 {
+ /* pre-processing is failed : 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);
+ }
+
+ /* 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};
+ 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;
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush start, port:%d", nPortIndex);
+
+ pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_TRUE;
+
+ if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
+ Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
+ } else {
+ Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+ Exynos_OMX_GetFlushBuffer(pExynosPort, flushPortBuffer);
+
+ if (pExynosComponent->pExynosPort[nPortIndex].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);
+ 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 (pVideoDec->bReconfigDPB == OMX_TRUE) {
+ ret = pVideoDec->exynos_codec_reconfigAllBuffers(pOMXComponent, nPortIndex);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_MutexUnlock(flushPortBuffer[1]->bufferMutex);
+ Exynos_OSAL_MutexUnlock(flushPortBuffer[0]->bufferMutex);
+ 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;
+ }
+
+ pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_FALSE;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush EventCmdComplete, port:%d", nPortIndex);
+ if (bEvent == OMX_TRUE)
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventCmdComplete,
+ OMX_CommandFlush, nPortIndex, NULL);
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_CountReset(pExynosPort->hBufferCount);
+#endif
+ }
+ Exynos_OSAL_MutexUnlock(flushPortBuffer[1]->bufferMutex);
+ Exynos_OSAL_MutexUnlock(flushPortBuffer[0]->bufferMutex);
+
+EXIT:
+ if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__);
+ pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError,
+ ret, 0, NULL);
+ }
+
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_InputBufferReturn(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ EXYNOS_OMX_DATABUFFER *pDataBuffer)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ OMX_BUFFERHEADERTYPE *pBufferHdr = NULL;
+
+ FunctionIn();
+
+ 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 = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_MESSAGE *message = NULL;
+ EXYNOS_OMX_DATABUFFER *inputUseBuffer = NULL;
+
+ FunctionIn();
+
+ inputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
+
+ if (pExynosComponent->currentState != OMX_StateExecuting) {
+ 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_SemaphoreWait(pExynosPort->bufferSemID);
+
+ if (inputUseBuffer->dataValid != OMX_TRUE) {
+ message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (message == NULL) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+ if (message->messageType == EXYNOS_OMX_CommandFakeBuffer) {
+ Exynos_OSAL_Free(message);
+ ret = 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, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", 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 = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ OMX_BUFFERHEADERTYPE *pBufferHdr = pDataBuffer->bufferHeader;
+
+ FunctionIn();
+
+ if (pBufferHdr != NULL) {
+ pBufferHdr->nFilledLen = pDataBuffer->remainDataLen;
+ pBufferHdr->nOffset = 0;
+ pBufferHdr->nFlags = pDataBuffer->nFlags;
+ pBufferHdr->nTimeStamp = pDataBuffer->timeStamp;
+
+ if ((pOutputPort->bStoreMetaData == OMX_TRUE) &&
+ (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,"event OMX_BUFFERFLAG_EOS!!!");
+ 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 = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_OMX_MESSAGE *message = NULL;
+ EXYNOS_OMX_DATABUFFER *outputUseBuffer = NULL;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosPort))){
+ Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+ if (outputUseBuffer->dataValid != OMX_TRUE) {
+ message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (message == NULL) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+ if (message->messageType == EXYNOS_OMX_CommandFakeBuffer) {
+ Exynos_OSAL_Free(message);
+ ret = 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 = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_OMX_MESSAGE *message = NULL;
+
+ FunctionIn();
+
+ if (pExynosComponent->currentState != OMX_StateExecuting) {
+ retBuffer = NULL;
+ goto EXIT;
+ } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosPort))){
+ Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+
+ message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (message == NULL) {
+ retBuffer = NULL;
+ goto EXIT;
+ }
+ if (message->messageType == 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();
+
+ pExynosPort= &pExynosComponent->pExynosPort[PortIndex];
+
+ if (data == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ 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();
+
+ pExynosPort = &pExynosComponent->pExynosPort[PortIndex];
+ Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID);
+ 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();
+
+ 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_BASEPORT *pExynosPort = 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 (ComponentParameterStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ 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) {
+ goto EXIT;
+ }
+
+ portParam->nPorts = pExynosComponent->portParam.nPorts;
+ portParam->nStartPortNumber = pExynosComponent->portParam.nStartPortNumber;
+ ret = OMX_ErrorNone;
+ }
+ break;
+ case OMX_IndexParamVideoPortFormat:
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+ OMX_U32 nPortIndex = pPortFormat->nPortIndex;
+ OMX_U32 nIndex = pPortFormat->nIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ 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) {
+ 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;
+
+#ifdef USE_ANB
+ if ((pExynosPort->bIsANBEnabled == OMX_FALSE) &&
+ (pExynosPort->bStoreMetaData == OMX_FALSE))
+#endif
+ {
+ if (pExynosPort->supportFormat[nIndex] == OMX_COLOR_FormatUnused) {
+ ret = OMX_ErrorNoMore;
+ goto EXIT;
+ }
+ pPortFormat->eColorFormat = pExynosPort->supportFormat[nIndex];
+ }
+#ifdef USE_ANB
+ else {
+ if (nIndex > 0) {
+ ret = OMX_ErrorNoMore;
+ goto EXIT;
+ }
+
+ bFormatSupport = pVideoDec->exynos_codec_checkFormatSupport(pExynosComponent, (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled);
+ 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_ANB
+ case OMX_IndexParamGetAndroidNativeBuffer:
+ {
+ ret = Exynos_OSAL_GetAndroidParameter(hComponent, nParamIndex, ComponentParameterStructure);
+ }
+ break;
+ case OMX_IndexParamPortDefinition:
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+ OMX_U32 portIndex = portDefinition->nPortIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+ ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ /* at this point, GetParameter has done all the verification, we
+ * just dereference things directly here
+ */
+ pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+ if ((pExynosPort->bIsANBEnabled == OMX_TRUE) ||
+ (pExynosPort->bStoreMetaData == OMX_TRUE)) {
+ if (pVideoDec->b10bitData == OMX_TRUE) {
+ portDefinition->format.video.eColorFormat =
+ (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HALPixelFormat((OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_Format10bitYUV420SemiPlanar, pExynosPort->ePlaneType);
+ } else {
+ portDefinition->format.video.eColorFormat =
+ (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HALPixelFormat(portDefinition->format.video.eColorFormat, pExynosPort->ePlaneType);
+ }
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] portDefinition->format.video.eColorFormat: 0x%x", pExynosComponent, __FUNCTION__, portDefinition->format.video.eColorFormat);
+ }
+ }
+ break;
+#endif
+ case OMX_IndexVendorNeedContigMemory:
+ {
+ EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *pPortMemType = (EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *)ComponentParameterStructure;
+ OMX_U32 nPortIndex = pPortMemType->nPortIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort;
+
+ 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)
+ goto EXIT;
+
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+ pPortMemType->bNeedContigMem = pExynosPort->bNeedContigMem;
+ }
+ break;
+ case OMX_IndexExynosParamCorruptedHeader:
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ 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_BASEPORT *pExynosPort = 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 (ComponentParameterStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
+ OMX_U32 nPortIndex = pPortFormat->nPortIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+ if (ret != OMX_ErrorNone) {
+ 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;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "nPortIndex:%d, pPortFormat->eColorFormat:0x%x", nPortIndex, pPortFormat->eColorFormat);
+ }
+ }
+ break;
+ case OMX_IndexParamPortDefinition:
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
+ OMX_U32 portIndex = pPortDefinition->nPortIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ 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) {
+ 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_ANB
+ /* 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_ANB // Modified by Google engineer
+ /* should not affect the format since in ANB case, the caller
+ * is providing us a HAL format */
+ if ((pExynosPort->bIsANBEnabled == OMX_TRUE) ||
+ (pExynosPort->bStoreMetaData == OMX_TRUE)) {
+ 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) {
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ pExynosOutputPort->portDefinition.format.video.nFrameWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
+ pExynosOutputPort->portDefinition.format.video.nFrameHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
+ pExynosOutputPort->portDefinition.format.video.nStride = realWidth;
+ pExynosOutputPort->portDefinition.format.video.nSliceHeight = realHeight;
+
+ if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) {
+ if ((pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) &&
+ (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;
+ } else if ((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) &&
+ (pExynosPort->portDefinition.nBufferSize > MAX_SECURE_INPUT_BUFFER_SIZE)) {
+ pExynosPort->portDefinition.nBufferSize = MAX_SECURE_INPUT_BUFFER_SIZE;
+ }
+ }
+
+ switch ((int)pExynosOutputPort->portDefinition.format.video.eColorFormat) {
+ case OMX_COLOR_FormatYUV420Planar:
+ case OMX_COLOR_FormatYUV420SemiPlanar:
+ case OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace:
+ case OMX_SEC_COLOR_Format10bitYUV420SemiPlanar:
+ case OMX_SEC_COLOR_FormatNV12Tiled:
+ pExynosOutputPort->portDefinition.nBufferSize = (ALIGN(realWidth, 16) * ALIGN(realHeight, 16) * 3) / 2;
+ break;
+ default:
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Color format is not support!! use default YUV size!!");
+ ret = OMX_ErrorUnsupportedSetting;
+ break;
+ }
+ }
+ }
+ break;
+#ifdef USE_ANB
+ case OMX_IndexParamEnableAndroidBuffers:
+ case OMX_IndexParamUseAndroidNativeBuffer:
+#ifdef USE_STOREMETADATA
+ case OMX_IndexParamStoreMetaDataBuffer:
+#endif
+ {
+ ret = Exynos_OSAL_SetAndroidParameter(hComponent, nIndex, ComponentParameterStructure);
+ }
+ break;
+#endif
+ case OMX_IndexVendorNeedContigMemory:
+ {
+ EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *pPortMemType = (EXYNOS_OMX_VIDEO_PARAM_PORTMEMTYPE *)ComponentParameterStructure;
+ OMX_U32 nPortIndex = pPortMemType->nPortIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort;
+
+ 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)
+ 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_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ goto EXIT;
+
+ pVideoDec->bDTSMode = pDTSParam->bDTSMode;
+ }
+ break;
+ case OMX_IndexParamEnableThumbnailMode:
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ 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_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ 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;
+
+ 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 (pComponentConfigStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+ case OMX_IndexVendorGetBufferFD:
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ goto EXIT;
+
+ pBufferInfo->fd = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pBufferInfo->pVirAddr);
+ }
+ break;
+ case OMX_IndexExynosConfigPTSMode: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+ *((OMX_BOOL *)pComponentConfigStructure) = (pVideoDec->bDTSMode == OMX_TRUE)? OMX_FALSE:OMX_TRUE;
+ }
+ break;
+ 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)) {
+ 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 (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+ case OMX_IndexVendorThumbnailMode: /* It is for backward compatibility */
+ {
+ pVideoDec->bThumbnailMode = *((OMX_BOOL *)pComponentConfigStructure);
+
+ ret = OMX_ErrorNone;
+ }
+ 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)
+ goto EXIT;
+
+ xFramerate = pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.xFramerate;
+ if ((xFramerate >> 16) == 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : xFramerate is zero. can't calculate QosRatio", __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;
+#ifdef USE_QOS_CTRL
+ case OMX_IndexVendorSetQosRatio: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *pQosInfo = (EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *)pComponentConfigStructure;
+
+ ret = Exynos_OMX_Check_SizeVersion(pQosInfo, sizeof(EXYNOS_OMX_VIDEO_CONFIG_QOSINFO));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ pVideoDec->nQosRatio = pQosInfo->nQosRatio;
+ pVideoDec->bQosChanged = OMX_TRUE;
+
+ ret = OMX_ErrorNone;
+ }
+ break;
+#endif
+ case OMX_IndexExynosConfigPTSMode: /* MSRND */
+ {
+ pVideoDec->bDTSMode = ((*((OMX_BOOL *)pComponentConfigStructure)) == OMX_TRUE)? OMX_FALSE:OMX_TRUE;
+ ret = OMX_ErrorNone;
+ }
+ break;
+ 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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ 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_CONFIG_OPERATING_RATE) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigOperatingRate;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+#ifdef USE_QOS_CTRL
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_SET_QOS_RATIO) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorSetQosRatio;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+#endif
+
+#ifdef USE_ANB
+ 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_GET_ANB) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamGetAndroidNativeBuffer;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_USE_ANB) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamUseAndroidNativeBuffer;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_USE_ANB2) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamUseAndroidNativeBuffer2;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+#endif
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_THUMBNAIL) == 0) {
+ *pIndexType = OMX_IndexVendorThumbnailMode;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) {
+ *pIndexType = OMX_IndexParamEnableThumbnailMode;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+#ifdef USE_STOREMETADATA
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamStoreMetaDataBuffer;
+ goto EXIT;
+ }
+#endif
+
+ 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;
+}
+
+#ifdef USE_ANB
+OMX_ERRORTYPE Exynos_Shared_ANBBufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_BASEPORT *pExynosPort)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ OMX_U32 width, height;
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+
+ Exynos_OSAL_Memset(planes, 0, sizeof(planes));
+
+ width = pExynosPort->portDefinition.format.video.nFrameWidth;
+ height = pExynosPort->portDefinition.format.video.nFrameHeight;
+
+#ifdef USE_STOREMETADATA
+ if ((pExynosPort->bIsANBEnabled == OMX_TRUE) ||
+ (pExynosPort->bStoreMetaData == OMX_TRUE)) {
+#else
+ if (pExynosPort->bIsANBEnabled == OMX_TRUE) {
+#endif
+ OMX_U32 stride;
+
+ if ((pUseBuffer->bufferHeader != NULL) &&
+ (pUseBuffer->bufferHeader->pBuffer != NULL) &&
+ (pExynosPort->exceptionFlag == GENERAL_STATE)) {
+
+ if (pExynosPort->bIsANBEnabled == OMX_TRUE)
+ ret = Exynos_OSAL_LockANBHandle(pUseBuffer->bufferHeader->pBuffer, width, height, pExynosPort->portDefinition.format.video.eColorFormat, &stride, planes);
+#ifdef USE_STOREMETADATA
+ else if (pExynosPort->bStoreMetaData == OMX_TRUE)
+ ret = Exynos_OSAL_LockMetaData(pUseBuffer->bufferHeader->pBuffer, width, height, pExynosPort->portDefinition.format.video.eColorFormat, &stride, planes);
+#endif
+
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ pUseBuffer->dataLen = sizeof(void *);
+ } else {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pData->multiPlaneBuffer.dataBuffer[0] = planes[0].addr;
+ pData->multiPlaneBuffer.dataBuffer[1] = planes[1].addr;
+ pData->multiPlaneBuffer.dataBuffer[2] = planes[2].addr;
+
+#ifdef USE_DMA_BUF
+ pData->multiPlaneBuffer.fd[0] = planes[0].fd;
+ pData->multiPlaneBuffer.fd[1] = planes[1].fd;
+ pData->multiPlaneBuffer.fd[2] = planes[2].fd;
+#endif
+
+ 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:
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Shared_DataToANBBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_BASEPORT *pExynosPort)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ 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 ((pUseBuffer->bufferHeader == NULL) ||
+ (pUseBuffer->bufferHeader->pBuffer == NULL)) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ if (pExynosPort->bIsANBEnabled == OMX_TRUE) {
+ Exynos_OSAL_UnlockANBHandle(pUseBuffer->bufferHeader->pBuffer);
+#ifdef USE_STOREMETADATA
+ } else if (pExynosPort->bStoreMetaData == OMX_TRUE) {
+ Exynos_OSAL_UnlockMetaData(pUseBuffer->bufferHeader->pBuffer);
+#endif
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+EXIT:
+ return ret;
+}
+#endif
+
+OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ 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;
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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)
+ * @version 2.0.0
+ * @history
+ * 2012.02.20 : Create
+ */
+
+#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);
+
+#ifdef USE_ANB
+OMX_ERRORTYPE Exynos_Shared_ANBBufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_BASEPORT *pExynosPort);
+OMX_ERRORTYPE Exynos_Shared_DataToANBBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_BASEPORT *pExynosPort);
+#endif
+
+OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer);
+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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
--- /dev/null
+
+ 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
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_H264dec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.AVC.Decoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+
+ifeq ($(BOARD_USE_ANB), true)
+LOCAL_CFLAGS += -DUSE_ANB
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_S3D_SUPPORT), true)
+ifeq ($(BOARD_USES_HWC_SERVICES), true)
+LOCAL_CFLAGS += -DUSE_S3D_SUPPORT
+else
+ifeq ($(TARGET_BOARD_PLATFORM), exynos5)
+LOCAL_CFLAGS += -DUSE_S3D_SUPPORT
+endif
+endif
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_CUSTOM_COMPONENT_SUPPORT), true)
+LOCAL_CFLAGS += -DUSE_CUSTOM_COMPONENT_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_TIMESTAMP_REORDER_SUPPORT), true)
+LOCAL_CFLAGS += -DUSE_TIMESTAMP_REORDER_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/dec \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_SKYPE_HD), true)
+LOCAL_CFLAGS += -DUSE_SKYPE_HD
+LOCAL_CFLAGS += -DBUILD_DEC
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/skype
+LOCAL_STATIC_LIBRARIES += libExynosOMX_SkypeHD_Dec
+endif
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+#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"
+
+#define H264_DEC_NUM_OF_EXTRA_BUFFERS 7
+
+//#define ADD_SPS_PPS_I_FRAME
+//#define FULL_FRAME_SEARCH
+
+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;
+
+ FunctionIn();
+
+ 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_100:
+ case MFC_101:
+ pH264Dec->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel52;
+ break;
+ case MFC_80:
+ case MFC_90:
+ case MFC_1010:
+ 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:
+ 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;
+ }
+
+ while ((pH264Dec->hMFCH264Handle.maxLevel >> nLevelCnt) > 0) {
+ nLevelCnt++;
+ }
+
+ if ((pH264Dec->hMFCH264Handle.nProfileCnt == 0) ||
+ (nLevelCnt == 0)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : there is no any profile/level", __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);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : supported profile(%x), level(%x)", __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+ 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, "%s : there is no any profile/level", __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, "%s : profile(%x)/level(%x) is %ssupported", __FUNCTION__,
+ pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+ (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+ return (bProfileSupport && bLevelSupport);
+}
+
+#if 0 /* unused code */
+static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+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;
+}
+
+#if 0 /* unused code */
+int Check_H264_Frame(
+ OMX_U8 *pInputStream,
+ OMX_U32 buffSize,
+ OMX_U32 flag,
+ OMX_BOOL bPreviousFrameEOF,
+ OMX_BOOL *pbEndOfFrame)
+{
+ OMX_U32 preFourByte = (OMX_U32)-1;
+ int accessUnitSize = 0;
+ int frameTypeBoundary = 0;
+ int nextNaluSize = 0;
+ int naluStart = 0;
+
+ if (bPreviousFrameEOF == OMX_TRUE)
+ naluStart = 0;
+ else
+ naluStart = 1;
+
+ while (1) {
+ int inputOneByte = 0;
+
+ if (accessUnitSize == (int)buffSize)
+ goto EXIT;
+
+ inputOneByte = *(pInputStream++);
+ accessUnitSize += 1;
+
+ if (preFourByte == 0x00000001 || (preFourByte << 8) == 0x00000100) {
+ int naluType = inputOneByte & 0x1F;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NaluType : %d", naluType);
+ if (naluStart == 0) {
+#ifdef ADD_SPS_PPS_I_FRAME
+ if (naluType == 1 || naluType == 5)
+#else
+ if (naluType == 1 || naluType == 5 || naluType == 7 || naluType == 8)
+#endif
+ naluStart = 1;
+ } else {
+#ifdef OLD_DETECT
+ frameTypeBoundary = (8 - naluType) & (naluType - 10); //AUD(9)
+#else
+ if (naluType == 9)
+ frameTypeBoundary = -2;
+#endif
+ if (naluType == 1 || naluType == 5) {
+ if (accessUnitSize == (int)buffSize) {
+ accessUnitSize--;
+ goto EXIT;
+ }
+ inputOneByte = *pInputStream++;
+ accessUnitSize += 1;
+
+ if (inputOneByte >= 0x80)
+ frameTypeBoundary = -1;
+ }
+ if (frameTypeBoundary < 0) {
+ break;
+ }
+ }
+
+ }
+ preFourByte = (preFourByte << 8) + inputOneByte;
+ }
+
+ *pbEndOfFrame = OMX_TRUE;
+ nextNaluSize = -5;
+ if (frameTypeBoundary == -1)
+ nextNaluSize = -6;
+ if (preFourByte != 0x00000001)
+ nextNaluSize++;
+ return (accessUnitSize + nextNaluSize);
+
+EXIT:
+ *pbEndOfFrame = OMX_FALSE;
+
+ return accessUnitSize;
+}
+#endif
+
+static OMX_BOOL Check_H264_StartCode(
+ OMX_U8 *pInputStream,
+ OMX_U32 streamSize)
+{
+ if (streamSize < 4) {
+ return OMX_FALSE;
+ }
+
+ 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, "NaluType : %d, 0x%x, 0x%x, 0x%x", (pInputStream[4] & 0x1F), pInputStream[3], pInputStream[4], pInputStream[5]);
+ return 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, "NaluType : %d, 0x%x, 0x%x, 0x%x", (pInputStream[3] & 0x1F), pInputStream[2], pInputStream[3], pInputStream[4]);
+ return OMX_TRUE;
+ } else {
+ return OMX_FALSE;
+ }
+}
+
+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_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate decoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+ /* check mandatory functions for decoder ops */
+ if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
+ (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) ||
+#ifdef USE_S3D_SUPPORT
+ (pDecOps->Enable_SEIParsing == NULL) || (pDecOps->Get_FramePackingInfo == NULL) ||
+#endif
+ (pDecOps->Get_FrameTag == NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pH264Dec->hMFCH264Handle.hMFCHandle = pH264Dec->hMFCH264Handle.pDecOps->Init(pVideoInstInfo);
+ if (pH264Dec->hMFCH264Handle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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, "Failed to Enable SEI Parsing");
+ 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;
+ }
+
+ /* 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
+ pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
+ pOutbufOps = pH264Dec->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_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = 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;
+ pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
+ 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) &&
+ (pOutputPort->bDynamicDPBMode == OMX_TRUE))
+ 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
+ pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
+ pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+ 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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE H264CodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
+ CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoDecBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
+ pBufOps = pH264Dec->hMFCH264Handle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
+ pBufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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);
+
+ /******************************************************/
+ /* V4L2 Destnation Setup for DPB Buffer Number Change */
+ /******************************************************/
+ ret = H264CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to H264CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+ /**********************************/
+ /* Codec Buffer Unregister */
+ /**********************************/
+ pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+ pBufferOps->Cleanup_Buffer(hMFCHandle);
+ }
+
+ Exynos_ResolutionUpdate(pOMXComponent);
+ } 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ int i, nOutbufs;
+
+ ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
+ 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) &&
+ (pH264Dec->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, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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->bDestinationStart == OMX_TRUE)) {
+ Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+ for (i = 0; i < pH264Dec->hMFCH264Handle.maxDPBNum; i++) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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;
+
+ /* Get Frame packing information*/
+ if (pDecOps->Get_FramePackingInfo(pH264Dec->hMFCH264Handle.hMFCHandle, &framePacking) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Get Frame Packing Information");
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+
+ if (framePacking.available) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "arrangement ID: 0x%08x", framePacking.arrangement_id);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "arrangement_type: %d", framePacking.arrangement_type);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "content_interpretation_type: %d", framePacking.content_interpretation_type);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "current_frame_is_frame0_flag: %d", framePacking.current_frame_is_frame0_flag);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "spatial_flipping_flag: %d", framePacking.spatial_flipping_flag);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fr0X:%d fr0Y:%d fr0X:%d fr0Y:%d", 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;
+ /** Send Port Settings changed call back - output color format change */
+ (*(pExynosComponent->pCallbacks->EventHandler))
+ (pOMXComponent,
+ pExynosComponent->callbackData,
+ 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:
+ return ret;
+}
+#endif
+
+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;
+
+ 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) ||
+ (codecOutbufConf.bInterlaced != pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced) ||
+#endif
+ (maxDPBNum != pH264Dec->hMFCH264Handle.maxDPBNum)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] DRC: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.nFrameWidth,
+ codecOutbufConf.nFrameHeight,
+ pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
+ pH264Dec->hMFCH264Handle.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__,
+ maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType,
+ pH264Dec->hMFCH264Handle.maxDPBNum,
+ pH264Dec->hMFCH264Handle.codecOutbufConf.eColorFormat,
+ pH264Dec->hMFCH264Handle.codecOutbufConf.eFilledDataType);
+
+ 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 (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ pOutputPortDefinition->nBufferCountActual = pH264Dec->hMFCH264Handle.maxDPBNum;
+ pOutputPortDefinition->nBufferCountMin = pH264Dec->hMFCH264Handle.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);
+ }
+ }
+
+ 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] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.cropRect.nWidth,
+ codecOutbufConf.cropRect.nHeight,
+ pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth,
+ 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;
+
+ /** 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, "Failed to get geometry for parsed header info");
+ ret = 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] H264CodecSetup maxDPBNum: %d", pExynosComponent, __FUNCTION__, pH264Dec->hMFCH264Handle.maxDPBNum);
+
+ /* get interlace info */
+ if (pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE)
+ Exynos_OSAL_Log(EXYNOS_LOG_INFO, "detect an interlaced type");
+
+ pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pCropRectangle = &(pOutputPort->cropRectangle);
+ pInputPortDefinition = &(pInputPort->portDefinition);
+ pOutputPortDefinition = &(pOutputPort->portDefinition);
+ } else {
+ pCropRectangle = &(pOutputPort->newCropRectangle);
+ pInputPortDefinition = &(pInputPort->newPortDefinition);
+ pOutputPortDefinition = &(pOutputPort->newPortDefinition);
+ }
+
+ 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) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.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;
+
+ pOutputPortDefinition->nBufferCountActual = pOutputPort->portDefinition.nBufferCountActual;
+ pOutputPortDefinition->nBufferCountMin = pOutputPort->portDefinition.nBufferCountMin;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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) ||
+ (pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight) ||
+ ((OMX_S32)pOutputPort->portDefinition.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;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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);
+ }
+ }
+ if ((pVideoDec->bReconfigDPB != OMX_TRUE) &&
+ ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth) ||
+ (pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight))) {
+ /* Check Crop */
+ 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);
+
+ /** 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;
+
+ 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;
+ int i;
+
+ FunctionIn();
+
+ if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ 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);
+ Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent);
+
+ 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->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);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ bufferConf.nSizeImage = pExynosInputPort->portDefinition.nBufferSize;
+ } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+ }
+ 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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* set output geometry */
+ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+ bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+ if (bSupportFormat == OMX_TRUE) { /* supported by H/W */
+ if ((pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport == VIDEO_TRUE) &&
+ (eOutputFormat != (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled)) {
+ /* Needs to eanble DualDPB feature */
+ if (pDecOps->Enable_DualDPBMode(hMFCHandle) != VIDEO_ERROR_NONE) {
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ }
+ 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;
+ goto EXIT;
+ }
+ }
+
+ pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat;
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+ if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* input buffer enqueue for header parsing */
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ /* set buffer process type */
+ if (pDecOps->Set_BufferProcessType(hMFCHandle, pExynosOutputPort->bufferProcessType) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set buffer process type(not supported)");
+ }
+
+ if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
+// ret = OMX_ErrorInsufficientResources;
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+ goto EXIT;
+ }
+
+ /* start header parsing */
+ if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
+ ret = OMX_ErrorCodecInit;
+ 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, "CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...",
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0]) , *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 1),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 2), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 3),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 4), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 5),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 6), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 7));
+ if (ret != OMX_ErrorNone) {
+ H264CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+ pInbufOps->Cleanup_Buffer(hMFCHandle);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_SleepMillisec(0);
+ ret = OMX_ErrorInputDataDecodeYet;
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
+ 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];
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_TRUE) {
+ if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enable Dynamic DPB");
+ 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 (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ /* get dpb count */
+ nOutbufs = pH264Dec->hMFCH264Handle.maxDPBNum;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Register output buffer */
+ ret = H264CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++)
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ } else {
+ if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ 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;
+
+ /* without Register output buffer */
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++) {
+ pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ (int *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+ pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+#ifdef USE_ANB
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+ int plane;
+
+ Exynos_OSAL_Memset((OMX_PTR)planes, 0, sizeof(ExynosVideoPlane) * MAX_BUFFER_PLANE);
+
+ /* get dpb count */
+ nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_TRUE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
+ planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
+ planes[plane].allocSize = nAllocLen[plane];
+ }
+
+ if (pOutbufOps->Register(hMFCHandle, planes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+
+ if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ } else {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ } else {
+ /* get dpb count */
+ nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ }
+#else
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+#endif
+ }
+
+ pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nParamIndex) {
+ case OMX_IndexParamVideoAvc:
+ {
+ OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
+ EXYNOS_H264DEC_HANDLE *pH264Dec = 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) {
+ goto EXIT;
+ }
+
+ if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ 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) {
+ 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;
+ EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+ EXYNOS_H264DEC_HANDLE *pH264Dec = 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;
+ }
+
+ pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ case OMX_IndexExynosParamReorderMode: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ goto EXIT;
+
+ pReorderParam->bReorderMode = pVideoDec->bReorderMode;
+ }
+ break;
+#endif
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
+ OMX_U32 portIndex = portDefinition->nPortIndex;
+ 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 *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (((pExynosPort->bIsANBEnabled == OMX_TRUE) || (pExynosPort->bStoreMetaData == OMX_TRUE)) &&
+ (pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
+ (portIndex == OUTPUT_PORT_INDEX)) {
+ portDefinition->format.video.eColorFormat =
+ (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HALPixelFormat((OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace, pExynosPort->ePlaneType);
+ }
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "portDefinition->format.video.eColorFormat: 0x%x", portDefinition->format.video.eColorFormat);
+ }
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+ case OMX_IndexParamVideoAvc:
+ {
+ OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
+ OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
+ EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
+ /* 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) {
+ goto EXIT;
+ }
+
+ if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ 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_ErrorBadParameter;
+ goto EXIT;
+ }
+ }
+ break;
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
+ EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ case OMX_IndexExynosParamReorderMode: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ goto EXIT;
+
+ pVideoDec->bReorderMode = pReorderParam->bReorderMode;
+ }
+ break;
+#endif
+ 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;
+
+ 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 (pComponentConfigStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
+ OMX_CONFIG_RECTTYPE *pSrcRectType = NULL;
+ OMX_CONFIG_RECTTYPE *pDstRectType = NULL;
+ pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ }
+
+ EXYNOS_OMX_BASEPORT *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:
+ {
+ EXYNOS_H264DEC_HANDLE *pH264Dec = NULL;
+ OMX_U32 *pS3DMode = NULL;
+ pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ pS3DMode = (OMX_U32 *)pComponentConfigStructure;
+ *pS3DMode = (OMX_U32) pH264Dec->hMFCH264Handle.S3DFPArgmtType;
+ }
+ break;
+#endif
+ case OMX_IndexExynosConfigDisplayDelay: /* MSRND */
+ {
+ EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ (*((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;
+
+ 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 (pComponentConfigStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+ case OMX_IndexExynosConfigDisplayDelay: /* MSRND */
+ {
+ EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ OMX_U32 nDisplayDelay;
+
+ if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_TRUE) {
+ ret = OMX_ErrorIncorrectStateOperation;
+ break;
+ }
+
+ nDisplayDelay = (*((OMX_U32 *)pComponentConfigStructure));
+ 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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+#ifdef USE_S3D_SUPPORT
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_GET_S3D) == 0) {
+ *pIndexType = OMX_IndexVendorS3DMode;
+ 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;
+ }
+
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_REORDER_MODE) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamReorderMode;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+#endif
+ }
+
+#ifdef USE_SKYPE_HD
+ ret = Exynos_H264Dec_GetExtensionIndex_SkypeHD(hComponent, cParameterName, pIndexType);
+ if (ret != OMX_ErrorNone)
+#endif
+ 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;
+ OMX_COMPONENTTYPE *pOMXComponent = NULL;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+ 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;
+ OMX_PTR hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ ExynosVideoInstInfo *pVideoInstInfo = &(pH264Dec->hMFCH264Handle.videoInstInfo);
+
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+ int i, plane;
+
+ FunctionIn();
+
+ pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
+ pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ 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;
+ }
+
+ pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
+ pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
+ pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+ Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+ if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ unsigned int nAllocLen[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
+ 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->hDestinationStartEvent);
+
+ 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ OMX_PTR hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+ int i, plane;
+
+ FunctionIn();
+
+ if (pVideoDec->csc_handle != NULL) {
+ csc_deinit(pVideoDec->csc_handle);
+ pVideoDec->csc_handle = NULL;
+ }
+
+ Exynos_OSAL_QueueTerminate(&pH264Dec->bypassBufferInfoQ);
+
+ Exynos_OSAL_SignalTerminate(pH264Dec->hDestinationStartEvent);
+ pH264Dec->hDestinationStartEvent = 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);
+ } 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);
+ } 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];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ OMX_U32 oneFrameSize = pSrcInputData->dataLen;
+
+ ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
+ 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;
+ int i;
+
+ FunctionIn();
+
+ if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
+ goto EXIT;
+ }
+
+ if ((pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) &&
+ (pVideoDec->bForceHeaderParsing == OMX_FALSE)) {
+ ret = H264CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to H264CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ }
+
+ if (((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) ||
+ ((bInStartCode = Check_H264_StartCode(pSrcInputData->multiPlaneBuffer.dataBuffer[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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x, oneFrameSize: %d", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pH264Dec->hMFCH264Handle.indexTimestamp, pSrcInputData->nFlags, oneFrameSize);
+
+ 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;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] bufferHeader: 0x%x, dataBuffer: 0x%x", pExynosComponent, __FUNCTION__, pSrcInputData->bufferHeader, pSrcInputData->multiPlaneBuffer.dataBuffer[0]);
+
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
+ tempBufferHeader.nFlags = pSrcInputData->nFlags;
+ tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+ pPrivate = (void *)&tempBufferHeader;
+ } else {
+ pPrivate = (void *)pSrcInputData->bufferHeader;
+ }
+ codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ } else if (bInStartCode == OMX_FALSE) {
+ ret = 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pH264Dec->hMFCH264Handle.pInbufOps;
+ ExynosVideoBuffer *pVideoBuffer;
+ 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->allocSize = 0;
+ pSrcOutputData->pPrivate = NULL;
+ } else {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pSrcOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[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, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#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];
+
+ ExynosVideoDecOps *pDecOps = pH264Dec->hMFCH264Handle.pDecOps;
+ 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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ 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] : %d => ADDR[%d]: 0x%x", pExynosComponent, __FUNCTION__, __LINE__, i,
+ pDstInputData->multiPlaneBuffer.dataBuffer[i]);
+ }
+
+ if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+ (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+ (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+ ret = H264CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to H264CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ codecReturn = pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ } else {
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ }
+
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &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;
+
+ OMX_S32 indexTimestamp = 0;
+ int plane, nPlaneCnt;
+
+ FunctionIn();
+
+ if (pH264Dec->bDestinationStart == OMX_FALSE) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ while (1) {
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
+ if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+
+ if (pVideoBuffer == NULL) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ } else {
+ 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, "HW is not available");
+ 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(pExynosOutputPort))) {
+ 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) {
+ pExynosOutputPort->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(pExynosOutputPort);
+
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pDstOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pDstOutputData->multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
+ pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+ pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
+ }
+ pDstOutputData->usedDataLen = 0;
+ pDstOutputData->pPrivate = pVideoBuffer;
+ if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ int i = 0;
+ pDstOutputData->pPrivate = NULL;
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ if (pDstOutputData->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+ /* get interlace frame info */
+ if ((pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+ (pH264Dec->hMFCH264Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
+ (pVideoBuffer->planes[2].addr != NULL)) {
+ /* only NV12 case */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] interlace type = %x", pExynosComponent, __FUNCTION__, pVideoBuffer->interlacedType);
+ *(int *)(pVideoBuffer->planes[2].addr) = pVideoBuffer->interlacedType;
+ }
+
+ pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+ bufferGeometry = &pH264Dec->hMFCH264Handle.codecOutbufConf;
+ pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
+ pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
+ pBufferInfo->imageStride = bufferGeometry->nStride;
+ pBufferInfo->ColorFormat = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+ Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+ 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 timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
+ }
+ } 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 reorder timestamp %lld us (%.2f secs), sCurrentTimestamp.nIndex: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, sCurrentTimestamp.nIndex, pDstOutputData->nFlags);
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport == VIDEO_FALSE) {
+ if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+ (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ 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] indexTimestamp(%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 = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+ if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ } else {
+ pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+ }
+ } else {
+ if ((displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+ ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+
+ if ((pExynosComponent->bBehaviorEOS == OMX_TRUE) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME)) {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (displayStatus != VIDEO_FRAME_STATUS_LAST_FRAME) {
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ } else {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 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 (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;
+ }
+
+ 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_SignalReset(pH264Dec->hSourceStartEvent);
+ }
+
+ ret = Exynos_H264Dec_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
+ 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_ErrorOutputBufferUseYet;
+ else
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
+ }
+ 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;
+ }
+
+ 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 (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
+ ret = Exynos_H264Dec_DstIn(pOMXComponent, pDstInputData);
+ if (ret != OMX_ErrorNone) {
+ 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 (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
+ }
+
+ if (Exynos_OSAL_GetElemNum(&pH264Dec->bypassBufferInfoQ) > 0) {
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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)) {
+ 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, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DEC, componentName) == 0) ||
+ (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_CUSTOM_DEC, componentName) == 0)) {
+ bSecureMode = OMX_FALSE;
+ } else if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DRM_DEC, componentName) == 0) ||
+ (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_CUSTOM_DRM_DEC, componentName) == 0)) {
+ bSecureMode = OMX_TRUE;
+ } else {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+
+ 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 | BUFFER_ANBSHARE;
+ 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;
+
+#if 0 /* unused code */
+ pVideoDec->exynos_checkInputFrame = &Check_H264_Frame;
+ pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ 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, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ Exynos_OSAL_Free(pH264Dec);
+ pH264Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->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]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
+ Exynos_OSAL_Free(pH264Dec);
+ pH264Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for dec %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport),
+ (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport),
+ (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport),
+ (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bSkypeSupport));
+
+ if (pH264Dec->hMFCH264Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport == VIDEO_TRUE)
+ pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bDynamicDPBMode = OMX_TRUE;
+
+ 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_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;
+
+ 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;
+ }
+
+ ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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"
+
+#ifdef USE_SKYPE_HD
+#include "OMX_Video_Extensions.h"
+#endif
+
+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;
+
+#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 hDestinationStartEvent;
+
+ EXYNOS_QUEUE bypassBufferInfoQ;
+
+ OMX_BOOL bLowLatency;
+} 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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;
+#ifdef USE_CUSTOM_COMPONENT_SUPPORT
+ /* component 3 - video custom decoder H.264 */
+ Exynos_OSAL_Strcpy(exynosComponents[2]->componentName, EXYNOS_OMX_COMPONENT_H264_CUSTOM_DEC);
+ Exynos_OSAL_Strcpy(exynosComponents[2]->roles[0], EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
+ exynosComponents[2]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+ /* component 4 - video custom decoder H.264 for DRM */
+ Exynos_OSAL_Strcpy(exynosComponents[3]->componentName, EXYNOS_OMX_COMPONENT_H264_CUSTOM_DRM_DEC);
+ Exynos_OSAL_Strcpy(exynosComponents[3]->roles[0], EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
+ exynosComponents[3]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+#endif
+EXIT:
+ FunctionOut();
+
+ return MAX_COMPONENT_NUM;
+}
--- /dev/null
+/*
+ *
+ * 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 4
+#define MAX_COMPONENT_ROLE_NUM 1
+
+/* H.264 */
+#define EXYNOS_OMX_COMPONENT_H264_DEC "OMX.Exynos.AVC.Decoder"
+#define EXYNOS_OMX_COMPONENT_H264_DRM_DEC "OMX.Exynos.AVC.Decoder.secure"
+
+#define EXYNOS_OMX_COMPONENT_H264_CUSTOM_DEC "OMX.Exynos.avc.dec"
+#define EXYNOS_OMX_COMPONENT_H264_CUSTOM_DRM_DEC "OMX.Exynos.avc.dec.secure"
+
+#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
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_HEVCdec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.HEVC.Decoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+LOCAL_CFLAGS += -DUSE_HEVC_SUPPORT
+
+ifeq ($(BOARD_USE_ANB), true)
+LOCAL_CFLAGS += -DUSE_ANB
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_S3D_SUPPORT), true)
+ifeq ($(BOARD_USES_HWC_SERVICES), true)
+LOCAL_CFLAGS += -DUSE_S3D_SUPPORT
+else
+ifeq ($(TARGET_BOARD_PLATFORM), exynos5)
+LOCAL_CFLAGS += -DUSE_S3D_SUPPORT
+endif
+endif
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_CUSTOM_COMPONENT_SUPPORT), true)
+LOCAL_CFLAGS += -DUSE_CUSTOM_COMPONENT_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_TIMESTAMP_REORDER_SUPPORT), true)
+LOCAL_CFLAGS += -DUSE_TIMESTAMP_REORDER_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/dec \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+#ifdef USE_ANB
+#include "Exynos_OSAL_Android.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"
+
+#define HEVC_DEC_NUM_OF_EXTRA_BUFFERS 7
+
+//#define FULL_FRAME_SEARCH /* Full frame search not support*/
+
+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;
+
+ FunctionIn();
+
+ 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_100:
+ case MFC_101:
+ pHevcDec->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel51;
+ break;
+ case HEVC_10:
+ case MFC_90:
+ case MFC_1010:
+ pHevcDec->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel5;
+ break;
+ case MFC_1011:
+ case MFC_1020:
+ pHevcDec->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel41;
+ break;
+ case MFC_92:
+ 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;
+ }
+
+ while ((pHevcDec->hMFCHevcHandle.maxLevel >> nLevelCnt) > 0) {
+ nLevelCnt++;
+ }
+
+ if ((pHevcDec->hMFCHevcHandle.nProfileCnt == 0) ||
+ (nLevelCnt == 0)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : there is no any profile/level", __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);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : supported profile(%x), level(%x)", __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+ 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, "%s : there is no any profile/level", __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, "%s : profile(%x)/level(%x) is %ssupported", __FUNCTION__,
+ pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+ (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+ return (bProfileSupport && bLevelSupport);
+}
+
+#if 0 /* unused code */
+static OMX_ERRORTYPE GetCodecInputPrivateData(
+ OMX_PTR codecBuffer,
+ OMX_PTR *pVirtAddr,
+ OMX_U32 *dataSize)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+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;
+}
+
+#if 0 /* unused code */
+static int Check_HEVC_Frame(
+ OMX_U8 *pInputStream,
+ OMX_U32 buffSize,
+ OMX_U32 flag,
+ OMX_BOOL bPreviousFrameEOF,
+ OMX_BOOL *pbEndOfFrame)
+{
+ OMX_U32 preFourByte = (OMX_U32)-1;
+ int accessUnitSize = 0;
+ int frameTypeBoundary = 0;
+ int nextNaluSize = 0;
+ int naluStart = 0;
+#if 0
+ if (bPreviousFrameEOF == OMX_TRUE)
+ naluStart = 0;
+ else
+ naluStart = 1;
+
+ while (1) {
+ int inputOneByte = 0;
+
+ if (accessUnitSize == (int)buffSize)
+ goto EXIT;
+
+ inputOneByte = *(pInputStream++);
+ accessUnitSize += 1;
+
+ if (preFourByte == 0x00000001 || (preFourByte << 8) == 0x00000100) {
+ int naluType = inputOneByte & 0x1F;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NaluType : %d", naluType);
+ if (naluStart == 0) {
+#ifdef ADD_SPS_PPS_I_FRAME
+ if (naluType == 1 || naluType == 5)
+#else
+ if (naluType == 1 || naluType == 5 || naluType == 7 || naluType == 8)
+#endif
+ naluStart = 1;
+ } else {
+#ifdef OLD_DETECT
+ frameTypeBoundary = (8 - naluType) & (naluType - 10); //AUD(9)
+#else
+ if (naluType == 9)
+ frameTypeBoundary = -2;
+#endif
+ if (naluType == 1 || naluType == 5) {
+ if (accessUnitSize == (int)buffSize) {
+ accessUnitSize--;
+ goto EXIT;
+ }
+ inputOneByte = *pInputStream++;
+ accessUnitSize += 1;
+
+ if (inputOneByte >= 0x80)
+ frameTypeBoundary = -1;
+ }
+ if (frameTypeBoundary < 0) {
+ break;
+ }
+ }
+
+ }
+ preFourByte = (preFourByte << 8) + inputOneByte;
+ }
+
+ *pbEndOfFrame = OMX_TRUE;
+ nextNaluSize = -5;
+ if (frameTypeBoundary == -1)
+ nextNaluSize = -6;
+ if (preFourByte != 0x00000001)
+ nextNaluSize++;
+ return (accessUnitSize + nextNaluSize);
+
+EXIT:
+ *pbEndOfFrame = OMX_FALSE;
+#endif
+ return accessUnitSize;
+}
+#endif
+
+static OMX_BOOL Check_HEVC_StartCode(
+ OMX_U8 *pInputStream,
+ OMX_U32 streamSize)
+{
+ if (streamSize < 4) {
+ return OMX_FALSE;
+ }
+
+ if ((pInputStream[0] == 0x00) &&
+ (pInputStream[1] == 0x00) &&
+ (pInputStream[2] == 0x01))
+ return OMX_TRUE;
+
+ if ((pInputStream[0] == 0x00) &&
+ (pInputStream[1] == 0x00) &&
+ (pInputStream[2] == 0x00) &&
+ (pInputStream[3] == 0x01))
+ return OMX_TRUE;
+
+ return OMX_FALSE;
+}
+
+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_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate decoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+ /* check mandatory functions for decoder ops */
+ if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
+ (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) ||
+#ifdef USE_S3D_SUPPORT
+ (pDecOps->Enable_SEIParsing == NULL) || (pDecOps->Get_FramePackingInfo == NULL) ||
+#endif
+ (pDecOps->Get_FrameTag == NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pHevcDec->hMFCHevcHandle.hMFCHandle = pHevcDec->hMFCHevcHandle.pDecOps->Init(pVideoInstInfo);
+
+ if (pHevcDec->hMFCHevcHandle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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, "Failed to Enable SEI Parsing");
+ 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;
+ }
+
+ /* 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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->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_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) &&
+ (pOutputPort->bDynamicDPBMode == OMX_TRUE))
+ 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_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE HevcCodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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;
+ CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoDecBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
+ pBufOps = pHevcDec->hMFCHevcHandle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
+ pBufOps = pHevcDec->hMFCHevcHandle.pOutbufOps;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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);
+
+ /******************************************************/
+ /* V4L2 Destnation Setup for DPB Buffer Number Change */
+ /******************************************************/
+ ret = HevcCodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to HevcCodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+ /**********************************/
+ /* Codec Buffer Unregister */
+ /**********************************/
+ pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+ pBufferOps->Cleanup_Buffer(hMFCHandle);
+ }
+
+ Exynos_ResolutionUpdate(pOMXComponent);
+ } 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;
+
+ ExynosVideoDecOps *pDecOps = pHevcDec->hMFCHevcHandle.pDecOps;
+ 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) &&
+ (pHevcDec->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, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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->bDestinationStart == OMX_TRUE)) {
+ Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+ for (i = 0; i < pHevcDec->hMFCHevcHandle.maxDPBNum; i++) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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;
+
+ /* Get Frame packing information*/
+ if (pDecOps->Get_FramePackingInfo(pHevcDec->hMFCHevcHandle.hMFCHandle, &framePacking) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Get Frame Packing Information");
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+
+ if (framePacking.available) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "arrangement ID: 0x%08x", framePacking.arrangement_id);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "arrangement_type: %d", framePacking.arrangement_type);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "content_interpretation_type: %d", framePacking.content_interpretation_type);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "current_frame_is_frame0_flag: %d", framePacking.current_frame_is_frame0_flag);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "spatial_flipping_flag: %d", framePacking.spatial_flipping_flag);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fr0X:%d fr0Y:%d fr0X:%d fr0Y:%d", 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;
+ /** Send Port Settings changed call back - output color format change */
+ (*(pExynosComponent->pCallbacks->EventHandler))
+ (pOMXComponent,
+ pExynosComponent->callbackData,
+ 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:
+ return ret;
+}
+#endif
+
+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;
+
+ 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) ||
+ (codecOutbufConf.bInterlaced != pHevcDec->hMFCHevcHandle.codecOutbufConf.bInterlaced) ||
+#endif
+ (maxDPBNum != pHevcDec->hMFCHevcHandle.maxDPBNum)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] DRC: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.nFrameWidth,
+ codecOutbufConf.nFrameHeight,
+ pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth,
+ pHevcDec->hMFCHevcHandle.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__,
+ maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType,
+ pHevcDec->hMFCHevcHandle.maxDPBNum,
+ pHevcDec->hMFCHevcHandle.codecOutbufConf.eColorFormat,
+ pHevcDec->hMFCHevcHandle.codecOutbufConf.eFilledDataType);
+
+ 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 (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ pOutputPortDefinition->nBufferCountActual = pHevcDec->hMFCHevcHandle.maxDPBNum;
+ pOutputPortDefinition->nBufferCountMin = pHevcDec->hMFCHevcHandle.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);
+ }
+ }
+
+ 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] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.cropRect.nWidth,
+ codecOutbufConf.cropRect.nHeight,
+ pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nWidth,
+ 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;
+
+ /** 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, "parsed header info has only VPS");
+ ret = OMX_ErrorNeedNextHeaderInfo;
+ goto EXIT;
+ } else if (codecRet != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
+ ret = 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] HevcCodecSetup maxDPBNum: %d", pExynosComponent, __FUNCTION__, pHevcDec->hMFCHevcHandle.maxDPBNum);
+
+ pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc = OMX_TRUE;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pCropRectangle = &(pOutputPort->cropRectangle);
+ pInputPortDefinition = &(pInputPort->portDefinition);
+ pOutputPortDefinition = &(pOutputPort->portDefinition);
+ } else {
+ pCropRectangle = &(pOutputPort->newCropRectangle);
+ pInputPortDefinition = &(pInputPort->newPortDefinition);
+ pOutputPortDefinition = &(pOutputPort->newPortDefinition);
+ }
+
+ 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 (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, "The format(%x) is changed to %x by H/W Codec",
+ pHevcDec->hMFCHevcHandle.MFCOutputColorType,
+ pHevcDec->hMFCHevcHandle.codecOutbufConf.eColorFormat);
+
+ pHevcDec->hMFCHevcHandle.MFCOutputColorType = pHevcDec->hMFCHevcHandle.codecOutbufConf.eColorFormat;
+ Exynos_SetPlaneToPort(pOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pOutputPort->ePlaneType));
+ }
+
+ pVideoDec->b10bitData = OMX_TRUE;
+ }
+
+ if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pVideoDec->bReconfigDPB) ||
+ (pVideoDec->b10bitData) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.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;
+
+ pOutputPortDefinition->nBufferCountActual = pOutputPort->portDefinition.nBufferCountActual;
+ pOutputPortDefinition->nBufferCountMin = pOutputPort->portDefinition.nBufferCountMin;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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->b10bitData) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.format.video.nFrameHeight != pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight) ||
+ ((OMX_S32)pOutputPort->portDefinition.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;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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);
+ }
+ }
+
+ if ((pVideoDec->bReconfigDPB != OMX_TRUE) &&
+ ((pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth != pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nWidth) ||
+ (pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight != pHevcDec->hMFCHevcHandle.codecOutbufConf.cropRect.nHeight))) {
+ /* Check Crop */
+ pInputPort->portDefinition.format.video.nFrameWidth = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth;
+ pInputPort->portDefinition.format.video.nFrameHeight = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight;
+ pInputPort->portDefinition.format.video.nStride = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameWidth;
+ pInputPort->portDefinition.format.video.nSliceHeight = pHevcDec->hMFCHevcHandle.codecOutbufConf.nFrameHeight;
+
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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 (pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc == OMX_FALSE) {
+ 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;
+
+ 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;
+ int i;
+
+ FunctionIn();
+
+ if ((oneFrameSize <= 0) &&
+ (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ 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);
+ Exynos_OSAL_SignalSet(pHevcDec->hDestinationStartEvent);
+
+ 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);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ bufferConf.nSizeImage = pExynosInputPort->portDefinition.nBufferSize;
+ } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+ }
+ 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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* set output geometry */
+ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+ bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+ 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, "Can not support this format (0x%x)", eOutputFormat);
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ }
+
+ pHevcDec->hMFCHevcHandle.MFCOutputColorType = bufferConf.eColorFormat;
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+ if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ 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 (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
+// ret = OMX_ErrorInsufficientResources;
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+ goto EXIT;
+ }
+
+ /* start header parsing */
+ if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
+ ret = OMX_ErrorCodecInit;
+ 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, "CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...",
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0]) , *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 1),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 2), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 3),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 4), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 5),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 6), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 7));
+ if (ret != OMX_ErrorNone) {
+ HevcCodecStop(pOMXComponent, INPUT_PORT_INDEX);
+ pInbufOps->Cleanup_Buffer(hMFCHandle);
+
+ if ((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorNeedNextHeaderInfo) {
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ EXYNOS_OMX_DATABUFFER directReturnUseBuffer;
+ Exynos_Shared_DataToBuffer(pSrcInputData, &directReturnUseBuffer);
+ 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_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];
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_TRUE) {
+ if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enable Dynamic DPB");
+ 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 (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ /* get dpb count */
+ nOutbufs = pHevcDec->hMFCHevcHandle.maxDPBNum;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Register output buffer */
+ ret = HevcCodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++)
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ } else {
+ if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ 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;
+
+ /* without Register output buffer */
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++) {
+ pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ (int *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+ pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+#ifdef USE_ANB
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+ int plane;
+
+ Exynos_OSAL_Memset((OMX_PTR)planes, 0, sizeof(ExynosVideoPlane) * MAX_BUFFER_PLANE);
+
+ /* get dpb count */
+ nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_TRUE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
+ planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
+ planes[plane].allocSize = nAllocLen[plane];
+ }
+
+ if (pOutbufOps->Register(hMFCHandle, planes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+
+ if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ } else {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ } else {
+ /* get dpb count */
+ nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ }
+#else
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+#endif
+ }
+
+ pHevcDec->hMFCHevcHandle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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;
+
+ 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) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nParamIndex) {
+ case OMX_IndexParamVideoHevc:
+ {
+ OMX_VIDEO_PARAM_HEVCTYPE *pDstHevcComponent = (OMX_VIDEO_PARAM_HEVCTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_HEVCTYPE *pSrcHevcComponent = NULL;
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = 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) {
+ goto EXIT;
+ }
+
+ if (pDstHevcComponent->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ 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) {
+ 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;
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = 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;
+ }
+
+ pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ case OMX_IndexExynosParamReorderMode: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ goto EXIT;
+
+ pReorderParam->bReorderMode = pVideoDec->bReorderMode;
+ }
+ break;
+#endif
+ 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;
+
+ 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) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+ case OMX_IndexParamVideoHevc:
+ {
+ OMX_VIDEO_PARAM_HEVCTYPE *pDstHevcComponent = NULL;
+ OMX_VIDEO_PARAM_HEVCTYPE *pSrcHevcComponent = (OMX_VIDEO_PARAM_HEVCTYPE *)pComponentParameterStructure;
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = NULL;
+ /* 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) {
+ goto EXIT;
+ }
+
+ if (pSrcHevcComponent->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ 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_ErrorBadParameter;
+ goto EXIT;
+ }
+ }
+ break;
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_HEVCTYPE *pDstHevcComponent = NULL;
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ case OMX_IndexExynosParamReorderMode: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ goto EXIT;
+
+ pVideoDec->bReorderMode = pReorderParam->bReorderMode;
+ }
+ break;
+#endif
+ 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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 ((int)nIndex) {
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = NULL;
+ OMX_CONFIG_RECTTYPE *pSrcRectType = NULL;
+ OMX_CONFIG_RECTTYPE *pDstRectType = NULL;
+ pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ }
+
+ EXYNOS_OMX_BASEPORT *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:
+ {
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = NULL;
+ OMX_U32 *pS3DMode = NULL;
+ pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ pS3DMode = (OMX_U32 *)pComponentConfigStructure;
+ *pS3DMode = (OMX_U32) pHevcDec->hMFCHevcHandle.S3DFPArgmtType;
+ }
+ break;
+#endif
+ case OMX_IndexExynosConfigDisplayDelay: /* MSRND */
+ {
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ (*((OMX_U32 *)pComponentConfigStructure)) = pHevcDec->hMFCHevcHandle.nDisplayDelay;
+ }
+ break;
+ 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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 ((int)nIndex) {
+ case OMX_IndexExynosConfigDisplayDelay: /* MSRND */
+ {
+ EXYNOS_HEVCDEC_HANDLE *pHevcDec = (EXYNOS_HEVCDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ OMX_U32 nDisplayDelay;
+
+ if (pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc == OMX_TRUE) {
+ ret = OMX_ErrorIncorrectStateOperation;
+ break;
+ }
+
+ nDisplayDelay = (*((OMX_U32 *)pComponentConfigStructure));
+ if (nDisplayDelay > MAX_HEVC_DISPLAYDELAY_VALIDNUM) {
+ ret = OMX_ErrorBadParameter;
+ break;
+ }
+
+ pHevcDec->hMFCHevcHandle.nDisplayDelay = nDisplayDelay;
+ }
+ break;
+ 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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+#ifdef USE_S3D_SUPPORT
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_GET_S3D) == 0) {
+ *pIndexType = OMX_IndexVendorS3DMode;
+ 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;
+ }
+
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_REORDER_MODE) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamReorderMode;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+#endif
+ }
+
+ 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;
+ OMX_COMPONENTTYPE *pOMXComponent = NULL;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+ 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, plane;
+
+ FunctionIn();
+
+ pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc = OMX_FALSE;
+ pHevcDec->hMFCHevcHandle.bConfiguredMFCDst = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ 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] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
+ 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->hDestinationStartEvent);
+
+ 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->hDestinationStartEvent);
+ pHevcDec->hDestinationStartEvent = 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);
+ } 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);
+ } 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;
+ int i;
+
+ FunctionIn();
+
+ if (pHevcDec->hMFCHevcHandle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = HevcCodecSrcSetup(pOMXComponent, pSrcInputData);
+ goto EXIT;
+ }
+
+ if ((pHevcDec->hMFCHevcHandle.bConfiguredMFCDst == OMX_FALSE) &&
+ (pVideoDec->bForceHeaderParsing == OMX_FALSE)) {
+ ret = HevcCodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to HevcCodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ }
+
+ if (((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) ||
+ ((bInStartCode = Check_HEVC_StartCode(pSrcInputData->multiPlaneBuffer.dataBuffer[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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x, oneFrameSize: %d", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pHevcDec->hMFCHevcHandle.indexTimestamp, pSrcInputData->nFlags, oneFrameSize);
+
+ 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;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] bufferHeader: 0x%x, dataBuffer: 0x%x", pExynosComponent, __FUNCTION__, pSrcInputData->bufferHeader, pSrcInputData->multiPlaneBuffer.dataBuffer[0]);
+
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
+ tempBufferHeader.nFlags = pSrcInputData->nFlags;
+ tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+ pPrivate = (void *)&tempBufferHeader;
+ } else {
+ pPrivate = (void *)pSrcInputData->bufferHeader;
+ }
+
+ codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pHevcDec->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ } else if (bInStartCode == OMX_FALSE) {
+ ret = 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->allocSize = 0;
+ pSrcOutputData->pPrivate = NULL;
+ } else {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pSrcOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[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, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ 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] : %d => ADDR[%d]: 0x%x", pExynosComponent, __FUNCTION__, __LINE__, i,
+ pDstInputData->multiPlaneBuffer.dataBuffer[i]);
+ }
+
+ if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+ (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+ (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+ ret = HevcCodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to HevcCodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ codecReturn = pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ } else {
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ }
+
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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 *pExynosOutputPort = &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;
+
+ OMX_S32 indexTimestamp = 0;
+ int plane, nPlaneCnt;
+
+ FunctionIn();
+
+ if (pHevcDec->bDestinationStart == OMX_FALSE) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ while (1) {
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
+ if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+
+ if (pVideoBuffer == NULL) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ } else {
+ 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, "HW is not available");
+ 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(pExynosOutputPort))) {
+ 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) {
+ pExynosOutputPort->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(pExynosOutputPort);
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pDstOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pDstOutputData->multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
+ pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+ pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
+ }
+ pDstOutputData->usedDataLen = 0;
+ pDstOutputData->pPrivate = pVideoBuffer;
+
+ if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ int i = 0;
+ pDstOutputData->pPrivate = NULL;
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ if (pDstOutputData->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+ pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+ bufferGeometry = &pHevcDec->hMFCHevcHandle.codecOutbufConf;
+ pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
+ pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
+ pBufferInfo->imageStride = bufferGeometry->nStride;
+ pBufferInfo->ColorFormat = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+ Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+ 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 timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
+ }
+ } 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 reorder timestamp %lld us (%.2f secs), sCurrentTimestamp.nIndex: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, sCurrentTimestamp.nIndex, pDstOutputData->nFlags);
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if (pHevcDec->hMFCHevcHandle.videoInstInfo.specificInfo.dec.bLastFrameSupport == VIDEO_FALSE) {
+ if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) != OMX_TRUE) {
+ if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+ (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ }
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ 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] indexTimestamp(%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 = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 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 = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+ }
+ } else {
+ if ((displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+ ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+
+ if ((pExynosComponent->bBehaviorEOS == OMX_TRUE) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME)) {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (displayStatus != VIDEO_FRAME_STATUS_LAST_FRAME) {
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ } else {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 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 (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;
+ }
+
+ 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_SignalReset(pHevcDec->hSourceStartEvent);
+ }
+
+ ret = Exynos_HevcDec_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) &&
+ (pExynosComponent->currentState == OMX_StateExecuting)) {
+ 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_ErrorOutputBufferUseYet;
+ else
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pHevcDec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pHevcDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pHevcDec->hDestinationStartEvent);
+ }
+ 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;
+ }
+
+ 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 (pHevcDec->hMFCHevcHandle.bConfiguredMFCDst == OMX_TRUE) {
+ ret = Exynos_HevcDec_DstIn(pOMXComponent, pDstInputData);
+ if (ret != OMX_ErrorNone) {
+ 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 (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pHevcDec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pHevcDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pHevcDec->hDestinationStartEvent);
+ }
+ if (Exynos_OSAL_GetElemNum(&pHevcDec->bypassBufferInfoQ) > 0) {
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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)) {
+ 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, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_HEVC_DEC, componentName) == 0) ||
+ (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_HEVC_CUSTOM_DEC, componentName) == 0)) {
+ bSecureMode = OMX_FALSE;
+ } else if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_HEVC_DRM_DEC, componentName) == 0) ||
+ (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_HEVC_CUSTOM_DRM_DEC, componentName) == 0)) {
+ bSecureMode = OMX_TRUE;
+ } else {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+
+ 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 | BUFFER_ANBSHARE;
+ 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;
+
+#if 0 /* unused code */
+ pVideoDec->exynos_checkInputFrame = &Check_HEVC_Frame;
+ pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ 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, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ Exynos_OSAL_Free(pHevcDec);
+ pHevcDec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->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]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
+ Exynos_OSAL_Free(pHevcDec);
+ pHevcDec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for dec %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pHevcDec->hMFCHevcHandle.videoInstInfo.specificInfo.dec.bDualDPBSupport),
+ (pHevcDec->hMFCHevcHandle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport),
+ (pHevcDec->hMFCHevcHandle.videoInstInfo.specificInfo.dec.bLastFrameSupport),
+ (pHevcDec->hMFCHevcHandle.videoInstInfo.specificInfo.dec.bSkypeSupport));
+
+ if (pHevcDec->hMFCHevcHandle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport == VIDEO_TRUE)
+ pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bDynamicDPBMode = OMX_TRUE;
+
+ 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;
+
+ 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) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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 1
+ 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 hDestinationStartEvent;
+
+ 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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;
+
+#ifdef USE_CUSTOM_COMPONENT_SUPPORT
+ /* component 3 - video custom decoder HEVC */
+ Exynos_OSAL_Strcpy(ppExynosComponent[2]->componentName, EXYNOS_OMX_COMPONENT_HEVC_CUSTOM_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[2]->roles[0], EXYNOS_OMX_COMPONENT_HEVC_DEC_ROLE);
+ ppExynosComponent[2]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+ /* component 4 - video custom decoder HEVC for DRM */
+ Exynos_OSAL_Strcpy(ppExynosComponent[3]->componentName, EXYNOS_OMX_COMPONENT_HEVC_CUSTOM_DRM_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[3]->roles[0], EXYNOS_OMX_COMPONENT_HEVC_DEC_ROLE);
+ ppExynosComponent[3]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+#endif
+EXIT:
+ FunctionOut();
+
+ return MAX_COMPONENT_NUM;
+}
--- /dev/null
+/*
+ *
+ * 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 4
+#define MAX_COMPONENT_ROLE_NUM 1
+
+/* HEVC */
+#define EXYNOS_OMX_COMPONENT_HEVC_DEC "OMX.Exynos.HEVC.Decoder"
+#define EXYNOS_OMX_COMPONENT_HEVC_DRM_DEC "OMX.Exynos.HEVC.Decoder.secure"
+
+#define EXYNOS_OMX_COMPONENT_HEVC_CUSTOM_DEC "OMX.Exynos.hevc.dec"
+#define EXYNOS_OMX_COMPONENT_HEVC_CUSTOM_DRM_DEC "OMX.Exynos.hevc.dec.secure"
+
+#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
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Mpeg2dec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.MPEG2.Decoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+
+ifeq ($(BOARD_USE_ANB), true)
+LOCAL_CFLAGS += -DUSE_ANB
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_CUSTOM_COMPONENT_SUPPORT), true)
+LOCAL_CFLAGS += -DUSE_CUSTOM_COMPONENT_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/dec \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+/* 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"
+
+#define MPEG2_DEC_NUM_OF_EXTRA_BUFFERS 7
+
+//#define FULL_FRAME_SEARCH /* Full frame search not support*/
+
+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;
+
+ FunctionIn();
+
+ 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;
+ }
+
+ 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, "%s : there is no any profile/level", __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);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : supported profile(%x), level(%x)", __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+ 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, "%s : there is no any profile/level", __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, "%s : profile(%x)/level(%x) is %ssupported", __FUNCTION__,
+ pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+ (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+ return (bProfileSupport && bLevelSupport);
+}
+
+#if 0 /* unused code */
+static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+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;
+}
+
+#if 0 /* unused code */
+int Check_Mpeg2_Frame(
+ OMX_U8 *pInputStream,
+ OMX_U32 buffSize,
+ OMX_U32 flag,
+ OMX_BOOL bPreviousFrameEOF,
+ OMX_BOOL *pbEndOfFrame)
+{
+ FunctionIn();
+
+ *pbEndOfFrame = OMX_TRUE;
+
+ /* Frame Start code*/
+ if (pInputStream[0] != 0x00 || pInputStream[1] != 0x00 || pInputStream[2]!=0x01) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mpeg2 Frame Start Code not Found");
+ *pbEndOfFrame = OMX_FALSE;
+ }
+
+ FunctionOut();
+ return buffSize;
+}
+#endif
+
+static OMX_BOOL Check_Mpeg2_StartCode(
+ OMX_U8 *pInputStream,
+ OMX_U32 streamSize)
+{
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "streamSize: %d",streamSize);
+
+ if (streamSize < 3) {
+ return OMX_FALSE;
+ }
+
+ /* Frame Start code*/
+ if (pInputStream[0] != 0x00 || pInputStream[1] != 0x00 || pInputStream[2]!=0x01) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mpeg2 Frame Start Code not Found");
+ 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_MPEG2DEC_HANDLE *pMpeg2Dec = NULL;
+ EXYNOS_OMX_BASEPORT *pOutputPort = NULL;
+ ExynosVideoColorFormatType eVideoFormat = VIDEO_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate decoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+ /* 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, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.pDecOps->Init(pVideoInstInfo);
+ if (pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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;
+ }
+
+ /* 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+ pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+ pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.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 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;
+ ExynosVideoDecOps *pDecOps = 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;
+ pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+ 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) &&
+ (pOutputPort->bDynamicDPBMode == OMX_TRUE))
+ 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+ pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+ pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+
+ 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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Mpeg2CodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+ CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoDecBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
+ pBufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
+ pBufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+ }
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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);
+
+ /******************************************************/
+ /* V4L2 Destnation Setup for DPB Buffer Number Change */
+ /******************************************************/
+ ret = Mpeg2CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to Mpeg2CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+ /**********************************/
+ /* Codec Buffer Unregister */
+ /**********************************/
+ pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+ pBufferOps->Cleanup_Buffer(hMFCHandle);
+ }
+
+ Exynos_ResolutionUpdate(pOMXComponent);
+ } 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ int i, nOutbufs;
+
+ ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+
+ FunctionIn();
+
+ if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((nPortIndex == INPUT_PORT_INDEX) &&
+ (pMpeg2Dec->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, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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->bDestinationStart == OMX_TRUE)) {
+ Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+ for (i = 0; i < pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum; i++) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+ Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+ }
+ pOutbufOps->Clear_Queue(hMFCHandle);
+ }
+
+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;
+
+ 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) ||
+ (codecOutbufConf.bInterlaced != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.bInterlaced) ||
+#endif
+ (maxDPBNum != pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] DRC: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.nFrameWidth,
+ codecOutbufConf.nFrameHeight,
+ pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth,
+ pMpeg2Dec->hMFCMpeg2Handle.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__,
+ maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType,
+ pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum,
+ pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.eColorFormat,
+ pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.eFilledDataType);
+
+ 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 (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ pOutputPortDefinition->nBufferCountActual = pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum;
+ pOutputPortDefinition->nBufferCountMin = pMpeg2Dec->hMFCMpeg2Handle.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);
+ }
+ }
+
+ 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] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.cropRect.nWidth,
+ codecOutbufConf.cropRect.nHeight,
+ pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nWidth,
+ 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;
+
+ /** 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, "Failed to get geometry for parsed header info");
+ ret = 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] Mpeg2CodecSetup maxDPBNum: %d", pExynosComponent, __FUNCTION__, pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum);
+
+ /* get interlace info */
+ if (pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE)
+ Exynos_OSAL_Log(EXYNOS_LOG_INFO, "detect an interlaced type");
+
+ pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc = OMX_TRUE;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pCropRectangle = &(pOutputPort->cropRectangle);
+ pInputPortDefinition = &(pInputPort->portDefinition);
+ pOutputPortDefinition = &(pOutputPort->portDefinition);
+ } else {
+ pCropRectangle = &(pOutputPort->newCropRectangle);
+ pInputPortDefinition = &(pInputPort->newPortDefinition);
+ pOutputPortDefinition = &(pOutputPort->newPortDefinition);
+ }
+
+ 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) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.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;
+
+ pOutputPortDefinition->nBufferCountActual = pOutputPort->portDefinition.nBufferCountActual;
+ pOutputPortDefinition->nBufferCountMin = pOutputPort->portDefinition.nBufferCountMin;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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) ||
+ (pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.format.video.nFrameHeight != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight) ||
+ ((OMX_S32)pOutputPort->portDefinition.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;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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);
+ }
+ }
+
+ if ((pVideoDec->bReconfigDPB != OMX_TRUE) &&
+ ((pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nWidth) ||
+ (pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.cropRect.nHeight))) {
+ /* Check Crop */
+ 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);
+
+ /** 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;
+ int i;
+
+ FunctionIn();
+
+ if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ 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);
+ Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationStartEvent);
+
+ 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);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ bufferConf.nSizeImage = pExynosInputPort->portDefinition.nBufferSize;
+ } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+ }
+ 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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* set output geometry */
+ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+ bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+ if (bSupportFormat == OMX_TRUE) { /* supported by H/W */
+ if ((pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport == VIDEO_TRUE) &&
+ (eOutputFormat != (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled)) {
+ /* Needs to eanble DualDPB feature */
+ if (pDecOps->Enable_DualDPBMode(hMFCHandle) != VIDEO_ERROR_NONE) {
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ }
+ 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;
+ goto EXIT;
+ }
+ }
+
+ pMpeg2Dec->hMFCMpeg2Handle.MFCOutputColorType = bufferConf.eColorFormat;
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+ if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* input buffer enqueue for header parsing */
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
+// ret = OMX_ErrorInsufficientResources;
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+ goto EXIT;
+ }
+
+ /* start header parsing */
+ if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
+ ret = OMX_ErrorCodecInit;
+ 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, "CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...",
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0]) , *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 1),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 2), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 3),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 4), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 5),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 6), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 7));
+ if (ret != OMX_ErrorNone) {
+ Mpeg2CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+ pInbufOps->Cleanup_Buffer(hMFCHandle);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_SleepMillisec(0);
+ ret = OMX_ErrorInputDataDecodeYet;
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+ 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];
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_TRUE) {
+ if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enable Dynamic DPB");
+ 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 (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ /* get dpb count */
+ nOutbufs = pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Register output buffer */
+ ret = Mpeg2CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++)
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ } else {
+ if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ 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;
+
+ /* without Register output buffer */
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++) {
+ pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ (int *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+ pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+#ifdef USE_ANB
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+ int plane;
+
+ Exynos_OSAL_Memset((OMX_PTR)planes, 0, sizeof(ExynosVideoPlane) * MAX_BUFFER_PLANE);
+
+ /* get dpb count */
+ nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_TRUE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
+ planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
+ planes[plane].allocSize = nAllocLen[plane];
+ }
+
+ if (pOutbufOps->Register(hMFCHandle, planes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+
+ if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ } else {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+
+ } else {
+ /* get dpb count */
+ nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ }
+#else
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+#endif
+ }
+
+ pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nParamIndex) {
+ case OMX_IndexParamVideoMpeg2:
+ {
+ OMX_VIDEO_PARAM_MPEG2TYPE *pDstMpeg2Param = (OMX_VIDEO_PARAM_MPEG2TYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_MPEG2TYPE *pSrcMpeg2Param = NULL;
+ EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = 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) {
+ goto EXIT;
+ }
+
+ if (pDstMpeg2Param->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ 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) {
+ 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;
+ EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+ EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = 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;
+ }
+
+ pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
+ OMX_U32 portIndex = portDefinition->nPortIndex;
+ 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 *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (((pExynosPort->bIsANBEnabled == OMX_TRUE) || (pExynosPort->bStoreMetaData == OMX_TRUE)) &&
+ (pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
+ (portIndex == OUTPUT_PORT_INDEX)) {
+ portDefinition->format.video.eColorFormat =
+ (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HALPixelFormat((OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace, pExynosPort->ePlaneType);
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "portDefinition->format.video.eColorFormat: 0x%x", portDefinition->format.video.eColorFormat);
+ }
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ case OMX_IndexParamVideoMpeg2:
+ {
+ OMX_VIDEO_PARAM_MPEG2TYPE *pDstMpeg2Param = NULL;
+ OMX_VIDEO_PARAM_MPEG2TYPE *pSrcMpeg2Param = (OMX_VIDEO_PARAM_MPEG2TYPE *)pComponentParameterStructure;
+ EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL;
+ /* 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) {
+ goto EXIT;
+ }
+
+ if (pSrcMpeg2Param->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ 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_ErrorBadParameter;
+ goto EXIT;
+ }
+ }
+ break;
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_MPEG2TYPE *pDstMpeg2Component = NULL;
+ EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+
+ 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 (nIndex) {
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = NULL;
+ OMX_CONFIG_RECTTYPE *pSrcRectType = NULL;
+ OMX_CONFIG_RECTTYPE *pDstRectType = NULL;
+
+ pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ }
+
+ EXYNOS_OMX_BASEPORT *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;
+
+ 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 (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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ 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;
+ OMX_COMPONENTTYPE *pOMXComponent = NULL;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+ 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;
+ OMX_PTR hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ ExynosVideoInstInfo *pVideoInstInfo = &(pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo);
+
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+ int i, plane;
+
+ FunctionIn();
+
+ pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc = OMX_FALSE;
+ pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ 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;
+ }
+
+ pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+ pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+ pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+
+ Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+ if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ unsigned int nAllocLen[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
+ 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->hDestinationStartEvent);
+
+ 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_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ OMX_PTR hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+
+ int i, plane;
+
+ FunctionIn();
+
+ if (pVideoDec->csc_handle != NULL) {
+ csc_deinit(pVideoDec->csc_handle);
+ pVideoDec->csc_handle = NULL;
+ }
+
+ Exynos_OSAL_QueueTerminate(&pMpeg2Dec->bypassBufferInfoQ);
+
+ Exynos_OSAL_SignalTerminate(pMpeg2Dec->hDestinationStartEvent);
+ pMpeg2Dec->hDestinationStartEvent = 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);
+ } 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);
+ } 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];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ OMX_U32 oneFrameSize = pSrcInputData->dataLen;
+
+ ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
+ 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;
+ int i;
+
+ FunctionIn();
+
+ if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = Mpeg2CodecSrcSetup(pOMXComponent, pSrcInputData);
+ goto EXIT;
+ }
+
+ if ((pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_FALSE) &&
+ (pVideoDec->bForceHeaderParsing == OMX_FALSE)) {
+ ret = Mpeg2CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to Mpeg2CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ }
+
+ if (((bInStartCode = Check_Mpeg2_StartCode(pSrcInputData->multiPlaneBuffer.dataBuffer[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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x, oneFrameSize: %d", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp, pSrcInputData->nFlags, oneFrameSize);
+ 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;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] bufferHeader: 0x%x, dataBuffer: 0x%x", pExynosComponent, __FUNCTION__, pSrcInputData->bufferHeader, pSrcInputData->multiPlaneBuffer.dataBuffer[0]);
+
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
+ tempBufferHeader.nFlags = pSrcInputData->nFlags;
+ tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+ pPrivate = (void *)&tempBufferHeader;
+ } else {
+ pPrivate = (void *)pSrcInputData->bufferHeader;
+ }
+ codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ } else if (bInStartCode == OMX_FALSE) {
+ ret = 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
+ ExynosVideoBuffer *pVideoBuffer;
+ 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->allocSize = 0;
+ pSrcOutputData->pPrivate = NULL;
+ } else {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pSrcOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[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, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#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];
+
+ ExynosVideoDecOps *pDecOps = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
+ 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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ 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] : %d => ADDR[%d]: 0x%x", pExynosComponent, __FUNCTION__, __LINE__, i,
+ pDstInputData->multiPlaneBuffer.dataBuffer[i]);
+ }
+
+ if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+ (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+ (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+ ret = Mpeg2CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to Mpeg2CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ codecReturn = pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ } else {
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ }
+
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &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;
+
+ OMX_S32 indexTimestamp = 0;
+ int plane, nPlaneCnt;
+
+ FunctionIn();
+
+ if (pMpeg2Dec->bDestinationStart == OMX_FALSE) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ while (1) {
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
+ if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+
+ if (pVideoBuffer == NULL) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ } else {
+ 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, "HW is not available");
+ 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(pExynosOutputPort))) {
+ ret = OMX_ErrorNone;
+ break;
+ }
+ }
+
+ if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+ (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) {
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pExynosOutputPort->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(pExynosOutputPort);
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pDstOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pDstOutputData->multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
+ pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+ pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
+ }
+ pDstOutputData->usedDataLen = 0;
+ pDstOutputData->pPrivate = pVideoBuffer;
+ if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ int i = 0;
+ pDstOutputData->pPrivate = NULL;
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ if (pDstOutputData->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+ /* get interlace frame info */
+ if ((pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+ (pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
+ (pVideoBuffer->planes[2].addr != NULL)) {
+ /* only NV12 case */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] interlace type = %x", pExynosComponent, __FUNCTION__, pVideoBuffer->interlacedType);
+ *(int *)(pVideoBuffer->planes[2].addr) = pVideoBuffer->interlacedType;
+ }
+
+ pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+ bufferGeometry = &pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf;
+ pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
+ pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
+ pBufferInfo->imageStride = bufferGeometry->nStride;
+ pBufferInfo->ColorFormat = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+ Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+ 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 timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if (pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport == VIDEO_FALSE) {
+ if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+ (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ 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] indexTimestamp(%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 = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ } else {
+ pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+ }
+ } else {
+ if ((displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+ ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+
+ if ((pExynosComponent->bBehaviorEOS == OMX_TRUE) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME)) {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (displayStatus != VIDEO_FRAME_STATUS_LAST_FRAME) {
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ } else {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 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 (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;
+ }
+
+ 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_SignalReset(pMpeg2Dec->hSourceStartEvent);
+ }
+
+ ret = Exynos_Mpeg2Dec_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) &&
+ (pExynosComponent->currentState == OMX_StateExecuting)) {
+ 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_ErrorOutputBufferUseYet;
+ else
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pMpeg2Dec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pMpeg2Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pMpeg2Dec->hDestinationStartEvent);
+ }
+ 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;
+ }
+
+ 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 (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_TRUE) {
+ ret = Exynos_Mpeg2Dec_DstIn(pOMXComponent, pDstInputData);
+ if (ret != OMX_ErrorNone) {
+ 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 (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pMpeg2Dec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pMpeg2Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pMpeg2Dec->hDestinationStartEvent);
+ }
+ if (Exynos_OSAL_GetElemNum(&pMpeg2Dec->bypassBufferInfoQ) > 0) {
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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)) {
+ 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, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG2_DEC, componentName) != 0) &&
+ (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG2_CUSTOM_DEC, componentName) != 0)) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+
+ 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 | BUFFER_ANBSHARE;
+ 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;
+
+#if 0 /* unused code */
+ pVideoDec->exynos_checkInputFrame = &Check_Mpeg2_Frame;
+ pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ 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, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ Exynos_OSAL_Free(pMpeg2Dec);
+ pMpeg2Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->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]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
+ Exynos_OSAL_Free(pMpeg2Dec);
+ pMpeg2Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for dec %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport),
+ (pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport),
+ (pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport),
+ (pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.specificInfo.dec.bSkypeSupport));
+
+ if (pMpeg2Dec->hMFCMpeg2Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport == VIDEO_TRUE)
+ pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bDynamicDPBMode = OMX_TRUE;
+
+ 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;
+
+ 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) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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 hDestinationStartEvent;
+
+ 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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;
+#ifdef USE_CUSTOM_COMPONENT_SUPPORT
+ /* component 2 - video custom decoder MPEG2 */
+ Exynos_OSAL_Strcpy(ppExynosComponent[1]->componentName, EXYNOS_OMX_COMPONENT_MPEG2_CUSTOM_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[1]->roles[0], EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE);
+ ppExynosComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+#endif
+EXIT:
+ FunctionOut();
+ return MAX_COMPONENT_NUM;
+}
--- /dev/null
+/*
+ *
+ * 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 2
+#define MAX_COMPONENT_ROLE_NUM 1
+
+/* MPEG2 */
+#define EXYNOS_OMX_COMPONENT_MPEG2_DEC "OMX.Exynos.MPEG2.Decoder"
+#define EXYNOS_OMX_COMPONENT_MPEG2_CUSTOM_DEC "OMX.Exynos.mpeg2.dec"
+#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
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Mpeg4dec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.MPEG4.Decoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+
+ifeq ($(BOARD_USE_ANB), true)
+LOCAL_CFLAGS += -DUSE_ANB
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_CUSTOM_COMPONENT_SUPPORT), true)
+LOCAL_CFLAGS += -DUSE_CUSTOM_COMPONENT_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_TIMESTAMP_REORDER_SUPPORT), true)
+LOCAL_CFLAGS += -DUSE_TIMESTAMP_REORDER_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/dec \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+/* 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"
+
+#define MPEG4_DEC_NUM_OF_EXTRA_BUFFERS 7
+
+//#define FULL_FRAME_SEARCH
+
+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;
+
+ FunctionIn();
+
+ 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;
+ }
+
+ while ((pMpeg4Dec->hMFCMpeg4Handle.maxLevel >> nLevelCnt) > 0) {
+ nLevelCnt++;
+ }
+
+ if ((pMpeg4Dec->hMFCMpeg4Handle.nProfileCnt == 0) ||
+ (nLevelCnt == 0)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : there is no any profile/level", __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);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : supported profile(%x), level(%x)", __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+ 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, "%s : there is no any profile/level", __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, "%s : profile(%x)/level(%x) is %ssupported", __FUNCTION__,
+ pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+ (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+ return (bProfileSupport && bLevelSupport);
+}
+
+#if 0 /* unused code */
+static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+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;
+
+#if 0 /* unused code */
+static int Check_Mpeg4_Frame(
+ OMX_U8 *pInputStream,
+ OMX_U32 buffSize,
+ OMX_U32 flag,
+ OMX_BOOL bPreviousFrameEOF,
+ OMX_BOOL *pbEndOfFrame)
+{
+ OMX_U32 len;
+ int readStream;
+ unsigned startCode;
+ OMX_BOOL bFrameStart;
+
+ len = 0;
+ bFrameStart = OMX_FALSE;
+
+ if (flag & OMX_BUFFERFLAG_CODECCONFIG) {
+ if (*pInputStream == 0x03) { /* FIMV1 */
+ BitmapInfoHhr *pInfoHeader;
+
+ pInfoHeader = (BitmapInfoHhr *)(pInputStream + 1);
+ /* FIXME */
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "############## NOT SUPPORTED #################");
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "width(%d), height(%d)", pInfoHeader->BiWidth, pInfoHeader->BiHeight);
+ gbFIMV1 = OMX_TRUE;
+ *pbEndOfFrame = OMX_TRUE;
+ return buffSize;
+ }
+ }
+
+ if (gbFIMV1) {
+ *pbEndOfFrame = OMX_TRUE;
+ return buffSize;
+ }
+
+ if (bPreviousFrameEOF == OMX_FALSE)
+ bFrameStart = OMX_TRUE;
+
+ startCode = 0xFFFFFFFF;
+ if (bFrameStart == OMX_FALSE) {
+ /* find VOP start code */
+ while(startCode != 0x1B6) {
+ readStream = *(pInputStream + len);
+ startCode = (startCode << 8) | readStream;
+ len++;
+ if (len > buffSize)
+ goto EXIT;
+ }
+ }
+
+ /* find next VOP start code */
+ startCode = 0xFFFFFFFF;
+ while ((startCode != 0x1B6)) {
+ readStream = *(pInputStream + len);
+ startCode = (startCode << 8) | readStream;
+ len++;
+ if (len > buffSize)
+ goto EXIT;
+ }
+
+ *pbEndOfFrame = OMX_TRUE;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "1. Check_Mpeg4_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 4, buffSize);
+
+ return len - 4;
+
+EXIT :
+ *pbEndOfFrame = OMX_FALSE;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "2. Check_Mpeg4_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 1, buffSize);
+
+ return --len;
+}
+
+static int Check_H263_Frame(
+ OMX_U8 *pInputStream,
+ OMX_U32 buffSize,
+ OMX_U32 flag,
+ OMX_BOOL bPreviousFrameEOF,
+ OMX_BOOL *pbEndOfFrame)
+{
+ OMX_U32 len;
+ int readStream;
+ unsigned startCode;
+ OMX_BOOL bFrameStart = 0;
+ unsigned pTypeMask = 0x03;
+ unsigned pType = 0;
+
+ len = 0;
+ bFrameStart = OMX_FALSE;
+
+ if (bPreviousFrameEOF == OMX_FALSE)
+ bFrameStart = OMX_TRUE;
+
+ startCode = 0xFFFFFFFF;
+ if (bFrameStart == OMX_FALSE) {
+ /* find 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 > buffSize)
+ goto EXIT;
+ }
+ }
+
+ /* find next PSC */
+ startCode = 0xFFFFFFFF;
+ pType = 0;
+ while (((startCode << 8 >> 10) != 0x20) || (pType != 0x02)) {
+ readStream = *(pInputStream + len);
+ startCode = (startCode << 8) | readStream;
+
+ readStream = *(pInputStream + len + 1);
+ pType = readStream & pTypeMask;
+
+ len++;
+ if (len > buffSize)
+ goto EXIT;
+ }
+
+ *pbEndOfFrame = OMX_TRUE;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "1. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 3, buffSize);
+
+ return len - 3;
+
+EXIT :
+
+ *pbEndOfFrame = OMX_FALSE;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "2. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 1, buffSize);
+
+ return --len;
+}
+#endif
+
+static OMX_BOOL Check_Stream_StartCode(
+ OMX_U8 *pInputStream,
+ OMX_U32 streamSize,
+ CODEC_TYPE codecType)
+{
+ switch (codecType) {
+ case CODEC_TYPE_MPEG4:
+ if (gbFIMV1) {
+ return OMX_TRUE;
+ } else {
+ if (streamSize < 3) {
+ return OMX_FALSE;
+ } else if ((pInputStream[0] == 0x00) &&
+ (pInputStream[1] == 0x00) &&
+ (pInputStream[2] == 0x01)) {
+ return OMX_TRUE;
+ } else {
+ return OMX_FALSE;
+ }
+ }
+ 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__);
+ return OMX_FALSE;
+ } else {
+ return OMX_TRUE;
+ }
+ } else {
+ return OMX_FALSE;
+ }
+ default:
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: undefined codec type (%d)", __FUNCTION__, codecType);
+ return OMX_FALSE;
+ }
+}
+
+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_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate decoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+ /* 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, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.pDecOps->Init(pVideoInstInfo);
+ if (pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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;
+ }
+
+ /* 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+ pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+ pOutbufOps = pMpeg4Dec->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;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = 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;
+ pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+ 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) &&
+ (pOutputPort->bDynamicDPBMode == OMX_TRUE))
+ 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+ pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+ pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+
+ 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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+ CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoDecBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
+ pBufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
+ pBufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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);
+
+ /******************************************************/
+ /* V4L2 Destnation Setup for DPB Buffer Number Change */
+ /******************************************************/
+ ret = Mpeg4CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to Mpeg4CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+ /**********************************/
+ /* Codec Buffer Unregister */
+ /**********************************/
+ pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+ pBufferOps->Cleanup_Buffer(hMFCHandle);
+ }
+
+ Exynos_ResolutionUpdate(pOMXComponent);
+ } 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;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ int i, nOutbufs;
+
+ ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+
+ FunctionIn();
+
+ if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((nPortIndex == INPUT_PORT_INDEX) &&
+ (pMpeg4Dec->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, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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->bDestinationStart == OMX_TRUE)) {
+ Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+ for (i = 0; i < pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum; i++) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+ Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+ }
+ pOutbufOps->Clear_Queue(hMFCHandle);
+ }
+
+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;
+
+ 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) ||
+ (codecOutbufConf.bInterlaced != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.bInterlaced) ||
+#endif
+ (maxDPBNum != pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] DRC: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.nFrameWidth,
+ codecOutbufConf.nFrameHeight,
+ pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth,
+ pMpeg4Dec->hMFCMpeg4Handle.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__,
+ maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType,
+ pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum,
+ pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.eColorFormat,
+ pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.eFilledDataType);
+
+ 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 (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ pOutputPortDefinition->nBufferCountActual = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum;
+ pOutputPortDefinition->nBufferCountMin = pMpeg4Dec->hMFCMpeg4Handle.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);
+ }
+ }
+
+ 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] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.cropRect.nWidth,
+ codecOutbufConf.cropRect.nHeight,
+ pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nWidth,
+ 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;
+
+ /** 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, "Failed to get geometry for parsed header info");
+ ret = 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] Mpeg4CodecSetup maxDPBNum: %d", pExynosComponent, __FUNCTION__, pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum);
+
+ /* get interlace info */
+ if (pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE)
+ Exynos_OSAL_Log(EXYNOS_LOG_INFO, "detect an interlaced type");
+
+ pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_TRUE;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pCropRectangle = &(pOutputPort->cropRectangle);
+ pInputPortDefinition = &(pInputPort->portDefinition);
+ pOutputPortDefinition = &(pOutputPort->portDefinition);
+ } else {
+ pCropRectangle = &(pOutputPort->newCropRectangle);
+ pInputPortDefinition = &(pInputPort->newPortDefinition);
+ pOutputPortDefinition = &(pOutputPort->newPortDefinition);
+ }
+
+ 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) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.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;
+
+ pOutputPortDefinition->nBufferCountActual = pOutputPort->portDefinition.nBufferCountActual;
+ pOutputPortDefinition->nBufferCountMin = pOutputPort->portDefinition.nBufferCountMin;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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) ||
+ (pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight) ||
+ ((OMX_S32)pOutputPort->portDefinition.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;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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);
+ }
+ }
+
+ if ((pVideoDec->bReconfigDPB != OMX_TRUE) &&
+ ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nWidth) ||
+ (pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nHeight))) {
+ /* Check Crop */
+ 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);
+
+ /** 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;
+ int i;
+
+ FunctionIn();
+
+ if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ 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);
+ Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationStartEvent);
+
+ 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);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ bufferConf.nSizeImage = pExynosInputPort->portDefinition.nBufferSize;
+ } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+ }
+ 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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* set output geometry */
+ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+ bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+ if (bSupportFormat == OMX_TRUE) { /* supported by H/W */
+ if ((pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport == VIDEO_TRUE) &&
+ (eOutputFormat != (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled)) {
+ /* Needs to eanble DualDPB feature */
+ if (pDecOps->Enable_DualDPBMode(hMFCHandle) != VIDEO_ERROR_NONE) {
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ }
+ 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;
+ goto EXIT;
+ }
+ }
+
+ pMpeg4Dec->hMFCMpeg4Handle.MFCOutputColorType = bufferConf.eColorFormat;
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+ if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* input buffer enqueue for header parsing */
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
+// ret = OMX_ErrorInsufficientResources;
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+ goto EXIT;
+ }
+
+ /* start header parsing */
+ if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
+ ret = OMX_ErrorCodecInit;
+ 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, "CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...",
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0]) , *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 1),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 2), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 3),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 4), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 5),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 6), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 7));
+ if (ret != OMX_ErrorNone) {
+ Mpeg4CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+ pInbufOps->Cleanup_Buffer(hMFCHandle);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_SleepMillisec(0);
+ ret = OMX_ErrorInputDataDecodeYet;
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+ 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];
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_TRUE) {
+ if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enable Dynamic DPB");
+ 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 (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ /* get dpb count */
+ nOutbufs = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Register output buffer */
+ ret = Mpeg4CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++)
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ } else {
+ if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ 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;
+
+ /* without Register output buffer */
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++) {
+ pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ (int *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+ pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+#ifdef USE_ANB
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+ int plane;
+
+ Exynos_OSAL_Memset((OMX_PTR)planes, 0, sizeof(ExynosVideoPlane) * MAX_BUFFER_PLANE);
+
+ /* get dpb count */
+ nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_TRUE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
+ planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
+ planes[plane].allocSize = nAllocLen[plane];
+ }
+
+ if (pOutbufOps->Register(hMFCHandle, planes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+
+ if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ } else {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ } else {
+ /* get dpb count */
+ nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ }
+#else
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+#endif
+ }
+
+ pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nParamIndex) {
+ case OMX_IndexParamVideoMpeg4:
+ {
+ OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL;
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = 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) {
+ goto EXIT;
+ }
+
+ if (pDstMpeg4Param->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = 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) {
+ goto EXIT;
+ }
+
+ if (pDstH263Param->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ goto EXIT;
+ }
+
+ codecType = ((EXYNOS_MPEG4DEC_HANDLE *)(((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->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) {
+ 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;
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
+ OMX_S32 codecType;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = 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;
+ }
+
+ pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ case OMX_IndexExynosParamReorderMode: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ goto EXIT;
+
+ pReorderParam->bReorderMode = pVideoDec->bReorderMode;
+ }
+ break;
+#endif
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
+ OMX_U32 portIndex = portDefinition->nPortIndex;
+ 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 *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (((pExynosPort->bIsANBEnabled == OMX_TRUE) || (pExynosPort->bStoreMetaData == OMX_TRUE)) &&
+ (pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
+ (portIndex == OUTPUT_PORT_INDEX)) {
+ portDefinition->format.video.eColorFormat =
+ (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HALPixelFormat((OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace, pExynosPort->ePlaneType);
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "portDefinition->format.video.eColorFormat: 0x%x", portDefinition->format.video.eColorFormat);
+ }
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+ case OMX_IndexParamVideoMpeg4:
+ {
+ OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL;
+ OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure;
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
+ /* 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) {
+ goto EXIT;
+ }
+
+ if (pSrcMpeg4Param->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
+ /* 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) {
+ goto EXIT;
+ }
+
+ if (pSrcH263Param->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ 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_ErrorBadParameter;
+ 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;
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
+ OMX_S32 codecType;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ case OMX_IndexExynosParamReorderMode: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ goto EXIT;
+
+ pVideoDec->bReorderMode = pReorderParam->bReorderMode;
+ }
+ break;
+#endif
+ 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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = NULL;
+ OMX_CONFIG_RECTTYPE *pSrcRectType = NULL;
+ OMX_CONFIG_RECTTYPE *pDstRectType = NULL;
+
+ pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ }
+
+ EXYNOS_OMX_BASEPORT *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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) {
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_REORDER_MODE) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamReorderMode;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ }
+#endif
+
+ 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;
+ OMX_PTR hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ ExynosVideoInstInfo *pVideoInstInfo = &(pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo);
+
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+ int i, plane;
+
+ FunctionIn();
+
+ pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE;
+ pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ 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;
+ }
+
+ pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+ pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+ pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+
+ Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+ if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ unsigned int nAllocLen[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
+ 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->hDestinationStartEvent);
+
+ 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_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ OMX_PTR hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+
+ int i, plane;
+
+ FunctionIn();
+
+ if (pVideoDec->csc_handle != NULL) {
+ csc_deinit(pVideoDec->csc_handle);
+ pVideoDec->csc_handle = NULL;
+ }
+
+ Exynos_OSAL_QueueTerminate(&pMpeg4Dec->bypassBufferInfoQ);
+
+ Exynos_OSAL_SignalTerminate(pMpeg4Dec->hDestinationStartEvent);
+ pMpeg4Dec->hDestinationStartEvent = 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);
+ } 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);
+ } 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];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ OMX_U32 oneFrameSize = pSrcInputData->dataLen;
+
+ ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
+ 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;
+ int i;
+
+ FunctionIn();
+
+ if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = Mpeg4CodecSrcSetup(pOMXComponent, pSrcInputData);
+ goto EXIT;
+ }
+
+ if ((pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE) &&
+ (pVideoDec->bForceHeaderParsing == OMX_FALSE)) {
+ ret = Mpeg4CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to Mpeg4CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ }
+
+ if (((pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) ||
+ ((bInStartCode = Check_Stream_StartCode(pSrcInputData->multiPlaneBuffer.dataBuffer[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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x, oneFrameSize: %d", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp, pSrcInputData->nFlags, oneFrameSize);
+
+ 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;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] bufferHeader: 0x%x, dataBuffer: 0x%x", pExynosComponent, __FUNCTION__, pSrcInputData->bufferHeader, pSrcInputData->multiPlaneBuffer.dataBuffer[0]);
+
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
+ tempBufferHeader.nFlags = pSrcInputData->nFlags;
+ tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+ pPrivate = (void *)&tempBufferHeader;
+ } else {
+ pPrivate = (void *)pSrcInputData->bufferHeader;
+ }
+ codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ } else if (bInStartCode == OMX_FALSE) {
+ ret = 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
+ ExynosVideoBuffer *pVideoBuffer;
+ 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->allocSize = 0;
+ pSrcOutputData->pPrivate = NULL;
+ } else {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pSrcOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[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, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#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];
+
+ ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
+ 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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ 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] : %d => ADDR[%d]: 0x%x", pExynosComponent, __FUNCTION__, __LINE__, i,
+ pDstInputData->multiPlaneBuffer.dataBuffer[i]);
+ }
+
+ if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+ (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+ (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+ ret = Mpeg4CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to Mpeg4CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ codecReturn = pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ } else {
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ }
+
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &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;
+
+ OMX_S32 indexTimestamp = 0;
+ int plane, nPlaneCnt;
+
+ FunctionIn();
+
+ if (pMpeg4Dec->bDestinationStart == OMX_FALSE) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ while (1) {
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
+ if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+
+ if (pVideoBuffer == NULL) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ } else {
+ 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, "HW is not available");
+ 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(pExynosOutputPort))) {
+ ret = OMX_ErrorNone;
+ break;
+ }
+ }
+
+ if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+ (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) {
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pExynosOutputPort->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(pExynosOutputPort);
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pDstOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pDstOutputData->multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
+ pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+ pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
+ }
+ pDstOutputData->usedDataLen = 0;
+ pDstOutputData->pPrivate = pVideoBuffer;
+ if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ int i = 0;
+ pDstOutputData->pPrivate = NULL;
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ if (pDstOutputData->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+ /* get interlace frame info */
+ if ((pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+ (pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
+ (pVideoBuffer->planes[2].addr != NULL)) {
+ /* only NV12 case */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] interlace type = %x", pExynosComponent, __FUNCTION__, pVideoBuffer->interlacedType);
+ *(int *)(pVideoBuffer->planes[2].addr) = pVideoBuffer->interlacedType;
+ }
+
+ pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+ bufferGeometry = &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf;
+ pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
+ pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
+ pBufferInfo->imageStride = bufferGeometry->nStride;
+ pBufferInfo->ColorFormat = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+ Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+ 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 timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
+ }
+ } 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 reorder timestamp %lld us (%.2f secs), sCurrentTimestamp.nIndex: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, sCurrentTimestamp.nIndex, pDstOutputData->nFlags);
+ }
+
+ if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_H263) {
+ pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp++;
+ pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if (pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport == VIDEO_FALSE) {
+ if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+ (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ 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] indexTimestamp(%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 = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ } else {
+ pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+ }
+ } else {
+ if ((displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+ ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+
+ if ((pExynosComponent->bBehaviorEOS == OMX_TRUE) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME)) {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (displayStatus != VIDEO_FRAME_STATUS_LAST_FRAME) {
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ } else {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 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 (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;
+ }
+
+ 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_SignalReset(pMpeg4Dec->hSourceStartEvent);
+ }
+
+ ret = Exynos_Mpeg4Dec_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) &&
+ (pExynosComponent->currentState == OMX_StateExecuting)) {
+ 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_ErrorOutputBufferUseYet;
+ else
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pMpeg4Dec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationStartEvent);
+ }
+ 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;
+ }
+
+ 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 (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE) {
+ ret = Exynos_Mpeg4Dec_DstIn(pOMXComponent, pDstInputData);
+ if (ret != OMX_ErrorNone) {
+ 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 (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pMpeg4Dec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationStartEvent);
+ }
+ if (Exynos_OSAL_GetElemNum(&pMpeg4Dec->bypassBufferInfoQ) > 0) {
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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)) {
+ 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, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG4_DEC, componentName) == 0) ||
+ (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG4_CUSTOM_DEC, componentName) == 0)) {
+ codecType = CODEC_TYPE_MPEG4;
+ bSecureMode = OMX_FALSE;
+ } else if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H263_DEC, componentName) == 0) ||
+ (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H263_CUSTOM_DEC, componentName) == 0)) {
+ codecType = CODEC_TYPE_H263;
+ bSecureMode = OMX_FALSE;
+ } else if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG4_DRM_DEC, componentName) == 0) ||
+ (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG4_CUSTOM_DRM_DEC, componentName) == 0)) {
+ codecType = CODEC_TYPE_MPEG4;
+ bSecureMode = OMX_TRUE;
+ } else {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+
+ 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 | BUFFER_ANBSHARE;
+ 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;
+
+#if 0 /* unused code */
+ if (codecType == CODEC_TYPE_MPEG4)
+ pVideoDec->exynos_checkInputFrame = &Check_Mpeg4_Frame;
+ else
+ pVideoDec->exynos_checkInputFrame = &Check_H263_Frame;
+
+ pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ 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, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ Exynos_OSAL_Free(pMpeg4Dec);
+ pMpeg4Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->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]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
+ Exynos_OSAL_Free(pMpeg4Dec);
+ pMpeg4Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for dec %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport),
+ (pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport),
+ (pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport),
+ (pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.specificInfo.dec.bSkypeSupport));
+
+ if (pMpeg4Dec->hMFCMpeg4Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport == VIDEO_TRUE)
+ pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bDynamicDPBMode = OMX_TRUE;
+
+ 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;
+
+ 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) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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 hDestinationStartEvent;
+
+ 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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;
+#ifdef USE_CUSTOM_COMPONENT_SUPPORT
+ /* component 4 - video custom decoder MPEG4 */
+ Exynos_OSAL_Strcpy(ppExynosComponent[3]->componentName, EXYNOS_OMX_COMPONENT_MPEG4_CUSTOM_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[3]->roles[0], EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE);
+ ppExynosComponent[3]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+ /* component 5 - video custom decoder MPEG4 for DRM */
+ Exynos_OSAL_Strcpy(ppExynosComponent[4]->componentName, EXYNOS_OMX_COMPONENT_MPEG4_CUSTOM_DRM_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[4]->roles[0], EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE);
+ ppExynosComponent[4]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+ /* component 6 - video custom decoder H.263 */
+ Exynos_OSAL_Strcpy(ppExynosComponent[5]->componentName, EXYNOS_OMX_COMPONENT_H263_CUSTOM_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[5]->roles[0], EXYNOS_OMX_COMPONENT_H263_DEC_ROLE);
+ ppExynosComponent[5]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+#endif
+EXIT:
+ FunctionOut();
+
+ return MAX_COMPONENT_NUM;
+}
--- /dev/null
+/*
+ *
+ * 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 6
+#define MAX_COMPONENT_ROLE_NUM 1
+
+/* MPEG4 */
+#define EXYNOS_OMX_COMPONENT_MPEG4_DEC "OMX.Exynos.MPEG4.Decoder"
+#define EXYNOS_OMX_COMPONENT_MPEG4_DRM_DEC "OMX.Exynos.MPEG4.Decoder.secure"
+
+#define EXYNOS_OMX_COMPONENT_MPEG4_CUSTOM_DEC "OMX.Exynos.mpeg4.dec"
+#define EXYNOS_OMX_COMPONENT_MPEG4_CUSTOM_DRM_DEC "OMX.Exynos.mpeg4.dec.secure"
+
+#define EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE "video_decoder.mpeg4"
+
+
+/* H.263 */
+#define EXYNOS_OMX_COMPONENT_H263_DEC "OMX.Exynos.H263.Decoder"
+#define EXYNOS_OMX_COMPONENT_H263_CUSTOM_DEC "OMX.Exynos.h263.dec"
+#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
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Wmvdec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.WMV.Decoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+
+ifeq ($(BOARD_USE_ANB), true)
+LOCAL_CFLAGS += -DUSE_ANB
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_CUSTOM_COMPONENT_SUPPORT), true)
+LOCAL_CFLAGS += -DUSE_CUSTOM_COMPONENT_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_TIMESTAMP_REORDER_SUPPORT), true)
+LOCAL_CFLAGS += -DUSE_TIMESTAMP_REORDER_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/dec \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+/* 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 WMV_DEC_NUM_OF_EXTRA_BUFFERS 7
+
+#define SL_META_LEN 36 /* sequence layer metadata length in bytes */
+
+/* parser does not send start code on Stagefright */
+#define WO_START_CODE
+
+/* Enable or disable "WMV3_ADDITIONAL_START_CODE" based on MFC F/W's need */
+//#define WMV3_ADDITIONAL_START_CODE
+
+//#define FULL_FRAME_SEARCH
+
+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;
+
+ FunctionIn();
+
+ 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, "%s : there is no any profile/level", __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, "%s : supported profile(%x), level(%x)", __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+ 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, "%s : there is no any profile/level", __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, "%s : profile(%x)/level(%x) is %ssupported", __FUNCTION__,
+ pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+ (ret == OMX_TRUE)? "":"not ");
+EXIT:
+ return ret;
+}
+
+#if 0 /* unused code */
+static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+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, "WMV_FORMAT_WMV3");
+ ret = WMV_FORMAT_WMV3;
+ } else if (((pCheckBuffer[3] == 0x01) &&
+ (pCheckBuffer[4] == 0x0F)) ||
+ ((pCheckBuffer[2] == 0x01) &&
+ (pCheckBuffer[3] == 0x0F))) {
+ Exynos_OSAL_Log(EXYNOS_LOG_INFO, "WMV_FORMAT_VC1");
+ ret = WMV_FORMAT_VC1;
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "WMV_FORMAT_UNKNOWN");
+ }
+
+ return ret;
+}
+
+#if 0 /* unused code */
+int Check_Wmv_Frame(
+ OMX_U8 *pInputStream,
+ OMX_U32 buffSize,
+ OMX_U32 flag,
+ OMX_BOOL bPreviousFrameEOF,
+ OMX_BOOL *pbEndOfFrame)
+{
+ OMX_U32 compressionID;
+ OMX_BOOL bFrameStart;
+ OMX_U32 len, readStream;
+ OMX_U32 startCode;
+
+ int retVal = (int)buffSize;
+ static WMV_FORMAT wmvFormat;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "buffSize = %d", buffSize);
+
+ len = 0;
+ bFrameStart = OMX_FALSE;
+
+ if (flag & OMX_BUFFERFLAG_CODECCONFIG)
+ wmvFormat = getFormatType(pInputStream);
+
+ if (wmvFormat == WMV_FORMAT_WMV3) {
+ *pbEndOfFrame = OMX_TRUE;
+ return retVal;
+ }
+
+#ifdef WO_START_CODE
+ /* parser does not send start code on Stagefright */
+ if (wmvFormat == WMV_FORMAT_VC1) {
+ *pbEndOfFrame = OMX_TRUE;
+ return retVal;
+ }
+#else
+ /* TODO : for comformanc test based on common buffer scheme w/o parser */
+
+ if (bPreviousFrameEOF == OMX_FALSE)
+ bFrameStart = OMX_TRUE;
+
+ startCode = 0xFFFFFFFF;
+ if (bFrameStart == OMX_FALSE) {
+ /* find Frame start code */
+ while(startCode != 0x10D) {
+ readStream = *(pInputStream + len);
+ startCode = (startCode << 8) | readStream;
+ len++;
+ if (len > retVal)
+ goto EXIT;
+ }
+ }
+
+ /* find next Frame start code */
+ startCode = 0xFFFFFFFF;
+ while ((startCode != 0x10D)) {
+ readStream = *(pInputStream + len);
+ startCode = (startCode << 8) | readStream;
+ len++;
+ if (len > retVal)
+ goto EXIT;
+ }
+
+ *pbEndOfFrame = OMX_TRUE;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "1. Check_Wmv_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 4, buffSize);
+
+ return len - 4;
+#endif
+
+EXIT :
+ *pbEndOfFrame = OMX_FALSE;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "2. Check_Wmv_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 1, buffSize);
+
+ return --len;
+}
+#endif
+
+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_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate decoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+ /* 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, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pWmvDec->hMFCWmvHandle.hMFCHandle = pWmvDec->hMFCWmvHandle.pDecOps->Init(pVideoInstInfo);
+ if (pWmvDec->hMFCWmvHandle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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;
+ }
+
+ /* 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
+ pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
+ pOutbufOps = pWmvDec->hMFCWmvHandle.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 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;
+ ExynosVideoDecOps *pDecOps = 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;
+ pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
+ 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) &&
+ (pOutputPort->bDynamicDPBMode == OMX_TRUE))
+ 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
+ pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
+ pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+
+ 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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE WMVCodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
+ CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoDecBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
+ pBufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
+ pBufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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);
+
+ /******************************************************/
+ /* V4L2 Destnation Setup for DPB Buffer Number Change */
+ /******************************************************/
+ ret = WmvCodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to WmvCodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+ /**********************************/
+ /* Codec Buffer Unregister */
+ /**********************************/
+ pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+ pBufferOps->Cleanup_Buffer(hMFCHandle);
+ }
+
+ Exynos_ResolutionUpdate(pOMXComponent);
+ } 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ int i, nOutbufs;
+
+ ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.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, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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->bDestinationStart == OMX_TRUE)) {
+ Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+ for (i = 0; i < pWmvDec->hMFCWmvHandle.maxDPBNum; i++) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+ Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+ }
+ pOutbufOps->Clear_Queue(hMFCHandle);
+ }
+
+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;
+
+ 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) ||
+ (codecOutbufConf.bInterlaced != pWmvDec->hMFCWmvHandle.codecOutbufConf.bInterlaced) ||
+#endif
+ (maxDPBNum != pWmvDec->hMFCWmvHandle.maxDPBNum)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] DRC: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.nFrameWidth,
+ codecOutbufConf.nFrameHeight,
+ pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth,
+ pWmvDec->hMFCWmvHandle.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__,
+ maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType,
+ pWmvDec->hMFCWmvHandle.maxDPBNum,
+ pWmvDec->hMFCWmvHandle.codecOutbufConf.eColorFormat,
+ pWmvDec->hMFCWmvHandle.codecOutbufConf.eFilledDataType);
+
+ 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 (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ pOutputPortDefinition->nBufferCountActual = pWmvDec->hMFCWmvHandle.maxDPBNum;
+ pOutputPortDefinition->nBufferCountMin = pWmvDec->hMFCWmvHandle.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);
+ }
+ }
+
+ 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] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.cropRect.nWidth,
+ codecOutbufConf.cropRect.nHeight,
+ pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nWidth,
+ 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;
+
+ /** 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, "Failed to get geometry for parsed header info");
+ ret = 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] WmvCodecSetup maxDPBNum: %d", pExynosComponent, __FUNCTION__, pWmvDec->hMFCWmvHandle.maxDPBNum);
+
+ /* get interlace info */
+ if (pWmvDec->hMFCWmvHandle.codecOutbufConf.bInterlaced == VIDEO_TRUE)
+ Exynos_OSAL_Log(EXYNOS_LOG_INFO, "detect an interlaced type");
+
+ pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_TRUE;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pCropRectangle = &(pOutputPort->cropRectangle);
+ pInputPortDefinition = &(pInputPort->portDefinition);
+ pOutputPortDefinition = &(pOutputPort->portDefinition);
+ } else {
+ pCropRectangle = &(pOutputPort->newCropRectangle);
+ pInputPortDefinition = &(pInputPort->newPortDefinition);
+ pOutputPortDefinition = &(pOutputPort->newPortDefinition);
+ }
+
+ 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) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.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;
+
+ pOutputPortDefinition->nBufferCountActual = pOutputPort->portDefinition.nBufferCountActual;
+ pOutputPortDefinition->nBufferCountMin = pOutputPort->portDefinition.nBufferCountMin;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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) ||
+ (pWmvDec->hMFCWmvHandle.codecOutbufConf.bInterlaced == VIDEO_TRUE) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.format.video.nFrameHeight != pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight) ||
+ ((OMX_S32)pOutputPort->portDefinition.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;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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);
+ }
+ }
+
+ if ((pVideoDec->bReconfigDPB != OMX_TRUE) &&
+ ((pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameWidth != pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nWidth) ||
+ (pWmvDec->hMFCWmvHandle.codecOutbufConf.nFrameHeight != pWmvDec->hMFCWmvHandle.codecOutbufConf.cropRect.nHeight))) {
+ /* Check Crop */
+ 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);
+
+ /** 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;
+ int i;
+
+ FunctionIn();
+
+ if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ 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);
+ Exynos_OSAL_SignalSet(pWmvDec->hDestinationStartEvent);
+
+ 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->multiPlaneBuffer.dataBuffer[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, "Unsupported WMV Codec Format Type");
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ pInbufOps->Set_Shareable(hMFCHandle);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ bufferConf.nSizeImage = pExynosInputPort->portDefinition.nBufferSize;
+ } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+ }
+ 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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* set output geometry */
+ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+ bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+ if (bSupportFormat == OMX_TRUE) { /* supported by H/W */
+ if ((pWmvDec->hMFCWmvHandle.videoInstInfo.specificInfo.dec.bDualDPBSupport == VIDEO_TRUE) &&
+ (eOutputFormat != (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled)) {
+ /* Needs to eanble DualDPB feature */
+ if (pDecOps->Enable_DualDPBMode(hMFCHandle) != VIDEO_ERROR_NONE) {
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ }
+ 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;
+ goto EXIT;
+ }
+ }
+
+ pWmvDec->hMFCWmvHandle.MFCOutputColorType = bufferConf.eColorFormat;
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+ if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ bMetaData = Make_Stream_MetaData(pSrcInputData->multiPlaneBuffer.dataBuffer[0], &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat);
+ if (bMetaData == OMX_FALSE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail to Make Stream MetaData");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* input buffer enqueue for header parsing */
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ nDataLen[0] = oneFrameSize; /* it is possible to be changed at Make_Stream_MetaData() */
+
+ if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
+// ret = OMX_ErrorInsufficientResources;
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+ goto EXIT;
+ }
+
+ /* start header parsing */
+ if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
+ ret = OMX_ErrorCodecInit;
+ 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, "CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...",
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0]) , *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 1),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 2), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 3),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 4), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 5),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 6), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 7));
+ if (ret != OMX_ErrorNone) {
+ WmvCodecStop(pOMXComponent, INPUT_PORT_INDEX);
+ pInbufOps->Cleanup_Buffer(hMFCHandle);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_SleepMillisec(0);
+ /* disable header info re-input scheme
+ ret = OMX_ErrorInputDataDecodeYet;
+ WmvCodecStop(pOMXComponent, INPUT_PORT_INDEX);
+ */
+ ret = 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
+ 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];
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_TRUE) {
+ if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enable Dynamic DPB");
+ 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 (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ /* get dpb count */
+ nOutbufs = pWmvDec->hMFCWmvHandle.maxDPBNum;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Register output buffer */
+ ret = WMVCodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++)
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ } else {
+ if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ 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,
+ (int *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+ pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+#ifdef USE_ANB
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+ int plane;
+
+ Exynos_OSAL_Memset((OMX_PTR)planes, 0, sizeof(ExynosVideoPlane) * MAX_BUFFER_PLANE);
+
+ /* get dpb count */
+ nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_TRUE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
+ planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
+ planes[plane].allocSize = nAllocLen[plane];
+ }
+
+ if (pOutbufOps->Register(hMFCHandle, planes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+
+ if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ } else {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ } else {
+ /* get dpb count */
+ nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ }
+#else
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+#endif
+ }
+
+ pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nParamIndex) {
+ case OMX_IndexParamVideoWmv:
+ {
+ OMX_VIDEO_PARAM_WMVTYPE *pDstWmvParam = (OMX_VIDEO_PARAM_WMVTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_WMVTYPE *pSrcWmvParam = NULL;
+ EXYNOS_WMVDEC_HANDLE *pWmvDec = 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) {
+ goto EXIT;
+ }
+
+ if (pDstWmvParam->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+ EXYNOS_WMVDEC_HANDLE *pWmvDec = 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) {
+ goto EXIT;
+ }
+
+ if (pDstVc1Param->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ 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) {
+ 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;
+ EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+ EXYNOS_WMVDEC_HANDLE *pWmvDec = 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;
+ }
+
+ pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ case OMX_IndexExynosParamReorderMode: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ goto EXIT;
+
+ pReorderParam->bReorderMode = pVideoDec->bReorderMode;
+ }
+ break;
+#endif
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
+ OMX_U32 portIndex = portDefinition->nPortIndex;
+ 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 *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (((pExynosPort->bIsANBEnabled == OMX_TRUE) || (pExynosPort->bStoreMetaData == OMX_TRUE)) &&
+ (pWmvDec->hMFCWmvHandle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
+ (portIndex == OUTPUT_PORT_INDEX)) {
+ portDefinition->format.video.eColorFormat =
+ (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HALPixelFormat((OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace, pExynosPort->ePlaneType);
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "portDefinition->format.video.eColorFormat: 0x%x", portDefinition->format.video.eColorFormat);
+ }
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+ case OMX_IndexParamVideoWmv:
+ {
+ OMX_VIDEO_PARAM_WMVTYPE *pDstWmvParam = NULL;
+ OMX_VIDEO_PARAM_WMVTYPE *pSrcWmvParam = (OMX_VIDEO_PARAM_WMVTYPE *)pComponentParameterStructure;
+ EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL;
+ /* 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) {
+ goto EXIT;
+ }
+
+ if (pSrcWmvParam->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+ EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL;
+ /* 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) {
+ goto EXIT;
+ }
+
+ if (pSrcVc1Param->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ 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_ErrorBadParameter;
+ goto EXIT;
+ }
+ }
+ break;
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_VC1TYPE *pDstVc1Component = NULL;
+ EXYNOS_WMVDEC_HANDLE *pVc1Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pVc1Dec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ pDstVc1Component = &pVc1Dec->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;
+ EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ case OMX_IndexExynosParamReorderMode: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ goto EXIT;
+
+ pVideoDec->bReorderMode = pReorderParam->bReorderMode;
+ }
+ break;
+#endif
+ 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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ EXYNOS_WMVDEC_HANDLE *pWmvDec = NULL;
+ OMX_CONFIG_RECTTYPE *pSrcRectType = NULL;
+ OMX_CONFIG_RECTTYPE *pDstRectType = NULL;
+
+ pWmvDec = (EXYNOS_WMVDEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ }
+
+ EXYNOS_OMX_BASEPORT *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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE) {
+#ifdef USE_TIMESTAMP_REORDER_SUPPORT
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_CUSTOM_INDEX_PARAM_REORDER_MODE) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexExynosParamReorderMode;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+#endif
+ }
+
+ 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;
+ OMX_COMPONENTTYPE *pOMXComponent = NULL;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+ 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;
+ OMX_PTR hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ ExynosVideoInstInfo *pVideoInstInfo = &(pWmvDec->hMFCWmvHandle.videoInstInfo);
+
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+ int i, plane;
+
+ FunctionIn();
+
+ pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc = OMX_FALSE;
+ pWmvDec->hMFCWmvHandle.bConfiguredMFCDst = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ 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;
+ }
+
+ pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
+ pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
+ pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+
+ Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+ if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ unsigned int nAllocLen[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
+ 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->hDestinationStartEvent);
+
+ 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ OMX_PTR hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+
+ int i, plane;
+
+ FunctionIn();
+
+ if (pVideoDec->csc_handle != NULL) {
+ csc_deinit(pVideoDec->csc_handle);
+ pVideoDec->csc_handle = NULL;
+ }
+
+ Exynos_OSAL_QueueTerminate(&pWmvDec->bypassBufferInfoQ);
+
+ Exynos_OSAL_SignalTerminate(pWmvDec->hDestinationStartEvent);
+ pWmvDec->hDestinationStartEvent = 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);
+ } 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);
+ } 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];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ OMX_U32 oneFrameSize = pSrcInputData->dataLen;
+
+ ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pWmvDec->hMFCWmvHandle.pOutbufOps;
+ 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;
+ int i;
+
+ FunctionIn();
+
+ if (pWmvDec->hMFCWmvHandle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = WmvCodecSrcSetup(pOMXComponent, pSrcInputData);
+ goto EXIT;
+ }
+
+ if ((pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_FALSE) &&
+ (pVideoDec->bForceHeaderParsing == OMX_FALSE)) {
+ ret = WmvCodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to WmvCodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ }
+
+ bStartCode = Check_Stream_PrefixCode(pSrcInputData->multiPlaneBuffer.dataBuffer[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_ERROR, "Can't attach startcode due to lack of buffer space");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+
+ bStartCode = Make_Stream_StartCode(pSrcInputData->multiPlaneBuffer.dataBuffer[0], &oneFrameSize, pWmvDec->hMFCWmvHandle.wmvFormat);
+ if (bStartCode == OMX_FALSE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail to Make Stream Start Code");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ 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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x, oneFrameSize: %d", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pWmvDec->hMFCWmvHandle.indexTimestamp, pSrcInputData->nFlags, oneFrameSize);
+
+ 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;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] bufferHeader: 0x%x, dataBuffer: 0x%x", pExynosComponent, __FUNCTION__, pSrcInputData->bufferHeader, pSrcInputData->multiPlaneBuffer.dataBuffer[0]);
+
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ nDataLen[0] = oneFrameSize; /* it is possible to be changed at Make_Stream_MetaData() */
+
+ if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
+ tempBufferHeader.nFlags = pSrcInputData->nFlags;
+ tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+ pPrivate = (void *)&tempBufferHeader;
+ } else {
+ pPrivate = (void *)pSrcInputData->bufferHeader;
+ }
+ codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pWmvDec->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ } else if (bStartCode == OMX_FALSE) {
+ ret = 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pWmvDec->hMFCWmvHandle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pWmvDec->hMFCWmvHandle.pInbufOps;
+ ExynosVideoBuffer *pVideoBuffer;
+ 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->allocSize = 0;
+ pSrcOutputData->pPrivate = NULL;
+ pSrcOutputData->bufferHeader = NULL;
+ } else {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pSrcOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[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, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#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];
+
+ ExynosVideoDecOps *pDecOps = pWmvDec->hMFCWmvHandle.pDecOps;
+ 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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ 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] : %d => ADDR[%d]: 0x%x", pExynosComponent, __FUNCTION__, __LINE__, i,
+ pDstInputData->multiPlaneBuffer.dataBuffer[i]);
+ }
+
+ if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+ (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+ (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+ ret = WmvCodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to WmvCodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ codecReturn = pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ } else {
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ }
+
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &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;
+
+ OMX_S32 indexTimestamp = 0;
+ int plane, nPlaneCnt;
+
+ FunctionIn();
+
+ if (pWmvDec->bDestinationStart == OMX_FALSE) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ while (1) {
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
+ if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+
+ if (pVideoBuffer == NULL) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ } else {
+ 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, "HW is not available");
+ 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(pExynosOutputPort))) {
+ ret = OMX_ErrorNone;
+ break;
+ }
+ }
+
+ if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+ (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) {
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pExynosOutputPort->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(pExynosOutputPort);
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pDstOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pDstOutputData->multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
+ pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+ pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
+ }
+ pDstOutputData->usedDataLen = 0;
+ pDstOutputData->pPrivate = pVideoBuffer;
+ if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ int i = 0;
+ pDstOutputData->pPrivate = NULL;
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ if (pDstOutputData->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+ /* get interlace frame info */
+ if ((pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+ (pWmvDec->hMFCWmvHandle.codecOutbufConf.bInterlaced == VIDEO_TRUE) &&
+ (pVideoBuffer->planes[2].addr != NULL)) {
+ /* only NV12 case */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] interlace type = %x", pExynosComponent, __FUNCTION__, pVideoBuffer->interlacedType);
+ *(int *)(pVideoBuffer->planes[2].addr) = pVideoBuffer->interlacedType;
+ }
+
+ pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+ bufferGeometry = &pWmvDec->hMFCWmvHandle.codecOutbufConf;
+ pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
+ pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
+ pBufferInfo->imageStride = bufferGeometry->nStride;
+ pBufferInfo->ColorFormat = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+ Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+ 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 timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
+ }
+ } 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 reorder timestamp %lld us (%.2f secs), sCurrentTimestamp.nIndex: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, sCurrentTimestamp.nIndex, pDstOutputData->nFlags);
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if (pWmvDec->hMFCWmvHandle.videoInstInfo.specificInfo.dec.bLastFrameSupport == VIDEO_FALSE) {
+ if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+ (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ 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] indexTimestamp(%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 = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ } else {
+ pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+ }
+ } else {
+ if ((displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+ ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+
+ if ((pExynosComponent->bBehaviorEOS == OMX_TRUE) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME)) {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (displayStatus != VIDEO_FRAME_STATUS_LAST_FRAME) {
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ } else {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 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 (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;
+ }
+
+ 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_SignalReset(pWmvDec->hSourceStartEvent);
+ }
+
+ ret = Exynos_WmvDec_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) &&
+ (pExynosComponent->currentState == OMX_StateExecuting)) {
+ 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_ErrorOutputBufferUseYet;
+ else
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pWmvDec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pWmvDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pWmvDec->hDestinationStartEvent);
+ }
+ 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;
+ }
+
+ 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 (pWmvDec->hMFCWmvHandle.bConfiguredMFCDst == OMX_TRUE) {
+ ret = Exynos_WmvDec_DstIn(pOMXComponent, pDstInputData);
+ if (ret != OMX_ErrorNone) {
+ 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 (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pWmvDec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pWmvDec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pWmvDec->hDestinationStartEvent);
+ }
+ if (Exynos_OSAL_GetElemNum(&pWmvDec->bypassBufferInfoQ) > 0) {
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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)) {
+ 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, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_WMV_DEC, componentName) != 0) &&
+ (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_WMV_CUSTOM_DEC, componentName) != 0)) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+
+ 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 | BUFFER_ANBSHARE;
+ 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;
+
+#if 0 /* unused code */
+ pVideoDec->exynos_checkInputFrame = &Check_Wmv_Frame;
+ pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ 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, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ Exynos_OSAL_Free(pWmvDec);
+ pWmvDec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->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]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
+ Exynos_OSAL_Free(pWmvDec);
+ pWmvDec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for dec %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pWmvDec->hMFCWmvHandle.videoInstInfo.specificInfo.dec.bDualDPBSupport),
+ (pWmvDec->hMFCWmvHandle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport),
+ (pWmvDec->hMFCWmvHandle.videoInstInfo.specificInfo.dec.bLastFrameSupport),
+ (pWmvDec->hMFCWmvHandle.videoInstInfo.specificInfo.dec.bSkypeSupport));
+
+ if (pWmvDec->hMFCWmvHandle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport == VIDEO_TRUE)
+ pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bDynamicDPBMode = OMX_TRUE;
+
+ 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;
+
+ 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) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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 hDestinationStartEvent;
+
+ 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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;
+#ifdef USE_CUSTOM_COMPONENT_SUPPORT
+ /* component 2 - video custom decoder WMV */
+ Exynos_OSAL_Strcpy(ppExynosComponent[1]->componentName, EXYNOS_OMX_COMPONENT_WMV_CUSTOM_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[1]->roles[0], EXYNOS_OMX_COMPONENT_WMV_DEC_ROLE);
+ ppExynosComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+#endif
+EXIT:
+ FunctionOut();
+ return MAX_COMPONENT_NUM;
+}
--- /dev/null
+/*
+ *
+ * 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 2
+#define MAX_COMPONENT_ROLE_NUM 1
+
+/* WMV */
+#define EXYNOS_OMX_COMPONENT_WMV_DEC "OMX.Exynos.WMV.Decoder"
+#define EXYNOS_OMX_COMPONENT_WMV_CUSTOM_DEC "OMX.Exynos.vc1.dec"
+#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
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Vp8dec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.VP8.Decoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+LOCAL_CFLAGS += -DUSE_VP8_SUPPORT
+
+ifeq ($(BOARD_USE_ANB), true)
+LOCAL_CFLAGS += -DUSE_ANB
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_CUSTOM_COMPONENT_SUPPORT), true)
+LOCAL_CFLAGS += -DUSE_CUSTOM_COMPONENT_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/dec \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+#define VP8_DEC_NUM_OF_EXTRA_BUFFERS 7
+
+//#define FULL_FRAME_SEARCH /* Full frame search not support*/
+
+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;
+
+ FunctionIn();
+
+ 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;
+ }
+
+ while ((pVp8Dec->hMFCVp8Handle.maxLevel >> nLevelCnt) > 0) {
+ nLevelCnt++;
+ }
+
+ if ((pVp8Dec->hMFCVp8Handle.nProfileCnt == 0) ||
+ (nLevelCnt == 0)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : there is no any profile/level", __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);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : supported profile(%x), level(%x)", __FUNCTION__, pProfileLevelType->eProfile, pProfileLevelType->eLevel);
+
+EXIT:
+ 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, "%s : there is no any profile/level", __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, "%s : profile(%x)/level(%x) is %ssupported", __FUNCTION__,
+ pProfileLevelType->eProfile, pProfileLevelType->eLevel,
+ (bProfileSupport && bLevelSupport)? "":"not ");
+
+EXIT:
+ return (bProfileSupport && bLevelSupport);
+}
+
+#if 0 /* unused code */
+static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+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;
+}
+
+#if 0 /* unused code */
+static int Check_VP8_Frame(
+ OMX_U8 *pInputStream,
+ OMX_U32 buffSize,
+ OMX_U32 flag,
+ OMX_BOOL bPreviousFrameEOF,
+ OMX_BOOL *pbEndOfFrame)
+{
+ /* Uncompressed data Chunk comprises a common
+ (for key frames and interframes) 3-byte frame tag that
+ contains four fields
+ - 1-bit frame type (0 - key frame, 1 - inter frame)
+ - 3-bit version number (0 - 3 are defined as four different
+ profiles with different decoding complexity)
+ - 1-bit show_frame flag ( 0 - current frame not for display,
+ 1 - current frame is for dispaly)
+ - 19-bit field - size of the first data partition in bytes
+
+ Key Frames : frame tag followed by 7 bytes of uncompressed
+ data
+ 3-bytes : Start code (byte 0: 0x9d,byte 1: 0x01,byte 2: 0x2a)
+ Next 4-bytes: Width & height, Horizontal and vertical scale information
+ 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits)
+ 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits)
+ */
+ int width, height;
+ int horizSscale, vertScale;
+
+ FunctionIn();
+
+ *pbEndOfFrame = OMX_TRUE;
+
+ /*Check for Key frame*/
+ if (!(pInputStream[0] & 0x01)){
+ /* Key Frame Start code*/
+ if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, " VP8 Key Frame Start Code not Found");
+ *pbEndOfFrame = OMX_FALSE;
+ }
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, " VP8 Found Key Frame Start Code");
+ width = (pInputStream[6] | (pInputStream[7] << 8)) & 0x3fff;
+ horizSscale = pInputStream[7] >> 6;
+ height = (pInputStream[8] | (pInputStream[9] << 8)) & 0x3fff;
+ vertScale = pInputStream[9] >> 6;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "width = %d, height = %d, horizSscale = %d, vertScale = %d", width, height, horizSscale, vertScale);
+ }
+
+ FunctionOut();
+ return (int)buffSize;
+}
+#endif
+
+OMX_BOOL Check_VP8_StartCode(
+ OMX_U8 *pInputStream,
+ OMX_U32 streamSize)
+{
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "streamSize: %d",streamSize);
+ if (streamSize < 3) {
+ return OMX_FALSE;
+ }
+
+ if (!(pInputStream[0] & 0x01)){
+ /* Key Frame Start code*/
+ if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, " VP8 Key Frame Start Code not Found");
+ return OMX_FALSE;
+ }
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, " VP8 Found Key Frame Start Code");
+ }
+
+ 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_VP8DEC_HANDLE *pVp8Dec = NULL;
+ EXYNOS_OMX_BASEPORT *pOutputPort = NULL;
+ ExynosVideoColorFormatType eVideoFormat = VIDEO_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate decoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+ /* 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, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pVp8Dec->hMFCVp8Handle.hMFCHandle = pVp8Dec->hMFCVp8Handle.pDecOps->Init(pVideoInstInfo);
+ if (pVp8Dec->hMFCVp8Handle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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;
+ }
+
+ /* 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
+ pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
+ pOutbufOps = pVp8Dec->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;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = 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;
+ pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
+ 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) &&
+ (pOutputPort->bDynamicDPBMode == OMX_TRUE))
+ 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
+ pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
+ pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+
+ 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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE VP8CodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+ CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoDecBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
+ pBufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
+ pBufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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);
+
+ /******************************************************/
+ /* V4L2 Destnation Setup for DPB Buffer Number Change */
+ /******************************************************/
+ ret = VP8CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to VP8CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+ /**********************************/
+ /* Codec Buffer Unregister */
+ /**********************************/
+ pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+ pBufferOps->Cleanup_Buffer(hMFCHandle);
+ }
+
+ Exynos_ResolutionUpdate(pOMXComponent);
+ } 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ int i, nOutbufs;
+
+ ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+
+ FunctionIn();
+
+ if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((nPortIndex == INPUT_PORT_INDEX) &&
+ (pVp8Dec->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, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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->bDestinationStart == OMX_TRUE)) {
+ Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+ for (i = 0; i < pVp8Dec->hMFCVp8Handle.maxDPBNum; i++) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+ Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+ }
+ pOutbufOps->Clear_Queue(hMFCHandle);
+ }
+
+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;
+
+ 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) ||
+ (codecOutbufConf.bInterlaced != pVp8Dec->hMFCVp8Handle.codecOutbufConf.bInterlaced) ||
+#endif
+ (maxDPBNum != pVp8Dec->hMFCVp8Handle.maxDPBNum)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] DRC: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.nFrameWidth,
+ codecOutbufConf.nFrameHeight,
+ pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth,
+ pVp8Dec->hMFCVp8Handle.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__,
+ maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType,
+ pVp8Dec->hMFCVp8Handle.maxDPBNum,
+ pVp8Dec->hMFCVp8Handle.codecOutbufConf.eColorFormat,
+ pVp8Dec->hMFCVp8Handle.codecOutbufConf.eFilledDataType);
+
+ 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 (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ pOutputPortDefinition->nBufferCountActual = pVp8Dec->hMFCVp8Handle.maxDPBNum;
+ pOutputPortDefinition->nBufferCountMin = pVp8Dec->hMFCVp8Handle.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);
+ }
+ }
+
+ 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] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.cropRect.nWidth,
+ codecOutbufConf.cropRect.nHeight,
+ pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nWidth,
+ 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;
+
+ /** 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, "Failed to get geometry for parsed header info");
+ ret = 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] VP8CodecSetup maxDPBNum: %d", pExynosComponent, __FUNCTION__, pVp8Dec->hMFCVp8Handle.maxDPBNum);
+
+ pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_TRUE;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pCropRectangle = &(pOutputPort->cropRectangle);
+ pInputPortDefinition = &(pInputPort->portDefinition);
+ pOutputPortDefinition = &(pOutputPort->portDefinition);
+ } else {
+ pCropRectangle = &(pOutputPort->newCropRectangle);
+ pInputPortDefinition = &(pInputPort->newPortDefinition);
+ pOutputPortDefinition = &(pOutputPort->newPortDefinition);
+ }
+
+ 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) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.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;
+
+ pOutputPortDefinition->nBufferCountActual = pOutputPort->portDefinition.nBufferCountActual;
+ pOutputPortDefinition->nBufferCountMin = pOutputPort->portDefinition.nBufferCountMin;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight) ||
+ ((OMX_S32)pOutputPort->portDefinition.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;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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);
+ }
+ }
+
+ if ((pVideoDec->bReconfigDPB != OMX_TRUE) &&
+ ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nWidth) ||
+ (pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nHeight))) {
+ /* Check Crop */
+ 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);
+
+ /** 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;
+ int i;
+
+ FunctionIn();
+
+ if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ 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);
+ Exynos_OSAL_SignalSet(pVp8Dec->hDestinationStartEvent);
+
+ 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);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ bufferConf.nSizeImage = pExynosInputPort->portDefinition.nBufferSize;
+ } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+ }
+ 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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* set output geometry */
+ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+ bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+ if (bSupportFormat == OMX_TRUE) { /* supported by H/W */
+ if ((pVp8Dec->hMFCVp8Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport == VIDEO_TRUE) &&
+ (eOutputFormat != (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled)) {
+ /* Needs to eanble DualDPB feature */
+ if (pDecOps->Enable_DualDPBMode(hMFCHandle) != VIDEO_ERROR_NONE) {
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ }
+ 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;
+ goto EXIT;
+ }
+ }
+
+ pVp8Dec->hMFCVp8Handle.MFCOutputColorType = bufferConf.eColorFormat;
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+ if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* input buffer enqueue for header parsing */
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ /* set buffer process type */
+ if (pDecOps->Set_BufferProcessType(hMFCHandle, pExynosOutputPort->bufferProcessType) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set buffer process type(not supported)");
+ }
+
+ if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
+// ret = OMX_ErrorInsufficientResources;
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+ goto EXIT;
+ }
+
+ /* start header parsing */
+ if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
+ ret = OMX_ErrorCodecInit;
+ 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, "CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...",
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0]) , *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 1),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 2), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 3),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 4), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 5),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 6), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 7));
+ if (ret != OMX_ErrorNone) {
+ VP8CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+ pInbufOps->Cleanup_Buffer(hMFCHandle);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_SleepMillisec(0);
+ ret = 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
+ 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];
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_TRUE) {
+ if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enable Dynamic DPB");
+ 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 (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ /* get dpb count */
+ nOutbufs = pVp8Dec->hMFCVp8Handle.maxDPBNum;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Register output buffer */
+ ret = VP8CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++)
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ } else {
+ if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ 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;
+
+ /* without Register output buffer */
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++) {
+ pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ (int *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+ pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+#ifdef USE_ANB
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+ int plane;
+
+ Exynos_OSAL_Memset((OMX_PTR)planes, 0, sizeof(ExynosVideoPlane) * MAX_BUFFER_PLANE);
+
+ /* get dpb count */
+ nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_TRUE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
+ planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
+ planes[plane].allocSize = nAllocLen[plane];
+ }
+
+ if (pOutbufOps->Register(hMFCHandle, planes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+
+ if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ } else {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ } else {
+ /* get dpb count */
+ nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ }
+#else
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+#endif
+ }
+
+ pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nParamIndex) {
+ case OMX_IndexParamVideoVp8:
+ {
+ OMX_VIDEO_PARAM_VP8TYPE *pDstVP8Component = (OMX_VIDEO_PARAM_VP8TYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_VP8TYPE *pSrcVP8Component = NULL;
+ EXYNOS_VP8DEC_HANDLE *pVp8Dec = 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) {
+ goto EXIT;
+ }
+
+ if (pDstVP8Component->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ 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) {
+ 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;
+ EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+ EXYNOS_VP8DEC_HANDLE *pVp8Dec = 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;
+ }
+
+ pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+ case OMX_IndexParamVideoVp8:
+ {
+ OMX_VIDEO_PARAM_VP8TYPE *pDstVP8Component = NULL;
+ OMX_VIDEO_PARAM_VP8TYPE *pSrcVP8Component = (OMX_VIDEO_PARAM_VP8TYPE *)pComponentParameterStructure;
+ EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
+ /* 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;
+ }
+
+ pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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) {
+ 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_ErrorBadParameter;
+ goto EXIT;
+ }
+ }
+ break;
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_VP8TYPE *pDstVP8Component = NULL;
+ EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL;
+ OMX_CONFIG_RECTTYPE *pSrcRectType = NULL;
+ OMX_CONFIG_RECTTYPE *pDstRectType = NULL;
+
+ pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ }
+
+ EXYNOS_OMX_BASEPORT *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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ 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;
+ OMX_COMPONENTTYPE *pOMXComponent = NULL;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+ 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;
+ OMX_PTR hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ ExynosVideoInstInfo *pVideoInstInfo = &(pVp8Dec->hMFCVp8Handle.videoInstInfo);
+
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+ int i, plane;
+
+ FunctionIn();
+
+ pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE;
+ pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ 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;
+ }
+
+ pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
+ pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
+ pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+
+ Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+ if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ unsigned int nAllocLen[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
+ 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->hDestinationStartEvent);
+
+ 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ OMX_PTR hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+
+ int i, plane;
+
+ FunctionIn();
+
+ if (pVideoDec->csc_handle != NULL) {
+ csc_deinit(pVideoDec->csc_handle);
+ pVideoDec->csc_handle = NULL;
+ }
+
+ Exynos_OSAL_QueueTerminate(&pVp8Dec->bypassBufferInfoQ);
+
+ Exynos_OSAL_SignalTerminate(pVp8Dec->hDestinationStartEvent);
+ pVp8Dec->hDestinationStartEvent = 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);
+ } 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);
+ } 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];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ OMX_U32 oneFrameSize = pSrcInputData->dataLen;
+
+ ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps;
+ 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;
+ int i;
+
+ FunctionIn();
+
+ if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = VP8CodecSrcSetup(pOMXComponent, pSrcInputData);
+ goto EXIT;
+ }
+
+ if ((pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_FALSE) &&
+ (pVideoDec->bForceHeaderParsing == OMX_FALSE)) {
+ ret = VP8CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to VP8CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ }
+
+ if (((bInStartCode = Check_VP8_StartCode(pSrcInputData->multiPlaneBuffer.dataBuffer[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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x, oneFrameSize: %d", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pVp8Dec->hMFCVp8Handle.indexTimestamp, pSrcInputData->nFlags, oneFrameSize);
+ 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;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] bufferHeader: 0x%x, dataBuffer: 0x%x", pExynosComponent, __FUNCTION__, pSrcInputData->bufferHeader, pSrcInputData->multiPlaneBuffer.dataBuffer[0]);
+
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
+ tempBufferHeader.nFlags = pSrcInputData->nFlags;
+ tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+ pPrivate = (void *)&tempBufferHeader;
+ } else {
+ pPrivate = (void *)pSrcInputData->bufferHeader;
+ }
+ codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pVp8Dec->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ } else if (bInStartCode == OMX_FALSE) {
+ ret = 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps;
+ ExynosVideoBuffer *pVideoBuffer;
+ 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->allocSize = 0;
+ pSrcOutputData->pPrivate = NULL;
+ } else {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pSrcOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[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, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#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];
+
+ ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps;
+ 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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ 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] : %d => ADDR[%d]: 0x%x", pExynosComponent, __FUNCTION__, __LINE__, i,
+ pDstInputData->multiPlaneBuffer.dataBuffer[i]);
+ }
+
+ if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+ (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+ (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+ ret = VP8CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to VP8CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ codecReturn = pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ } else {
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ }
+
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &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;
+
+ OMX_S32 indexTimestamp = 0;
+ int plane, nPlaneCnt;
+
+ FunctionIn();
+
+ if (pVp8Dec->bDestinationStart == OMX_FALSE) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ while (1) {
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
+ if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+
+ if (pVideoBuffer == NULL) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ } else {
+ 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, "HW is not available");
+ 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(pExynosOutputPort))) {
+ ret = OMX_ErrorNone;
+ break;
+ }
+ }
+
+ if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+ (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) {
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pExynosOutputPort->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(pExynosOutputPort);
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pDstOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pDstOutputData->multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
+ pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+ pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
+ }
+ pDstOutputData->usedDataLen = 0;
+ pDstOutputData->pPrivate = pVideoBuffer;
+ if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ int i = 0;
+ pDstOutputData->pPrivate = NULL;
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ if (pDstOutputData->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+ pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+ bufferGeometry = &pVp8Dec->hMFCVp8Handle.codecOutbufConf;
+ pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
+ pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
+ pBufferInfo->imageStride = bufferGeometry->nStride;
+ pBufferInfo->ColorFormat = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+ Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+ 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 timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if (pVp8Dec->hMFCVp8Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport == VIDEO_FALSE) {
+ if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+ (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ 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] indexTimestamp(%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 = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ } else {
+ pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+ }
+ } else {
+ if ((displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+ ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+
+ if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (displayStatus != VIDEO_FRAME_STATUS_LAST_FRAME) {
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ } else {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 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 (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;
+ }
+
+ 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_SignalReset(pVp8Dec->hSourceStartEvent);
+ }
+
+ ret = Exynos_VP8Dec_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) &&
+ (pExynosComponent->currentState == OMX_StateExecuting)) {
+ 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_ErrorOutputBufferUseYet;
+ else
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pVp8Dec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pVp8Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pVp8Dec->hDestinationStartEvent);
+ }
+ 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;
+ }
+
+ 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 (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_TRUE) {
+ ret = Exynos_VP8Dec_DstIn(pOMXComponent, pDstInputData);
+ if (ret != OMX_ErrorNone) {
+ 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 (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pVp8Dec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pVp8Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pVp8Dec->hDestinationStartEvent);
+ }
+ if (Exynos_OSAL_GetElemNum(&pVp8Dec->bypassBufferInfoQ) > 0) {
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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)) {
+ 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, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP8_DEC, componentName) != 0) &&
+ (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP8_CUSTOM_DEC, componentName) != 0)) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+
+ 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 | BUFFER_ANBSHARE;
+ 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;
+
+#if 0 /* unused code */
+ pVideoDec->exynos_checkInputFrame = &Check_VP8_Frame;
+ pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ 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, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ Exynos_OSAL_Free(pVp8Dec);
+ pVp8Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->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]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
+ Exynos_OSAL_Free(pVp8Dec);
+ pVp8Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for dec %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pVp8Dec->hMFCVp8Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport),
+ (pVp8Dec->hMFCVp8Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport),
+ (pVp8Dec->hMFCVp8Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport),
+ (pVp8Dec->hMFCVp8Handle.videoInstInfo.specificInfo.dec.bSkypeSupport));
+
+ if (pVp8Dec->hMFCVp8Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport == VIDEO_TRUE)
+ pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bDynamicDPBMode = OMX_TRUE;
+
+ 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;
+
+ 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) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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 hDestinationStartEvent;
+
+ 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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;
+#ifdef USE_CUSTOM_COMPONENT_SUPPORT
+ /* component 2 - video custom decoder VP8 */
+ Exynos_OSAL_Strcpy(ppExynosComponent[1]->componentName, EXYNOS_OMX_COMPONENT_VP8_CUSTOM_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[1]->roles[0], EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE);
+ ppExynosComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+#endif
+EXIT:
+ FunctionOut();
+ return MAX_COMPONENT_NUM;
+}
--- /dev/null
+/*
+ *
+ * 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 2
+#define MAX_COMPONENT_ROLE_NUM 1
+
+/* VP8 */
+#define EXYNOS_OMX_COMPONENT_VP8_DEC "OMX.Exynos.VP8.Decoder"
+#define EXYNOS_OMX_COMPONENT_VP8_CUSTOM_DEC "OMX.Exynos.vp8.dec"
+#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
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Vp9dec.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.VP9.Decoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+LOCAL_CFLAGS += -DUSE_VP9_SUPPORT
+
+ifeq ($(BOARD_USE_ANB), true)
+LOCAL_CFLAGS += -DUSE_ANB
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_CUSTOM_COMPONENT_SUPPORT), true)
+LOCAL_CFLAGS += -DUSE_CUSTOM_COMPONENT_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Vdec libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/dec \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+/* 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"
+
+#define VP9_DEC_NUM_OF_EXTRA_BUFFERS 7
+
+//#define FULL_FRAME_SEARCH /* Full frame search not support*/
+
+#if 0 /* unused code */
+static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+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;
+}
+
+#if 0 /* unused code */
+static int Check_VP9_Frame(
+ OMX_U8 *pInputStream,
+ OMX_U32 buffSize,
+ OMX_U32 flag,
+ OMX_BOOL bPreviousFrameEOF,
+ OMX_BOOL *pbEndOfFrame)
+{
+ /* Uncompressed data Chunk comprises a common
+ (for key frames and interframes) 3-byte frame tag that
+ contains four fields
+ - 1-bit frame type (0 - key frame, 1 - inter frame)
+ - 3-bit version number (0 - 3 are defined as four different
+ profiles with different decoding complexity)
+ - 1-bit show_frame flag ( 0 - current frame not for display,
+ 1 - current frame is for dispaly)
+ - 19-bit field - size of the first data partition in bytes
+
+ Key Frames : frame tag followed by 7 bytes of uncompressed
+ data
+ 3-bytes : Start code (byte 0: 0x9d,byte 1: 0x01,byte 2: 0x2a)
+ Next 4-bytes: Width & height, Horizontal and vertical scale information
+ 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits)
+ 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits)
+ */
+ int width, height;
+ int horizSscale, vertScale;
+
+ FunctionIn();
+
+ *pbEndOfFrame = OMX_TRUE;
+
+ /*Check for Key frame*/
+ if (!(pInputStream[0] & 0x01)){
+ /* Key Frame Start code*/
+ if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, " VP9 Key Frame Start Code not Found");
+ *pbEndOfFrame = OMX_FALSE;
+ }
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, " VP9 Found Key Frame Start Code");
+ width = (pInputStream[6] | (pInputStream[7] << 8)) & 0x3fff;
+ horizSscale = pInputStream[7] >> 6;
+ height = (pInputStream[8] | (pInputStream[9] << 8)) & 0x3fff;
+ vertScale = pInputStream[9] >> 6;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "width = %d, height = %d, horizSscale = %d, vertScale = %d", width, height, horizSscale, vertScale);
+ }
+
+ FunctionOut();
+ return (int)buffSize;
+}
+#endif
+
+OMX_BOOL Check_VP9_StartCode(
+ OMX_U8 *pInputStream,
+ OMX_U32 streamSize)
+{
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "buffer: %p, streamSize: %d", pInputStream, streamSize);
+ if (streamSize < 3) {
+ 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_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate decoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
+
+ /* 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, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pVp9Dec->hMFCVp9Handle.hMFCHandle = pVp9Dec->hMFCVp9Handle.pDecOps->Init(pVideoInstInfo);
+ if (pVp9Dec->hMFCVp9Handle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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;
+ }
+
+ /* 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
+ pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
+ pOutbufOps = pVp9Dec->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;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = 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;
+ pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
+ 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) &&
+ (pOutputPort->bDynamicDPBMode == OMX_TRUE))
+ 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
+ EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
+ pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
+ pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+
+ 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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE VP9CodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+ CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoDecBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
+ pBufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
+ pBufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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);
+
+ /******************************************************/
+ /* V4L2 Destnation Setup for DPB Buffer Number Change */
+ /******************************************************/
+ ret = VP9CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to VP9CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+ /**********************************/
+ /* Codec Buffer Unregister */
+ /**********************************/
+ pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+ pBufferOps->Cleanup_Buffer(hMFCHandle);
+ }
+
+ Exynos_ResolutionUpdate(pOMXComponent);
+ } 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ int i, nOutbufs;
+
+ ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+
+ FunctionIn();
+
+ if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((nPortIndex == INPUT_PORT_INDEX) &&
+ (pVp9Dec->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, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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->bDestinationStart == OMX_TRUE)) {
+ Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+
+ for (i = 0; i < pVp9Dec->hMFCVp9Handle.maxDPBNum; i++) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+ Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
+ }
+ pOutbufOps->Clear_Queue(hMFCHandle);
+ }
+
+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;
+
+ 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) ||
+ (codecOutbufConf.bInterlaced != pVp9Dec->hMFCVp9Handle.codecOutbufConf.bInterlaced) ||
+#endif
+ (maxDPBNum != pVp9Dec->hMFCVp9Handle.maxDPBNum)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] DRC: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.nFrameWidth,
+ codecOutbufConf.nFrameHeight,
+ pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth,
+ pVp9Dec->hMFCVp9Handle.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__,
+ maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType,
+ pVp9Dec->hMFCVp9Handle.maxDPBNum,
+ pVp9Dec->hMFCVp9Handle.codecOutbufConf.eColorFormat,
+ pVp9Dec->hMFCVp9Handle.codecOutbufConf.eFilledDataType);
+
+ 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 (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ pOutputPortDefinition->nBufferCountActual = pVp9Dec->hMFCVp9Handle.maxDPBNum;
+ pOutputPortDefinition->nBufferCountMin = pVp9Dec->hMFCVp9Handle.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);
+ }
+ }
+
+ 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] CROP: W(%d), H(%d) -> W(%d), H(%d)",
+ pExynosComponent, __FUNCTION__,
+ codecOutbufConf.cropRect.nWidth,
+ codecOutbufConf.cropRect.nHeight,
+ pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth,
+ 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;
+
+ /** 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, "Failed to get geometry for parsed header info");
+ ret = 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] Vp9CodecSetup maxDPBNum: %d", pExynosComponent, __FUNCTION__, pVp9Dec->hMFCVp9Handle.maxDPBNum);
+
+ pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc = OMX_TRUE;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pCropRectangle = &(pOutputPort->cropRectangle);
+ pInputPortDefinition = &(pInputPort->portDefinition);
+ pOutputPortDefinition = &(pOutputPort->portDefinition);
+ } else {
+ pCropRectangle = &(pOutputPort->newCropRectangle);
+ pInputPortDefinition = &(pInputPort->newPortDefinition);
+ pOutputPortDefinition = &(pOutputPort->newPortDefinition);
+ }
+
+ 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) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.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;
+
+ pOutputPortDefinition->nBufferCountActual = pOutputPort->portDefinition.nBufferCountActual;
+ pOutputPortDefinition->nBufferCountMin = pOutputPort->portDefinition.nBufferCountMin;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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) ||
+ (pInputPort->portDefinition.format.video.nFrameWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth) ||
+ (pInputPort->portDefinition.format.video.nFrameHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight) ||
+ ((OMX_S32)pOutputPort->portDefinition.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;
+
+ if (pVideoDec->bReconfigDPB != OMX_TRUE)
+ Exynos_UpdateFrameSize(pOMXComponent);
+
+ /** 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);
+ }
+ }
+
+ if ((pVideoDec->bReconfigDPB != OMX_TRUE) &&
+ ((pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth) ||
+ (pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nHeight))) {
+ /* Check Crop */
+ 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);
+
+ /** 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;
+
+ 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;
+ int i;
+
+ FunctionIn();
+
+ if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ 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);
+ Exynos_OSAL_SignalSet(pVp9Dec->hDestinationStartEvent);
+
+ 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);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ bufferConf.nSizeImage = pExynosInputPort->portDefinition.nBufferSize;
+ } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+ }
+ 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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* set output geometry */
+ Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+ bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
+ if (bSupportFormat == OMX_TRUE) { /* supported by H/W */
+ if ((pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport == VIDEO_TRUE) &&
+ (eOutputFormat != (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled)) {
+ /* Needs to eanble DualDPB feature */
+ if (pDecOps->Enable_DualDPBMode(hMFCHandle) != VIDEO_ERROR_NONE) {
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ }
+ 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;
+ goto EXIT;
+ }
+ }
+
+ pVp9Dec->hMFCVp9Handle.MFCOutputColorType = bufferConf.eColorFormat;
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
+ if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* input buffer enqueue for header parsing */
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ /* set buffer process type */
+ if (pDecOps->Set_BufferProcessType(hMFCHandle, pExynosOutputPort->bufferProcessType) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set buffer process type(not supported)");
+ }
+
+ if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
+// ret = OMX_ErrorInsufficientResources;
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
+ goto EXIT;
+ }
+
+ /* start header parsing */
+ if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
+ ret = OMX_ErrorCodecInit;
+ 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, "CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...",
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0]) , *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 1),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 2), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 3),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 4), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 5),
+ *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 6), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 7));
+ if (ret != OMX_ErrorNone) {
+ VP9CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+ pInbufOps->Cleanup_Buffer(hMFCHandle);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_SleepMillisec(0);
+ ret = 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
+ 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];
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_TRUE) {
+ if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enable Dynamic DPB");
+ 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 (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ /* get dpb count */
+ nOutbufs = pVp9Dec->hMFCVp9Handle.maxDPBNum;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Register output buffer */
+ ret = VP9CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++)
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ } else {
+ if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ 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;
+
+ /* without Register output buffer */
+
+ /* Enqueue output buffer */
+ for (i = 0; i < nOutbufs; i++) {
+ pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
+ (int *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
+ pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+#ifdef USE_ANB
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+ int plane;
+
+ Exynos_OSAL_Memset((OMX_PTR)planes, 0, sizeof(ExynosVideoPlane) * MAX_BUFFER_PLANE);
+
+ /* get dpb count */
+ nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_TRUE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
+ planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
+ planes[plane].allocSize = nAllocLen[plane];
+ }
+
+ if (pOutbufOps->Register(hMFCHandle, planes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
+ nDataLen,
+ nPlaneCnt,
+ NULL);
+ }
+
+ if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+ } else {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ } else {
+ /* get dpb count */
+ nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
+ if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
+ (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+ }
+#else
+ /*************/
+ /* TBD */
+ /*************/
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+#endif
+ }
+
+ pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nParamIndex) {
+ 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) {
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP9_DEC_ROLE);
+ }
+ break;
+ case OMX_IndexParamVideoErrorCorrection:
+ {
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
+ EXYNOS_VP9DEC_HANDLE *pVp9Dec = 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;
+ }
+
+ pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ switch (nIndex) {
+ 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) {
+ 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_ErrorBadParameter;
+ goto EXIT;
+ }
+ }
+ break;
+ case OMX_IndexParamVideoErrorCorrection:
+ {
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
+ EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ 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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (nIndex) {
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
+ OMX_CONFIG_RECTTYPE *pSrcRectType = NULL;
+ OMX_CONFIG_RECTTYPE *pDstRectType = NULL;
+
+ pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+
+ 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;
+ }
+
+ EXYNOS_OMX_BASEPORT *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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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 (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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ 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;
+ OMX_COMPONENTTYPE *pOMXComponent = NULL;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+
+ 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;
+ OMX_PTR hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = NULL;
+ ExynosVideoDecBufferOps *pInbufOps = NULL;
+ ExynosVideoDecBufferOps *pOutbufOps = NULL;
+ ExynosVideoInstInfo *pVideoInstInfo = &(pVp9Dec->hMFCVp9Handle.videoInstInfo);
+
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+ int i, plane;
+
+ FunctionIn();
+
+ pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc = OMX_FALSE;
+ pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ 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;
+ }
+
+ pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
+ pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
+ pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+
+ Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+ if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ unsigned int nAllocLen[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
+ 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->hDestinationStartEvent);
+
+ 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
+ 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ OMX_PTR hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+
+ ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+
+ int i, plane;
+
+ FunctionIn();
+
+ if (pVideoDec->csc_handle != NULL) {
+ csc_deinit(pVideoDec->csc_handle);
+ pVideoDec->csc_handle = NULL;
+ }
+
+ Exynos_OSAL_QueueTerminate(&pVp9Dec->bypassBufferInfoQ);
+
+ Exynos_OSAL_SignalTerminate(pVp9Dec->hDestinationStartEvent);
+ pVp9Dec->hDestinationStartEvent = 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);
+ } 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);
+ } 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];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ OMX_U32 oneFrameSize = pSrcInputData->dataLen;
+
+ ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
+ ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
+ 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;
+ int i;
+
+ FunctionIn();
+
+ if (pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = VP9CodecSrcSetup(pOMXComponent, pSrcInputData);
+ goto EXIT;
+ }
+
+ if ((pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst == OMX_FALSE) &&
+ (pVideoDec->bForceHeaderParsing == OMX_FALSE)) {
+ ret = VP9CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to VP9CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ }
+
+ if (((bInStartCode = Check_VP9_StartCode(pSrcInputData->multiPlaneBuffer.dataBuffer[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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x, oneFrameSize: %d", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pVp9Dec->hMFCVp9Handle.indexTimestamp, pSrcInputData->nFlags, oneFrameSize);
+ 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;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] bufferHeader: 0x%x, dataBuffer: 0x%x", pExynosComponent, __FUNCTION__, pSrcInputData->bufferHeader, pSrcInputData->multiPlaneBuffer.dataBuffer[0]);
+
+ if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+ nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
+ else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
+ nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
+
+ if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
+ tempBufferHeader.nFlags = pSrcInputData->nFlags;
+ tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+ pPrivate = (void *)&tempBufferHeader;
+ } else {
+ pPrivate = (void *)pSrcInputData->bufferHeader;
+ }
+ codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosInputPort),
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pVp9Dec->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ } else if (bInStartCode == OMX_FALSE) {
+ ret = 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 *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
+ ExynosVideoDecBufferOps *pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
+ ExynosVideoBuffer *pVideoBuffer;
+ 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->allocSize = 0;
+ pSrcOutputData->pPrivate = NULL;
+ } else {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pSrcOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[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, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#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];
+
+ ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
+ 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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ 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] : %d => ADDR[%d]: 0x%x", pExynosComponent, __FUNCTION__, __LINE__, i,
+ pDstInputData->multiPlaneBuffer.dataBuffer[i]);
+ }
+
+ if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+ (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+ (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+ ret = VP9CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to VP9CodecDstSetup(0x%x)", __func__, __LINE__, ret);
+ goto EXIT;
+ }
+ pVideoDec->bReconfigDPB = OMX_FALSE;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ codecReturn = pOutbufOps->Enqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ } else {
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pDstInputData->bufferHeader);
+ }
+
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &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;
+
+ OMX_S32 indexTimestamp = 0;
+ int plane, nPlaneCnt;
+
+ FunctionIn();
+
+ if (pVp9Dec->bDestinationStart == OMX_FALSE) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ while (1) {
+ if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
+ pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
+ if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ }
+
+ if (pVideoBuffer == NULL) {
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ } else {
+ 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, "HW is not available");
+ 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(pExynosOutputPort))) {
+ ret = OMX_ErrorNone;
+ break;
+ }
+ }
+
+ if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+ (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) {
+ if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+ pExynosOutputPort->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(pExynosOutputPort);
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pDstOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pDstOutputData->multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
+ pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+ pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
+ }
+ pDstOutputData->usedDataLen = 0;
+ pDstOutputData->pPrivate = pVideoBuffer;
+ if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ int i = 0;
+ pDstOutputData->pPrivate = NULL;
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ if (pDstOutputData->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+ pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
+ bufferGeometry = &pVp9Dec->hMFCVp9Handle.codecOutbufConf;
+ pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
+ pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
+ pBufferInfo->imageStride = bufferGeometry->nStride;
+ pBufferInfo->ColorFormat = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
+ Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
+
+ 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 timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport == VIDEO_FALSE) {
+ if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
+ (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ 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] indexTimestamp(%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 = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ } else {
+ pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+ }
+ } else {
+ if ((displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+ (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
+ ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+
+ if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+
+ if (displayStatus != VIDEO_FRAME_STATUS_LAST_FRAME) {
+ pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
+ } else {
+ pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+ }
+ }
+ } else {
+ pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 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 (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;
+ }
+
+ 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_SignalReset(pVp9Dec->hSourceStartEvent);
+ }
+
+ ret = Exynos_VP9Dec_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) &&
+ (pExynosComponent->currentState == OMX_StateExecuting)) {
+ 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_ErrorOutputBufferUseYet;
+ else
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pVp9Dec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pVp9Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pVp9Dec->hDestinationStartEvent);
+ }
+ 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;
+ }
+
+ 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 (pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst == OMX_TRUE) {
+ ret = Exynos_VP9Dec_DstIn(pOMXComponent, pDstInputData);
+ if (ret != OMX_ErrorNone) {
+ 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 (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pVp9Dec->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pVp9Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoDec->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pVp9Dec->hDestinationStartEvent);
+ }
+ if (Exynos_OSAL_GetElemNum(&pVp9Dec->bypassBufferInfoQ) > 0) {
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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)) {
+ 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;
+ 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, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ goto EXIT;
+ }
+ if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP9_DEC, componentName) != 0) &&
+ (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP9_CUSTOM_DEC, componentName) != 0)) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+
+ 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 | BUFFER_ANBSHARE;
+ pExynosPort->portWayType = WAY2_PORT;
+ pExynosPort->ePlaneType = PLANE_MULTIPLE;
+
+ 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;
+
+#if 0 /* unused code */
+ pVideoDec->exynos_checkInputFrame = &Check_VP9_Frame;
+ pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ 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, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ Exynos_OSAL_Free(pVp9Dec);
+ pVp9Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->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]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
+ Exynos_OSAL_Free(pVp9Dec);
+ pVp9Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for dec %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport),
+ (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport),
+ (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport),
+ (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bSkypeSupport));
+
+ if (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport == VIDEO_TRUE)
+ pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bDynamicDPBMode = OMX_TRUE;
+
+ Exynos_Output_SetSupportFormat(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;
+
+ 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) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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;
+} EXYNOS_MFC_VP9DEC_HANDLE;
+
+typedef struct _EXYNOS_VP9DEC_HANDLE
+{
+ /* OMX Codec specific */
+ 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 hDestinationStartEvent;
+
+ 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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;
+#ifdef USE_CUSTOM_COMPONENT_SUPPORT
+ /* component 2 - video custom decoder VP9 */
+ Exynos_OSAL_Strcpy(ppExynosComponent[1]->componentName, EXYNOS_OMX_COMPONENT_VP9_CUSTOM_DEC);
+ Exynos_OSAL_Strcpy(ppExynosComponent[1]->roles[0], EXYNOS_OMX_COMPONENT_VP9_DEC_ROLE);
+ ppExynosComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+#endif
+EXIT:
+ FunctionOut();
+ return MAX_COMPONENT_NUM;
+}
--- /dev/null
+/*
+ *
+ * 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 */
+#define EXYNOS_OMX_COMPONENT_VP9_DEC "OMX.Exynos.VP9.Decoder"
+#define EXYNOS_OMX_COMPONENT_VP9_CUSTOM_DEC "OMX.Exynos.vp9.dec"
+#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
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_VencControl.c \
+ Exynos_OMX_Venc.c
+
+LOCAL_MODULE := libExynosOMX_Venc
+LOCAL_ARM_MODE := arm
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/enc \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_CFLAGS += -DUSE_ANDROID
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+ifeq ($(EXYNOS_OMX_SUPPORT_TUNNELING), true)
+LOCAL_CFLAGS += -DTUNNELING_SUPPORT
+endif
+
+ifeq ($(BOARD_USE_METADATABUFFERTYPE), true)
+LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE
+
+ifeq ($(BOARD_USE_STOREMETADATA), true)
+LOCAL_CFLAGS += -DUSE_STOREMETADATA
+endif
+
+ifeq ($(BOARD_USE_ANDROIDOPAQUE), true)
+LOCAL_CFLAGS += -DUSE_ANDROIDOPAQUE
+endif
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_GSC_RGB_ENCODER), true)
+LOCAL_CFLAGS += -DUSE_HW_CSC_GRALLOC_SOURCE
+endif
+
+ifeq ($(BOARD_USE_FIMC_RGB_ENCODER), true)
+LOCAL_CFLAGS += -DUSE_HW_CSC_GRALLOC_SOURCE
+LOCAL_CFLAGS += -DUSE_FIMC_CSC
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_QOS_CTRL), true)
+LOCAL_CFLAGS += -DUSE_QOS_CTRL
+endif
+
+ifeq ($(BOARD_USE_VIDEO_EXT_FOR_WFD_HDCP), true)
+LOCAL_CFLAGS += -DUSE_VIDEO_EXT_FOR_WFD_HDCP
+endif
+
+LOCAL_SHARED_LIBRARIES := libcsc
+
+include $(BUILD_STATIC_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+#ifdef USE_METADATABUFFERTYPE
+#include "Exynos_OSAL_Android.h"
+#endif
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG "EXYNOS_VIDEO_ENC"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+inline 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_ANDROIDOPAQUE
+ 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, "Support Format[%d] : 0x%x", 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_ANDROIDOPAQUE
+ if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)
+ eColorFormat = pVideoEnc->ANBColorFormat;
+#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)
+{
+ 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;
+ 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_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, "Failed to Alloc codec buffer");
+ 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, "Failed to Alloc plane");
+ 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_TRACE, "PORT[%d]: pMFCCodecBuffer[%d]->pVirAddr[%d]: 0x%x", nPortIndex, i, j, ppCodecBuffer[i]->pVirAddr[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->currentState == OMX_StateExecuting) &&
+ (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) &&
+ (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];
+
+ /* 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);
+ }
+
+ 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->multiPlaneBuffer.dataBuffer[i] = pCodecBuffer->pVirAddr[i];
+ pData->multiPlaneBuffer.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 *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ 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_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME);
+ 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 *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;
+ CODEC_ENC_BUFFER *codecInputBuffer = (CODEC_ENC_BUFFER *)srcInputData->pPrivate;
+ OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat;
+ OMX_COLOR_FORMATTYPE inputColorFormat = OMX_COLOR_FormatUnused;
+
+ FunctionIn();
+
+ void *pInputBuf = (void *)inputUseBuffer->bufferHeader->pBuffer;
+ void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, };
+ void *pDstBuf[MAX_BUFFER_PLANE] = {NULL, };
+
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+ unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+ unsigned int nDataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+ OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL};
+
+ OMX_U32 nSrcFrameWidth = 0, nSrcFrameHeight = 0;
+ OMX_U32 nSrcImageWidth = 0, nSrcImageHeight = 0, stride = 0;
+
+ OMX_U32 nDstFrameWidth = 0, nDstFrameHeight = 0;
+ OMX_U32 nDstImageWidth = 0, nDstImageHeight = 0;
+ int i, nPlaneCnt;
+
+ CSC_ERRORCODE cscRet = CSC_ErrorNone;
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+ CSC_MEMTYPE csc_memType = CSC_MEMORY_USERPTR;
+ unsigned int srcCacheable = 1, dstCacheable = 1;
+ unsigned int csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar, PLANE_SINGLE_USER);
+ unsigned int csc_dst_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar, exynosInputPort->ePlaneType);
+
+ nDstFrameWidth = nSrcFrameWidth = ALIGN(exynosInputPort->portDefinition.format.video.nFrameWidth, 16);
+ nDstImageWidth = nSrcImageWidth = exynosInputPort->portDefinition.format.video.nFrameWidth;
+ nDstFrameHeight = nDstImageHeight = nSrcFrameHeight = nSrcImageHeight = exynosInputPort->portDefinition.format.video.nFrameHeight;
+
+ if ((pVideoEnc->eRotationType == ROTATE_90) ||
+ (pVideoEnc->eRotationType == ROTATE_270)) {
+ nDstFrameWidth = ALIGN(exynosInputPort->portDefinition.format.video.nFrameHeight, 16);
+ nDstImageWidth = exynosInputPort->portDefinition.format.video.nFrameHeight;
+ nDstFrameHeight = nDstImageHeight = exynosInputPort->portDefinition.format.video.nFrameWidth;
+ }
+
+ csc_get_method(pVideoEnc->csc_handle, &csc_method);
+
+ /* blur filtering and rotation are supported by H/W */
+ if (((pVideoEnc->bUseBlurFilter == OMX_TRUE) ||
+ (pVideoEnc->eRotationType != ROTATE_0)) &&
+ (csc_method == CSC_METHOD_SW)) {
+ cscRet = csc_set_method(pVideoEnc->csc_handle, CSC_METHOD_HW);
+ if (cscRet != CSC_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: csc_set_method(CSC_METHOD_HW) is failed", __FUNCTION__);
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+
+ csc_method = CSC_METHOD_HW;
+ }
+
+ /* setup dst buffer */
+ pDstBuf[0] = srcInputData->multiPlaneBuffer.dataBuffer[0];
+ pDstBuf[1] = srcInputData->multiPlaneBuffer.dataBuffer[1];
+ pDstBuf[2] = srcInputData->multiPlaneBuffer.dataBuffer[2];
+
+ inputColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+ Exynos_OSAL_GetPlaneSize(inputColorFormat, exynosInputPort->ePlaneType, nDstImageWidth, nDstImageHeight, nDataLen, nAllocLen);
+ codecInputBuffer->dataSize = 0;
+ nPlaneCnt = Exynos_GetPlaneFromPort(exynosInputPort);
+ for (i = 0; i < nPlaneCnt; i++)
+ codecInputBuffer->dataSize += nDataLen[i];
+
+ if (exynosInputPort->ePlaneType == PLANE_SINGLE) { /* for H/W. only Y addr is valid */
+ /* get a count of color plane */
+ int nPlaneCnt = Exynos_OSAL_GetPlaneCount(inputColorFormat, PLANE_MULTIPLE);
+
+ if (nPlaneCnt == 2) { /* Semi-Planar : interleaved */
+ pDstBuf[1] = (void *)(((char *)pDstBuf[0]) + GET_UV_OFFSET(nDstImageWidth, nDstImageHeight));
+ } else if (nPlaneCnt == 3) { /* Planar */
+ pDstBuf[1] = (void *)(((char *)pDstBuf[0]) + GET_CB_OFFSET(nDstImageWidth, nDstImageHeight));
+ pDstBuf[2] = (void *)(((char *)pDstBuf[0]) + GET_CR_OFFSET(nDstImageWidth, nDstImageHeight));
+ }
+ }
+
+ /* setup src buffer */
+#ifdef USE_METADATABUFFERTYPE
+ if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
+ /* 1. meta data is enabled
+ *
+ * 1) gralloc source
+ * 2) camera source
+ */
+ if (OMX_ErrorNone != Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: GetInfoFromMetadata() is failed", __FUNCTION__);
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+
+#ifdef USE_ANDROIDOPAQUE
+ /* 1-1) gralloc source
+ * -> kMetadataBufferTypeGrallocSource
+ * -> when format is not supported at H/W codec
+ */
+ if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque) {
+ OMX_COLOR_FORMATTYPE eDestFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+
+ csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)pVideoEnc->ANBColorFormat, exynosInputPort->ePlaneType);
+ csc_dst_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)eDestFormat, exynosInputPort->ePlaneType);
+
+ if (OMX_ErrorNone != Exynos_OSAL_LockANBHandle(ppBuf[0], nSrcImageWidth, nSrcImageHeight, OMX_COLOR_FormatAndroidOpaque, &stride, planes)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OSAL_LockANBHandle() failed", __FUNCTION__);
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+
+#ifdef USE_HW_CSC_GRALLOC_SOURCE
+#ifdef USE_FIMC_CSC
+ if ((csc_method != CSC_METHOD_HW) &&
+ (pVideoEnc->ANBColorFormat != (OMX_COLOR_FORMATTYPE)OMX_COLOR_Format32BitRGBA8888))
+#else
+ if (csc_method != CSC_METHOD_HW)
+#endif // USE_FIMC_CSC
+ {
+ cscRet = csc_set_method(pVideoEnc->csc_handle, CSC_METHOD_HW);
+ if (cscRet != CSC_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: csc_set_method(CSC_METHOD_HW) is failed", __FUNCTION__);
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+ csc_method = CSC_METHOD_HW;
+ }
+#endif // USE_HW_CSC_GRALLOC_SOURCE
+
+ pSrcBuf[0] = (void *)planes[0].addr;
+ pSrcBuf[1] = (void *)planes[1].addr;
+ pSrcBuf[2] = (void *)planes[2].addr;
+
+#ifdef USE_DMA_BUF
+ if (csc_method == CSC_METHOD_HW) {
+ srcCacheable = 0;
+ csc_memType = CSC_MEMORY_DMABUF;
+ pSrcBuf[0] = INT_TO_PTR(planes[0].fd);
+ pSrcBuf[1] = INT_TO_PTR(planes[1].fd);
+ pSrcBuf[2] = INT_TO_PTR(planes[2].fd);
+ }
+#endif // USE_DMA_BUF
+ } else
+#endif // USE_ANDROIDOPAQUE
+ {
+ /* 1-2) camera source
+ * -> kMetadataBufferTypeCameraSource
+ * -> when blur filter or rotation mode is enabled
+ */
+ csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)eColorFormat, exynosInputPort->ePlaneType);
+ csc_dst_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)eColorFormat, exynosInputPort->ePlaneType);
+
+#ifdef USE_DMA_BUF
+ if (csc_method == CSC_METHOD_HW) {
+ srcCacheable = 0;
+ csc_memType = CSC_MEMORY_DMABUF;
+ pSrcBuf[0] = INT_TO_PTR(ppBuf[0]);
+ pSrcBuf[1] = INT_TO_PTR(ppBuf[1]);
+ pSrcBuf[2] = INT_TO_PTR(ppBuf[2]);
+ } else
+#endif // USE_DMA_BUF
+ { /* CSC_METHOD_SW */
+ Exynos_OSAL_GetPlaneSize(inputColorFormat, exynosInputPort->ePlaneType, nSrcImageWidth, nSrcImageHeight, nDataLen, nAllocLen);
+ for (i = 0; i < nPlaneCnt; i++) {
+ if (PTR_TO_INT(ppBuf[i]) != -1) {
+ pSrcBuf[i] = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, PTR_TO_INT(ppBuf[i]));
+ if(pSrcBuf[i] == NULL)
+ pSrcBuf[i] = Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, nAllocLen[i], PTR_TO_INT(ppBuf[i]));
+
+ if (pSrcBuf[i] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Exynos_OSAL_SharedMemory_Map(%d) is failed", __FUNCTION__, PTR_TO_INT(ppBuf[i]));
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+ }
+ }
+ }
+ }
+ } else
+#endif // USE_USE_METADATABUFFERTYPE
+ {
+ /* 2. meta data is not enabled
+ *
+ * 1) format is supported at HW codec
+ * uses SW CSC for satisfying HW constraints except for blur, rotation mode and USE_CSC_HW.
+ * * blur, rotation is supported by HW.
+ * 2) format is not supported at HW codec
+ * needs CSC(Color-Space-Conversion).
+ */
+ /* calculate each plane info from the application */
+ Exynos_OSAL_GetPlaneSize(eColorFormat, PLANE_SINGLE_USER, nSrcImageWidth, nSrcImageHeight, nDataLen, nAllocLen);
+ pSrcBuf[0] = (void *)((char *)pInputBuf);
+ pSrcBuf[1] = (void *)((char *)pInputBuf + nDataLen[0]);
+ pSrcBuf[2] = (void *)((char *)pInputBuf + nDataLen[0] + nDataLen[1]);
+
+#ifdef USE_CSC_HW
+ if ((pVideoEnc->bUseBlurFilter != OMX_TRUE) &&
+ (pVideoEnc->eRotationType == ROTATE_0) &&
+ (csc_method != CSC_METHOD_HW) &&
+ (eColorFormat == inputColorFormat)) {
+#else
+ if ((pVideoEnc->bUseBlurFilter != OMX_TRUE) &&
+ (pVideoEnc->eRotationType == ROTATE_0) &&
+ (eColorFormat == inputColorFormat)) {
+#endif
+ csc_memType = CSC_MEMORY_MFC; /* to remove stride value */
+ csc_method = CSC_METHOD_SW;
+
+ cscRet = csc_set_method(pVideoEnc->csc_handle, CSC_METHOD_SW);
+ if (cscRet != CSC_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: csc_set_method(CSC_METHOD_SW) for CSC_MEMORY_MFC is failed", __FUNCTION__);
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+ }
+
+ if (pVideoEnc->csc_set_format == OMX_FALSE) {
+ csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)eColorFormat, PLANE_SINGLE_USER);
+ csc_dst_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)inputColorFormat, exynosInputPort->ePlaneType);
+ }
+
+#ifdef USE_DMA_BUF
+ if (csc_method == CSC_METHOD_HW) {
+ srcCacheable = 0;
+ csc_memType = CSC_MEMORY_DMABUF;
+ pSrcBuf[0] = INT_TO_PTR(Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, (char *)pInputBuf));
+ pSrcBuf[1] = NULL;
+ pSrcBuf[2] = NULL;
+ }
+#endif
+ }
+
+ /* re-check a csc_method and setup dst buffer */
+#ifdef USE_DMA_BUF
+ if (csc_method == CSC_METHOD_HW) {
+ dstCacheable = 0;
+ csc_memType = CSC_MEMORY_DMABUF;
+ pDstBuf[0] = INT_TO_PTR(srcInputData->multiPlaneBuffer.fd[0]);
+ pDstBuf[1] = INT_TO_PTR(srcInputData->multiPlaneBuffer.fd[1]);
+ pDstBuf[2] = INT_TO_PTR(srcInputData->multiPlaneBuffer.fd[2]);
+ }
+#endif
+
+ /* set info to libcsc */
+ if (pVideoEnc->csc_set_format == OMX_FALSE) {
+ csc_set_src_format(
+ pVideoEnc->csc_handle, /* handle */
+ nSrcFrameWidth, /* width */
+ nSrcFrameHeight , /* height */
+ 0, /* crop_left */
+ 0, /* crop_right */
+ nSrcImageWidth, /* crop_width */
+ nSrcImageHeight, /* crop_height */
+ csc_src_color_format, /* color_format */
+ srcCacheable); /* cacheable */
+
+ csc_set_dst_format(
+ pVideoEnc->csc_handle, /* handle */
+ nDstFrameWidth, /* width */
+ nDstFrameHeight, /* height */
+ 0, /* crop_left */
+ 0, /* crop_right */
+ nDstImageWidth, /* crop_width */
+ nDstImageHeight, /* crop_height */
+ csc_dst_color_format, /* color_format */
+ dstCacheable); /* cacheable */
+
+ csc_set_eq_property(
+ pVideoEnc->csc_handle, /* handle */
+ CSC_EQ_MODE_USER, /* user select */
+ CSC_EQ_RANGE_NARROW, /* narrow */
+ CSC_EQ_COLORSPACE_SMPTE170M); /* bt.601 */
+
+ pVideoEnc->csc_set_format = OMX_TRUE;
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s CSC(%x) %s/ [SRC] width(%d/%d),height(%d/%d),format(0x%x) -> [DST] width(%d/%d),height(%d/%d),format(0x%x)",
+ pExynosComponent, __FUNCTION__,
+ (csc_method == CSC_METHOD_SW)? "SW":"HW", csc_memType,
+ (pVideoEnc->eRotationType != ROTATE_0)? "with rotation":"",
+ nSrcFrameWidth, nSrcImageWidth, nSrcFrameHeight, nSrcImageHeight, csc_src_color_format,
+ nDstFrameWidth, nDstImageWidth, nDstFrameHeight, nDstImageHeight, csc_dst_color_format);
+ }
+
+ /* blur filter */
+ 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;
+ case BLUR_RESOL_1080:
+ filterType = CSC_FT_1080;
+ break;
+ default:
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invliad eBlurResol(%d)", __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_set_src_buffer(
+ pVideoEnc->csc_handle, /* handle */
+ pSrcBuf,
+ csc_memType); /* YUV Addr or FD */
+
+ csc_set_dst_buffer(
+ pVideoEnc->csc_handle, /* handle */
+ pDstBuf,
+ csc_memType); /* YUV Addr or FD */
+
+ if (pVideoEnc->eRotationType != ROTATE_0)
+ cscRet = csc_convert_with_rotation(pVideoEnc->csc_handle, (int)pVideoEnc->eRotationType, 0, 0);
+ else
+ cscRet = csc_convert(pVideoEnc->csc_handle);
+
+ if (cscRet != CSC_ErrorNone)
+ ret = OMX_FALSE;
+ else
+ ret = OMX_TRUE;
+
+#ifdef USE_METADATABUFFERTYPE
+ if ((exynosInputPort->bStoreMetaData == OMX_TRUE) &&
+ (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)) {
+#ifdef USE_ANDROIDOPAQUE
+ Exynos_OSAL_UnlockANBHandle(ppBuf[0]);
+#endif
+ }
+#endif
+
+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;
+ OMX_BYTE checkInputStream = NULL;
+ OMX_U32 checkInputStreamLen = 0;
+ OMX_BOOL flagEOS = OMX_FALSE;
+
+ FunctionIn();
+
+ if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+ if ((srcInputData->multiPlaneBuffer.dataBuffer[0] == NULL) ||
+ (srcInputData->pPrivate == NULL)) {
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+ }
+
+ if (inputUseBuffer->dataValid == OMX_TRUE) {
+ if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Input port is BUFFER_SHARE", pExynosComponent, __FUNCTION__);
+
+ Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE);
+#ifdef USE_METADATABUFFERTYPE
+ if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
+ OMX_COLOR_FORMATTYPE inputColorFormat = OMX_COLOR_FormatUnused;
+
+ OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL};
+ unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+ unsigned int nDataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+ int plane = 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 (plane = 0; plane < nPlaneCnt; plane++)
+ nAllocLen[plane] += pVideoEnc->nInbufSpareSize;
+ }
+
+ for (plane = 0; plane < MAX_BUFFER_PLANE; plane++) {
+ srcInputData->multiPlaneBuffer.fd[plane] = -1;
+ srcInputData->multiPlaneBuffer.dataBuffer[plane] = NULL;
+ }
+
+ 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);
+ Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
+ Exynos_ResetDataBuffer(inputUseBuffer); /* reset dataBuffer */
+ } else {
+ /* with EOS flag
+ * makes a buffer for EOS handling needed at MFC Processing scheme.
+ */
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ srcInputData->multiPlaneBuffer.dataBuffer[plane] =
+ (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, nAllocLen[plane], NORMAL_MEMORY);
+ srcInputData->multiPlaneBuffer.fd[plane] =
+ Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, srcInputData->multiPlaneBuffer.dataBuffer[plane]);
+ }
+ }
+ } else {
+ if (OMX_ErrorNone != Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: GetInfoFromMetadata() is failed", __FUNCTION__);
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ ret = OMX_FALSE;
+ goto EXIT;
+ }
+#ifdef USE_DMA_BUF
+#ifdef USE_ANDROIDOPAQUE
+ if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque) {
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+ OMX_U32 stride = 0;
+
+ Exynos_OSAL_LockANBHandle(ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, &stride, planes);
+
+ if (stride == ALIGN(exynosInputPort->portDefinition.format.video.nFrameWidth, 16))
+ exynosInputPort->portDefinition.format.video.nStride = stride;
+
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ srcInputData->multiPlaneBuffer.fd[plane] = planes[plane].fd;
+ srcInputData->multiPlaneBuffer.dataBuffer[plane] = planes[plane].addr;
+ }
+ } else
+#endif
+ {
+ /* kMetadataBufferTypeCameraSource */
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ srcInputData->multiPlaneBuffer.fd[plane] = PTR_TO_INT(ppBuf[plane]);
+ }
+ }
+
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ if ((srcInputData->multiPlaneBuffer.fd[plane] != -1) &&
+ (srcInputData->multiPlaneBuffer.dataBuffer[plane] == NULL)) {
+ srcInputData->multiPlaneBuffer.dataBuffer[plane] =
+ Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, srcInputData->multiPlaneBuffer.fd[plane]);
+ if(srcInputData->multiPlaneBuffer.dataBuffer[plane] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Initial mapping is now in progress. fd[%d]",srcInputData->multiPlaneBuffer.fd[plane]);
+ srcInputData->multiPlaneBuffer.dataBuffer[plane] =
+ Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, nAllocLen[plane], srcInputData->multiPlaneBuffer.fd[plane]);
+ }
+ }
+ }
+#else
+#ifdef USE_ANDROIDOPAQUE
+ if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_COLOR_FormatAndroidOpaque share don't implemented in UserPtr mode.");
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, OMX_ErrorNotImplemented, 0, NULL);
+ ret = OMX_FALSE;
+ goto EXIT;
+ } else
+#endif
+ {
+ /* kMetadataBufferTypeCameraSource */
+ for (plane = 0; plane < MAX_BUFFER_PLANE; plane++) {
+ srcInputData->multiPlaneBuffer.dataBuffer[plane] = (int)ppBuf[plane];
+ }
+ }
+#endif
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s:%d YAddr: 0x%p CbCrAddr: 0x%p", __FUNCTION__, __LINE__, ppBuf[0], ppBuf[1]);
+ }
+ }
+#endif
+ /* reset dataBuffer */
+ Exynos_ResetDataBuffer(inputUseBuffer);
+ } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Input port is BUFFER_COPY", pExynosComponent, __FUNCTION__);
+
+ checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
+ checkInputStreamLen = inputUseBuffer->remainDataLen;
+
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+
+ if (checkInputStreamLen == 0) {
+ inputUseBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
+ flagEOS = OMX_TRUE;
+ }
+
+ copySize = checkInputStreamLen;
+
+ if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
+ if ((copySize > 0) || (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) {
+ ret = OMX_TRUE;
+ if (copySize > 0)
+ ret = Exynos_CSC_InputData(pOMXComponent, srcInputData);
+ if (ret) {
+ 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;
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_CSC_InputData() failure");
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ ret = OMX_FALSE;
+ }
+ } else {
+ ret = OMX_FALSE;
+ }
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ ret = OMX_FALSE;
+ }
+
+ Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
+
+ /* reset dataBuffer */
+ Exynos_ResetDataBuffer(inputUseBuffer);
+ }
+
+ if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE");
+ pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+ if (srcInputData->dataLen != 0)
+ pExynosComponent->bBehaviorEOS = OMX_TRUE;
+ }
+
+ 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_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
+ srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
+ }
+
+ ret = OMX_TRUE;
+ }
+
+EXIT:
+
+ 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(dstOutputData, outputUseBuffer, OMX_FALSE) == 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_TRACE, "garbage frame drop after flush");
+ ret = OMX_TRUE;
+ goto EXIT;
+ }
+ } else if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
+ ret = OMX_TRUE;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input buffer has not come after flush.");
+ goto EXIT;
+ }
+
+ if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ if (dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) {
+ copySize = dstOutputData->remainDataLen;
+ if (copySize > 0)
+ Exynos_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen),
+ ((char *)dstOutputData->multiPlaneBuffer.dataBuffer[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)) {
+ Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
+ }
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than encoded data size Out Length");
+ 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) == OMX_BUFFERFLAG_EOS) ||
+ (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
+ if (exynosOutputPort->bStoreMetaData == OMX_TRUE)
+ Exynos_OSAL_SetDataLengthToMetaData(outputUseBuffer->bufferHeader->pBuffer, outputUseBuffer->remainDataLen);
+ Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
+ } else {
+ Exynos_OMX_FillThisBufferAgain(pOMXComponent, outputUseBuffer->bufferHeader);
+ Exynos_ResetDataBuffer(outputUseBuffer);
+ }
+ }
+ } else {
+ ret = OMX_FALSE;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+#ifdef USE_METADATABUFFERTYPE
+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};
+ OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL};
+ int i = 0;
+
+#ifdef USE_METADATABUFFERTYPE
+ if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
+ 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);
+#ifdef USE_ANDROIDOPAQUE
+ if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque) {
+ pVideoEnc->ANBColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+ exynosInputPort->bufferProcessType = BUFFER_SHARE;
+ Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(pVideoEnc->ANBColorFormat, exynosInputPort->ePlaneType));
+ } else
+#endif
+ {
+ Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(eColorFormat, exynosInputPort->ePlaneType));
+ }
+
+ goto EXIT;
+ } else {
+ ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)srcInputUseBuffer->bufferHeader->pBuffer, ppBuf);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: GetInfoFromMetadata() is failed", __FUNCTION__);
+ goto EXIT;
+ }
+
+#ifdef USE_ANDROIDOPAQUE
+ if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque) {
+ /* kMetadataBufferTypeGrallocSource */
+ pVideoEnc->ANBColorFormat = Exynos_OSAL_GetANBColorFormat(ppBuf[0]);
+ eActualFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+ if (eActualFormat == OMX_COLOR_FormatUnused) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported color format : ANB color is 0x%x", __FUNCTION__, pVideoEnc->ANBColorFormat);
+ ret = OMX_ErrorNotImplemented;
+ goto EXIT;
+ }
+
+ if (pVideoEnc->ANBColorFormat == eActualFormat) {
+ exynosInputPort->bufferProcessType = BUFFER_SHARE;
+ Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(pVideoEnc->ANBColorFormat, exynosInputPort->ePlaneType));
+ } else {
+ exynosInputPort->bufferProcessType = BUFFER_COPY;
+ }
+ } else
+#endif
+ {
+ Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(eColorFormat, exynosInputPort->ePlaneType));
+ }
+ }
+
+ }
+#endif
+
+ /* 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;
+ }
+
+ 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, "[%s] unsupported color format : 0x%x", __func__, 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)
+ 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 ANBColorFormat: 0x%x bufferProcessType: 0x%x", pExynosComponent, __FUNCTION__, eActualFormat, eColorFormat, pVideoEnc->ANBColorFormat, exynosInputPort->bufferProcessType);
+
+ return ret;
+}
+#endif
+
+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;
+ OMX_BOOL bValidCodecData = 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_SemaphoreWait(exynosInputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
+ continue;
+ }
+
+ while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
+ (!pVideoEnc->bExitBufferProcessThread)) {
+ Exynos_OSAL_SleepMillisec(0);
+
+ if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
+ break;
+ if (exynosInputPort->portState != OMX_StateIdle)
+ break;
+
+ Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
+ if (pVideoEnc->bFirstInput == OMX_FALSE) {
+ if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
+ OMX_PTR codecBuffer;
+ if ((pSrcInputData->multiPlaneBuffer.dataBuffer[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) {
+ (*(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_SemaphoreWait(exynosInputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
+ 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) {
+ OMX_BOOL bNeedUnlock = OMX_FALSE;
+ OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat;
+#ifdef USE_ANDROIDOPAQUE
+ if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)
+ bNeedUnlock = OMX_TRUE;
+#endif
+ Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer, bNeedUnlock);
+ 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_SemaphoreWait(exynosOutputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
+ continue;
+ }
+
+ while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
+ (!pVideoEnc->bExitBufferProcessThread)) {
+ Exynos_OSAL_SleepMillisec(0);
+
+ if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
+ (!CHECK_PORT_POPULATED(exynosOutputPort)))
+ break;
+ if (exynosOutputPort->portState != OMX_StateIdle)
+ 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;
+ }
+ Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, ONE_PLANE);
+ if (exynosOutputPort->bStoreMetaData == OMX_TRUE) {
+ int ionFD = -1;
+ OMX_PTR dataBuffer = NULL;
+ OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL};
+
+ ret = Exynos_OSAL_GetBufferFdFromMetaData((OMX_BYTE)dstInputUseBuffer->bufferHeader->pBuffer, ppBuf);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OSAL_GetBufferFdFromMetaData() is failed", __FUNCTION__);
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+ break;
+ }
+
+ /* caution : data loss */
+ ionFD = PTR_TO_INT(ppBuf[0]);
+
+ dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, ionFD);
+ if (dataBuffer == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Wrong dst-input Metadata buffer", __LINE__);
+ ret = OMX_ErrorUndefined;
+ Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+ break;
+ }
+ dstInputData.multiPlaneBuffer.fd[0] = ionFD;
+ dstInputData.multiPlaneBuffer.dataBuffer[0] = dataBuffer;
+ } else {
+ if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC) {
+ /* caution : data loss */
+ int ionFD = PTR_TO_INT(dstInputData.multiPlaneBuffer.dataBuffer[0]);
+
+ OMX_PTR dataBuffer = NULL;
+ dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, ionFD);
+ if (dataBuffer == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Wrong dst-input Secure buffer", __LINE__);
+ ret = OMX_ErrorUndefined;
+ Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
+ break;
+ }
+ dstInputData.multiPlaneBuffer.fd[0] = ionFD;
+ dstInputData.multiPlaneBuffer.dataBuffer[0] = dataBuffer;
+ } else {
+ dstInputData.multiPlaneBuffer.fd[0] =
+ Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory,
+ dstInputData.multiPlaneBuffer.dataBuffer[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_SemaphoreWait(exynosOutputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
+ 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;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+ EXYNOS_OMX_MESSAGE *message = 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;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ 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;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+ EXYNOS_OMX_MESSAGE *message = 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;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ 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;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+ EXYNOS_OMX_MESSAGE *message = 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;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ 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;
+ EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
+ EXYNOS_OMX_MESSAGE *message = 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;
+ }
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ 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;
+ unsigned int i = 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_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);
+
+ 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);
+
+ 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);
+
+ 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) {
+ 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, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_Port_Constructor(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ pVideoEnc = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
+ if (pVideoEnc == NULL) {
+ Exynos_OMX_Port_Destructor(pOMXComponent);
+ Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+
+ pExynosComponent->bMultiThreadProcess = OMX_TRUE;
+
+ /* 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+
+#ifdef USE_METADATABUFFERTYPE
+ pExynosPort->bStoreMetaData = OMX_FALSE;
+#endif
+
+ /* 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+
+ 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) {
+ 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;
+
+ 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;
+}
--- /dev/null
+/*
+ *
+ * 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 DEFAULT_FRAME_WIDTH 176
+#define DEFAULT_FRAME_HEIGHT 144
+
+#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 2 /* 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 */
+ int 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 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 ANBColorFormat;
+
+ /* 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);
+
+#if 0 /* unused code */
+ int (*exynos_checkInputFrame) (OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag,
+ OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame);
+ OMX_ERRORTYPE (*exynos_codec_getCodecInputPrivateData) (OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[]);
+#endif
+
+ 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
+
+inline 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
--- /dev/null
+/*
+ *
+ * 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)
+ * @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_Mutex.h"
+#include "Exynos_OSAL_ETC.h"
+#include "Exynos_OSAL_SharedMemory.h"
+
+#ifdef USE_METADATABUFFERTYPE
+#include "Exynos_OSAL_Android.h"
+#endif
+
+#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) {
+ 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) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+
+ if (pExynosPort->portState != OMX_StateIdle) {
+ 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) {
+ 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++;
+ if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+ pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ }
+ *ppBufferHdr = pTempBufferHdr;
+ ret = OMX_ErrorNone;
+ 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;
+ int fdTempBuffer = -1;
+ MEMORY_TYPE eMemType = NORMAL_MEMORY;
+ OMX_U32 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->hComponentHandle == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+
+ if (nPortIndex >= pExynosComponent->portParam.nPorts) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+/*
+ if (pExynosPort->portState != OMX_StateIdle ) {
+ 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->bStoreMetaData == OMX_TRUE)) {
+ OMX_U32 nDataBufferSize = 0;
+
+#ifdef USE_VIDEO_EXT_FOR_WFD_HDCP
+ if ((eMemType & SECURE_MEMORY) || // secure component
+ (eMemType & CONTIG_MEMORY)) // Normal DRM
+ eMemType |= EXT_MEMORY;
+#endif
+
+ nDataBufferSize = ALIGN(pExynosPort->portDefinition.format.video.nFrameWidth *
+ pExynosPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+ pTempBuffer = Exynos_OSAL_AllocMetaDataBuffer(pVideoEnc->hSharedMemory,
+ pExynosComponent->codecType,
+ nPortIndex,
+ nDataBufferSize,
+ eMemType);
+ if (pTempBuffer == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else {
+ pTempBuffer = Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, nSizeBytes, eMemType);
+ if (pTempBuffer == NULL) {
+ 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_SharedMemory_Free(pVideoEnc->hSharedMemory, pTempBuffer);
+ 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->bStoreMetaData == OMX_FALSE))
+ pTempBufferHdr->pBuffer = INT_TO_PTR(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++;
+ if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+ pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ }
+ *ppBufferHdr = pTempBufferHdr;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pTempBufferHdr);
+ Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pTempBuffer);
+
+ 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) {
+ 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) {
+ 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 != OMX_StateLoaded) &&
+ (pExynosPort->portState != OMX_StateInvalid)) &&
+ (pExynosPort->portDefinition.bEnabled != OMX_FALSE)) {
+ (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent,
+ pExynosComponent->callbackData,
+ (OMX_U32)OMX_EventError,
+ (OMX_U32)OMX_ErrorPortUnpopulated,
+ nPortIndex, NULL);
+ ret = OMX_ErrorInvalidState;
+ 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) {
+ if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) {
+ if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+ (pExynosPort->bStoreMetaData == OMX_TRUE)) {
+ ret = Exynos_OSAL_FreeMetaDataBuffer(pVideoEnc->hSharedMemory,
+ pExynosComponent->codecType,
+ nPortIndex,
+ pOMXBufferHdr->pBuffer);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+ } else {
+ if ((pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC) &&
+ (nPortIndex == OUTPUT_PORT_INDEX)) {
+ /* caution : data loss */
+ int ionFD = PTR_TO_INT(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;
+ pBufferHdr = NULL;
+ }
+
+ pExynosPort->bufferStateAllocate[i] = BUFFER_STATE_FREE;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ }
+ }
+
+EXIT:
+ if ((ret == OMX_ErrorNone) &&
+ (pExynosPort->assignedBufferNum == 0)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosPort->unloadedResource signal set");
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->unloadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ pExynosPort->portDefinition.bPopulated = OMX_FALSE;
+ }
+
+ 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;
+
+ FunctionIn();
+
+ *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);
+ }
+
+EXIT:
+ FunctionOut();
+
+ 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) {
+ 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->messageType != 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 (pExynosComponent->bMultiThreadProcess == OMX_TRUE) {
+ if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+ if (pExynosPort->processData.bufferHeader != NULL) {
+ if (nPortIndex == INPUT_PORT_INDEX) {
+#if defined(USE_METADATABUFFERTYPE) && defined(USE_ANDROIDOPAQUE)
+ if ((pExynosPort->bStoreMetaData == OMX_TRUE) &&
+ (pExynosPort->portDefinition.format.video.eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)) {
+ OMX_PTR ppBuf[MAX_BUFFER_PLANE];
+ if (OMX_ErrorNone ==
+ Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pExynosPort->processData.bufferHeader->pBuffer, ppBuf))
+ Exynos_OSAL_UnlockANBHandle(ppBuf[0]);
+ }
+#endif
+ 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 defined(USE_METADATABUFFERTYPE) && defined(USE_ANDROIDOPAQUE)
+ if ((pExynosPort->bStoreMetaData == OMX_TRUE) &&
+ (pExynosPort->portDefinition.format.video.eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)) {
+ OMX_PTR ppBuf[MAX_BUFFER_PLANE];
+ if (OMX_ErrorNone ==
+ Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer, ppBuf))
+ Exynos_OSAL_UnlockANBHandle(ppBuf[0]);
+ }
+#endif
+ Exynos_OMX_InputBufferReturn(pOMXComponent,
+ pExynosPort->extendBufferHeader[i].OMXBufferHeader);
+ }
+ }
+ }
+ }
+ } else {
+ Exynos_ResetCodecData(&pExynosPort->processData);
+ }
+
+ 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};
+ OMX_U32 i = 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;
+
+ 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,"OMX_CommandFlush start, port:%d", nPortIndex);
+
+ pExynosPort->bIsPortFlushed = OMX_TRUE;
+
+ if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
+ Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
+ } else {
+ 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;
+ }
+
+ pExynosPort->bIsPortFlushed = OMX_FALSE;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush EventCmdComplete, port:%d", nPortIndex);
+ if (bEvent == OMX_TRUE)
+ pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventCmdComplete,
+ OMX_CommandFlush, nPortIndex, NULL);
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_CountReset(pExynosPort->hBufferCount);
+#endif
+ }
+
+ if (pDataBuffer[1] != NULL)
+ Exynos_OSAL_MutexUnlock(pDataBuffer[1]->bufferMutex);
+
+ Exynos_OSAL_MutexUnlock(pDataBuffer[0]->bufferMutex);
+
+EXIT:
+ if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__);
+ pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
+ pExynosComponent->callbackData,
+ OMX_EventError,
+ ret, 0, NULL);
+ }
+
+ 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) {
+ 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]);
+
+ if (pDataBuffer != NULL)
+ 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) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
+ Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+ if (pDataBuffer->dataValid != OMX_TRUE) {
+ pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (pMessage == NULL) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+ if (pMessage->messageType == EXYNOS_OMX_CommandFakeBuffer) {
+ Exynos_OSAL_Free(pMessage);
+ ret = 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, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", 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->bStoreMetaData == OMX_TRUE) &&
+ (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, "event OMX_BUFFERFLAG_EOS!!!");
+ 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) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
+ Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
+ if (pDataBuffer->dataValid != OMX_TRUE) {
+ pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (pMessage == NULL) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+ if (pMessage->messageType == EXYNOS_OMX_CommandFakeBuffer) {
+ Exynos_OSAL_Free(pMessage);
+ ret = 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_SemaphoreWait(pExynosPort->bufferSemID);
+
+ pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
+ if (pMessage == NULL) {
+ pBufferHdr = NULL;
+ goto EXIT;
+ }
+ if (pMessage->messageType == 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_SemaphoreWait(pExynosPort->codecSemID);
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ if (pVideoEnc == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ 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)
+ 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)
+ 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;
+ /* 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)
+ goto EXIT;
+
+ pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
+ Exynos_OSAL_Memcpy(((char *)pPortDef) + nOffset,
+ ((char *)&pExynosPort->portDefinition) + nOffset,
+ pPortDef->nSize - nOffset);
+
+#ifdef USE_STOREMETADATA
+ if (pExynosPort->bStoreMetaData == OMX_TRUE)
+ pPortDef->nBufferSize = MAX_METADATA_BUFFER_SIZE;
+#endif
+ }
+ 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)
+ 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)
+ 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)
+ 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_GetAndroidParameter(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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ if (pVideoEnc == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ 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)
+ 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, "%s[%x] xFramerate is invalid(%d)",
+ __FUNCTION__, OMX_IndexParamVideoPortFormat, 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)
+ 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, "pExynosOutputPort->portDefinition.nBufferSize: %d",
+ pExynosPort->portDefinition.nBufferSize);
+ }
+ ret = OMX_ErrorNone;
+ }
+ break;
+#ifdef USE_STOREMETADATA
+ case OMX_IndexParamStoreMetaDataBuffer:
+ {
+ ret = Exynos_OSAL_SetAndroidParameter(hComponent, nParamIndex, pComponentParameterStructure);
+ }
+ break;
+#endif
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ if (pVideoEnc == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ 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)
+ goto EXIT;
+
+ pBufferInfo->fd = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pBufferInfo->pVirAddr);
+ }
+ break;
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ if (pVideoEnc == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ 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, "Rate control(eControlRate) is disable. can not change a bitrate");
+ 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, "%s[%x] xFramerate is invalid(%d)",
+ __FUNCTION__, OMX_IndexConfigVideoFramerate, 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)
+ goto EXIT;
+
+ xFramerate = pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.xFramerate;
+ if (xFramerate == 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s : xFramerate is zero. can't calculate QosRatio", __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;
+#ifdef USE_QOS_CTRL
+ case OMX_IndexVendorSetQosRatio: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *pQosInfo = (EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *)pComponentConfigStructure;
+
+ ret = Exynos_OMX_Check_SizeVersion(pQosInfo, sizeof(EXYNOS_OMX_VIDEO_CONFIG_QOSINFO));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ pVideoEnc->nQosRatio = pQosInfo->nQosRatio;
+ pVideoEnc->bQosChanged = OMX_TRUE;
+
+ ret = OMX_ErrorNone;
+ }
+ break;
+#endif
+ 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)
+ 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, "[%s] Resolution(%d x %d) is smaller than target resolution",
+ __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, "[%s] Blur Filter is not enabled, it will be discard", __FUNCTION__);
+ }
+
+ ret = (OMX_ERRORTYPE)OMX_ErrorNoneExpiration;
+ }
+ break;
+ 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) {
+ 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 ((szParamName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) {
+ *pIndexType = 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_CONFIG_OPERATING_RATE) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexConfigOperatingRate;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+#ifdef USE_QOS_CTRL
+ if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_CONFIG_SET_QOS_RATIO) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexVendorSetQosRatio;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+#endif
+
+#ifdef USE_STOREMETADATA
+ if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) {
+ *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamStoreMetaDataBuffer;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+#endif
+
+ 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;
+ }
+
+ ret = Exynos_OMX_GetExtensionIndex(hComponent, szParamName, pIndexType);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer, OMX_BOOL bNeedUnlock)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ 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 defined(USE_METADATABUFFERTYPE) && defined(USE_ANDROIDOPAQUE)
+ if ((bNeedUnlock == OMX_TRUE) && (pUseBuffer->bufferHeader != NULL)) {
+ OMX_PTR ppBuf[MAX_BUFFER_PLANE];
+ if (OMX_ErrorNone ==
+ Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pUseBuffer->bufferHeader->pBuffer, ppBuf))
+ Exynos_OSAL_UnlockANBHandle(ppBuf[0]);
+ }
+#endif
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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)
+ * @version 2.0.0
+ * @history
+ * 2012.02.20 : Create
+ */
+
+#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_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer, OMX_BOOL bNeedUnlock);
+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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
--- /dev/null
+
+ 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
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_H264enc.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.AVC.Encoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_CFLAGS += -DUSE_ANDROID
+endif
+
+ifeq ($(BOARD_USE_METADATABUFFERTYPE), true)
+LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE
+
+ifeq ($(BOARD_USE_ANDROIDOPAQUE), true)
+LOCAL_CFLAGS += -DUSE_ANDROIDOPAQUE
+endif
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_QOS_CTRL), true)
+LOCAL_CFLAGS += -DUSE_QOS_CTRL
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/enc \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_SKYPE_HD), true)
+LOCAL_CFLAGS += -DUSE_SKYPE_HD
+LOCAL_CFLAGS += -DBUILD_ENC
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/skype
+LOCAL_STATIC_LIBRARIES += libExynosOMX_SkypeHD_Enc
+endif
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+#ifdef USE_ANDROID
+#include "Exynos_OSAL_Android.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;
+
+ FunctionIn();
+
+ 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_100:
+ case MFC_101:
+ pH264Enc->hMFCH264Handle.maxLevel = OMX_VIDEO_AVCLevel52;
+ break;
+ case MFC_80:
+ case MFC_90:
+ case MFC_1010:
+ 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:
+ 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;
+ }
+
+ while ((pH264Enc->hMFCH264Handle.maxLevel >> nLevelCnt) > 0) {
+ nLevelCnt++;
+ }
+
+ if ((pH264Enc->hMFCH264Handle.nProfileCnt == 0) ||
+ (nLevelCnt == 0)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : there is no any profile/level", __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);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : supported profile(%x), level(%x)", __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, "%s : there is no any profile/level", __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, "%s : profile(%x)/level(%x) is %ssupported", __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_ESSENTIAL, "PadControlOn : %d", pCommonParam->PadControlOn);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LumaPadVal : %d", pCommonParam->LumaPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CbPadVal : %d", pCommonParam->CbPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "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_ESSENTIAL, "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_ESSENTIAL, "LoopFilterDisable : %d", pH264Param->LoopFilterDisable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LoopFilterAlphaC0Offset : %d", pH264Param->LoopFilterAlphaC0Offset);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LoopFilterBetaOffset : %d", pH264Param->LoopFilterBetaOffset);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SymbolMode : %d", pH264Param->SymbolMode);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "PictureInterlace : %d", pH264Param->PictureInterlace);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Transform8x8Mode : %d", pH264Param->Transform8x8Mode);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "DarkDisable : %d", pH264Param->DarkDisable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SmoothDisable : %d", pH264Param->SmoothDisable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "StaticDisable : %d", pH264Param->StaticDisable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "ActivityDisable : %d", pH264Param->ActivityDisable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "HierarType: : %d", pH264Param->HierarType);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "VuiRestrictionEnable: : %d", pH264Param->VuiRestrictionEnable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "HeaderWithIFrame: : %d", pH264Param->HeaderWithIFrame);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SarEnable: : %d", pH264Param->SarEnable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SarIndex: : %d", pH264Param->SarIndex);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SarWidth: : %d", pH264Param->SarWidth);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SarHeight: : %d", pH264Param->SarHeight);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LTREnable: : %d", pH264Param->LTREnable);
+
+ /* 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 *pExynosInputPort = NULL;
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = 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;
+ pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ pEncParam = &pMFCH264Handle->encParam;
+ pCommonParam = &pEncParam->commonParam;
+ pH264Param = &pEncParam->codecParam.h264;
+
+ pEncParam->eCompressionFormat = VIDEO_CODING_AVC;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "eCompressionFormat: %d", pEncParam->eCompressionFormat);
+
+ /* common parameters */
+ if ((pVideoEnc->eRotationType == ROTATE_0) ||
+ (pVideoEnc->eRotationType == ROTATE_180)) {
+ pCommonParam->SourceWidth = pExynosOutputPort->portDefinition.format.video.nFrameWidth;
+ pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameHeight;
+ } else {
+ pCommonParam->SourceWidth = pExynosOutputPort->portDefinition.format.video.nFrameHeight;
+ pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameWidth;
+ }
+ pCommonParam->IDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
+ pCommonParam->SliceMode = pH264Enc->AVCSliceFmo.eSliceMode;
+ pCommonParam->Bitrate = pExynosOutputPort->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;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh: %d", pCommonParam->RandomIntraMBRefresh);
+ } else {
+ /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+ pCommonParam->RandomIntraMBRefresh = 0;
+ }
+
+ eColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+ pCommonParam->FrameMap = Exynos_OSAL_OMX2VideoFormat(eColorFormat, pExynosInputPort->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 = (pExynosInputPort->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 */
+ pH264Param->TemporalSVC.nTemporalLayerCount = (unsigned int)pH264Enc->TemporalSVC.nTemporalLayerCount;
+ for (i = 0; i < OMX_VIDEO_ANDROID_MAXAVCTEMPORALLAYERS; i++)
+ pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)pH264Enc->TemporalSVC.nTemporalLayerBitrateRatio[i];
+
+ /* Hierarchal P & B */
+ pH264Param->HierarType = pH264Enc->eHierarchicalType;
+
+ /* SPS VUI */
+ if (pH264Enc->stSarParam.SarEnable == OMX_TRUE) {
+ pH264Param->SarEnable = 1;
+ /* TBD */
+ /*need value check*/
+ pH264Param->SarIndex = pH264Enc->stSarParam.SarIndex;
+ pH264Param->SarWidth = pH264Enc->stSarParam.SarWidth;
+ pH264Param->SarHeight = pH264Enc->stSarParam.SarHeight;
+
+ } else {
+ pH264Param->SarEnable = 0;
+ pH264Param->SarIndex = 0;
+ pH264Param->SarWidth = 0;
+ pH264Param->SarHeight = 0;
+ }
+
+ 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;
+ }
+
+ if (pMFCH264Handle->bLTREnable == OMX_TRUE)
+ pH264Param->LTREnable = 1;
+ else
+ pH264Param->LTREnable = 0;
+
+ if (pMFCH264Handle->bRoiInfo == OMX_TRUE)
+ pH264Param->ROIEnable = 1;
+ else
+ pH264Param->ROIEnable = 0;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", 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;
+ 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 void Change_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+ 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;
+ }
+ break;
+ case OMX_IndexConfigVideoIntraPeriod:
+ {
+ OMX_S32 nPFrames = (*((OMX_S32 *)pConfigData)) - 1;
+ nValue = nPFrames + 1;
+ pEncOps->Set_IDRPeriod(pH264Enc->hMFCH264Handle.hMFCHandle, nValue);
+ }
+ break;
+ case OMX_IndexConfigVideoAVCIntraPeriod:
+ {
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pConfigData;
+ nValue = pAVCIntraPeriod->nIDRPeriod;
+ pEncOps->Set_IDRPeriod(pMFCH264Handle->hMFCHandle, 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);
+ }
+ }
+ 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);
+ }
+ }
+ 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);
+ }
+ 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;
+ }
+ break;
+#ifdef USE_QOS_CTRL
+ case OMX_IndexVendorSetQosRatio: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *pQosInfo = (EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *)pConfigData;
+ nValue = pQosInfo->nQosRatio;
+ pEncOps->Set_QosRatio(pMFCH264Handle->hMFCHandle, nValue);
+ pVideoEnc->bQosChanged = OMX_FALSE;
+ }
+ break;
+#endif
+ case OMX_IndexConfigVideoTemporalSVC:
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pTemporalSVC = (EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *)pConfigData;
+ ExynosVideoQPRange qpRange;
+
+ 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);
+
+ /* Temporal SVC */
+ TemporalLayerShareBuffer TemporalSVC;
+ Exynos_OSAL_Memset(&TemporalSVC, 0, sizeof(TemporalLayerShareBuffer));
+ TemporalSVC.nTemporalLayerCount = (unsigned int)pTemporalSVC->nTemporalLayerCount;
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "nTemporalLayerCount : %d", TemporalSVC.nTemporalLayerCount);
+ for (i = 0; i < OMX_VIDEO_ANDROID_MAXAVCTEMPORALLAYERS; i++) {
+ TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)pTemporalSVC->nTemporalLayerBitrateRatio[i];
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "nTempBitrateRatio[%d] : %d", i, TemporalSVC.nTemporalLayerBitrateRatio[i]);
+ }
+ pEncOps->Set_LayerChange(pMFCH264Handle->hMFCHandle, TemporalSVC);
+ }
+ 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;
+ if (pEncOps->Set_RoiInfo != NULL)
+ pEncOps->Set_RoiInfo(pMFCH264Handle->hMFCHandle, &RoiInfo);
+ else
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: Not supported control: Set_RoiInfo", __func__);
+ }
+ break;
+ default:
+#ifdef USE_SKYPE_HD
+ if (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bSkypeSupport == VIDEO_TRUE)
+ Change_H264Enc_SkypeHDParam(pExynosComponent, pDynamicConfigCMD);
+#endif
+ break;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nCmdIndex %x nValue %d ", pExynosComponent, __FUNCTION__, (int)nCmdIndex, nValue);
+ Exynos_OSAL_Free(pDynamicConfigCMD);
+
+ Set_H264Enc_Param(pExynosComponent);
+
+EXIT:
+ return;
+}
+
+#if 0 /* unused code */
+OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ ExynosVideoBuffer *pCodecBuffer;
+
+ if (codecBuffer == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
+
+ if (pVirtAddr != NULL)
+ *pVirtAddr = pCodecBuffer->planes[0].addr;
+
+ if (dataSize != NULL)
+ *dataSize = pCodecBuffer->planes[0].allocSize;
+
+ pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
+
+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_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate encoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps);
+
+ /* 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, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pH264Enc->hMFCH264Handle.hMFCHandle = pH264Enc->hMFCH264Handle.pEncOps->Init(pVideoInstInfo);
+ if (pH264Enc->hMFCH264Handle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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;
+ }
+
+ /* 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+ ExynosVideoEncBufferOps *pInbufOps = NULL;
+ ExynosVideoEncBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
+ EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
+ 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+ ExynosVideoEncBufferOps *pInbufOps = NULL;
+ ExynosVideoEncBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
+ EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
+ 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+ ExynosVideoEncBufferOps *pInbufOps = NULL;
+ ExynosVideoEncBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
+ EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
+ pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
+ pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+
+ 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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE H264CodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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;
+ CODEC_ENC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoEncBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
+ pBufOps = pH264Enc->hMFCH264Handle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
+ pBufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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 *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ int i, nOutbufs;
+
+ ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+
+ 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, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
+
+ 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, "pVideoEnc->pMFCEncOutputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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 *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ void *hMFCHandle = pMFCH264Handle->hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ OMX_U32 oneFrameSize = pSrcInputData->dataLen;
+
+ ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+ ExynosVideoEncParam *pEncParam = NULL;
+
+ ExynosVideoGeometry bufferConf;
+ OMX_U32 inputBufferNumber = 0;
+ int i, nOutbufs;
+
+ FunctionIn();
+
+ if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] FBD with EOS will be processed through bypassBufferInfoQ",
+ 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);
+ Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent); /* awake dstInput thread */
+
+ 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, "Failed to set geometry for input buffer");
+ 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, "%s: Not supported control: Enable_PrependSpsPpsToIdr", __func__);
+ }
+
+ /* 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 = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+ bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+ bufferConf.nStride = ALIGN(pExynosInputPort->portDefinition.format.video.nFrameWidth, 16);
+ } else {
+ bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+ bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+ bufferConf.nStride = ALIGN(pExynosInputPort->portDefinition.format.video.nFrameHeight, 16);
+ }
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+ pInbufOps->Set_Shareable(hMFCHandle);
+ inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+ if (pExynosInputPort->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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+#ifdef USE_METADATABUFFERTYPE
+ && (pExynosInputPort->bStoreMetaData != OMX_TRUE)
+#endif
+ ) {
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
+ 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, nOutbufs;
+
+ FunctionIn();
+
+ int nOutBufSize = pExynosOutputPort->portDefinition.nBufferSize;
+ if (pExynosOutputPort->bStoreMetaData == OMX_TRUE) {
+ nOutBufSize = ALIGN(pExynosOutputPort->portDefinition.format.video.nFrameWidth *
+ pExynosOutputPort->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(pExynosOutputPort);
+
+ if (pOutbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
+ 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);
+ int SetupBufferNumber = 0;
+ if (pExynosOutputPort->bufferProcessType & BUFFER_COPY)
+ SetupBufferNumber = MFC_OUTPUT_BUFFER_NUM_MAX;
+ else
+ SetupBufferNumber = pExynosOutputPort->portDefinition.nBufferCountActual;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SetupBufferNumber:%d", SetupBufferNumber);
+
+ if (pOutbufOps->Setup(pH264Enc->hMFCH264Handle.hMFCHandle, SetupBufferNumber) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ nAllocLen[0] = nOutBufSize;
+ ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX, nAllocLen);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
+ (int *)pVideoEnc->pMFCEncOutputBuffer[i]->fd,
+ pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosOutputPort),
+ NULL);
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ /* Register output buffer */
+ /*************/
+ /* TBD */
+ /*************/
+ }
+ pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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) {
+ 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) {
+ 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) {
+ goto EXIT;
+ }
+
+ 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) {
+ 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) {
+ 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) {
+ 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)
+ 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) {
+ 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) {
+ goto EXIT;
+ }
+
+ if (pDstEnableRoiInfo->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pDstEnableRoiInfo->bEnableRoiInfo = pH264Enc->hMFCH264Handle.bRoiInfo;
+ }
+ break;
+
+ default:
+#ifdef USE_SKYPE_HD
+ if (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bSkypeSupport == VIDEO_TRUE)
+ ret = Exynos_H264Enc_GetParameter_SkypeHD(hComponent, nParamIndex, pComponentParameterStructure);
+ else
+ ret = OMX_ErrorUnsupportedIndex;
+
+ if (OMX_ErrorNone != ret)
+#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;
+
+ 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 ) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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) {
+ 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) {
+ 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) {
+ 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)) {
+ 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)
+ 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) {
+ 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)
+ 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;
+ case OMX_IndexParamPrependSPSPPSToIDR:
+ {
+#ifdef USE_ANDROID
+ ret = Exynos_OSAL_SetPrependSPSPPSToIDR(pComponentParameterStructure, &(pH264Enc->hMFCH264Handle.bPrependSpsPpsToIdr));
+#else
+ ret = OMX_ErrorNotImplemented;
+#endif
+ }
+ break;
+ 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) {
+ goto EXIT;
+ }
+
+ if (pSrcEnableTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) &&
+ (pSrcEnableTemporalSVC->bEnableTemporalSVC == OMX_TRUE)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: MFC D/D doesn't support Temporal SVC", __func__);
+ 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_ANDROID_MAXAVCTEMPORALLAYERS; 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;
+ int i;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcEnableRoiInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcEnableRoiInfo->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bRoiInfoSupport == VIDEO_FALSE) &&
+ (pSrcEnableRoiInfo->bEnableRoiInfo == OMX_TRUE)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: MFC D/D doesn't support Roi Info", __func__);
+ 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) {
+ 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, "%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);
+
+ if (pVideoEnc->bFirstInput == OMX_FALSE)
+ pVideoEnc->bEncDRC = OMX_TRUE;
+
+ pVideoEnc->bFirstInput = OMX_TRUE;
+ pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosOutputPort->portDefinition.nBufferSize: %d", pExynosPort->portDefinition.nBufferSize);
+ } else if (nPortIndex == OUTPUT_PORT_INDEX) {
+ pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
+ }
+
+ ret = OMX_ErrorNone;
+ }
+ break;
+
+ default:
+#ifdef USE_SKYPE_HD
+ if (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bSkypeSupport == VIDEO_TRUE)
+ ret = Exynos_H264Enc_SetParameter_SkypeHD(hComponent, nIndex, pComponentParameterStructure);
+ else
+ ret = OMX_ErrorUnsupportedIndex;
+
+ if (OMX_ErrorNone != ret)
+#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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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)
+ 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;
+ default:
+#ifdef USE_SKYPE_HD
+ if (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bSkypeSupport == VIDEO_TRUE)
+ ret = Exynos_H264Enc_GetConfig_SkypeHD(hComponent, nIndex, pComponentConfigStructure);
+ else
+ ret = OMX_ErrorUnsupportedIndex;
+
+ if (OMX_ErrorNone != ret)
+#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;
+
+ FunctionIn();
+
+ if (hComponent == NULL || pComponentConfigStructure == 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+ switch ((int)nIndex) {
+ case OMX_IndexConfigVideoIntraPeriod:
+ {
+ EXYNOS_OMX_VIDEOENC_COMPONENT *pVEncBase = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
+ 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)
+ 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;
+ case OMX_IndexConfigVideoTemporalSVC:
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pDstTemporalSVC = &pH264Enc->TemporalSVC;
+ 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)
+ goto EXIT;
+
+ if (pSrcTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pH264Enc->hMFCH264Handle.bTemporalSVC == OMX_FALSE) ||
+ (pSrcTemporalSVC->nTemporalLayerCount > OMX_VIDEO_ANDROID_MAXAVCTEMPORALLAYERS)) {
+ 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);
+ }
+ 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) ||
+ ((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;
+ }
+ }
+ break;
+ default:
+#ifdef USE_SKYPE_HD
+ if (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bSkypeSupport == VIDEO_TRUE)
+ ret = Exynos_H264Enc_SetConfig_SkypeHD(hComponent, nIndex, pComponentConfigStructure);
+ else
+ ret = OMX_ErrorUnsupportedIndex;
+
+ if (OMX_ErrorNone != ret)
+#endif
+ ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ if (ret == OMX_ErrorNone) {
+ OMX_PTR pDynamicConfigCMD = NULL;
+ pDynamicConfigCMD = Exynos_OMX_MakeDynamicConfigCMD(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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR) == 0) {
+ *pIndexType = OMX_IndexParamPrependSPSPPSToIDR;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_TEMPORALSVC) == 0) {
+ *pIndexType = OMX_IndexConfigVideoTemporalSVC;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_VIDEO_AVC_ENABLE_TEMPORALSVC) == 0) {
+ *pIndexType = OMX_IndexParamVideoAVCEnableTemporalSVC;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_ROIINFO) == 0) {
+ *pIndexType = OMX_IndexConfigVideoRoiInfo;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_VIDEO_ENABLE_ROIINFO) == 0) {
+ *pIndexType = OMX_IndexParamVideoEnableRoiInfo;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+#ifdef USE_SKYPE_HD
+ if (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bSkypeSupport == VIDEO_TRUE)
+ ret = Exynos_H264Enc_GetExtensionIndex_SkypeHD(hComponent, cParameterName, pIndexType);
+ else
+ ret = OMX_ErrorUnsupportedIndex;
+
+ if (ret != OMX_ErrorNone)
+#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)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ OMX_PTR hMFCHandle = NULL;
+ OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
+
+ ExynosVideoEncOps *pEncOps = NULL;
+ ExynosVideoEncBufferOps *pInbufOps = NULL;
+ ExynosVideoEncBufferOps *pOutbufOps = NULL;
+ ExynosVideoInstInfo *pVideoInstInfo = &(pH264Enc->hMFCH264Handle.videoInstInfo);
+
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+ int i = 0;
+
+ FunctionIn();
+
+ pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
+ pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
+ pVideoEnc->bFirstInput = OMX_TRUE;
+ pVideoEnc->bFirstOutput = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+ eColorFormat = pExynosInputPort->portDefinition.format.video.eColorFormat;
+#ifdef USE_METADATABUFFERTYPE
+ if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
+#ifdef USE_ANDROIDOPAQUE
+ if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque) {
+ pExynosInputPort->bufferProcessType = BUFFER_COPY;
+ } else {
+ pExynosInputPort->bufferProcessType = BUFFER_SHARE;
+ }
+#else
+ pExynosInputPort->bufferProcessType = BUFFER_SHARE;
+#endif
+ } else {
+ pExynosInputPort->bufferProcessType = BUFFER_COPY;
+ }
+#else
+ pExynosInputPort->bufferProcessType = BUFFER_COPY;
+#endif
+
+ 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(pH264Enc, pVideoInstInfo);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
+ pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
+ pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+ hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
+
+ Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+ Exynos_SetPlaneToPort(pExynosOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+
+ Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
+ Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+
+ 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. */
+ }
+
+ pH264Enc->bSourceStart = OMX_FALSE;
+ Exynos_OSAL_SignalCreate(&pH264Enc->hSourceStartEvent);
+ pH264Enc->bDestinationStart = OMX_FALSE;
+ Exynos_OSAL_SignalCreate(&pH264Enc->hDestinationStartEvent);
+
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ OMX_PTR hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
+
+ ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+
+ int i = 0, plane = 0;
+
+ FunctionIn();
+
+ if (pVideoEnc->csc_handle != NULL) {
+ csc_deinit(pVideoEnc->csc_handle);
+ pVideoEnc->csc_handle = NULL;
+ }
+
+ Exynos_OSAL_QueueTerminate(&pH264Enc->bypassBufferInfoQ);
+
+ Exynos_OSAL_SignalTerminate(pH264Enc->hDestinationStartEvent);
+ pH264Enc->hDestinationStartEvent = NULL;
+ pH264Enc->bDestinationStart = OMX_FALSE;
+ Exynos_OSAL_SignalTerminate(pH264Enc->hSourceStartEvent);
+ pH264Enc->hSourceStartEvent = NULL;
+ pH264Enc->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);
+ } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ /*************/
+ /* TBD */
+ /*************/
+ /* Does not require any actions. */
+ }
+
+ if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+ } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ /*************/
+ /* TBD */
+ /*************/
+ /* Does not require any actions. */
+ }
+
+ Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
+ Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
+
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ OMX_U32 oneFrameSize = pSrcInputData->dataLen;
+ OMX_COLOR_FORMATTYPE inputColorFormat = OMX_COLOR_FormatUnused;
+
+ ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+ 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;
+
+ FunctionIn();
+
+ if (pH264Enc->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
+ if ((ret != OMX_ErrorNone) ||
+ ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ goto EXIT;
+ }
+ }
+
+ if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
+ ret = H264CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+ }
+
+ while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+ Change_H264Enc_Param(pExynosComponent);
+ }
+
+ 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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pH264Enc->hMFCH264Handle.indexTimestamp, pSrcInputData->nFlags);
+ pEncOps->Set_FrameTag(hMFCHandle, pH264Enc->hMFCH264Handle.indexTimestamp);
+ pH264Enc->hMFCH264Handle.indexTimestamp++;
+ pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] oneFrameSize: %ld, bufferHeader: 0x%p", pExynosComponent, __FUNCTION__, oneFrameSize, pSrcInputData->bufferHeader);
+
+ inputColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+
+ if ((pVideoEnc->eRotationType == ROTATE_0) ||
+ (pVideoEnc->eRotationType == ROTATE_180)) {
+ Exynos_OSAL_GetPlaneSize(inputColorFormat,
+ pExynosInputPort->ePlaneType,
+ pExynosInputPort->portDefinition.format.video.nFrameWidth,
+ pExynosInputPort->portDefinition.format.video.nFrameHeight,
+ nDataLen,
+ nAllocLen);
+ } else {
+ Exynos_OSAL_GetPlaneSize(inputColorFormat,
+ pExynosInputPort->ePlaneType,
+ pExynosInputPort->portDefinition.format.video.nFrameHeight,
+ pExynosInputPort->portDefinition.format.video.nFrameWidth,
+ nDataLen,
+ nAllocLen);
+ }
+
+ if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
+ tempBufferHeader.nFlags = pSrcInputData->nFlags;
+ tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+ pPrivate = (void *)&tempBufferHeader;
+ } else {
+ pPrivate = (void *)pSrcInputData->bufferHeader;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+ 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->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent);
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+ ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
+ 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->pPrivate = NULL;
+ } else {
+ int plane = 0, nPlaneCnt;
+ nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pSrcOutputData->multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
+
+ pSrcOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+ }
+
+ if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ int i;
+ for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+ if (pSrcOutputData->multiPlaneBuffer.dataBuffer[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, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__);
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountDecrease(pExynosInputPort->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 *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoEncOps *pEncOps = pH264Enc->hMFCH264Handle.pEncOps;
+ 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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+ nAllocLen[0] = pExynosOutputPort->portDefinition.nBufferSize;
+ if (pExynosOutputPort->bStoreMetaData == OMX_TRUE)
+ nAllocLen[0] = ALIGN(pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosOutputPort),
+ pDstInputData->bufferHeader);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
+ 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 *pExynosOutputPort = &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;
+ ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
+ 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, "HW is not available");
+ pVideoBuffer = NULL;
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ } else {
+ pVideoBuffer = NULL;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ pH264Enc->hMFCH264Handle.outputIndexTimestamp++;
+ pH264Enc->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+ pDstOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pDstOutputData->multiPlaneBuffer.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 (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ int i = 0;
+ pDstOutputData->pPrivate = NULL;
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ if (pDstOutputData->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ 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->multiPlaneBuffer.dataBuffer[0] + 4),
+ pDstOutputData->dataLen - 4);
+
+ iSpsSize = PTR_TO_INT((p - (OMX_U8 *)pDstOutputData->multiPlaneBuffer.dataBuffer[0]));
+ pH264Enc->hMFCH264Handle.headerData.pHeaderSPS =
+ (OMX_PTR)pDstOutputData->multiPlaneBuffer.dataBuffer[0];
+ pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize;
+
+ iPpsSize = pDstOutputData->dataLen - iSpsSize;
+ pH264Enc->hMFCH264Handle.headerData.pHeaderPPS =
+ (OMX_U8 *)pDstOutputData->multiPlaneBuffer.dataBuffer[0] + iSpsSize;
+ pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize;
+ }
+
+ 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);
+
+ 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;
+ }
+ }
+ }
+
+ 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 timestamp %lld us (%.2f secs), Tag: %d, frameType: %d dataLen: %d",
+ pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp,
+ pVideoBuffer->frameType, pDstOutputData->dataLen);
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+ (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
+ (pExynosComponent->bBehaviorEOS == OMX_FALSE))) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+ }
+
+ if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
+ (pExynosComponent->bBehaviorEOS == OMX_TRUE))
+ 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_H264ENC_HANDLE *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->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 (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_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 *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 ((pH264Enc->bSourceStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
+ Exynos_OSAL_SignalWait(pH264Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pH264Enc->hSourceStartEvent);
+ }
+
+ ret = Exynos_H264Enc_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 *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 (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
+ }
+
+ if (Exynos_OSAL_GetElemNum(&pH264Enc->bypassBufferInfoQ) > 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] buffer with EOS will be returned by bypassBufferInfoQ",
+ pExynosComponent, __FUNCTION__);
+
+ BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pH264Enc->bypassBufferInfoQ);
+ if (pBufferInfo == NULL) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ 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_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 *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 (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
+ }
+
+ if (Exynos_OSAL_GetElemNum(&pH264Enc->bypassBufferInfoQ) > 0) {
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+ }
+
+ 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->hMFCH264Handle.bTemporalSVC = OMX_FALSE;
+ for (i = 0; i < OMX_VIDEO_ANDROID_MAXAVCTEMPORALLAYERS; 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;
+
+ 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;
+
+#if 0 /* unused code */
+ pVideoEnc->exynos_checkInputFrame = NULL;
+ pVideoEnc->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+
+ pVideoEnc->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
+
+ pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+ if (pVideoEnc->hSharedMemory == NULL) {
+ Exynos_OSAL_Free(pH264Enc);
+ pH264Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->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]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
+ Exynos_OSAL_Free(pH264Enc);
+ pH264Enc = ((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 %d %d %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bRGBSupport),
+ (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.nSpareSize),
+ (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bTemporalSvcSupport),
+ (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bSkypeSupport),
+ (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bRoiInfoSupport),
+ (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.bQpRangePBSupport));
+
+ if (pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.nSpareSize > 0)
+ pVideoEnc->nInbufSpareSize = pH264Enc->hMFCH264Handle.videoInstInfo.specificInfo.enc.nSpareSize;
+
+ Exynos_Input_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_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;
+
+ 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;
+ }
+
+ ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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"
+
+#ifdef USE_SKYPE_HD
+#include "OMX_Video_Extensions.h"
+#endif
+
+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 bLTREnable;
+ 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;
+ EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC TemporalSVC; /* Temporal SVC */
+
+ /* SEC MFC Codec specific */
+ EXYNOS_MFC_H264ENC_HANDLE hMFCH264Handle;
+
+ OMX_BOOL bSourceStart;
+ OMX_BOOL bDestinationStart;
+ OMX_HANDLETYPE hSourceStartEvent;
+ OMX_HANDLETYPE hDestinationStartEvent;
+
+ EXYNOS_QUEUE bypassBufferInfoQ;
+
+ OMX_BOOL bLowLatency;
+ EXYNOS_OMX_HIERARCHICAL_CODING_TYPE eHierarchicalType;
+#ifdef USE_SKYPE_HD
+ OMX_VIDEO_ENCODERPARAMS stEncParam;
+#endif
+ H264_VUI_SAR stSarParam;
+ OMX_S32 nBaseLayerPid;
+} 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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_ENC_ROLE);
+ exynosComponents[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+ FunctionOut();
+
+ return MAX_COMPONENT_NUM;
+}
+
--- /dev/null
+/*
+ *
+ * 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"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_HEVCenc.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.HEVC.Encoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+LOCAL_CFLAGS += -DUSE_HEVC_SUPPORT
+
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_CFLAGS += -DUSE_ANDROID
+endif
+
+ifeq ($(BOARD_USE_METADATABUFFERTYPE), true)
+LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE
+
+ifeq ($(BOARD_USE_ANDROIDOPAQUE), true)
+LOCAL_CFLAGS += -DUSE_ANDROIDOPAQUE
+endif
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_QOS_CTRL), true)
+LOCAL_CFLAGS += -DUSE_QOS_CTRL
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/enc \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+#ifdef USE_ANDROID
+#include "Exynos_OSAL_Android.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;
+
+ FunctionIn();
+
+ 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_100:
+ case MFC_101:
+ pHevcEnc->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel51;
+ break;
+ case MFC_90:
+ case MFC_1010:
+ pHevcEnc->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel5;
+ break;
+ case MFC_1011:
+ case MFC_1020:
+ pHevcEnc->hMFCHevcHandle.maxLevel = OMX_VIDEO_HEVCHighTierLevel41;
+ break;
+ case MFC_92:
+ 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;
+ }
+
+ while ((pHevcEnc->hMFCHevcHandle.maxLevel >> nLevelCnt) > 0) {
+ nLevelCnt++;
+ }
+
+ if ((pHevcEnc->hMFCHevcHandle.nProfileCnt == 0) ||
+ (nLevelCnt == 0)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : there is no any profile/level", __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);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : supported profile(%x), level(%x)", __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, "%s : there is no any profile/level", __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, "%s : profile(%x)/level(%x) is %ssupported", __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_ESSENTIAL, "PadControlOn : %d", pCommonParam->PadControlOn);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LumaPadVal : %d", pCommonParam->LumaPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CbPadVal : %d", pCommonParam->CbPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "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_ESSENTIAL, "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_ESSENTIAL, "LoopFilterDisable : %d", pHEVCParam->LoopFilterDisable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LoopFilterSliceFlag : %d", pHEVCParam->LoopFilterSliceFlag);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LoopFilterTcOffset : %d", pHEVCParam->LoopFilterTcOffset);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LoopFilterBetaOffset : %d", pHEVCParam->LoopFilterBetaOffset);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LongtermRefEnable : %d", pHEVCParam->LongtermRefEnable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LongtermUserRef : %d", pHEVCParam->LongtermUserRef);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LongtermStoreRef : %d", pHEVCParam->LongtermStoreRef);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "DarkDisable : %d", pHEVCParam->DarkDisable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SmoothDisable : %d", pHEVCParam->SmoothDisable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "StaticDisable : %d", pHEVCParam->StaticDisable);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "ActivityDisable : %d", pHEVCParam->ActivityDisable);
+
+ /* 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;
+ 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 = pHevcEnc->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 = 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;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh: %d", pCommonParam->RandomIntraMBRefresh);
+ } else {
+ /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+ pCommonParam->RandomIntraMBRefresh = 0;
+ }
+
+ 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 */
+ pHEVCParam->TemporalSVC.nTemporalLayerCount = (unsigned int)pHevcEnc->TemporalSVC.nTemporalLayerCount;
+ for (i = 0; i < OMX_VIDEO_ANDROID_MAXHEVCTEMPORALLAYERS; i++)
+ pHEVCParam->TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)pHevcEnc->TemporalSVC.nTemporalLayerBitrateRatio[i];
+
+ if (pMFCHevcHandle->bRoiInfo == OMX_TRUE)
+ pHEVCParam->ROIEnable = 1;
+ else
+ pHEVCParam->ROIEnable = 0;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", 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_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;
+
+ 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;
+ }
+ break;
+ case OMX_IndexConfigVideoIntraPeriod:
+ {
+ OMX_S32 nPFrames = (*((OMX_U32 *)pConfigData)) - 1;
+ nValue = nPFrames + 1;
+ pEncOps->Set_IDRPeriod(pMFCHevcHandle->hMFCHandle, 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);
+ }
+ }
+ 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);
+ }
+ }
+ 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);
+ }
+ 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;
+ }
+ break;
+#ifdef USE_QOS_CTRL
+ case OMX_IndexVendorSetQosRatio: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *pQosInfo = (EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *)pConfigData;
+ nValue = pQosInfo->nQosRatio;
+ pEncOps->Set_QosRatio(pMFCHevcHandle->hMFCHandle, nValue);
+ pVideoEnc->bQosChanged = OMX_FALSE;
+ }
+ break;
+#endif
+ case OMX_IndexConfigVideoTemporalSVC:
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pTemporalSVC = (EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *)pConfigData;
+ ExynosVideoQPRange qpRange;
+ int i;
+
+ 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);
+
+ /* Temporal SVC */
+ TemporalLayerShareBuffer TemporalSVC;
+ Exynos_OSAL_Memset(&TemporalSVC, 0, sizeof(TemporalLayerShareBuffer));
+ TemporalSVC.nTemporalLayerCount = (unsigned int)pTemporalSVC->nTemporalLayerCount;
+ for (i = 0; i < OMX_VIDEO_ANDROID_MAXHEVCTEMPORALLAYERS; i++)
+ TemporalSVC.nTemporalLayerBitrateRatio[i] = (unsigned int)pTemporalSVC->nTemporalLayerBitrateRatio[i];
+
+ if (pEncOps->Set_LayerChange(pMFCHevcHandle->hMFCHandle, TemporalSVC) != VIDEO_ERROR_NONE)
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: Not supported control: Set_LayerChange", __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;
+ if (pEncOps->Set_RoiInfo != NULL)
+ pEncOps->Set_RoiInfo(pMFCHevcHandle->hMFCHandle, &RoiInfo);
+ else
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: Not supported control: Set_RoiInfo", __func__);
+ }
+ break;
+ default:
+ break;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nCmdIndex %x nValue %d ", pExynosComponent, __FUNCTION__, (int)nCmdIndex, nValue);
+ Exynos_OSAL_Free(pDynamicConfigCMD);
+
+ Set_HEVCEnc_Param(pExynosComponent);
+
+EXIT:
+ return;
+}
+
+#if 0 /* unused code */
+OMX_ERRORTYPE GetCodecInputPrivateData(
+ OMX_PTR pCodecBuffer,
+ OMX_PTR pVirtAddr[],
+ OMX_U32 nSize[])
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+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_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate encoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps);
+
+ /* 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, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pHevcEnc->hMFCHevcHandle.hMFCHandle = pHevcEnc->hMFCHevcHandle.pEncOps->Init(pVideoInstInfo);
+ if (pHevcEnc->hMFCHevcHandle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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;
+ }
+
+ /* 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoEncBufferOps *pInbufOps = NULL;
+ ExynosVideoEncBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
+ EXYNOS_HEVCENC_HANDLE *pHevcEnc = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ void *hMFCHandle = NULL;
+ ExynosVideoEncBufferOps *pInbufOps = NULL;
+ ExynosVideoEncBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
+ EXYNOS_HEVCENC_HANDLE *pHevcEnc = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ void *hMFCHandle = NULL;
+ ExynosVideoEncBufferOps *pInbufOps = NULL;
+ ExynosVideoEncBufferOps *pOutbufOps = NULL;
+ EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
+ EXYNOS_HEVCENC_HANDLE *pHevcEnc = NULL;
+
+ FunctionIn();
+
+ if (pOMXComponent == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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) {
+ 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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE HEVCCodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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;
+ CODEC_ENC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoEncBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
+ pBufOps = pHevcEnc->hMFCHevcHandle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
+ pBufOps = pHevcEnc->hMFCHevcHandle.pOutbufOps;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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;
+ EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ int i, nOutbufs;
+
+ ExynosVideoEncOps *pEncOps = pHevcEnc->hMFCHevcHandle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pHevcEnc->hMFCHevcHandle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pHevcEnc->hMFCHevcHandle.pOutbufOps;
+
+ 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, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
+
+ 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, "pVideoEnc->pMFCEncOutputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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];
+
+ ExynosVideoEncOps *pEncOps = pHevcEnc->hMFCHevcHandle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pHevcEnc->hMFCHevcHandle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pHevcEnc->hMFCHevcHandle.pOutbufOps;
+ ExynosVideoEncParam *pEncParam = NULL;
+
+ ExynosVideoGeometry bufferConf;
+ OMX_U32 nInputBufferCnt = 0;
+ int i, nOutbufs;
+
+ FunctionIn();
+
+ if ((pSrcInputData->dataLen <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] FBD with EOS will be processed through bypassBufferInfoQ",
+ 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);
+ Exynos_OSAL_SignalSet(pHevcEnc->hDestinationStartEvent); /* awake dstInput thread */
+
+ 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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ }
+ Print_HEVCEnc_Param(pEncParam);
+
+ if ((pMFCHevcHandle->bPrependSpsPpsToIdr == OMX_TRUE) &&
+ (pEncOps->Enable_PrependSpsPpsToIdr)) {
+ if (pEncOps->Enable_PrependSpsPpsToIdr(pHevcEnc->hMFCHevcHandle.hMFCHandle) != VIDEO_ERROR_NONE)
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: Not supported control: Enable_PrependSpsPpsToIdr", __func__);
+ }
+
+ /* 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 = pInputPort->portDefinition.format.video.nFrameWidth;
+ bufferConf.nFrameHeight = pInputPort->portDefinition.format.video.nFrameHeight;
+ bufferConf.nStride = ALIGN(pInputPort->portDefinition.format.video.nFrameWidth, 16);
+ } else {
+ bufferConf.nFrameWidth = pInputPort->portDefinition.format.video.nFrameHeight;
+ bufferConf.nFrameHeight = pInputPort->portDefinition.format.video.nFrameWidth;
+ bufferConf.nStride = ALIGN(pInputPort->portDefinition.format.video.nFrameHeight, 16);
+ }
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+ pInbufOps->Set_Shareable(hMFCHandle);
+ nInputBufferCnt = 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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(hMFCHandle, nInputBufferCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pInputPort->bufferProcessType & BUFFER_SHARE)
+#ifdef USE_METADATABUFFERTYPE
+ && (pInputPort->bStoreMetaData != OMX_TRUE)
+#endif
+ ) {
+ 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 *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoEncOps *pEncOps = pHevcEnc->hMFCHevcHandle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pHevcEnc->hMFCHevcHandle.pInbufOps;
+ 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->bStoreMetaData == OMX_TRUE) {
+ 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_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, "Failed to set geometry for output buffer");
+ 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, "Failed to setup output buffer");
+ 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)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
+ (int *)pVideoEnc->pMFCEncOutputBuffer[i]->fd,
+ pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pOutputPort),
+ NULL);
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ /* Register output buffer */
+ /*************/
+ /* TBD */
+ /*************/
+ }
+
+ pHevcEnc->hMFCHevcHandle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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;
+
+ 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) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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)
+ goto EXIT;
+
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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) {
+ goto EXIT;
+ }
+
+ if (pDstEnableRoiInfo->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pDstEnableRoiInfo->bEnableRoiInfo = pHevcEnc->hMFCHevcHandle.bRoiInfo;
+ }
+ break;
+ 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;
+
+ 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) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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)
+ 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)) {
+ pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC;
+ } else {
+ ret = OMX_ErrorBadParameter;
+ 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)
+ 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)
+ 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)
+ 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;
+ case OMX_IndexParamPrependSPSPPSToIDR:
+ {
+#ifdef USE_ANDROID
+ ret = Exynos_OSAL_SetPrependSPSPPSToIDR(pComponentParameterStructure, &(pHevcEnc->hMFCHevcHandle.bPrependSpsPpsToIdr));
+#else
+ ret = OMX_ErrorNotImplemented;
+#endif
+ }
+ break;
+ 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)
+ goto EXIT;
+
+ if (pSrcEnableTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pHevcEnc->hMFCHevcHandle.videoInstInfo.specificInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) &&
+ (pSrcEnableTemporalSVC->bEnableTemporalSVC == OMX_TRUE)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: MFC D/D doesn't support Temporal SVC", __func__);
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ pHevcEnc->hMFCHevcHandle.bTemporalSVC = pSrcEnableTemporalSVC->bEnableTemporalSVC;
+ if ((pHevcEnc->hMFCHevcHandle.bTemporalSVC == OMX_TRUE) &&
+ (pHevcEnc->TemporalSVC.nTemporalLayerCount == 0)) { /* not initialized yet */
+ pHevcEnc->TemporalSVC.nTemporalLayerCount = 1;
+ pHevcEnc->TemporalSVC.nTemporalLayerBitrateRatio[0] = pPortDef->format.video.nBitrate;
+ } else if (pHevcEnc->hMFCHevcHandle.bTemporalSVC == OMX_FALSE) { /* set default value */
+ pHevcEnc->TemporalSVC.nTemporalLayerCount = 0;
+ for (i = 0; i < OMX_VIDEO_ANDROID_MAXHEVCTEMPORALLAYERS; i++)
+ pHevcEnc->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;
+ OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition);
+ int i;
+
+ ret = Exynos_OMX_Check_SizeVersion(pSrcEnableRoiInfo, sizeof(EXYNOS_OMX_VIDEO_PARAM_ENABLE_ROIINFO));
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ if (pSrcEnableRoiInfo->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pHevcEnc->hMFCHevcHandle.videoInstInfo.specificInfo.enc.bRoiInfoSupport == VIDEO_FALSE) &&
+ (pSrcEnableRoiInfo->bEnableRoiInfo == OMX_TRUE)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: MFC D/D doesn't support Roi Info", __func__);
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+ pHevcEnc->hMFCHevcHandle.bRoiInfo = pSrcEnableRoiInfo->bEnableRoiInfo;
+ }
+ 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;
+
+ FunctionIn();
+
+ if ((hComponent == NULL) ||
+ (pComponentConfigStructure == 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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)
+ 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;
+ EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pSrcTemporalSVC = &pHevcEnc->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)
+ goto EXIT;
+
+ if (pDstTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pSrcTemporalSVC->nKeyFrameInterval = pHevcEnc->nPFrames + 1;
+
+ pSrcTemporalSVC->nMinQuantizer = pHevcEnc->qpRangeI.nMinQP;
+ pSrcTemporalSVC->nMaxQuantizer = pHevcEnc->qpRangeI.nMaxQP;
+
+ Exynos_OSAL_Memcpy(((char *)pDstTemporalSVC) + nOffset,
+ ((char *)pSrcTemporalSVC) + nOffset,
+ sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC) - nOffset);
+ }
+ 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;
+
+ FunctionIn();
+
+ if ((hComponent == NULL) ||
+ (pComponentConfigStructure == 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pHevcEnc = (EXYNOS_HEVCENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] nIndex %x", pExynosComponent, __FUNCTION__, (int)nIndex);
+ switch ((int)nIndex) {
+ case OMX_IndexConfigVideoIntraPeriod:
+ {
+ OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1;
+
+ pHevcEnc->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)
+ 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;
+ case OMX_IndexConfigVideoTemporalSVC:
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC *pDstTemporalSVC = &pHevcEnc->TemporalSVC;
+ 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)
+ goto EXIT;
+
+ if (pSrcTemporalSVC->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pHevcEnc->hMFCHevcHandle.bTemporalSVC == OMX_FALSE) ||
+ (pSrcTemporalSVC->nTemporalLayerCount > OMX_VIDEO_ANDROID_MAXHEVCTEMPORALLAYERS)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pHevcEnc->nPFrames = pSrcTemporalSVC->nKeyFrameInterval - 1;
+
+ pHevcEnc->qpRangeI.nMinQP = pSrcTemporalSVC->nMinQuantizer;
+ pHevcEnc->qpRangeI.nMaxQP = pSrcTemporalSVC->nMaxQuantizer;
+
+ Exynos_OSAL_Memcpy(((char *)pDstTemporalSVC) + nOffset,
+ ((char *)pSrcTemporalSVC) + nOffset,
+ sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC) - nOffset);
+ }
+ 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) ||
+ ((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;
+ }
+ }
+ break;
+ default:
+ ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ if (ret == OMX_ErrorNone) {
+ OMX_PTR pDynamicConfigCMD = NULL;
+ pDynamicConfigCMD = Exynos_OMX_MakeDynamicConfigCMD(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;
+
+ 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 ((cParameterName == NULL) ||
+ (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR) == 0) {
+ *pIndexType = OMX_IndexParamPrependSPSPPSToIDR;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_TEMPORALSVC) == 0) {
+ *pIndexType = OMX_IndexConfigVideoTemporalSVC;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_VIDEO_HEVC_ENABLE_TEMPORALSVC) == 0) {
+ *pIndexType = OMX_IndexParamVideoHevcEnableTemporalSVC;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_ROIINFO) == 0) {
+ *pIndexType = OMX_IndexConfigVideoRoiInfo;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+ if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_VIDEO_ENABLE_ROIINFO) == 0) {
+ *pIndexType = OMX_IndexParamVideoEnableRoiInfo;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ 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;
+
+ 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_ENC_ROLE);
+ ret = OMX_ErrorNone;
+ } else {
+ ret = OMX_ErrorNoMore;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+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_PTR hMFCHandle = NULL;
+ OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
+
+ ExynosVideoEncOps *pEncOps = NULL;
+ ExynosVideoEncBufferOps *pInbufOps = NULL;
+ ExynosVideoEncBufferOps *pOutbufOps = NULL;
+ ExynosVideoInstInfo *pVideoInstInfo = &(pHevcEnc->hMFCHevcHandle.videoInstInfo);
+
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+
+ int i = 0, nPlaneCnt;
+
+ FunctionIn();
+
+ pHevcEnc->hMFCHevcHandle.bConfiguredMFCSrc = OMX_FALSE;
+ pHevcEnc->hMFCHevcHandle.bConfiguredMFCDst = OMX_FALSE;
+ pVideoEnc->bFirstInput = OMX_TRUE;
+ pVideoEnc->bFirstOutput = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+ eColorFormat = pInputPort->portDefinition.format.video.eColorFormat;
+#ifdef USE_METADATABUFFERTYPE
+ if (pInputPort->bStoreMetaData == OMX_TRUE) {
+#ifdef USE_ANDROIDOPAQUE
+ if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)
+ pInputPort->bufferProcessType = BUFFER_COPY;
+ else
+ pInputPort->bufferProcessType = BUFFER_SHARE;
+#else
+ pInputPort->bufferProcessType = BUFFER_COPY;
+#endif
+ } else {
+ pInputPort->bufferProcessType = BUFFER_COPY;
+ }
+#else
+ pInputPort->bufferProcessType = BUFFER_COPY;
+#endif
+
+ 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;
+
+ pEncOps = pHevcEnc->hMFCHevcHandle.pEncOps;
+ pInbufOps = pHevcEnc->hMFCHevcHandle.pInbufOps;
+ pOutbufOps = pHevcEnc->hMFCHevcHandle.pOutbufOps;
+ hMFCHandle = pHevcEnc->hMFCHevcHandle.hMFCHandle;
+
+ 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->hDestinationStartEvent);
+
+ 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;
+
+ int i = 0, plane = 0;
+
+ FunctionIn();
+
+ if (pVideoEnc->csc_handle != NULL) {
+ csc_deinit(pVideoEnc->csc_handle);
+ pVideoEnc->csc_handle = NULL;
+ }
+
+ Exynos_OSAL_QueueTerminate(&pHevcEnc->bypassBufferInfoQ);
+
+ Exynos_OSAL_SignalTerminate(pHevcEnc->hDestinationStartEvent);
+ pHevcEnc->hDestinationStartEvent = 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);
+ } 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);
+
+ 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_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;
+
+ FunctionIn();
+
+ if (pHevcEnc->hMFCHevcHandle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = HEVCCodecSrcSetup(pOMXComponent, pSrcInputData);
+ if ((ret != OMX_ErrorNone) ||
+ ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ goto EXIT;
+ }
+ }
+
+ if (pHevcEnc->hMFCHevcHandle.bConfiguredMFCDst == OMX_FALSE) {
+ ret = HEVCCodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+ }
+
+ while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+ Change_HEVCEnc_Param(pExynosComponent);
+ }
+
+ 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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pHevcEnc->hMFCHevcHandle.indexTimestamp, pSrcInputData->nFlags);
+
+ pEncOps->Set_FrameTag(hMFCHandle, pHevcEnc->hMFCHevcHandle.indexTimestamp);
+ pHevcEnc->hMFCHevcHandle.indexTimestamp++;
+ pHevcEnc->hMFCHevcHandle.indexTimestamp %= MAX_TIMESTAMP;
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] oneFrameSize: %ld, bufferHeader: 0x%p", pExynosComponent, __FUNCTION__, pSrcInputData->dataLen, pSrcInputData->bufferHeader);
+
+ 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->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pHevcEnc->hDestinationStartEvent);
+ 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->pPrivate = NULL;
+ } else {
+ int plane = 0, nPlaneCnt;
+ nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pSrcOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[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, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__);
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#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];
+
+ ExynosVideoEncOps *pEncOps = pHevcEnc->hMFCHevcHandle.pEncOps;
+ 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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ 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->bStoreMetaData == OMX_TRUE)
+ nAllocLen[0] = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth * pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pOutputPort),
+ pDstInputData->bufferHeader);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
+ 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;
+ ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
+ 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, "HW is not available");
+ pVideoBuffer = NULL;
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ } else {
+ pVideoBuffer = NULL;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ pHevcEnc->hMFCHevcHandle.outputIndexTimestamp++;
+ pHevcEnc->hMFCHevcHandle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+ pDstOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pDstOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+ if (pVideoEnc->bFirstOutput == OMX_FALSE) {
+ 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);
+
+ 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;
+ }
+
+ 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 timestamp %lld us (%.2f secs), Tag: %d, frameType: %d dataLen: %d",
+ pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6,
+ indexTimestamp, pVideoBuffer->frameType, pDstOutputData->dataLen);
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+ (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
+ (pExynosComponent->bBehaviorEOS == OMX_FALSE))) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+ }
+
+ if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
+ (pExynosComponent->bBehaviorEOS == OMX_TRUE))
+ 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_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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_SignalReset(pHevcEnc->hSourceStartEvent);
+ }
+
+ ret = Exynos_HEVCEnc_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) &&
+ (pExynosComponent->currentState == OMX_StateExecuting)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pHevcEnc->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+ Exynos_OSAL_SignalWait(pHevcEnc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pHevcEnc->hDestinationStartEvent);
+ }
+
+ if (Exynos_OSAL_GetElemNum(&pHevcEnc->bypassBufferInfoQ) > 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] buffer with EOS will be returned by bypassBufferInfoQ",
+ pExynosComponent, __FUNCTION__);
+
+ BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pHevcEnc->bypassBufferInfoQ);
+ if (pBufferInfo == NULL) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ 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_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 (pOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pHevcEnc->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+ Exynos_OSAL_SignalWait(pHevcEnc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pHevcEnc->hDestinationStartEvent);
+ }
+
+ if (Exynos_OSAL_GetElemNum(&pHevcEnc->bypassBufferInfoQ) > 0) {
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+ 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;
+ 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->nPFrames = 29;
+
+ Exynos_OSAL_Memset(&pHevcEnc->TemporalSVC, 0, sizeof(EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC));
+ INIT_SET_SIZE_VERSION(&pHevcEnc->TemporalSVC, EXYNOS_OMX_VIDEO_CONFIG_TEMPORALSVC);
+ pHevcEnc->TemporalSVC.nKeyFrameInterval = pHevcEnc->nPFrames + 1;
+ pHevcEnc->TemporalSVC.nTemporalLayerCount = 0;
+ pHevcEnc->hMFCHevcHandle.bTemporalSVC = OMX_FALSE;
+ for (i = 0; i < OMX_VIDEO_ANDROID_MAXHEVCTEMPORALLAYERS; i++) {
+ pHevcEnc->TemporalSVC.nTemporalLayerBitrateRatio[i] =
+ pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.nBitrate;
+ }
+ pHevcEnc->TemporalSVC.nMinQuantizer = pHevcEnc->qpRangeI.nMinQP;
+ pHevcEnc->TemporalSVC.nMaxQuantizer = pHevcEnc->qpRangeI.nMaxQP;
+
+ 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;
+
+#if 0 /* unused code */
+ pVideoEnc->exynos_checkInputFrame = NULL;
+ pVideoEnc->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+
+ pVideoEnc->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
+
+ pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+ if (pVideoEnc->hSharedMemory == NULL) {
+ Exynos_OSAL_Free(pHevcEnc);
+ pHevcEnc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->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]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
+ Exynos_OSAL_Free(pHevcEnc);
+ pHevcEnc = ((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 %d %d %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pHevcEnc->hMFCHevcHandle.videoInstInfo.specificInfo.enc.bRGBSupport),
+ (pHevcEnc->hMFCHevcHandle.videoInstInfo.specificInfo.enc.nSpareSize),
+ (pHevcEnc->hMFCHevcHandle.videoInstInfo.specificInfo.enc.bTemporalSvcSupport),
+ (pHevcEnc->hMFCHevcHandle.videoInstInfo.specificInfo.enc.bSkypeSupport),
+ (pHevcEnc->hMFCHevcHandle.videoInstInfo.specificInfo.enc.bRoiInfoSupport),
+ (pHevcEnc->hMFCHevcHandle.videoInstInfo.specificInfo.enc.bQpRangePBSupport));
+
+ if (pHevcEnc->hMFCHevcHandle.videoInstInfo.specificInfo.enc.nSpareSize > 0)
+ pVideoEnc->nInbufSpareSize = pHevcEnc->hMFCHevcHandle.videoInstInfo.specificInfo.enc.nSpareSize;
+
+ Exynos_Input_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_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;
+
+ 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;
+ }
+
+ ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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;
+
+ ExynosVideoEncOps *pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps;
+ ExynosVideoEncParam encParam;
+ ExynosVideoInstInfo videoInstInfo;
+
+ #define MAX_PROFILE_NUM 1
+ 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_U32 nPFrames; /* IDR period control */
+ 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_HEVCENC_HANDLE hMFCHevcHandle;
+
+ OMX_BOOL bSourceStart;
+ OMX_BOOL bDestinationStart;
+ OMX_HANDLETYPE hSourceStartEvent;
+ OMX_HANDLETYPE hDestinationStartEvent;
+
+ 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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_ENC_ROLE);
+ exynosComponents[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM;
+
+EXIT:
+ FunctionOut();
+
+ return MAX_COMPONENT_NUM;
+}
+
--- /dev/null
+/*
+ *
+ * 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"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OSCL_EXPORT_REF int Exynos_OMX_COMPONENT_Library_Register(ExynosRegisterComponentType **exynosComponents);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Mpeg4enc.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.MPEG4.Encoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+
+ifeq ($(BOARD_USE_METADATABUFFERTYPE), true)
+LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE
+
+ifeq ($(BOARD_USE_ANDROIDOPAQUE), true)
+LOCAL_CFLAGS += -DUSE_ANDROIDOPAQUE
+endif
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_QOS_CTRL), true)
+LOCAL_CFLAGS += -DUSE_QOS_CTRL
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/enc \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+/* 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;
+
+ FunctionIn();
+
+ 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;
+ }
+
+ while ((pMpeg4Enc->hMFCMpeg4Handle.maxLevel >> nLevelCnt) > 0) {
+ nLevelCnt++;
+ }
+
+ if ((pMpeg4Enc->hMFCMpeg4Handle.nProfileCnt == 0) ||
+ (nLevelCnt == 0)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : there is no any profile/level", __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);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : supported profile(%x), level(%x)", __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, "%s : there is no any profile/level", __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, "%s : profile(%x)/level(%x) is %ssupported", __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_ESSENTIAL, "PadControlOn : %d", pCommonParam->PadControlOn);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LumaPadVal : %d", pCommonParam->LumaPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CbPadVal : %d", pCommonParam->CbPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "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_ESSENTIAL, "TimeIncreamentRes : %d", pMpeg4Param->TimeIncreamentRes);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "VopTimeIncreament : %d", pMpeg4Param->VopTimeIncreament);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "SliceArgument : %d", pMpeg4Param->SliceArgument);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "NumberBFrames : %d", pMpeg4Param->NumberBFrames);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "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_ESSENTIAL, "PadControlOn : %d", pCommonParam->PadControlOn);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LumaPadVal : %d", pCommonParam->LumaPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CbPadVal : %d", pCommonParam->CbPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "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 *pExynosInputPort = NULL;
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = 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;
+ pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ pEncParam = &pMFCMpeg4Handle->encParam;
+ pCommonParam = &pEncParam->commonParam;
+ pMpeg4Param = &pEncParam->codecParam.mpeg4;
+ pEncParam->eCompressionFormat = VIDEO_CODING_MPEG4;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "eCompressionFormat: %d", pEncParam->eCompressionFormat);
+
+ /* common parameters */
+ if ((pVideoEnc->eRotationType == ROTATE_0) ||
+ (pVideoEnc->eRotationType == ROTATE_180)) {
+ pCommonParam->SourceWidth = pExynosOutputPort->portDefinition.format.video.nFrameWidth;
+ pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameHeight;
+ } else {
+ pCommonParam->SourceWidth = pExynosOutputPort->portDefinition.format.video.nFrameHeight;
+ pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameWidth;
+ }
+ pCommonParam->IDRPeriod = pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1;
+ pCommonParam->SliceMode = 0;
+ pCommonParam->Bitrate = pExynosOutputPort->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;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh: %d", pCommonParam->RandomIntraMBRefresh);
+ } else {
+ /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+ pCommonParam->RandomIntraMBRefresh = 0;
+ }
+
+ eColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+ pCommonParam->FrameMap = Exynos_OSAL_OMX2VideoFormat(eColorFormat, pExynosInputPort->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 = (pExynosInputPort->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_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", 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_Mpeg4Enc_Param(pEncParam);
+}
+
+static void Set_H263Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
+{
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = NULL;
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = 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;
+ pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ pExynosOutputPort = &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 = pExynosOutputPort->portDefinition.format.video.nFrameWidth;
+ pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameHeight;
+ } else {
+ pCommonParam->SourceWidth = pExynosOutputPort->portDefinition.format.video.nFrameHeight;
+ pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameWidth;
+ }
+ pCommonParam->IDRPeriod = pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1;
+ pCommonParam->SliceMode = 0;
+ pCommonParam->Bitrate = pExynosOutputPort->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;
+ }
+
+ eColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+ pCommonParam->FrameMap = Exynos_OSAL_OMX2VideoFormat(eColorFormat, pExynosInputPort->ePlaneType);
+
+ /* H263 specific parameters */
+ pH263Param->FrameRate = (pExynosInputPort->portDefinition.format.video.xFramerate) >> 16;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", 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 (nCmdIndex) {
+ case OMX_IndexConfigVideoIntraVOPRefresh:
+ {
+ nValue = VIDEO_FRAME_I;
+ pEncOps->Set_FrameType(pMFCMpeg4Handle->hMFCHandle, nValue);
+ pVideoEnc->IntraRefreshVOP = OMX_FALSE;
+ }
+ break;
+ case OMX_IndexConfigVideoIntraPeriod:
+ {
+ OMX_S32 nPFrames = (*((OMX_U32 *)pConfigData)) - 1;
+ nValue = nPFrames + 1;
+ pEncOps->Set_IDRPeriod(pMFCMpeg4Handle->hMFCHandle, 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);
+ }
+ }
+ 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);
+ }
+ }
+ 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);
+ }
+ 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;
+ }
+ break;
+#ifdef USE_QOS_CTRL
+ case OMX_IndexVendorSetQosRatio: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *pQosInfo = (EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *)pConfigData;
+ nValue = pQosInfo->nQosRatio;
+ pEncOps->Set_QosRatio(pMFCMpeg4Handle->hMFCHandle, nValue);
+ pVideoEnc->bQosChanged = OMX_FALSE;
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nCmdIndex %x nValue %d ", pExynosComponent, __FUNCTION__, (int)nCmdIndex, nValue);
+ Exynos_OSAL_Free(pDynamicConfigCMD);
+
+ if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
+ Set_Mpeg4Enc_Param(pExynosComponent);
+ else
+ Set_H263Enc_Param(pExynosComponent);
+
+EXIT:
+ return;
+}
+
+#if 0 /* unused code */
+OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ ExynosVideoBuffer *pCodecBuffer;
+
+ if (codecBuffer == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
+
+ if (pVirtAddr != NULL)
+ *pVirtAddr = pCodecBuffer->planes[0].addr;
+
+ if (dataSize != NULL)
+ *dataSize = pCodecBuffer->planes[0].allocSize;
+
+ pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
+
+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_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate encoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps);
+
+ /* 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, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.pEncOps->Init(pVideoInstInfo);
+ if (pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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;
+ }
+
+ /* 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoEncOps *pEncOps = 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+ 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoEncOps *pEncOps = 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+ 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;
+ void *hMFCHandle = NULL;
+ ExynosVideoEncOps *pEncOps = 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+ pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+ pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+
+ 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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Mpeg4CodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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;
+ CODEC_ENC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoEncBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
+ pBufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
+ pBufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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 *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ void *hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ int i, nOutbufs;
+
+ ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+
+ 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, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
+
+ 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, "pVideoEnc->pMFCEncOutputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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 *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle;
+ void *hMFCHandle = pMFCMpeg4Handle->hMFCHandle;
+ EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ OMX_U32 oneFrameSize = pSrcInputData->dataLen;
+
+ ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+ ExynosVideoEncParam *pEncParam = NULL;
+
+ ExynosVideoGeometry bufferConf;
+ OMX_U32 inputBufferNumber = 0;
+ int i, nOutbufs;
+
+ FunctionIn();
+
+ if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] FBD with EOS will be processed through bypassBufferInfoQ",
+ 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);
+ Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationStartEvent); /* awake dstInput thread */
+
+ 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, "Failed to set geometry for input buffer");
+ 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 = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+ bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+ bufferConf.nStride = ALIGN(pExynosInputPort->portDefinition.format.video.nFrameWidth, 16);
+ } else {
+ bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+ bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+ bufferConf.nStride = ALIGN(pExynosInputPort->portDefinition.format.video.nFrameHeight, 16);
+ }
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+ pInbufOps->Set_Shareable(hMFCHandle);
+ inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
+
+ if (pExynosInputPort->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(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pExynosInputPort->bufferProcessType & BUFFER_SHARE)
+#ifdef USE_METADATABUFFERTYPE
+ && (pExynosInputPort->bStoreMetaData != OMX_TRUE)
+#endif
+ ) {
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+ 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, nOutbufs;
+
+ FunctionIn();
+
+ int nOutBufSize = pExynosOutputPort->portDefinition.nBufferSize;
+ if (pExynosOutputPort->bStoreMetaData == OMX_TRUE) {
+ nOutBufSize = ALIGN(pExynosOutputPort->portDefinition.format.video.nFrameWidth *
+ pExynosOutputPort->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(pExynosOutputPort);
+
+ if (pOutbufOps->Set_Geometry(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ }
+
+ /* should be done before prepare output buffer */
+ if (pOutbufOps->Enable_Cacheable) {
+ if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ }
+
+ if (pOutbufOps->Set_Shareable) {
+ pOutbufOps->Set_Shareable(hMFCHandle);
+ }
+ int SetupBufferNumber = 0;
+ if (pExynosOutputPort->bufferProcessType & BUFFER_COPY)
+ SetupBufferNumber = MFC_OUTPUT_BUFFER_NUM_MAX;
+ else
+ SetupBufferNumber = pExynosOutputPort->portDefinition.nBufferCountActual;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SetupBufferNumber:%d", SetupBufferNumber);
+
+ if (pOutbufOps->Setup(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, SetupBufferNumber) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ nAllocLen[0] = nOutBufSize;
+ ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, MFC_OUTPUT_BUFFER_NUM_MAX, nAllocLen);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
+ (int *)pVideoEnc->pMFCEncOutputBuffer[i]->fd,
+ pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosOutputPort),
+ NULL);
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ /* Register output buffer */
+ /*************/
+ /* TBD */
+ /*************/
+ }
+ pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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)
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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)
+ 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) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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)
+ 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)
+ 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_ErrorBadParameter;
+ 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)
+ 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) {
+ 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)
+ 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) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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;
+ 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_MakeDynamicConfigCMD(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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ 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;
+}
+
+/* MFC Init */
+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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)pVideoEnc->hCodecHandle;;
+ EXYNOS_MFC_MPEG4ENC_HANDLE *pMFCMpeg4Handle = &pMpeg4Enc->hMFCMpeg4Handle;
+ OMX_PTR hMFCHandle = NULL;
+ OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
+
+ ExynosVideoEncOps *pEncOps = NULL;
+ ExynosVideoEncBufferOps *pInbufOps = NULL;
+ ExynosVideoEncBufferOps *pOutbufOps = NULL;
+ ExynosVideoInstInfo *pVideoInstInfo = &(pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo);
+
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+ int i = 0, nPlaneCnt;
+
+ FunctionIn();
+
+ pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE;
+ pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE;
+ pVideoEnc->bFirstInput = OMX_TRUE;
+ pVideoEnc->bFirstOutput = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+ eColorFormat = pExynosInputPort->portDefinition.format.video.eColorFormat;
+#ifdef USE_METADATABUFFERTYPE
+ if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
+#ifdef USE_ANDROIDOPAQUE
+ if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque) {
+ pExynosInputPort->bufferProcessType = BUFFER_COPY;
+ } else {
+ pExynosInputPort->bufferProcessType = BUFFER_SHARE;
+ }
+#else
+ pExynosInputPort->bufferProcessType = BUFFER_SHARE;
+#endif
+ } else {
+ pExynosInputPort->bufferProcessType = BUFFER_COPY;
+ }
+#else
+ pExynosInputPort->bufferProcessType = BUFFER_COPY;
+#endif
+
+ 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/H.263 Codec Open */
+ ret = Mpeg4CodecOpen(pMpeg4Enc, pVideoInstInfo);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+ pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+ pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+ hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
+
+ Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
+ Exynos_SetPlaneToPort(pExynosOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
+
+ Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
+ Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
+
+ 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. */
+ }
+
+ pMpeg4Enc->bSourceStart = OMX_FALSE;
+ Exynos_OSAL_SignalCreate(&pMpeg4Enc->hSourceStartEvent);
+ pMpeg4Enc->bDestinationStart = OMX_FALSE;
+ Exynos_OSAL_SignalCreate(&pMpeg4Enc->hDestinationStartEvent);
+
+ 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_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ EXYNOS_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ OMX_PTR hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
+
+ ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+
+ int i = 0, plane = 0;
+
+ FunctionIn();
+
+ if (pVideoEnc->csc_handle != NULL) {
+ csc_deinit(pVideoEnc->csc_handle);
+ pVideoEnc->csc_handle = NULL;
+ }
+
+ Exynos_OSAL_QueueTerminate(&pMpeg4Enc->bypassBufferInfoQ);
+
+ Exynos_OSAL_SignalTerminate(pMpeg4Enc->hDestinationStartEvent);
+ pMpeg4Enc->hDestinationStartEvent = NULL;
+ pMpeg4Enc->bDestinationStart = OMX_FALSE;
+ Exynos_OSAL_SignalTerminate(pMpeg4Enc->hSourceStartEvent);
+ pMpeg4Enc->hSourceStartEvent = NULL;
+ pMpeg4Enc->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);
+ } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ /*************/
+ /* TBD */
+ /*************/
+ /* Does not require any actions. */
+ }
+
+ if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
+ } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
+ /*************/
+ /* TBD */
+ /*************/
+ /* Does not require any actions. */
+ }
+
+ Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
+ Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
+
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ OMX_U32 oneFrameSize = pSrcInputData->dataLen;
+ OMX_COLOR_FORMATTYPE inputColorFormat = OMX_COLOR_FormatUnused;
+
+ ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+ 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;
+
+ FunctionIn();
+
+ if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = Mpeg4CodecSrcSetup(pOMXComponent, pSrcInputData);
+ if ((ret != OMX_ErrorNone) ||
+ ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ goto EXIT;
+ }
+ }
+
+ if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE) {
+ ret = Mpeg4CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+ }
+
+ while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+ Change_Mpeg4Enc_Param(pExynosComponent);
+ }
+
+ 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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp, pSrcInputData->nFlags);
+ pEncOps->Set_FrameTag(hMFCHandle, pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp);
+ pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++;
+ pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP;
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
+#endif
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] oneFrameSize: %ld, bufferHeader: 0x%p", pExynosComponent, __FUNCTION__, oneFrameSize, pSrcInputData->bufferHeader);
+
+ inputColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+ if ((pVideoEnc->eRotationType == ROTATE_0) ||
+ (pVideoEnc->eRotationType == ROTATE_180)) {
+ Exynos_OSAL_GetPlaneSize(inputColorFormat,
+ pExynosInputPort->ePlaneType,
+ pExynosInputPort->portDefinition.format.video.nFrameWidth,
+ pExynosInputPort->portDefinition.format.video.nFrameHeight,
+ nDataLen,
+ nAllocLen);
+ } else {
+ Exynos_OSAL_GetPlaneSize(inputColorFormat,
+ pExynosInputPort->ePlaneType,
+ pExynosInputPort->portDefinition.format.video.nFrameHeight,
+ pExynosInputPort->portDefinition.format.video.nFrameWidth,
+ nDataLen,
+ nAllocLen);
+ }
+
+ if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
+ tempBufferHeader.nFlags = pSrcInputData->nFlags;
+ tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+ pPrivate = (void *)&tempBufferHeader;
+ } else {
+ pPrivate = (void *)pSrcInputData->bufferHeader;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+ 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->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationStartEvent);
+ 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 *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+
+ ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+ 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->pPrivate = NULL;
+ } else {
+ int plane = 0, nPlaneCnt;
+ nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pSrcOutputData->multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
+
+ pSrcOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
+ }
+
+ if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+ int i;
+ for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+ if (pSrcOutputData->multiPlaneBuffer.dataBuffer[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, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__);
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountDecrease(pExynosInputPort->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 *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoEncOps *pEncOps = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
+ 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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+#ifdef PERFORMANCE_DEBUG
+ Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
+#endif
+
+ nAllocLen[0] = pExynosOutputPort->portDefinition.nBufferSize;
+ if (pExynosOutputPort->bStoreMetaData == OMX_TRUE)
+ nAllocLen[0] = ALIGN(pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pExynosOutputPort),
+ pDstInputData->bufferHeader);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
+ 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 *pExynosOutputPort = &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;
+ ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
+ ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
+
+ OMX_S32 indexTimestamp = 0;
+
+ 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, "HW is not available");
+ pVideoBuffer = NULL;
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ } else {
+ pVideoBuffer = NULL;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp++;
+ pMpeg4Enc->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+ pDstOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pDstOutputData->multiPlaneBuffer.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 (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ int i = 0;
+ pDstOutputData->pPrivate = NULL;
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ if (pDstOutputData->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+ if (pVideoEnc->bFirstOutput == OMX_FALSE) {
+ OMX_U8 *p = NULL;
+
+ /* start header return */
+ 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);
+
+ 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;
+ }
+ }
+ }
+
+ 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 timestamp %lld us (%.2f secs), Tag: %d, frameType: %d dataLen: %d",
+ pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp,
+ pVideoBuffer->frameType, pDstOutputData->dataLen);
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+ (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
+ (pExynosComponent->bBehaviorEOS == OMX_FALSE))) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+ }
+
+ if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
+ (pExynosComponent->bBehaviorEOS == OMX_TRUE))
+ 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_MPEG4ENC_HANDLE *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->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 (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_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 *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 ((pMpeg4Enc->bSourceStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
+ Exynos_OSAL_SignalWait(pMpeg4Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pMpeg4Enc->hSourceStartEvent);
+ }
+
+ ret = Exynos_Mpeg4Enc_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 *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 (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pMpeg4Enc->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pMpeg4Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pMpeg4Enc->hDestinationStartEvent);
+ }
+
+ if (Exynos_OSAL_GetElemNum(&pMpeg4Enc->bypassBufferInfoQ) > 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] buffer with EOS will be returned by bypassBufferInfoQ",
+ pExynosComponent, __FUNCTION__);
+
+ BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pMpeg4Enc->bypassBufferInfoQ);
+ if (pBufferInfo == NULL) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ 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_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 *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 (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pMpeg4Enc->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
+ Exynos_OSAL_SignalWait(pMpeg4Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pMpeg4Enc->hDestinationStartEvent);
+ }
+
+ if (Exynos_OSAL_GetElemNum(&pMpeg4Enc->bypassBufferInfoQ) > 0) {
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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: parameters are null, ret: %X", __FUNCTION__, ret);
+ 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: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_VideoDecodeComponentInit error, ret: %X", __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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret);
+ 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: EXYNOS_MPEG4ENC_HANDLE alloc error, ret: %X", __FUNCTION__, ret);
+ 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;
+
+#if 0 /* unused code */
+ pVideoEnc->exynos_checkInputFrame = NULL;
+ pVideoEnc->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+
+ pVideoEnc->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
+
+ pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+ if (pVideoEnc->hSharedMemory == NULL) {
+ Exynos_OSAL_Free(pMpeg4Enc);
+ pMpeg4Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->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]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
+ Exynos_OSAL_Free(pMpeg4Enc);
+ pMpeg4Enc = ((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 %d %d %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.specificInfo.enc.bRGBSupport),
+ (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.specificInfo.enc.nSpareSize),
+ (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.specificInfo.enc.bTemporalSvcSupport),
+ (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.specificInfo.enc.bSkypeSupport),
+ (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.specificInfo.enc.bRoiInfoSupport),
+ (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.specificInfo.enc.bQpRangePBSupport));
+
+ if (pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.specificInfo.enc.nSpareSize > 0)
+ pVideoEnc->nInbufSpareSize = pMpeg4Enc->hMFCMpeg4Handle.videoInstInfo.specificInfo.enc.nSpareSize;
+
+ Exynos_Input_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_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;
+
+ Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
+
+ Exynos_OSAL_Free(pExynosComponent->componentName);
+ pExynosComponent->componentName = NULL;
+
+ pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+ if (pMpeg4Enc != NULL) {
+ Exynos_OSAL_Free(pMpeg4Enc);
+ pMpeg4Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
+ }
+
+ ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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 hDestinationStartEvent;
+
+ 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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;
+}
--- /dev/null
+/*
+ *
+ * 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
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Vp8enc.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.VP8.Encoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS :=
+LOCAL_CFLAGS += -DUSE_VP8_SUPPORT
+
+ifeq ($(BOARD_USE_METADATABUFFERTYPE), true)
+LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE
+
+ifeq ($(BOARD_USE_ANDROIDOPAQUE), true)
+LOCAL_CFLAGS += -DUSE_ANDROIDOPAQUE
+endif
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_QOS_CTRL), true)
+LOCAL_CFLAGS += -DUSE_QOS_CTRL
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/enc \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+/* 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;
+
+ FunctionIn();
+
+ 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;
+ }
+
+ while ((pVp8Enc->hMFCVp8Handle.maxLevel >> nLevelCnt) > 0) {
+ nLevelCnt++;
+ }
+
+ if ((pVp8Enc->hMFCVp8Handle.nProfileCnt == 0) ||
+ (nLevelCnt == 0)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : there is no any profile/level", __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);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : supported profile(%x), level(%x)", __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, "%s : there is no any profile/level", __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, "%s : profile(%x)/level(%x) is %ssupported", __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_ESSENTIAL, "PadControlOn : %d", pCommonParam->PadControlOn);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LumaPadVal : %d", pCommonParam->LumaPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CbPadVal : %d", pCommonParam->CbPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "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_ESSENTIAL, "Vp8NumberOfPartitions : %d", pVp8Param->Vp8NumberOfPartitions);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Vp8FilterLevel : %d", pVp8Param->Vp8FilterLevel);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Vp8FilterSharpness : %d", pVp8Param->Vp8FilterSharpness);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Vp8GoldenFrameSel : %d", pVp8Param->Vp8GoldenFrameSel);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Vp8GFRefreshPeriod : %d", pVp8Param->Vp8GFRefreshPeriod);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "RefNumberForPFrame : %d", pVp8Param->RefNumberForPFrame);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "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;
+ 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 = 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;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh: %d", pCommonParam->RandomIntraMBRefresh);
+ } else {
+ /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+ pCommonParam->RandomIntraMBRefresh = 0;
+ }
+
+ 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_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", 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;
+
+ 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 (nCmdIndex) {
+ case OMX_IndexConfigVideoIntraVOPRefresh:
+ {
+ nValue = VIDEO_FRAME_I;
+ pEncOps->Set_FrameType(pMFCVp8Handle->hMFCHandle, nValue);
+ pVideoEnc->IntraRefreshVOP = OMX_FALSE;
+ }
+ break;
+ case OMX_IndexConfigVideoIntraPeriod:
+ {
+ OMX_S32 nPFrames = (*((OMX_U32 *)pConfigData)) - 1;
+ nValue = nPFrames + 1;
+ pEncOps->Set_IDRPeriod(pMFCVp8Handle->hMFCHandle, nValue);
+ }
+ break;
+ case OMX_IndexConfigVideoBitrate:
+ {
+ OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pConfigData;
+ int i;
+
+ if (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] != OMX_Video_ControlRateDisable) {
+ /* bitrate : main */
+ nValue = pConfigBitrate->nEncodeBitrate;
+ pEncOps->Set_BitRate(pMFCVp8Handle->hMFCHandle, 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);
+ }
+ }
+ 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;
+
+ pEncOps->Set_QpRange(pMFCVp8Handle->hMFCHandle, qpRange);
+ }
+ 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;
+ }
+ break;
+#ifdef USE_QOS_CTRL
+ case OMX_IndexVendorSetQosRatio: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *pQosInfo = (EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *)pConfigData;
+ nValue = pQosInfo->nQosRatio;
+ pEncOps->Set_QosRatio(pMFCVp8Handle->hMFCHandle, nValue);
+ pVideoEnc->bQosChanged = OMX_FALSE;
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nCmdIndex %x nValue %d ", pExynosComponent, __FUNCTION__, (int)nCmdIndex, nValue);
+ Exynos_OSAL_Free(pDynamicConfigCMD);
+
+ Set_VP8Enc_Param(pExynosComponent);
+
+EXIT:
+ return;
+}
+
+#if 0 /* unused code */
+OMX_ERRORTYPE GetCodecInputPrivateData(
+ OMX_PTR pCodecBuffer,
+ OMX_PTR pVirtAddr[],
+ OMX_U32 nSize[])
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+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_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate encoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps);
+
+ /* 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, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pVp8Enc->hMFCVp8Handle.hMFCHandle = pVp8Enc->hMFCVp8Handle.pEncOps->Init(pVideoInstInfo);
+ if (pVp8Enc->hMFCVp8Handle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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;
+ }
+
+ /* 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;
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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) {
+ 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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE VP8CodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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;
+ CODEC_ENC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoEncBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
+ pBufOps = pVp8Enc->hMFCVp8Handle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
+ pBufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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;
+ EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ int i, nOutbufs;
+
+ ExynosVideoEncOps *pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps;
+ 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, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
+
+ 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, "pVideoEnc->pMFCEncOutputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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];
+
+ ExynosVideoEncOps *pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps;
+ ExynosVideoEncParam *pEncParam = NULL;
+
+ ExynosVideoGeometry bufferConf;
+ OMX_U32 nInputBufferCnt = 0;
+ int i, nOutbufs;
+
+ FunctionIn();
+
+ if ((pSrcInputData->dataLen <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] FBD with EOS will be processed through bypassBufferInfoQ",
+ 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);
+ Exynos_OSAL_SignalSet(pVp8Enc->hDestinationStartEvent); /* awake dstInput thread */
+
+ 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 = pInputPort->portDefinition.format.video.nFrameWidth;
+ bufferConf.nFrameHeight = pInputPort->portDefinition.format.video.nFrameHeight;
+ bufferConf.nStride = ALIGN(pInputPort->portDefinition.format.video.nFrameWidth, 16);
+ } else {
+ bufferConf.nFrameWidth = pInputPort->portDefinition.format.video.nFrameHeight;
+ bufferConf.nFrameHeight = pInputPort->portDefinition.format.video.nFrameWidth;
+ bufferConf.nStride = ALIGN(pInputPort->portDefinition.format.video.nFrameHeight, 16);
+ }
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+ pInbufOps->Set_Shareable(hMFCHandle);
+ nInputBufferCnt = 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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(hMFCHandle, nInputBufferCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pInputPort->bufferProcessType & BUFFER_SHARE)
+#ifdef USE_METADATABUFFERTYPE
+ && (pInputPort->bStoreMetaData != OMX_TRUE)
+#endif
+ ) {
+ 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 *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoEncOps *pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps;
+ 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->bStoreMetaData == OMX_TRUE) {
+ 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, "Failed to set geometry for output buffer");
+ 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, "Failed to setup output buffer");
+ 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)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
+ (int *)pVideoEnc->pMFCEncOutputBuffer[i]->fd,
+ pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pOutputPort),
+ NULL);
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ /* Register output buffer */
+ /*************/
+ /* TBD */
+ /*************/
+ }
+
+ pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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;
+ 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)
+ 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;
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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_ErrorBadParameter;
+ 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)
+ 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)
+ 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) {
+ 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, "%s[%x] xFramerate is changed to invalid value(%d)",
+ __FUNCTION__, OMX_IndexParamVideoPortFormat, 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) {
+ 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_WARNING, "%s[%x] xFramerate is changed to invalid value(%d)",
+ __FUNCTION__, OMX_IndexParamPortDefinition, pPortDef->format.video.xFramerate >> 16);
+ }
+
+ 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, "pExynosOutputPort->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;
+ 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.specificInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) &&
+ (pSrcVp8EncoderType->eTemporalPattern != OMX_VIDEO_VPXTemporalLayerPatternNone)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: MFC D/D doesn't support Temporal SVC", __FUNCTION__);
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ if ((pSrcVp8EncoderType->nMinQuantizer > pSrcVp8EncoderType->nMaxQuantizer) ||
+ (pSrcVp8EncoderType->nMaxQuantizer >= VP8_QP_INDEX_RANGE)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: QP value is invalid(min:%d, max:%d)", __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;
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pVp8Enc = (EXYNOS_VP8ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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;
+ default:
+ ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ if (ret == OMX_ErrorNone) {
+ OMX_PTR pDynamicConfigCMD = NULL;
+ pDynamicConfigCMD = Exynos_OMX_MakeDynamicConfigCMD(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) {
+ 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 ((cParameterName == NULL) ||
+ (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ 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_PTR hMFCHandle = NULL;
+ OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
+
+ ExynosVideoEncOps *pEncOps = NULL;
+ ExynosVideoEncBufferOps *pInbufOps = NULL;
+ ExynosVideoEncBufferOps *pOutbufOps = NULL;
+ ExynosVideoInstInfo *pVideoInstInfo = &(pVp8Enc->hMFCVp8Handle.videoInstInfo);
+
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+
+ int i = 0, nPlaneCnt;
+
+ FunctionIn();
+
+ pVp8Enc->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE;
+ pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE;
+ pVideoEnc->bFirstInput = OMX_TRUE;
+ pVideoEnc->bFirstOutput = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+ eColorFormat = pInputPort->portDefinition.format.video.eColorFormat;
+#ifdef USE_METADATABUFFERTYPE
+ if (pInputPort->bStoreMetaData == OMX_TRUE) {
+#ifdef USE_ANDROIDOPAQUE
+ if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)
+ pInputPort->bufferProcessType = BUFFER_COPY;
+ else
+ pInputPort->bufferProcessType = BUFFER_SHARE;
+#else
+ pInputPort->bufferProcessType = BUFFER_COPY;
+#endif
+ } else {
+ pInputPort->bufferProcessType = BUFFER_COPY;
+ }
+#else
+ pInputPort->bufferProcessType = BUFFER_COPY;
+#endif
+
+ 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;
+
+ pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps;
+ pInbufOps = pVp8Enc->hMFCVp8Handle.pInbufOps;
+ pOutbufOps = pVp8Enc->hMFCVp8Handle.pOutbufOps;
+ hMFCHandle = pVp8Enc->hMFCVp8Handle.hMFCHandle;
+
+ 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->hDestinationStartEvent);
+
+ 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;
+
+ int i = 0, plane = 0;
+
+ FunctionIn();
+
+ if (pVideoEnc->csc_handle != NULL) {
+ csc_deinit(pVideoEnc->csc_handle);
+ pVideoEnc->csc_handle = NULL;
+ }
+
+ Exynos_OSAL_QueueTerminate(&pVp8Enc->bypassBufferInfoQ);
+
+ Exynos_OSAL_SignalTerminate(pVp8Enc->hDestinationStartEvent);
+ pVp8Enc->hDestinationStartEvent = 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);
+ } 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);
+
+ 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;
+
+ FunctionIn();
+
+ if (pVp8Enc->hMFCVp8Handle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = VP8CodecSrcSetup(pOMXComponent, pSrcInputData);
+ if ((ret != OMX_ErrorNone) ||
+ ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+ goto EXIT;
+ }
+ }
+
+ if (pVp8Enc->hMFCVp8Handle.bConfiguredMFCDst == OMX_FALSE) {
+ ret = VP8CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+ }
+
+ while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+ Change_VP8Enc_Param(pExynosComponent);
+ }
+
+ 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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pVp8Enc->hMFCVp8Handle.indexTimestamp, pSrcInputData->nFlags);
+
+ 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
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] oneFrameSize: %ld, bufferHeader: 0x%p", pExynosComponent, __FUNCTION__, pSrcInputData->dataLen, pSrcInputData->bufferHeader);
+
+ 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->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pVp8Enc->hDestinationStartEvent);
+ 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->pPrivate = NULL;
+ } else {
+ int plane = 0, nPlaneCnt;
+ nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pSrcOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[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, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__);
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#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];
+
+ ExynosVideoEncOps *pEncOps = pVp8Enc->hMFCVp8Handle.pEncOps;
+ 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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ 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->bStoreMetaData == OMX_TRUE)
+ nAllocLen[0] = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth * pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)&pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pOutputPort),
+ pDstInputData->bufferHeader);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
+ 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;
+ ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
+ 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, "HW is not available");
+ pVideoBuffer = NULL;
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ } else {
+ pVideoBuffer = NULL;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ pVp8Enc->hMFCVp8Handle.outputIndexTimestamp++;
+ pVp8Enc->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+ pDstOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pDstOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+ if (pVideoEnc->bFirstOutput == OMX_FALSE) {
+ 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);
+
+ 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;
+ }
+
+ 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 timestamp %lld us (%.2f secs), Tag: %d, frameType: %d dataLen: %d",
+ pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp,
+ pVideoBuffer->frameType, pDstOutputData->dataLen);
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+ (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
+ (pExynosComponent->bBehaviorEOS == OMX_FALSE))) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+ }
+
+ if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
+ (pExynosComponent->bBehaviorEOS == OMX_TRUE))
+ 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_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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_SignalReset(pVp8Enc->hSourceStartEvent);
+ }
+
+ ret = Exynos_VP8Enc_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) &&
+ (pExynosComponent->currentState == OMX_StateExecuting)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pVp8Enc->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+ Exynos_OSAL_SignalWait(pVp8Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pVp8Enc->hDestinationStartEvent);
+ }
+
+ if (Exynos_OSAL_GetElemNum(&pVp8Enc->bypassBufferInfoQ) > 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] buffer with EOS will be returned by bypassBufferInfoQ",
+ pExynosComponent, __FUNCTION__);
+
+ BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pVp8Enc->bypassBufferInfoQ);
+ if (pBufferInfo == NULL) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ 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_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 (pOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pVp8Enc->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+ Exynos_OSAL_SignalWait(pVp8Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pVp8Enc->hDestinationStartEvent);
+ }
+
+ if (Exynos_OSAL_GetElemNum(&pVp8Enc->bypassBufferInfoQ) > 0) {
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP8_ENC, componentName) != 0) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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;
+
+#if 0 /* unused code */
+ pVideoEnc->exynos_checkInputFrame = NULL;
+ pVideoEnc->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+
+ pVideoEnc->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
+
+ pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+ if (pVideoEnc->hSharedMemory == NULL) {
+ Exynos_OSAL_Free(pVp8Enc);
+ pVp8Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->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]: Exynos_Video_GetInstInfo is failed", 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 %d %d %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pVp8Enc->hMFCVp8Handle.videoInstInfo.specificInfo.enc.bRGBSupport),
+ (pVp8Enc->hMFCVp8Handle.videoInstInfo.specificInfo.enc.nSpareSize),
+ (pVp8Enc->hMFCVp8Handle.videoInstInfo.specificInfo.enc.bTemporalSvcSupport),
+ (pVp8Enc->hMFCVp8Handle.videoInstInfo.specificInfo.enc.bSkypeSupport),
+ (pVp8Enc->hMFCVp8Handle.videoInstInfo.specificInfo.enc.bRoiInfoSupport),
+ (pVp8Enc->hMFCVp8Handle.videoInstInfo.specificInfo.enc.bQpRangePBSupport));
+
+ if (pVp8Enc->hMFCVp8Handle.videoInstInfo.specificInfo.enc.nSpareSize > 0)
+ pVideoEnc->nInbufSpareSize = pVp8Enc->hMFCVp8Handle.videoInstInfo.specificInfo.enc.nSpareSize;
+
+ Exynos_Input_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_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;
+
+ 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;
+ }
+
+ ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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 hDestinationStartEvent;
+
+ 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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;
+}
--- /dev/null
+/*
+ *
+ * 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
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Vp9enc.c \
+ library_register.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOMX.Exynos.VP9.Encoder
+LOCAL_MODULE_RELATIVE_PATH := omx
+
+LOCAL_CFLAGS := -DUSE_VP9_SUPPORT
+
+ifeq ($(BOARD_USE_METADATABUFFERTYPE), true)
+LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE
+
+ifeq ($(BOARD_USE_ANDROIDOPAQUE), true)
+LOCAL_CFLAGS += -DUSE_ANDROIDOPAQUE
+endif
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_QOS_CTRL), true)
+LOCAL_CFLAGS += -DUSE_QOS_CTRL
+endif
+
+ifeq ($(BOARD_USE_SINGLE_PLANE_IN_DRM), true)
+LOCAL_CFLAGS += -DUSE_SINGLE_PLANE_IN_DRM
+endif
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_Venc libExynosOMX_OSAL libExynosOMX_Basecomponent \
+ libExynosVideoApi
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libui \
+ libExynosOMX_Resourcemanager libcsc libexynosv4l2 libion libhardware
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/enc \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null
+/*
+ *
+ * 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"
+
+/* 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;
+
+ FunctionIn();
+
+ 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_VP9ProfileMain;
+ pVp9Enc->hMFCVp9Handle.nProfileCnt = nProfileCnt;
+ pVp9Enc->hMFCVp9Handle.maxLevel = OMX_VIDEO_VP9Level_Version0;
+
+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;
+
+ 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;
+ }
+
+ pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+ if (pVp9Enc == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ while ((pVp9Enc->hMFCVp9Handle.maxLevel >> nLevelCnt) > 0) {
+ nLevelCnt++;
+ }
+
+ if ((pVp9Enc->hMFCVp9Handle.nProfileCnt == 0) ||
+ (nLevelCnt == 0)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : there is no any profile/level", __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);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : supported profile(%x), level(%x)", __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, "%s : there is no any profile/level", __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, "%s : profile(%x)/level(%x) is %ssupported", __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_VP9ProfileMain:
+ ret = 0;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+static OMX_U32 OMXVP9LevelToMFCVersion(OMX_VIDEO_VP9LEVELTYPE eLevel)
+{
+ OMX_U32 ret;
+
+ switch (eLevel) {
+ case OMX_VIDEO_VP9Level_Version0:
+ 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_ESSENTIAL, "PadControlOn : %d", pCommonParam->PadControlOn);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "LumaPadVal : %d", pCommonParam->LumaPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "CbPadVal : %d", pCommonParam->CbPadVal);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "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_ESSENTIAL, "Vp9GoldenFrameSel : %d", pVp9Param->Vp9GoldenFrameSel);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "Vp9GFRefreshPeriod : %d", pVp9Param->Vp9GFRefreshPeriod);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "RefNumberForPFrame : %d", pVp9Param->RefNumberForPFrame);
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "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;
+ 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 = pVp9Enc->nPFrames + 1;
+ pCommonParam->SliceMode = 0; /* invalid */
+ 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;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh: %d", pCommonParam->RandomIntraMBRefresh);
+ } else {
+ /* Don't support "Adaptive" and "Cyclic + Adaptive" */
+ pCommonParam->RandomIntraMBRefresh = 0;
+ }
+
+ eColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
+ pCommonParam->FrameMap = Exynos_OSAL_OMX2VideoFormat(eColorFormat, pInputPort->ePlaneType);
+
+ /* Vp9 specific parameters */
+ pVp9Param->FrameRate = (pInputPort->portDefinition.format.video.xFramerate) >> 16;
+ pVp9Param->Vp9Version = OMXVP9LevelToMFCVersion(pVp9Enc->VP9Component[OUTPUT_PORT_INDEX].eLevel);
+ /* 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_MAXVP9TEMPORALLAYERS; 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_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", 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;
+
+ 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 (nCmdIndex) {
+ case OMX_IndexConfigVideoIntraVOPRefresh:
+ {
+ nValue = VIDEO_FRAME_I;
+ pEncOps->Set_FrameType(pMFCVp9Handle->hMFCHandle, nValue);
+ pVideoEnc->IntraRefreshVOP = OMX_FALSE;
+ }
+ break;
+ case OMX_IndexConfigVideoIntraPeriod:
+ {
+ OMX_S32 nPFrames = (*((OMX_U32 *)pConfigData)) - 1;
+ nValue = nPFrames + 1;
+ pEncOps->Set_IDRPeriod(pMFCVp9Handle->hMFCHandle, nValue);
+ }
+ break;
+ case OMX_IndexConfigVideoBitrate:
+ {
+ OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pConfigData;
+ int i;
+
+ if (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] != OMX_Video_ControlRateDisable) {
+ /* bitrate : main */
+ nValue = pConfigBitrate->nEncodeBitrate;
+ pEncOps->Set_BitRate(pMFCVp9Handle->hMFCHandle, 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_MAXVP9TEMPORALLAYERS; 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);
+ }
+ }
+ 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;
+
+ pEncOps->Set_QpRange(pMFCVp9Handle->hMFCHandle, qpRange);
+ }
+ 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;
+ }
+ break;
+#ifdef USE_QOS_CTRL
+ case OMX_IndexVendorSetQosRatio: /* MSRND */
+ {
+ EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *pQosInfo = (EXYNOS_OMX_VIDEO_CONFIG_QOSINFO *)pConfigData;
+ nValue = pQosInfo->nQosRatio;
+ pEncOps->Set_QosRatio(pMFCVp9Handle->hMFCHandle, nValue);
+ pVideoEnc->bQosChanged = OMX_FALSE;
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] nCmdIndex %x nValue %d ", pExynosComponent, __FUNCTION__, (int)nCmdIndex, nValue);
+ Exynos_OSAL_Free(pDynamicConfigCMD);
+
+ Set_VP9Enc_Param(pExynosComponent);
+
+EXIT:
+ return;
+}
+
+#if 0 /* unused code */
+OMX_ERRORTYPE GetCodecInputPrivateData(
+ OMX_PTR pCodecBuffer,
+ OMX_PTR pVirtAddr[],
+ OMX_U32 nSize[])
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+#endif
+
+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_CODING_UNKNOWN;
+ int i;
+
+ FunctionIn();
+
+ 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) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ 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, "Failed to allocate encoder ops buffer");
+ 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);
+
+ Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps);
+
+ /* 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, "Mandatory functions must be supplied");
+ 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, "Mandatory functions must be supplied");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
+#else
+ pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
+#endif
+ pVp9Enc->hMFCVp9Handle.hMFCHandle = pVp9Enc->hMFCVp9Handle.pEncOps->Init(pVideoInstInfo);
+ if (pVp9Enc->hMFCVp9Handle.hMFCHandle == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
+ 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;
+ }
+
+ /* 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;
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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;
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->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) {
+ 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->hDestinationStartEvent);
+ Exynos_OSAL_SleepMillisec(0);
+ }
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE VP9CodecRegistCodecBuffers(
+ OMX_COMPONENTTYPE *pOMXComponent,
+ OMX_U32 nPortIndex,
+ int nBufferCnt)
+{
+ 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;
+ CODEC_ENC_BUFFER **ppCodecBuffer = NULL;
+ ExynosVideoEncBufferOps *pBufOps = NULL;
+ ExynosVideoPlane *pPlanes = NULL;
+
+ int nPlaneCnt = 0;
+ int i, j;
+
+ FunctionIn();
+
+ if (nPortIndex == INPUT_PORT_INDEX) {
+ ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
+ pBufOps = pVp9Enc->hMFCVp9Handle.pInbufOps;
+ } else {
+ ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
+ pBufOps = pVp9Enc->hMFCVp9Handle.pOutbufOps;
+ }
+
+ nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
+ pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+ if (pPlanes == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ /* Register buffer */
+ for (i = 0; i < nBufferCnt; i++) {
+ for (j = 0; j < nPlaneCnt; j++) {
+ pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
+ pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
+ pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
+ }
+
+ if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Free(pPlanes);
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(pPlanes);
+
+ 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;
+ EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ int i, nOutbufs;
+
+ ExynosVideoEncOps *pEncOps = pVp9Enc->hMFCVp9Handle.pEncOps;
+ 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, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
+
+ 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, "pVideoEnc->pMFCEncOutputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, 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];
+
+ ExynosVideoEncOps *pEncOps = pVp9Enc->hMFCVp9Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pVp9Enc->hMFCVp9Handle.pInbufOps;
+ ExynosVideoEncBufferOps *pOutbufOps = pVp9Enc->hMFCVp9Handle.pOutbufOps;
+ ExynosVideoEncParam *pEncParam = NULL;
+
+ ExynosVideoGeometry bufferConf;
+ OMX_U32 nInputBufferCnt = 0;
+ int i, nOutbufs;
+
+ FunctionIn();
+
+ if ((pSrcInputData->dataLen <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] FBD with EOS will be processed through bypassBufferInfoQ",
+ 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);
+ Exynos_OSAL_SignalSet(pVp9Enc->hDestinationStartEvent); /* awake dstInput thread */
+
+ 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);
+
+ /* 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 = pInputPort->portDefinition.format.video.nFrameWidth;
+ bufferConf.nFrameHeight = pInputPort->portDefinition.format.video.nFrameHeight;
+ bufferConf.nStride = ALIGN(pInputPort->portDefinition.format.video.nFrameWidth, 16);
+ } else {
+ bufferConf.nFrameWidth = pInputPort->portDefinition.format.video.nFrameHeight;
+ bufferConf.nFrameHeight = pInputPort->portDefinition.format.video.nFrameWidth;
+ bufferConf.nStride = ALIGN(pInputPort->portDefinition.format.video.nFrameHeight, 16);
+ }
+ bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+ pInbufOps->Set_Shareable(hMFCHandle);
+ nInputBufferCnt = 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, "Failed to set geometry for input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ }
+
+ /* setup input buffer */
+ if (pInbufOps->Setup(hMFCHandle, nInputBufferCnt) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+
+ if ((pInputPort->bufferProcessType & BUFFER_SHARE)
+#ifdef USE_METADATABUFFERTYPE
+ && (pInputPort->bStoreMetaData != OMX_TRUE)
+#endif
+ ) {
+ 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 *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+ EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+ ExynosVideoEncOps *pEncOps = pVp9Enc->hMFCVp9Handle.pEncOps;
+ ExynosVideoEncBufferOps *pInbufOps = pVp9Enc->hMFCVp9Handle.pInbufOps;
+ 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->bStoreMetaData == OMX_TRUE) {
+ 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, "Failed to set geometry for output buffer");
+ 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, "Failed to setup output buffer");
+ 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)
+ goto EXIT;
+
+ /* Enqueue output buffer */
+ for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+ pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
+ (int *)pVideoEnc->pMFCEncOutputBuffer[i]->fd,
+ pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pOutputPort),
+ NULL);
+ }
+
+ if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ /* Register output buffer */
+ /*************/
+ /* TBD */
+ /*************/
+ }
+
+ pVp9Enc->hMFCVp9Handle.bConfiguredMFCDst = OMX_TRUE;
+
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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;
+ case OMX_IndexParamVideoAndroidVp9Encoder:
+ {
+ OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE *pDstVp9EncoderType = (OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE *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_VP9ENCODERTYPE));
+ if (ret != OMX_ErrorNone)
+ 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_VP9ENCODERTYPE) - nOffset);
+ }
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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_ErrorBadParameter;
+ 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)
+ 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)
+ 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;
+ case OMX_IndexParamVideoAndroidVp9Encoder:
+ {
+ OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE *pSrcVp9EncoderType = (OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE *)pComponentParameterStructure;
+ OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE *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_VP9ENCODERTYPE));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pSrcVp9EncoderType->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pVp9Enc->hMFCVp9Handle.videoInstInfo.specificInfo.enc.bTemporalSvcSupport == VIDEO_FALSE) &&
+ (pSrcVp9EncoderType->eTemporalPattern != OMX_VIDEO_VPXTemporalLayerPatternNone)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "%s: MFC D/D doesn't support Temporal SVC", __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_VP9ENCODERTYPE) - nOffset);
+ }
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pVp9Enc = (EXYNOS_VP9ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%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)
+ 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;
+ default:
+ ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
+ break;
+ }
+
+EXIT:
+ if (ret == OMX_ErrorNone) {
+ OMX_PTR pDynamicConfigCMD = NULL;
+ pDynamicConfigCMD = Exynos_OMX_MakeDynamicConfigCMD(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) {
+ 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 ((cParameterName == NULL) ||
+ (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ 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_PTR hMFCHandle = NULL;
+ OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
+
+ ExynosVideoEncOps *pEncOps = NULL;
+ ExynosVideoEncBufferOps *pInbufOps = NULL;
+ ExynosVideoEncBufferOps *pOutbufOps = NULL;
+ ExynosVideoInstInfo *pVideoInstInfo = &(pVp9Enc->hMFCVp9Handle.videoInstInfo);
+
+ CSC_METHOD csc_method = CSC_METHOD_SW;
+
+ int i = 0, nPlaneCnt;
+
+ FunctionIn();
+
+ pVp9Enc->hMFCVp9Handle.bConfiguredMFCSrc = OMX_FALSE;
+ pVp9Enc->hMFCVp9Handle.bConfiguredMFCDst = OMX_FALSE;
+ pVideoEnc->bFirstInput = OMX_TRUE;
+ pVideoEnc->bFirstOutput = OMX_FALSE;
+ pExynosComponent->bUseFlagEOF = OMX_TRUE;
+ pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+ pExynosComponent->bBehaviorEOS = OMX_FALSE;
+
+ eColorFormat = pInputPort->portDefinition.format.video.eColorFormat;
+#ifdef USE_METADATABUFFERTYPE
+ if (pInputPort->bStoreMetaData == OMX_TRUE) {
+#ifdef USE_ANDROIDOPAQUE
+ if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)
+ pInputPort->bufferProcessType = BUFFER_COPY;
+ else
+ pInputPort->bufferProcessType = BUFFER_SHARE;
+#else
+ pInputPort->bufferProcessType = BUFFER_COPY;
+#endif
+ } else {
+ pInputPort->bufferProcessType = BUFFER_COPY;
+ }
+#else
+ pInputPort->bufferProcessType = BUFFER_COPY;
+#endif
+
+ 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;
+
+ pEncOps = pVp9Enc->hMFCVp9Handle.pEncOps;
+ pInbufOps = pVp9Enc->hMFCVp9Handle.pInbufOps;
+ pOutbufOps = pVp9Enc->hMFCVp9Handle.pOutbufOps;
+ hMFCHandle = pVp9Enc->hMFCVp9Handle.hMFCHandle;
+
+ 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->hDestinationStartEvent);
+
+ 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;
+
+ int i = 0, plane = 0;
+
+ FunctionIn();
+
+ if (pVideoEnc->csc_handle != NULL) {
+ csc_deinit(pVideoEnc->csc_handle);
+ pVideoEnc->csc_handle = NULL;
+ }
+
+ Exynos_OSAL_QueueTerminate(&pVp9Enc->bypassBufferInfoQ);
+
+ Exynos_OSAL_SignalTerminate(pVp9Enc->hDestinationStartEvent);
+ pVp9Enc->hDestinationStartEvent = 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);
+ } 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);
+
+ 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;
+
+ FunctionIn();
+
+ if (pVp9Enc->hMFCVp9Handle.bConfiguredMFCSrc == OMX_FALSE) {
+ ret = VP9CodecSrcSetup(pOMXComponent, pSrcInputData);
+ if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
+ goto EXIT;
+ }
+
+ if (pVp9Enc->hMFCVp9Handle.bConfiguredMFCDst == OMX_FALSE) {
+ ret = VP9CodecDstSetup(pOMXComponent);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+ }
+
+ while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
+ Change_VP9Enc_Param(pExynosComponent);
+ }
+
+ 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 timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
+ pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pVp9Enc->hMFCVp9Handle.indexTimestamp, pSrcInputData->nFlags);
+
+ 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
+
+ /* queue work for input buffer */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] oneFrameSize: %ld, bufferHeader: 0x%p", pExynosComponent, __FUNCTION__, pSrcInputData->dataLen, pSrcInputData->bufferHeader);
+
+ 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->multiPlaneBuffer.dataBuffer,
+ (int *)pSrcInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ nPlaneCnt,
+ pPrivate);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
+ 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->bDestinationStart = OMX_TRUE;
+ Exynos_OSAL_SignalSet(pVp9Enc->hDestinationStartEvent);
+ 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->multiPlaneBuffer.dataBuffer[0] = NULL;
+ pSrcOutputData->pPrivate = NULL;
+ } else {
+ int plane = 0, nPlaneCnt;
+ nPlaneCnt = Exynos_GetPlaneFromPort(pInputPort);
+ for (plane = 0; plane < nPlaneCnt; plane++) {
+ pSrcOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
+ pSrcOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[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, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__);
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ if (pInputPort->bufferProcessType == BUFFER_SHARE)
+ pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+
+#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];
+
+ ExynosVideoEncOps *pEncOps = pVp9Enc->hMFCVp9Handle.pEncOps;
+ 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->multiPlaneBuffer.dataBuffer[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
+ 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->bStoreMetaData == OMX_TRUE)
+ nAllocLen[0] = ALIGN(pOutputPort->portDefinition.format.video.nFrameWidth * pOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2, 512);
+
+ codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
+ (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
+ (int *)&pDstInputData->multiPlaneBuffer.fd,
+ nAllocLen,
+ nDataLen,
+ Exynos_GetPlaneFromPort(pOutputPort),
+ pDstInputData->bufferHeader);
+ if (codecReturn != VIDEO_ERROR_NONE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
+ 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;
+ ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
+ 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, "HW is not available");
+ pVideoBuffer = NULL;
+ ret = OMX_ErrorHardware;
+ goto EXIT;
+ } else {
+ pVideoBuffer = NULL;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ pVp9Enc->hMFCVp9Handle.outputIndexTimestamp++;
+ pVp9Enc->hMFCVp9Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
+
+ pDstOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
+ pDstOutputData->multiPlaneBuffer.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->multiPlaneBuffer.dataBuffer[0] ==
+ pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]) {
+ pDstOutputData->pPrivate = pVideoEnc->pMFCEncOutputBuffer[i];
+ break;
+ }
+ }
+
+ if (pDstOutputData->pPrivate == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+ ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
+ goto EXIT;
+ }
+ }
+
+ /* For Share Buffer */
+ pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
+
+ if (pVideoEnc->bFirstOutput == OMX_FALSE) {
+ 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);
+
+ 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;
+ }
+
+ 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 timestamp %lld us (%.2f secs), Tag: %d, frameType: %d dataLen: %d",
+ pExynosComponent, __FUNCTION__,
+ pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp,
+ pVideoBuffer->frameType, pDstOutputData->dataLen);
+
+#ifdef PERFORMANCE_DEBUG
+ if (pDstOutputData->bufferHeader != NULL) {
+ pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
+ Exynos_OSAL_V4L2CountDecrease(pOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
+ }
+#endif
+
+ if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+ (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
+ (pExynosComponent->bBehaviorEOS == OMX_FALSE))) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
+ pDstOutputData->remainDataLen = 0;
+ }
+
+ if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
+ (pExynosComponent->bBehaviorEOS == OMX_TRUE)) {
+ 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_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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_SignalReset(pVp9Enc->hSourceStartEvent);
+ }
+
+ ret = Exynos_VP9Enc_SrcOut(pOMXComponent, pSrcOutputData);
+ if ((ret != OMX_ErrorNone) &&
+ (pExynosComponent->currentState == OMX_StateExecuting)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+ if ((pVp9Enc->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+ Exynos_OSAL_SignalWait(pVp9Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pVp9Enc->hDestinationStartEvent);
+ }
+
+ if (Exynos_OSAL_GetElemNum(&pVp9Enc->bypassBufferInfoQ) > 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] buffer with EOS will be returned by bypassBufferInfoQ",
+ pExynosComponent, __FUNCTION__);
+
+ BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pVp9Enc->bypassBufferInfoQ);
+ if (pBufferInfo == NULL) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ 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_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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 (pOutputPort->bufferProcessType & BUFFER_COPY) {
+ if ((pVp9Enc->bDestinationStart == OMX_FALSE) &&
+ (!CHECK_PORT_BEING_FLUSHED(pOutputPort))) {
+ Exynos_OSAL_SignalWait(pVp9Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
+ if (pVideoEnc->bExitBufferProcessThread)
+ goto EXIT;
+
+ Exynos_OSAL_SignalReset(pVp9Enc->hDestinationStartEvent);
+ }
+
+ if (Exynos_OSAL_GetElemNum(&pVp9Enc->bypassBufferInfoQ) > 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] buffer with EOS will be returned by bypassBufferInfoQ",
+ pExynosComponent, __FUNCTION__);
+
+ EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+ OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+ BYPASS_BUFFER_INFO *pBufferInfo = NULL;
+
+ 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_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__);
+ 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, "OMX_ErrorBadParameter, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP9_ENC, componentName) != 0) {
+ ret = OMX_ErrorBadParameter;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+ ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
+ 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ ret = OMX_ErrorInsufficientResources;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
+ 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 = 8 */
+ pVp9Enc->qpRangeI.nMaxQP = 63; /* index = 63, value = 255 */
+ pVp9Enc->qpRangeP.nMinQP = 2; /* index = 2, value = 8 */
+ 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_VP9ProfileMain;
+ pVp9Enc->VP9Component[i].eLevel = OMX_VIDEO_VP9Level_Version0;
+ }
+ pVp9Enc->nPFrames = -1;
+
+ Exynos_OSAL_Memset(&pVp9Enc->AndroidVp9EncoderType, 0, sizeof(OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE));
+ INIT_SET_SIZE_VERSION(&pVp9Enc->AndroidVp9EncoderType, OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE);
+ pVp9Enc->AndroidVp9EncoderType.nKeyFrameInterval = pVp9Enc->nPFrames + 1;
+ pVp9Enc->AndroidVp9EncoderType.eTemporalPattern = OMX_VIDEO_VPXTemporalLayerPatternNone;
+ pVp9Enc->AndroidVp9EncoderType.nTemporalLayerCount = 1;
+ for (i = 0; i < OMX_VIDEO_ANDROID_MAXVP9TEMPORALLAYERS; 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;
+
+#if 0 /* unused code */
+ pVideoEnc->exynos_checkInputFrame = NULL;
+ pVideoEnc->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
+#endif
+
+ pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+
+ pVideoEnc->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
+
+ pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
+ if (pVideoEnc->hSharedMemory == NULL) {
+ Exynos_OSAL_Free(pVp9Enc);
+ pVp9Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->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 %d %d %d %d %d %d", pExynosComponent, __FUNCTION__,
+ (pVp9Enc->hMFCVp9Handle.videoInstInfo.specificInfo.enc.bRGBSupport),
+ (pVp9Enc->hMFCVp9Handle.videoInstInfo.specificInfo.enc.nSpareSize),
+ (pVp9Enc->hMFCVp9Handle.videoInstInfo.specificInfo.enc.bTemporalSvcSupport),
+ (pVp9Enc->hMFCVp9Handle.videoInstInfo.specificInfo.enc.bSkypeSupport),
+ (pVp9Enc->hMFCVp9Handle.videoInstInfo.specificInfo.enc.bRoiInfoSupport),
+ (pVp9Enc->hMFCVp9Handle.videoInstInfo.specificInfo.enc.bQpRangePBSupport));
+
+ if (pVp9Enc->hMFCVp9Handle.videoInstInfo.specificInfo.enc.nSpareSize > 0)
+ pVideoEnc->nInbufSpareSize = pVp9Enc->hMFCVp9Handle.videoInstInfo.specificInfo.enc.nSpareSize;
+
+ Exynos_Input_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_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;
+
+ 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;
+ }
+
+ ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
--- /dev/null
+/*
+ *
+ * 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 1
+ 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_VP9ENCODERTYPE AndroidVp9EncoderType;
+
+ /* SEC MFC Codec specific */
+ EXYNOS_MFC_VP9ENC_HANDLE hMFCVp9Handle;
+
+ OMX_BOOL bSourceStart;
+ OMX_BOOL bDestinationStart;
+ OMX_HANDLETYPE hSourceStartEvent;
+ OMX_HANDLETYPE hDestinationStartEvent;
+
+ 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
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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;
+}
--- /dev/null
+/*
+ *
+ * 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
+
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ Exynos_OMX_Component_Register.c \
+ Exynos_OMX_Core.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libExynosOMX_Core
+
+LOCAL_CFLAGS :=
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_STATIC_LIBRARIES := libExynosOMX_OSAL libExynosOMX_Basecomponent
+LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils \
+ libExynosOMX_Resourcemanager
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_TOP)/component/common
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+ifeq ($(EXYNOS_OMX_SUPPORT_TUNNELING), true)
+LOCAL_CFLAGS += -DTUNNELING_SUPPORT
+endif
+
+ifeq ($(EXYNOS_OMX_SUPPORT_EGL_IMAGE), true)
+LOCAL_CFLAGS += -DEGL_IMAGE_SUPPORT
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
--- /dev/null
+/*
+ *
+ * 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"
+
+OMX_ERRORTYPE Exynos_OMX_Component_Register(EXYNOS_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ int componentNum = 0, roleNum = 0, totalCompNum = 0;
+ char *libName;
+ size_t len;
+ const char *errorMsg;
+ DIR *dir;
+ struct dirent *d;
+
+ int (*Exynos_OMX_COMPONENT_Library_Register)(ExynosRegisterComponentType **exynosComponents);
+ ExynosRegisterComponentType **exynosComponentsTemp;
+ EXYNOS_OMX_COMPONENT_REGLIST *componentList;
+
+ FunctionIn();
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s lib is loaded", (IS_64BIT_OS? "64bit":"32bit"));
+ dir = opendir((IS_64BIT_OS?
+ EXYNOS_OMX64_INSTALL_PATH : EXYNOS_OMX_INSTALL_PATH));
+ if (dir == NULL) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ componentList = (EXYNOS_OMX_COMPONENT_REGLIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM);
+ Exynos_OSAL_Memset(componentList, 0, sizeof(EXYNOS_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM);
+ libName = Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_LIBNAME_SIZE);
+
+ while ((d = readdir(dir)) != NULL) {
+ OMX_HANDLETYPE soHandle;
+
+ if (Exynos_OSAL_Strncmp(d->d_name, "libOMX.Exynos.", Exynos_OSAL_Strlen("libOMX.Exynos.")) == 0) {
+ Exynos_OSAL_Memset(libName, 0, MAX_OMX_COMPONENT_LIBNAME_SIZE);
+ Exynos_OSAL_Strcpy(libName, (IS_64BIT_OS? EXYNOS_OMX64_INSTALL_PATH : EXYNOS_OMX_INSTALL_PATH));
+ Exynos_OSAL_Strcat(libName, d->d_name);
+ Exynos_OSAL_Log(EXYNOS_LOG_INFO, "Loading the library: %s", 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) {
+ int i = 0;
+ unsigned int j = 0;
+
+ componentNum = (*Exynos_OMX_COMPONENT_Library_Register)(NULL);
+ exynosComponentsTemp = (ExynosRegisterComponentType **)Exynos_OSAL_Malloc(sizeof(ExynosRegisterComponentType*) * componentNum);
+ for (i = 0; i < componentNum; i++) {
+ exynosComponentsTemp[i] = Exynos_OSAL_Malloc(sizeof(ExynosRegisterComponentType));
+ 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 < 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]);
+ }
+
+ Exynos_OSAL_Free(exynosComponentsTemp);
+ } else {
+ if ((errorMsg = Exynos_OSAL_dlerror()) != NULL)
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "dlsym failed: %s", errorMsg);
+ }
+ Exynos_OSAL_dlclose(soHandle);
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "dlopen failed: %s", Exynos_OSAL_dlerror());
+ }
+ } else {
+ /* not a component name line. skip */
+ continue;
+ }
+ }
+
+ Exynos_OSAL_Free(libName);
+
+ closedir(dir);
+
+ *compList = componentList;
+ *compNum = totalCompNum;
+
+EXIT:
+ 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;
+ OMX_COMPONENTTYPE *pOMXComponent;
+
+ 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) {
+ ret = OMX_ErrorInvalidComponentName;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInvalidComponentName, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ Exynos_OMX_ComponentInit = Exynos_OSAL_dlsym(libHandle, "Exynos_OMX_ComponentInit");
+ if (!Exynos_OMX_ComponentInit) {
+ Exynos_OSAL_dlclose(libHandle);
+ ret = OMX_ErrorInvalidComponent;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__);
+ goto EXIT;
+ }
+
+ pOMXComponent = (OMX_COMPONENTTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_COMPONENTTYPE));
+ 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]Exynos_OMX_ComponentInit() is failed(%d)", __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, "OMX_ErrorInvalidComponent, Line:%d", __LINE__);
+ 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;
+}
+
--- /dev/null
+/*
+ *
+ * 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
--- /dev/null
+/*
+ *
+ * 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, "Exynos_OMX_Init : %s", "OMX_ErrorInsufficientResources");
+ goto EXIT;
+ }
+
+ ret = Exynos_OMX_ResourceManager_Init();
+ if (OMX_ErrorNone != ret) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_OMX_Init : Exynos_OMX_ResourceManager_Init failed");
+ goto EXIT;
+ }
+
+ ret = Exynos_OSAL_MutexCreate(&ghLoadComponentListMutex);
+ if (OMX_ErrorNone != ret) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_OMX_Init : Exynos_OSAL_MutexCreate(&ghLoadComponentListMutex) failed");
+ goto EXIT;
+ }
+
+ gInitialized = 1;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_OMX_Init : %s", "OMX_ErrorNone");
+ }
+
+ 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)) {
+ 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, "ComponentName : %s", 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));
+ 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, "OMX_Error, Line:%d", __LINE__);
+ 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, "OMX_Error, Line:%d", __LINE__);
+ 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);
+ 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, "Exynos_OMX_GetHandle : %s", "OMX_ErrorNone");
+ 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;
+ OMX_STRING RoleString[MAX_OMX_COMPONENT_ROLE_SIZE];
+ 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;
+}
--- /dev/null
+/*
+ *
+ * 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
+
--- /dev/null
+
+ 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
+
--- /dev/null
+/*
+ *
+ * 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 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 EXYNOS_OMX_INSTALL_PATH "/system/lib/omx/"
+#define EXYNOS_OMX64_INSTALL_PATH "/system/lib64/omx/"
+
+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_PARAM_THUMBNAIL "OMX.SEC.index.ThumbnailMode"
+ OMX_IndexVendorThumbnailMode = 0x7F000001,
+
+#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"
+ OMX_IndexVendorNeedContigMemory = 0x7F000004,
+
+#define EXYNOS_INDEX_CONFIG_GET_BUFFER_FD "OMX.SEC.index.GetBufferFD"
+ OMX_IndexVendorGetBufferFD = 0x7F000005,
+
+#define EXYNOS_INDEX_PARAM_SET_DTS_MODE "OMX.SEC.index.SetDTSMode"
+ OMX_IndexVendorSetDTSMode = 0x7F000006,
+
+#define EXYNOS_INDEX_CONFIG_SET_QOS_RATIO "OMX.SEC.index.SetQosRatio"
+ OMX_IndexVendorSetQosRatio = 0x7F000007,
+
+ /* for Android Native Window */
+#define EXYNOS_INDEX_PARAM_ENABLE_ANB "OMX.google.android.index.enableAndroidNativeBuffers"
+ OMX_IndexParamEnableAndroidBuffers = 0x7F000011,
+
+#define EXYNOS_INDEX_PARAM_GET_ANB "OMX.google.android.index.getAndroidNativeBufferUsage"
+ OMX_IndexParamGetAndroidNativeBuffer = 0x7F000012,
+
+#define EXYNOS_INDEX_PARAM_USE_ANB "OMX.google.android.index.useAndroidNativeBuffer"
+ OMX_IndexParamUseAndroidNativeBuffer = 0x7F000013,
+
+ /* for Android Store Metadata Inbuffer */
+#define EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER "OMX.google.android.index.storeMetaDataInBuffers"
+ OMX_IndexParamStoreMetaDataBuffer = 0x7F000014,
+
+ /* prepend SPS/PPS to I/IDR for H.264 Encoder */
+#define EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR "OMX.google.android.index.prependSPSPPSToIDRFrames"
+ OMX_IndexParamPrependSPSPPSToIDR = 0x7F000015,
+
+#ifdef USE_KHRONOS_OMX_HEADER
+ /* VP8 Codec */
+#if 0 /* USE_VP8_SUPPORT : these are declared in OMX_IndexExt.h */
+#define EXYNOS_INDEX_PARAM_VIDEO_VP8_TYPE "OMX.SEC.index.VideoVp8Type"
+ OMX_IndexParamVideoVp8 = 0x7F000016,
+
+#define EXYNOS_INDEX_CONFIG_VIDEO_VP8_REFERENCEFRAME "OMX.SEC.index.VideoVp8ReferenceFrame"
+ OMX_IndexConfigVideoVp8ReferenceFrame = 0x7F000017,
+
+#define EXYNOS_INDEX_CONFIG_VIDEO_VP8_REFERENCEFRAMETYPE "OMX.SEC.index.VideoVp8ReferenceFrameType"
+ OMX_IndexConfigVideoVp8ReferenceFrameType = 0x7F000018,
+#endif // USE_VP8_SUPPORT
+
+ /* HEVC Codec */
+#ifdef USE_HEVC_SUPPORT
+#define EXYNOS_INDEX_PARAM_VIDEO_HEVC_TYPE "OMX.SEC.index.VideoHevcType"
+ OMX_IndexParamVideoHevc = 0x7F000019,
+#endif // USE_HEVC_SUPPORT
+
+#endif // USE_KHRONOS_OMX_HEADER
+
+ /* Thumbnail */
+#define EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL "OMX.SEC.index.enableThumbnailMode"
+ OMX_IndexParamEnableThumbnailMode = 0x7F000020,
+
+ /* Android Native Buffer */
+#define EXYNOS_INDEX_PARAM_USE_ANB2 "OMX.google.android.index.useAndroidNativeBuffer2"
+ OMX_IndexParamUseAndroidNativeBuffer2 = 0x7F000021,
+
+ /* QP control */
+#define EXYNOS_INDEX_PARAM_VIDEO_QPRANGE_TYPE "OMX.SEC.indexParam.VideoQPRange"
+ OMX_IndexParamVideoQPRange = 0x7F000022,
+
+#define EXYNOS_INDEX_CONFIG_VIDEO_QPRANGE_TYPE "OMX.SEC.indexConfig.VideoQPRange"
+ OMX_IndexConfigVideoQPRange = 0x7F000023,
+
+#ifdef USE_KHRONOS_OMX_HEADER
+ /* VP8 Codec */
+#ifdef USE_VP8_SUPPORT
+#define EXYNOS_INDEX_PARAM_VIDEO_ANDROID_VP8_ENCODER "OMX.SEC.index.VideoAndroidVP8Encoder"
+ OMX_IndexParamVideoAndroidVp8Encoder = 0x7F000024,
+#endif // USE_VP8_SUPPORT
+
+#define EXYNOS_INDEX_PARAM_SLICE_SEGMENTS "OMX.SEC.index.SliceSegments"
+ OMX_IndexParamSliceSegments = 0x7F000025,
+
+#endif // USE_KHRONOS_OMX_HEADER
+
+ /* Temporal SVC */
+#define EXYNOS_INDEX_CONFIG_VIDEO_TEMPORALSVC "OMX.SEC.index.TemporalSVC"
+ OMX_IndexConfigVideoTemporalSVC = 0x7F000026,
+
+#define EXYNOS_INDEX_PARAM_VIDEO_AVC_ENABLE_TEMPORALSVC "OMX.SEC.index.AVC.enableTemporalSVC"
+ OMX_IndexParamVideoAVCEnableTemporalSVC = 0x7F000027,
+
+ /* VC1 Codec */
+#ifndef USE_KHRONOS_OMX_1_2
+#define EXYNOS_INDEX_PARAM_VIDEO_VC1_TYPE "OMX.SEC.index.VideoVc1Type"
+ OMX_IndexParamVideoVC1 = 0x7F000028,
+#endif
+
+//#ifdef USE_KHRONOS_OMX_HEADER
+ /* VP9 Codec */
+#ifdef USE_VP9_SUPPORT
+#define EXYNOS_INDEX_PARAM_VIDEO_VP9_TYPE "OMX.SEC.index.VideoVp9Type"
+ OMX_IndexParamVideoVp9 = 0x7F000029,
+
+#define EXYNOS_INDEX_CONFIG_VIDEO_VP9_REFERENCEFRAME "OMX.SEC.index.VideoVp9ReferenceFrame"
+ OMX_IndexConfigVideoVp9ReferenceFrame = 0x7F000030,
+
+#define EXYNOS_INDEX_CONFIG_VIDEO_VP9_REFERENCEFRAMETYPE "OMX.SEC.index.VideoVp9ReferenceFrameType"
+ OMX_IndexConfigVideoVp9ReferenceFrameType = 0x7F000031,
+
+#define EXYNOS_INDEX_PARAM_VIDEO_ANDROID_VP9_ENCODER "OMX.SEC.index.VideoAndroidVP9Encoder"
+ OMX_IndexParamVideoAndroidVp9Encoder = 0x7F000032,
+#endif // USE_VP9_SUPPORT
+//#endif // USE_KHRONOS_OMX_HEADER
+
+ /* blur filtering */
+#define EXYNOS_INDEX_PARAM_ENABLE_BLUR_FILTER "OMX.SEC.indexParam.enableBlurFilter"
+ OMX_IndexParamEnableBlurFilter = 0x7F000033,
+#define EXYNOS_INDEX_CONFIG_BLUR_INFO "OMX.SEC.indexConfig.BlurInfo"
+ OMX_IndexConfigBlurInfo = 0x7F000034,
+
+#define EXYNOS_INDEX_PARAM_VIDEO_HEVC_ENABLE_TEMPORALSVC "OMX.SEC.index.Hevc.enableTemporalSVC"
+ OMX_IndexParamVideoHevcEnableTemporalSVC = 0x7F000035,
+
+ /* ROI Information */
+#define EXYNOS_INDEX_CONFIG_VIDEO_ROIINFO "OMX.SEC.index.RoiInfo"
+ OMX_IndexConfigVideoRoiInfo = 0x7F000036,
+#define EXYNOS_INDEX_PARAM_VIDEO_ENABLE_ROIINFO "OMX.SEC.index.enableRoiInfo"
+ OMX_IndexParamVideoEnableRoiInfo = 0x7F000037,
+
+ /* rotation about encoder's input */
+#define EXYNOS_INDEX_PARAM_ROATION_INFO "OMX.SEC.indexParam.RotationInfo"
+ OMX_IndexParamRotationInfo = 0x7F000038,
+
+#define EXYNOS_INDEX_CONFIG_OPERATING_RATE "OMX.SEC.index.OperatingRate"
+#ifdef USE_KHRONOS_OMX_HEADER
+ OMX_IndexConfigOperatingRate = 0x7F000039,
+#endif
+
+ /* for custom component(MSRND) */
+ OMX_IndexExynosStartUnused = 0x7F050000, /* Reserved region for Exynos Extensions */
+
+#define EXYNOS_CUSTOM_INDEX_CONFIG_PTS_MODE "OMX.SEC.CUSTOM.index.PTSMode"
+ OMX_IndexExynosConfigPTSMode = 0x7F050001, /* to support PTS Video TimeStamp - OMX_BOOL */
+#define EXYNOS_CUSTOM_INDEX_CONFIG_DISPLAY_DELAY "OMX.SEC.CUSTOM.index.DisplayDelay"
+ OMX_IndexExynosConfigDisplayDelay = 0x7F050002, /* to support H264 DisplayDelay Setting - OMX_U32 */
+ /* Timestamp reorder */
+#define EXYNOS_CUSTOM_INDEX_PARAM_REORDER_MODE "OMX.SEC.CUSTOM.index.ReorderMode"
+ OMX_IndexExynosParamReorderMode = 0x7F050003,
+#define EXYNOS_CUSTOM_INDEX_PARAM_CORRUPTEDHEADER "OMX.SEC.CUSTOM.index.CorruptedHeader"
+ OMX_IndexExynosParamCorruptedHeader = 0x7F050004,
+
+
+ /* for Skype HD Common */
+#define OMX_MS_SKYPE_PARAM_DRIVERVER "OMX.microsoft.skype.index.driverversion"
+ OMX_IndexSkypeParamDriverVersion = 0x7F060001,
+ /* for Skype HD Decode */
+#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,
+ /* for Skype HD Encode */
+#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,
+#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,
+#define OMX_MS_SKYPE_CONFIG_TEMPORALLAYERCOUNT "OMX.microsoft.skype.index.temporallayercount"
+ OMX_IndexSkypeConfigTemporalLayerCount = 0x7F060009,
+#define OMX_MS_SKYPE_CONFIG_BASELAYERPID "OMX.microsoft.skype.index.basepid"
+ OMX_IndexSkypeConfigBasePid = 0x7F06000a,
+
+ 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_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_COLOR_FORMATTYPE {
+ OMX_SEC_COLOR_FormatNV12TPhysicalAddress = 0x7F000001, /**< Reserved region for introducing Vendor Extensions */
+ OMX_SEC_COLOR_FormatNV12LPhysicalAddress = 0x7F000002,
+ OMX_SEC_COLOR_FormatNV12LVirtualAddress = 0x7F000003,
+#ifdef USE_KHRONOS_OMX_HEADER
+ OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002, /* 0x7FC00002 */
+#endif
+ OMX_SEC_COLOR_FormatNV21LPhysicalAddress = 0x7F000010,
+ OMX_SEC_COLOR_FormatNV21Linear = 0x7F000011,
+ OMX_SEC_COLOR_FormatYVU420Planar = 0x7F000012,
+ OMX_SEC_COLOR_Format32bitABGR8888 = 0x7F000013, /* unused */
+ OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace = 0x7F000014,
+ OMX_SEC_COLOR_Format10bitYUV420SemiPlanar = 0x7F000015,
+
+ /* to copy a encoded data for drm component using gsc or fimc */
+ OMX_SEC_COLOR_FormatEncodedData = OMX_COLOR_FormatYCbYCr,
+#ifdef USE_KHRONOS_OMX_HEADER
+ /* for Android SurfaceMediaSource*/
+ OMX_COLOR_FormatAndroidOpaque = 0x7F000789,
+ OMX_COLOR_Format32BitRGBA8888 = 0x7F00A000,
+#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,
+ BUFFER_METADATA = 0x04,
+ BUFFER_ANBSHARE = 0x08,
+} 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_S3D_SUPPORT
+ OMX_EventS3DInformation,
+#endif
+} EXYNOS_OMX_EVENTTYPE;
+
+typedef enum _EXYNOS_ANB_TYPE {
+ NATIVE_GRAPHIC_BUFFER1,
+ NATIVE_GRAPHIC_BUFFER2,
+} EXYNOS_ANB_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_VIDEO_THUMBNAILMODE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnable;
+} EXYNOS_OMX_VIDEO_THUMBNAILMODE;
+
+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_PARAM_DTSMODE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_BOOL bDTSMode;
+} EXYNOS_OMX_VIDEO_PARAM_DTSMODE;
+
+typedef struct _EXYNOS_OMX_VIDEO_PARAM_REORDERMODE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_BOOL bReorderMode;
+} EXYNOS_OMX_VIDEO_PARAM_REORDERMODE;
+
+typedef struct _EXYNOS_OMX_VIDEO_PARAM_CORRUPTEDHEADER {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_BOOL bDiscardEvent;
+} EXYNOS_OMX_VIDEO_PARAM_CORRUPTEDHEADER;
+
+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_CONFIG_QOSINFO {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nQosRatio;
+} EXYNOS_OMX_VIDEO_CONFIG_QOSINFO;
+
+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_ANDROID_MAXAVCTEMPORALLAYERS 7
+#define OMX_VIDEO_ANDROID_MAXHEVCTEMPORALLAYERS 7
+
+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_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;
+
+/* 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
+
+/* for Ext-Codec support */
+typedef enum EXYNOS_OMX_VIDEO_CODINGTYPE {
+#ifdef USE_KHRONOS_OMX_HEADER
+ OMX_VIDEO_CodingHEVC = 0x7F000002, /**< ITU H.265/HEVC */
+ OMX_VIDEO_CodingVP9 = 0x7F000003, /**< Google VP9 */
+#endif
+ OMX_VIDEO_VendorCodingMAX = 0x7FFFFFFF,
+} EXYNOS_OMX_VIDEO_CODINGTYPE;
+
+typedef enum _EXYNOS_OMX_HIERARCHICAL_CODING_TYPE
+{
+ EXYNOS_OMX_Hierarchical_P = 0x00,
+ EXYNOS_OMX_Hierarchical_B,
+} EXYNOS_OMX_HIERARCHICAL_CODING_TYPE;
+
+#ifdef USE_KHRONOS_OMX_HEADER
+
+#if defined(USE_VP8_SUPPORT) || defined(USE_VP9_SUPPORT)
+/** 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;
+#endif
+
+ /* VP8 Codec */
+#ifdef USE_VP8_SUPPORT
+/** Maximum number of VP8 temporal layers */
+#define OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS 3
+
+/**
+ * Android specific VP8 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;
+ 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;
+#endif // USE_VP8_SUPPORT
+
+ /* HEVC codec */
+#ifdef USE_HEVC_SUPPORT
+/** HEVC Profile enum type */
+typedef enum OMX_VIDEO_HEVCPROFILETYPE {
+ OMX_VIDEO_HEVCProfileUnknown = 0x0,
+ OMX_VIDEO_HEVCProfileMain = 0x01, /**< Main profile */
+ OMX_VIDEO_HEVCProfileMain10 = 0x02, /**< Main 10 profile */
+ OMX_VIDEO_HEVCProfileMainStillPicture = 0x04, /**< Main Still Picture */
+ 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_VIDEO_PARAM_HEVCTYPE;
+
+#endif // USE_HEVC_SUPPORT
+
+/** 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;
+
+#endif // USE_KHRONOS_OMX_HEADER
+
+//#ifdef USE_KHRONOS_OMX_HEADER
+ /* VP9 Codec */
+#ifdef USE_VP9_SUPPORT
+ /* VP9 profiles */
+typedef enum OMX_VIDEO_VP9PROFILETYPE {
+ OMX_VIDEO_VP9ProfileMain = 0x00000001,
+ 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_VP9Level_Version0 = 0x00000001,
+ 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;
+
+ /* VP9 param */
+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;
+
+ /* VP9 reference frames */
+typedef struct OMX_VIDEO_VP9REFERENCEFRAMETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL nPreviousFrameRefresh;
+ OMX_BOOL bGoldenFrameRefresh;
+ OMX_BOOL bAlternateFrameRefresh;
+ OMX_BOOL bUsePreviousFrame;
+ OMX_BOOL bUseGoldenFrame;
+ OMX_BOOL bUseAlternateFrame;
+} OMX_VIDEO_VP9REFERENCEFRAMETYPE;
+
+ /* VP9 reference frame type */
+typedef struct OMX_VIDEO_VP9REFERENCEFRAMEINFOTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bIsIntraFrame;
+ OMX_BOOL bIsGoldenOrAlternateFrame;
+} OMX_VIDEO_VP9REFERENCEFRAMEINFOTYPE;
+
+/** Maximum number of VP9 temporal layers */
+#define OMX_VIDEO_ANDROID_MAXVP9TEMPORALLAYERS 3
+
+/**
+ * Android specific 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_VP9ENCODERTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nKeyFrameInterval;
+ OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE eTemporalPattern;
+ OMX_U32 nTemporalLayerCount;
+ OMX_U32 nTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXVP9TEMPORALLAYERS];
+ OMX_U32 nMinQuantizer;
+ OMX_U32 nMaxQuantizer;
+} OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE;
+#endif // USE_VP9_SUPPORT
+//#endif // USE_KHRONOS_OMX_HEADER
+
+#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
+
+#ifndef __OMX_EXPORTS
+#define __OMX_EXPORTS
+#define EXYNOS_EXPORT_REF __attribute__((visibility("default")))
+#define EXYNOS_IMPORT_REF __attribute__((visibility("default")))
+#endif
+
+#endif
--- /dev/null
+/*
+ *
+ * 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.
+ */
+#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))
+
+#define GET_2B_SIZE(w, h) (ALIGN(w / 4, 16) * ALIGN(h, 16) + 64)
+#define GET_10B_Y_SIZE(w, h) (GET_Y_SIZE(w, h) + GET_2B_SIZE(w, h))
+#define GET_10B_UV_SIZE(w, h) (GET_UV_SIZE(w, h) + GET_2B_SIZE(w, h / 2))
+#define GET_10B_CB_SIZE(w, h) (GET_CB_SIZE(w, h) + GET_2B_SIZE(w, h / 2))
+#define GET_10B_CR_SIZE(w, h) (GET_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->bIsPortFlushed == OMX_TRUE)
+#define CHECK_PORT_BEING_DISABLED(port) (port->bIsPortDisabled == OMX_TRUE)
+#define CHECK_PORT_BEING_FLUSHED_OR_DISABLED(port) ((port->bIsPortFlushed == OMX_TRUE) || (port->bIsPortDisabled == OMX_TRUE))
+#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
--- /dev/null
+/*
+ * 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 */
+
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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 */
+} 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 */
+
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/**
+ * 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 */
--- /dev/null
+/**
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/**
+ * 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 */
+
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*@@@+++@@@@******************************************************************
+
+ 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
--- /dev/null
+LOCAL_PATH := $(call my-dir)
+
+ifeq ($(BOARD_USE_SKYPE_HD), true)
+
+#################################
+#### libExynosOMX_SkypeHD_Enc ###
+#################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libExynosOMX_SkypeHD_Enc
+
+LOCAL_CFLAGS := -DUSE_SKYPE_HD
+LOCAL_CFLAGS += -DBUILD_ENC
+
+LOCAL_SRC_FILES := Exynos_OSAL_SkypeHD.c
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_INC)/skype \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/enc \
+ $(EXYNOS_OMX_COMPONENT)/video/enc/h264 \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_SOC)/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_STATIC_LIBRARY)
+
+#################################
+#### libExynosOMX_SkypeHD_Dec ###
+#################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libExynosOMX_SkypeHD_Dec
+
+LOCAL_CFLAGS := -DUSE_SKYPE_HD
+LOCAL_CFLAGS += -DBUILD_DEC
+LOCAL_SRC_FILES := Exynos_OSAL_SkypeHD.c
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_INC)/skype \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/dec \
+ $(EXYNOS_OMX_COMPONENT)/video/dec/h264 \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_SOC)/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_STATIC_LIBRARY)
+endif # for Skype HD
+
+
+##########################
+#### libExynosOMX_OSAL ###
+##########################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ 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_SharedMemory.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libExynosOMX_OSAL
+
+LOCAL_CFLAGS :=
+
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_SRC_FILES += \
+ Exynos_OSAL_Android.cpp
+endif
+
+ifeq ($(BOARD_USE_ANB), true)
+LOCAL_CFLAGS += -DUSE_ANB
+
+ifeq ($(BOARD_USE_ANB_OUTBUF_SHARE), true)
+LOCAL_CFLAGS += -DUSE_ANB_OUTBUF_SHARE
+endif
+endif
+
+ifeq ($(BOARD_USE_DMA_BUF), true)
+LOCAL_CFLAGS += -DUSE_DMA_BUF
+endif
+
+ifeq ($(BOARD_USE_METADATABUFFERTYPE), true)
+LOCAL_CFLAGS += -DUSE_METADATABUFFERTYPE
+
+ifeq ($(BOARD_USE_STOREMETADATA), true)
+LOCAL_CFLAGS += -DUSE_STOREMETADATA
+endif
+
+ifeq ($(BOARD_USE_ANDROIDOPAQUE), true)
+LOCAL_CFLAGS += -DUSE_ANDROIDOPAQUE
+endif
+endif
+
+ifeq ($(BOARD_USE_IMPROVED_BUFFER), true)
+LOCAL_CFLAGS += -DUSE_IMPROVED_BUFFER
+endif
+
+ifeq ($(BOARD_USE_CSC_HW), true)
+LOCAL_CFLAGS += -DUSE_CSC_HW
+endif
+
+ifeq ($(BOARD_USE_NON_CACHED_GRAPHICBUFFER), true)
+LOCAL_CFLAGS += -DUSE_NON_CACHED_GRAPHICBUFFER
+endif
+
+ifeq ($(TARGET_BOARD_PLATFORM),exynos3)
+LOCAL_CFLAGS += -DUSE_MFC5X_ALIGNMENT
+endif
+
+ifeq ($(TARGET_BOARD_PLATFORM),exynos4)
+LOCAL_CFLAGS += -DUSE_MFC5X_ALIGNMENT
+endif
+
+LOCAL_SHARED_LIBRARIES := libhardware
+LOCAL_STATIC_LIBRARIES := liblog libcutils libExynosVideoApi
+
+LOCAL_C_INCLUDES := \
+ $(EXYNOS_OMX_TOP)/core \
+ $(EXYNOS_OMX_INC)/exynos \
+ $(EXYNOS_OMX_TOP)/osal \
+ $(EXYNOS_OMX_COMPONENT)/common \
+ $(EXYNOS_OMX_COMPONENT)/video/dec \
+ $(EXYNOS_OMX_COMPONENT)/video/enc \
+ $(EXYNOS_VIDEO_CODEC)/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_SOC)/include \
+ $(TOP)/hardware/samsung_slsi/$(TARGET_BOARD_PLATFORM)/include \
+ $(TOP)/hardware/samsung_slsi/exynos/include
+
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += \
+ $(ANDROID_MEDIA_INC)/hardware \
+ $(TOP)/system/core/libion/include
+endif
+
+ifeq ($(BOARD_USE_KHRONOS_OMX_HEADER), true)
+LOCAL_CFLAGS += -DUSE_KHRONOS_OMX_HEADER
+LOCAL_C_INCLUDES += $(EXYNOS_OMX_INC)/khronos
+else
+ifeq ($(BOARD_USE_ANDROID), true)
+LOCAL_C_INCLUDES += $(ANDROID_MEDIA_INC)/openmax
+endif
+endif
+
+include $(BUILD_STATIC_LIBRARY)
--- /dev/null
+/*
+ * 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_Android.cpp
+ * @brief
+ * @author Seungbeom Kim (sbcrux.kim@samsung.com)
+ * @author Hyeyeon Chung (hyeon.chung@samsung.com)
+ * @author Yunji Kim (yunji.kim@samsung.com)
+ * @author Jinsung Yang (jsgood.yang@samsung.com)
+ * @version 2.0.0
+ * @history
+ * 2012.02.20 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <system/window.h>
+#include <cutils/properties.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferMapper.h>
+#include <ui/Rect.h>
+#include <media/hardware/OMXPluginBase.h>
+#include <media/hardware/HardwareAPI.h>
+#include <hardware/hardware.h>
+#include <media/hardware/MetadataBufferType.h>
+#ifdef USE_DMA_BUF
+#include <gralloc_priv.h>
+#endif
+
+#include <ion/ion.h>
+#include "exynos_ion.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_Android.h"
+#include "Exynos_OSAL_ETC.h"
+#include "exynos_format.h"
+
+#include "ExynosVideoApi.h"
+
+#undef EXYNOS_LOG_TAG
+#define EXYNOS_LOG_TAG "Exynos_OSAL_Android"
+//#define EXYNOS_LOG_OFF
+#include "Exynos_OSAL_Log.h"
+
+using namespace android;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _EXYNOS_OMX_SHARED_BUFFER {
+ OMX_S32 bufferFd;
+ OMX_S32 bufferFd1;
+ OMX_S32 bufferFd2;
+
+ ion_user_handle_t ionHandle;
+ ion_user_handle_t ionHandle1;
+ ion_user_handle_t ionHandle2;
+
+ OMX_U32 cnt;
+} EXYNOS_OMX_SHARED_BUFFER;
+
+typedef struct _EXYNOS_OMX_REF_HANDLE {
+ OMX_HANDLETYPE hMutex;
+ OMX_PTR pGrallocModule;
+ EXYNOS_OMX_SHARED_BUFFER SharedBuffer[MAX_BUFFER_REF];
+} EXYNOS_OMX_REF_HANDLE;
+
+static int lockCnt = 0;
+
+int getIonFd(gralloc_module_t const *module)
+{
+ private_module_t* m = const_cast<private_module_t*>(reinterpret_cast<const private_module_t*>(module));
+ return m->ionfd;
+}
+
+OMX_ERRORTYPE setBufferProcessTypeForDecoder(EXYNOS_OMX_BASEPORT *pExynosPort)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ if (pExynosPort == NULL) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+#ifdef USE_ANB_OUTBUF_SHARE
+ if (pExynosPort->bufferProcessType & BUFFER_ANBSHARE) {
+ 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_INFO, "output buffer sharing mode is on (%x)", pExynosPort->portDefinition.format.video.eColorFormat);
+ } else
+#endif
+ if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+ if (pExynosPort->bStoreMetaData == OMX_TRUE) {
+ ret = OMX_ErrorUndefined;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: bufferProcessType is invalid", __FUNCTION__);
+ goto EXIT;
+ }
+
+ pExynosPort->bufferProcessType = BUFFER_COPY;
+ pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+ }
+
+EXIT:
+ return ret;
+}
+
+void resetBufferProcessTypeForDecoder(EXYNOS_OMX_BASEPORT *pExynosPort)
+{
+ int i;
+
+ if (pExynosPort == NULL)
+ return;
+
+ pExynosPort->bufferProcessType = (EXYNOS_OMX_BUFFERPROCESS_TYPE)(BUFFER_COPY | BUFFER_ANBSHARE);
+ pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+
+ return;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_LockANBHandle(
+ OMX_IN OMX_PTR handle,
+ OMX_IN OMX_U32 width,
+ OMX_IN OMX_U32 height,
+ OMX_IN OMX_COLOR_FORMATTYPE format,
+ OMX_OUT OMX_U32 *pStride,
+ OMX_OUT OMX_PTR planes)
+{
+ FunctionIn();
+
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+ buffer_handle_t bufferHandle = (buffer_handle_t) handle;
+#ifdef USE_DMA_BUF
+ private_handle_t *priv_hnd = (private_handle_t *) bufferHandle;
+#endif
+ Rect bounds((uint32_t)width, (uint32_t)height);
+ ExynosVideoPlane *vplanes = (ExynosVideoPlane *) planes;
+ void *vaddr[MAX_BUFFER_PLANE] = {NULL, };
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: handle: 0x%x, format = %x", __FUNCTION__, handle, priv_hnd->format);
+
+ int usage = 0;
+ switch ((int)format) {
+ case OMX_COLOR_FormatYUV420Planar:
+ case OMX_COLOR_FormatYUV420SemiPlanar:
+ case OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace:
+ case OMX_SEC_COLOR_Format10bitYUV420SemiPlanar:
+ case OMX_SEC_COLOR_FormatNV12Tiled:
+ usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
+ break;
+#ifdef USE_ANDROIDOPAQUE
+ case OMX_COLOR_FormatAndroidOpaque:
+ {
+ OMX_COLOR_FORMATTYPE formatType;
+ formatType = Exynos_OSAL_GetANBColorFormat(priv_hnd);
+ if ((formatType == OMX_COLOR_FormatYUV420SemiPlanar) ||
+ (formatType == (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled))
+ usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
+ else
+ usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_VIDEO_ENCODER;
+ }
+ break;
+#endif
+ default:
+ usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
+ break;
+ }
+
+ if (mapper.lock(bufferHandle, usage, bounds, vaddr) != 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: mapper.lock() fail", __func__);
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+ lockCnt++;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: lockCnt:%d", __func__, lockCnt);
+
+#ifdef USE_DMA_BUF
+ vplanes[0].fd = priv_hnd->fd;
+ vplanes[0].offset = 0;
+ vplanes[1].fd = priv_hnd->fd1;
+ vplanes[1].offset = 0;
+ vplanes[2].fd = priv_hnd->fd2;
+ vplanes[2].offset = 0;
+#endif
+
+ if (priv_hnd->flags & GRALLOC_USAGE_PROTECTED) {
+ /* in case of DRM, vaddrs are invalid */
+ vplanes[0].addr = INT_TO_PTR(priv_hnd->fd);
+ vplanes[1].addr = INT_TO_PTR(priv_hnd->fd1);
+ vplanes[2].addr = INT_TO_PTR(priv_hnd->fd2);
+ } else {
+ vplanes[0].addr = vaddr[0];
+ vplanes[1].addr = vaddr[1];
+ vplanes[2].addr = vaddr[2];
+ }
+
+ if ((priv_hnd->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV) &&
+ (vaddr[2] != NULL))
+ vplanes[2].addr = vaddr[2];
+
+ *pStride = (OMX_U32)priv_hnd->stride;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: buffer locked: 0x%x", __func__, *vaddr);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_UnlockANBHandle(OMX_IN OMX_PTR handle)
+{
+ FunctionIn();
+
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+ buffer_handle_t bufferHandle = (buffer_handle_t) handle;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: handle: 0x%x", __func__, handle);
+
+ if (mapper.unlock(bufferHandle) != 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: mapper.unlock() fail", __func__);
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+ lockCnt--;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: lockCnt:%d", __func__, lockCnt);
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: buffer unlocked: 0x%x", __func__, handle);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_COLOR_FORMATTYPE Exynos_OSAL_GetANBColorFormat(OMX_IN OMX_PTR handle)
+{
+ FunctionIn();
+
+ OMX_COLOR_FORMATTYPE ret = OMX_COLOR_FormatUnused;
+ private_handle_t *priv_hnd = (private_handle_t *) handle;
+
+ ret = Exynos_OSAL_HAL2OMXColorFormat(priv_hnd->format);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ColorFormat: 0x%x", ret);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_LockMetaData(
+ OMX_IN OMX_PTR pBuffer,
+ OMX_IN OMX_U32 width,
+ OMX_IN OMX_U32 height,
+ OMX_IN OMX_COLOR_FORMATTYPE format,
+ OMX_OUT OMX_U32 *pStride,
+ OMX_OUT OMX_PTR planes)
+{
+ FunctionIn();
+
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ OMX_PTR pBuf = NULL;
+
+ ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pBuffer, &pBuf);
+ if (ret == OMX_ErrorNone)
+ ret = Exynos_OSAL_LockANBHandle(pBuf, width, height, format, pStride, planes);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_UnlockMetaData(OMX_IN OMX_PTR pBuffer)
+{
+ FunctionIn();
+
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ OMX_PTR pBuf = NULL;
+
+ ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)pBuffer, &pBuf);
+ if (ret == OMX_ErrorNone)
+ ret = Exynos_OSAL_UnlockANBHandle(pBuf);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_HANDLETYPE Exynos_OSAL_RefANB_Create()
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_REF_HANDLE *phREF = NULL;
+ gralloc_module_t *module = NULL;
+
+ int i = 0;
+
+ FunctionIn();
+
+ phREF = (EXYNOS_OMX_REF_HANDLE *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_REF_HANDLE));
+ if (phREF == NULL)
+ goto EXIT;
+
+ Exynos_OSAL_Memset(phREF, 0, sizeof(EXYNOS_OMX_REF_HANDLE));
+ for (i = 0; i < MAX_BUFFER_REF; i++) {
+ phREF->SharedBuffer[i].bufferFd = -1;
+ phREF->SharedBuffer[i].bufferFd1 = -1;
+ phREF->SharedBuffer[i].bufferFd2 = -1;
+ }
+ if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&module) != 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: hw_get_module(GRALLOC_HARDWARE_MODULE_ID) fail", __func__);
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ phREF->pGrallocModule = (OMX_PTR)module;
+
+ ret = Exynos_OSAL_MutexCreate(&phREF->hMutex);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Free(phREF);
+ phREF = NULL;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ((OMX_HANDLETYPE)phREF);
+}
+
+OMX_ERRORTYPE Exynos_OSAL_RefANB_Reset(OMX_HANDLETYPE hREF)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
+ gralloc_module_t *module = NULL;
+
+ int i = 0;
+
+ FunctionIn();
+
+ if (phREF == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ module = (gralloc_module_t *)phREF->pGrallocModule;
+
+ Exynos_OSAL_MutexLock(phREF->hMutex);
+
+ for (i = 0; i < MAX_BUFFER_REF; i++) {
+ if (phREF->SharedBuffer[i].bufferFd > -1) {
+ while(phREF->SharedBuffer[i].cnt > 0) {
+ if (phREF->SharedBuffer[i].ionHandle != -1)
+ ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle);
+ if (phREF->SharedBuffer[i].ionHandle1 != -1)
+ ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle1);
+ if (phREF->SharedBuffer[i].ionHandle2 != -1)
+ ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle2);
+ phREF->SharedBuffer[i].cnt--;
+ }
+ phREF->SharedBuffer[i].bufferFd = -1;
+ phREF->SharedBuffer[i].bufferFd1 = -1;
+ phREF->SharedBuffer[i].bufferFd2 = -1;
+ phREF->SharedBuffer[i].ionHandle = -1;
+ phREF->SharedBuffer[i].ionHandle1 = -1;
+ phREF->SharedBuffer[i].ionHandle2 = -1;
+ }
+ }
+ Exynos_OSAL_MutexUnlock(phREF->hMutex);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_RefANB_Terminate(OMX_HANDLETYPE hREF)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
+
+ FunctionIn();
+
+ if (phREF == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_RefANB_Reset(phREF);
+
+ phREF->pGrallocModule = NULL;
+
+ ret = Exynos_OSAL_MutexTerminate(phREF->hMutex);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ Exynos_OSAL_Free(phREF);
+ phREF = NULL;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_RefANB_Increase(
+ OMX_HANDLETYPE hREF,
+ OMX_PTR pBuffer,
+ PLANE_TYPE ePlaneType)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
+ OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatUnused;
+
+ buffer_handle_t bufferHandle = (buffer_handle_t)pBuffer;
+ private_handle_t *priv_hnd = (private_handle_t *)bufferHandle;
+ gralloc_module_t *module = NULL;
+
+ ion_user_handle_t ionHandle = -1;
+ ion_user_handle_t ionHandle1 = -1;
+ ion_user_handle_t ionHandle2 = -1;
+ int i, nPlaneCnt;
+
+ FunctionIn();
+
+ if (phREF == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ eColorFormat = Exynos_OSAL_HAL2OMXColorFormat(priv_hnd->format);
+ if (eColorFormat == OMX_COLOR_FormatUnused) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+
+ nPlaneCnt = Exynos_OSAL_GetPlaneCount(eColorFormat, ePlaneType);
+ module = (gralloc_module_t *)phREF->pGrallocModule;
+
+ Exynos_OSAL_MutexLock(phREF->hMutex);
+
+ if ((priv_hnd->fd >= 0) &&
+ (nPlaneCnt >= 1)) {
+ if (ion_import(getIonFd(module), priv_hnd->fd, &ionHandle) < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_import is failed(client:%d, fd:%d)", getIonFd(module), priv_hnd->fd);
+ ionHandle = -1;
+ }
+ }
+
+ if ((priv_hnd->fd1 >= 0) &&
+ (nPlaneCnt >= 2)) {
+ if (ion_import(getIonFd(module), priv_hnd->fd1, &ionHandle1) < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_import is failed(client:%d, fd1:%d)", getIonFd(module), priv_hnd->fd1);
+ ionHandle1 = -1;
+ }
+ }
+
+ if ((priv_hnd->fd2 >= 0) &&
+ (nPlaneCnt == 3)) {
+ if (ion_import(getIonFd(module), priv_hnd->fd2, &ionHandle2) < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_import is failed(client:%d, fd2:%d)", getIonFd(module), priv_hnd->fd2);
+ ionHandle2 = -1;
+ }
+ }
+
+ for (i = 0; i < MAX_BUFFER_REF; i++) {
+ if (phREF->SharedBuffer[i].bufferFd == priv_hnd->fd) {
+ phREF->SharedBuffer[i].cnt++;
+ break;
+ }
+ }
+
+ if (i >= MAX_BUFFER_REF) {
+ for (i = 0; i < MAX_BUFFER_REF; i++) {
+ if (phREF->SharedBuffer[i].bufferFd == -1) {
+ phREF->SharedBuffer[i].bufferFd = priv_hnd->fd;
+ phREF->SharedBuffer[i].bufferFd1 = priv_hnd->fd1;
+ phREF->SharedBuffer[i].bufferFd2 = priv_hnd->fd2;
+ phREF->SharedBuffer[i].ionHandle = ionHandle;
+ phREF->SharedBuffer[i].ionHandle1 = ionHandle1;
+ phREF->SharedBuffer[i].ionHandle2 = ionHandle2;
+ phREF->SharedBuffer[i].cnt++;
+ break;
+ }
+ }
+ }
+
+ if (i >= MAX_BUFFER_REF) {
+ ret = OMX_ErrorUndefined;
+ Exynos_OSAL_MutexUnlock(phREF->hMutex);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "inc fd:%d cnt:%d", phREF->SharedBuffer[i].bufferFd, phREF->SharedBuffer[i].cnt);
+ Exynos_OSAL_MutexUnlock(phREF->hMutex);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_RefANB_Decrease(OMX_HANDLETYPE hREF, OMX_S32 bufferFd)
+{
+
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_REF_HANDLE *phREF = (EXYNOS_OMX_REF_HANDLE *)hREF;
+ gralloc_module_t *module = NULL;
+
+ int i;
+
+ FunctionIn();
+
+ if ((phREF == NULL) || (bufferFd < 0)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ module = (gralloc_module_t *)phREF->pGrallocModule;
+
+ Exynos_OSAL_MutexLock(phREF->hMutex);
+
+ for (i = 0; i < MAX_BUFFER_REF; i++) {
+ if (phREF->SharedBuffer[i].bufferFd == bufferFd) {
+ if (phREF->SharedBuffer[i].ionHandle != -1)
+ ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle);
+ if (phREF->SharedBuffer[i].ionHandle1 != -1)
+ ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle1);
+ if (phREF->SharedBuffer[i].ionHandle2 != -1)
+ ion_free(getIonFd(module), phREF->SharedBuffer[i].ionHandle2);
+ phREF->SharedBuffer[i].cnt--;
+
+ if (phREF->SharedBuffer[i].cnt == 0) {
+ phREF->SharedBuffer[i].bufferFd = -1;
+ phREF->SharedBuffer[i].bufferFd1 = -1;
+ phREF->SharedBuffer[i].bufferFd2 = -1;
+ phREF->SharedBuffer[i].ionHandle = -1;
+ phREF->SharedBuffer[i].ionHandle1 = -1;
+ phREF->SharedBuffer[i].ionHandle2 = -1;
+ }
+ break;
+ }
+ }
+
+ if (i >= MAX_BUFFER_REF) {
+ ret = OMX_ErrorUndefined;
+ Exynos_OSAL_MutexUnlock(phREF->hMutex);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "dec fd:%d cnt:%d", phREF->SharedBuffer[i].bufferFd, phREF->SharedBuffer[i].cnt);
+ Exynos_OSAL_MutexUnlock(phREF->hMutex);
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE useAndroidNativeBuffer(
+ EXYNOS_OMX_BASEPORT *pExynosPort,
+ OMX_BUFFERHEADERTYPE **ppBufferHdr,
+ OMX_U32 nPortIndex,
+ OMX_PTR pAppPrivate,
+ OMX_U32 nSizeBytes,
+ OMX_U8 *pBuffer)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL;
+ unsigned int i = 0;
+ OMX_U32 width, height;
+ OMX_U32 stride;
+ ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+
+ FunctionIn();
+
+ if (pExynosPort == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosPort->portState != OMX_StateIdle) {
+ 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) {
+ 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);
+ if (pExynosPort->eANBType == NATIVE_GRAPHIC_BUFFER1) {
+ android_native_buffer_t *pANB = (android_native_buffer_t *)pBuffer;
+ temp_bufferHeader->pBuffer = (OMX_U8 *)pANB->handle;
+ } else {
+ temp_bufferHeader->pBuffer = (OMX_U8 *)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;
+
+ width = pExynosPort->portDefinition.format.video.nFrameWidth;
+ height = pExynosPort->portDefinition.format.video.nFrameHeight;
+ Exynos_OSAL_LockANBHandle(temp_bufferHeader->pBuffer, width, height,
+ pExynosPort->portDefinition.format.video.eColorFormat,
+ &stride, planes);
+#ifdef USE_DMA_BUF
+ pExynosPort->extendBufferHeader[i].buf_fd[0] = planes[0].fd;
+ pExynosPort->extendBufferHeader[i].buf_fd[1] = planes[1].fd;
+ pExynosPort->extendBufferHeader[i].buf_fd[2] = planes[2].fd;
+#endif
+ pExynosPort->extendBufferHeader[i].pYUVBuf[0] = planes[0].addr;
+ pExynosPort->extendBufferHeader[i].pYUVBuf[1] = planes[1].addr;
+ pExynosPort->extendBufferHeader[i].pYUVBuf[2] = planes[2].addr;
+ Exynos_OSAL_UnlockANBHandle(temp_bufferHeader->pBuffer);
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "useAndroidNativeBuffer: buf %d pYUVBuf[0]:0x%x , pYUVBuf[1]:0x%x ",
+ i, pExynosPort->extendBufferHeader[i].pYUVBuf[0],
+ pExynosPort->extendBufferHeader[i].pYUVBuf[1]);
+
+ pExynosPort->assignedBufferNum++;
+ if (pExynosPort->assignedBufferNum == (OMX_S32)pExynosPort->portDefinition.nBufferCountActual) {
+ pExynosPort->portDefinition.bPopulated = OMX_TRUE;
+ /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
+ Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
+ /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
+ }
+ *ppBufferHdr = temp_bufferHeader;
+ ret = OMX_ErrorNone;
+
+ goto EXIT;
+ }
+ }
+
+ Exynos_OSAL_Free(temp_bufferHeader);
+ ret = OMX_ErrorInsufficientResources;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_GetAndroidParameter(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_INOUT OMX_PTR ComponentParameterStructure)
+{
+ 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 (ComponentParameterStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+#ifdef USE_ANB
+ case OMX_IndexParamGetAndroidNativeBuffer:
+ {
+ GetAndroidNativeBufferUsageParams *pANBParams = (GetAndroidNativeBufferUsageParams *) ComponentParameterStructure;
+ OMX_U32 portIndex = pANBParams->nPortIndex;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamGetAndroidNativeBuffer", __func__);
+
+ ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(GetAndroidNativeBufferUsageParams));
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(GetAndroidNativeBufferUsageParams) is failed", __func__);
+ goto EXIT;
+ }
+
+ if (portIndex >= pExynosComponent->portParam.nPorts) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ /* NOTE: OMX_IndexParamGetAndroidNativeBuffer returns original 'nUsage' without any
+ * modifications since currently not defined what the 'nUsage' is for.
+ */
+ pANBParams->nUsage |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
+#if defined(USE_IMPROVED_BUFFER) && !defined(USE_CSC_HW) && !defined(USE_NON_CACHED_GRAPHICBUFFER)
+ pANBParams->nUsage |= (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+#endif
+#if defined(USE_MFC5X_ALIGNMENT)
+ if ((pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferProcessType & BUFFER_SHARE) &&
+ (pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)) {
+ pANBParams->nUsage |= GRALLOC_USAGE_PRIVATE_0;
+ }
+#endif
+ if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC) { // secure decoder component
+ /* never knows actual image size before parsing a header info
+ * could not guarantee DRC(Dynamic Resolution Chnage) case */
+ EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ unsigned int HD_SIZE = 1280 * 720 * 3 / 2; /* 720p */
+
+ if ((pExynosPort->portDefinition.format.video.nFrameWidth *
+ pExynosPort->portDefinition.format.video.nFrameHeight * 3 / 2) > HD_SIZE) { /* over than 720p */
+ pANBParams->nUsage |= GRALLOC_USAGE_PROTECTED_DPB; /* try to use a CMA area */
+ }
+ }
+ }
+ break;
+ case OMX_IndexParamConsumerUsageBits:
+ {
+ OMX_U32 *pUsageBits = (OMX_U32 *)ComponentParameterStructure;
+
+ switch ((int)pExynosComponent->codecType) {
+ case HW_VIDEO_ENC_CODEC:
+ (*pUsageBits) = GRALLOC_USAGE_HW_VIDEO_ENCODER;
+ break;
+ case HW_VIDEO_ENC_SECURE_CODEC:
+ (*pUsageBits) = GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_PROTECTED;
+ break;
+ default:
+ (*pUsageBits) = 0;
+ ret = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ }
+ break;
+#endif
+ default:
+ {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex);
+ ret = OMX_ErrorUnsupportedIndex;
+ goto EXIT;
+ }
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SetAndroidParameter(
+ 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;
+
+ 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 (ComponentParameterStructure == NULL) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ switch ((int)nIndex) {
+#ifdef USE_ANB
+ case OMX_IndexParamEnableAndroidBuffers:
+ {
+ EnableAndroidNativeBuffersParams *pANBParams = (EnableAndroidNativeBuffersParams *) ComponentParameterStructure;
+ OMX_U32 portIndex = pANBParams->nPortIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamEnableAndroidNativeBuffers", __func__);
+
+ ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(EnableAndroidNativeBuffersParams));
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(EnableAndroidNativeBuffersParams) is failed", __func__);
+ goto EXIT;
+ }
+
+ if (portIndex >= pExynosComponent->portParam.nPorts) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+ if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if (pExynosPort->bStoreMetaData != OMX_TRUE) {
+ if (portIndex == OUTPUT_PORT_INDEX) {
+ if (pANBParams->enable == OMX_TRUE) {
+ ret = setBufferProcessTypeForDecoder(pExynosPort);
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+ } else if ((pANBParams->enable == OMX_FALSE) &&
+ (pExynosPort->bIsANBEnabled == OMX_TRUE)) {
+ /* reset to initialized value */
+ resetBufferProcessTypeForDecoder(pExynosPort);
+ }
+ }
+
+ pExynosPort->bIsANBEnabled = pANBParams->enable;
+ }
+ }
+ break;
+
+ case OMX_IndexParamUseAndroidNativeBuffer:
+ {
+ UseAndroidNativeBufferParams *pANBParams = (UseAndroidNativeBufferParams *) ComponentParameterStructure;
+ OMX_U32 portIndex = pANBParams->nPortIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+ android_native_buffer_t *pANB;
+ OMX_U32 nSizeBytes;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamUseAndroidNativeBuffer, portIndex: %d", __func__, portIndex);
+
+ ret = Exynos_OMX_Check_SizeVersion(pANBParams, sizeof(UseAndroidNativeBufferParams));
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(UseAndroidNativeBufferParams) is failed", __func__);
+ goto EXIT;
+ }
+
+ if (portIndex >= pExynosComponent->portParam.nPorts) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+ if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if (pExynosPort->portState != OMX_StateIdle) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Port state should be IDLE", __func__);
+ ret = OMX_ErrorIncorrectStateOperation;
+ goto EXIT;
+ }
+
+ pANB = pANBParams->nativeBuffer.get();
+
+ /* MALI alignment restriction */
+ nSizeBytes = ALIGN(pANB->width, 16) * ALIGN(pANB->height, 16);
+ nSizeBytes += ALIGN(pANB->width / 2, 16) * ALIGN(pANB->height / 2, 16) * 2;
+
+ ret = useAndroidNativeBuffer(pExynosPort,
+ pANBParams->bufferHeader,
+ pANBParams->nPortIndex,
+ pANBParams->pAppPrivate,
+ nSizeBytes,
+ (OMX_U8 *) pANB);
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: useAndroidNativeBuffer is failed: err=0x%x", __func__,ret);
+ goto EXIT;
+ }
+ }
+ break;
+#endif
+
+#ifdef USE_STOREMETADATA
+ case OMX_IndexParamStoreMetaDataBuffer:
+ {
+ StoreMetaDataInBuffersParams *pMetaParams = (StoreMetaDataInBuffersParams *)ComponentParameterStructure;
+ OMX_U32 portIndex = pMetaParams->nPortIndex;
+ EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: OMX_IndexParamStoreMetaDataBuffer", __func__);
+
+ ret = Exynos_OMX_Check_SizeVersion(pMetaParams, sizeof(StoreMetaDataInBuffersParams));
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(StoreMetaDataInBuffersParams) is failed", __func__);
+ goto EXIT;
+ }
+
+ if (portIndex >= pExynosComponent->portParam.nPorts) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) ||
+ (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)) {
+ EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+ if ((portIndex == INPUT_PORT_INDEX) ||
+ (pOutputPort->bDynamicDPBMode == OMX_FALSE)) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+ }
+
+ pExynosPort = &pExynosComponent->pExynosPort[portIndex];
+ if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if (((pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) ||
+ (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)) &&
+ (portIndex == OUTPUT_PORT_INDEX)) {
+ if (pMetaParams->bStoreMetaData == OMX_TRUE) {
+ pExynosPort->bStoreMetaData = pMetaParams->bStoreMetaData;
+ ret = setBufferProcessTypeForDecoder(pExynosPort);
+ } else if ((pMetaParams->bStoreMetaData == OMX_FALSE) &&
+ (pExynosPort->bStoreMetaData == OMX_TRUE)) {
+ /* reset to initialized value */
+ resetBufferProcessTypeForDecoder(pExynosPort);
+ }
+ }
+
+ pExynosPort->bStoreMetaData = pMetaParams->bStoreMetaData;
+ }
+ break;
+#endif
+
+ default:
+ {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Unsupported index (%d)", __func__, nIndex);
+ ret = OMX_ErrorUnsupportedIndex;
+ goto EXIT;
+ }
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(OMX_IN OMX_BYTE pBuffer,
+ OMX_OUT OMX_PTR *ppBuf)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ MetadataBufferType type;
+
+ FunctionIn();
+
+/*
+ * meta data contains the following data format.
+ * payload depends on the MetadataBufferType
+ * ---------------------------------------------------------------
+ * | MetadataBufferType | payload |
+ * ---------------------------------------------------------------
+ *
+ * If MetadataBufferType is kMetadataBufferTypeCameraSource, then
+ * ---------------------------------------------------------------
+ * | kMetadataBufferTypeCameraSource | addr. of Y | addr. of UV |
+ * ---------------------------------------------------------------
+ *
+ * If MetadataBufferType is kMetadataBufferTypeGrallocSource, then
+ * ---------------------------------------------------------------
+ * | kMetadataBufferTypeGrallocSource | buffer_handle_t |
+ * ---------------------------------------------------------------
+ */
+
+ /* MetadataBufferType */
+ Exynos_OSAL_Memcpy(&type, (MetadataBufferType *)pBuffer, sizeof(MetadataBufferType));
+
+ switch ((int)type) {
+ case kMetadataBufferTypeCameraSource:
+ {
+ void *pAddress = NULL;
+
+ /* Address. of Y */
+ Exynos_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType), sizeof(void *));
+ ppBuf[0] = (void *)pAddress;
+
+ /* Address. of CbCr */
+ Exynos_OSAL_Memcpy(&pAddress, pBuffer + sizeof(MetadataBufferType) + sizeof(void *), sizeof(void *));
+ ppBuf[1] = (void *)pAddress;
+
+ if ((ppBuf[0] == NULL) || (ppBuf[1] == NULL))
+ ret = OMX_ErrorBadParameter;
+ }
+ break;
+ case kMetadataBufferTypeGrallocSource:
+ {
+ buffer_handle_t pBufHandle;
+
+ /* buffer_handle_t */
+ Exynos_OSAL_Memcpy(&pBufHandle, pBuffer + sizeof(MetadataBufferType), sizeof(buffer_handle_t));
+ ppBuf[0] = (OMX_PTR)pBufHandle;
+
+ if (ppBuf[0] == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "GrallocBuffer's pHandle is NULL");
+ ret = OMX_ErrorBadParameter;
+ }
+ }
+ break;
+ default:
+ {
+ ret = OMX_ErrorBadParameter;
+ }
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_GetBufferFdFromMetaData(
+ OMX_IN OMX_BYTE pBuffer,
+ OMX_OUT OMX_PTR *ppBuf)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ MetadataBufferType type = kMetadataBufferTypeInvalid;
+
+ FunctionIn();
+
+ /* MetadataBufferType */
+ Exynos_OSAL_Memcpy(&type, (MetadataBufferType *)pBuffer, sizeof(MetadataBufferType));
+
+ switch ((int)type) {
+ case kMetadataBufferTypeCameraSource:
+ {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Unsupport Type of MetadataBuffer", __FUNCTION__, __LINE__);
+ }
+ break;
+ case kMetadataBufferTypeGrallocSource:
+ {
+ VideoGrallocMetadata *pMetaData = (VideoGrallocMetadata *)pBuffer;
+ buffer_handle_t bufferHandle = (buffer_handle_t)pMetaData->pHandle;
+ native_handle_t *pNativeHandle = (native_handle_t *)bufferHandle;
+
+ /* ION FD. */
+ ppBuf[0] = INT_TO_PTR(pNativeHandle->data[0]);
+ }
+ break;
+ default:
+ {
+ ret = OMX_ErrorBadParameter;
+ }
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SetDataLengthToMetaData(
+ OMX_IN OMX_BYTE pBuffer,
+ OMX_IN OMX_U32 dataLength)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ MetadataBufferType type = kMetadataBufferTypeInvalid;
+
+ FunctionIn();
+
+ /* MetadataBufferType */
+ Exynos_OSAL_Memcpy(&type, (MetadataBufferType *)pBuffer, sizeof(MetadataBufferType));
+
+ switch ((int)type) {
+ case kMetadataBufferTypeCameraSource:
+ {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Unsupport Type of MetadataBuffer", __FUNCTION__, __LINE__);
+ }
+ break;
+ case kMetadataBufferTypeGrallocSource:
+ {
+ VideoGrallocMetadata *pMetaData = (VideoGrallocMetadata *)pBuffer;
+ buffer_handle_t bufferHandle = (buffer_handle_t)pMetaData->pHandle;
+ native_handle_t *pNativeHandle = (native_handle_t *)bufferHandle;
+
+ /* size of stream */
+ pNativeHandle->data[3] = dataLength;
+ }
+ break;
+ default:
+ {
+ ret = OMX_ErrorBadParameter;
+ }
+ break;
+ }
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_PTR Exynos_OSAL_AllocMetaDataBuffer(
+ OMX_HANDLETYPE hSharedMemory,
+ EXYNOS_CODEC_TYPE codecType,
+ OMX_U32 nPortIndex,
+ OMX_U32 nSizeBytes,
+ MEMORY_TYPE eMemoryType)
+{
+ /*
+ * meta data contains the following data format.
+ * payload depends on the MetadataBufferType
+ * ---------------------------------------------------------------
+ * | MetadataBufferType | payload |
+ * ---------------------------------------------------------------
+ * If MetadataBufferType is kMetadataBufferTypeGrallocSource, then
+ * ---------------------------------------------------------------
+ * | kMetadataBufferTypeGrallocSource | buffer_handle_t |
+ * ---------------------------------------------------------------
+ */
+
+#define ENC_OUT_FD_NUM 1
+#define EXTRA_DATA_NUM 3
+
+ VideoGrallocMetadata *pMetaData = NULL;
+ buffer_handle_t bufferHandle = NULL;
+ native_handle_t *pNativeHandle = NULL;
+
+ OMX_PTR pTempBuffer = NULL;
+ OMX_PTR pTempVirAdd = NULL;
+ OMX_U32 nTempFD = 0;
+
+ if (((codecType == HW_VIDEO_ENC_CODEC) ||
+ (codecType == HW_VIDEO_ENC_SECURE_CODEC)) &&
+ (nPortIndex == OUTPUT_PORT_INDEX)) {
+ pTempBuffer = Exynos_OSAL_Malloc(MAX_METADATA_BUFFER_SIZE);
+ if (pTempBuffer == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Error InsufficientResources", __FUNCTION__, __LINE__);
+ goto EXIT;
+ }
+
+ pNativeHandle = native_handle_create(ENC_OUT_FD_NUM, EXTRA_DATA_NUM);
+ if (pNativeHandle == NULL) {
+ Exynos_OSAL_Free(pTempBuffer);
+ pTempBuffer = NULL;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Error InsufficientResources", __FUNCTION__, __LINE__);
+ goto EXIT;
+ }
+
+ pTempVirAdd = Exynos_OSAL_SharedMemory_Alloc(hSharedMemory, nSizeBytes, eMemoryType);
+ if (pTempVirAdd == NULL) {
+ native_handle_delete(pNativeHandle);
+ pNativeHandle = NULL;
+ Exynos_OSAL_Free(pTempBuffer);
+ pTempBuffer = NULL;
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Error InsufficientResources", __FUNCTION__, __LINE__);
+ goto EXIT;
+ }
+
+ nTempFD = Exynos_OSAL_SharedMemory_VirtToION(hSharedMemory, pTempVirAdd);
+
+ pNativeHandle->data[0] = (int)nTempFD;
+ pNativeHandle->data[1] = PTR_TO_INT(pTempVirAdd); /* caution : data loss & FIXME : remove */
+ pNativeHandle->data[2] = (int)nSizeBytes;
+ pNativeHandle->data[3] = (int)0;
+
+ pMetaData = (VideoGrallocMetadata *)pTempBuffer;
+ bufferHandle = (buffer_handle_t)pNativeHandle;
+
+ pMetaData->eType = kMetadataBufferTypeGrallocSource;
+ pMetaData->pHandle = bufferHandle;
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Unsupport MetadataBuffer", __FUNCTION__, __LINE__);
+ pTempBuffer = NULL;
+ }
+
+EXIT:
+ return pTempBuffer;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_FreeMetaDataBuffer(
+ OMX_HANDLETYPE hSharedMemory,
+ EXYNOS_CODEC_TYPE codecType,
+ OMX_U32 nPortIndex,
+ OMX_PTR pTempBuffer)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ OMX_U32 nTempFD = 0;
+ OMX_PTR pTempVirAdd = NULL;
+
+ VideoGrallocMetadata *pMetaData = NULL;
+ buffer_handle_t bufferHandle = NULL;
+ native_handle_t *pNativeHandle = NULL;
+
+ if (((codecType == HW_VIDEO_ENC_CODEC) ||
+ (codecType == HW_VIDEO_ENC_SECURE_CODEC)) &&
+ (nPortIndex == OUTPUT_PORT_INDEX)) {
+ if (*(MetadataBufferType *)(pTempBuffer) != (MetadataBufferType)kMetadataBufferTypeGrallocSource) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Invalid MetaDataBuffer", __FUNCTION__, __LINE__);
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pMetaData = (VideoGrallocMetadata *)pTempBuffer;
+ bufferHandle = (buffer_handle_t)pMetaData->pHandle;
+ pNativeHandle = (native_handle_t *)bufferHandle;
+
+ nTempFD = (OMX_U32)pNativeHandle->data[0];
+ pTempVirAdd = Exynos_OSAL_SharedMemory_IONToVirt(hSharedMemory, nTempFD);
+
+ Exynos_OSAL_SharedMemory_Free(hSharedMemory, pTempVirAdd);
+
+ native_handle_delete(pNativeHandle);
+
+ Exynos_OSAL_Free(pTempBuffer);
+
+ ret = OMX_ErrorNone;
+ } else {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d - Unsupport MetadataBuffer", __FUNCTION__, __LINE__);
+ ret = OMX_ErrorNotImplemented;
+ }
+
+EXIT:
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_SetPrependSPSPPSToIDR(
+ OMX_PTR pComponentParameterStructure,
+ OMX_PTR pbPrependSpsPpsToIdr)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ PrependSPSPPSToIDRFramesParams *pParams = (PrependSPSPPSToIDRFramesParams *)pComponentParameterStructure;
+
+ ret = Exynos_OMX_Check_SizeVersion(pParams, sizeof(PrependSPSPPSToIDRFramesParams));
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OMX_Check_SizeVersion(PrependSPSPPSToIDRFramesParams) is failed", __func__);
+ goto EXIT;
+ }
+
+ (*((OMX_BOOL *)pbPrependSpsPpsToIdr)) = pParams->bEnable;
+
+EXIT:
+ return ret;
+}
+
+OMX_U32 Exynos_OSAL_GetDisplayExtraBufferCount(void)
+{
+ char value[PROPERTY_VALUE_MAX] = {0, };
+
+ if (property_get("debug.hwc.otf", value, NULL)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "DisplayExtraBufferCount is 3. The OTF exist");
+ return 3; /* Display System has OTF */
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "DisplayExtraBufferCount is 2. The OTF not exist");
+ return 2; /* min count */
+}
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*
+ * 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_Android.h
+ * @brief
+ * @author Seungbeom Kim (sbcrux.kim@samsung.com)
+ * @author Hyeyeon Chung (hyeon.chung@samsung.com)
+ * @author Yunji Kim (yunji.kim@samsung.com)
+ * @author Jinsung Yang (jsgood.yang@samsung.com)
+ * @version 2.0.0
+ * @history
+ * 2012.02.20 : Create
+ */
+
+#ifndef Exynos_OSAL_ANDROID
+#define Exynos_OSAL_ANDROID
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+#include "OMX_Index.h"
+#include "Exynos_OSAL_SharedMemory.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OMX_ERRORTYPE Exynos_OSAL_GetAndroidParameter(OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_INOUT OMX_PTR ComponentParameterStructure);
+
+OMX_ERRORTYPE Exynos_OSAL_SetAndroidParameter(OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_IN OMX_PTR ComponentParameterStructure);
+
+OMX_COLOR_FORMATTYPE Exynos_OSAL_GetANBColorFormat(OMX_IN OMX_PTR handle);
+
+OMX_ERRORTYPE Exynos_OSAL_LockMetaData(OMX_IN OMX_PTR pBuffer,
+ OMX_IN OMX_U32 width,
+ OMX_IN OMX_U32 height,
+ OMX_IN OMX_COLOR_FORMATTYPE format,
+ OMX_OUT OMX_U32 *pStride,
+ OMX_OUT OMX_PTR planes);
+
+OMX_ERRORTYPE Exynos_OSAL_UnlockMetaData(OMX_IN OMX_PTR pBuffer);
+
+OMX_ERRORTYPE Exynos_OSAL_LockANBHandle(OMX_IN OMX_PTR pBuffer,
+ OMX_IN OMX_U32 width,
+ OMX_IN OMX_U32 height,
+ OMX_IN OMX_COLOR_FORMATTYPE format,
+ OMX_OUT OMX_U32 *pStride,
+ OMX_OUT OMX_PTR planes);
+
+OMX_HANDLETYPE Exynos_OSAL_RefANB_Create();
+OMX_ERRORTYPE Exynos_OSAL_RefANB_Reset(OMX_HANDLETYPE hREF);
+OMX_ERRORTYPE Exynos_OSAL_RefANB_Terminate(OMX_HANDLETYPE hREF);
+OMX_ERRORTYPE Exynos_OSAL_RefANB_Increase(OMX_HANDLETYPE hREF, OMX_PTR pBuffer, PLANE_TYPE ePlaneType);
+OMX_ERRORTYPE Exynos_OSAL_RefANB_Decrease(OMX_HANDLETYPE hREF, OMX_S32 bufferFd);
+
+OMX_ERRORTYPE Exynos_OSAL_UnlockANBHandle(OMX_IN OMX_PTR pBuffer);
+
+OMX_ERRORTYPE Exynos_OSAL_GetInfoFromMetaData(OMX_IN OMX_BYTE pBuffer,
+ OMX_OUT OMX_PTR *pOutBuffer);
+OMX_ERRORTYPE Exynos_OSAL_GetBufferFdFromMetaData(OMX_IN OMX_BYTE pBuffer, OMX_OUT OMX_PTR *pOutBuffer);
+
+OMX_PTR Exynos_OSAL_AllocMetaDataBuffer(OMX_HANDLETYPE hSharedMemory, EXYNOS_CODEC_TYPE codecType, OMX_U32 nPortIndex, OMX_U32 nSizeBytes, MEMORY_TYPE eMemoryType);
+OMX_ERRORTYPE Exynos_OSAL_FreeMetaDataBuffer(OMX_HANDLETYPE hSharedMemory, EXYNOS_CODEC_TYPE codecType, OMX_U32 nPortIndex, OMX_PTR pTempBuffer);
+OMX_ERRORTYPE Exynos_OSAL_SetDataLengthToMetaData(OMX_IN OMX_BYTE pBuffer, OMX_IN OMX_U32 dataLength);
+
+OMX_ERRORTYPE Exynos_OSAL_CheckANB(OMX_IN EXYNOS_OMX_DATA *pBuffer,
+ OMX_OUT OMX_BOOL *bIsANBEnabled);
+
+OMX_ERRORTYPE Exynos_OSAL_SetPrependSPSPPSToIDR(OMX_PTR pComponentParameterStructure,
+ OMX_PTR pbPrependSpsPpsToIdr);
+
+OMX_ERRORTYPE Exynos_OSAL_SetAndroidParameter(OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_INDEXTYPE nIndex, OMX_IN OMX_PTR ComponentParameterStructure);
+
+OMX_ERRORTYPE useAndroidNativeBuffer(EXYNOS_OMX_BASEPORT *pExynosPort, OMX_BUFFERHEADERTYPE **ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, OMX_U32 nSizeBytes, OMX_U8 *pBuffer);
+
+OMX_U32 Exynos_OSAL_GetDisplayExtraBufferCount(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ *
+ * 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>
+#include <system/graphics.h>
+
+#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"
+
+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)
+{
+ return strlcpy(dest, src, (size_t)(strlen((const char *)src) + 1));
+}
+
+size_t Exynos_OSAL_Strncpy(OMX_PTR dest, OMX_PTR src, size_t num)
+{
+ return strlcpy(dest, src, (size_t)(num + 1));
+}
+
+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)
+{
+ return strlcat(dest, src, (size_t)(strlen((const char *)dest) + strlen((const char *)src) + 1));
+}
+
+size_t Exynos_OSAL_Strncat(OMX_PTR dest, OMX_PTR src, size_t num)
+{
+ size_t len = num;
+
+ /* caution : num should be a size of dest buffer */
+ return strlcat(dest, src, (size_t)(strlen((const char *)dest) + strlen((const char *)src) + 1));
+}
+
+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 Frame Count: %d", prefix, frameCount);
+ Exynos_OSAL_Log(EXYNOS_LOG_INFO, "%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_FormatYUV420SemiPlanarInterlace:
+ case OMX_SEC_COLOR_Format10bitYUV420SemiPlanar:
+ case OMX_SEC_COLOR_FormatNV21Linear:
+ 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(%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;
+
+ nAllocLen[0] = GET_Y_SIZE(nWidth, nHeight) + GET_CB_SIZE(nWidth, nHeight) + GET_CR_SIZE(nWidth, nHeight);
+ } 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(nHeight, 16) >> 1), 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;
+
+ nAllocLen[0] = GET_Y_SIZE(nWidth, nHeight) + GET_UV_SIZE(nWidth, nHeight);
+ } else {
+ nDataLen[0] = nWidth * nHeight;
+ nDataLen[1] = nDataLen[0] >> 1;
+
+ nAllocLen[0] = ALIGN(ALIGN(nWidth, 16) * ALIGN(nHeight, 16), 256);
+ nAllocLen[1] = ALIGN(ALIGN(nWidth, 16) * ALIGN(nHeight, 16) >> 1, 256);
+ }
+ break;
+ case OMX_SEC_COLOR_Format10bitYUV420SemiPlanar:
+
+ if (ePlaneType == PLANE_SINGLE) {
+ nDataLen[0] = (nWidth * nHeight) * 3 / 2;
+
+ nAllocLen[0] = GET_10B_Y_SIZE(nWidth, nHeight) + GET_10B_UV_SIZE(nWidth, nHeight);
+ } else {
+ nDataLen[0] = nWidth * nHeight;
+ nDataLen[1] = nDataLen[0] >> 1;
+
+ nAllocLen[0] = ALIGN((ALIGN(nWidth, 16) * ALIGN(nHeight, 16) + 64) + (ALIGN(nWidth / 4, 16) * nHeight + 64), 256);
+ nAllocLen[1] = ALIGN((ALIGN(nWidth, 16) * ALIGN(nHeight, 16) + 64) + (ALIGN(nWidth / 4, 16) * (nHeight / 2) + 64), 256);
+ }
+ break;
+ case OMX_COLOR_Format32bitARGB8888:
+ case OMX_COLOR_Format32bitBGRA8888:
+ case OMX_COLOR_Format32BitRGBA8888:
+ nDataLen[0] = nWidth * nHeight * 4;
+
+ nAllocLen[0] = ALIGN(ALIGN(nWidth, 16) * ALIGN(nHeight, 16) * 4, 256);
+ break;
+ default:
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: unsupported color format(%x).", __func__, 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, VIDEO_COLORFORMAT_NV12}, (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace},
+{{VIDEO_COLORFORMAT_NV12M, VIDEO_COLORFORMAT_NV12}, (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_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_TRACE, "OMX(%x)/Plane type(%x) is not supported", eColorFormat, ePlaneType);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX(%x)/Plane type(%x) -> VIDEO(%x) is changed", 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_TRACE, "VIDEO(%x) is not supported", nVideoFormat);
+ goto EXIT;
+ }
+
+#if 0
+ if ((eOMXFormat == OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace) ||
+ (eOMXFormat == OMX_SEC_COLOR_Format10bitYUV420SemiPlanar)) {
+ eOMXFormat = OMX_COLOR_FormatYUV420SemiPlanar; /* hiding */
+ }
+#endif
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "VIDEO(%x) -> OMX(%x) is changed", 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 */
+{{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_PRIV, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP},
+ (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace}, /* deinterlacing at single-FD(H/W) is not supported */
+
+{{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_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},
+
+/* 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) ||
+ (HAL_COLORFORMAT_MAP[i].nHALFormat[2] == nHALFormat)) {
+ eOMXFormat = HAL_COLORFORMAT_MAP[i].eOMXFormat;
+ break;
+ }
+ }
+
+ if (eOMXFormat == OMX_COLOR_FormatUnused) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "HAL(%x) is not supported", nHALFormat);
+ goto EXIT;
+ }
+
+#if 0
+ if ((eOMXFormat == OMX_SEC_COLOR_FormatYUV420SemiPlanarInterlace) ||
+ (eOMXFormat == OMX_SEC_COLOR_Format10bitYUV420SemiPlanar)) {
+ eOMXFormat = OMX_COLOR_FormatYUV420SemiPlanar; /* hiding */
+ }
+#endif
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "HAL(%x) -> OMX(%x) is changed", 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) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX(%x)/Plane type(%x) is not supported", eOMXFormat, ePlaneType);
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX(%x) -> HAL(%x) is changed", eOMXFormat, nHALFormat);
+
+EXIT:
+
+ return nHALFormat;
+}
+
+#ifdef PERFORMANCE_DEBUG
+typedef struct _EXYNOS_OMX_COUNT
+{
+ OMX_HANDLETYPE mutex;
+ OMX_S32 OMXQCount;
+ OMX_S32 V4L2QCount;
+ BUFFER_TIME sBufferTime[MAX_TIMESTAMP];
+ OMX_U32 bufferTimeIndex;
+ OMX_TICKS dstOutPreviousTimeStamp;
+} EXYNOS_OMX_COUNT;
+
+OMX_ERRORTYPE Exynos_OSAL_CountCreate(OMX_HANDLETYPE *hCountHandle)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_COUNT *countHandle = NULL;
+
+ countHandle = (EXYNOS_OMX_COUNT *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_COUNT));
+ if (countHandle == NULL) {
+ *hCountHandle = NULL;
+ return OMX_ErrorInsufficientResources;
+ }
+ Exynos_OSAL_Memset((OMX_PTR)countHandle, 0, sizeof(EXYNOS_OMX_COUNT));
+
+ ret = Exynos_OSAL_MutexCreate(&(countHandle->mutex));
+ if (ret != OMX_ErrorNone) {
+ Exynos_OSAL_Free(countHandle);
+ *hCountHandle = NULL;
+ goto EXIT;
+ }
+
+ countHandle->OMXQCount = 0;
+ *hCountHandle = countHandle;
+
+EXIT:
+ return ret;
+}
+
+void Exynos_OSAL_CountTerminate(OMX_HANDLETYPE *hCountHandle)
+{
+ EXYNOS_OMX_COUNT *countHandle = (EXYNOS_OMX_COUNT *)*hCountHandle;
+
+ if (countHandle == NULL)
+ return;
+
+ Exynos_OSAL_MutexTerminate(countHandle->mutex);
+ Exynos_OSAL_Free(countHandle);
+ *hCountHandle = NULL;
+
+ return;
+}
+
+OMX_S32 Exynos_OSAL_CountIncrease(OMX_HANDLETYPE hCountHandle, OMX_BUFFERHEADERTYPE *OMXBufferHeader, OMX_U32 nPortIndex)
+{
+ EXYNOS_OMX_COUNT *countHandle = (EXYNOS_OMX_COUNT *)hCountHandle;
+ OMX_U32 nextIndex = 0;
+ OMX_S32 ret = -1;
+
+ struct timeval currentTime;
+ struct tm* ptm;
+ char time_string[40];
+ long milliseconds;
+
+ if (countHandle == NULL)
+ return ret;
+
+ if (OMX_ErrorNone == Exynos_OSAL_MutexLock(countHandle->mutex)) {
+ countHandle->OMXQCount++;
+ nextIndex = (countHandle->bufferTimeIndex + 1) % MAX_TIMESTAMP;
+ //Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "nextIndex:%d, countHandle->bufferTimeIndex:%d", nextIndex, countHandle->bufferTimeIndex);
+ gettimeofday(&(currentTime), NULL);
+ countHandle->sBufferTime[countHandle->bufferTimeIndex].currentTimeStamp = OMXBufferHeader->nTimeStamp;
+ Exynos_OSAL_Memcpy(&countHandle->sBufferTime[countHandle->bufferTimeIndex].currentIncomingTime, ¤tTime, sizeof(currentTime));
+ countHandle->sBufferTime[countHandle->bufferTimeIndex].OMXQBufferCount = countHandle->OMXQCount;
+ countHandle->sBufferTime[countHandle->bufferTimeIndex].pBufferHeader = OMXBufferHeader;
+ countHandle->sBufferTime[nextIndex].previousTimeStamp = OMXBufferHeader->nTimeStamp;
+ Exynos_OSAL_Memcpy(&countHandle->sBufferTime[nextIndex].previousIncomingTime, ¤tTime, sizeof(currentTime));
+
+ countHandle->bufferTimeIndex = nextIndex;
+ ret = countHandle->OMXQCount;
+ Exynos_OSAL_MutexUnlock(countHandle->mutex);
+
+ ptm = localtime (¤tTime.tv_sec);
+ strftime (time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
+ milliseconds = currentTime.tv_usec / 1000;
+/*
+ if (nPortIndex == INPUT_PORT_INDEX)
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ETB time = %s.%03ld, header:0x%x, OMXQCount:%d", time_string, milliseconds, OMXBufferHeader, ret);
+ else
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FTB time = %s.%03ld, header:0x%x, OMXQCount:%d", time_string, milliseconds, OMXBufferHeader, ret);
+*/
+ }
+
+ return ret;
+}
+
+OMX_S32 Exynos_OSAL_CountDecrease(OMX_HANDLETYPE hCountHandle, OMX_BUFFERHEADERTYPE *OMXBufferHeader, OMX_U32 nPortIndex)
+{
+ EXYNOS_OMX_COUNT *countHandle = (EXYNOS_OMX_COUNT *)hCountHandle;
+ OMX_U32 i = 0;
+ OMX_S32 ret = -1;
+
+ struct timeval currentTime;
+ struct tm* ptm;
+ char time_string[40];
+ long milliseconds;
+
+ if (countHandle == NULL)
+ return ret;
+
+ if (OMX_ErrorNone == Exynos_OSAL_MutexLock(countHandle->mutex)) {
+ for (i = 0; i < MAX_TIMESTAMP; i++) {
+ if (countHandle->sBufferTime[i].pBufferHeader == OMXBufferHeader) {
+ countHandle->sBufferTime[i].pBufferHeader = NULL;
+ if (nPortIndex == OUTPUT_PORT_INDEX)
+ countHandle->dstOutPreviousTimeStamp = countHandle->sBufferTime[i].currentTimeStamp;
+ break;
+ }
+ }
+
+ countHandle->OMXQCount--;
+ ret = countHandle->OMXQCount;
+ Exynos_OSAL_MutexUnlock(countHandle->mutex);
+
+ if (i >= MAX_TIMESTAMP) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "can not find a bufferHeader !!");
+ ret = OMX_ErrorNoMore;
+ }
+
+ gettimeofday(&(currentTime), NULL);
+ ptm = localtime (¤tTime.tv_sec);
+ strftime (time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
+ milliseconds = currentTime.tv_usec / 1000;
+/*
+ if (nPortIndex == INPUT_PORT_INDEX)
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EBD time = %s.%03ld, header:0x%x, OMXQCount:%d", time_string, milliseconds, OMXBufferHeader, ret);
+ else
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FBD time = %s.%03ld, header:0x%x, OMXQCount:%d", time_string, milliseconds, OMXBufferHeader, ret);
+*/
+ }
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_GetCountInfoUseOMXBuffer(OMX_HANDLETYPE hCountHandle, OMX_BUFFERHEADERTYPE *OMXBufferHeader, BUFFER_TIME *pBufferInfo)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ EXYNOS_OMX_COUNT *countHandle = (EXYNOS_OMX_COUNT *)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;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_GetCountInfoUseTimestamp(OMX_HANDLETYPE hCountHandle, OMX_TICKS Timestamp, BUFFER_TIME *pBufferInfo)
+{
+ EXYNOS_OMX_COUNT *countHandle = (EXYNOS_OMX_COUNT *)hCountHandle;
+ OMX_U32 i = 0;
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ if ((countHandle == 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].currentTimeStamp == Timestamp) {
+ 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 timestamp !!");
+ ret = OMX_ErrorNoMore;
+ }
+ }
+ return ret;
+}
+
+OMX_S32 Exynos_OSAL_V4L2CountIncrease(OMX_HANDLETYPE hCountHandle, OMX_BUFFERHEADERTYPE *OMXBufferHeader, OMX_U32 nPortIndex)
+{
+ EXYNOS_OMX_COUNT *countHandle = (EXYNOS_OMX_COUNT *)hCountHandle;
+ OMX_U32 i = 0, index = 0;
+ OMX_S32 ret = -1;
+
+ struct tm* ptm;
+ char time_string[40];
+ long milliseconds;
+
+ if (countHandle == NULL)
+ return ret;
+
+ if (OMX_ErrorNone == Exynos_OSAL_MutexLock(countHandle->mutex)) {
+ for (i = 0; i < MAX_TIMESTAMP; i++) {
+ if (countHandle->sBufferTime[i].pBufferHeader == OMXBufferHeader) {
+ index = i;
+ break;
+ }
+ }
+
+ if (i >= MAX_TIMESTAMP) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "can not find a bufferHeader !!");
+ Exynos_OSAL_MutexUnlock(countHandle->mutex);
+ return OMX_ErrorNoMore;
+ }
+
+ countHandle->V4L2QCount++;
+ gettimeofday(&(countHandle->sBufferTime[index].V4L2QBufferTime), NULL);
+ countHandle->sBufferTime[index].V4L2QBufferCount = countHandle->V4L2QCount;
+ ret = countHandle->V4L2QCount;
+ Exynos_OSAL_MutexUnlock(countHandle->mutex);
+
+ ptm = localtime (&countHandle->sBufferTime[index].V4L2QBufferTime.tv_sec);
+ strftime (time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
+ milliseconds = countHandle->sBufferTime[index].V4L2deQBufferTime.tv_usec / 1000;
+/*
+ if (nPortIndex == INPUT_PORT_INDEX)
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "V4L2 Src Q time = %s.%03ld, header:0x%x, index:%d", time_string, milliseconds, OMXBufferHeader, index);
+ else
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "V4L2 Dst Q time = %s.%03ld, header:0x%x", time_string, milliseconds, OMXBufferHeader);
+*/
+ }
+
+ return ret;
+}
+
+OMX_S32 Exynos_OSAL_V4L2CountDecrease(OMX_HANDLETYPE hCountHandle, OMX_BUFFERHEADERTYPE *OMXBufferHeader, OMX_U32 nPortIndex)
+{
+ EXYNOS_OMX_COUNT *countHandle = (EXYNOS_OMX_COUNT *)hCountHandle;
+ OMX_U32 i = 0, index = 0;
+ OMX_S32 ret = -1;
+
+ struct tm* ptm;
+ char time_string[40];
+ long milliseconds;
+
+ if (countHandle == NULL)
+ return ret;
+
+ if (OMX_ErrorNone == Exynos_OSAL_MutexLock(countHandle->mutex)) {
+ for (i = 0; i < MAX_TIMESTAMP; i++) {
+ if (countHandle->sBufferTime[i].pBufferHeader == OMXBufferHeader) {
+ index = i;
+ break;
+ }
+ }
+
+ if (i >= MAX_TIMESTAMP) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "can not find a bufferHeader !!");
+ Exynos_OSAL_MutexUnlock(countHandle->mutex);
+ return OMX_ErrorNoMore;
+ }
+
+ countHandle->V4L2QCount--;
+ gettimeofday(&(countHandle->sBufferTime[index].V4L2deQBufferTime), NULL);
+ if (nPortIndex == OUTPUT_PORT_INDEX) {
+ countHandle->sBufferTime[index].currentTimeStamp = OMXBufferHeader->nTimeStamp;
+ countHandle->sBufferTime[index].previousTimeStamp = countHandle->dstOutPreviousTimeStamp;
+ }
+ ret = countHandle->V4L2QCount;
+ Exynos_OSAL_MutexUnlock(countHandle->mutex);
+
+ ptm = localtime (&countHandle->sBufferTime[index].V4L2deQBufferTime.tv_sec);
+ strftime (time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", ptm);
+ milliseconds = countHandle->sBufferTime[index].V4L2deQBufferTime.tv_usec / 1000;
+/*
+ if (nPortIndex == INPUT_PORT_INDEX)
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "V4L2 Src deQ time = %s.%03ld, header:0x%x", time_string, milliseconds, OMXBufferHeader);
+ else
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "V4L2 Dst deQ time = %s.%03ld, header:0x%x", time_string, milliseconds, OMXBufferHeader);
+*/
+ }
+
+ return ret;
+}
+
+OMX_ERRORTYPE Exynos_OSAL_CountReset(OMX_HANDLETYPE hCountHandle)
+{
+ EXYNOS_OMX_COUNT *countHandle = (EXYNOS_OMX_COUNT *)hCountHandle;
+
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ if (countHandle == NULL)
+ return OMX_ErrorBadParameter;
+
+ if (OMX_ErrorNone == Exynos_OSAL_MutexLock(countHandle->mutex)) {
+ countHandle->bufferTimeIndex = 0;
+ countHandle->OMXQCount = 0;
+ countHandle->V4L2QCount = 0;
+ Exynos_OSAL_Memset(&countHandle->sBufferTime, 0, sizeof(BUFFER_TIME) * MAX_TIMESTAMP);
+ Exynos_OSAL_MutexUnlock(countHandle->mutex);
+ }
+
+ return ret;
+}
+
+void Exynos_OSAL_PrintCountInfo(BUFFER_TIME srcBufferInfo, BUFFER_TIME dstBufferInfo)
+{
+ struct timeval FBDTime;
+ struct tm* ptm;
+ char time_string[40];
+ 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;
+
+ {
+ gettimeofday(&FBDTime, NULL);
+
+ srcOMXtoV4L2 = Exynos_OSAL_MeasureTime(&(srcBufferInfo.currentIncomingTime), &(srcBufferInfo.V4L2QBufferTime)) / 1000;
+ //srcV4L2toOMX = Exynos_OSAL_MeasureTime(&(srcBufferInfo.V4L2deQBufferTime), &(srcBufferInfo.?????????????????)) / 1000;
+ dstOMXtoV4L2 = Exynos_OSAL_MeasureTime(&(dstBufferInfo.currentIncomingTime), &(dstBufferInfo.V4L2QBufferTime)) / 1000;
+ dstV4L2toOMX = Exynos_OSAL_MeasureTime(&(dstBufferInfo.V4L2deQBufferTime), &FBDTime) / 1000;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PERFORM:: INTERNAL: srcOMXtoV4L2:%d, srcV4L2toOMX:%d, dstOMXtoV4L2:%d, dstV4L2toOMX:%d", srcOMXtoV4L2, srcV4L2toOMX, dstOMXtoV4L2, dstV4L2toOMX);
+ }
+
+ {
+ srcQdstQ = Exynos_OSAL_MeasureTime(&(srcBufferInfo.V4L2QBufferTime), &(dstBufferInfo.V4L2QBufferTime)) / 1000;
+ srcQdstDQ = Exynos_OSAL_MeasureTime(&(srcBufferInfo.V4L2QBufferTime), &(dstBufferInfo.V4L2deQBufferTime)) / 1000;
+ dstQdstDQ = Exynos_OSAL_MeasureTime(&(dstBufferInfo.V4L2QBufferTime), &(dstBufferInfo.V4L2deQBufferTime)) / 1000;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PERFORM:: V4L2: srcQdstQ:%d, srcQdstDQ:%d, dstQdstDQ:%d, src-V4L2QBufferCount:%d, dst-V4L2QBufferCount:%d",
+ srcQdstQ, srcQdstDQ, dstQdstDQ, srcBufferInfo.V4L2QBufferCount, dstBufferInfo.V4L2QBufferCount);
+ }
+
+ {
+ ETBFTB = Exynos_OSAL_MeasureTime(&(srcBufferInfo.currentIncomingTime), &(dstBufferInfo.currentIncomingTime)) / 1000;
+ ETBFBD = Exynos_OSAL_MeasureTime(&(srcBufferInfo.currentIncomingTime), &FBDTime) / 1000;
+ FTBFBD = Exynos_OSAL_MeasureTime(&(dstBufferInfo.currentIncomingTime), &FBDTime) / 1000;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PERFORM:: BUFFER: ETBFTB:%d, ETBFBD:%d, FTBFBD:%d, src-OMXQBufferCount:%d, dst-OMXQBufferCount:%d",
+ ETBFTB, ETBFBD, FTBFBD, srcBufferInfo.OMXQBufferCount, dstBufferInfo.OMXQBufferCount);
+
+ if (ETBFTB > 0)
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PERFORM:: BUFFER: Output port buffer slow. real decode time:%d", FTBFBD / dstBufferInfo.OMXQBufferCount);
+ else if (ETBFTB < 0)
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PERFORM:: BUFFER: Input port buffer slow. real decode time:%d", ETBFBD / srcBufferInfo.OMXQBufferCount);
+ else
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PERFORM:: BUFFER: real decode time:%d or %d", ETBFBD / srcBufferInfo.OMXQBufferCount, FTBFBD / dstBufferInfo.OMXQBufferCount);
+ }
+
+ {
+ 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.currentTimeStamp - 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.currentTimeStamp - 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.currentTimeStamp - srcBufferInfo.previousTimeStamp)) / 1000;
+ dstTimestampInterval = ((OMX_S32)(dstBufferInfo.currentTimeStamp - 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
--- /dev/null
+/*
+ *
+ * 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);
+ssize_t getline(char **ppLine, size_t *len, FILE *stream);
+
+/* 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);
+
+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
+typedef struct _BUFFER_TIME
+{
+ OMX_TICKS previousTimeStamp;
+ OMX_TICKS currentTimeStamp;
+ struct timeval previousIncomingTime;
+ struct timeval currentIncomingTime;
+ OMX_S32 OMXQBufferCount;
+ OMX_BUFFERHEADERTYPE *pBufferHeader;
+
+ OMX_S32 V4L2QBufferCount;
+ struct timeval V4L2QBufferTime;
+ struct timeval V4L2deQBufferTime;
+} BUFFER_TIME;
+
+OMX_ERRORTYPE Exynos_OSAL_CountCreate(OMX_HANDLETYPE *phCountHandle);
+void Exynos_OSAL_CountTerminate(OMX_HANDLETYPE *phCountHandle);
+OMX_S32 Exynos_OSAL_CountIncrease(OMX_HANDLETYPE hCountHandle, OMX_BUFFERHEADERTYPE *OMXBufferHeader, OMX_U32 nPortIndex);
+OMX_S32 Exynos_OSAL_CountDecrease(OMX_HANDLETYPE hCountHandle, OMX_BUFFERHEADERTYPE *OMXBufferHeader, OMX_U32 nPortIndex);
+OMX_ERRORTYPE Exynos_OSAL_GetCountInfoUseOMXBuffer(OMX_HANDLETYPE hCountHandle, OMX_BUFFERHEADERTYPE *OMXBufferHeader, BUFFER_TIME *pBufferInfo);
+OMX_ERRORTYPE Exynos_OSAL_GetCountInfoUseTimestamp(OMX_HANDLETYPE hCountHandle, OMX_TICKS Timestamp, BUFFER_TIME *pBufferInfo);
+OMX_S32 Exynos_OSAL_V4L2CountIncrease(OMX_HANDLETYPE hCountHandle, OMX_BUFFERHEADERTYPE *OMXBufferHeader, OMX_U32 nPortIndex);
+OMX_S32 Exynos_OSAL_V4L2CountDecrease(OMX_HANDLETYPE hCountHandle, OMX_BUFFERHEADERTYPE *OMXBufferHeader, OMX_U32 nPortIndex);
+OMX_ERRORTYPE Exynos_OSAL_CountReset(OMX_HANDLETYPE hCountHandle);
+void Exynos_OSAL_PrintCountInfo(BUFFER_TIME srcBufferInfo, BUFFER_TIME dstBufferInfo);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ *
+ * 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 "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)) {
+ 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;
+ OMX_U32 tv_us;
+
+ 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;
+ timeout.tv_nsec = (tv_us % 1000000) * 1000;
+
+ 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;
+}
--- /dev/null
+/*
+ *
+ * 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
--- /dev/null
+/*
+ *
+ * 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 "Exynos_OSAL_Library.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();
+}
--- /dev/null
+/*
+ *
+ * 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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ *
+ * 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 "Exynos_OSAL_Log.h"
+#include "Exynos_OSAL_ETC.h"
+/* =======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_DEFAULT = EXYNOS_LOG_INFO,
+ LOG_LEVEL1 = EXYNOS_LOG_ESSENTIAL,
+ LOG_LEVEL2 = EXYNOS_LOG_TRACE,
+ LOG_LEVELTAG = 3
+} EXYNOS_DEBUG_LEVEL;
+
+static unsigned int log_prop = LOG_DEFAULT;
+
+void Exynos_OSAL_Get_Log_Property()
+{
+#ifdef EXYNOS_LOG
+ if (property_get("debug.omx.level", debugProp, NULL) > 0) {
+ 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 {
+ log_prop = LOG_LEVELTAG;
+ }
+ }
+#endif
+}
+
+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_TRACE:
+ __android_log_vprint(ANDROID_LOG_VERBOSE, tag, msg, argptr);
+ break;
+ case EXYNOS_LOG_ESSENTIAL:
+ __android_log_vprint(ANDROID_LOG_DEBUG, tag, msg, argptr);
+ break;
+ case EXYNOS_LOG_INFO:
+ __android_log_vprint(ANDROID_LOG_INFO, tag, msg, argptr);
+ break;
+ case EXYNOS_LOG_WARNING:
+ __android_log_vprint(ANDROID_LOG_WARN, tag, msg, argptr);
+ break;
+ case EXYNOS_LOG_ERROR:
+ __android_log_vprint(ANDROID_LOG_ERROR, tag, msg, argptr);
+ break;
+ default:
+ __android_log_vprint(ANDROID_LOG_VERBOSE, tag, msg, argptr);
+ }
+
+ va_end(argptr);
+}
--- /dev/null
+/*
+ *
+ * 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 "EXYNOS_LOG"
+#endif
+
+#define EXYNOS_TRACE_FUNCTION_INFO
+
+typedef enum _LOG_LEVEL
+{
+ 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_TRACE, EXYNOS_LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__)
+#define FunctionOut() _Exynos_OSAL_Log(EXYNOS_LOG_TRACE, EXYNOS_LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__)
+#else
+#define FunctionIn() ((void *)0)
+#define FunctionOut() ((void *)0)
+#endif
+
+extern void Exynos_OSAL_Get_Log_Property();
+extern void _Exynos_OSAL_Log(EXYNOS_LOG_LEVEL logLevel, const char *tag, const char *msg, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ *
+ * 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 "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)
+{
+ mem_cnt++;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "alloc count: %d", mem_cnt);
+
+ return (OMX_PTR)malloc(size);
+}
+
+void Exynos_OSAL_Free(OMX_PTR addr)
+{
+ mem_cnt--;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "free count: %d", mem_cnt);
+
+ if (addr)
+ free(addr);
+
+ 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);
+}
--- /dev/null
+/*
+ *
+ * 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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
--- /dev/null
+/*
+ *
+ * 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;
+ int result;
+
+ 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;
+ int result;
+
+ if (mutex == NULL)
+ return OMX_ErrorBadParameter;
+
+ if (pthread_mutex_unlock(mutex) != 0)
+ return OMX_ErrorUndefined;
+
+ return OMX_ErrorNone;
+}
--- /dev/null
+/*
+ *
+ * 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
--- /dev/null
+/*
+ *
+ * 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++) {
+ currentqelem = queue->first->qNext;
+ Exynos_OSAL_Free(queue->first);
+ queue->first = currentqelem;
+ }
+
+ if(queue->first) {
+ Exynos_OSAL_Free(queue->first);
+ queue->first = NULL;
+ }
+
+ ret = Exynos_OSAL_MutexTerminate(queue->qMutex);
+
+ 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;
+}
--- /dev/null
+/*
+ *
+ * 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
--- /dev/null
+/*
+ *
+ * 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;
+}
--- /dev/null
+/*
+ *
+ * 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
--- /dev/null
+/*
+ *
+ * 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>
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include <ion/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
+{
+ OMX_U32 IONBuffer;
+ OMX_PTR mapAddr;
+ OMX_U32 allocSize;
+ OMX_BOOL owner;
+ struct _EXYNOS_SHAREDMEM_LIST *pNextMemory;
+} EXYNOS_SHAREDMEM_LIST;
+
+typedef struct _EXYNOS_SHARED_MEMORY
+{
+ int hIONHandle;
+ EXYNOS_SHAREDMEM_LIST *pAllocMemory;
+ OMX_HANDLETYPE hSMMutex;
+} EXYNOS_SHARED_MEMORY;
+
+
+OMX_HANDLETYPE Exynos_OSAL_SharedMemory_Open()
+{
+ EXYNOS_SHARED_MEMORY *pHandle = NULL;
+ int 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 = 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 = IONClient;
+
+ if (OMX_ErrorNone != Exynos_OSAL_MutexCreate(&pHandle->hSMMutex)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_OSAL_MutexCreate(hSMMutex) is failed");
+ /* free a ion_client */
+ ion_close(pHandle->hIONHandle);
+ pHandle->hIONHandle = -1;
+
+ 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 != INT_TO_PTR(pDeleteElement->IONBuffer)) {
+ if (munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize))
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "munmap is failed");
+ }
+
+ 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, "SharedMemory mem count: %d", 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 = -1;
+
+ 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;
+ OMX_S32 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;
+ }
+
+#ifdef USE_IMPROVED_BUFFER
+ if (flag & ION_FLAG_CACHED) /* use improved cache oprs */
+ flag |= ION_FLAG_CACHED_NEEDS_SYNC;
+#endif
+
+ if (ion_alloc_fd(pHandle->hIONHandle, size, 0, mask, flag, (int *)&IONBuffer) < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "ion_alloc_fd is failed(mask:%x, flag:%x)", mask, flag);
+ if (memoryType == CONTIG_MEMORY) {
+ /* retry at normal area */
+ flag = 0;
+ if (ion_alloc_fd(pHandle->hIONHandle, size, 0, mask, flag, (int *)&IONBuffer) < 0)
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "retry, ion_alloc_fd is failed(mask:%x, flag:%x)", mask, flag);
+ }
+ }
+
+ if (IONBuffer < 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion buffer is wrong: fd = %d", 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 = INT_TO_PTR(IONBuffer);
+ } else {
+ pBuffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, IONBuffer, 0);
+ if (pBuffer == MAP_FAILED) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "mmap is failed(size:%d)", 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, "SharedMemory mem count: %d", 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, "Can not find SharedMemory");
+ goto EXIT;
+ }
+ }
+ Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+
+ if (pDeleteElement->mapAddr != INT_TO_PTR(pDeleteElement->IONBuffer)) {
+ if (munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "munmap is failed");
+ 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, "SharedMemory mem count: %d", mem_cnt);
+
+EXIT:
+ return;
+}
+
+#ifdef USE_DMA_BUF
+OMX_PTR Exynos_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, unsigned int 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)
+ goto EXIT;
+
+ pElement = (EXYNOS_SHAREDMEM_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHAREDMEM_LIST));
+ Exynos_OSAL_Memset(pElement, 0, sizeof(EXYNOS_SHAREDMEM_LIST));
+
+ IONBuffer = (OMX_S32)ionfd;
+
+ if (IONBuffer <= 0) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ionFD(%d) is wrong", IONBuffer);
+ Exynos_OSAL_Free((void*)pElement);
+ goto EXIT;
+ }
+
+ pBuffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, IONBuffer, 0);
+ if (pBuffer == NULL) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "mmap is failed(size:%d)", 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, "SharedMemory map count: %d", map_cnt);
+
+EXIT:
+ return pBuffer;
+}
+
+void Exynos_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, unsigned int 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, "Can not find SharedMemory");
+ goto EXIT;
+ }
+ }
+ Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+
+ if (munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
+ Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "munmap is failed");
+ goto EXIT;
+ }
+ pDeleteElement->mapAddr = NULL;
+ pDeleteElement->allocSize = 0;
+ pDeleteElement->IONBuffer = 0;
+
+ Exynos_OSAL_Free(pDeleteElement);
+
+ map_cnt--;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory map count: %d", map_cnt);
+
+EXIT:
+ return;
+}
+#endif
+
+int 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;
+ int 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_WARNING, "Can not find SharedMemory");
+ goto EXIT;
+ }
+ }
+ Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+
+ ion_addr = pFindElement->IONBuffer;
+
+EXIT:
+ return ion_addr;
+}
+
+OMX_PTR Exynos_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, int ion_addr)
+{
+ 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 || ion_addr == 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 == (OMX_U32)ion_addr) {
+ pFindElement = pSMList;
+ } else {
+ while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
+ (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer != (OMX_U32)ion_addr))
+ pCurrentElement = pCurrentElement->pNextMemory;
+
+ if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
+ (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer == (OMX_U32)ion_addr)) {
+ pFindElement = pCurrentElement->pNextMemory;
+ } else {
+ Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+ Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Can not find SharedMemory");
+ goto EXIT;
+ }
+ }
+ Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
+
+ pBuffer = pFindElement->mapAddr;
+
+EXIT:
+ return pBuffer;
+}
--- /dev/null
+/*
+ *
+ * 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);
+int Exynos_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer);
+OMX_PTR Exynos_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, int ion_addr);
+
+#ifdef USE_DMA_BUF
+OMX_PTR Exynos_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, unsigned int ionfd);
+void Exynos_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, unsigned int ionfd);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
--- /dev/null
+/*
+ * 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"
+
+#include "OMX_Video_Extensions.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
+
+/* Change CHECK_SIZE_VERSION Macro for SkypeHD */
+OMX_ERRORTYPE Exynos_OMX_Check_SizeVersion_SkypeHD(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_TRACE, "nVersionMajor:%d, nVersionMinor:%d", version->s.nVersionMajor, version->s.nVersionMinor);
+ if (version->s.nVersionMajor != OMX_VIDEO_MajorVersion ||
+ version->s.nVersionMinor > OMX_VIDEO_MinorVersion) {
+ ret = OMX_ErrorVersionMismatch;
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+
+
+
+/* ENCODE_ONLY */
+#ifdef BUILD_ENC
+/* video enc */
+OMX_ERRORTYPE Exynos_H264Enc_GetExtensionIndex_SkypeHD(
+ 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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, OMX_MS_SKYPE_PARAM_DRIVERVER) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexSkypeParamDriverVersion;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, OMX_MS_SKYPE_PARAM_ENCODERSETTING) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexSkypeParamEncoderSetting;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, OMX_MS_SKYPE_PARAM_ENCODERCAP) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexSkypeParamEncoderCapability;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, OMX_MS_SKYPE_CONFIG_MARKLTRFRAME) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexSkypeConfigMarkLTRFrame;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, OMX_MS_SKYPE_CONFIG_USELTRFRAME) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexSkypeConfigUseLTRFrame;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, OMX_MS_SKYPE_CONFIG_QP) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexSkypeConfigQP;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, OMX_MS_SKYPE_CONFIG_TEMPORALLAYERCOUNT) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexSkypeConfigTemporalLayerCount;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, OMX_MS_SKYPE_CONFIG_BASELAYERPID) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexSkypeConfigBasePid;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorUnsupportedIndex;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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_SkypeHD(pDriverVer, sizeof(OMX_VIDEO_PARAM_DRIVERVER));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pDriverVer->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pDriverVer->nDriverVersion = (OMX_U64)(pH264Enc->hMFCH264Handle.videoInstInfo.SwVersion);
+ }
+ break;
+ case OMX_IndexSkypeParamEncoderCapability:
+ {
+ OMX_VIDEO_PARAM_ENCODERCAP *pEncoderCap = (OMX_VIDEO_PARAM_ENCODERCAP *)pComponentParameterStructure;
+ OMX_VIDEO_ENCODERCAP *pstEncCap = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pEncoderCap, sizeof(OMX_VIDEO_PARAM_ENCODERCAP));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pEncoderCap->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pstEncCap = &(pEncoderCap->stEncCap);
+
+ pstEncCap->bLowLatency = OMX_TRUE;
+ pstEncCap->nMaxFrameWidth = MAX_FRAME_WIDTH;
+ pstEncCap->nMaxFrameHeight = MAX_FRAME_HEIGHT;
+ pstEncCap->nMaxInstances = RESOURCE_VIDEO_ENC;
+ pstEncCap->nMaxTemporaLayerCount = OMX_VIDEO_MAX_TEMPORAL_LAYERS;
+ pstEncCap->nMaxRefFrames = ((OMX_VIDEO_MAX_TEMPORAL_LAYERS_WITH_LTR + 1) / 2) + OMX_VIDEO_MAX_LTR_FRAMES;
+ pstEncCap->nMaxLTRFrames = OMX_VIDEO_MAX_LTR_FRAMES;
+ pstEncCap->nMaxLevel = OMX_VIDEO_AVCLevel42;
+ pstEncCap->nSliceControlModesBM = (1 << (OMX_VIDEO_SliceControlModeMB - 1)) | (1 << (OMX_VIDEO_SliceControlModeByte - 1));
+ pstEncCap->nMaxMacroblockProcessingRate = ENC_BLOCKS_PER_SECOND;
+ pstEncCap->nResize = 0;
+ pstEncCap->xMinScaleFactor = 0;
+ }
+ break;
+ case OMX_IndexSkypeParamEncoderSetting:
+ {
+ OMX_VIDEO_PARAM_ENCODERSETTING *pEncoderSetting = (OMX_VIDEO_PARAM_ENCODERSETTING *)pComponentParameterStructure;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pEncoderSetting, sizeof(OMX_VIDEO_PARAM_ENCODERSETTING));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pEncoderSetting->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ Exynos_OSAL_Memcpy(&(pEncoderSetting->stEncParam), &(pH264Enc->stEncParam), sizeof(OMX_VIDEO_ENCODERPARAMS));
+ }
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ switch ((int)nIndex) {
+ case OMX_IndexSkypeParamEncoderSetting:
+ {
+ OMX_VIDEO_PARAM_ENCODERSETTING *pEncoderSetting = (OMX_VIDEO_PARAM_ENCODERSETTING *)pComponentParameterStructure;
+ OMX_VIDEO_ENCODERPARAMS *pstEncParam = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pEncoderSetting, sizeof(OMX_VIDEO_PARAM_ENCODERSETTING));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pEncoderSetting->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pstEncParam = &(pEncoderSetting->stEncParam);
+
+ pH264Enc->bLowLatency = pstEncParam->bLowLatency;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pstEncParam->bLowLatency: %s", (pstEncParam->bLowLatency == OMX_TRUE) ? "OMX_TRUE" : "OMX_FALSE");
+
+ /* SetPrependSPSPPSToIDR */
+ pH264Enc->hMFCH264Handle.bPrependSpsPpsToIdr = pstEncParam->bSequenceHeaderWithIDR;
+
+ if (pstEncParam->bUseExtendedProfile == OMX_TRUE) {
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pstEncParam->eProfile: 0x%x", pstEncParam->eProfile);
+ switch (pstEncParam->eProfile) {
+ case OMX_VIDEO_EXT_AVCProfileConstrainedBaseline:
+ pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eProfile = OMX_VIDEO_AVCProfileConstrainedBaseline;
+ break;
+ case OMX_VIDEO_EXT_AVCProfileConstrainedHigh:
+ pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eProfile = OMX_VIDEO_AVCProfileConstrainedHigh;
+ break;
+ default:
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "default eProfile: 0x%x", pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eProfile);
+ break;
+ }
+ }
+
+ switch (pstEncParam->eHierarType) {
+ case OMX_VIDEO_HierarType_P:
+ pH264Enc->eHierarchicalType = EXYNOS_OMX_Hierarchical_P;
+ break;
+ case OMX_VIDEO_HierarType_B:
+ pH264Enc->eHierarchicalType = EXYNOS_OMX_Hierarchical_B;
+ break;
+ default:
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "default eHierarType: 0x%x", pH264Enc->eHierarchicalType);
+ break;
+ }
+
+ if (pstEncParam->nMaxTemporalLayerCount > OMX_VIDEO_ANDROID_MAXAVCTEMPORALLAYERS) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ } else {
+ if (pstEncParam->nMaxTemporalLayerCount > 0) {
+ pH264Enc->hMFCH264Handle.bTemporalSVC = OMX_TRUE;
+ pH264Enc->TemporalSVC.nTemporalLayerCount = pstEncParam->nMaxTemporalLayerCount | GENERAL_TSVC_ENABLE;
+ } else {
+ pH264Enc->hMFCH264Handle.bTemporalSVC = OMX_FALSE;
+ }
+ }
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pstEncParam->nLTRFrames: %d", pstEncParam->nLTRFrames);
+ if (((int)(pstEncParam->nLTRFrames) > ((int)OMX_VIDEO_MAX_LTR_FRAMES)) ||
+ (((int)pstEncParam->nLTRFrames) < 0)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ } else {
+ if (pstEncParam->nLTRFrames > 0)
+ pH264Enc->hMFCH264Handle.bLTREnable = OMX_TRUE;
+ else
+ pH264Enc->hMFCH264Handle.bLTREnable = OMX_FALSE;
+ }
+
+ switch (pstEncParam->eSliceControlMode) {
+ case OMX_VIDEO_SliceControlModeMB:
+ pH264Enc->AVCSliceFmo.eSliceMode = OMX_VIDEO_SLICEMODE_AVCMBSlice;
+ break;
+ case OMX_VIDEO_SliceControlModeByte:
+ pH264Enc->AVCSliceFmo.eSliceMode = OMX_VIDEO_SLICEMODE_AVCByteSlice;
+ break;
+ case OMX_VIDEO_SliceControlModeNone:
+ case OMX_VIDEO_SliceControlModMBRow:
+ default:
+ pH264Enc->AVCSliceFmo.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault;
+ break;
+ }
+
+ if (pstEncParam->nSarIndex > 0)
+ pH264Enc->stSarParam.SarEnable = OMX_TRUE;
+
+ pH264Enc->stSarParam.SarIndex = pstEncParam->nSarIndex;
+ pH264Enc->stSarParam.SarWidth = pstEncParam->nSarWidth;
+ pH264Enc->stSarParam.SarHeight = pstEncParam->nSarHeight;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SarIndex:%d, SarWidth:%d, SarHeight:%d",
+ pstEncParam->nSarIndex, pstEncParam->nSarWidth, pstEncParam->nSarHeight);
+
+ Exynos_OSAL_Memcpy(&(pH264Enc->stEncParam), &(pEncoderSetting->stEncParam), sizeof(OMX_VIDEO_ENCODERPARAMS));
+ }
+ 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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ switch ((int)nIndex) {
+ case OMX_IndexSkypeConfigTemporalLayerCount:
+ {
+ OMX_VIDEO_CONFIG_TEMPORALLAYERCOUNT *pTemporalLayerCount = (OMX_VIDEO_CONFIG_TEMPORALLAYERCOUNT *)pComponentConfigStructure;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pTemporalLayerCount, sizeof(OMX_VIDEO_CONFIG_TEMPORALLAYERCOUNT));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pTemporalLayerCount->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pTemporalLayerCount->nTemporalLayerCount = pH264Enc->TemporalSVC.nTemporalLayerCount & (~GENERAL_TSVC_ENABLE);
+ }
+ break;
+ case OMX_IndexSkypeConfigBasePid:
+ {
+ OMX_VIDEO_CONFIG_BASELAYERPID *pBaseLayerPid = (OMX_VIDEO_CONFIG_BASELAYERPID *)pComponentConfigStructure;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pBaseLayerPid, sizeof(OMX_VIDEO_CONFIG_BASELAYERPID));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pBaseLayerPid->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pBaseLayerPid->nPID = pH264Enc->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)) {
+ 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;
+ }
+
+ pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
+
+ switch ((int)nIndex) {
+ case OMX_IndexSkypeConfigMarkLTRFrame:
+ {
+ OMX_VIDEO_CONFIG_MARKLTRFRAME *pMarkLTRFrame = (OMX_VIDEO_CONFIG_MARKLTRFRAME *)pComponentConfigStructure;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
+ ExynosVideoEncParam *pEncParam = NULL;
+ ExynosVideoEncCommonParam *pCommonParam = NULL;
+ ExynosVideoEncH264Param *pH264Param = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pMarkLTRFrame, sizeof(OMX_VIDEO_CONFIG_MARKLTRFRAME));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pMarkLTRFrame->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ pEncParam = &pMFCH264Handle->encParam;
+ pCommonParam = &pEncParam->commonParam;
+ pH264Param = &pEncParam->codecParam.h264;
+ pEncOps = pMFCH264Handle->pEncOps;
+
+ /* TBD */
+ }
+ break;
+ case OMX_IndexSkypeConfigUseLTRFrame:
+ {
+ OMX_VIDEO_CONFIG_USELTRFRAME *pUseLTRFrame = (OMX_VIDEO_CONFIG_USELTRFRAME *)pComponentConfigStructure;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
+ ExynosVideoEncParam *pEncParam = NULL;
+ ExynosVideoEncCommonParam *pCommonParam = NULL;
+ ExynosVideoEncH264Param *pH264Param = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pUseLTRFrame, sizeof(OMX_VIDEO_CONFIG_USELTRFRAME));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pUseLTRFrame->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ pEncParam = &pMFCH264Handle->encParam;
+ pCommonParam = &pEncParam->commonParam;
+ pH264Param = &pEncParam->codecParam.h264;
+ pEncOps = pMFCH264Handle->pEncOps;
+
+ /* TBD */
+ }
+ break;
+ case OMX_IndexSkypeConfigQP:
+ {
+ OMX_VIDEO_CONFIG_QP *pConfigQp = (OMX_VIDEO_CONFIG_QP *)pComponentConfigStructure;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
+ ExynosVideoEncParam *pEncParam = NULL;
+ ExynosVideoEncCommonParam *pCommonParam = NULL;
+ ExynosVideoEncH264Param *pH264Param = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pConfigQp, sizeof(OMX_VIDEO_CONFIG_QP));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pConfigQp->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ pEncParam = &pMFCH264Handle->encParam;
+ pCommonParam = &pEncParam->commonParam;
+ pH264Param = &pEncParam->codecParam.h264;
+ pEncOps = pMFCH264Handle->pEncOps;
+
+ /* will remove */
+ pVideoEnc->quantization.nQpI = pConfigQp->nQP;
+ pVideoEnc->quantization.nQpP = pConfigQp->nQP;
+ pVideoEnc->quantization.nQpB = pConfigQp->nQP;
+// pCommonParam->FrameQp = pVideoEnc->quantization.nQpI;
+// pCommonParam->FrameQp_P = pVideoEnc->quantization.nQpP;
+// pH264Param->FrameQp_B = pVideoEnc->quantization.nQpB;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : pConfigQp->nQP:%d", __FUNCTION__, pConfigQp->nQP);
+
+ /* TBD */
+ }
+ break;
+ case OMX_IndexSkypeConfigTemporalLayerCount:
+ {
+ OMX_VIDEO_CONFIG_TEMPORALLAYERCOUNT *pTemporalLayerCount = (OMX_VIDEO_CONFIG_TEMPORALLAYERCOUNT *)pComponentConfigStructure;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+
+ int i = 0;
+ TemporalLayerShareBuffer TemporalSVC;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pTemporalLayerCount, sizeof(OMX_VIDEO_CONFIG_TEMPORALLAYERCOUNT));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pTemporalLayerCount->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pH264Enc->hMFCH264Handle.bTemporalSVC == OMX_FALSE) ||
+ (pTemporalLayerCount->nTemporalLayerCount > OMX_VIDEO_ANDROID_MAXAVCTEMPORALLAYERS)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ /* Temporal SVC */
+ pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ pEncOps = pMFCH264Handle->pEncOps;
+
+ pH264Enc->TemporalSVC.nTemporalLayerCount = pTemporalLayerCount->nTemporalLayerCount | GENERAL_TSVC_ENABLE;
+ }
+ break;
+ case OMX_IndexSkypeConfigBasePid:
+ {
+ OMX_VIDEO_CONFIG_BASELAYERPID *pBaseLayerPid = (OMX_VIDEO_CONFIG_BASELAYERPID *)pComponentConfigStructure;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
+ ExynosVideoEncParam *pEncParam = NULL;
+ ExynosVideoEncCommonParam *pCommonParam = NULL;
+ ExynosVideoEncH264Param *pH264Param = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pBaseLayerPid, sizeof(OMX_VIDEO_CONFIG_BASELAYERPID));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pBaseLayerPid->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ pEncParam = &pMFCH264Handle->encParam;
+ pCommonParam = &pEncParam->commonParam;
+ pH264Param = &pEncParam->codecParam.h264;
+ pEncOps = pMFCH264Handle->pEncOps;
+
+ pH264Enc->nBaseLayerPid = pBaseLayerPid->nPID;
+ }
+ break;
+ default:
+ ret = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+EXIT:
+
+ FunctionOut();
+
+ return ret;
+}
+
+void 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;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
+ ExynosVideoEncParam *pEncParam = NULL;
+ ExynosVideoEncCommonParam *pCommonParam = NULL;
+ ExynosVideoEncH264Param *pH264Param = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pMarkLTRFrame, sizeof(OMX_VIDEO_CONFIG_MARKLTRFRAME));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pMarkLTRFrame->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ pEncParam = &pMFCH264Handle->encParam;
+ pCommonParam = &pEncParam->commonParam;
+ pH264Param = &pEncParam->codecParam.h264;
+ pEncOps = pMFCH264Handle->pEncOps;
+
+ /* TBD */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pMarkLTRFrame->nLongTermFrmIdx: %d", 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;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
+ ExynosVideoEncParam *pEncParam = NULL;
+ ExynosVideoEncCommonParam *pCommonParam = NULL;
+ ExynosVideoEncH264Param *pH264Param = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+
+ OMX_S32 nUsedLTRFrameNum = 0;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pUseLTRFrame, sizeof(OMX_VIDEO_CONFIG_USELTRFRAME));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pUseLTRFrame->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ pEncParam = &pMFCH264Handle->encParam;
+ pCommonParam = &pEncParam->commonParam;
+ pH264Param = &pEncParam->codecParam.h264;
+ pEncOps = pMFCH264Handle->pEncOps;
+
+ nUsedLTRFrameNum = pUseLTRFrame->nUsedLTRFrameBM;
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pUseLTRFrame->nUsedLTRFrameBM: %d, nUsedLTRFrameNum = %d", pUseLTRFrame->nUsedLTRFrameBM, nUsedLTRFrameNum);
+ if (nUsedLTRFrameNum < 0) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ pEncOps->Set_UsedLTRFrame(pMFCH264Handle->hMFCHandle, nUsedLTRFrameNum);
+ }
+ break;
+ case OMX_IndexSkypeConfigQP:
+ {
+ OMX_VIDEO_CONFIG_QP *pConfigQp = (OMX_VIDEO_CONFIG_QP *)pConfigData;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
+ ExynosVideoEncParam *pEncParam = NULL;
+ ExynosVideoEncCommonParam *pCommonParam = NULL;
+ ExynosVideoEncH264Param *pH264Param = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pConfigQp, sizeof(OMX_VIDEO_CONFIG_QP));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pConfigQp->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ pEncParam = &pMFCH264Handle->encParam;
+ pCommonParam = &pEncParam->commonParam;
+ pH264Param = &pEncParam->codecParam.h264;
+ pEncOps = pMFCH264Handle->pEncOps;
+
+ /* will remove */
+ pVideoEnc->quantization.nQpI = pConfigQp->nQP;
+ pVideoEnc->quantization.nQpP = pConfigQp->nQP;
+ pVideoEnc->quantization.nQpB = pConfigQp->nQP;
+// pCommonParam->FrameQp = pVideoEnc->quantization.nQpI;
+// pCommonParam->FrameQp_P = pVideoEnc->quantization.nQpP;
+// pH264Param->FrameQp_B = pVideoEnc->quantization.nQpB;
+
+ /* TBD */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pConfigQp->nQP: %d", pConfigQp->nQP);
+ pEncOps->Set_DynamicQpControl(pMFCH264Handle->hMFCHandle, pConfigQp->nQP);
+ }
+ break;
+ case OMX_IndexSkypeConfigTemporalLayerCount:
+ {
+ OMX_VIDEO_CONFIG_TEMPORALLAYERCOUNT *pTemporalLayerCount = (OMX_VIDEO_CONFIG_TEMPORALLAYERCOUNT *)pConfigData;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+
+ int i = 0;
+ TemporalLayerShareBuffer TemporalSVC;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pTemporalLayerCount, sizeof(OMX_VIDEO_CONFIG_TEMPORALLAYERCOUNT));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pTemporalLayerCount->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ if ((pH264Enc->hMFCH264Handle.bTemporalSVC == OMX_FALSE) ||
+ (pTemporalLayerCount->nTemporalLayerCount > OMX_VIDEO_ANDROID_MAXAVCTEMPORALLAYERS)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+
+ /* Temporal SVC */
+ pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ pEncOps = pMFCH264Handle->pEncOps;
+
+ Exynos_OSAL_Memset(&TemporalSVC, 0, sizeof(TemporalLayerShareBuffer));
+ TemporalSVC.nTemporalLayerCount = (unsigned int)pTemporalLayerCount->nTemporalLayerCount | GENERAL_TSVC_ENABLE;
+ for (i = 0; i < OMX_VIDEO_ANDROID_MAXAVCTEMPORALLAYERS; i++)
+ TemporalSVC.nTemporalLayerBitrateRatio[i] = 0;
+
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "TemporalSVC.nTemporalLayerCount: %d", TemporalSVC.nTemporalLayerCount & (~GENERAL_TSVC_ENABLE));
+ pEncOps->Set_LayerChange(pMFCH264Handle->hMFCHandle, TemporalSVC);
+ }
+ break;
+ case OMX_IndexSkypeConfigBasePid:
+ {
+ OMX_VIDEO_CONFIG_BASELAYERPID *pBaseLayerPid = (OMX_VIDEO_CONFIG_BASELAYERPID *)pConfigData;
+ EXYNOS_MFC_H264ENC_HANDLE *pMFCH264Handle = NULL;
+ ExynosVideoEncParam *pEncParam = NULL;
+ ExynosVideoEncCommonParam *pCommonParam = NULL;
+ ExynosVideoEncH264Param *pH264Param = NULL;
+ ExynosVideoEncOps *pEncOps = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pBaseLayerPid, sizeof(OMX_VIDEO_CONFIG_BASELAYERPID));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pBaseLayerPid->nPortIndex != OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pMFCH264Handle = &pH264Enc->hMFCH264Handle;
+ pEncParam = &pMFCH264Handle->encParam;
+ pCommonParam = &pEncParam->commonParam;
+ pH264Param = &pEncParam->codecParam.h264;
+ pEncOps = pMFCH264Handle->pEncOps;
+
+ /* TBD */
+ Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pBaseLayerPid->nPID: %d", pBaseLayerPid->nPID);
+ pEncOps->Set_BasePID(pMFCH264Handle->hMFCHandle, pBaseLayerPid->nPID);
+ }
+ break;
+ default:
+ break;
+ }
+
+EXIT:
+
+ FunctionOut();
+
+ return;
+}
+#endif
+
+
+/* DECODE_ONLY */
+#ifdef BUILD_DEC
+/* video dec */
+OMX_ERRORTYPE Exynos_H264Dec_GetExtensionIndex_SkypeHD(
+ 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) {
+ 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 ((cParameterName == NULL) || (pIndexType == NULL)) {
+ ret = OMX_ErrorBadParameter;
+ goto EXIT;
+ }
+ if (pExynosComponent->currentState == OMX_StateInvalid) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, OMX_MS_SKYPE_PARAM_DRIVERVER) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexSkypeParamDriverVersion;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, OMX_MS_SKYPE_PARAM_DECODERSETTING) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexSkypeParamDecoderSetting;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ if (Exynos_OSAL_Strcmp(cParameterName, OMX_MS_SKYPE_PARAM_DECODERCAP) == 0) {
+ *pIndexType = (OMX_INDEXTYPE) OMX_IndexSkypeParamDecoderCapability;
+ ret = OMX_ErrorNone;
+ goto EXIT;
+ }
+
+ ret = OMX_ErrorUnsupportedIndex;
+
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+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)) {
+ 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;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ 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_SkypeHD(pDriverVer, sizeof(OMX_VIDEO_PARAM_DRIVERVER));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pDriverVer->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pDriverVer->nDriverVersion = (OMX_U64)(pH264Dec->hMFCH264Handle.videoInstInfo.SwVersion);
+ }
+ break;
+ case OMX_IndexSkypeParamDecoderCapability:
+ {
+ OMX_VIDEO_PARAM_DECODERCAP *pDecoderCap = (OMX_VIDEO_PARAM_DECODERCAP *)pComponentParameterStructure;
+ OMX_VIDEO_DECODERCAP *pstDecCap = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pDecoderCap, sizeof(OMX_VIDEO_PARAM_DECODERCAP));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pDecoderCap->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pstDecCap = &(pDecoderCap->stDecoderCap);
+
+ /* TBD */
+ pstDecCap->bLowLatency = OMX_TRUE;
+ pstDecCap->nMaxFrameWidth = MAX_FRAME_WIDTH;
+ pstDecCap->nMaxFrameHeight = MAX_FRAME_HEIGHT;
+ pstDecCap->nMaxInstances = RESOURCE_VIDEO_DEC;
+ pstDecCap->nMaxLevel = OMX_VIDEO_AVCLevel42;
+ pstDecCap->nMaxMacroblockProcessingRate = DEC_BLOCKS_PER_SECOND;
+ }
+ break;
+ case OMX_IndexSkypeParamDecoderSetting:
+ {
+ OMX_VIDEO_PARAM_DECODERSETTING *pDecoderSetting = (OMX_VIDEO_PARAM_DECODERSETTING *)pComponentParameterStructure;
+ EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+ OMX_VIDEO_DECODERPARAMS *pstDecParam = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pDecoderSetting, sizeof(OMX_VIDEO_PARAM_DECODERSETTING));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pDecoderSetting->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pstDecParam = &(pDecoderSetting->stDecParam);
+ pstDecParam->bLowLatency = pH264Dec->bLowLatency;
+ }
+ 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) {
+ ret = OMX_ErrorInvalidState;
+ goto EXIT;
+ }
+
+ pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+ pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+
+ switch ((int)nIndex) {
+ case OMX_IndexSkypeParamDecoderSetting:
+ {
+ OMX_VIDEO_PARAM_DECODERSETTING *pDecoderSetting = (OMX_VIDEO_PARAM_DECODERSETTING *)pComponentParameterStructure;
+ OMX_VIDEO_DECODERPARAMS *pstDecParam = NULL;
+
+ ret = Exynos_OMX_Check_SizeVersion_SkypeHD(pDecoderSetting, sizeof(OMX_VIDEO_PARAM_DECODERSETTING));
+ if (ret != OMX_ErrorNone)
+ goto EXIT;
+
+ if (pDecoderSetting->nPortIndex > OUTPUT_PORT_INDEX) {
+ ret = OMX_ErrorBadPortIndex;
+ goto EXIT;
+ }
+
+ pstDecParam = &(pDecoderSetting->stDecParam);
+ pH264Dec->bLowLatency = pstDecParam->bLowLatency;
+ }
+ break;
+ default:
+ ret = OMX_ErrorUnsupportedIndex;
+ break;
+
+ }
+
+EXIT:
+
+ FunctionOut();
+
+ return ret;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*
+ * 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
+
+/* COMMON_ONLY */
+OMX_ERRORTYPE Exynos_OMX_Check_SizeVersion_SkypeHD(OMX_PTR header, OMX_U32 size);
+
+#ifdef BUILD_ENC
+/* ENCODE_ONLY */
+OMX_ERRORTYPE Exynos_H264Enc_GetExtensionIndex_SkypeHD(OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_STRING cParameterName, OMX_OUT OMX_INDEXTYPE *pIndexType);
+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);
+void Change_H264Enc_SkypeHDParam(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR pDynamicConfigCMD);
+#endif
+
+#ifdef BUILD_DEC
+/* DECODE_ONLY */
+OMX_ERRORTYPE Exynos_H264Dec_GetExtensionIndex_SkypeHD(OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_STRING cParameterName, OMX_OUT OMX_INDEXTYPE *pIndexType);
+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
--- /dev/null
+/*
+ *
+ * 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));
+ 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_ThreadCancel(OMX_HANDLETYPE threadHandle)
+{
+ EXYNOS_THREAD_HANDLE_TYPE *thread = (EXYNOS_THREAD_HANDLE_TYPE *)threadHandle;
+
+ if (!thread)
+ return OMX_ErrorBadParameter;
+
+ /* thread_cancel(thread->pthread); */
+ pthread_exit(&thread->pthread);
+ pthread_join(thread->pthread, NULL);
+
+ 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;
+}
--- /dev/null
+/*
+ *
+ * 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_ThreadCancel(OMX_HANDLETYPE threadHandle);
+void Exynos_OSAL_ThreadExit(void *value_ptr);
+void Exynos_OSAL_SleepMillisec(OMX_U32 ms);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+
+ 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
+