| |
| /* |
| * Copyright (C) Texas Instruments - http://www.ti.com/ |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| /* ============================================================================= |
| * Texas Instruments OMAP(TM) Platform Software |
| * (c) Copyright Texas Instruments, Incorporated. All Rights Reserved. |
| * |
| * Use of this software is controlled by the terms and conditions found |
| * in the license agreement under which this software has been supplied. |
| * ============================================================================*/ |
| /** |
| * @file OMX_VideoEnc_Utils.c |
| * |
| * This file implements OMX Component for MPEG-4 encoder that |
| * is fully compliant with the OMX specification 1.5. |
| * |
| * @path $(CSLPATH)\src |
| * |
| * @rev 0.1 |
| */ |
| /* ---------------------------------------------------------------------------*/ |
| /* ============================================================================= |
| *! |
| *! Revision History |
| *! ============================================================================= |
| *! |
| *! 02-Feb-2006 mf: Revisions appear in reverse chronological order; |
| *! that is, newest first. The date format is dd-Mon-yyyy. |
| * ============================================================================*/ |
| |
| /* ------compilation control switches ----------------------------------------*/ |
| /****************************************************************************** |
| * INCLUDE FILES |
| *******************************************************************************/ |
| /* ----- system and platform files -------------------------------------------*/ |
| #ifdef UNDER_CE |
| #include <windows.h> |
| #include <omx_core.h> |
| #include <stdlib.h> |
| #include <pthread.h> |
| #else |
| #include <wchar.h> |
| #include <unistd.h> |
| #include <sys/types.h> |
| #include <sys/wait.h> |
| #include <sys/types.h> |
| #include <sys/select.h> |
| #include <sys/stat.h> |
| #include <dlfcn.h> |
| #include <malloc.h> |
| #include <memory.h> |
| #include <fcntl.h> |
| #endif |
| |
| #include <dbapi.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| |
| /*------- Program Header Files -----------------------------------------------*/ |
| #include "OMX_VideoEnc_Utils.h" |
| #include "OMX_VideoEnc_Thread.h" |
| #include "OMX_VideoEnc_DSP.h" |
| |
| #define DSP_MMU_FAULT_HANDLING |
| |
| // We cannot request the same MHz for all resolutions. |
| // we have to change this implementation once we modify |
| // opencore to request the correct level based on resolution/bitrate/etc |
| #define VIDEO_ENCODER_MHZ (400 - 45 + 2) |
| |
| /* H264 Specific */ |
| #define SPS_CODE_PREFIX 0x07 |
| #define PPS_CODE_PREFIX 0x08 |
| |
| #ifdef UNDER_CE |
| HINSTANCE g_hLcmlDllHandle = NULL; |
| #endif |
| #ifdef UNDER_CE |
| void sleep(DWORD Duration) |
| { |
| Sleep(Duration); |
| } |
| #endif |
| /******************************************************************************* |
| * EXTERNAL REFERENCES NOTE : only use if not found in header file |
| *******************************************************************************/ |
| /*--------data declarations --------------------------------------------------*/ |
| /*--------function prototypes ------------------------------------------------*/ |
| |
| /******************************************************************************* |
| * PUBLIC DECLARATIONS Defined here, used elsewhere |
| *******************************************************************************/ |
| /*--------data declarations --------------------------------------------------*/ |
| |
| |
| /*--------function prototypes ------------------------------------------------*/ |
| |
| /******************************************************************************* |
| * PRIVATE DECLARATIONS Defined here, used only here |
| *******************************************************************************/ |
| /*--------data declarations --------------------------------------------------*/ |
| struct DSP_UUID H264VESOCKET_TI_UUID = { |
| 0x63A3581A, 0x09D7, 0x4AD0, 0x80, 0xB8, { |
| 0x5F, 0x2C, 0x4D, 0x4D, 0x59, 0xC9 |
| } |
| }; |
| |
| struct DSP_UUID MP4VESOCKET_TI_UUID = { |
| 0x98c2e8d8, 0x4644, 0x11d6, 0x81, 0x18, { |
| 0x00, 0xb0, 0xd0, 0x8d, 0x72, 0x9f |
| } |
| }; |
| |
| struct DSP_UUID USN_UUID = { |
| 0x79A3C8B3, 0x95F2, 0x403F, 0x9A, 0x4B, { |
| 0xCF, 0x80, 0x57, 0x73, 0x05, 0x41 |
| } |
| }; |
| |
| OMX_U32 VIDENC_STRUCT_H264DEFBITRATE [VIDENC_MAXBITRATES][2] = { |
| /*1*/ {176 * 144, 128000}, /*128KBps*/ |
| /*2*/ {320 * 240, 400000}, /*400KBps*/ |
| /*3*/ {352 * 288, 500000}, /*500kBps*/ |
| /*4*/ {640 * 480, 1500000}, /*1.5MBps*/ |
| /*5*/ {720 * 480, 2000000}, /*2MBps*/ |
| /*6*/ {720 * 576, 3000000}, /*3MBps*/ |
| /*7*/ {1280 * 720, 3000000}, /*3MBps*/ |
| }; |
| |
| OMX_U32 VIDENC_STRUCT_MPEG4DEFBITRATE [VIDENC_MAXBITRATES][2] = { |
| /*1*/ {176 * 144, 128000}, /*128KBps*/ |
| /*2*/ {320 * 240, 400000}, /*400KBps*/ |
| /*3*/ {352 * 288, 500000}, /*500kBps*/ |
| /*4*/ {640 * 480, 1500000}, /*1.5MBps*/ |
| /*5*/ {720 * 480, 2000000}, /*2MBps*/ |
| /*6*/ {720 * 576, 3000000}, /*3MBps*/ |
| /*7*/ {1280 * 720, 3000000}, /*3MBps*/ |
| }; |
| |
| OMX_U32 VIDENC_STRUCT_H263DEFBITRATE [VIDENC_MAXBITRATES][2] = { |
| /*1*/ {176 * 144, 128000}, /*128KBps*/ |
| /*2*/ {320 * 240, 400000}, /*400KBps*/ |
| /*3*/ {352 * 288, 500000}, /*500kBps*/ |
| /*4*/ {640 * 480, 1500000}, /*1.5MBps*/ |
| /*5*/ {720 * 480, 2000000}, /*2MBps*/ |
| /*6*/ {720 * 576, 3000000}, /*3MBps*/ |
| /*7*/ {1280 * 720, 3000000}, /*3MBps*/ |
| }; |
| /*--------macro definitions ---------------------------------------------------*/ |
| |
| static const int iQ16_Const = 1 << 16; |
| static const float fQ16_Const = (float)(1 << 16); |
| |
| static float Q16Tof(int nQ16) |
| { |
| return nQ16 / fQ16_Const; |
| } |
| |
| |
| |
| /*-----------------------------------------------------------------------------*/ |
| /** |
| * ListCreate() |
| * |
| * Function call in OMX_ComponentInit(). Creates the List Head of the Component Memory List. |
| * |
| * @param pListHead VIDENC_NODE double pointer with the List Header of the Memory List. |
| * |
| * @retval OMX_ErrorNone |
| * OMX_ErrorInsufficientResources if the malloc fails |
| * |
| **/ |
| /*-----------------------------------------------------------------------------*/ |
| OMX_ERRORTYPE OMX_VIDENC_ListCreate(struct OMX_TI_Debug *dbg, struct VIDENC_NODE** pListHead) |
| { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| |
| *pListHead = (VIDENC_NODE*)malloc(sizeof(VIDENC_NODE)); /* need to malloc!!! */ |
| if (*pListHead == NULL) |
| { |
| OMX_TRACE4(*dbg, "malloc() out of memory error\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorInsufficientResources); |
| } |
| |
| OMX_TRACE1(*dbg, "Create MemoryListHeader[%p]\n", *pListHead); |
| memset(*pListHead, 0x0, sizeof(VIDENC_NODE)); |
| |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*-----------------------------------------------------------------------------*/ |
| /** |
| * ListAdd() |
| * |
| * Called inside VIDENC_MALLOC Macro to add a new node to Component Memory List |
| * |
| * @param pListHead VIDENC_NODE Points List Header of the Memory List. |
| * pData OMX_PTR points to the new allocated data. |
| * @retval OMX_ErrorNone |
| * OMX_ErrorInsufficientResources if the malloc fails |
| * |
| **/ |
| /*-----------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_ListAdd(struct OMX_TI_Debug *dbg, struct VIDENC_NODE* pListHead, OMX_PTR pData) |
| { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| VIDENC_NODE* pTmp = NULL; |
| VIDENC_NODE* pNewNode = NULL; |
| pNewNode = (VIDENC_NODE*)malloc(sizeof(VIDENC_NODE)); /* need to malloc!!! */ |
| if (pNewNode == NULL) |
| { |
| OMX_TRACE4(*dbg, "malloc() out of memory error\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorInsufficientResources); |
| } |
| memset(pNewNode, 0x0, sizeof(VIDENC_NODE)); |
| pNewNode->pData = pData; |
| pNewNode->pNext = NULL; |
| OMX_TRACE1(*dbg, "Add MemoryNode[%p] -> [%p]\n", pNewNode, pNewNode->pData); |
| pTmp = pListHead; |
| |
| while (pTmp->pNext != NULL) |
| { |
| pTmp = pTmp->pNext; |
| } |
| pTmp->pNext = pNewNode; |
| |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*-----------------------------------------------------------------------------*/ |
| /** |
| * ListRemove() |
| * |
| * Called inside VIDENC_FREE Macro remove node from Component Memory List and free the memory pointed by the node. |
| * |
| * @param pListHead VIDENC_NODE Points List Header of the Memory List. |
| * pData OMX_PTR points to the new allocated data. |
| * @retval OMX_ErrorNone |
| * |
| * |
| **/ |
| /*-----------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_ListRemove(struct OMX_TI_Debug *dbg, struct VIDENC_NODE* pListHead, |
| OMX_PTR pData) |
| { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| VIDENC_NODE* pNode = NULL; |
| VIDENC_NODE* pTmp = NULL; |
| |
| pNode = pListHead; |
| |
| while (pNode->pNext != NULL) |
| { |
| if (pNode->pNext->pData == pData) |
| { |
| pTmp = pNode->pNext; |
| pNode->pNext = pTmp->pNext; |
| OMX_TRACE1(*dbg, "Remove MemoryNode[%p] -> [%p]\n", pTmp, pTmp->pData); |
| free(pTmp->pData); |
| free(pTmp); |
| pTmp = NULL; |
| break; |
| /* VIDENC_ListPrint2(pListHead); */ |
| } |
| pNode = pNode->pNext; |
| } |
| return eError; |
| } |
| |
| /*-----------------------------------------------------------------------------*/ |
| /** |
| * ListDestroy() |
| * |
| * Called inside OMX_ComponentDeInit() Remove all nodes and free all the memory in the Component Memory List. |
| * |
| * @param pListHead VIDENC_NODE Points List Header of the Memory List. |
| * |
| * @retval OMX_ErrorNone |
| * |
| * |
| **/ |
| /*-----------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_ListDestroy(struct OMX_TI_Debug *dbg, struct VIDENC_NODE* pListHead) |
| { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| VIDENC_NODE* pTmp = NULL; |
| VIDENC_NODE* pNode = NULL; |
| pNode = pListHead; |
| |
| while (pNode->pNext != NULL) |
| { |
| pTmp = pNode->pNext; |
| pNode->pNext=pTmp->pNext; |
| if (pTmp->pData != NULL) |
| { |
| OMX_TRACE0(*dbg, "Remove MemoryNode[%p] -> [%p]\n", pTmp, pTmp->pData); |
| free(pTmp->pData); |
| pTmp->pData = NULL; |
| } |
| free(pTmp); |
| pTmp = NULL; |
| } |
| |
| OMX_TRACE1(*dbg, "Destroy MemoryListHeader[%p]\n", pListHead); |
| free(pListHead); |
| return eError; |
| } |
| |
| |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_EmptyDataPipes Wait until all buffers are processed |
| * |
| * @param pComponentPrivate pointer to the private video encoder structure |
| * |
| * @return None |
| * |
| **/ |
| /*---------------------------------------------------------------------------------------*/ |
| void OMX_VIDENC_EmptyDataPipes (VIDENC_COMPONENT_PRIVATE *pComponentPrivate) |
| { |
| pthread_mutex_lock(&bufferReturned_mutex); |
| while (pComponentPrivate->EmptythisbufferCount != pComponentPrivate->EmptybufferdoneCount || |
| pComponentPrivate->FillthisbufferCount != pComponentPrivate->FillbufferdoneCount) { |
| pthread_cond_wait(&bufferReturned_condition, &bufferReturned_mutex); |
| } |
| pthread_mutex_unlock(&bufferReturned_mutex); |
| LOGI("Video encoder has returned all buffers"); |
| } |
| |
| void OMX_VIDENC_IncrementBufferCountByOne(OMX_U32 *count) |
| { |
| pthread_mutex_lock(&bufferReturned_mutex); |
| (*count)++; |
| pthread_mutex_unlock(&bufferReturned_mutex); |
| } |
| |
| void OMX_VIDENC_SignalIfAllBuffersAreReturned(VIDENC_COMPONENT_PRIVATE *pComponentPrivate) |
| { |
| pthread_mutex_lock(&bufferReturned_mutex); |
| if ((pComponentPrivate->EmptythisbufferCount == pComponentPrivate->EmptybufferdoneCount) && |
| (pComponentPrivate->FillthisbufferCount == pComponentPrivate->FillbufferdoneCount)) { |
| pthread_cond_broadcast(&bufferReturned_condition); |
| LOGI("Sending pthread signal that video encoder has returned all buffers to app"); |
| } |
| pthread_mutex_unlock(&bufferReturned_mutex); |
| } |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_HandleError() will handle the error and pass the component to Invalid |
| * State, and send the event to the client. |
| * @param eError - OMX_ERRORTYPE that occur. |
| * |
| * @retval OMX_NoError Success, ready to roll |
| * OMX_Error_BadParameter The input parameter pointer is null |
| **/ |
| /*---------------------------------------------------------------------------------------*/ |
| OMX_ERRORTYPE OMX_VIDENC_HandleError(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, |
| OMX_ERRORTYPE eErrorCmp) |
| { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pComponentPrivate->bHandlingFatalError = OMX_TRUE; |
| |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| eErrorCmp, |
| OMX_TI_ErrorSevere, |
| NULL); |
| |
| switch (eErrorCmp) |
| { |
| case OMX_ErrorBadParameter: |
| case OMX_ErrorPortUnresponsiveDuringAllocation: |
| case OMX_ErrorUnsupportedIndex: |
| case OMX_ErrorInsufficientResources: |
| goto OMX_CONF_CMD_BAIL; |
| default: |
| ; |
| } |
| |
| pComponentPrivate->bHideEvents = OMX_TRUE; |
| |
| eError = eErrorCmp; |
| pComponentPrivate->eState = OMX_StateInvalid; |
| |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorInvalidState, |
| OMX_TI_ErrorCritical, |
| NULL); |
| |
| OMX_CONF_CMD_BAIL: |
| if (pComponentPrivate) |
| pComponentPrivate->bHandlingFatalError = OMX_FALSE; |
| return eError; |
| } |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_HandleLcmlEvent() will handle the event from the LCML |
| * thread. |
| * @param eError - OMX_ERRORTYPE that occur. |
| * |
| * @retval OMX_NoError Success, ready to roll |
| * OMX_Error_BadParameter The input parameter pointer is null |
| **/ |
| /*---------------------------------------------------------------------------------------*/ |
| OMX_ERRORTYPE OMX_VIDENC_HandleLcmlEvent(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, |
| TUsnCodecEvent eEvent, void* argsCb []) |
| { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| switch(eEvent) |
| { |
| case EMMCodecDspMessageRecieved: |
| OMX_PRDSP1(pComponentPrivate->dbg, "EMMCodecDspMessageRecieved\n"); |
| break; |
| case EMMCodecBufferProcessed: |
| OMX_PRDSP1(pComponentPrivate->dbg, "EMMCodecBufferProcessed\n"); |
| break; |
| case EMMCodecProcessingStarted: |
| OMX_PRDSP1(pComponentPrivate->dbg, "EMMCodecProcessingStarted\n"); |
| break; |
| case EMMCodecProcessingPaused: |
| OMX_PRDSP1(pComponentPrivate->dbg, "EMMCodecProcessingPaused\n"); |
| break; |
| case EMMCodecProcessingStoped: |
| OMX_PRDSP1(pComponentPrivate->dbg, "EMMCodecProcessingStoped\n"); |
| break; |
| case EMMCodecProcessingEof: |
| OMX_PRDSP1(pComponentPrivate->dbg, "EMMCodecProcessingEof\n"); |
| break; |
| case EMMCodecBufferNotProcessed: |
| OMX_PRDSP1(pComponentPrivate->dbg, "EMMCodecBufferNotProcessed\n"); |
| break; |
| case EMMCodecAlgCtrlAck: |
| OMX_PRDSP1(pComponentPrivate->dbg, "EMMCodecAlgCtrlAck\n"); |
| break; |
| case EMMCodecStrmCtrlAck: |
| OMX_PRDSP1(pComponentPrivate->dbg, "EMMCodecStrmCtrlAck\n"); |
| break; |
| case EMMCodecInternalError: |
| OMX_PRDSP2(pComponentPrivate->dbg, "EMMCodecInternalError\n"); |
| #ifdef DSP_MMU_FAULT_HANDLING |
| if((argsCb[4] == (void *)USN_ERR_UNKNOWN_MSG) && (argsCb[5] == (void*)NULL)) |
| { |
| OMX_VIDENC_SET_ERROR_BAIL(eError, OMX_ErrorInvalidState, pComponentPrivate); |
| } |
| else |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorHardware, |
| OMX_TI_ErrorCritical, |
| "Error Hardware\n"); |
| eError = OMX_ErrorHardware; |
| } |
| #else |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorHardware, |
| OMX_TI_ErrorCritical, |
| "Error Hardware\n"); |
| eError = OMX_ErrorHardware; |
| #endif |
| break; |
| case EMMCodecInitError: |
| OMX_PRDSP2(pComponentPrivate->dbg, "EMMCodecInitError\n"); |
| #ifdef DSP_MMU_FAULT_HANDLING |
| if((argsCb[4] == (void *)USN_ERR_UNKNOWN_MSG) && (argsCb[5] == (void*)NULL)) |
| { |
| OMX_VIDENC_SET_ERROR_BAIL(eError, OMX_ErrorInvalidState, pComponentPrivate); |
| } |
| else |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorHardware, |
| OMX_TI_ErrorCritical, |
| "Error Hardware\n"); |
| eError = OMX_ErrorHardware; |
| } |
| #else |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorHardware, |
| OMX_TI_ErrorCritical, |
| "Error Hardware\n"); |
| eError = OMX_ErrorHardware; |
| #endif |
| break; |
| case EMMCodecDspError: |
| OMX_PRDSP2(pComponentPrivate->dbg, "EMMCodecDspError\n"); |
| #ifdef DSP_MMU_FAULT_HANDLING |
| if((argsCb[4] == (void *)NULL) && (argsCb[5] == (void*)NULL)) |
| { |
| OMX_VIDENC_SET_ERROR_BAIL(eError, OMX_ErrorInvalidState, pComponentPrivate); |
| } |
| else |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorHardware, |
| OMX_TI_ErrorCritical, |
| "Error Hardware\n"); |
| eError = OMX_ErrorHardware; |
| } |
| #else |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorHardware, |
| OMX_TI_ErrorCritical, |
| "Error Hardware\n"); |
| eError = OMX_ErrorHardware; |
| #endif |
| break; |
| } |
| |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*-----------------------------------------------------------------------------*/ |
| /** |
| * Disable Port() |
| * |
| * Called by component thread, handles commands sent by the app. |
| * |
| * @param |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * |
| **/ |
| /*-----------------------------------------------------------------------------*/ |
| OMX_ERRORTYPE OMX_VIDENC_HandleCommandDisablePort (VIDENC_COMPONENT_PRIVATE* pComponentPrivate, |
| OMX_U32 nParam1) |
| { |
| OMX_U8 i = 0; |
| OMX_BOOL bFlushFlag; |
| OMX_COMPONENTTYPE* pHandle = NULL; |
| VIDENC_NODE* pMemoryListHead = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| VIDEOENC_PORT_TYPE* pCompPortIn = NULL; |
| VIDEOENC_PORT_TYPE* pCompPortOut = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefIn = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pHandle = (OMX_COMPONENTTYPE*)pComponentPrivate->pHandle; |
| pCompPortIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]; |
| pCompPortOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]; |
| pPortDefIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->pPortDef; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| pMemoryListHead = pComponentPrivate->pMemoryListHead; |
| |
| OMX_DBG_CHECK_CMD(pComponentPrivate->dbg, pHandle, pPortDefIn, pPortDefOut); |
| |
| if (nParam1 == VIDENC_INPUT_PORT || nParam1 == (OMX_U32)-1) |
| { |
| /* Flush the DSP side before sending buffers back to the client */ |
| bFlushFlag = OMX_FALSE; |
| for (i = 0; i < pPortDefIn->nBufferCountActual; i++) |
| { |
| if(pCompPortIn->pBufferPrivate[i]->eBufferOwner != VIDENC_BUFFER_WITH_CLIENT) |
| { |
| bFlushFlag = OMX_TRUE; |
| } |
| } |
| |
| if(bFlushFlag == OMX_TRUE) |
| { |
| eError = OMX_VIDENC_HandleCommandFlush(pComponentPrivate, VIDENC_INPUT_PORT, OMX_TRUE); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRBUFFER3, |
| "Flush command failed (%x)\n", eError); |
| bFlushFlag = OMX_FALSE; |
| } |
| |
| /*Return buffer to client*/ |
| if (pCompPortIn->hTunnelComponent == NULL) |
| { |
| for (i = 0; i < pPortDefIn->nBufferCountActual; i++) |
| { |
| if (pCompPortIn->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_COMPONENT || |
| pCompPortIn->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_DSP) |
| { |
| pCompPortIn->pBufferPrivate[i]->eBufferOwner = VIDENC_BUFFER_WITH_CLIENT; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| PREF(pCompPortIn->pBufferPrivate[i]->pBufferHdr, pBuffer), |
| 0, |
| PERF_ModuleHLMM); |
| #endif |
| pComponentPrivate->sCbData.EmptyBufferDone(pComponentPrivate->pHandle, |
| pComponentPrivate->pHandle->pApplicationPrivate, |
| pCompPortIn->pBufferPrivate[i]->pBufferHdr); |
| OMX_VIDENC_IncrementBufferCountByOne(&pComponentPrivate->EmptybufferdoneCount); |
| OMX_VIDENC_SignalIfAllBuffersAreReturned(pComponentPrivate); |
| } |
| } |
| } |
| else |
| { |
| for (i = 0; i < pPortDefIn->nBufferCountActual; i++) |
| { |
| if (pCompPortIn->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_COMPONENT || |
| pCompPortIn->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_DSP) |
| { |
| pCompPortIn->pBufferPrivate[i]->eBufferOwner = VIDENC_BUFFER_WITH_TUNNELEDCOMP; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| PREF(pCompPortIn->pBufferPrivate[i]->pBufferHdr, pBuffer), |
| 0, |
| PERF_ModuleLLMM); |
| #endif |
| eError = OMX_FillThisBuffer(pCompPortIn->hTunnelComponent, |
| pCompPortIn->pBufferPrivate[i]->pBufferHdr); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRBUFFER4, |
| "FillThisBuffer failed (%x)\n", eError); |
| } |
| } |
| } |
| } |
| if (nParam1 == VIDENC_OUTPUT_PORT || nParam1 == (OMX_U32)-1) |
| { |
| /* Flush the DSP side before sending buffers back to the client */ |
| bFlushFlag = OMX_FALSE; |
| for (i = 0; i < pPortDefOut->nBufferCountActual; i++) |
| { |
| if(pCompPortOut->pBufferPrivate[i]->eBufferOwner != VIDENC_BUFFER_WITH_CLIENT) |
| { |
| bFlushFlag = OMX_TRUE; |
| } |
| } |
| |
| if(bFlushFlag == OMX_TRUE) |
| { |
| eError = OMX_VIDENC_HandleCommandFlush(pComponentPrivate, VIDENC_OUTPUT_PORT, OMX_TRUE); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRBUFFER3, |
| "Flush command failed (%x)\n", eError); |
| bFlushFlag = OMX_FALSE; |
| } |
| |
| /*Return buffer to client*/ |
| if (pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->hTunnelComponent == NULL) |
| { |
| for (i = 0; i < pPortDefOut->nBufferCountActual; i++) |
| { |
| if (pCompPortOut->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_COMPONENT || |
| pCompPortOut->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_DSP) |
| { |
| |
| pCompPortOut->pBufferPrivate[i]->eBufferOwner = VIDENC_BUFFER_WITH_CLIENT; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| pCompPortOut->pBufferPrivate[i]->pBufferHdr ? |
| pCompPortOut->pBufferPrivate[i]->pBufferHdr->pBuffer : |
| NULL, |
| pCompPortOut->pBufferPrivate[i]->pBufferHdr ? |
| pCompPortOut->pBufferPrivate[i]->pBufferHdr->nFilledLen : |
| 0, |
| PERF_ModuleHLMM); |
| #endif |
| OMX_CONF_CIRCULAR_BUFFER_MOVE_HEAD(pCompPortOut->pBufferPrivate[i]->pBufferHdr, |
| pComponentPrivate->sCircularBuffer, |
| pComponentPrivate); |
| /* trigger event handler if we are supposed to */ |
| if (pCompPortOut->pBufferPrivate[i]->pBufferHdr->hMarkTargetComponent == pComponentPrivate->pHandle && |
| pCompPortOut->pBufferPrivate[i]->pBufferHdr->pMarkData) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventMark, |
| 0x0, |
| 0x0, |
| pCompPortOut->pBufferPrivate[i]->pBufferHdr->pMarkData); |
| } |
| pComponentPrivate->sCbData.FillBufferDone(pComponentPrivate->pHandle, |
| pComponentPrivate->pHandle->pApplicationPrivate, |
| pCompPortOut->pBufferPrivate[i]->pBufferHdr); |
| OMX_VIDENC_IncrementBufferCountByOne(&pComponentPrivate->FillbufferdoneCount); |
| OMX_VIDENC_SignalIfAllBuffersAreReturned(pComponentPrivate); |
| } |
| } |
| } |
| else |
| { |
| /* If tunneled with VPP - NOT Implemented*/ |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| PREF(pCompPortOut->pBufferPrivate[i]->pBufferHdr,pBuffer), |
| PREF(pCompPortOut->pBufferPrivate[i]->pBufferHdr,nFilledLen), |
| PERF_ModuleLLMM); |
| #endif |
| } |
| } |
| |
| OMX_PRBUFFER2(pComponentPrivate->dbg, "Flushing Pipes!\n"); |
| OMX_VIDENC_EmptyDataPipes (pComponentPrivate); |
| |
| /*while (1) |
| {*/ |
| |
| if (nParam1 == VIDENC_INPUT_PORT) |
| { |
| while ((pPortDefIn->bPopulated)) |
| { |
| /*Send event*/ |
| #ifndef UNDER_CE |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| pthread_cond_wait(&pComponentPrivate->unpopulate_cond, &pComponentPrivate->videoe_mutex_app); |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| #else |
| OMX_WaitForEvent(&(pComponentPrivate->InIdle_event)); |
| #endif |
| break; |
| } |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandPortDisable, |
| VIDENC_INPUT_PORT, |
| NULL); |
| |
| } |
| |
| else if (nParam1 == VIDENC_OUTPUT_PORT) |
| { |
| while ((pPortDefOut->bPopulated)) |
| { |
| /*Send event*/ |
| #ifndef UNDER_CE |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| pthread_cond_wait(&pComponentPrivate->unpopulate_cond, &pComponentPrivate->videoe_mutex_app); |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| #else |
| OMX_WaitForEvent(&(pComponentPrivate->InIdle_event)); |
| #endif |
| break; |
| } |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandPortDisable, |
| VIDENC_OUTPUT_PORT, |
| NULL); |
| |
| } |
| |
| else if (nParam1 == (OMX_U32)-1) |
| { |
| while ((pPortDefIn->bPopulated) || (pPortDefOut->bPopulated)) |
| { |
| /*Send events*/ |
| #ifndef UNDER_CE |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| pthread_cond_wait(&pComponentPrivate->unpopulate_cond, &pComponentPrivate->videoe_mutex_app); |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| #else |
| OMX_WaitForEvent(&(pComponentPrivate->InIdle_event)); |
| #endif |
| break; |
| } |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandPortDisable, |
| VIDENC_INPUT_PORT, |
| NULL); |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandPortDisable, |
| VIDENC_OUTPUT_PORT, |
| NULL); |
| |
| |
| } |
| |
| |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*-----------------------------------------------------------------------------*/ |
| /** |
| * Enable Port() |
| * |
| * Called by component thread, handles commands sent by the app. |
| * |
| * @param |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * |
| **/ |
| /*-----------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_HandleCommandEnablePort (VIDENC_COMPONENT_PRIVATE* pComponentPrivate, |
| OMX_U32 nParam1) |
| { |
| OMX_U32 nTimeout = 0x0; |
| OMX_COMPONENTTYPE* pHandle = NULL; |
| VIDENC_NODE* pMemoryListHead = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefIn = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pHandle = (OMX_COMPONENTTYPE*)pComponentPrivate->pHandle; |
| pPortDefIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->pPortDef; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| pMemoryListHead = pComponentPrivate->pMemoryListHead; |
| |
| nTimeout = 0x0; |
| /*while(1) |
| {*/ |
| if(nParam1 == VIDENC_INPUT_PORT) |
| { |
| if (pComponentPrivate->eState != OMX_StateLoaded) |
| { |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| while (!pPortDefIn->bPopulated) |
| { |
| #ifndef UNDER_CE |
| pthread_cond_wait(&pComponentPrivate->populate_cond, &pComponentPrivate->videoe_mutex_app); |
| #else |
| OMX_WaitForEvent(&(pComponentPrivate->InIdle_event)); |
| #endif |
| |
| } |
| } |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandPortEnable, |
| VIDENC_INPUT_PORT, |
| NULL); |
| |
| |
| } |
| else if(nParam1 == VIDENC_OUTPUT_PORT) |
| { |
| if (pComponentPrivate->eState != OMX_StateLoaded) |
| { |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| while(!pPortDefOut->bPopulated) |
| { |
| #ifndef UNDER_CE |
| pthread_cond_wait(&pComponentPrivate->populate_cond, &pComponentPrivate->videoe_mutex_app); |
| #else |
| OMX_WaitForEvent(&(pComponentPrivate->InIdle_event)); |
| #endif |
| |
| } |
| } |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandPortEnable, |
| VIDENC_OUTPUT_PORT, |
| NULL); |
| |
| |
| } |
| else if(nParam1 == (OMX_U32)-1) |
| { |
| if (pComponentPrivate->eState != OMX_StateLoaded) |
| { |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| while(!pPortDefOut->bPopulated && !pPortDefIn->bPopulated) |
| { |
| #ifndef UNDER_CE |
| pthread_cond_wait(&pComponentPrivate->populate_cond, &pComponentPrivate->videoe_mutex_app); |
| #else |
| OMX_WaitForEvent(&(pComponentPrivate->InIdle_event)); |
| #endif |
| break; |
| } |
| } |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandPortEnable, |
| VIDENC_INPUT_PORT, |
| NULL); |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandPortEnable, |
| VIDENC_OUTPUT_PORT, |
| NULL); |
| |
| |
| } |
| |
| |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /** |
| * OMX_OMX_VIDENC_HandleCommandFlush() |
| * |
| * Called by component thread, handles commands sent by the app. |
| * |
| * @param phandle LCML_DSP_INTERFACE handle for this instance of the component |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * OMX_ErrorInsufficientResources if the malloc fails |
| **/ |
| /*----------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_HandleCommandFlush(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, |
| OMX_U32 nParam1, |
| OMX_BOOL bInternalFlush) |
| { |
| OMX_U16 i = 0; |
| OMX_U32 aParam[3] = {0}; |
| OMX_COMPONENTTYPE* pHandle = NULL; |
| VIDENC_NODE* pMemoryListHead = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| LCML_DSP_INTERFACE* pLcmlHandle = NULL; |
| VIDEOENC_PORT_TYPE* pCompPortIn = NULL; |
| VIDEOENC_PORT_TYPE* pCompPortOut = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefIn = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; |
| pCompPortIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]; |
| pCompPortOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]; |
| pPortDefIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->pPortDef; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| pHandle = (OMX_COMPONENTTYPE*)pComponentPrivate->pHandle; |
| pMemoryListHead = pComponentPrivate->pMemoryListHead; |
| |
| if (nParam1 == VIDENC_INPUT_PORT || nParam1 == (OMX_U32)-1) |
| { |
| aParam[0] = USN_STRMCMD_FLUSH; |
| aParam[1] = VIDENC_INPUT_PORT; |
| aParam[2] = 0x0; |
| |
| eError = LCML_ControlCodec(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, |
| EMMCodecControlStrmCtrl, |
| (void*)aParam); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRDSP4, |
| "DSP Input flush failed (%x).\n", eError); |
| |
| #ifndef UNDER_CE |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| while (pComponentPrivate->bFlushComplete == OMX_FALSE) |
| { |
| pthread_cond_wait(&pComponentPrivate->flush_cond, &pComponentPrivate->videoe_mutex_app); |
| } |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| #else |
| while (pComponentPrivate->bFlushComplete == OMX_FALSE) |
| { |
| sched_yield(); |
| } |
| #endif |
| |
| pComponentPrivate->bFlushComplete = OMX_FALSE; |
| |
| if (pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->hTunnelComponent == NULL) |
| { |
| for (i = 0; i < pPortDefIn->nBufferCountActual; i++) |
| { |
| if (pCompPortIn->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_COMPONENT || |
| pCompPortIn->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_DSP) |
| { |
| |
| pCompPortIn->pBufferPrivate[i]->eBufferOwner = VIDENC_BUFFER_WITH_CLIENT; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| PREF(pCompPortIn->pBufferPrivate[i]->pBufferHdr,pBuffer), |
| 0, |
| PERF_ModuleHLMM); |
| #endif |
| pComponentPrivate->sCbData.EmptyBufferDone(pComponentPrivate->pHandle, |
| pComponentPrivate->pHandle->pApplicationPrivate, |
| pCompPortIn->pBufferPrivate[i]->pBufferHdr); |
| OMX_VIDENC_IncrementBufferCountByOne(&pComponentPrivate->EmptybufferdoneCount); |
| OMX_VIDENC_SignalIfAllBuffersAreReturned(pComponentPrivate); |
| } |
| } |
| } |
| else |
| { |
| for (i = 0; i < pPortDefIn->nBufferCountActual; i++) |
| { |
| if (pCompPortIn->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_COMPONENT || |
| pCompPortIn->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_DSP) |
| { |
| |
| pCompPortIn->pBufferPrivate[i]->eBufferOwner = VIDENC_BUFFER_WITH_TUNNELEDCOMP; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| PREF(pCompPortOut->pBufferPrivate[i]->pBufferHdr,pBuffer), |
| 0, |
| PERF_ModuleLLMM); |
| #endif |
| eError = OMX_FillThisBuffer(pCompPortIn->hTunnelComponent, |
| pCompPortIn->pBufferPrivate[i]->pBufferHdr); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRBUFFER4, |
| "FillThisBuffer failed (%x)\n", eError); |
| } |
| } |
| } |
| if (bInternalFlush == OMX_FALSE) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandFlush, |
| VIDENC_INPUT_PORT, |
| NULL); |
| } |
| } |
| if (nParam1 == VIDENC_OUTPUT_PORT || nParam1 == (OMX_U32)-1) |
| { |
| aParam[0] = USN_STRMCMD_FLUSH; |
| aParam[1] = VIDENC_OUTPUT_PORT; |
| aParam[2] = 0x0; |
| |
| eError = LCML_ControlCodec(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, |
| EMMCodecControlStrmCtrl, |
| (void*)aParam); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRDSP4, |
| "DSP Output flush failed (%x).\n", eError); |
| #ifndef UNDER_CE |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| while (pComponentPrivate->bFlushComplete == OMX_FALSE) |
| { |
| pthread_cond_wait(&pComponentPrivate->flush_cond, &pComponentPrivate->videoe_mutex_app); |
| } |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| #else |
| while (pComponentPrivate->bFlushComplete == OMX_FALSE) |
| { |
| sched_yield(); |
| } |
| #endif |
| |
| pComponentPrivate->bFlushComplete = OMX_FALSE; |
| |
| if (pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->hTunnelComponent == NULL) |
| { |
| for (i = 0; i < pPortDefOut->nBufferCountActual; i++) |
| { |
| if (pCompPortOut->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_COMPONENT || |
| pCompPortOut->pBufferPrivate[i]->eBufferOwner == VIDENC_BUFFER_WITH_DSP) |
| { |
| |
| pCompPortOut->pBufferPrivate[i]->eBufferOwner = VIDENC_BUFFER_WITH_CLIENT; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| PREF(pCompPortOut->pBufferPrivate[i]->pBufferHdr,pBuffer), |
| PREF(pCompPortOut->pBufferPrivate[i]->pBufferHdr,nFilledLen), |
| PERF_ModuleHLMM); |
| #endif |
| /*Copy Buffer Data to be propagated*/ |
| OMX_CONF_CIRCULAR_BUFFER_MOVE_HEAD(pCompPortOut->pBufferPrivate[i]->pBufferHdr, |
| pComponentPrivate->sCircularBuffer, |
| pComponentPrivate); |
| /* trigger event handler if we are supposed to */ |
| if (pCompPortOut->pBufferPrivate[i]->pBufferHdr->hMarkTargetComponent == pComponentPrivate->pHandle && |
| pCompPortOut->pBufferPrivate[i]->pBufferHdr->pMarkData) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventMark, |
| 0x0, |
| 0x0, |
| pCompPortOut->pBufferPrivate[i]->pBufferHdr->pMarkData); |
| } |
| pComponentPrivate->sCbData.FillBufferDone(pComponentPrivate->pHandle, |
| pComponentPrivate->pHandle->pApplicationPrivate, |
| pCompPortOut->pBufferPrivate[i]->pBufferHdr); |
| OMX_VIDENC_IncrementBufferCountByOne(&pComponentPrivate->FillbufferdoneCount); |
| OMX_VIDENC_SignalIfAllBuffersAreReturned(pComponentPrivate); |
| } |
| } |
| } |
| else |
| { |
| /* If tunneled with VPP - NOT Implemented*/ |
| } |
| if (bInternalFlush == OMX_FALSE) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandFlush, |
| VIDENC_OUTPUT_PORT, |
| NULL); |
| } |
| } |
| |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_HandleCommand() |
| * |
| * Called by component thread, handles commands sent by the app. |
| * |
| * @param phandle LCML_DSP_INTERFACE handle for this instance of the component |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * OMX_ErrorInsufficientResources if the malloc fails |
| **/ |
| /*----------------------------------------------------------------------------*/ |
| OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSet (VIDENC_COMPONENT_PRIVATE* pComponentPrivate, |
| OMX_U32 nParam1) |
| { |
| VIDENC_NODE* pMemoryListHead = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefIn = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pPortDefIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->pPortDef; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| pMemoryListHead = pComponentPrivate->pMemoryListHead; |
| |
| switch (nParam1) |
| { |
| case OMX_StateIdle: |
| eError = OMX_VIDENC_HandleCommandStateSetIdle (pComponentPrivate); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRSTATE3, |
| "Failed to move to Idle state (%x).\n", eError); |
| break; |
| case OMX_StateExecuting: |
| eError = OMX_VIDENC_HandleCommandStateSetExecuting (pComponentPrivate); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRSTATE3, |
| "Failed to move to Execute state (%x).\n", eError); |
| break; |
| case OMX_StateLoaded: |
| eError = OMX_VIDENC_HandleCommandStateSetLoaded (pComponentPrivate); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRSTATE3, |
| "Failed to move to Loaded state (%x).\n", eError); |
| break; |
| case OMX_StatePause: |
| eError = OMX_VIDENC_HandleCommandStateSetPause (pComponentPrivate); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRSTATE3, |
| "Failed to move to Pause state (%x).\n", eError); |
| break; |
| case OMX_StateInvalid: |
| if (pComponentPrivate->eState == OMX_StateInvalid) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorSameState, |
| OMX_TI_ErrorSevere, |
| NULL); |
| } |
| else |
| { |
| pComponentPrivate->eState = OMX_StateInvalid; |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorInvalidState, |
| OMX_TI_ErrorSevere, |
| NULL); |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandStateSet, |
| OMX_StateInvalid, |
| NULL); |
| } |
| break; |
| case OMX_StateWaitForResources: |
| if (pComponentPrivate->eState == OMX_StateWaitForResources) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorSameState, |
| OMX_TI_ErrorMinor, |
| NULL); |
| } |
| else if (pComponentPrivate->eState == OMX_StateLoaded) |
| { |
| pComponentPrivate->eState = OMX_StateWaitForResources; |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandStateSet, |
| OMX_StateWaitForResources, |
| NULL); |
| } |
| else |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| OMX_TI_ErrorMinor, |
| NULL); |
| } |
| break; |
| case OMX_StateMax: |
| break; |
| } /* End of Switch */ |
| |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_HandleCommandStateSet() |
| * |
| * Called by component thread, handles commands sent by the app. |
| * |
| * @param phandle LCML_DSP_INTERFACE handle for this instance of the component |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * OMX_ErrorInsufficientResources if the malloc fails |
| **/ |
| /*----------------------------------------------------------------------------*/ |
| OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetIdle(VIDENC_COMPONENT_PRIVATE* pComponentPrivate) |
| { |
| OMX_U8 nCount = 0; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| LCML_DSP_INTERFACE* pLcmlHandle = NULL; |
| VIDEOENC_PORT_TYPE* pCompPortIn = NULL; |
| VIDEOENC_PORT_TYPE* pCompPortOut = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefIn = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pCompPortIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]; |
| pCompPortOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]; |
| pPortDefIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->pPortDef; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| |
| |
| switch (pComponentPrivate->eState) |
| { |
| case OMX_StateIdle: |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorSameState, |
| OMX_TI_ErrorMinor, |
| NULL); |
| break; |
| case OMX_StateInvalid: |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| OMX_TI_ErrorMajor, |
| NULL); |
| break; |
| case OMX_StateLoaded: |
| case OMX_StateWaitForResources: |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_Boundary(pComponentPrivate->pPERFcomp, |
| PERF_BoundaryStart | PERF_BoundarySetup); |
| #endif |
| if ( pPortDefIn->bEnabled == OMX_TRUE || pPortDefOut->bEnabled == OMX_TRUE ) |
| { |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| while ( (!pPortDefIn->bPopulated) || (!pPortDefOut->bPopulated)) |
| { |
| #ifndef UNDER_CE |
| pthread_cond_wait(&pComponentPrivate->populate_cond, &pComponentPrivate->videoe_mutex_app); |
| #else |
| OMX_WaitForEvent(&(pComponentPrivate->InLoaded_event)); |
| #endif |
| } |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| } |
| /* Make sure the DSP node has been deleted first to cover |
| any idle->loaded->idle or idle->wfr->idle combinations |
| */ |
| if (pComponentPrivate->bCodecStarted == OMX_TRUE || |
| pComponentPrivate->bCodecLoaded == OMX_TRUE) |
| { |
| OMX_PRDSP2(pComponentPrivate->dbg, "Attempting to destroy the node...\n"); |
| pLcmlHandle = NULL; |
| pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; |
| eError = LCML_ControlCodec(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, |
| EMMCodecControlDestroy, |
| NULL); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRDSP3, |
| "Failed to destroy socket node (%x).\n", eError); |
| |
| |
| /*Unload LCML */ |
| if(pComponentPrivate->pModLcml != NULL) |
| { |
| #ifndef UNDER_CE |
| dlclose(pComponentPrivate->pModLcml); |
| #else |
| FreeLibrary(pComponentPrivate->pModLcml); |
| FreeLibrary(g_hLcmlDllHandle); |
| g_hLcmlDllHandle = NULL; |
| |
| #endif |
| pComponentPrivate->pModLcml = NULL; |
| pComponentPrivate->pLCML = NULL; |
| } |
| |
| if (pComponentPrivate->sps) { |
| free(pComponentPrivate->sps); |
| pComponentPrivate->sps = NULL; |
| pComponentPrivate->spsLen = 0; |
| } |
| |
| pComponentPrivate->bCodecStarted = OMX_FALSE; |
| pComponentPrivate->bCodecLoaded = OMX_FALSE; |
| } |
| |
| eError = OMX_VIDENC_InitLCML(pComponentPrivate); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRDSP4, |
| "Failed to initialize LCML (%x).\n", eError); |
| |
| #ifdef __PERF_INSTRUMENTATION__ |
| pComponentPrivate->nLcml_nCntIp = 0; |
| pComponentPrivate->nLcml_nCntOpReceived = 0; |
| #endif |
| if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| eError = OMX_VIDENC_InitDSP_H264Enc(pComponentPrivate); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRDSP4, |
| "Failed to initialize H264 SN (%x).\n", eError); |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4 || |
| pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| eError = OMX_VIDENC_InitDSP_Mpeg4Enc(pComponentPrivate); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRDSP4, |
| "Failed to initialize MPEG4 SN (%x).\n", eError); |
| } |
| else |
| { |
| OMX_PRSTATE4(pComponentPrivate->dbg, "Unsupported compression format (%d)\n", |
| pPortDefOut->format.video.eCompressionFormat); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| |
| #ifdef RESOURCE_MANAGER_ENABLED |
| |
| OMX_PRMGR2(pComponentPrivate->dbg, "Setting CallBack In Video Encoder component\n"); |
| pComponentPrivate->cRMCallBack.RMPROXY_Callback = (void*)OMX_VIDENC_ResourceManagerCallBack; |
| switch (pPortDefOut->format.video.eCompressionFormat) |
| { |
| case OMX_VIDEO_CodingAVC: |
| switch(pComponentPrivate->pH264->eLevel) |
| { |
| case OMX_VIDEO_AVCLevel1: |
| case OMX_VIDEO_AVCLevel1b: |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_RequestResource, |
| OMX_H264_Encode_COMPONENT, |
| VIDEO_ENCODER_MHZ, |
| 3456, |
| &(pComponentPrivate->cRMCallBack)); |
| |
| break; |
| case OMX_VIDEO_AVCLevel11: |
| case OMX_VIDEO_AVCLevel12: |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_RequestResource, |
| OMX_H264_Encode_COMPONENT, |
| VIDEO_ENCODER_MHZ, |
| 3456, |
| &(pComponentPrivate->cRMCallBack)); |
| break; |
| case OMX_VIDEO_AVCLevel13: |
| case OMX_VIDEO_AVCLevel2: |
| case OMX_VIDEO_AVCLevel21: |
| case OMX_VIDEO_AVCLevel22: |
| case OMX_VIDEO_AVCLevel3: |
| default: |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_RequestResource, |
| OMX_H264_Encode_COMPONENT, |
| VIDEO_ENCODER_MHZ, |
| 3456, |
| &(pComponentPrivate->cRMCallBack)); |
| } |
| break; |
| case OMX_VIDEO_CodingMPEG4: |
| switch(pComponentPrivate->pMpeg4->eLevel) |
| { |
| case 0: |
| case 1: |
| case 100: |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_RequestResource, |
| OMX_MPEG4_Encode_COMPONENT, |
| VIDEO_ENCODER_MHZ, |
| 3456, |
| &(pComponentPrivate->cRMCallBack)); |
| break; |
| case 2: |
| case 3: |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_RequestResource, |
| OMX_MPEG4_Encode_COMPONENT, |
| VIDEO_ENCODER_MHZ, |
| 3456, |
| &(pComponentPrivate->cRMCallBack)); |
| break; |
| case 4: |
| default: |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_RequestResource, |
| OMX_MPEG4_Encode_COMPONENT, |
| VIDEO_ENCODER_MHZ, |
| 3456, |
| &(pComponentPrivate->cRMCallBack)); |
| } |
| break; |
| case OMX_VIDEO_CodingH263: |
| switch(pComponentPrivate->pH263->eLevel) |
| { |
| case OMX_VIDEO_H263Level10: |
| case OMX_VIDEO_H263Level40: |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_RequestResource, |
| OMX_H263_Encode_COMPONENT, |
| VIDEO_ENCODER_MHZ, |
| 3456, |
| &(pComponentPrivate->cRMCallBack)); |
| break; |
| case OMX_VIDEO_H263Level20: |
| case OMX_VIDEO_H263Level30: |
| default: |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_RequestResource, |
| OMX_H263_Encode_COMPONENT, |
| VIDEO_ENCODER_MHZ, |
| 3456, |
| &(pComponentPrivate->cRMCallBack)); |
| } |
| break; |
| default: |
| OMX_PRSTATE4(pComponentPrivate->dbg, "Unsupported compression format (%d)\n", |
| pPortDefOut->format.video.eCompressionFormat); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| |
| /* Resource Manager Proxy Calls */ |
| if (pCompPortOut->pPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_H264_Encode_COMPONENT, 0); */ |
| OMX_PRMGR2(pComponentPrivate->dbg, "RMProxy_SendCommand: Setting state to Idle from Loaded\n"); |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_H264_Encode_COMPONENT, |
| OMX_StateIdle, |
| 3456, |
| NULL); |
| } |
| else if (pCompPortOut->pPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_MPEG4_Encode_COMPONENT, 0); */ |
| OMX_PRMGR2(pComponentPrivate->dbg, "RMProxy_SendCommand: Setting state to Idle from Loaded\n"); |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_MPEG4_Encode_COMPONENT, |
| OMX_StateIdle, |
| 3456, |
| NULL); |
| } |
| else if (pCompPortOut->pPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_H263_Encode_COMPONENT, 0); */ |
| OMX_PRMGR2(pComponentPrivate->dbg, "RMProxy_SendCommand: Setting state to Idle from Loaded\n"); |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_H263_Encode_COMPONENT, |
| OMX_StateIdle, |
| 3456, |
| NULL); |
| } |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorHardware, |
| OMX_TI_ErrorSevere, |
| NULL); |
| } |
| |
| if (eError == OMX_ErrorNone) { |
| |
| pComponentPrivate->eState = OMX_StateIdle; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_Boundary(pComponentPrivate->pPERFcomp, |
| PERF_BoundaryComplete | PERF_BoundarySetup); |
| #endif |
| |
| /* Decrement reference count with signal enabled */ |
| if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) { |
| return OMX_ErrorUndefined; |
| } |
| |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandStateSet, |
| OMX_StateIdle, |
| NULL); |
| } |
| else if (eError == OMX_ErrorInsufficientResources) |
| { |
| pComponentPrivate->eState = OMX_StateWaitForResources; |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorInsufficientResources, |
| OMX_TI_ErrorMajor, |
| NULL); |
| } |
| #else /* WinCE MM will not use Linux RM, so do this... */ |
| pComponentPrivate->eState = OMX_StateIdle; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_Boundary(pComponentPrivate->pPERFcomp, |
| PERF_BoundaryComplete | PERF_BoundarySetup); |
| #endif |
| |
| /* Decrement reference count with signal enabled */ |
| if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) { |
| return OMX_ErrorUndefined; |
| } |
| |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandStateSet, |
| OMX_StateIdle, |
| NULL); |
| #endif |
| break; |
| case OMX_StateExecuting: |
| case OMX_StatePause: |
| pLcmlHandle = NULL; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_Boundary(pComponentPrivate->pPERF, |
| PERF_BoundaryComplete | PERF_BoundarySteadyState); |
| #endif |
| |
| pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; |
| eError = LCML_ControlCodec(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, |
| MMCodecControlStop, |
| NULL); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRDSP3, |
| "Failed to stop socket node (%x).\n", eError); |
| pComponentPrivate->bCodecStarted = OMX_FALSE; |
| OMX_PRDSP2(pComponentPrivate->dbg, "MMCodecControlStop called...\n"); |
| |
| #ifndef UNDER_CE |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| while (pComponentPrivate->bDSPStopAck == OMX_FALSE) |
| { |
| pthread_cond_wait(&pComponentPrivate->stop_cond, &pComponentPrivate->videoe_mutex_app); |
| } |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| #else |
| while (pComponentPrivate->bDSPStopAck == OMX_FALSE) |
| { |
| sched_yield(); |
| } |
| #endif |
| pComponentPrivate->bDSPStopAck = OMX_FALSE; |
| |
| for (nCount = 0; nCount < pPortDefIn->nBufferCountActual; nCount++) |
| { |
| OMX_PRBUFFER2(pComponentPrivate->dbg, "Buffer[%d]:port[%d] -> %p [OWNER = %d]\n", |
| nCount, |
| VIDENC_INPUT_PORT, |
| pCompPortIn->pBufferPrivate[nCount]->pBufferHdr, |
| pCompPortIn->pBufferPrivate[nCount]->eBufferOwner); |
| |
| if (pCompPortIn->pBufferPrivate[nCount]->eBufferOwner == VIDENC_BUFFER_WITH_DSP || |
| pCompPortIn->pBufferPrivate[nCount]->eBufferOwner == VIDENC_BUFFER_WITH_COMPONENT) |
| { |
| OMX_PRBUFFER1(pComponentPrivate->dbg, "Buffer[%d]:port[%d] -> %p [SEND BACK TO SUPPLIER]\n", |
| nCount, |
| VIDENC_INPUT_PORT, |
| pCompPortIn->pBufferPrivate[nCount]->pBufferHdr); |
| |
| if (pCompPortIn->hTunnelComponent == NULL) |
| { |
| |
| pCompPortIn->pBufferPrivate[nCount]->pBufferHdr->nFilledLen = 0; |
| OMX_PRBUFFER1(pComponentPrivate->dbg, "Buffer[%d]:port[%d] -> %p [memset %lu bytes]\n", |
| nCount, |
| VIDENC_INPUT_PORT, |
| pCompPortIn->pBufferPrivate[nCount]->pBufferHdr, |
| pCompPortIn->pBufferPrivate[nCount]->pBufferHdr->nAllocLen); |
| |
| memset(pCompPortIn->pBufferPrivate[nCount]->pBufferHdr->pBuffer, |
| 0x0, |
| pCompPortIn->pBufferPrivate[nCount]->pBufferHdr->nAllocLen); |
| |
| pCompPortIn->pBufferPrivate[nCount]->eBufferOwner = VIDENC_BUFFER_WITH_CLIENT; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| pCompPortIn->pBufferPrivate[nCount]->pBufferHdr->pBuffer, |
| 0, |
| PERF_ModuleHLMM); |
| #endif |
| pComponentPrivate->sCbData.EmptyBufferDone(pComponentPrivate->pHandle, |
| pComponentPrivate->pHandle->pApplicationPrivate, |
| pCompPortIn->pBufferPrivate[nCount]->pBufferHdr); |
| OMX_VIDENC_IncrementBufferCountByOne(&pComponentPrivate->EmptybufferdoneCount); |
| OMX_VIDENC_SignalIfAllBuffersAreReturned(pComponentPrivate); |
| } |
| else |
| { |
| pCompPortIn->pBufferPrivate[nCount]->pBufferHdr->nFilledLen = 0; |
| pCompPortIn->pBufferPrivate[nCount]->eBufferOwner = VIDENC_BUFFER_WITH_TUNNELEDCOMP; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| pCompPortIn->pBufferPrivate[nCount]->pBufferHdr->pBuffer, |
| 0, |
| PERF_ModuleLLMM); |
| #endif |
| eError = OMX_FillThisBuffer(pCompPortIn->hTunnelComponent, |
| pCompPortIn->pBufferPrivate[nCount]->pBufferHdr); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRBUFFER4, |
| "FillThisBuffer failed (%x).\n", eError); |
| } |
| } |
| } |
| |
| for (nCount = 0; nCount < pPortDefOut->nBufferCountActual; nCount++) |
| { |
| OMX_PRBUFFER2(pComponentPrivate->dbg, "Buffer[%d]:port[%d] -> %p [OWNER = %d]\n", |
| nCount, |
| VIDENC_OUTPUT_PORT, |
| pCompPortOut->pBufferPrivate[nCount]->pBufferHdr, |
| pCompPortOut->pBufferPrivate[nCount]->eBufferOwner); |
| |
| if (pCompPortOut->pBufferPrivate[nCount]->eBufferOwner == VIDENC_BUFFER_WITH_DSP || |
| pCompPortOut->pBufferPrivate[nCount]->eBufferOwner == VIDENC_BUFFER_WITH_COMPONENT) |
| { |
| |
| if (pCompPortOut->hTunnelComponent == NULL) |
| { |
| OMX_PRBUFFER1(pComponentPrivate->dbg, "Buffer[%d]:port[%d] -> %p [memset %lu bytes]\n", |
| nCount, |
| VIDENC_OUTPUT_PORT, |
| pCompPortOut->pBufferPrivate[nCount]->pBufferHdr, |
| pCompPortOut->pBufferPrivate[nCount]->pBufferHdr->nAllocLen); |
| |
| memset(pCompPortOut->pBufferPrivate[nCount]->pBufferHdr->pBuffer, |
| 0x0, |
| pCompPortOut->pBufferPrivate[nCount]->pBufferHdr->nAllocLen); |
| } |
| |
| OMX_PRBUFFER1(pComponentPrivate->dbg, "Buffer[%d]:port[%d] -> %p [SEND BACK TO SUPPLIER]\n", nCount, |
| VIDENC_OUTPUT_PORT, |
| pCompPortOut->pBufferPrivate[nCount]->pBufferHdr); |
| |
| pCompPortOut->pBufferPrivate[nCount]->pBufferHdr->nFilledLen = 0; |
| pCompPortOut->pBufferPrivate[nCount]->eBufferOwner = VIDENC_BUFFER_WITH_CLIENT; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| pCompPortOut->pBufferPrivate[nCount]->pBufferHdr->pBuffer, |
| pCompPortOut->pBufferPrivate[nCount]->pBufferHdr->nFilledLen, |
| PERF_ModuleHLMM); |
| #endif |
| /*Propagate pBufferHeader Data*/ |
| OMX_CONF_CIRCULAR_BUFFER_MOVE_HEAD(pCompPortOut->pBufferPrivate[nCount]->pBufferHdr, |
| pComponentPrivate->sCircularBuffer, |
| pComponentPrivate); |
| /* trigger event handler if we are supposed to */ |
| if (pCompPortOut->pBufferPrivate[nCount]->pBufferHdr->hMarkTargetComponent == pComponentPrivate->pHandle && |
| pCompPortOut->pBufferPrivate[nCount]->pBufferHdr->pMarkData) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventMark, |
| 0x0, |
| 0x0, |
| pCompPortOut->pBufferPrivate[nCount]->pBufferHdr->pMarkData); |
| } |
| pComponentPrivate->sCbData.FillBufferDone(pComponentPrivate->pHandle, |
| pComponentPrivate->pHandle->pApplicationPrivate, |
| pCompPortOut->pBufferPrivate[nCount]->pBufferHdr); |
| OMX_VIDENC_IncrementBufferCountByOne(&pComponentPrivate->FillbufferdoneCount); |
| OMX_VIDENC_SignalIfAllBuffersAreReturned(pComponentPrivate); |
| } |
| } |
| |
| #ifdef RESOURCE_MANAGER_ENABLED /* Resource Manager Proxy Calls */ |
| if (pCompPortOut->pPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_H264_Encode_COMPONENT, 0); */ |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_H264_Encode_COMPONENT, |
| OMX_StateIdle, |
| 3456, |
| NULL); |
| } |
| else if (pCompPortOut->pPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_MPEG4_Encode_COMPONENT, 0); */ |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_MPEG4_Encode_COMPONENT, |
| OMX_StateIdle, |
| 3456, |
| NULL); |
| } |
| else if (pCompPortOut->pPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_H263_Encode_COMPONENT, 0); */ |
| OMX_PRMGR2(pComponentPrivate->dbg, "Setting Idle state from Executing to RMProxy\n"); |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_H263_Encode_COMPONENT, |
| OMX_StateIdle, |
| 3456, |
| NULL); |
| } |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorHardware, |
| OMX_TI_ErrorMajor, |
| NULL); |
| } |
| |
| #endif |
| OMX_PRBUFFER2(pComponentPrivate->dbg, "Flushing Pipes!\n"); |
| OMX_VIDENC_EmptyDataPipes (pComponentPrivate); |
| |
| pComponentPrivate->eState = OMX_StateIdle; |
| |
| /* Decrement reference count with signal enabled */ |
| if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) { |
| return OMX_ErrorUndefined; |
| } |
| |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandStateSet, |
| OMX_StateIdle, |
| NULL); |
| break; |
| default: |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| OMX_TI_ErrorMinor, |
| NULL); |
| } |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_HandleCommandStateSet() |
| * |
| * Called by component thread, handles commands sent by the app. |
| * |
| * @param phandle LCML_DSP_INTERFACE handle for this instance of the component |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * OMX_ErrorInsufficientResources if the malloc fails |
| **/ |
| /*----------------------------------------------------------------------------*/ |
| OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetExecuting(VIDENC_COMPONENT_PRIVATE* pComponentPrivate) |
| { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| LCML_DSP_INTERFACE* pLcmlHandle = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefIn = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pPortDefIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->pPortDef; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| |
| switch (pComponentPrivate->eState) |
| { |
| case OMX_StateExecuting: |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, OMX_EventError, OMX_ErrorSameState, OMX_TI_ErrorMinor, NULL); |
| break; |
| case OMX_StateIdle: |
| OMX_CONF_CIRCULAR_BUFFER_RESTART(pComponentPrivate->sCircularBuffer); |
| case OMX_StatePause: |
| if (pComponentPrivate->bCodecStarted == OMX_FALSE) |
| { |
| pLcmlHandle = NULL; |
| pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; |
| pLcmlHandle->pComponentPrivate = (VIDENC_COMPONENT_PRIVATE*)pComponentPrivate; |
| |
| OMX_PRDSP2(pComponentPrivate->dbg, "Starting the codec...\n"); |
| eError = LCML_ControlCodec(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, |
| EMMCodecControlStart, |
| NULL); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRDSP4, |
| "Failed to start socket node (%x).\n", eError); |
| |
| pComponentPrivate->bCodecStarted = OMX_TRUE; |
| } |
| |
| #ifdef RESOURCE_MANAGER_ENABLED /* Resource Manager Proxy Calls */ |
| if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| /* TODO: Disable RM Send for now */ |
| OMX_PRMGR2(pComponentPrivate->dbg, "Setting executing state to RMProxy\n"); |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_H264_Encode_COMPONENT, 0); */ |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_H264_Encode_COMPONENT, |
| OMX_StateExecuting, |
| 3456, |
| NULL); |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) |
| { |
| /* TODO: Disable RM Send for now */ |
| OMX_PRMGR2(pComponentPrivate->dbg, "Setting executing state to RMProxy\n"); |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_MPEG4_Encode_COMPONENT, 0); */ |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_MPEG4_Encode_COMPONENT, |
| OMX_StateExecuting, |
| 3456, |
| NULL); |
| |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_H263_Encode_COMPONENT, 0); */ |
| OMX_PRMGR2(pComponentPrivate->dbg, "Setting executing state to RMProxy\n"); |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_H263_Encode_COMPONENT, |
| OMX_StateExecuting, |
| 3456, |
| NULL); |
| } |
| if (eError != OMX_ErrorNone) |
| { |
| pComponentPrivate->eState = OMX_StateWaitForResources; |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorHardware, |
| OMX_TI_ErrorMajor, |
| NULL); |
| } |
| #endif |
| pComponentPrivate->eState = OMX_StateExecuting; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_Boundary(pComponentPrivate->pPERFcomp, |
| PERF_BoundaryStart | PERF_BoundarySteadyState); |
| #endif |
| |
| /* Decrement reference count with signal enabled */ |
| if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) { |
| return OMX_ErrorUndefined; |
| } |
| |
| /*Send state change notificaiton to Application*/ |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandStateSet, |
| OMX_StateExecuting, |
| NULL); |
| break; |
| default: |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| OMX_TI_ErrorMinor, |
| NULL); |
| } |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_HandleCommandStateSetPause() |
| * |
| * Called by component thread, handles commands sent by the app. |
| * |
| * @param phandle LCML_DSP_INTERFACE handle for this instance of the component |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * OMX_ErrorInsufficientResources if the malloc fails |
| **/ |
| /*----------------------------------------------------------------------------*/ |
| OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetPause (VIDENC_COMPONENT_PRIVATE* pComponentPrivate) |
| { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefIn = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| LCML_DSP_INTERFACE* pLcmlHandle = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; |
| pPortDefIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->pPortDef; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| |
| |
| switch (pComponentPrivate->eState) |
| { |
| case OMX_StatePause: |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorSameState, |
| OMX_TI_ErrorMinor, |
| NULL); |
| break; |
| case OMX_StateIdle: |
| case OMX_StateExecuting: |
| pLcmlHandle = NULL; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_Boundary(pComponentPrivate->pPERFcomp, |
| PERF_BoundaryComplete | PERF_BoundarySteadyState); |
| #endif |
| pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; |
| eError = LCML_ControlCodec(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, |
| EMMCodecControlPause, |
| NULL); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRDSP4, |
| "Failed to pause socket node (%x).\n", eError); |
| |
| |
| pComponentPrivate->bCodecStarted = OMX_FALSE; |
| OMX_PRDSP2(pComponentPrivate->dbg, "MMCodecControlPaused called...\n"); |
| |
| |
| #ifndef UNDER_CE |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| while (pComponentPrivate->bDSPStopAck == OMX_FALSE) |
| { |
| pthread_cond_wait(&pComponentPrivate->stop_cond, &pComponentPrivate->videoe_mutex_app); |
| } |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| #else |
| while (pComponentPrivate->bDSPStopAck == OMX_FALSE) |
| { |
| sched_yield(); |
| } |
| #endif |
| |
| pComponentPrivate->bDSPStopAck = OMX_FALSE; |
| |
| pComponentPrivate->eState = OMX_StatePause; |
| |
| /* Decrement reference count with signal enabled */ |
| if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) { |
| return OMX_ErrorUndefined; |
| } |
| |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandStateSet, |
| OMX_StatePause, |
| NULL); |
| break; |
| default: |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| OMX_TI_ErrorMinor, |
| NULL); |
| } |
| |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*----------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_HandleCommandStateSetLoaded() |
| * |
| * Called by component thread, handles commands sent by the app. |
| * |
| * @param phandle LCML_DSP_INTERFACE handle for this instance of the component |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * OMX_ErrorInsufficientResources if the malloc fails |
| **/ |
| /*----------------------------------------------------------------------------*/ |
| OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetLoaded (VIDENC_COMPONENT_PRIVATE* pComponentPrivate) |
| { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| LCML_DSP_INTERFACE* pLcmlHandle = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefIn = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pPortDefIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->pPortDef; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| |
| switch (pComponentPrivate->eState) |
| { |
| case OMX_StateLoaded: |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorSameState, |
| OMX_TI_ErrorMinor, |
| NULL); |
| break; |
| case OMX_StateWaitForResources: |
| OMX_PRSTATE2(pComponentPrivate->dbg, "Transitioning from WFR to Loaded\n"); |
| #ifdef RESOURCE_MANAGER_ENABLED |
| if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_H264_Encode_COMPONENT, 0); */ |
| OMX_PRMGR2(pComponentPrivate->dbg, "RMProxy_SendCommand: Setting state to Loaded from WFR\n"); |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_H264_Encode_COMPONENT, |
| OMX_StateLoaded, |
| 3456, |
| NULL); |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_MPEG4_Encode_COMPONENT, 0); */ |
| OMX_PRMGR2(pComponentPrivate->dbg, "RMProxy_SendCommand: Setting state to Loaded from WFR\n"); |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_MPEG4_Encode_COMPONENT, |
| OMX_StateLoaded, |
| 3456, |
| NULL); |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_H263_Encode_COMPONENT, 0); */ |
| OMX_PRMGR2(pComponentPrivate->dbg, "RMProxy_SendCommand: Setting state to Loaded from WFR\n"); |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_StateSet, |
| OMX_H263_Encode_COMPONENT, |
| OMX_StateLoaded, |
| 3456, |
| NULL); |
| } |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorHardware, |
| OMX_TI_ErrorMajor, |
| NULL); |
| break; |
| } |
| #endif |
| pComponentPrivate->eState = OMX_StateLoaded; |
| /* Decrement reference count with signal enabled */ |
| if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) { |
| return OMX_ErrorUndefined; |
| } |
| |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_Boundary(pComponentPrivate->pPERFcomp, |
| PERF_BoundaryComplete | PERF_BoundaryCleanup); |
| #endif |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandStateSet, |
| OMX_StateLoaded, |
| NULL); |
| break; |
| case OMX_StateIdle: |
| OMX_PRSTATE2(pComponentPrivate->dbg, "Transitioning from Idle to Loaded\n"); |
| pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_Boundary(pComponentPrivate->pPERFcomp, |
| PERF_BoundaryStart | PERF_BoundaryCleanup); |
| #endif |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| while ( (pPortDefIn->bPopulated) || (pPortDefOut->bPopulated)) |
| { |
| #ifndef UNDER_CE |
| pthread_cond_wait(&pComponentPrivate->unpopulate_cond, &pComponentPrivate->videoe_mutex_app); |
| #else |
| OMX_WaitForEvent(&(pComponentPrivate->InIdle_event)); |
| #endif |
| } |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| |
| #ifdef RESOURCE_MANAGER_ENABLED /* Resource Manager Proxy Calls */ |
| if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_H264_Encode_COMPONENT, 0); */ |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_FreeResource, |
| OMX_H264_Encode_COMPONENT, |
| 0, |
| 3456, |
| NULL); |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_MPEG4_Encode_COMPONENT, 0); */ |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_FreeResource, |
| OMX_MPEG4_Encode_COMPONENT, |
| 0, |
| 3456, |
| NULL); |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| /* TODO: Disable RM Send for now */ |
| /* eError = RMProxy_SendCommand(pHandle, RMProxy_RequestResource, OMX_H263_Encode_COMPONENT, 0); */ |
| eError = RMProxy_NewSendCommand(pComponentPrivate->pHandle, |
| RMProxy_FreeResource, |
| OMX_H263_Encode_COMPONENT, |
| 0, |
| 3456, |
| NULL); |
| } |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorHardware, |
| OMX_TI_ErrorMajor, |
| NULL); |
| } |
| #endif |
| /* Make sure the DSP node has been deleted */ |
| if (pComponentPrivate->bCodecStarted == OMX_TRUE || pComponentPrivate->bCodecLoaded == OMX_TRUE) |
| { |
| OMX_TRACE2(pComponentPrivate->dbg, "LCML_ControlCodec EMMCodecControlDestroy\n"); |
| eError = LCML_ControlCodec(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, |
| EMMCodecControlDestroy, |
| NULL); |
| OMX_CONF_BAIL_IF_ERROR(eError); |
| OMX_TRACE2(pComponentPrivate->dbg,"Atempting to Unload LCML"); |
| /*Unload LCML */ |
| if(pComponentPrivate->pModLcml != NULL) |
| { |
| OMX_TRACE2(pComponentPrivate->dbg,"Unloading LCML"); |
| dlclose(pComponentPrivate->pModLcml); |
| pComponentPrivate->pModLcml = NULL; |
| pComponentPrivate->pLCML = NULL; |
| } |
| |
| pComponentPrivate->bCodecStarted = OMX_FALSE; |
| pComponentPrivate->bCodecLoaded = OMX_FALSE; |
| } |
| |
| OMX_CONF_BAIL_IF_ERROR(eError); |
| |
| #ifdef __KHRONOS_CONF__ |
| pComponentPrivate->bPassingIdleToLoaded = OMX_FALSE; |
| #endif |
| pComponentPrivate->eState = OMX_StateLoaded; |
| |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_Boundary(pComponentPrivate->pPERFcomp, |
| PERF_BoundaryComplete | PERF_BoundaryCleanup); |
| #endif |
| |
| /* Decrement reference count with signal enabled */ |
| if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) { |
| return OMX_ErrorUndefined; |
| } |
| |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventCmdComplete, |
| OMX_CommandStateSet, |
| OMX_StateLoaded, |
| NULL); |
| break; |
| default: |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| OMX_TI_ErrorMinor, |
| NULL); |
| } |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * OMX_OMX_VIDENC_Process_FreeOutBuf() |
| * |
| * Called by component thread, handles free output buffers from app. |
| * |
| * @param pComponentPrivate private component structure for this instance of the component |
| * |
| * @param phandle LCML_DSP_INTERFACE handle for this instance of the component |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * OMX_ErrorInsufficientResources if the malloc fails |
| **/ |
| /*---------------------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_Process_FreeOutBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate) |
| { |
| int nRet = -1; |
| void *pUalgOutParams = NULL; |
| VIDENC_NODE* pMemoryListHead = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| OMX_BUFFERHEADERTYPE* pBufHead = NULL; |
| LCML_DSP_INTERFACE* pLcmlHandle = NULL; |
| VIDENC_BUFFER_PRIVATE* pBufferPrivate = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| pLcmlHandle = (LCML_DSP_INTERFACE*)(((VIDENC_COMPONENT_PRIVATE*)pComponentPrivate)->pLCML); |
| pMemoryListHead = pComponentPrivate->pMemoryListHead; |
| |
| #ifndef UNDER_CE |
| if (pthread_mutex_lock(&(pComponentPrivate->mVideoEncodeBufferMutex)) != 0) |
| { |
| OMX_TRACE4(pComponentPrivate->dbg, "pthread_mutex_lock() failed.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorHardware); |
| } |
| nRet = read(pComponentPrivate->nFree_oPipe[0], &pBufHead, sizeof(pBufHead)); |
| if ((nRet == -1) || !pBufHead || !pBufHead->pOutputPortPrivate) |
| { |
| pthread_mutex_unlock(&(pComponentPrivate->mVideoEncodeBufferMutex)); |
| OMX_ERROR4(pComponentPrivate->dbg, "Error while reading from the pipe\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorHardware); |
| } |
| |
| pBufferPrivate = pBufHead->pOutputPortPrivate; |
| |
| pBufferPrivate->bReadFromPipe = OMX_TRUE; |
| if (pthread_mutex_unlock(&(pComponentPrivate->mVideoEncodeBufferMutex)) != 0) |
| { |
| OMX_TRACE4(pComponentPrivate->dbg, "pthread_mutex_unlock() failed.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorHardware); |
| } |
| #else |
| nRet = read(pComponentPrivate->nFree_oPipe[0], &pBufHead, sizeof(pBufHead)); |
| if ((nRet == -1) || (pBufHead == NULL) || (pBufHead->pOutputPortPrivate == NULL)) |
| { |
| OMX_ERROR4(pComponentPrivate->dbg, "Error while reading from the pipe\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorHardware); |
| } |
| if (pBufHead != NULL) |
| { |
| pBufferPrivate = pBufHead->pOutputPortPrivate; |
| } |
| pBufferPrivate->bReadFromPipe = OMX_TRUE; |
| #endif |
| |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| PREF(pBufHead,pBuffer), |
| 0, |
| PERF_ModuleCommonLayer); |
| #endif |
| |
| if (pBufferPrivate->eBufferOwner == VIDENC_BUFFER_WITH_DSP || |
| pBufferPrivate->eBufferOwner == VIDENC_BUFFER_WITH_CLIENT) |
| { |
| goto EXIT; |
| |
| } |
| |
| if(!pBufferPrivate || !pLcmlHandle || !pPortDefOut) |
| goto EXIT; |
| |
| if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| pUalgOutParams =(H264VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam; |
| OMX_PRBUFFER1(pComponentPrivate->dbg, " %p \n", (void*)pBufHead); |
| pBufferPrivate->eBufferOwner = VIDENC_BUFFER_WITH_DSP; |
| eError = LCML_QueueBuffer(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, |
| EMMCodecOuputBuffer, |
| pBufHead->pBuffer, |
| pBufHead->nAllocLen, |
| 0, |
| (OMX_U8*)pUalgOutParams, |
| sizeof(H264VE_GPP_SN_UALGOutputParams), |
| (void*)pBufHead); |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_PRDSP4(pComponentPrivate->dbg, "LCML QueueBuffer failed: %x\n", eError); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorHardware); |
| } |
| |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4 || |
| pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| pUalgOutParams = (MP4VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam; |
| OMX_PRBUFFER1(pComponentPrivate->dbg, " %p\n", (void*)pBufHead); |
| pBufferPrivate->eBufferOwner = VIDENC_BUFFER_WITH_DSP; |
| eError = LCML_QueueBuffer(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, |
| EMMCodecOuputBuffer, |
| pBufHead->pBuffer, |
| pBufHead->nAllocLen, |
| 0, |
| (OMX_U8*)pUalgOutParams, |
| sizeof(MP4VE_GPP_SN_UALGOutputParams), |
| (void*)pBufHead); |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_PRDSP4(pComponentPrivate->dbg, "LCML QueueBuffer failed: %x\n", eError); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorHardware); |
| } |
| } |
| else |
| { |
| OMX_PRBUFFER4(pComponentPrivate->dbg, "Unsupported compression format (%d)\n", |
| pPortDefOut->format.video.eCompressionFormat); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| EXIT: |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_Process_FilledInBuf() |
| * |
| * Called by component thread, handles filled input buffers from app. |
| * |
| * @param pComponentPrivate private component structure for this instance of the component |
| * |
| * @param phandle LCML_DSP_INTERFACE handle for this instance of the component |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * OMX_ErrorInsufficientResources if the malloc fails |
| **/ |
| /*---------------------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_Process_FilledInBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate) |
| { |
| OMX_U8 i = 0; |
| int nRet = -1; |
| void* pUalgInpParams = NULL; |
| VIDENC_NODE* pMemoryListHead = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| OMX_BUFFERHEADERTYPE* pBufHead = NULL; |
| LCML_DSP_INTERFACE* pLcmlHandle = NULL; |
| VIDENC_BUFFER_PRIVATE* pBufferPrivate = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefIn = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| VIDEOENC_PORT_TYPE* pCompPortOut = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pPortDefIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->pPortDef; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| pCompPortOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]; |
| pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; |
| pMemoryListHead = pComponentPrivate->pMemoryListHead; |
| |
| OMX_DBG_CHECK_CMD(pComponentPrivate->dbg, pLcmlHandle, pPortDefIn, 1); |
| |
| #ifndef UNDER_CE |
| if (pthread_mutex_lock(&(pComponentPrivate->mVideoEncodeBufferMutex)) != 0) |
| { |
| OMX_TRACE4(pComponentPrivate->dbg, "pthread_mutex_lock() failed.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorHardware); |
| } |
| nRet = read(pComponentPrivate->nFilled_iPipe[0], &(pBufHead), sizeof(pBufHead)); |
| if ((nRet == -1) || !pBufHead || !pBufHead->pInputPortPrivate) |
| { |
| pthread_mutex_unlock(&(pComponentPrivate->mVideoEncodeBufferMutex)); |
| OMX_TRACE4(pComponentPrivate->dbg, "Error while reading from the pipe\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorHardware); |
| } |
| |
| if (pBufHead != NULL) |
| { |
| pBufferPrivate = (VIDENC_BUFFER_PRIVATE*)pBufHead->pInputPortPrivate; |
| } |
| OMX_DBG_CHECK_CMD(pComponentPrivate->dbg, pBufHead, pBufferPrivate, 1); |
| pBufferPrivate->bReadFromPipe = OMX_TRUE; |
| |
| if (pthread_mutex_unlock(&(pComponentPrivate->mVideoEncodeBufferMutex)) != 0) |
| { |
| OMX_TRACE4(pComponentPrivate->dbg, "pthread_mutex_unlock() failed.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorHardware); |
| } |
| #else |
| nRet = read(pComponentPrivate->nFilled_iPipe[0], &(pBufHead), sizeof(pBufHead)); |
| if (nRet == -1) |
| { |
| OMX_TRACE4(pComponentPrivate->dbg, "Error while reading from the pipe\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorHardware); |
| } |
| pBufferPrivate = (VIDENC_BUFFER_PRIVATE*)pBufHead->pInputPortPrivate; |
| OMX_DBG_CHECK_CMD(pComponentPrivate->dbg, pBufHead, pBufferPrivate, 1); |
| pBufferPrivate->bReadFromPipe = OMX_TRUE; |
| #endif |
| |
| #ifdef __PERF_INSTRUMENTATION__ |
| /*For Steady State Instumentation*/ |
| #if 0 |
| if ((pComponentPrivate->nLcml_nCntIp == 1)) |
| { |
| PERF_Boundary(pComponentPrivate->pPERFcomp, |
| PERF_BoundaryStart | PERF_BoundarySteadyState); |
| } |
| #endif |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| PREF(pBufHead,pBuffer), |
| pPortDefIn->nBufferSize, |
| PERF_ModuleCommonLayer); |
| #endif |
| |
| if (pBufferPrivate->eBufferOwner == VIDENC_BUFFER_WITH_DSP || |
| pBufferPrivate->eBufferOwner == VIDENC_BUFFER_WITH_CLIENT) |
| { |
| goto EXIT; |
| } |
| |
| |
| |
| if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| |
| pUalgInpParams = (H264VE_GPP_SN_UALGInputParams*)pBufferPrivate->pUalgParam; |
| OMX_DBG_CHECK_CMD(pComponentPrivate->dbg, pUalgInpParams, 1, 1); |
| |
| /*< must be followed for all video encoders*/ |
| /* size of this structure */ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.videncDynamicParams.size = sizeof(H264VE_GPP_SN_UALGInputParams); |
| /* Input frame height */ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.videncDynamicParams.inputHeight = pPortDefIn->format.video.nFrameHeight; |
| /* Input frame width */ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.videncDynamicParams.inputWidth = pPortDefIn->format.video.nFrameWidth; |
| /* Reference or input frame rate*1000 */ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.videncDynamicParams.refFrameRate = (OMX_U32)(Q16Tof(pPortDefIn->format.video.xFramerate)*1000.0); |
| /* Target frame rate * 1000 */ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.videncDynamicParams.targetFrameRate = pComponentPrivate->nTargetFrameRate; |
| /* Target bit rate in bits per second */ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.videncDynamicParams.targetBitRate = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pBitRateTypeConfig->nEncodeBitrate; |
| /* I frame interval e.g. 30 */ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.videncDynamicParams.intraFrameInterval = pComponentPrivate->nIntraFrameInterval; |
| /* XDM_ENCODE_AU, XDM_GENERATE_HEADER */ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.videncDynamicParams.generateHeader = 0; |
| /* DEFAULT(0): use imagewidth as pitch |
| * else use given capture width for |
| * pitch provided it is greater than |
| * image width.*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.videncDynamicParams.captureWidth = 0; |
| /* Force given frame as I or IDR (in H.264) frame */ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.videncDynamicParams.forceIFrame = pComponentPrivate->bForceIFrame; |
| |
| |
| |
| /*< initial QP of I frames Range[-1,51]. -1 is for auto initialization.*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.qpIntra = 0x0000001c; |
| /*< initial QP of P frames Range[-1,51]. -1 is for auto initialization.*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.qpInter = 0x0000001c; |
| /*< Maximum QP to be used Range[0,51]*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.qpMax = 0x00000033; |
| /*< Minimum QP to be used Range[0,51]*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.qpMin = 0x00000000; |
| /*< Controls enable/disable loop filter, See IH264VENC_LoopFilterParams for more details*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.lfDisableIdc = 0x00000000; |
| /*< enable/disable Quarter Pel Interpolation*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.quartPelDisable = 0x00000000; |
| /*< Adaptive Intra Refesh MB Period: Period at which intra macro blocks should be insterted in a frame*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.airMbPeriod = pComponentPrivate->nAIRRate; |
| /*< Maximum number of macro block in a slice <minimum value is 8>*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.maxMBsPerSlice = 0; |
| /*< Maximum number of bytes in a slice */ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.maxBytesPerSlice = 0; |
| /*< Row number from which slice needs to be intra coded*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.sliceRefreshRowStartNumber = 0; |
| /*< Number of rows to be coded as intra slice*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.sliceRefreshRowNumber = 0; |
| /*< alpha offset for loop filter [-12, 12] even number*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.filterOffsetA = 0; |
| /*< beta offset for loop filter [-12, 12] even number*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.filterOffsetB = 0 ; |
| /*< Limits the maximum frame number in the bit-stream to (1<< (log2MaxFNumMinus4 + 4)) Range[0,12]*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.log2MaxFNumMinus4 = 0; |
| /*< Specifies offset to be added to luma QP for addressing QPC values table for chroma components. Valid value is between -12 and 12, (inclusive)*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.chromaQPIndexOffset = 0; |
| /*< Controls the intra macroblock coding in P slices [0,1]*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.constrainedIntraPredEnable = 0; |
| /*< Picture Order count type Valid values 0, 2*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.picOrderCountType = 0; |
| /*< enable/Disable Multiple Motion vector per MB, valid values are [1, 4] [For DM6446, allowed value is only 1]*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.maxMVperMB = pComponentPrivate->maxMVperMB; |
| /*< See IH264VENC_Intra4x4Params for more details*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.intra4x4EnableIdc = pComponentPrivate->intra4x4EnableIdc; |
| /*< enable/Disable Motion vector access*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.mvDataEnable = 0; |
| /*< Enable/Disable Hierarchical P Frame (non-reference P frame) Coding. [Not useful for DM6446]*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.hierCodingEnable = 0; /* should be 1; */ |
| /*< Signals the type of stream generated with Call-back*/ |
| if (pComponentPrivate->AVCNALFormat == VIDENC_AVC_NAL_UNIT) |
| { |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.streamFormat = IH264_BYTE_STREAM; |
| } |
| else |
| { |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.streamFormat = IH264_NALU_STREAM; |
| } |
| /*< Mechanism to do intra Refresh, see IH264VENC_IntraRefreshMethods for valid values*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.intraRefreshMethod = IH264_INTRAREFRESH_NONE; |
| /* Enable Perceptual Quantization a.k.a. Perceptual Rate Control*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.perceptualQuant = 0; |
| /* Enable Scene Change Detection*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.sceneChangeDet = 0; |
| /*< Function pointer of the call-back function to be used by Encoder*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.pfNalUnitCallBack = NULL; |
| |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.pContext = NULL; |
| |
| /*< Following Parameter are related to Arbitrary Slice Ordering (ASO)*/ |
| /*< Number of valid enteries in asoSliceOrder array valid range is [0,8], |
| //!< where 0 and 1 doesn't have any effect*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.numSliceASO = pComponentPrivate->numSliceASO; |
| /*!< Array containing the order of slices in which they should |
| //!< be present in bit-stream. vaild enteries are [0, any entry lesser than numSlicesASO]*/ |
| for( i=0; i<MAXNUMSLCGPS;i++) |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.asoSliceOrder[i] = pComponentPrivate->asoSliceOrder[i]; |
| |
| /*< Following Parameter are related to Flexible macro block ordering (FMO)*/ |
| /*< Total Number of slice groups, valid enteries are [0,8]*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.numSliceGroups = pComponentPrivate->numSliceGroups; |
| /*< Slice GroupMapType : For Valid enteries see IH264VENC_SliceGroupMapType*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.sliceGroupMapType = pComponentPrivate->sliceGroupMapType; |
| /*< Slice Group Change Direction Flag: Only valid when sliceGroupMapType |
| //!< is equal to IH264_RASTER_SCAN_SLICE_GRP. |
| //!< For valid values refer IH264VENC_SliceGroupChangeDirection*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.sliceGroupChangeDirectionFlag = pComponentPrivate->sliceGroupChangeDirectionFlag; |
| /*< Slice Group Change Rate: Only valid when sliceGroupMapType |
| //!< is equal to IH264_RASTER_SCAN_SLICE_GRP. |
| //!< valid values are : [0, factor of number of Mbs in a row]*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.sliceGroupChangeRate = pComponentPrivate->sliceGroupChangeRate; |
| /*< Slice Group Change Cycle: Only valid when sliceGroupMapType |
| //!< is equal to IH264_RASTER_SCAN_SLICE_GRP. |
| //!< Valid values can be 0 to numMbsRowsInPicture, also constrained |
| //!< by sliceGroupChangeRate*sliceGroupChangeCycle < totalMbsInFrame*/ |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.sliceGroupChangeCycle = pComponentPrivate->sliceGroupChangeCycle; |
| /*< This field is useful in case of sliceGroupMapType equal to either |
| //!< IH264_INTERLEAVED_SLICE_GRP or IH264_FOREGRND_WITH_LEFTOVER_SLICE_GRP |
| //!< In both cases it has different meaning: |
| //!< In case of IH264_INTERLEAVED_SLICE_GRP: |
| //!< The i-th entery in this array is used to specify the number of consecutive |
| //!< slice group macroblocks to be assigned to the i-th slice group in |
| //!< raster scan order of slice group macroblock units. |
| //!< Valid values are 0 to totalMbsInFrame again constrained by sum of all the elements |
| //!< shouldn't exceed totalMbsInFrame |
| //!< In case of IH264_FOREGRND_WITH_LEFTOVER_SLICE_GRP: |
| //!< First entry in the array specify the start position of foreground region in terms |
| //!< of macroblock number, valid values are [0, totalMbsInFrame-1] |
| //!< Second entry in the array specify the end position of foreground region in terms |
| //!< of macroblock number, valid values are [0, totalMbsInFrame-1] with following constrains: |
| //!< endPos > startPos && endPos%mbsInOneRow > startPos%mbsInOneRow*/ |
| for( i=0; i<MAXNUMSLCGPS;i++) |
| { |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->H264VENC_TI_DYNAMICPARAMS.sliceGroupParams[i] = pComponentPrivate->sliceGroupParams[i]; |
| } |
| |
| ((H264VE_GPP_SN_UALGInputParams*)pUalgInpParams)->ulFrameIndex = pComponentPrivate->nFrameCnt; |
| |
| pComponentPrivate->bForceIFrame = 0; |
| ++pComponentPrivate->nFrameCnt; |
| |
| printH264UAlgInParam(pUalgInpParams, 0, &pComponentPrivate->dbg); |
| OMX_CONF_CIRCULAR_BUFFER_MOVE_TAIL(pBufHead, |
| pComponentPrivate->sCircularBuffer, |
| pComponentPrivate); |
| |
| /*Send Buffer to LCML*/ |
| OMX_PRBUFFER1(pComponentPrivate->dbg, " %p\n", (void*)pBufHead); |
| pBufferPrivate->eBufferOwner = VIDENC_BUFFER_WITH_DSP; |
| eError = LCML_QueueBuffer(pLcmlHandle->pCodecinterfacehandle, |
| EMMCodecInputBuffer, |
| pBufHead->pBuffer, |
| pBufHead->nAllocLen, |
| pBufHead->nFilledLen, |
| (OMX_U8*)pUalgInpParams, |
| sizeof(H264VE_GPP_SN_UALGInputParams), |
| (OMX_U8*)pBufHead); |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_PRDSP4(pComponentPrivate->dbg, "LCML QueueBuffer failed: %x\n", eError); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorHardware); |
| } |
| |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4 || |
| pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| eError = OMX_VIDENC_Queue_Mpeg4_Buffer(pComponentPrivate, pBufHead); |
| } |
| else |
| { |
| OMX_PRBUFFER4(pComponentPrivate->dbg, "Unsupported compression format (%d)\n", |
| pPortDefOut->format.video.eCompressionFormat); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| OMX_CONF_CMD_BAIL: |
| EXIT: |
| return eError; |
| } |
| |
| OMX_ERRORTYPE OMX_VIDENC_Queue_Mpeg4_Buffer(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BUFFERHEADERTYPE* pBufHead) |
| { |
| MP4VE_GPP_SN_UALGInputParams* pUalgInpParams = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| VIDENC_BUFFER_PRIVATE* pBufferPrivate; |
| LCML_DSP_INTERFACE* pLcmlHandle = NULL; |
| VIDEOENC_PORT_TYPE* pCompPortOut = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| |
| pBufferPrivate = (VIDENC_BUFFER_PRIVATE*)pBufHead->pInputPortPrivate; |
| pCompPortOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]; |
| pPortDefOut = pCompPortOut->pPortDef; |
| pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; |
| |
| pUalgInpParams = (MP4VE_GPP_SN_UALGInputParams*)pBufferPrivate->pUalgParam; |
| OMX_DBG_CHECK_CMD(pComponentPrivate->dbg, pUalgInpParams, 1, 1); |
| |
| pUalgInpParams->ulFrameIndex = pComponentPrivate->nFrameCnt; |
| pUalgInpParams->ulTargetFrameRate = pComponentPrivate->nTargetFrameRate; |
| pUalgInpParams->ulTargetBitRate = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pBitRateTypeConfig->nEncodeBitrate; |
| pUalgInpParams->ulGenerateHeader = 0; |
| pUalgInpParams->ulForceIFrame = pComponentPrivate->bForceIFrame; |
| pUalgInpParams->ulResyncInterval = pCompPortOut->pErrorCorrectionType->nResynchMarkerSpacing; |
| if(pCompPortOut->pErrorCorrectionType->bEnableHEC) |
| pUalgInpParams->ulHecInterval = 3; |
| else |
| pUalgInpParams->ulHecInterval = 0; |
| pUalgInpParams->ulAIRRate = pCompPortOut->pIntraRefreshType->nAirRef; |
| pUalgInpParams->ulMIRRate = pComponentPrivate->nMIRRate; |
| pUalgInpParams->ulfCode = 5; |
| pUalgInpParams->ulHalfPel = 1; |
| pUalgInpParams->ul4MV = 0; |
| pUalgInpParams->ulIntraFrameInterval = pComponentPrivate->nIntraFrameInterval; |
| |
| /*Set nQPI Value*/ |
| if (pUalgInpParams->ulForceIFrame == OMX_TRUE) |
| { |
| pUalgInpParams->ulQPIntra = pComponentPrivate->nQPI; |
| } |
| else |
| { |
| pUalgInpParams->ulQPIntra = 0; |
| } |
| |
| /*Set segment mode params*/ |
| if (pComponentPrivate->bMVDataEnable) |
| { |
| pUalgInpParams->ul4MV =1; |
| pUalgInpParams->uluseUMV =1; |
| pUalgInpParams->ulMVDataEnable =1; |
| } |
| else |
| { |
| pUalgInpParams->ul4MV =0; |
| pUalgInpParams->uluseUMV =0; |
| pUalgInpParams->ulMVDataEnable =0; |
| } |
| if (pComponentPrivate->bResyncDataEnable) |
| pUalgInpParams->ulResyncDataEnable =1; |
| else |
| pUalgInpParams->ulResyncDataEnable =0; |
| /* Reset bForceMPEG4IFrame to zero */ |
| pComponentPrivate->bForceIFrame = OMX_FALSE; |
| |
| /*Set ulACPred Value*/ |
| if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) |
| { |
| pUalgInpParams->ulACPred = pComponentPrivate->pMpeg4->bACPred; |
| } |
| else |
| { |
| pUalgInpParams->ulACPred = 0; |
| } |
| pUalgInpParams->ulQPInter = 8; |
| pUalgInpParams->ulLastFrame = 0; |
| pUalgInpParams->ulcapturewidth = 0; |
| pUalgInpParams->ulQpMax = 31; |
| pUalgInpParams->ulQpMin = 2; |
| ++pComponentPrivate->nFrameCnt; |
| |
| if(pComponentPrivate->bRequestVOLHeader == OMX_TRUE) |
| { |
| /*In the case of Mpeg4 we have to send an extra Buffer to LCML requesting for VOL Header*/ |
| memcpy(pComponentPrivate->pTempUalgInpParams,pUalgInpParams,sizeof(MP4VE_GPP_SN_UALGInputParams)); |
| pComponentPrivate->pTempUalgInpParams->ulGenerateHeader = 1; |
| pBufferPrivate->eBufferOwner = VIDENC_BUFFER_WITH_DSP; |
| eError = LCML_QueueBuffer(pLcmlHandle->pCodecinterfacehandle, |
| EMMCodecInputBuffer, |
| pComponentPrivate->pTempUalgInpParams,/*send any buffer*/ |
| 1, |
| 0, |
| pComponentPrivate->pTempUalgInpParams, |
| sizeof(MP4VE_GPP_SN_UALGInputParams), |
| (OMX_U8*)pBufHead); |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_PRDSP2(pComponentPrivate->dbg, "LCML QueueBuffer failed: %x\n", eError); |
| } |
| pComponentPrivate->bRequestVOLHeader = OMX_FALSE; |
| } |
| |
| OMX_PRDSP1(pComponentPrivate->dbg, |
| "TargetFrameRate -> %d\n\ |
| TargetBitRate -> %d\n\ |
| QPI -> %d\n", pComponentPrivate->nTargetFrameRate, |
| (int)pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pBitRateTypeConfig->nEncodeBitrate, |
| pComponentPrivate->nQPI); |
| |
| printMpeg4UAlgInParam(pUalgInpParams, 0, &pComponentPrivate->dbg); |
| OMX_CONF_CIRCULAR_BUFFER_MOVE_TAIL(pBufHead, |
| pComponentPrivate->sCircularBuffer, |
| pComponentPrivate); |
| |
| /*Send Buffer to LCML*/ |
| OMX_PRBUFFER1(pComponentPrivate->dbg, " %p\n", (void*)pBufHead); |
| pBufferPrivate->eBufferOwner = VIDENC_BUFFER_WITH_DSP; |
| eError = LCML_QueueBuffer(pLcmlHandle->pCodecinterfacehandle, |
| EMMCodecInputBuffer, |
| pBufHead->pBuffer, |
| pBufHead->nAllocLen, |
| pBufHead->nFilledLen, |
| (OMX_U8*)pUalgInpParams, |
| sizeof(MP4VE_GPP_SN_UALGInputParams), |
| (OMX_U8*)pBufHead); |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_PRDSP4(pComponentPrivate->dbg, "LCML QueueBuffer failed: %x\n", eError); |
| } |
| |
| OMX_CONF_CMD_BAIL: |
| |
| return eError; |
| } |
| |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_Process_FilledOutBuf() |
| * |
| * Called by component thread, handles filled output buffers from DSP. |
| * |
| * @param pComponentPrivate private component structure for this instance of the component |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * OMX_ErrorInsufficientResources if the malloc fails |
| **/ |
| /*---------------------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_Process_FilledOutBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BUFFERHEADERTYPE* pBufHead) |
| { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| VIDENC_BUFFER_PRIVATE* pBufferPrivate = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| OMX_OTHER_EXTRADATATYPE_1_1_2* pExtraDataType; |
| H264VE_GPP_SN_UALGOutputParams* pSNPrivateParams; |
| OMX_U8* pTemp; |
| OMX_U32* pIndexNal; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| |
| if (pComponentPrivate->bCodecStarted == OMX_TRUE) |
| { |
| |
| pBufferPrivate = pBufHead->pOutputPortPrivate; |
| pSNPrivateParams = (H264VE_GPP_SN_UALGOutputParams*)(pBufferPrivate->pUalgParam); |
| pBufHead->nFilledLen = ((H264VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam)->ulBitstreamSize; |
| |
| if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| pBufHead->nFlags &= ~OMX_BUFFERFLAG_CODECCONFIG; |
| |
| /*Copy Buffer Data to be propagated*/ |
| if((pComponentPrivate->AVCNALFormat == VIDENC_AVC_NAL_SLICE) && |
| (pSNPrivateParams->ulNALUnitsPerFrame != (pSNPrivateParams->ulNALUnitIndex+1)) && |
| (pSNPrivateParams->ulNALUnitsPerFrame != 0)) |
| { |
| |
| pBufHead->pMarkData = NULL; |
| pBufHead->hMarkTargetComponent = NULL; |
| pBufHead->nTickCount = pComponentPrivate->sCircularBuffer.pHead->nTickCount; |
| pBufHead->nTimeStamp = pComponentPrivate->sCircularBuffer.pHead->nTimeStamp; |
| pBufHead->nFlags = 0; |
| } |
| else |
| { |
| OMX_CONF_CIRCULAR_BUFFER_MOVE_HEAD(pBufHead, pComponentPrivate->sCircularBuffer, |
| pComponentPrivate); |
| pBufHead->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; |
| } |
| |
| |
| /* Set lFrameType*/ |
| if (((H264VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam)->lFrameType == OMX_LFRAMETYPE_H264 || |
| ((H264VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam)->lFrameType == OMX_LFRAMETYPE_IDR_H264) |
| { |
| /* IDR Frame */ |
| OMX_S32 nalType = pBufHead->pBuffer[0] & 0x1F; |
| if (nalType == SPS_CODE_PREFIX || nalType == PPS_CODE_PREFIX) { |
| /* Need to drop subsequent SPS or PPS NAL unit since opencore does not |
| * correctly handle storage */ |
| if (!pComponentPrivate->bSentFirstSpsPps) { |
| if (nalType == SPS_CODE_PREFIX) { |
| // Save SPS and send it along with PPS later in a single buffer |
| // Workaround to send a 0-length buffer first. |
| // Ideally, we should not send a buffer at all. |
| pComponentPrivate->sps = malloc(4 + pBufHead->nFilledLen); |
| pComponentPrivate->spsLen = 4 + pBufHead->nFilledLen; |
| memcpy(pComponentPrivate->sps, "\x00\x00\x00\x01", 4); |
| memcpy(pComponentPrivate->sps + 4, pBufHead->pBuffer, pBufHead->nFilledLen); |
| pBufHead->nFilledLen = 0; |
| } |
| |
| /* we can assume here that PPS always comes second */ |
| if (nalType == PPS_CODE_PREFIX) { |
| pComponentPrivate->bSentFirstSpsPps = OMX_TRUE; |
| if (pComponentPrivate->sps == NULL || |
| pComponentPrivate->spsLen == 0) { |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUndefined); |
| } |
| memmove(pBufHead->pBuffer + pComponentPrivate->spsLen + 4, |
| pBufHead->pBuffer, pBufHead->nFilledLen); |
| memmove(pBufHead->pBuffer, |
| pComponentPrivate->sps, pComponentPrivate->spsLen); |
| memcpy(pBufHead->pBuffer + pComponentPrivate->spsLen, "\x00\x00\x00\x01", 4); |
| pBufHead->nFilledLen += pComponentPrivate->spsLen + 4; |
| pBufHead->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; |
| free(pComponentPrivate->sps); |
| pComponentPrivate->sps = NULL; |
| pComponentPrivate->spsLen = 0; |
| } |
| } else { |
| pBufHead->nFilledLen = 0; |
| } |
| } |
| |
| pBufHead->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; |
| } |
| |
| /* if NAL frame mode */ |
| if (pComponentPrivate->AVCNALFormat == VIDENC_AVC_NAL_FRAME) |
| { |
| |
| /*H264VE_GPP_SN_UALGOutputParams* pSNPrivateParams;*/ |
| int nNalSlices; |
| |
| pBufHead->nFlags |= OMX_BUFFERFLAG_EXTRADATA; |
| |
| pTemp = pBufHead->pBuffer + pBufHead->nOffset + pBufHead->nFilledLen + 3; |
| pExtraDataType = (OMX_OTHER_EXTRADATATYPE_1_1_2*) (((OMX_U32) pTemp) & ~3); |
| pIndexNal = (OMX_U32*)(pExtraDataType->data); |
| /*pSNPrivateParams = (H264VE_GPP_SN_UALGOutputParams*)(pBufferPrivate->pUalgParam);*/ |
| |
| pExtraDataType->nVersion.s.nVersionMajor = 1; |
| pExtraDataType->nVersion.s.nVersionMinor = 1; |
| pExtraDataType->nVersion.s.nRevision = 2; |
| pExtraDataType->nPortIndex = VIDENC_OUTPUT_PORT; |
| pExtraDataType->eType = OMX_ExtraDataQuantization; |
| pExtraDataType->nDataSize = (1+pSNPrivateParams->ulNALUnitsPerFrame)*sizeof(OMX_U32); |
| |
| *pIndexNal = pSNPrivateParams->ulNALUnitsPerFrame; |
| pIndexNal++; |
| for (nNalSlices = 0; (OMX_U32)nNalSlices < pSNPrivateParams->ulNALUnitsPerFrame; nNalSlices++, pIndexNal++) |
| { |
| |
| *pIndexNal = (OMX_U32)(pSNPrivateParams->ulNALUnitsSizes[nNalSlices]); |
| } |
| |
| pTemp = (OMX_U8*)((((OMX_U32)pIndexNal)+3) & ~3); |
| pExtraDataType->nSize = (OMX_U32)pTemp-(OMX_U32)pExtraDataType; |
| |
| pExtraDataType = (OMX_OTHER_EXTRADATATYPE_1_1_2*) pTemp; |
| pExtraDataType->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE_1_1_2)+3) & ~3; |
| pExtraDataType->nVersion.s.nVersionMajor = 1; |
| pExtraDataType->nVersion.s.nVersionMinor = 1; |
| pExtraDataType->nVersion.s.nRevision = 2; |
| pExtraDataType->nPortIndex = VIDENC_OUTPUT_PORT; |
| pExtraDataType->eType = OMX_ExtraDataNone; |
| pExtraDataType->nDataSize = 0; |
| } |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4 || |
| pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| pBufHead->nFlags &= ~OMX_BUFFERFLAG_CODECCONFIG; |
| |
| /*We ignore the first Mpeg4 buffer which contains VOL Header since we did not add it to the circular list*/ |
| if(pComponentPrivate->bWaitingForVOLHeaderBuffer == OMX_FALSE) |
| { |
| OMX_CONF_CIRCULAR_BUFFER_MOVE_HEAD(pBufHead, pComponentPrivate->sCircularBuffer, |
| pComponentPrivate); |
| } |
| else |
| { |
| pComponentPrivate->bWaitingForVOLHeaderBuffer = OMX_FALSE; |
| pBufHead->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; |
| } |
| |
| pBufHead->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; |
| |
| /* Set cFrameType*/ |
| if (((MP4VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam)->cFrameType == OMX_CFRAMETYPE_MPEG4) |
| { |
| /* I-VOP Frame */ |
| pBufHead->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; |
| } |
| VIDENC_MPEG4_SEGMENTMODE_METADATA* pMetaData; |
| /*copy MPEG4 segment mode meta data */ |
| pMetaData=(VIDENC_MPEG4_SEGMENTMODE_METADATA*)pBufferPrivate->pMetaData; |
| if (pComponentPrivate->bMVDataEnable==OMX_TRUE) |
| { |
| pMetaData->mvDataSize=((MP4VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam)->mvDataSize; |
| pMetaData->pMVData=((MP4VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam)->MVData; |
| } |
| if (pComponentPrivate->bResyncDataEnable==OMX_TRUE) |
| { |
| pMetaData->pResyncData=((MP4VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam)->ResyncData; |
| pMetaData->numPackets=((MP4VE_GPP_SN_UALGOutputParams*)pBufferPrivate->pUalgParam)->numPackets; |
| } |
| } |
| else |
| { |
| OMX_PRBUFFER4(pComponentPrivate->dbg, "Unsupported compression format (%d)\n", |
| pPortDefOut->format.video.eCompressionFormat); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| |
| if (pBufHead->nFlags & OMX_BUFFERFLAG_EOS) |
| { |
| /* trigger event handler */ |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, OMX_EventBufferFlag, 0x1, pBufHead->nFlags, NULL); |
| /* clear flag */ |
| pComponentPrivate->nFlags = 0; |
| } |
| |
| if (pBufHead->pMarkData != NULL) |
| { |
| /* trigger event handler if we are supposed to */ |
| if (pBufHead->hMarkTargetComponent == pComponentPrivate->pHandle && |
| pBufHead->pMarkData) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, OMX_EventMark, 0x0, 0x0, |
| pBufHead->pMarkData); |
| } |
| } |
| pBufferPrivate->eBufferOwner = VIDENC_BUFFER_WITH_CLIENT; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingBuffer(pComponentPrivate->pPERFcomp, |
| pBufHead->pBuffer, |
| pBufHead->nFilledLen, |
| PERF_ModuleHLMM); |
| #endif |
| pComponentPrivate->sCbData.FillBufferDone(pComponentPrivate->pHandle, |
| pComponentPrivate->pHandle->pApplicationPrivate, |
| pBufHead); |
| OMX_VIDENC_IncrementBufferCountByOne(&pComponentPrivate->FillbufferdoneCount); |
| OMX_VIDENC_SignalIfAllBuffersAreReturned(pComponentPrivate); |
| } |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_Process_FreeInBuf() |
| * |
| * Called by component thread, handles free input buffers from DSP. |
| * |
| * @param pComponentPrivate private component structure for this instance of the component |
| * |
| * @retval OMX_ErrorNone success, ready to roll |
| * OMX_ErrorInsufficientResources if the malloc fails |
| **/ |
| /*---------------------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_Process_FreeInBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BUFFERHEADERTYPE* pBufHead) |
| { |
| VIDENC_NODE* pMemoryListHead = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| OMX_HANDLETYPE hTunnelComponent = NULL; |
| VIDENC_BUFFER_PRIVATE* pBufferPrivate = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| hTunnelComponent = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->hTunnelComponent; |
| pMemoryListHead = pComponentPrivate->pMemoryListHead; |
| |
| /*pBufHead is checked for NULL*/ |
| OMX_DBG_CHECK_CMD(pComponentPrivate->dbg, pBufHead, 1, 1); |
| pBufferPrivate = pBufHead->pInputPortPrivate; |
| |
| if (hTunnelComponent != NULL) |
| { |
| pBufferPrivate->eBufferOwner = VIDENC_BUFFER_WITH_TUNNELEDCOMP; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| PREF(pBufHead,pBuffer), |
| pBufHead->nFilledLen, |
| PERF_ModuleLLMM); |
| #endif |
| |
| eError = OMX_FillThisBuffer(hTunnelComponent, pBufHead); |
| OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, |
| OMX_PRBUFFER4, "FillThisBuffer failed (%x)", eError); |
| } |
| else |
| { |
| pBufferPrivate->eBufferOwner = VIDENC_BUFFER_WITH_CLIENT; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_SendingFrame(pComponentPrivate->pPERFcomp, |
| PREF(pBufHead,pBuffer), |
| 0, |
| PERF_ModuleHLMM); |
| #endif |
| pComponentPrivate->sCbData.EmptyBufferDone(pComponentPrivate->pHandle, |
| pComponentPrivate->pHandle->pApplicationPrivate, |
| pBufHead); |
| OMX_VIDENC_IncrementBufferCountByOne(&pComponentPrivate->EmptybufferdoneCount); |
| OMX_VIDENC_SignalIfAllBuffersAreReturned(pComponentPrivate); |
| } |
| |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * Function to initialize LCML |
| * |
| * |
| * |
| * @retval OMX_NoError Success, ready to roll |
| * |
| **/ |
| /*---------------------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_InitLCML(VIDENC_COMPONENT_PRIVATE* pComponentPrivate) |
| { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| OMX_HANDLETYPE hLCML = NULL; |
| VIDENC_NODE* pMemoryListHead = NULL; |
| #ifdef UNDER_CE |
| typedef OMX_ERRORTYPE (*LPFNDLLFUNC1)(OMX_HANDLETYPE); |
| LPFNDLLFUNC1 fpGetHandle1; |
| #else |
| void* pMyLCML = NULL; |
| fpo fpGetHandle = NULL; |
| char* error = NULL; |
| #endif |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| #ifndef UNDER_CE |
| pMyLCML = dlopen("libLCML.so", RTLD_LAZY); |
| pComponentPrivate->pModLcml = pMyLCML; |
| if (!pMyLCML) |
| { |
| OMX_ERROR5(pComponentPrivate->dbg, "Could not open LCML library\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUndefined); |
| } |
| |
| fpGetHandle = dlsym(pMyLCML, "GetHandle"); |
| if ((error = dlerror()) != NULL) |
| { |
| OMX_ERROR4(pComponentPrivate->dbg, "No GetHandle in LCML library\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUndefined); |
| } |
| |
| eError = (*fpGetHandle)(&hLCML); |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_ERROR5(pComponentPrivate->dbg, "Error While Getting LCML Handle (%x)...\n", eError); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUndefined); |
| } |
| |
| pComponentPrivate->pLCML = (LCML_DSP_INTERFACE*)hLCML; |
| pMemoryListHead = pComponentPrivate->pMemoryListHead; |
| pComponentPrivate->pLCML->pComponentPrivate = (VIDENC_COMPONENT_PRIVATE *)pComponentPrivate; |
| |
| #else |
| g_hLcmlDllHandle = LoadLibraryEx(TEXT("oaf_bml.dll"), NULL, 0); |
| if (g_hLcmlDllHandle == NULL) |
| { |
| OMX_ERROR5(pComponentPrivate->dbg, "BML Load Failed!!!, %d\n", GetLastError()); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUndefined); |
| } |
| fpGetHandle1 = (LPFNDLLFUNC1)GetProcAddress(g_hLcmlDllHandle,TEXT("GetHandle")); |
| if (!fpGetHandle1) |
| { |
| FreeLibrary(g_hLcmlDllHandle); |
| g_hLcmlDllHandle = NULL; |
| OMX_ERROR4(pComponentPrivate->dbg, "No GetHandle in BML\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUndefined); |
| } |
| eError = fpGetHandle1(&hLCML); |
| if (eError != OMX_ErrorNone) |
| { |
| FreeLibrary(g_hLcmlDllHandle); |
| g_hLcmlDllHandle = NULL; |
| OMX_ERROR5(pComponentPrivate->dbg, "Error While Getting LCML Handle (%x)...\n", eError); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUndefined); |
| } |
| (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML = (LCML_DSP_INTERFACE*)hLCML; |
| pComponentPrivate->pLCML->pComponentPrivate = (VIDENC_COMPONENT_PRIVATE *)pComponentPrivate; |
| #endif |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * Function to fill DSP structures via LCML |
| * |
| * |
| * |
| * @retval OMX_NoError Success, ready to roll |
| * |
| **/ |
| /*---------------------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_InitDSP_H264Enc(VIDENC_COMPONENT_PRIVATE* pComponentPrivate) |
| { |
| OMX_U16 nArr[100]; |
| OMX_U32* pTmp = NULL; |
| LCML_CALLBACKTYPE sCb; |
| LCML_DSP* pLcmlDSP = NULL; |
| VIDENC_NODE* pMemoryListHead = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| OMX_VIDEO_PARAM_AVCTYPE* pH264 = NULL; |
| LCML_DSP_INTERFACE* pLcmlHandle = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefIn = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| OMX_VIDEO_PARAM_BITRATETYPE* pVidParamBitrate = NULL; |
| OMX_VIDEO_PARAM_QUANTIZATIONTYPE* pQuantization = NULL; |
| H264VE_GPP_SN_Obj_CreatePhase* pCreatePhaseArgs = NULL; |
| /* OMX_VIDEO_CONFIG_AVCINTRAPERIOD* pH264IntraPeriod = NULL; */ |
| OMX_VIDEO_PARAM_MOTIONVECTORTYPE* pMotionVector = NULL; |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pPortDefIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->pPortDef; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| pH264 = pComponentPrivate->pH264; |
| pVidParamBitrate = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pBitRateType; |
| pQuantization = pComponentPrivate->pQuantization; |
| pMemoryListHead = pComponentPrivate->pMemoryListHead; |
| /* pH264IntraPeriod = pComponentPrivate->pH264IntraPeriod; */ |
| pMotionVector = pComponentPrivate->pMotionVector; |
| pComponentPrivate->bErrorLcmlHandle = OMX_FALSE; |
| |
| pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; |
| pLcmlDSP = (((LCML_DSP_INTERFACE*)pLcmlHandle)->dspCodec); |
| pLcmlDSP = (((LCML_DSP_INTERFACE*)pLcmlHandle)->dspCodec); |
| |
| pLcmlDSP->In_BufInfo.nBuffers = pPortDefIn->nBufferCountActual; |
| pLcmlDSP->In_BufInfo.nSize = pComponentPrivate->nInBufferSize; |
| pLcmlDSP->In_BufInfo.DataTrMethod = DMM_METHOD; |
| |
| pLcmlDSP->Out_BufInfo.nBuffers = pPortDefOut->nBufferCountActual; |
| pLcmlDSP->Out_BufInfo.nSize = pComponentPrivate->nOutBufferSize; |
| pLcmlDSP->Out_BufInfo.DataTrMethod = DMM_METHOD; |
| |
| pLcmlDSP->NodeInfo.nNumOfDLLs = OMX_H264ENC_NUM_DLLS; |
| pLcmlDSP->NodeInfo.AllUUIDs[0].uuid = &H264VESOCKET_TI_UUID; |
| strcpy ((char *)pLcmlDSP->NodeInfo.AllUUIDs[0].DllName,H264_ENC_NODE_DLL); |
| pLcmlDSP->NodeInfo.AllUUIDs[0].eDllType = DLL_NODEOBJECT; |
| |
| pLcmlDSP->NodeInfo.AllUUIDs[1].uuid = &H264VESOCKET_TI_UUID; |
| strcpy ((char *)pLcmlDSP->NodeInfo.AllUUIDs[1].DllName,H264_ENC_NODE_DLL); |
| pLcmlDSP->NodeInfo.AllUUIDs[1].eDllType = DLL_DEPENDENT; |
| |
| pLcmlDSP->NodeInfo.AllUUIDs[2].uuid = &USN_UUID; |
| strcpy ((char *)pLcmlDSP->NodeInfo.AllUUIDs[2].DllName,USN_DLL); |
| pLcmlDSP->NodeInfo.AllUUIDs[2].eDllType = DLL_DEPENDENT; |
| |
| pLcmlDSP->SegID = 0; |
| pLcmlDSP->Timeout = -1; |
| pLcmlDSP->Alignment = 0; |
| pLcmlDSP->Priority = 5; |
| |
| #ifdef GPP_PRIVATE_NODE_HEAP |
| if ((pPortDefIn->format.video.nFrameWidth <= 176) && |
| (pPortDefIn->format.video.nFrameHeight <= 144)) |
| { |
| pLcmlDSP->ProfileID = 0; |
| } |
| else if ((pPortDefIn->format.video.nFrameWidth <= 352) && |
| (pPortDefIn->format.video.nFrameHeight <= 288)) |
| { |
| pLcmlDSP->ProfileID = 1; |
| } |
| else |
| { |
| pLcmlDSP->ProfileID = 2; |
| } |
| #else |
| pLcmlDSP->ProfileID = 0xff; /* Use DSP node heap */ |
| #endif |
| |
| /* pLcmlDSP->buffindx = 999; */ |
| |
| VIDENC_MALLOC(pCreatePhaseArgs, |
| sizeof(H264VE_GPP_SN_Obj_CreatePhase), |
| H264VE_GPP_SN_Obj_CreatePhase, |
| pMemoryListHead, |
| pComponentPrivate->dbg); |
| |
| pCreatePhaseArgs->usNumStreams = 2; |
| pCreatePhaseArgs->usStreamId = VIDENC_INPUT_PORT; |
| pCreatePhaseArgs->usBuffTypeInStream = 0; |
| pCreatePhaseArgs->usMaxBuffsInStream = (OMX_U16)pPortDefIn->nBufferCountActual; |
| pCreatePhaseArgs->usStreamId2 = VIDENC_OUTPUT_PORT; |
| pCreatePhaseArgs->usBuffTypeInStream2 = 0; |
| pCreatePhaseArgs->usMaxBuffsInStream2 = (OMX_U16)pPortDefOut->nBufferCountActual; |
| |
| pCreatePhaseArgs->ulWidth = pPortDefIn->format.video.nFrameWidth; |
| pCreatePhaseArgs->ulHeight = pPortDefIn->format.video.nFrameHeight; |
| pCreatePhaseArgs->ulTargetBitRate = pPortDefOut->format.video.nBitrate; |
| pCreatePhaseArgs->ulBitstreamBuffSize = pComponentPrivate->nOutBufferSize; |
| pCreatePhaseArgs->ulFrameRate = (unsigned int)(Q16Tof(pPortDefIn->format.video.xFramerate)*1000.0); |
| |
| /* set run-time frame and bit rates to create-time values */ |
| pComponentPrivate->nTargetFrameRate = pCreatePhaseArgs->ulFrameRate; |
| pComponentPrivate->nPrevTargetFrameRate = 0; |
| pComponentPrivate->bSentFirstSpsPps = OMX_FALSE; |
| |
| if (pPortDefIn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) |
| { |
| pCreatePhaseArgs->ucYUVFormat = 0; |
| } |
| else if (pPortDefIn->format.video.eColorFormat == OMX_COLOR_FormatCbYCrY) /*422 LE UYVY*/ |
| { |
| pCreatePhaseArgs->ucYUVFormat = 2; |
| } |
| else if (pPortDefIn->format.video.eColorFormat == OMX_COLOR_FormatYCbYCr) /*422 BE YUYV */ |
| { |
| pCreatePhaseArgs->ucYUVFormat = 1; |
| } |
| else |
| { |
| OMX_PRDSP2(pComponentPrivate->dbg, "Unsupported YUV format.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| |
| pCreatePhaseArgs->ucUnrestrictedMV = pComponentPrivate->ucUnrestrictedMV; |
| pCreatePhaseArgs->ucNumRefFrames = 1; |
| |
| if (pVidParamBitrate->eControlRate == OMX_Video_ControlRateVariable) |
| { |
| pCreatePhaseArgs->ucRateControlAlgorithm = 0; |
| } |
| else if (pVidParamBitrate->eControlRate == OMX_Video_ControlRateConstant) |
| { |
| pCreatePhaseArgs->ucRateControlAlgorithm = 1; |
| } |
| else if (pVidParamBitrate->eControlRate == OMX_Video_ControlRateDisable) |
| { |
| pCreatePhaseArgs->ucRateControlAlgorithm = 2; |
| } |
| else |
| { |
| OMX_PRDSP2(pComponentPrivate->dbg, "Unsupported rate control algorithm.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| |
| pCreatePhaseArgs->ucIDREnable = 1; |
| |
| if (pComponentPrivate->bDeblockFilter == OMX_FALSE) |
| { |
| pCreatePhaseArgs->ucDeblockingEnable = 0; |
| } |
| else if (pComponentPrivate->bDeblockFilter == OMX_TRUE) |
| { |
| pCreatePhaseArgs->ucDeblockingEnable = 1; |
| } |
| else |
| { |
| OMX_PRDSP2(pComponentPrivate->dbg, "Unsupported deblocking setting.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorBadParameter); |
| } |
| |
| pCreatePhaseArgs->ucMVRange = (pMotionVector->sXSearchRange > pMotionVector->sYSearchRange ? pMotionVector->sXSearchRange : pMotionVector->sYSearchRange); |
| pCreatePhaseArgs->ucQPIFrame = 28; |
| pCreatePhaseArgs->ucProfile = 66; |
| pCreatePhaseArgs->ulIntraFramePeriod = pCreatePhaseArgs->ulFrameRate > 15000 ? 29 : 14; |
| |
| if (pH264->eLevel == OMX_VIDEO_AVCLevel1b) |
| { |
| pCreatePhaseArgs->ucLevel = 9; |
| } |
| else if (pH264->eLevel == OMX_VIDEO_AVCLevel1) |
| { |
| pCreatePhaseArgs->ucLevel = 10; |
| } |
| else if (pH264->eLevel == OMX_VIDEO_AVCLevel11) |
| { |
| pCreatePhaseArgs->ucLevel = 11; |
| } |
| else if (pH264->eLevel == OMX_VIDEO_AVCLevel12) |
| { |
| pCreatePhaseArgs->ucLevel = 12; |
| } |
| else if (pH264->eLevel == OMX_VIDEO_AVCLevel13) |
| { |
| pCreatePhaseArgs->ucLevel = 13; |
| } |
| else if (pH264->eLevel == OMX_VIDEO_AVCLevel2) |
| { |
| pCreatePhaseArgs->ucLevel = 20; |
| } |
| else if (pH264->eLevel == OMX_VIDEO_AVCLevel21) |
| { |
| pCreatePhaseArgs->ucLevel = 21; |
| } |
| else if (pH264->eLevel == OMX_VIDEO_AVCLevel22) |
| { |
| pCreatePhaseArgs->ucLevel = 22; |
| } |
| else if (pH264->eLevel == OMX_VIDEO_AVCLevel3) |
| { |
| pCreatePhaseArgs->ucLevel = 30; |
| if ((pPortDefIn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) && |
| (pPortDefIn->format.video.nFrameWidth == 320) && |
| (pPortDefIn->format.video.nFrameHeight == 240)) |
| { |
| pCreatePhaseArgs->ucQPIFrame = 0; |
| } |
| } |
| else |
| { |
| OMX_DBG_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting, |
| pComponentPrivate->dbg, OMX_PRDSP2, |
| "Unsupported level.\n"); |
| } |
| |
| /* override parameters for VGA & D1 encoding */ |
| if ((pPortDefIn->format.video.nFrameWidth >= 640 || |
| pPortDefIn->format.video.nFrameHeight >= 480) && |
| pCreatePhaseArgs->ulFrameRate > 15000) |
| { |
| pComponentPrivate->maxMVperMB = 1; |
| pComponentPrivate->intra4x4EnableIdc = INTRA4x4_ISLICES; |
| pComponentPrivate->nIntraFrameInterval = 30; |
| pComponentPrivate->nAIRRate = 0; |
| /* Encoding preset = 4 enables DSP side optimizations for high resolutions */ |
| pComponentPrivate->nEncodingPreset = 4; |
| pCreatePhaseArgs->ulIntraFramePeriod = 0; |
| /* Constant bit rate control enabled */ |
| pCreatePhaseArgs->ucRateControlAlgorithm = 1; |
| pCreatePhaseArgs->ucLevel = 30; |
| } |
| /* Ensure frame rate update interval, which forces IDR frames, is same as I-Slice interval */ |
| pComponentPrivate->nFrameRateUpdateInterval = pComponentPrivate->nIntraFrameInterval; |
| pCreatePhaseArgs->usNalCallback = pComponentPrivate->AVCNALFormat; |
| pCreatePhaseArgs->ulEncodingPreset = pComponentPrivate->nEncodingPreset; |
| pCreatePhaseArgs->ulRcAlgo = 0; |
| pCreatePhaseArgs->endArgs = END_OF_CR_PHASE_ARGS; |
| printH264CreateParams(pCreatePhaseArgs, &pComponentPrivate->dbg); |
| |
| pTmp = memcpy (nArr, pCreatePhaseArgs, sizeof(H264VE_GPP_SN_Obj_CreatePhase)); |
| if (pTmp == NULL) |
| { |
| OMX_TRACE4(pComponentPrivate->dbg, "memcpy() out of memory error.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorInsufficientResources); |
| } |
| pLcmlDSP->pCrPhArgs = nArr; |
| sCb.LCML_Callback = (void *)OMX_VIDENC_LCML_Callback; |
| |
| eError = LCML_InitMMCodec(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, |
| NULL, |
| &pLcmlHandle, |
| NULL, |
| &sCb); |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_PRDSP4(pComponentPrivate->dbg, "LCML_InitMMCodec Failed!...\n"); |
| /*TODO: Validate eError from LCML_InitMMCodec for ResourceExhaustionTest */ |
| pComponentPrivate->bErrorLcmlHandle = OMX_TRUE; |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorInsufficientResources); |
| } |
| pComponentPrivate->bCodecLoaded = OMX_TRUE; |
| VIDENC_FREE(pCreatePhaseArgs, pMemoryListHead, |
| pComponentPrivate->dbg); |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * Function to fill DSP structures via LCML |
| * |
| * |
| * |
| * @retval OMX_NoError Success, ready to roll |
| * |
| **/ |
| /*---------------------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_InitDSP_Mpeg4Enc(VIDENC_COMPONENT_PRIVATE* pComponentPrivate) |
| { |
| OMX_U16 nArr[100]; |
| OMX_U32* pTmp = NULL; |
| LCML_CALLBACKTYPE sCb; |
| LCML_DSP* pLcmlDSP = NULL; |
| VIDENC_NODE* pMemoryListHead = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| LCML_DSP_INTERFACE* pLcmlHandle = NULL; |
| OMX_VIDEO_PARAM_H263TYPE* pH263 = NULL; |
| OMX_VIDEO_PARAM_MPEG4TYPE* pMpeg4 = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefIn = NULL; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| MP4VE_GPP_SN_Obj_CreatePhase* pCreatePhaseArgs = NULL; |
| OMX_VIDEO_PARAM_BITRATETYPE* pVidParamBitrate = NULL; |
| OMX_VIDEO_PARAM_QUANTIZATIONTYPE* pQuantization = NULL; |
| VIDEOENC_PORT_TYPE* pCompPortOut = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pPortDefIn = pComponentPrivate->pCompPort[VIDENC_INPUT_PORT]->pPortDef; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| pCompPortOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]; |
| pVidParamBitrate = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pBitRateType; |
| pQuantization = pComponentPrivate->pQuantization; |
| pH263 = pComponentPrivate->pH263; |
| pMpeg4 = pComponentPrivate->pMpeg4; |
| pMemoryListHead = pComponentPrivate->pMemoryListHead; |
| |
| pComponentPrivate->bErrorLcmlHandle = OMX_FALSE; |
| |
| pLcmlHandle = (LCML_DSP_INTERFACE*)pComponentPrivate->pLCML; |
| pLcmlDSP = (((LCML_DSP_INTERFACE*)pLcmlHandle)->dspCodec); |
| |
| pLcmlDSP->In_BufInfo.nBuffers = pPortDefIn->nBufferCountActual; |
| pLcmlDSP->In_BufInfo.nSize = pComponentPrivate->nInBufferSize; |
| pLcmlDSP->In_BufInfo.DataTrMethod = DMM_METHOD; |
| |
| pLcmlDSP->Out_BufInfo.nBuffers = pPortDefOut->nBufferCountActual; |
| pLcmlDSP->Out_BufInfo.nSize = pComponentPrivate->nOutBufferSize; |
| pLcmlDSP->Out_BufInfo.DataTrMethod = DMM_METHOD; |
| |
| pLcmlDSP->NodeInfo.nNumOfDLLs = OMX_MP4ENC_NUM_DLLS; |
| pLcmlDSP->NodeInfo.AllUUIDs[0].uuid = &MP4VESOCKET_TI_UUID; |
| strcpy ((char *)pLcmlDSP->NodeInfo.AllUUIDs[0].DllName,MP4_ENC_NODE_DLL); |
| pLcmlDSP->NodeInfo.AllUUIDs[0].eDllType = DLL_NODEOBJECT; |
| |
| pLcmlDSP->NodeInfo.AllUUIDs[1].uuid = &MP4VESOCKET_TI_UUID; |
| strcpy ((char *)pLcmlDSP->NodeInfo.AllUUIDs[1].DllName,MP4_ENC_NODE_DLL); |
| pLcmlDSP->NodeInfo.AllUUIDs[1].eDllType = DLL_DEPENDENT; |
| |
| pLcmlDSP->NodeInfo.AllUUIDs[2].uuid = &USN_UUID; |
| strcpy ((char *)pLcmlDSP->NodeInfo.AllUUIDs[2].DllName,USN_DLL); |
| pLcmlDSP->NodeInfo.AllUUIDs[2].eDllType = DLL_DEPENDENT; |
| |
| pLcmlDSP->SegID = 0; |
| pLcmlDSP->Timeout = -1; |
| pLcmlDSP->Alignment = 0; |
| pLcmlDSP->Priority = 5; |
| |
| #ifdef GPP_PRIVATE_NODE_HEAP |
| if ((pPortDefIn->format.video.nFrameWidth <= 176) && |
| (pPortDefIn->format.video.nFrameHeight <= 144)) |
| { |
| pLcmlDSP->ProfileID = 0; |
| } |
| else if ((pPortDefIn->format.video.nFrameWidth <= 352) && |
| (pPortDefIn->format.video.nFrameHeight <= 288)) |
| { |
| pLcmlDSP->ProfileID = 1; |
| } |
| else if ((pPortDefIn->format.video.nFrameWidth <= 640) && |
| (pPortDefIn->format.video.nFrameHeight <= 480)) |
| { |
| pLcmlDSP->ProfileID = 2; |
| } |
| else if ((pPortDefIn->format.video.nFrameWidth <= 720) && |
| (pPortDefIn->format.video.nFrameHeight <= 480)) |
| { |
| pLcmlDSP->ProfileID = 3; |
| } |
| else if ((pPortDefIn->format.video.nFrameWidth <= 720) && |
| (pPortDefIn->format.video.nFrameHeight <= 576)) |
| { |
| pLcmlDSP->ProfileID = 4; |
| } |
| else |
| { |
| pLcmlDSP->ProfileID = 4; |
| } |
| #else |
| pLcmlDSP->ProfileID = 0xff; /* Use DSP node heap */ |
| #endif |
| |
| /* pLcmlDSP->buffindx = 999; */ |
| |
| VIDENC_MALLOC(pCreatePhaseArgs, |
| sizeof(MP4VE_GPP_SN_Obj_CreatePhase), |
| MP4VE_GPP_SN_Obj_CreatePhase, |
| pMemoryListHead, |
| pComponentPrivate->dbg); |
| |
| pCreatePhaseArgs->ucUnrestrictedMV = pComponentPrivate->ucUnrestrictedMV; |
| pCreatePhaseArgs->ucProfile = 1; |
| |
| pCreatePhaseArgs->usNumStreams = 2; |
| pCreatePhaseArgs->usStreamId = 0; |
| pCreatePhaseArgs->usBuffTypeInStream = 0; |
| pCreatePhaseArgs->usMaxBuffsInStream = (OMX_U16)pPortDefIn->nBufferCountActual; |
| pCreatePhaseArgs->usStreamId2 = 1; |
| pCreatePhaseArgs->usBuffTypeInStream2 = 0; |
| pCreatePhaseArgs->usMaxBuffsInStream2 = (OMX_U16)pPortDefOut->nBufferCountActual; |
| |
| pCreatePhaseArgs->ulWidth = pPortDefIn->format.video.nFrameWidth; |
| pCreatePhaseArgs->ulHeight = pPortDefIn->format.video.nFrameHeight; |
| pCreatePhaseArgs->ulTargetBitRate = pPortDefOut->format.video.nBitrate; |
| pCreatePhaseArgs->ulVBVSize = pComponentPrivate->nVBVSize; |
| |
| if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| pCreatePhaseArgs->ulGOBHeadersInterval = pH263->nGOBHeaderInterval; |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) |
| { |
| pCreatePhaseArgs->ulGOBHeadersInterval = 0; |
| } |
| |
| if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| pCreatePhaseArgs->ucIsMPEG4 = 0; |
| } |
| else if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) |
| { |
| pCreatePhaseArgs->ucIsMPEG4 = 1; |
| /*Initialize variables for the generation of VOL Header*/ |
| pComponentPrivate->bRequestVOLHeader = OMX_TRUE; |
| pComponentPrivate->bWaitingForVOLHeaderBuffer = OMX_TRUE; |
| pComponentPrivate->bWaitingVOLHeaderCallback = OMX_TRUE; |
| } |
| else |
| { |
| OMX_PRDSP4(pComponentPrivate->dbg, "Unsupported video format (%d).\n", |
| pPortDefOut->format.video.eCompressionFormat); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| |
| if (pPortDefIn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) |
| { |
| pCreatePhaseArgs->ucYUVFormat = 0; |
| } |
| else if (pPortDefIn->format.video.eColorFormat == OMX_COLOR_FormatCbYCrY) /*422 LE UYVY*/ |
| { |
| pCreatePhaseArgs->ucYUVFormat = 2; |
| } |
| else if (pPortDefIn->format.video.eColorFormat == OMX_COLOR_FormatYCbYCr) /*422 BE YUYV */ |
| { |
| pCreatePhaseArgs->ucYUVFormat = 1; |
| } |
| else |
| { |
| OMX_PRDSP2(pComponentPrivate->dbg, "Unsupported YUV format.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| if(pCompPortOut->pErrorCorrectionType->bEnableHEC) |
| pCreatePhaseArgs->ucHEC = 1; |
| else |
| pCreatePhaseArgs->ucHEC = 0;/**/ |
| |
| if(pCompPortOut->pErrorCorrectionType->bEnableResync) |
| pCreatePhaseArgs->ucResyncMarker = 1; |
| else |
| pCreatePhaseArgs->ucResyncMarker = 0;/**/ |
| |
| if(pCompPortOut->pErrorCorrectionType->bEnableDataPartitioning) |
| pCreatePhaseArgs->ucDataPartitioning = 1; |
| else |
| pCreatePhaseArgs->ucDataPartitioning = 0;/**/ |
| |
| if(pCompPortOut->pErrorCorrectionType->bEnableRVLC) |
| pCreatePhaseArgs->ucReversibleVLC = 1; |
| else |
| pCreatePhaseArgs->ucReversibleVLC = 0;/**/ |
| |
| pCreatePhaseArgs->ucFrameRate = (OMX_U8) Q16Tof(pPortDefIn->format.video.xFramerate); |
| |
| /* set run-time frame and bit rates to create-time values */ |
| pComponentPrivate->nTargetFrameRate = pCreatePhaseArgs->ucFrameRate; |
| pComponentPrivate->nPrevTargetFrameRate = 0; |
| pComponentPrivate->nTargetBitRate = pCreatePhaseArgs->ulTargetBitRate; |
| |
| if (pVidParamBitrate->eControlRate == OMX_Video_ControlRateConstant) |
| { |
| pCreatePhaseArgs->ucRateControlAlgorithm = IVIDEO_LOW_DELAY; |
| } |
| else if (pVidParamBitrate->eControlRate == OMX_Video_ControlRateVariable) |
| { |
| pCreatePhaseArgs->ucRateControlAlgorithm = IVIDEO_STORAGE; |
| } |
| else if (pVidParamBitrate->eControlRate == OMX_Video_ControlRateDisable) |
| { |
| pCreatePhaseArgs->ucRateControlAlgorithm = IVIDEO_NONE; |
| } |
| else |
| { |
| OMX_PRDSP2(pComponentPrivate->dbg, "Unsupported rate control algorithm.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| |
| pCreatePhaseArgs->ucQPFirstIFrame = (OMX_U8)pQuantization->nQpI; |
| |
| if (pCreatePhaseArgs->ucIsMPEG4 == 1) |
| { |
| #ifdef __KHRONOS_CONF_1_1__ |
| if (pMpeg4->eLevel == OMX_VIDEO_MPEG4Level0) |
| { |
| pCreatePhaseArgs->ucLevel = 0; |
| } |
| else if (pMpeg4->eLevel == OMX_VIDEO_MPEG4Level1) |
| { |
| pCreatePhaseArgs->ucLevel = 1; |
| } |
| else if (pMpeg4->eLevel == OMX_VIDEO_MPEG4Level2) |
| { |
| pCreatePhaseArgs->ucLevel = 2; |
| } |
| else if (pMpeg4->eLevel == OMX_VIDEO_MPEG4Level3) |
| { |
| pCreatePhaseArgs->ucLevel = 3; |
| } |
| else if (pMpeg4->eLevel == OMX_VIDEO_MPEG4Level4a || |
| pMpeg4->eLevel == OMX_VIDEO_MPEG4Level4) |
| { |
| pCreatePhaseArgs->ucLevel = 4; |
| } |
| else if (pMpeg4->eLevel == OMX_VIDEO_MPEG4Level5) |
| { |
| pCreatePhaseArgs->ucLevel = 5; |
| } |
| else if (pMpeg4->eLevel == OMX_VIDEO_MPEG4Level0b) |
| { |
| pCreatePhaseArgs->ucLevel = 100; |
| } |
| else |
| { |
| OMX_PRDSP2(pComponentPrivate->dbg, "Unsupported level.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| #else |
| pCreatePhaseArgs->ucLevel = pMpeg4->eLevel; |
| #endif |
| pCreatePhaseArgs->enableH263AnnexI = 0; |
| pCreatePhaseArgs->enableH263AnnexJ = 0; |
| pCreatePhaseArgs->enableH263AnnexT = 0; |
| |
| } |
| else |
| { |
| if (pH263->eLevel == OMX_VIDEO_H263Level10) |
| { |
| pCreatePhaseArgs->ucLevel = 10; |
| } |
| else if (pH263->eLevel == OMX_VIDEO_H263Level20) |
| { |
| pCreatePhaseArgs->ucLevel = 20; |
| } |
| else if (pH263->eLevel == OMX_VIDEO_H263Level30) |
| { |
| pCreatePhaseArgs->ucLevel = 30; |
| } |
| else if (pH263->eLevel == OMX_VIDEO_H263Level40) |
| { |
| pCreatePhaseArgs->ucLevel = 40; |
| } |
| else if (pH263->eLevel == OMX_VIDEO_H263Level45) |
| { |
| pCreatePhaseArgs->ucLevel = 45; |
| } |
| else if (pH263->eLevel == OMX_VIDEO_H263Level50) |
| { |
| pCreatePhaseArgs->ucLevel = 50; |
| } |
| else if (pH263->eLevel == OMX_VIDEO_H263Level60) |
| { |
| pCreatePhaseArgs->ucLevel = 60; |
| } |
| else if (pH263->eLevel == OMX_VIDEO_H263Level70) |
| { |
| pCreatePhaseArgs->ucLevel = 70; |
| } |
| else |
| { |
| OMX_PRDSP2(pComponentPrivate->dbg, "Unsupported level.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUnsupportedSetting); |
| } |
| |
| pCreatePhaseArgs->enableH263AnnexI = 0; |
| pCreatePhaseArgs->enableH263AnnexJ = 0; |
| pCreatePhaseArgs->enableH263AnnexT = 0; |
| } |
| pCreatePhaseArgs->ulMaxDelay = 300; |
| #ifndef MODE_3410 |
| pCreatePhaseArgs->ulVbvParamEnable = 0; |
| pCreatePhaseArgs->ulH263SliceMode = 0; |
| #endif |
| pCreatePhaseArgs->ulUseGOV = 0; |
| if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) |
| pCreatePhaseArgs->ulUseVOS = 1;//needed to generate VOL Header |
| else |
| pCreatePhaseArgs->ulUseVOS = 0; |
| pCreatePhaseArgs->endArgs = END_OF_CR_PHASE_ARGS; |
| pTmp = memcpy(nArr, pCreatePhaseArgs, sizeof(MP4VE_GPP_SN_Obj_CreatePhase)); |
| if (pTmp == NULL) |
| { |
| OMX_TRACE4(pComponentPrivate->dbg, "memcpy() out of memory error.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorInsufficientResources); |
| } |
| |
| pLcmlDSP->pCrPhArgs = nArr; |
| printMpeg4Params(pCreatePhaseArgs, &pComponentPrivate->dbg); |
| |
| sCb.LCML_Callback = (void *)OMX_VIDENC_LCML_Callback; |
| eError = LCML_InitMMCodec(((LCML_DSP_INTERFACE*)pLcmlHandle)->pCodecinterfacehandle, |
| NULL, |
| &pLcmlHandle, |
| NULL, |
| &sCb); |
| |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_PRDSP4(pComponentPrivate->dbg, "LCML_InitMMCodec Failed!...\n"); |
| /*TODO: Validate eError from LCML_InitMMCodec for ResourceExhaustionTest */ |
| pComponentPrivate->bErrorLcmlHandle = OMX_TRUE; |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorInsufficientResources); |
| } |
| pComponentPrivate->bCodecLoaded = OMX_TRUE; |
| VIDENC_FREE(pCreatePhaseArgs, pMemoryListHead, |
| pComponentPrivate->dbg); |
| |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| /*----------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_Allocate_DSPResources() |
| * |
| * |
| * |
| * |
| * @param |
| * @param |
| * @param |
| * |
| * @retval OMX_NoError Success, ready to roll |
| * OMX_Error_BadParameter The input parameter pointer is null |
| **/ |
| /*----------------------------------------------------------------------------*/ |
| |
| OMX_ERRORTYPE OMX_VIDENC_Allocate_DSPResources(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, |
| OMX_IN OMX_U32 nPortIndex) |
| { |
| char* pTemp = NULL; |
| OMX_U32 nBufferCnt = -1; |
| VIDENC_NODE* pMemoryListHead = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| VIDEOENC_PORT_TYPE* pCompPort = NULL; |
| OMX_VIDEO_CODINGTYPE eCompressionFormat = -1; |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDefOut = NULL; |
| |
| OMX_CONF_CHECK_CMD(pComponentPrivate, 1, 1); |
| |
| pMemoryListHead = pComponentPrivate->pMemoryListHead; |
| pCompPort = pComponentPrivate->pCompPort[nPortIndex]; |
| nBufferCnt = pComponentPrivate->pCompPort[nPortIndex]->nBufferCnt; |
| pPortDefOut = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| eCompressionFormat = pPortDefOut->format.video.eCompressionFormat; |
| |
| if (nPortIndex == VIDENC_INPUT_PORT) |
| { |
| if (eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| H264VE_GPP_SN_UALGInputParams* pUalgParam; |
| |
| VIDENC_MALLOC(pUalgParam, |
| sizeof(H264VE_GPP_SN_UALGInputParams) + 256, |
| H264VE_GPP_SN_UALGInputParams, |
| pMemoryListHead, |
| pComponentPrivate->dbg); |
| |
| pTemp = (char*)pUalgParam; |
| pTemp += 128; |
| pUalgParam = (H264VE_GPP_SN_UALGInputParams*)pTemp; |
| pCompPort->pBufferPrivate[nBufferCnt]->pUalgParam = pUalgParam; |
| } |
| else if (eCompressionFormat == OMX_VIDEO_CodingMPEG4 || |
| eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| MP4VE_GPP_SN_UALGInputParams* pUalgParam; |
| |
| VIDENC_MALLOC(pUalgParam, |
| sizeof(MP4VE_GPP_SN_UALGInputParams) + 256, |
| MP4VE_GPP_SN_UALGInputParams, |
| pMemoryListHead, |
| pComponentPrivate->dbg); |
| pTemp = (char*)pUalgParam; |
| pTemp += 128; |
| pUalgParam = (MP4VE_GPP_SN_UALGInputParams*)pTemp; |
| pCompPort->pBufferPrivate[nBufferCnt]->pUalgParam = pUalgParam; |
| if(eCompressionFormat == OMX_VIDEO_CodingMPEG4) |
| {/*Structure needed to send the request for VOLHeader to SN*/ |
| VIDENC_MALLOC(pComponentPrivate->pTempUalgInpParams, |
| sizeof(MP4VE_GPP_SN_UALGInputParams) + 256, |
| MP4VE_GPP_SN_UALGInputParams, |
| pMemoryListHead, |
| pComponentPrivate->dbg); |
| pTemp = (char*)pComponentPrivate->pTempUalgInpParams; |
| pTemp += 128; |
| pComponentPrivate->pTempUalgInpParams = (MP4VE_GPP_SN_UALGInputParams*)pTemp; |
| } |
| } |
| } |
| else if (nPortIndex == VIDENC_OUTPUT_PORT) |
| { |
| if (eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| H264VE_GPP_SN_UALGOutputParams* pUalgParam; |
| |
| VIDENC_MALLOC(pUalgParam, |
| sizeof(H264VE_GPP_SN_UALGOutputParams) + 256, |
| H264VE_GPP_SN_UALGOutputParams, |
| pMemoryListHead, |
| pComponentPrivate->dbg); |
| pTemp = (char*)pUalgParam; |
| pTemp += 128; |
| pUalgParam = (H264VE_GPP_SN_UALGOutputParams*)pTemp; |
| pCompPort->pBufferPrivate[nBufferCnt]->pUalgParam = pUalgParam; |
| } |
| else if (eCompressionFormat == OMX_VIDEO_CodingMPEG4 || |
| eCompressionFormat == OMX_VIDEO_CodingH263) |
| { |
| MP4VE_GPP_SN_UALGOutputParams* pUalgParam; |
| |
| VIDENC_MALLOC(pUalgParam, |
| sizeof(MP4VE_GPP_SN_UALGOutputParams) + 256, |
| MP4VE_GPP_SN_UALGOutputParams, |
| pMemoryListHead, |
| pComponentPrivate->dbg); |
| pTemp = (char*)pUalgParam; |
| pTemp += 128; |
| pUalgParam = (MP4VE_GPP_SN_UALGOutputParams*)pTemp; |
| pCompPort->pBufferPrivate[nBufferCnt]->pUalgParam = pUalgParam; |
| } |
| } |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| /*---------------------------------------------------------------------------------------*/ |
| /** |
| * Callback() function will be called LCML component to write the msg |
| * |
| * @param msgBuffer This buffer will be returned by the LCML |
| * |
| * @retval OMX_NoError Success, ready to roll |
| * OMX_Error_BadParameter The input parameter pointer is null |
| **/ |
| /*---------------------------------------------------------------------------------------*/ |
| OMX_ERRORTYPE OMX_VIDENC_LCML_Callback(TUsnCodecEvent event,void* argsCb [10]) |
| { |
| int nRet = -1; |
| OMX_COMPONENTTYPE* pHandle = NULL; |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| OMX_BUFFERHEADERTYPE* pBufHead = NULL; |
| VIDENC_BUFFER_PRIVATE* pBufferPrivate = NULL; |
| LCML_DSP_INTERFACE* pLcmlDspInterface = NULL; |
| TUsnCodecEvent eEvent = (TUsnCodecEvent)event; |
| VIDENC_COMPONENT_PRIVATE* pComponentPrivate = NULL; |
| |
| OMX_CONF_CHECK_CMD(argsCb, 1, 1); |
| |
| if (argsCb[6]) |
| { |
| pLcmlDspInterface = (LCML_DSP_INTERFACE*)argsCb[6]; |
| pComponentPrivate = (VIDENC_COMPONENT_PRIVATE*)pLcmlDspInterface->pComponentPrivate; |
| pHandle = (OMX_COMPONENTTYPE *)pComponentPrivate->pHandle; |
| } |
| else |
| { |
| OMXDBG_PRINT(stderr, DSP, 5, 0, "No LCML handle\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorBadParameter); |
| } |
| |
| |
| if (eEvent == EMMCodecBufferProcessed) |
| { |
| if (((OMX_S32)argsCb[0]) == EMMCodecOuputBuffer) |
| { |
| pBufHead = (OMX_BUFFERHEADERTYPE*)argsCb[7]; |
| pBufferPrivate = (VIDENC_BUFFER_PRIVATE*)pBufHead->pOutputPortPrivate; |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_ReceivedFrame(pComponentPrivate->pPERFcomp, |
| PREF(pBufHead,pBuffer), |
| PREF(pBufHead,nFilledLen), |
| PERF_ModuleCommonLayer); |
| |
| pComponentPrivate->nLcml_nCntOpReceived++; |
| |
| if ((pComponentPrivate->nLcml_nCntIp >= 1) && |
| (pComponentPrivate->nLcml_nCntOpReceived == 1)) |
| { |
| PERF_Boundary(pComponentPrivate->pPERFcomp, |
| PERF_BoundaryStart | PERF_BoundarySteadyState); |
| } |
| #endif |
| OMX_PRDSP1(pComponentPrivate->dbg, " [OUT] -> %p\n", pBufHead); |
| if(pBufHead->nFilledLen > pBufHead->nAllocLen) { |
| LOGD("VE Warning!!! Output buffer overflow."); |
| } |
| pBufferPrivate->eBufferOwner = VIDENC_BUFFER_WITH_COMPONENT; |
| if (pComponentPrivate->bCodecStarted == OMX_TRUE) |
| { |
| OMX_PRDSP1(pComponentPrivate->dbg, "Enters OMX_VIDENC_Process_FilledOutBuf\n"); |
| eError = OMX_VIDENC_Process_FilledOutBuf(pComponentPrivate, pBufHead); |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorUndefined, |
| OMX_TI_ErrorCritical, |
| NULL); |
| OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate); |
| } |
| } |
| } |
| if ((int)argsCb [0] == EMMCodecInputBuffer) |
| { |
| pBufHead = (OMX_BUFFERHEADERTYPE*)argsCb[7]; |
| pBufferPrivate = (VIDENC_BUFFER_PRIVATE*)pBufHead->pInputPortPrivate; |
| |
| #ifdef __PERF_INSTRUMENTATION__ |
| PERF_ReceivedFrame(pComponentPrivate->pPERFcomp, |
| PREF(pBufHead,pBuffer), |
| 0, |
| PERF_ModuleCommonLayer); |
| #endif |
| |
| OMX_PRDSP1(pComponentPrivate->dbg, " [IN] -> %p\n", pBufHead); |
| pBufferPrivate->eBufferOwner = VIDENC_BUFFER_WITH_COMPONENT; |
| /*we should ignore the callback asociated to the VOL Header request*/ |
| if (pComponentPrivate->bCodecStarted == OMX_TRUE && pComponentPrivate->bWaitingVOLHeaderCallback == OMX_FALSE) |
| { |
| OMX_PRDSP1(pComponentPrivate->dbg, "Enters OMX_VIDENC_Process_FreeInBuf\n"); |
| eError = OMX_VIDENC_Process_FreeInBuf(pComponentPrivate, pBufHead); |
| if (eError != OMX_ErrorNone) |
| { |
| OMX_VIDENC_EVENT_HANDLER(pComponentPrivate, |
| OMX_EventError, |
| OMX_ErrorUndefined, |
| OMX_TI_ErrorCritical, |
| NULL); |
| OMX_VIDENC_BAIL_IF_ERROR(eError, pComponentPrivate); |
| } |
| OMX_PRDSP1(pComponentPrivate->dbg, "Exits OMX_VIDENC_Process_FreeInBuf\n"); |
| } |
| else if(pComponentPrivate->bWaitingVOLHeaderCallback == OMX_TRUE) |
| { |
| pComponentPrivate->bWaitingVOLHeaderCallback = OMX_FALSE; |
| } |
| } |
| } |
| |
| if(eEvent == EMMCodecProcessingPaused || |
| eEvent == EMMCodecProcessingStoped) |
| { |
| if (pComponentPrivate != NULL) |
| { |
| pComponentPrivate->bDSPStopAck = OMX_TRUE; |
| #ifndef UNDER_CE |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| pthread_cond_signal(&pComponentPrivate->stop_cond); |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| #endif |
| } |
| } |
| |
| if(eEvent == EMMCodecStrmCtrlAck) |
| { |
| if ((int)argsCb [0] == USN_ERR_NONE) |
| { |
| pComponentPrivate->bFlushComplete = OMX_TRUE; |
| #ifndef UNDER_CE |
| pthread_mutex_lock(&pComponentPrivate->videoe_mutex_app); |
| pthread_cond_signal(&pComponentPrivate->flush_cond); |
| pthread_mutex_unlock(&pComponentPrivate->videoe_mutex_app); |
| #endif |
| } |
| } |
| nRet = OMX_VIDENC_HandleLcmlEvent(pComponentPrivate, eEvent, argsCb); |
| if (nRet == -1) |
| { |
| OMX_ERROR4(pComponentPrivate->dbg, "LCML Event Handler failed.\n"); |
| OMX_CONF_SET_ERROR_BAIL(eError, OMX_ErrorUndefined); |
| } |
| |
| OMX_CONF_CMD_BAIL: |
| return eError; |
| } |
| |
| |
| #ifdef UNDER_CE |
| /* ================================================================================= */ |
| /** |
| * @fns Sleep replace for WIN CE |
| */ |
| /* ================================================================================ */ |
| int OMX_CreateEvent(OMX_Event *event){ |
| int ret = OMX_ErrorNone; |
| HANDLE createdEvent = NULL; |
| if (event == NULL) |
| { |
| ret = OMX_ErrorBadParameter; |
| goto EXIT; |
| } |
| event->event = CreateEvent(NULL, TRUE, FALSE, NULL); |
| if(event->event == NULL) |
| ret = (int)GetLastError(); |
| EXIT: |
| return ret; |
| } |
| |
| int OMX_SignalEvent(OMX_Event *event){ |
| int ret = OMX_ErrorNone; |
| if (event == NULL) |
| { |
| ret = OMX_ErrorBadParameter; |
| goto EXIT; |
| } |
| SetEvent(event->event); |
| ret = (int)GetLastError(); |
| EXIT: |
| return ret; |
| } |
| |
| int OMX_WaitForEvent(OMX_Event *event) { |
| int ret = OMX_ErrorNone; |
| if (event == NULL) |
| { |
| ret = OMX_ErrorBadParameter; |
| goto EXIT; |
| } |
| WaitForSingleObject(event->event, INFINITE); |
| ret = (int)GetLastError(); |
| EXIT: |
| return ret; |
| } |
| |
| int OMX_DestroyEvent(OMX_Event *event) { |
| int ret = OMX_ErrorNone; |
| if (event == NULL) |
| { |
| ret = OMX_ErrorBadParameter; |
| goto EXIT; |
| } |
| CloseHandle(event->event); |
| EXIT: |
| return ret; |
| } |
| #endif |
| |
| #ifdef RESOURCE_MANAGER_ENABLED |
| /*-----------------------------------------------------------------------------*/ |
| /** |
| * OMX_VIDENC_ResourceManagerCallBack() |
| * |
| * Called from Resource Manager() |
| * |
| * |
| * |
| **/ |
| /*-----------------------------------------------------------------------------*/ |
| void OMX_VIDENC_ResourceManagerCallBack(RMPROXY_COMMANDDATATYPE cbData) |
| { |
| OMX_COMMANDTYPE Cmd = OMX_CommandStateSet; |
| OMX_STATETYPE state = OMX_StateIdle; |
| OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *)cbData.hComponent; |
| VIDENC_COMPONENT_PRIVATE *pCompPrivate = NULL; |
| |
| pCompPrivate = (VIDENC_COMPONENT_PRIVATE*)pHandle->pComponentPrivate; |
| OMX_PRMGR2(pCompPrivate->dbg, "OMX_VIDENC_ResourceManagerCallBack\n"); |
| OMX_PRMGR2(pCompPrivate->dbg, "Arguments:\ncbData.RM_Error = %dcbData.RM_Cmd = %d\n", *(cbData.RM_Error), cbData.RM_Cmd); |
| if (*(cbData.RM_Error) == OMX_ErrorResourcesPreempted) |
| { |
| if (pCompPrivate->eState== OMX_StateExecuting || |
| pCompPrivate->eState == OMX_StatePause) |
| { |
| |
| pCompPrivate->sCbData.EventHandler ( |
| pHandle, pHandle->pApplicationPrivate, |
| OMX_EventError, |
| OMX_ErrorResourcesPreempted,OMX_TI_ErrorMinor, |
| "Componentn Preempted\n"); |
| |
| OMX_PRSTATE2(pCompPrivate->dbg, "Send command to Idle from RM CallBack\n"); |
| OMX_SendCommand(pHandle, Cmd, state, NULL); |
| pCompPrivate->bPreempted = 1; |
| |
| } |
| } |
| else if (*(cbData.RM_Error) == OMX_RmProxyCallback_ResourcesAcquired) |
| { |
| pCompPrivate->sCbData.EventHandler ( |
| pHandle, pHandle->pApplicationPrivate, |
| OMX_EventResourcesAcquired, 0,0, |
| NULL); |
| OMX_PRSTATE2(pCompPrivate->dbg, "Send command to Executing from RM CallBack\n"); |
| OMX_SendCommand(pHandle, Cmd, OMX_StateExecuting, NULL); |
| } |
| } |
| #endif |
| |
| void CalculateBufferSize(OMX_PARAM_PORTDEFINITIONTYPE* pCompPort, VIDENC_COMPONENT_PRIVATE* pCompPrivate) |
| { |
| |
| if(pCompPort->nPortIndex == VIDENC_INPUT_PORT) { |
| if (pCompPort->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) |
| { |
| pCompPort->nBufferSize = pCompPort->format.video.nFrameWidth * |
| pCompPort->format.video.nFrameHeight * 1.5; |
| } |
| else |
| { |
| pCompPort->nBufferSize = pCompPort->format.video.nFrameWidth * |
| pCompPort->format.video.nFrameHeight * 2; |
| } |
| } |
| else { |
| if (pCompPort->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) |
| { |
| pCompPort->nBufferSize = GetMaxAVCBufferSize(pCompPort->format.video.nFrameWidth, pCompPort->format.video.nFrameHeight); |
| } |
| else |
| {/*coding Mpeg4 or H263*/ |
| pCompPort->nBufferSize = pCompPort->format.video.nFrameWidth * |
| pCompPort->format.video.nFrameHeight / 2; |
| } |
| pCompPort->nBufferSize += 256; |
| } |
| } |
| |
| OMX_U32 GetMaxAVCBufferSize(OMX_U32 width, OMX_U32 height) |
| { |
| OMX_U32 MaxCPB; |
| OMX_U32 nMacroBlocks; |
| |
| /* Calculate output buffer size based on max possible CPB for the resolution |
| Output bitrate may not be set yet, so only resolution is taken into account */ |
| |
| nMacroBlocks = (width * height) / 256; |
| |
| /* Following values are set based on Annex A of AVC Standard */ |
| if(nMacroBlocks <= 99) { |
| MaxCPB = 500; |
| } |
| else if(nMacroBlocks <= 396) { |
| MaxCPB = 2000; |
| } |
| else if(nMacroBlocks <= 792) { |
| MaxCPB = 4000; |
| } |
| else if(nMacroBlocks <= 1620) { |
| /* Note - Max bitrate in this case is assumed to max 4 Mbps to limit the buffer size |
| If bitrate in this particular case could be higher than 4 Mbps, increase MxCPB value */ |
| MaxCPB = 4000; |
| } |
| else |
| MaxCPB = 14000; |
| |
| /* MaxCPB are in units of 1200 bits i.e. 150 bytes */ |
| /* Return buffer size in bytes*/ |
| /*Last patch to improve the performance*/ |
| /*return (150 * MaxCPB);*/ |
| return (width * height) / 2; |
| } |
| OMX_U32 OMX_VIDENC_GetDefaultBitRate(VIDENC_COMPONENT_PRIVATE* pComponentPrivate) |
| { |
| OMX_PARAM_PORTDEFINITIONTYPE* pPortDef; |
| OMX_U32 bitrate; |
| int nCount; |
| |
| pPortDef = pComponentPrivate->pCompPort[VIDENC_OUTPUT_PORT]->pPortDef; |
| for ( nCount = 0; nCount < VIDENC_MAXBITRATES; nCount++ ) { |
| if (pPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) { |
| bitrate = VIDENC_STRUCT_H264DEFBITRATE [nCount][1]; |
| if ((pPortDef->format.video.nFrameWidth * pPortDef->format.video.nFrameHeight) |
| <= VIDENC_STRUCT_H264DEFBITRATE[nCount][0]) { |
| break; |
| } |
| } |
| else if (pPortDef->format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) { |
| bitrate = VIDENC_STRUCT_MPEG4DEFBITRATE [nCount][1]; |
| if ((pPortDef->format.video.nFrameWidth * pPortDef->format.video.nFrameHeight) |
| <= VIDENC_STRUCT_MPEG4DEFBITRATE[nCount][0]) { |
| break; |
| } |
| } |
| else { |
| bitrate = VIDENC_STRUCT_H263DEFBITRATE [nCount][1]; |
| if ((pPortDef->format.video.nFrameWidth * pPortDef->format.video.nFrameHeight) |
| <= VIDENC_STRUCT_H263DEFBITRATE[nCount][0]) { |
| break; |
| } |
| } |
| } |
| |
| return bitrate; |
| } |
| |
| |
| void printMpeg4Params(MP4VE_GPP_SN_Obj_CreatePhase* pCreatePhaseArgs, |
| struct OMX_TI_Debug *dbg) |
| { |
| OMX_PRDSP2(*dbg, "\nusNumStreams = %d\n", pCreatePhaseArgs->usNumStreams); |
| OMX_PRDSP2(*dbg, "usStreamId = %d\n", pCreatePhaseArgs->usStreamId); |
| OMX_PRDSP2(*dbg, "usBuffTypeInStream = %d\n", pCreatePhaseArgs->usBuffTypeInStream); |
| OMX_PRDSP2(*dbg, "usMaxBuffsInStream = %d\n", pCreatePhaseArgs->usMaxBuffsInStream); |
| OMX_PRDSP2(*dbg, "usStreamId2 = %d\n", pCreatePhaseArgs->usStreamId2); |
| OMX_PRDSP2(*dbg, "usBuffTypeInStream2 = %d\n", pCreatePhaseArgs->usBuffTypeInStream2); |
| OMX_PRDSP2(*dbg, "usMaxBuffsInStream2 = %d\n", pCreatePhaseArgs->usMaxBuffsInStream2); |
| |
| OMX_PRDSP2(*dbg, "ulWidth = %d\n", pCreatePhaseArgs->ulWidth); |
| OMX_PRDSP2(*dbg, "ulHeight = %d\n", pCreatePhaseArgs->ulHeight); |
| OMX_PRDSP2(*dbg, "ulTargetBitRate = %d\n", pCreatePhaseArgs->ulTargetBitRate); |
| OMX_PRDSP2(*dbg, "ulVBVSize = %d\n", pCreatePhaseArgs->ulVBVSize); |
| OMX_PRDSP2(*dbg, "ulGOBHeadersInterval = %d\n", pCreatePhaseArgs->ulGOBHeadersInterval); |
| |
| OMX_PRDSP2(*dbg, "ucIsMPEG4 = %d\n", pCreatePhaseArgs->ucIsMPEG4); |
| OMX_PRDSP2(*dbg, "ucYUVFormat = %d\n", pCreatePhaseArgs->ucYUVFormat); |
| OMX_PRDSP2(*dbg, "ucHEC = %d\n", pCreatePhaseArgs->ucHEC); |
| OMX_PRDSP2(*dbg, "ucResyncMarker = %d\n", pCreatePhaseArgs->ucResyncMarker); |
| OMX_PRDSP2(*dbg, "ucDataPartitioning = %d\n", pCreatePhaseArgs->ucDataPartitioning); |
| OMX_PRDSP2(*dbg, "ucReversibleVLC = %d\n", pCreatePhaseArgs->ucReversibleVLC); |
| OMX_PRDSP2(*dbg, "ucUnrestrictedMV = %d\n", pCreatePhaseArgs->ucUnrestrictedMV); |
| OMX_PRDSP2(*dbg, "ucFrameRate = %d\n", pCreatePhaseArgs->ucFrameRate); |
| OMX_PRDSP2(*dbg, "ucRateControlAlgorithm = %d\n", pCreatePhaseArgs->ucRateControlAlgorithm); |
| OMX_PRDSP2(*dbg, "ucQPFirstIFrame = %d\n", pCreatePhaseArgs->ucQPFirstIFrame); |
| OMX_PRDSP2(*dbg, "ucProfile = %d\n", pCreatePhaseArgs->ucProfile); |
| OMX_PRDSP2(*dbg, "ucLevel = %d\n", pCreatePhaseArgs->ucLevel); |
| OMX_PRDSP2(*dbg, "ulMaxDelay = %d\n", pCreatePhaseArgs->ulMaxDelay); |
| /* |
| OMX_PRDSP2(*dbg, "ulVbvParamEnable = %d\n", pCreatePhaseArgs->ulVbvParamEnable); |
| OMX_PRDSP2(*dbg, "ulH263SliceMode = %d\n", pCreatePhaseArgs->ulH263SliceMode); |
| */ |
| OMX_PRDSP2(*dbg, "ulUseGOV = %d\n", pCreatePhaseArgs->ulUseGOV); |
| OMX_PRDSP2(*dbg, "ulUseVOS = %d\n", pCreatePhaseArgs->ulUseVOS); |
| OMX_PRDSP2(*dbg, "enableH263AnnexI = %d\n", pCreatePhaseArgs->enableH263AnnexI); |
| OMX_PRDSP2(*dbg, "enableH263AnnexJ = %d\n", pCreatePhaseArgs->enableH263AnnexJ); |
| OMX_PRDSP2(*dbg, "enableH263AnnexT = %d\n", pCreatePhaseArgs->enableH263AnnexT); |
| } |
| void printH264CreateParams(H264VE_GPP_SN_Obj_CreatePhase* pCreatePhaseArgs, struct OMX_TI_Debug *dbg) |
| { |
| OMX_PRDSP2(*dbg, "\nusNumStreams = %d\n", pCreatePhaseArgs->usNumStreams); |
| OMX_PRDSP2(*dbg, "usStreamId = %d\n", pCreatePhaseArgs->usStreamId); |
| OMX_PRDSP2(*dbg, "usBuffTypeInStream = %d\n", pCreatePhaseArgs->usBuffTypeInStream); |
| OMX_PRDSP2(*dbg, "usMaxBuffsInStream = %d\n", pCreatePhaseArgs->usMaxBuffsInStream); |
| OMX_PRDSP2(*dbg, "usStreamId2 = %d\n", pCreatePhaseArgs->usStreamId2); |
| OMX_PRDSP2(*dbg, "usBuffTypeInStream2 = %d\n", pCreatePhaseArgs->usBuffTypeInStream2); |
| OMX_PRDSP2(*dbg, "usMaxBuffsInStream2 = %d\n", pCreatePhaseArgs->usMaxBuffsInStream2); |
| |
| OMX_PRDSP2(*dbg, "ulWidth = %d\n", pCreatePhaseArgs->ulWidth); |
| OMX_PRDSP2(*dbg, "ulHeight = %d\n", pCreatePhaseArgs->ulHeight); |
| OMX_PRDSP2(*dbg, "ulTargetBitRate = %d\n", pCreatePhaseArgs->ulTargetBitRate); |
| OMX_PRDSP2(*dbg, "ulBitstreamBuffSize = %d\n", pCreatePhaseArgs->ulBitstreamBuffSize); |
| OMX_PRDSP2(*dbg, "ulIntraFramePeriod = %d\n", pCreatePhaseArgs->ulIntraFramePeriod); |
| OMX_PRDSP2(*dbg, "ulFrameRate = %d\n", pCreatePhaseArgs->ulFrameRate); |
| |
| OMX_PRDSP2(*dbg, "ucYUVFormat = %d\n", pCreatePhaseArgs->ucYUVFormat); |
| OMX_PRDSP2(*dbg, "ucUnrestrictedMV = %d\n", pCreatePhaseArgs->ucUnrestrictedMV); |
| OMX_PRDSP2(*dbg, "ucNumRefFrames = %d\n", pCreatePhaseArgs->ucNumRefFrames); |
| OMX_PRDSP2(*dbg, "ucRateControlAlgorithm = %d\n", pCreatePhaseArgs->ucRateControlAlgorithm); |
| OMX_PRDSP2(*dbg, "ucIDREnable = %d\n", pCreatePhaseArgs->ucIDREnable); |
| OMX_PRDSP2(*dbg, "ucDeblockingEnable = %d\n", pCreatePhaseArgs->ucDeblockingEnable); |
| OMX_PRDSP2(*dbg, "ucMVRange = %d\n", pCreatePhaseArgs->ucMVRange); |
| OMX_PRDSP2(*dbg, "ucQPIFrame = %d\n", pCreatePhaseArgs->ucQPIFrame); |
| OMX_PRDSP2(*dbg, "ucProfile = %d\n", pCreatePhaseArgs->ucProfile); |
| OMX_PRDSP2(*dbg, "ucLevel = %d\n", pCreatePhaseArgs->ucLevel); |
| |
| OMX_PRDSP2(*dbg, "usNalCallback = %d\n", pCreatePhaseArgs->usNalCallback); |
| OMX_PRDSP2(*dbg, "ulEncodingPreset = %d\n", pCreatePhaseArgs->ulEncodingPreset); |
| OMX_PRDSP2(*dbg, "ulRcAlgo = %d\n", pCreatePhaseArgs->ulRcAlgo); |
| } |
| |
| void printMpeg4UAlgInParam(MP4VE_GPP_SN_UALGInputParams* pUalgInpParams, int printAlways, struct OMX_TI_Debug *dbg) |
| { |
| static int printed=0; |
| |
| if(printAlways || !printed) |
| { |
| printed++; |
| OMX_PRDSP2(*dbg, "\nulFrameIndex = %u\n", pUalgInpParams->ulFrameIndex); |
| OMX_PRDSP2(*dbg, "ulTargetFrameRate = %u\n", pUalgInpParams->ulTargetFrameRate); |
| OMX_PRDSP2(*dbg, "ulTargetBitRate = %u\n", pUalgInpParams->ulTargetBitRate); |
| OMX_PRDSP2(*dbg, "ulIntraFrameInterval = %u\n", pUalgInpParams->ulIntraFrameInterval); |
| OMX_PRDSP2(*dbg, "ulGenerateHeader = %u\n", pUalgInpParams->ulGenerateHeader); |
| OMX_PRDSP2(*dbg, "ulForceIFrame = %u\n", pUalgInpParams->ulForceIFrame); |
| OMX_PRDSP2(*dbg, "ulResyncInterval = %u\n", pUalgInpParams->ulResyncInterval); |
| OMX_PRDSP2(*dbg, "ulHecInterval = %u\n", pUalgInpParams->ulHecInterval); |
| OMX_PRDSP2(*dbg, "ulAIRRate = %u\n", pUalgInpParams->ulAIRRate); |
| OMX_PRDSP2(*dbg, "ulMIRRate = %u\n", pUalgInpParams->ulMIRRate); |
| OMX_PRDSP2(*dbg, "ulQPIntra = %u\n", pUalgInpParams->ulQPIntra); |
| OMX_PRDSP2(*dbg, "ulfCode = %u\n", pUalgInpParams->ulfCode); |
| OMX_PRDSP2(*dbg, "ulHalfPel = %u\n", pUalgInpParams->ulHalfPel); |
| OMX_PRDSP2(*dbg, "ulACPred = %u\n", pUalgInpParams->ulACPred); |
| OMX_PRDSP2(*dbg, "ul4MV = %u\n", pUalgInpParams->ul4MV); |
| OMX_PRDSP2(*dbg, "uluseUMV = %u\n", pUalgInpParams->uluseUMV); |
| OMX_PRDSP2(*dbg, "ulMVDataEnable = %u\n", pUalgInpParams->ulMVDataEnable); |
| OMX_PRDSP2(*dbg, "ulResyncDataEnable = %u\n", pUalgInpParams->ulResyncDataEnable); |
| OMX_PRDSP2(*dbg, "ulQPInter = %u\n", pUalgInpParams->ulQPInter); |
| OMX_PRDSP2(*dbg, "ulLastFrame = %u\n", pUalgInpParams->ulLastFrame); |
| OMX_PRDSP2(*dbg, "ulcapturewidth = %u\n", pUalgInpParams->ulcapturewidth); |
| OMX_PRDSP2(*dbg, "ulQpMax = %u\n", pUalgInpParams->ulQpMax); |
| OMX_PRDSP2(*dbg, "ulQpMin = %u\n", pUalgInpParams->ulQpMin); |
| } |
| } |
| |
| |
| void printH264UAlgInParam(H264VE_GPP_SN_UALGInputParams* pUalgInpParams, int printAlways, struct OMX_TI_Debug *dbg) |
| { |
| static int printed=0; |
| |
| if(printAlways || !printed) |
| { |
| printed++; |
| OMX_PRDSP2(*dbg, "\nqpIntra = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.qpIntra); |
| OMX_PRDSP2(*dbg, "qpInter = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.qpInter); |
| OMX_PRDSP2(*dbg, "qpMax = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.qpMax); |
| OMX_PRDSP2(*dbg, "qpMin = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.qpMin); |
| OMX_PRDSP2(*dbg, "lfDisableIdc = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.lfDisableIdc); |
| OMX_PRDSP2(*dbg, "quartPelDisable = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.quartPelDisable); |
| OMX_PRDSP2(*dbg, "airMbPeriod = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.airMbPeriod); |
| OMX_PRDSP2(*dbg, "maxMBsPerSlice = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.maxMBsPerSlice); |
| OMX_PRDSP2(*dbg, "maxBytesPerSlice = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.maxBytesPerSlice); |
| OMX_PRDSP2(*dbg, "sliceRefreshRowStartNumber = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.sliceRefreshRowStartNumber); |
| OMX_PRDSP2(*dbg, "sliceRefreshRowNumber = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.sliceRefreshRowNumber); |
| OMX_PRDSP2(*dbg, "filterOffsetA = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.filterOffsetA); |
| OMX_PRDSP2(*dbg, "filterOffsetB = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.filterOffsetB); |
| OMX_PRDSP2(*dbg, "log2MaxFNumMinus4 = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.log2MaxFNumMinus4); |
| OMX_PRDSP2(*dbg, "chromaQPIndexOffset = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.chromaQPIndexOffset); |
| OMX_PRDSP2(*dbg, "constrainedIntraPredEnable = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.constrainedIntraPredEnable); |
| OMX_PRDSP2(*dbg, "picOrderCountType = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.picOrderCountType); |
| OMX_PRDSP2(*dbg, "maxMVperMB = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.maxMVperMB); |
| OMX_PRDSP2(*dbg, "intra4x4EnableIdc = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.intra4x4EnableIdc); |
| OMX_PRDSP2(*dbg, "mvDataEnable = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.mvDataEnable); |
| OMX_PRDSP2(*dbg, "hierCodingEnable = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.hierCodingEnable); |
| OMX_PRDSP2(*dbg, "streamFormat = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.streamFormat); |
| OMX_PRDSP2(*dbg, "intraRefreshMethod = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.intraRefreshMethod); |
| OMX_PRDSP2(*dbg, "perceptualQuant = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.perceptualQuant); |
| OMX_PRDSP2(*dbg, "sceneChangeDet = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.sceneChangeDet); |
| OMX_PRDSP2(*dbg, "numSliceASO = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.numSliceASO); |
| OMX_PRDSP2(*dbg, "numSliceGroups = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.numSliceGroups); |
| OMX_PRDSP2(*dbg, "sliceGroupMapType = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.sliceGroupMapType); |
| OMX_PRDSP2(*dbg, "sliceGroupChangeDirectionFlag = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.sliceGroupChangeDirectionFlag); |
| OMX_PRDSP2(*dbg, "sliceGroupChangeRate = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.sliceGroupChangeRate); |
| OMX_PRDSP2(*dbg, "sliceGroupChangeCycle = %lu\n", pUalgInpParams->H264VENC_TI_DYNAMICPARAMS.sliceGroupChangeCycle); |
| OMX_PRDSP2(*dbg, "ulFrameIndex = %lu\n", pUalgInpParams->ulFrameIndex); |
| } |
| } |
| |
| OMX_ERRORTYPE IsResolutionPlayable (OMX_U32 width, OMX_U32 height) |
| { |
| if (width > WVGA_MAX_WIDTH || height > WVGA_MAX_HEIGHT) |
| { |
| return OMX_ErrorBadParameter; |
| } |
| return OMX_ErrorNone; |
| |
| } |
| |
| OMX_ERRORTYPE AddStateTransition(VIDENC_COMPONENT_PRIVATE* pComponentPrivate) { |
| |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| |
| if(pthread_mutex_lock(&pComponentPrivate->mutexStateChangeRequest)) { |
| return OMX_ErrorUndefined; |
| } |
| |
| /* Increment state change request reference count */ |
| pComponentPrivate->nPendingStateChangeRequests++; |
| |
| if(pthread_mutex_unlock(&pComponentPrivate->mutexStateChangeRequest)) { |
| return OMX_ErrorUndefined; |
| } |
| |
| return eError; |
| } |
| |
| OMX_ERRORTYPE RemoveStateTransition(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BOOL bEnableSignal) { |
| OMX_ERRORTYPE eError = OMX_ErrorNone; |
| |
| /* Decrement state change request reference count*/ |
| if(pthread_mutex_lock(&pComponentPrivate->mutexStateChangeRequest)) { |
| return OMX_ErrorUndefined; |
| } |
| |
| pComponentPrivate->nPendingStateChangeRequests--; |
| |
| /* If there are no more pending requests, signal the thread waiting on this*/ |
| if(!pComponentPrivate->nPendingStateChangeRequests && bEnableSignal) { |
| pthread_cond_signal(&(pComponentPrivate->StateChangeCondition)); |
| } |
| |
| if(pthread_mutex_unlock(&pComponentPrivate->mutexStateChangeRequest)) { |
| return OMX_ErrorUndefined; |
| } |
| |
| return eError; |
| } |