diff options
Diffstat (limited to 'mm-video-v4l2/vidc/venc/src/omx_video_base.cpp')
-rw-r--r--[-rwxr-xr-x] | mm-video-v4l2/vidc/venc/src/omx_video_base.cpp | 314 |
1 files changed, 238 insertions, 76 deletions
diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp index 0cf76d9..52a9313 100755..100644 --- a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp +++ b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp @@ -1,5 +1,5 @@ /*-------------------------------------------------------------------------- -Copyright (c) 2010-2014, Linux Foundation. All rights reserved. +Copyright (c) 2010-2016, Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -38,6 +38,8 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Include Files ////////////////////////////////////////////////////////////////////////////// +#define __STDC_FORMAT_MACROS //enables the format specifiers in inttypes.h +#include <inttypes.h> #include <string.h> #include "omx_video_base.h" #include <stdlib.h> @@ -78,10 +80,11 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define SZ_4K 0x1000 #define SZ_1M 0x100000 -#define SECURE_BUFPTR 0xDEADBEEF typedef struct OMXComponentCapabilityFlagsType { ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; OMX_BOOL iIsOMXComponentMultiThreaded; OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc; OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc; @@ -210,11 +213,12 @@ VideoHeap::VideoHeap(int fd, size_t size, void* base) ========================================================================== */ omx_video::omx_video(): c2d_opened(false), - mUsesColorConversion(false), psource_frame(NULL), pdest_frame(NULL), secure_session(false), mEmptyEosBuffer(NULL), + m_pipe_in(-1), + m_pipe_out(-1), m_pInput_pmem(NULL), m_pOutput_pmem(NULL), #ifdef USE_ION @@ -240,7 +244,8 @@ omx_video::omx_video(): m_flags(0), m_etb_count(0), m_fbd_count(0), - m_event_port_settings_sent(false) + m_event_port_settings_sent(false), + hw_overload(false) { DEBUG_PRINT_HIGH("omx_video(): Inside Constructor()"); memset(&m_cmp,0,sizeof(m_cmp)); @@ -248,8 +253,10 @@ omx_video::omx_video(): async_thread_created = false; msg_thread_created = false; + mUsesColorConversion = false; pthread_mutex_init(&m_lock, NULL); sem_init(&m_cmd_lock,0,0); + DEBUG_PRINT_LOW("meta_buffer_hdr = %p", meta_buffer_hdr); } @@ -269,8 +276,8 @@ omx_video::omx_video(): omx_video::~omx_video() { DEBUG_PRINT_HIGH("~omx_video(): Inside Destructor()"); - if (m_pipe_in) close(m_pipe_in); - if (m_pipe_out) close(m_pipe_out); + if (m_pipe_in >= 0) close(m_pipe_in); + if (m_pipe_out >= 0) close(m_pipe_out); DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit"); if (msg_thread_created) pthread_join(msg_thread_id,NULL); @@ -283,10 +290,10 @@ omx_video::~omx_video() #endif pthread_mutex_destroy(&m_lock); sem_destroy(&m_cmd_lock); - DEBUG_PRINT_HIGH("m_etb_count = %u, m_fbd_count = %u", m_etb_count, + DEBUG_PRINT_HIGH("m_etb_count = %" PRIu64 ", m_fbd_count = %" PRIu64, m_etb_count, m_fbd_count); DEBUG_PRINT_HIGH("omx_video: Destructor exit"); - DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ..."); + DEBUG_PRINT_HIGH("Exiting OMX Video Encoder ..."); } /* ====================================================================== @@ -405,13 +412,18 @@ void omx_video::process_event_cb(void *ctxt, unsigned char id) pThis->omx_report_error (); } break; - case OMX_COMPONENT_GENERATE_ETB: + case OMX_COMPONENT_GENERATE_ETB: { + OMX_ERRORTYPE iret; DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB"); - if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("ERROR: ETBProxy() failed!"); + iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2); + if (iret == OMX_ErrorInsufficientResources) { + DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload"); + pThis->omx_report_hw_overload (); + } else if (iret != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure"); pThis->omx_report_error (); } + } break; case OMX_COMPONENT_GENERATE_FTB: @@ -446,7 +458,7 @@ void omx_video::process_event_cb(void *ctxt, unsigned char id) case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: pThis->input_flush_progress = false; - DEBUG_PRINT_HIGH("m_etb_count at i/p flush = %u", m_etb_count); + DEBUG_PRINT_HIGH("m_etb_count at i/p flush = %" PRIu64, m_etb_count); m_etb_count = 0; if (pThis->m_pCallbacks.EventHandler) { /*Check if we need generate event for Flush done*/ @@ -473,7 +485,7 @@ void omx_video::process_event_cb(void *ctxt, unsigned char id) case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: pThis->output_flush_progress = false; - DEBUG_PRINT_HIGH("m_fbd_count at o/p flush = %u", m_fbd_count); + DEBUG_PRINT_HIGH("m_fbd_count at o/p flush = %" PRIu64, m_fbd_count); m_fbd_count = 0; if (pThis->m_pCallbacks.EventHandler) { /*Check if we need generate event for Flush done*/ @@ -526,7 +538,7 @@ void omx_video::process_event_cb(void *ctxt, unsigned char id) } BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING); } else { - DEBUG_PRINT_LOW("ERROR: unknown flags=%x",pThis->m_flags); + DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags); } } else { DEBUG_PRINT_LOW("Event Handler callback is NULL"); @@ -586,7 +598,7 @@ void omx_video::process_event_cb(void *ctxt, unsigned char id) } BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING); } else { - DEBUG_PRINT_LOW("ERROR: unknown flags=%x",pThis->m_flags); + DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags); } } @@ -1432,6 +1444,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, switch ((int)paramIndex) { case OMX_IndexParamPortDefinition: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE); OMX_PARAM_PORTDEFINITIONTYPE *portDefn; portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; @@ -1455,10 +1468,12 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } #endif } else if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { + if (m_state != OMX_StateExecuting) { dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, &m_sOutPortDef.nBufferCountActual, &m_sOutPortDef.nBufferSize, m_sOutPortDef.nPortIndex); + } DEBUG_PRINT_LOW("m_sOutPortDef: size = %u, min cnt = %u, actual cnt = %u", (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)m_sOutPortDef.nBufferCountMin, (unsigned int)m_sOutPortDef.nBufferCountActual); @@ -1471,6 +1486,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_IndexParamVideoInit: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); OMX_PORT_PARAM_TYPE *portParamType = (OMX_PORT_PARAM_TYPE *) paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit"); @@ -1480,6 +1496,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_IndexParamVideoPortFormat: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE); OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat"); @@ -1497,7 +1514,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, [2] = OMX_COLOR_FormatYUV420SemiPlanar, }; - if (index >= sizeof(supportedFormats)/sizeof(*supportedFormats)) + if (index > (sizeof(supportedFormats)/sizeof(*supportedFormats) - 1)) eRet = OMX_ErrorNoMore; else { memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat)); @@ -1514,6 +1531,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_IndexParamVideoBitrate: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_BITRATETYPE); OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate"); @@ -1528,6 +1546,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_IndexParamVideoMpeg4: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_MPEG4TYPE); OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4"); memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4)); @@ -1535,6 +1554,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_IndexParamVideoH263: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_H263TYPE); OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263"); memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263)); @@ -1542,6 +1562,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_IndexParamVideoAvc: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_AVCTYPE); OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc"); memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC)); @@ -1549,13 +1570,23 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_VP8TYPE); OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoVp8"); memcpy(pParam, &m_sParamVP8, sizeof(m_sParamVP8)); break; } + case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc: + { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_HEVCTYPE); + OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoHevc"); + memcpy(pParam, &m_sParamHEVC, sizeof(m_sParamHEVC)); + break; + } case OMX_IndexParamVideoProfileLevelQuerySupported: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported"); eRet = get_supported_profile_level(pParam); @@ -1566,6 +1597,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_IndexParamVideoProfileLevelCurrent: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE); OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent"); memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel)); @@ -1574,6 +1606,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, /*Component should support this port definition*/ case OMX_IndexParamAudioInit: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit"); memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio)); @@ -1582,6 +1615,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, /*Component should support this port definition*/ case OMX_IndexParamImageInit: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE); OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit"); memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img)); @@ -1597,24 +1631,20 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_IndexParamStandardComponentRole: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE); OMX_PARAM_COMPONENTROLETYPE *comp_role; comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; comp_role->nVersion.nVersion = OMX_SPEC_VERSION; comp_role->nSize = sizeof(*comp_role); DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",paramIndex); - if (NULL != comp_role->cRole) { - strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE); - } else { - DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role",paramIndex); - eRet =OMX_ErrorBadParameter; - } + strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE); break; } /* Added for parameter test */ case OMX_IndexParamPriorityMgmt: { - + VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE); OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt"); memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt)); @@ -1623,6 +1653,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, /* Added for parameter test */ case OMX_IndexParamCompBufferSupplier: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE); OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier"); if (bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN) { @@ -1638,6 +1669,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, case OMX_IndexParamVideoQuantization: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_QUANTIZATIONTYPE); OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization"); memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization)); @@ -1646,6 +1678,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, case OMX_QcomIndexParamVideoQPRange: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_QPRANGETYPE); OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData; DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoQPRange"); memcpy(qp_range, &m_sSessionQPRange, sizeof(m_sSessionQPRange)); @@ -1654,6 +1687,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, case OMX_IndexParamVideoErrorCorrection: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE); OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection"); errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC; @@ -1663,6 +1697,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_IndexParamVideoIntraRefresh: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_INTRAREFRESHTYPE); OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh"); DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET"); @@ -1675,6 +1710,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, break; case OMX_COMPONENT_CAPABILITY_TYPE_INDEX: { + VALIDATE_OMX_PARAM_DATA(paramData, OMXComponentCapabilityFlagsType); OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData); DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX"); pParam->iIsOMXComponentMultiThreaded = OMX_TRUE; @@ -1692,6 +1728,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, #if !defined(MAX_RES_720P) || defined(_MSM8974_) case OMX_QcomIndexParamIndexExtraDataType: { + VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE); DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType"); QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) { @@ -1737,6 +1774,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case QOMX_IndexParamVideoLTRCountRangeSupported: { + VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_RANGETYPE); DEBUG_PRINT_HIGH("get_parameter: QOMX_IndexParamVideoLTRCountRangeSupported"); QOMX_EXTNINDEX_RANGETYPE *pParam = (QOMX_EXTNINDEX_RANGETYPE *)paramData; if (pParam->nPortIndex == PORT_INDEX_OUT) { @@ -1755,9 +1793,19 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } } break; + case OMX_QcomIndexParamVideoLTRCount: + { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE); + DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoLTRCount"); + OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE *pParam = + reinterpret_cast<OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*>(paramData); + memcpy(pParam, &m_sParamLTRCount, sizeof(m_sParamLTRCount)); + break; + } #endif case QOMX_IndexParamVideoSyntaxHdr: { + VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_PARAMTYPE); DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr"); QOMX_EXTNINDEX_PARAMTYPE* pParam = reinterpret_cast<QOMX_EXTNINDEX_PARAMTYPE*>(paramData); @@ -1781,7 +1829,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } if (dev_get_seq_hdr(pParam->pData, (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)), - (OMX_U32 *)(void *)&pParam->nDataSize)) { + (unsigned *)(void *)&pParam->nDataSize)) { DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %u)", (unsigned int)pParam->nDataSize); for (unsigned i = 0; i < pParam->nDataSize; i++) { @@ -1803,6 +1851,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_QcomIndexHierarchicalStructure: { + VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_HIERARCHICALLAYERS); QOMX_VIDEO_HIERARCHICALLAYERS* hierp = (QOMX_VIDEO_HIERARCHICALLAYERS*) paramData; DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexHierarchicalStructure"); memcpy(hierp, &m_sHierLayers, sizeof(m_sHierLayers)); @@ -1810,6 +1859,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_QcomIndexParamPerfLevel: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PERF_LEVEL); OMX_U32 perflevel; OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam = reinterpret_cast<OMX_QCOM_VIDEO_PARAM_PERF_LEVEL*>(paramData); @@ -1824,6 +1874,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_QcomIndexParamH264VUITimingInfo: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO); OMX_U32 enabled; OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam = reinterpret_cast<OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO*>(paramData); @@ -1838,6 +1889,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case OMX_QcomIndexParamPeakBitrate: { + VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE); OMX_U32 peakbitrate; OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam = reinterpret_cast<OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE*>(paramData); @@ -1852,6 +1904,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, } case QOMX_IndexParamVideoInitialQp: { + VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_INITIALQP); QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp = reinterpret_cast<QOMX_EXTNINDEX_VIDEO_INITIALQP *>(paramData); memcpy(initqp, &m_sParamInitqp, sizeof(m_sParamInitqp)); @@ -1911,18 +1964,21 @@ OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, switch ((int)configIndex) { case OMX_IndexConfigVideoBitrate: { + VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_BITRATETYPE); OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData); memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate)); break; } case OMX_IndexConfigVideoFramerate: { + VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_FRAMERATETYPE); OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData); memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate)); break; } case OMX_IndexConfigCommonRotate: { + VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ROTATIONTYPE); OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData); memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation)); break; @@ -1930,12 +1986,14 @@ OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, case QOMX_IndexConfigVideoIntraperiod: { DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod"); + VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_INTRAPERIODTYPE); QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData); memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod)); break; } case OMX_IndexConfigVideoAVCIntraPeriod: { + VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_AVCINTRAPERIOD); OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam = reinterpret_cast<OMX_VIDEO_CONFIG_AVCINTRAPERIOD*>(configData); DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoAVCIntraPeriod"); @@ -1944,6 +2002,7 @@ OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, } case OMX_IndexConfigCommonDeinterlace: { + VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_DEINTERLACE); OMX_VIDEO_CONFIG_DEINTERLACE *pParam = reinterpret_cast<OMX_VIDEO_CONFIG_DEINTERLACE*>(configData); DEBUG_PRINT_LOW("get_config: OMX_IndexConfigCommonDeinterlace"); @@ -1952,12 +2011,28 @@ OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, } case OMX_IndexConfigVideoVp8ReferenceFrame: { + VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_VP8REFERENCEFRAMETYPE); OMX_VIDEO_VP8REFERENCEFRAMETYPE* pParam = reinterpret_cast<OMX_VIDEO_VP8REFERENCEFRAMETYPE*>(configData); DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoVp8ReferenceFrame"); memcpy(pParam, &m_sConfigVp8ReferenceFrame, sizeof(m_sConfigVp8ReferenceFrame)); break; } + case OMX_QcomIndexConfigPerfLevel: + { + VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL); + OMX_U32 perflevel; + OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *pParam = + reinterpret_cast<OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL*>(configData); + DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigPerfLevel"); + if (!dev_get_performance_level(&perflevel)) { + DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d", + pParam->ePerfLevel); + } else { + pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel; + } + break; + } default: DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); return OMX_ErrorUnsupportedIndex; @@ -2101,6 +2176,7 @@ OMX_ERRORTYPE omx_video::use_input_buffer( DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr"); return OMX_ErrorInsufficientResources; } + DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr); m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); @@ -2175,7 +2251,7 @@ OMX_ERRORTYPE omx_video::use_input_buffer( m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; m_pInput_pmem[i].offset = 0; - m_pInput_pmem[i].buffer = (OMX_U8 *)SECURE_BUFPTR; + m_pInput_pmem[i].buffer = NULL; if(!secure_session) { m_pInput_pmem[i].buffer = (unsigned char *)mmap( NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, @@ -2183,6 +2259,7 @@ OMX_ERRORTYPE omx_video::use_input_buffer( if (m_pInput_pmem[i].buffer == MAP_FAILED) { DEBUG_PRINT_ERROR("ERROR: mmap() Failed"); + m_pInput_pmem[i].buffer = NULL; close(m_pInput_pmem[i].fd); #ifdef USE_ION free_ion_memory(&m_pInput_ion[i]); @@ -2332,7 +2409,6 @@ OMX_ERRORTYPE omx_video::use_output_buffer( *bufferHdr = (m_out_mem_ptr + i ); (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; (*bufferHdr)->pAppPrivate = appData; - BITMASK_SET(&m_out_bm_count,i); if (!m_use_output_pmem) { #ifdef USE_ION @@ -2367,7 +2443,7 @@ OMX_ERRORTYPE omx_video::use_output_buffer( m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; m_pOutput_pmem[i].offset = 0; - m_pOutput_pmem[i].buffer = (OMX_U8 *)SECURE_BUFPTR; + m_pOutput_pmem[i].buffer = NULL; if(!secure_session) { #ifdef _MSM8974_ m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL, @@ -2380,6 +2456,7 @@ OMX_ERRORTYPE omx_video::use_output_buffer( #endif if (m_pOutput_pmem[i].buffer == MAP_FAILED) { DEBUG_PRINT_ERROR("ERROR: mmap() Failed"); + m_pOutput_pmem[i].buffer = NULL; close(m_pOutput_pmem[i].fd); #ifdef USE_ION free_ion_memory(&m_pOutput_ion[i]); @@ -2410,6 +2487,8 @@ OMX_ERRORTYPE omx_video::use_output_buffer( DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf"); return OMX_ErrorInsufficientResources; } + + BITMASK_SET(&m_out_bm_count,i); } else { DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for " "index = %u", i); @@ -2497,7 +2576,7 @@ OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) return OMX_ErrorBadParameter; } - index = bufferHdr - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); + index = bufferHdr - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr); #ifdef _ANDROID_ICS_ if (meta_mode_enable) { if (index < m_sInPortDef.nBufferCountActual) { @@ -2518,6 +2597,8 @@ OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) } if (index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) { + auto_lock l(m_lock); + if (m_pInput_pmem[index].fd > 0 && input_use_buffer == false) { DEBUG_PRINT_LOW("FreeBuffer:: i/p AllocateBuffer case"); if(!secure_session) { @@ -2525,6 +2606,7 @@ OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) } else { free(m_pInput_pmem[index].buffer); } + m_pInput_pmem[index].buffer = NULL; close (m_pInput_pmem[index].fd); #ifdef USE_ION free_ion_memory(&m_pInput_ion[index]); @@ -2537,7 +2619,8 @@ OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) DEBUG_PRINT_ERROR("ERROR: dev_free_buf() Failed for i/p buf"); } if(!secure_session) { - munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); + munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); + m_pInput_pmem[index].buffer = NULL; } close (m_pInput_pmem[index].fd); #ifdef USE_ION @@ -2576,7 +2659,8 @@ OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) m_pOutput_pmem[index].size); } else { char *data = (char*) m_pOutput_pmem[index].buffer; - native_handle_t *handle = (native_handle_t*) data + 4; + native_handle_t *handle = NULL; + memcpy(&handle, data + sizeof(OMX_U32), sizeof(native_handle_t*)); native_handle_delete(handle); free(m_pOutput_pmem[index].buffer); } @@ -2620,8 +2704,11 @@ OMX_ERRORTYPE omx_video::allocate_input_meta_buffer( return OMX_ErrorBadParameter; } - if (!m_inp_mem_ptr && !mUseProxyColorFormat) + if (!m_inp_mem_ptr && !mUseProxyColorFormat) { m_inp_mem_ptr = meta_buffer_hdr; + DEBUG_PRINT_LOW("use meta_buffer_hdr (%p) as m_inp_mem_ptr = %p", + meta_buffer_hdr, m_inp_mem_ptr); + } for (index = 0; ((index < m_sInPortDef.nBufferCountActual) && meta_buffer_hdr[index].pBuffer); index++); if (index == m_sInPortDef.nBufferCountActual) { @@ -2697,6 +2784,7 @@ OMX_ERRORTYPE omx_video::allocate_input_buffer( return OMX_ErrorInsufficientResources; } + DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr); m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); if (m_pInput_pmem == NULL) { @@ -2767,13 +2855,14 @@ OMX_ERRORTYPE omx_video::allocate_input_buffer( m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; m_pInput_pmem[i].offset = 0; - m_pInput_pmem[i].buffer = (OMX_U8 *)SECURE_BUFPTR; + m_pInput_pmem[i].buffer = NULL; if(!secure_session) { m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL, m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, MAP_SHARED,m_pInput_pmem[i].fd,0); if (m_pInput_pmem[i].buffer == MAP_FAILED) { DEBUG_PRINT_ERROR("ERROR: mmap FAILED= %d", errno); + m_pInput_pmem[i].buffer = NULL; close(m_pInput_pmem[i].fd); #ifdef USE_ION free_ion_memory(&m_pInput_ion[i]); @@ -2784,6 +2873,11 @@ OMX_ERRORTYPE omx_video::allocate_input_buffer( //This should only be used for passing reference to source type and //secure handle fd struct native_handle_t* m_pInput_pmem[i].buffer = malloc(sizeof(OMX_U32) + sizeof(native_handle_t*)); + if (m_pInput_pmem[i].buffer == NULL) { + DEBUG_PRINT_ERROR("%s: failed to allocate native-handle", __func__); + return OMX_ErrorInsufficientResources; + } + (*bufferHdr)->nAllocLen = sizeof(OMX_U32) + sizeof(native_handle_t*); } (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer; @@ -2902,7 +2996,7 @@ OMX_ERRORTYPE omx_video::allocate_output_buffer( align_size = ((m_sOutPortDef.nBufferSize + 4095)/4096) * 4096; m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size, &m_pOutput_ion[i].ion_alloc_data, - &m_pOutput_ion[i].fd_ion_data,0); + &m_pOutput_ion[i].fd_ion_data, ION_FLAG_CACHED); #else m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize, &m_pOutput_ion[i].ion_alloc_data, @@ -2928,7 +3022,7 @@ OMX_ERRORTYPE omx_video::allocate_output_buffer( m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; m_pOutput_pmem[i].offset = 0; - m_pOutput_pmem[i].buffer = (OMX_U8 *)SECURE_BUFPTR; + m_pOutput_pmem[i].buffer = NULL; if(!secure_session) { #ifdef _MSM8974_ m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL, @@ -2941,6 +3035,7 @@ OMX_ERRORTYPE omx_video::allocate_output_buffer( #endif if (m_pOutput_pmem[i].buffer == MAP_FAILED) { DEBUG_PRINT_ERROR("ERROR: MMAP_FAILED in o/p alloc buffer"); + m_pOutput_pmem[i].buffer = NULL; close (m_pOutput_pmem[i].fd); #ifdef USE_ION free_ion_memory(&m_pOutput_ion[i]); @@ -2952,12 +3047,17 @@ OMX_ERRORTYPE omx_video::allocate_output_buffer( //This should only be used for passing reference to source type and //secure handle fd struct native_handle_t* m_pOutput_pmem[i].buffer = malloc(sizeof(OMX_U32) + sizeof(native_handle_t*)); + if (m_pOutput_pmem[i].buffer == NULL) { + DEBUG_PRINT_ERROR("%s: Failed to allocate native-handle", __func__); + return OMX_ErrorInsufficientResources; + } + (*bufferHdr)->nAllocLen = sizeof(OMX_U32) + sizeof(native_handle_t*); native_handle_t *handle = native_handle_create(1, 0); handle->data[0] = m_pOutput_pmem[i].fd; char *data = (char*) m_pOutput_pmem[i].buffer; OMX_U32 type = 1; - memcpy(data, &type, 4); - memcpy(data + 4, &handle, sizeof(native_handle_t*)); + memcpy(data, &type, sizeof(OMX_U32)); + memcpy(data + sizeof(OMX_U32), &handle, sizeof(native_handle_t*)); } *bufferHdr = (m_out_mem_ptr + i ); @@ -3102,28 +3202,27 @@ OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp, if (port == PORT_INDEX_IN) { // check if the buffer is valid - nPortIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); + nPortIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr); DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %u, actual cnt %u", nPortIndex, (unsigned int)m_sInPortDef.nBufferCountActual); - if (nPortIndex < m_sInPortDef.nBufferCountActual) { + if (nPortIndex < m_sInPortDef.nBufferCountActual && + BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) { // Clear the bit associated with it. BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); free_input_buffer (buffer); m_sInPortDef.bPopulated = OMX_FALSE; /*Free the Buffer Header*/ - if (release_input_done() -#ifdef _ANDROID_ICS_ - && !meta_mode_enable -#endif - ) { + if (release_input_done()) { input_use_buffer = false; - if (m_inp_mem_ptr) { + // "m_inp_mem_ptr" may point to "meta_buffer_hdr" in some modes, + // in which case, it was not explicitly allocated + if (m_inp_mem_ptr && m_inp_mem_ptr != meta_buffer_hdr) { DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr"); free (m_inp_mem_ptr); - m_inp_mem_ptr = NULL; } + m_inp_mem_ptr = NULL; if (m_pInput_pmem) { DEBUG_PRINT_LOW("Freeing m_pInput_pmem"); free(m_pInput_pmem); @@ -3156,7 +3255,8 @@ OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp, DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %u, actual cnt %u", nPortIndex, (unsigned int)m_sOutPortDef.nBufferCountActual); - if (nPortIndex < m_sOutPortDef.nBufferCountActual) { + if (nPortIndex < m_sOutPortDef.nBufferCountActual && + BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) { // Clear the bit associated with it. BITMASK_CLEAR(&m_out_bm_count,nPortIndex); m_sOutPortDef.bPopulated = OMX_FALSE; @@ -3212,7 +3312,7 @@ OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp, post_event(OMX_CommandStateSet, OMX_StateLoaded, OMX_COMPONENT_GENERATE_EVENT); } else { - DEBUG_PRINT_HIGH("in free buffer, release not done, need to free more buffers input 0x%x output 0x%x", + DEBUG_PRINT_HIGH("in free buffer, release not done, need to free more buffers input %" PRIx64" output %" PRIx64, m_out_bm_count, m_inp_bm_count); } } @@ -3243,7 +3343,9 @@ OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, unsigned int nBufferIndex ; DEBUG_PRINT_LOW("ETB: buffer = %p, buffer->pBuffer[%p]", buffer, buffer->pBuffer); - if (m_state == OMX_StateInvalid) { + if (m_state != OMX_StateExecuting && + m_state != OMX_StatePause && + m_state != OMX_StateIdle) { DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State"); return OMX_ErrorInvalidState; } @@ -3267,7 +3369,7 @@ OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, return OMX_ErrorIncorrectStateOperation; } - nBufferIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); + nBufferIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr); if (nBufferIndex > m_sInPortDef.nBufferCountActual ) { DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]", nBufferIndex); @@ -3367,6 +3469,10 @@ OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, if (meta_mode_enable && !mUseProxyColorFormat) { // Camera or Gralloc-source meta-buffers queued with pre-announced color-format struct pmem Input_pmem_info; + if (!media_buffer) { + DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__); + return OMX_ErrorBadParameter; + } if (media_buffer->buffer_type == kMetadataBufferTypeCameraSource) { Input_pmem_info.buffer = media_buffer; Input_pmem_info.fd = media_buffer->meta_handle->data[0]; @@ -3415,9 +3521,13 @@ OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, #endif { DEBUG_PRINT_LOW("Heap UseBuffer case, so memcpy the data"); + + auto_lock l(m_lock); pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer; - memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset), - buffer->nFilledLen); + if (pmem_data_buf) { + memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset), + buffer->nFilledLen); + } DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf"); } else if (mUseProxyColorFormat) { // Gralloc-source buffers with color-conversion @@ -3449,6 +3559,9 @@ OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD); /*Generate an async error and move to invalid state*/ pending_input_buffers--; + if (hw_overload) { + return OMX_ErrorInsufficientResources; + } return OMX_ErrorBadParameter; } return ret; @@ -3473,7 +3586,9 @@ OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_IN OMX_BUFFERHEADERTYPE* buffer) { DEBUG_PRINT_LOW("FTB: buffer->pBuffer[%p]", buffer->pBuffer); - if (m_state == OMX_StateInvalid) { + if (m_state != OMX_StateExecuting && + m_state != OMX_StatePause && + m_state != OMX_StateIdle) { DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State"); return OMX_ErrorInvalidState; } @@ -3694,6 +3809,16 @@ OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, } } #endif + else if ((!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp((char*)m_nkind, "OMX.qti.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE))) { + if ((0 == index) && role) { + strlcpy((char *)role, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s", role); + } else { + DEBUG_PRINT_ERROR("ERROR: No more roles"); + eRet = OMX_ErrorNoMore; + } + } else { DEBUG_PRINT_ERROR("ERROR: Querying Role on Unknown Component"); eRet = OMX_ErrorInvalidComponentName; @@ -3961,22 +4086,20 @@ OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp, OMX_BUFFERHEADERTYPE* buffer) { int buffer_index = -1; - int buffer_index_meta = -1; - buffer_index = (buffer - m_inp_mem_ptr); - buffer_index_meta = (buffer - meta_buffer_hdr); + buffer_index = buffer - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr); DEBUG_PRINT_LOW("empty_buffer_done: buffer[%p]", buffer); if (buffer == NULL || - ((buffer_index > (int)m_sInPortDef.nBufferCountActual) && - (buffer_index_meta > (int)m_sInPortDef.nBufferCountActual))) { + ((buffer_index > (int)m_sInPortDef.nBufferCountActual))) { DEBUG_PRINT_ERROR("ERROR in empty_buffer_done due to index buffer"); return OMX_ErrorBadParameter; } pending_input_buffers--; - if (mUseProxyColorFormat && ((OMX_U32)buffer_index < m_sInPortDef.nBufferCountActual)) { - if (!pdest_frame && !input_flush_progress) { + if (mUseProxyColorFormat && + (buffer_index >= 0 && (buffer_index < (int)m_sInPortDef.nBufferCountActual))) { + if (!pdest_frame && !input_flush_progress && mUsesColorConversion) { pdest_frame = buffer; DEBUG_PRINT_LOW("empty_buffer_done pdest_frame address is %p",pdest_frame); return push_input_buffer(hComp); @@ -3997,10 +4120,9 @@ OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp, } else { // We are not dealing with color-conversion, Buffer being returned // here is client's buffer, return it back to client - OMX_BUFFERHEADERTYPE* il_buffer = &meta_buffer_hdr[buffer_index]; - if (m_pCallbacks.EmptyBufferDone && il_buffer) { - m_pCallbacks.EmptyBufferDone(hComp, m_app_data, il_buffer); - DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p",il_buffer); + if (m_pCallbacks.EmptyBufferDone && buffer) { + m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer); + DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p", buffer); } } } else if (m_pCallbacks.EmptyBufferDone) { @@ -4199,6 +4321,18 @@ OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVE (unsigned int)profileLevelType->nProfileIndex); eRet = OMX_ErrorNoMore; } + } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingHEVC) { + if (profileLevelType->nProfileIndex == 0) { + profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain; + profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel52; + } else if (profileLevelType->nProfileIndex == 1) { + profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10; + profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel52; + } else { + DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", + (unsigned int)profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } } else { DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore"); eRet = OMX_ErrorNoMore; @@ -4237,20 +4371,22 @@ int omx_video::alloc_map_ion_memory(int size, alloc_data->align = SZ_1M; alloc_data->flags = ION_SECURE; alloc_data->ION_HEAP_MASK = ION_HEAP(ION_CP_MM_HEAP_ID); - DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %d align %d flags %x", - alloc_data->len, alloc_data->align,alloc_data->flags); + DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %u align %u flags %x", + (unsigned int)alloc_data->len, (unsigned int)alloc_data->align, + alloc_data->flags); } else { alloc_data->len = (size + (SZ_4K - 1)) & ~(SZ_4K - 1); alloc_data->align = SZ_4K; alloc_data->flags = (flag & ION_FLAG_CACHED ? ION_FLAG_CACHED : 0); #ifdef MAX_RES_720P - alloc_data->ION_HEAP_MASK = ION_HEAP(MEM_HEAP_ID); + alloc_data->ION_HEAP_MASK = ION_HEAP(MEM_HEAP_ID); #else - alloc_data->ION_HEAP_MASK = (ION_HEAP(MEM_HEAP_ID) | + alloc_data->ION_HEAP_MASK = (ION_HEAP(MEM_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID)); #endif - DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %d align %d flags %x", - alloc_data->len, alloc_data->align,alloc_data->flags); + DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %u align %u flags %x", + (unsigned int)alloc_data->len, (unsigned int)alloc_data->align, + alloc_data->flags); } rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data); @@ -4476,6 +4612,7 @@ OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp, unsigned nBufIndex = 0; OMX_ERRORTYPE ret = OMX_ErrorNone; encoder_media_buffer_type *media_buffer; + private_handle_t *handle = NULL; DEBUG_PRINT_LOW("ETBProxyOpaque: buffer[%p]", buffer); if (buffer == NULL) { @@ -4489,19 +4626,27 @@ OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp, return OMX_ErrorBadParameter; } media_buffer = (encoder_media_buffer_type *)buffer->pBuffer; - private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; + if ((!media_buffer || !media_buffer->meta_handle) && + !(buffer->nFlags & OMX_BUFFERFLAG_EOS)) { + DEBUG_PRINT_ERROR("Incorrect Buffer queued media buffer = %p", + media_buffer); + m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer); + return OMX_ErrorBadParameter; + } else if (media_buffer) { + handle = (private_handle_t *)media_buffer->meta_handle; + } /*Enable following code once private handle color format is updated correctly*/ + mUsesColorConversion = true; - if (buffer->nFilledLen > 0) { + if (buffer->nFilledLen > 0 && handle) { if (c2d_opened && handle->format != c2d_conv.get_src_format()) { c2d_conv.close(); c2d_opened = false; } if (!c2d_opened) { if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) { - mUsesColorConversion = true; DEBUG_PRINT_INFO("open Color conv for RGBA888 W: %u, H: %u", (unsigned int)m_sInPortDef.format.video.nFrameWidth, (unsigned int)m_sInPortDef.format.video.nFrameHeight); @@ -4517,8 +4662,12 @@ OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp, if (!dev_set_format(handle->format)) DEBUG_PRINT_ERROR("cannot set color format for RGBA8888"); #endif - } else if (handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) { + } else if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE && + handle->format != QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) { + mUsesColorConversion = false; + } else { DEBUG_PRINT_ERROR("Incorrect color format"); + mUsesColorConversion = false; m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); return OMX_ErrorBadParameter; } @@ -4672,6 +4821,7 @@ OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp) unsigned long address = 0,p2,id, index = 0; OMX_ERRORTYPE ret = OMX_ErrorNone; + DEBUG_PRINT_LOW("In push input buffer"); if (!psource_frame && m_opq_meta_q.m_size) { m_opq_meta_q.pop_entry(&address,&p2,&id); psource_frame = (OMX_BUFFERHEADERTYPE* ) address; @@ -4717,7 +4867,8 @@ OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp) Input_pmem_info.size = handle->size; if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) ret = convert_queue_buffer(hComp,Input_pmem_info,index); - else if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) + else if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE || + handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ret = queue_meta_buffer(hComp,Input_pmem_info); else ret = OMX_ErrorBadParameter; @@ -4730,7 +4881,11 @@ OMX_ERRORTYPE omx_video::push_empty_eos_buffer(OMX_HANDLETYPE hComp, OMX_BUFFERHEADERTYPE* buffer) { OMX_BUFFERHEADERTYPE* opqBuf = NULL; OMX_ERRORTYPE retVal = OMX_ErrorNone; + unsigned index = 0; + + DEBUG_PRINT_LOW("In push empty eos buffer"); do { + if (mUsesColorConversion) { if (pdest_frame) { //[1] use a checked out conversion buffer, if one is available opqBuf = pdest_frame; @@ -4741,7 +4896,12 @@ OMX_ERRORTYPE omx_video::push_empty_eos_buffer(OMX_HANDLETYPE hComp, m_opq_pmem_q.pop_entry(&address,&p2,&id); opqBuf = (OMX_BUFFERHEADERTYPE* ) address; } - unsigned index = opqBuf - m_inp_mem_ptr; + index = opqBuf - m_inp_mem_ptr; + } else { + opqBuf = (OMX_BUFFERHEADERTYPE* ) buffer; + index = opqBuf - meta_buffer_hdr; + } + if (!opqBuf || index >= m_sInPortDef.nBufferCountActual) { DEBUG_PRINT_ERROR("push_empty_eos_buffer: Could not find a " "color-conversion buffer to queue ! defer until available"); @@ -4770,6 +4930,8 @@ OMX_ERRORTYPE omx_video::push_empty_eos_buffer(OMX_HANDLETYPE hComp, emptyEosBufHdr.nTimeStamp = buffer->nTimeStamp; emptyEosBufHdr.nFlags = buffer->nFlags; emptyEosBufHdr.pBuffer = NULL; + if (!mUsesColorConversion) + emptyEosBufHdr.nAllocLen = m_sInPortDef.nBufferSize; if (dev_empty_buf(&emptyEosBufHdr, 0, index, m_pInput_pmem[index].fd) != true) { DEBUG_PRINT_ERROR("ERROR: in dev_empty_buf for empty eos buffer"); dev_free_buf(&Input_pmem_info, PORT_INDEX_IN); |