5738 lines
213 KiB
C++
Executable File
5738 lines
213 KiB
C++
Executable File
/*
|
|
* Copyright (c) 2008-2016 Allwinner Technology Co. Ltd.
|
|
* All rights reserved.
|
|
*
|
|
* File : omx_vdec.cpp
|
|
* Description :
|
|
* History :
|
|
* Author : AL3
|
|
* Date : 2013/05/05
|
|
* Comment : complete the design code
|
|
*/
|
|
|
|
/*============================================================================
|
|
O p e n M A X w r a p p e r s
|
|
O p e n M A X C o r e
|
|
|
|
*//** @file omx_vdec.cpp
|
|
This module contains the implementation of the OpenMAX core & component.
|
|
|
|
*//*========================================================================*/
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Include Files
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define LOG_TAG "omx_vdec"
|
|
#include "log.h"
|
|
|
|
#include <string.h>
|
|
#include <pthread.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <sys/time.h>
|
|
#include "omx_vdec.h"
|
|
#include <fcntl.h>
|
|
#include "AWOMX_VideoIndexExtension.h"
|
|
#include "transform_color_format.h"
|
|
#include "veAdapter.h"
|
|
|
|
#include "memoryAdapter.h"
|
|
#include "vdecoder.h"
|
|
#include "omxMM.h"
|
|
//#include "ve.h"
|
|
#include <CdcSysinfo.h>
|
|
#include <dlfcn.h>
|
|
|
|
#define SCALEDOWN_WHEN_RESOLUTION_MOER_THAN_1080P (1)
|
|
|
|
/*************** frame buffer config start ***********************/
|
|
#define NUM_OF_PICTURES_KEEP_IN_LIST 3
|
|
#define NUM_OF_PICTURES_KEEPPED_BY_DEINTERLACE 2
|
|
#define NUM_OF_PICTURES_KEEPPED_BY_ROTATE 0
|
|
#define NUM_OF_PICTURES_FOR_EXTRA_SMOOTH 3
|
|
#define DISPLAY_HOLH_BUFFER_NUM_DEFAULT (4)
|
|
|
|
/*************** frame buffer config end *************************/
|
|
|
|
#ifdef __ANDROID__
|
|
#include <binder/IPCThreadState.h>
|
|
#include <media/stagefright/foundation/ADebug.h>
|
|
#include <ui/GraphicBufferMapper.h>
|
|
#include <ui/Rect.h>
|
|
#include <HardwareAPI.h>
|
|
#endif
|
|
|
|
#define debug logv("LINE %d, FUNCTION %s", __LINE__, __FUNCTION__);
|
|
|
|
#define OPEN_STATISTICS (0)
|
|
#define PRINT_FRAME_CNT (50)
|
|
#define HW_VIDEO_CALL_APK "com.huawei.iptv.stb.videotalk.activity"
|
|
|
|
|
|
#define OMX_CACHE_BUFF_NUM (4)
|
|
#define ANDROID_SHMEM_ALIGN 32
|
|
|
|
|
|
#ifdef __ANDROID__
|
|
using namespace android;
|
|
#endif
|
|
|
|
typedef enum OMX_RESULT_STATE
|
|
{
|
|
OMX_RESULT_ERROR = -1,
|
|
OMX_RESULT_OK = 0,
|
|
OMX_RESULT_PAUSE = 1,
|
|
OMX_RESULT_EXECUT = 2,
|
|
OMX_RESULT_EXIT = 3,
|
|
OMX_RESOLUTION_CHANGE = 4,
|
|
}OMX_RESULT_STATE;
|
|
/*
|
|
* Enumeration for the commands processed by the component
|
|
*/
|
|
typedef enum ThrCmdType
|
|
{
|
|
MAIN_THREAD_CMD_SET_STATE = 0,
|
|
MAIN_THREAD_CMD_FLUSH = 1,
|
|
MAIN_THREAD_CMD_STOP_PORT = 2,
|
|
MAIN_THREAD_CMD_RESTART_PORT = 3,
|
|
MAIN_THREAD_CMD_MARK_BUF = 4,
|
|
MAIN_THREAD_CMD_STOP = 5,
|
|
MAIN_THREAD_CMD_FILL_BUF = 6,
|
|
MAIN_THREAD_CMD_EMPTY_BUF = 7,
|
|
|
|
MAIN_THREAD_CMD_VDRV_NOTIFY_EOS = 8,
|
|
MAIN_THREAD_CMD_VDRV_RESOLUTION_CHANGE = 9,
|
|
} ThrCmdType;
|
|
|
|
typedef enum OMX_VDRV_COMMANDTYPE
|
|
{
|
|
VDRV_THREAD_CMD_PREPARE_VDECODER = 0,
|
|
VDRV_THREAD_CMD_CLOSE_VDECODER = 1,
|
|
VDRV_THREAD_CMD_FLUSH_VDECODER = 2,
|
|
VDRV_THREAD_CMD_STOP_VDECODER = 3,
|
|
VDRV_THREAD_CMD_EndOfStream = 4,
|
|
} OMX_VDRV_COMMANDTYPE;
|
|
|
|
typedef enum OMX_RENDER_COMMANDTYPE
|
|
{
|
|
RENDER_THREAD_CMD_START = 0,
|
|
RENDER_THREAD_CMD_EXECUT = 1,
|
|
RENDER_THREAD_CMD_PAUSE = 2,
|
|
RENDER_THREAD_CMD_EXIT = 3,
|
|
}OMX_RENDER_COMMANDTYPE;
|
|
|
|
/* H.263 Supported Levels & profiles */
|
|
static VIDEO_PROFILE_LEVEL_TYPE SupportedH263ProfileLevels[] = {
|
|
{OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10},
|
|
{OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level20},
|
|
{OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level30},
|
|
{OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level40},
|
|
{OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45},
|
|
{OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level50},
|
|
{OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level60},
|
|
{OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level70},
|
|
{-1, -1}};
|
|
|
|
/* MPEG4 Supported Levels & profiles */
|
|
static VIDEO_PROFILE_LEVEL_TYPE SupportedMPEG4ProfileLevels[] ={
|
|
{OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0},
|
|
{OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b},
|
|
{OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1},
|
|
{OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2},
|
|
{OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3},
|
|
{OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4},
|
|
{OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a},
|
|
{OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5},
|
|
{OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0},
|
|
{OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0b},
|
|
{OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1},
|
|
{OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2},
|
|
{OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3},
|
|
{OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4},
|
|
{OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5},
|
|
{-1,-1}};
|
|
|
|
/* AVC Supported Levels & profiles for cts */
|
|
static VIDEO_PROFILE_LEVEL_TYPE CTSSupportedAVCProfileLevels[] ={
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32},
|
|
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2 },
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3 },
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32},
|
|
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1 },
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2 },
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3 },
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32},
|
|
|
|
{-1,-1}};
|
|
|
|
/* AVC Supported Levels & profiles */
|
|
static VIDEO_PROFILE_LEVEL_TYPE SupportedAVCProfileLevels[] ={
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel5},
|
|
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel51},
|
|
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2 },
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3 },
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel41},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel5},
|
|
{OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel51},
|
|
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1 },
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2 },
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3 },
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel41},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel42},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel5},
|
|
{OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel51},
|
|
|
|
{-1,-1}};
|
|
/*
|
|
* M A C R O S
|
|
*/
|
|
|
|
/*
|
|
* Initializes a data structure using a pointer to the structure.
|
|
* The initialization of OMX structures always sets up the nSize and nVersion fields
|
|
* of the structure.
|
|
*/
|
|
#define OMX_CONF_INIT_STRUCT_PTR(_variable_, _struct_name_) \
|
|
memset((_variable_), 0x0, sizeof(_struct_name_)); \
|
|
(_variable_)->nSize = sizeof(_struct_name_); \
|
|
(_variable_)->nVersion.s.nVersionMajor = 0x1; \
|
|
(_variable_)->nVersion.s.nVersionMinor = 0x1; \
|
|
(_variable_)->nVersion.s.nRevision = 0x0; \
|
|
(_variable_)->nVersion.s.nStep = 0x0
|
|
|
|
static VIDDEC_CUSTOM_PARAM sVideoDecCustomParams[] =
|
|
{
|
|
{VIDDEC_CUSTOMPARAM_ENABLE_ANDROID_NATIVE_BUFFER,
|
|
(OMX_INDEXTYPE)AWOMX_IndexParamVideoEnableAndroidNativeBuffers},
|
|
{VIDDEC_CUSTOMPARAM_GET_ANDROID_NATIVE_BUFFER_USAGE,
|
|
(OMX_INDEXTYPE)AWOMX_IndexParamVideoGetAndroidNativeBufferUsage},
|
|
{VIDDEC_CUSTOMPARAM_USE_ANDROID_NATIVE_BUFFER2,
|
|
(OMX_INDEXTYPE)AWOMX_IndexParamVideoUseAndroidNativeBuffer2},
|
|
{VIDDEC_CUSTOMPARAM_STORE_META_DATA_IN_BUFFER,
|
|
(OMX_INDEXTYPE)AWOMX_IndexParamVideoUseStoreMetaDataInBuffer},
|
|
{VIDDEC_CUSTOMPARAM_PREPARE_FOR_ADAPTIVE_PLAYBACK,
|
|
(OMX_INDEXTYPE)AWOMX_IndexParamVideoUsePrepareForAdaptivePlayback}
|
|
};
|
|
|
|
static void* ComponentThread(void* pThreadData);
|
|
static void* ComponentVdrvThread(void* pThreadData);
|
|
static void* RenderThread(void* pThreadData);
|
|
|
|
#ifdef __ANDROID__
|
|
#define GET_CALLING_PID (IPCThreadState::self()->getCallingPid())
|
|
static void getCallingProcessName(char *name)
|
|
{
|
|
char proc_node[128];
|
|
|
|
if (name == 0)
|
|
{
|
|
logd("error in params");
|
|
return;
|
|
}
|
|
|
|
memset(proc_node, 0, sizeof(proc_node));
|
|
sprintf(proc_node, "/proc/%d/cmdline", GET_CALLING_PID);
|
|
int fp = ::open(proc_node, O_RDONLY);
|
|
if (fp > 0)
|
|
{
|
|
memset(name, 0, 128);
|
|
::read(fp, name, 128);
|
|
::close(fp);
|
|
fp = 0;
|
|
logd("Calling process is: %s", name);
|
|
}
|
|
else
|
|
{
|
|
logd("Obtain calling process failed");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//* factory function executed by the core to create instances
|
|
void *get_omx_component_factory_fn(void)
|
|
{
|
|
return (new omx_vdec);
|
|
}
|
|
|
|
#if (OPEN_STATISTICS)
|
|
static int64_t OMX_GetNowUs() {
|
|
struct timeval tv;
|
|
gettimeofday(&tv, NULL);
|
|
|
|
return (int64_t)tv.tv_sec * 1000000ll + tv.tv_usec;
|
|
}
|
|
#endif
|
|
|
|
static inline void tryPostSem(sem_t* pSem)
|
|
{
|
|
int nSemVal;
|
|
int nRetSemGetValue;
|
|
nRetSemGetValue=sem_getvalue(pSem, &nSemVal);
|
|
if(0 == nRetSemGetValue)
|
|
{
|
|
if(0 == nSemVal)
|
|
{
|
|
sem_post(pSem);
|
|
}
|
|
else
|
|
{
|
|
logv("Be careful, sema frame_output[%d]!=0", nSemVal);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
logw("fatal error, why sem getvalue of m_sem_frame_output[%d] fail!",nRetSemGetValue);
|
|
}
|
|
}
|
|
|
|
static OMX_U32 omx_vdec_align(unsigned int nOriginValue, int nAlign)
|
|
{
|
|
return (nOriginValue + (nAlign-1)) & (~(nAlign-1));
|
|
}
|
|
|
|
static inline const char* statusToString(OutBufferStatus mStatus)
|
|
{
|
|
static char str[128];;
|
|
switch(mStatus)
|
|
{
|
|
case 0:
|
|
strcpy(str,"OWNED_BY_NONE");
|
|
break;
|
|
case 1:
|
|
strcpy(str,"OWNED_BY_RENDER");
|
|
break;
|
|
case 2:
|
|
strcpy(str, "OWNED_BY_DECODER");
|
|
break;
|
|
case 3:
|
|
strcpy(str, "OWNED_BY_US");
|
|
break;
|
|
default:
|
|
strcpy(str, "UNKOWN_STATUS");
|
|
break;
|
|
}
|
|
return str;
|
|
}
|
|
static inline void omxPrintOutListStatusDebug(omx_vdec * pSelf)
|
|
{
|
|
int i;
|
|
logd("");
|
|
logd("***************status*************num = %d", (int)pSelf->m_sOutBufList.nBufArrSize);
|
|
for(i=0; i<pSelf->m_sOutBufList.nBufArrSize; i++)
|
|
{
|
|
logd("i: %d, pBufHdr: %p, pPicture: %p, status: %s",
|
|
i,
|
|
pSelf->mOutputBufferInfo[i].pHeadBufInfo,
|
|
pSelf->mOutputBufferInfo[i].pVideoPicture,
|
|
statusToString(pSelf->mOutputBufferInfo[i].mStatus));
|
|
}
|
|
logd("***************status end*************");
|
|
logd("");
|
|
|
|
}
|
|
|
|
omx_vdec::omx_vdec()
|
|
{
|
|
logd("(f:%s, l:%d) ", __FUNCTION__, __LINE__);
|
|
mConvertAverageDuration = 0;
|
|
mConvertTotalCount = 0;
|
|
mConvertAverageDuration = 0;
|
|
mDecodeNoBitstreamAverageDuration = 0;
|
|
mDecodeFrameBigAverageDuration = 0;
|
|
mConvertTotalDuration = 0;
|
|
mDecodeFrameSmallAverageDuration = 0;
|
|
mDecodeOtherTotalCount = 0;
|
|
mDecodeNoBitstreamTotalCount = 0;
|
|
mDecodeNoFrameAverageDuration = 0;
|
|
mDecodeNoFrameTotalCount = 0;
|
|
mDecodeOKTotalCount = 0;
|
|
mDecodeOtherTotalDuration = 0;
|
|
mDecodeNoBitstreamTotalDuration = 0;
|
|
mDecodeFrameTotalCount = 0;
|
|
mDecodeNoFrameTotalDuration = 0;
|
|
mDecodeOKTotalDuration = 0;
|
|
mDecodeFrameTotalDuration = 0;
|
|
m_state = OMX_StateLoaded;
|
|
m_cRole[0] = 0;
|
|
m_cName[0] = 0;
|
|
m_eCompressionFormat = OMX_VIDEO_CodingUnused;
|
|
m_pAppData = NULL;
|
|
m_thread_id = 0;
|
|
m_vdrv_thread_id = 0;
|
|
m_InputNum = 0;
|
|
m_OutputNum = 0;
|
|
m_maxWidth = 0;
|
|
m_maxHeight = 0;
|
|
m_decoder = NULL;
|
|
|
|
memops = OMX_GetMemAdapterOpsS();
|
|
OMX_MemOpen(memops);
|
|
|
|
#if CONF_OMX_USE_SHARE_BUFFER
|
|
bUseShareBuffer = OMX_TRUE;
|
|
#else
|
|
bUseShareBuffer = OMX_FALSE;
|
|
#endif
|
|
bFlushAllFrameFlag = OMX_FALSE;
|
|
m_storeOutputMetaDataFlag = OMX_FALSE;
|
|
m_useAndroidBuffer = OMX_FALSE;
|
|
m_JumpFlag = OMX_FALSE;
|
|
mIsFromCts = OMX_FALSE;
|
|
m_nInportPrevTimeStamp = 0;
|
|
mFirstInputDataFlag = OMX_TRUE;
|
|
mVp9orH265SoftDecodeFlag = OMX_FALSE;
|
|
mResolutionChangeFlag = OMX_FALSE;
|
|
nResolutionChangeNativeThreadFlag = OMX_FALSE;
|
|
nResolutionChangeVdrvThreadFlag = OMX_FALSE;
|
|
mIsCyber = false;
|
|
mEmptyBufCnt = 0;
|
|
mFillBufCnt = 0;
|
|
#if CONF_OMX_USE_SHARE_BUFFER
|
|
mGpuAlignStride = 16;
|
|
#else
|
|
mGpuAlignStride = 16;
|
|
#endif
|
|
nPhyOffset = 0;
|
|
nInBufEos = OMX_FALSE;
|
|
pMarkBuf = NULL;
|
|
pMarkData = NULL;
|
|
hMarkTargetComponent = NULL;
|
|
port_setting_match = OMX_TRUE;
|
|
nVdrvNotifyEosFlag = OMX_FALSE;
|
|
nInputEosFlag = OMX_FALSE;
|
|
nVdrvResolutionChangeFlag = OMX_FALSE;
|
|
|
|
memset(mCallingProcess, 0, sizeof(mCallingProcess));
|
|
|
|
mHadGetVideoFbmBufInfoFlag = OMX_FALSE;
|
|
mSetToDecoderBufferNum = 0;
|
|
mNeedReSetToDecoderBufferNum = 0;
|
|
mExtraOutBufferNum = 0;
|
|
#ifdef __ANDROID__
|
|
getCallingProcessName(mCallingProcess);
|
|
if((strcmp(mCallingProcess, "com.android.cts.media") == 0)
|
|
|| (strcmp(mCallingProcess, "com.android.cts.videoperf") == 0)
|
|
|| (strcmp(mCallingProcess, "com.android.pts.videoperf") == 0))
|
|
{
|
|
mIsFromCts = true;
|
|
}
|
|
|
|
if((strcmp(mCallingProcess, "com.cloud.cyber") == 0))
|
|
{
|
|
mIsCyber = true;
|
|
logd("+++ cyber apk");
|
|
}
|
|
if((strcmp(mCallingProcess, HW_VIDEO_CALL_APK) == 0))
|
|
{
|
|
mCropEnable = false;
|
|
logd("mCropEnable = false");
|
|
}
|
|
else
|
|
{
|
|
mCropEnable = true;
|
|
}
|
|
#else
|
|
mCropEnable = false;
|
|
#endif
|
|
|
|
mIsFirstGetOffset = true;
|
|
|
|
memset(&m_Callbacks, 0, sizeof(m_Callbacks));
|
|
memset(&m_sInPortDefType, 0, sizeof(m_sInPortDefType));
|
|
memset(&m_sOutPortDefType, 0, sizeof(m_sOutPortDefType));
|
|
memset(&m_sInPortFormatType, 0, sizeof(m_sInPortFormatType));
|
|
memset(&m_sOutPortFormatType, 0, sizeof(m_sOutPortFormatType));
|
|
memset(&m_sPriorityMgmtType, 0, sizeof(m_sPriorityMgmtType));
|
|
memset(&m_sInBufSupplierType, 0, sizeof(m_sInBufSupplierType));
|
|
memset(&m_sOutBufSupplierType, 0, sizeof(m_sOutBufSupplierType));
|
|
memset(&m_sInBufList, 0, sizeof(m_sInBufList));
|
|
memset(&m_sOutBufList, 0, sizeof(m_sOutBufList));
|
|
memset(&m_sCacheBufList, 0, sizeof(m_sCacheBufList));
|
|
|
|
memset(&m_streamInfo, 0, sizeof(m_streamInfo));
|
|
memset(&m_videoConfig,0,sizeof(VConfig));
|
|
memset(&mOutputBufferInfo, 0, sizeof(OMXOutputBufferInfoT)*OMX_MAX_VIDEO_BUFFER_NUM);
|
|
memset(&mVideoRect,0,sizeof(OMX_CONFIG_RECTTYPE));
|
|
|
|
|
|
memset(&mOutBufferKeepInOmx, 0, sizeof(OMX_BUFFERHEADERTYPE*)*OMX_MAX_VIDEO_BUFFER_NUM);
|
|
mOutBufferKeepInOmxNum = 0;
|
|
pthread_mutex_init(&m_inBufMutex, NULL);
|
|
pthread_mutex_init(&m_outBufMutex, NULL);
|
|
pthread_mutex_init(&m_pipeMutex, NULL);
|
|
|
|
sem_init(&m_vdrv_cmd_lock,0,0);
|
|
sem_init(&m_render_cmd_lock,0,0);
|
|
sem_init(&m_sem_vbs_input,0,0);
|
|
sem_init(&m_sem_frame_output,0,0);
|
|
sem_init(&m_semExtraOutBufferNum,0,0);
|
|
sem_init(&m_semResolutionChange,0,0);
|
|
sem_init(&m_semFlushAllFrame,0,0);
|
|
int type = VE_OPS_TYPE_NORMAL;
|
|
VeOpsS* veOps = GetVeOpsS(type);
|
|
if(veOps == NULL)
|
|
{
|
|
loge("get ve ops failed");
|
|
}
|
|
else
|
|
{
|
|
VeConfig mVeConfig;
|
|
memset(&mVeConfig, 0, sizeof(VeConfig));
|
|
mVeConfig.nDecoderFlag = 1;
|
|
void* pVeopsSelf = CdcVeInit(veOps,&mVeConfig);
|
|
if(pVeopsSelf == NULL)
|
|
{
|
|
loge("init ve ops failed");
|
|
CdcVeRelease(veOps, pVeopsSelf);
|
|
nPhyOffset = 0x40000000;
|
|
}
|
|
else
|
|
{
|
|
nPhyOffset = CdcVeGetPhyOffset(veOps, pVeopsSelf);
|
|
CdcVeRelease(veOps, pVeopsSelf);
|
|
}
|
|
logd("** nPhyOffset = %lx",nPhyOffset);
|
|
}
|
|
|
|
mqMainThread = CdcMessageQueueCreate(64, "omx_vdec_mainThread");
|
|
mqVdrvThread = CdcMessageQueueCreate(64, "omx_vdec_VdrvThread");
|
|
mqRenderThread = CdcMessageQueueCreate(64, "omx_vdec_RenderThread");
|
|
if(mqMainThread == NULL || mqVdrvThread == NULL || mqRenderThread == NULL)
|
|
{
|
|
loge(" create mqMainThread[%p] or mqVdrvThread[%p] or mqRenderThread[%p] failed",
|
|
mqMainThread, mqVdrvThread, mqRenderThread);
|
|
}
|
|
}
|
|
|
|
|
|
omx_vdec::~omx_vdec()
|
|
{
|
|
OMX_S32 nIndex;
|
|
// In case the client crashes, check for nAllocSize parameter.
|
|
// If this is greater than zero, there are elements in the list that are not free'd.
|
|
// In that case, free the elements.
|
|
logv("(f:%s, l:%d) ", __FUNCTION__, __LINE__);
|
|
pthread_mutex_lock(&m_inBufMutex);
|
|
|
|
for(nIndex=0; nIndex<m_sInBufList.nBufArrSize; nIndex++)
|
|
{
|
|
if(m_sInBufList.pBufArr==NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if(m_sInBufList.pBufArr[nIndex].pBuffer != NULL)
|
|
{
|
|
if(m_sInBufList.nAllocBySelfFlags & (1<<nIndex))
|
|
{
|
|
free(m_sInBufList.pBufArr[nIndex].pBuffer);
|
|
m_sInBufList.pBufArr[nIndex].pBuffer = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_sInBufList.pBufArr != NULL)
|
|
free(m_sInBufList.pBufArr);
|
|
|
|
if (m_sInBufList.pBufHdrList != NULL)
|
|
free(m_sInBufList.pBufHdrList);
|
|
|
|
memset(&m_sInBufList, 0, sizeof(struct _BufferList));
|
|
m_sInBufList.nBufArrSize = m_sInPortDefType.nBufferCountActual;
|
|
|
|
pthread_mutex_unlock(&m_inBufMutex);
|
|
|
|
|
|
pthread_mutex_lock(&m_outBufMutex);
|
|
|
|
for(nIndex=0; nIndex<m_sOutBufList.nBufArrSize; nIndex++)
|
|
{
|
|
if(m_sOutBufList.pBufArr[nIndex].pBuffer != NULL)
|
|
{
|
|
if(m_sOutBufList.nAllocBySelfFlags & (1<<nIndex))
|
|
{
|
|
if(bUseShareBuffer)
|
|
OMX_MemPfree(memops,m_sOutBufList.pBufArr[nIndex].pBuffer);
|
|
//VideoDecoderFreeIonBuf(m_decoder, m_sOutBufList.pBufArr[nIndex].pBuffer);
|
|
else
|
|
free(m_sOutBufList.pBufArr[nIndex].pBuffer);
|
|
m_sOutBufList.pBufArr[nIndex].pBuffer = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_sOutBufList.pBufArr != NULL)
|
|
free(m_sOutBufList.pBufArr);
|
|
|
|
if (m_sOutBufList.pBufHdrList != NULL)
|
|
free(m_sOutBufList.pBufHdrList);
|
|
|
|
memset(&m_sOutBufList, 0, sizeof(struct _BufferList));
|
|
m_sOutBufList.nBufArrSize = m_sOutPortDefType.nBufferCountActual;
|
|
|
|
|
|
if (m_sCacheBufList.pBufHdrList != NULL)
|
|
free(m_sCacheBufList.pBufHdrList);
|
|
|
|
memset(&m_sCacheBufList, 0, sizeof(struct _BufferList));
|
|
m_sCacheBufList.nBufArrSize = OMX_CACHE_BUFF_NUM;
|
|
pthread_mutex_unlock(&m_outBufMutex);
|
|
|
|
if(m_decoder != NULL)
|
|
{
|
|
DestroyVideoDecoder(m_decoder);
|
|
m_decoder = NULL;
|
|
}
|
|
|
|
pthread_mutex_destroy(&m_inBufMutex);
|
|
pthread_mutex_destroy(&m_outBufMutex);
|
|
|
|
pthread_mutex_destroy(&m_pipeMutex);
|
|
sem_destroy(&m_vdrv_cmd_lock);
|
|
sem_destroy(&m_render_cmd_lock);
|
|
sem_destroy(&m_sem_vbs_input);
|
|
sem_destroy(&m_sem_frame_output);
|
|
sem_destroy(&m_semExtraOutBufferNum);
|
|
sem_destroy(&m_semResolutionChange);
|
|
sem_destroy(&m_semFlushAllFrame);
|
|
|
|
if(m_streamInfo.pCodecSpecificData)
|
|
free(m_streamInfo.pCodecSpecificData);
|
|
if(memops)
|
|
OMX_MemClose(memops);
|
|
|
|
if(mqMainThread)
|
|
CdcMessageQueueDestroy(mqMainThread);
|
|
|
|
if(mqVdrvThread)
|
|
CdcMessageQueueDestroy(mqVdrvThread);
|
|
|
|
if(mqRenderThread)
|
|
CdcMessageQueueDestroy(mqRenderThread);
|
|
#if(OPEN_STATISTICS)
|
|
if(mDecodeFrameTotalCount!=0 && mConvertTotalCount!=0)
|
|
{
|
|
mDecodeFrameSmallAverageDuration
|
|
= (mDecodeFrameTotalDuration + mDecodeOKTotalDuration)/(mDecodeFrameTotalCount);
|
|
mDecodeFrameBigAverageDuration
|
|
= (mDecodeFrameTotalDuration + mDecodeOKTotalDuration \
|
|
+ mDecodeNoFrameTotalDuration + mDecodeNoBitstreamTotalDuration \
|
|
+ mDecodeOtherTotalDuration)/(mDecodeFrameTotalCount);
|
|
if(mDecodeNoFrameTotalCount > 0)
|
|
{
|
|
mDecodeNoFrameAverageDuration
|
|
= (mDecodeNoFrameTotalDuration)/(mDecodeNoFrameTotalCount);
|
|
}
|
|
else
|
|
{
|
|
mDecodeNoFrameAverageDuration = 0;
|
|
}
|
|
if(mDecodeNoBitstreamTotalCount > 0)
|
|
{
|
|
mDecodeNoBitstreamAverageDuration
|
|
= (mDecodeNoBitstreamTotalDuration)/(mDecodeNoBitstreamTotalCount);
|
|
}
|
|
else
|
|
{
|
|
mDecodeNoBitstreamAverageDuration = 0;
|
|
}
|
|
mConvertAverageDuration = mConvertTotalDuration/mConvertTotalCount;
|
|
logd("decode and convert statistics: \
|
|
\n mDecodeFrameTotalDuration[%lld]ms, mDecodeOKTotalDuration[%lld]ms, \
|
|
mDecodeNoFrameTotalDuration[%lld]ms, mDecodeNoBitstreamTotalDuration[%lld]ms, \
|
|
mDecodeOtherTotalDuration[%lld]ms, \
|
|
\n mDecodeFrameTotalCount[%lld], mDecodeOKTotalCount[%lld], \
|
|
mDecodeNoFrameTotalCount[%lld], mDecodeNoBitstreamTotalCount[%lld], \
|
|
mDecodeOtherTotalCount[%lld],\
|
|
\n mDecodeFrameSmallAverageDuration[%lld]ms, mDecodeFrameBigAverageDuration[%lld]ms,\
|
|
mDecodeNoFrameAverageDuration[%lld]ms, mDecodeNoBitstreamAverageDuration[%lld]ms\
|
|
\n mConvertTotalDuration[%lld]ms, mConvertTotalCount[%lld],\
|
|
mConvertAverageDuration[%lld]ms",
|
|
mDecodeFrameTotalDuration/1000, mDecodeOKTotalDuration/1000,
|
|
mDecodeNoFrameTotalDuration/1000, mDecodeNoBitstreamTotalDuration/1000,
|
|
mDecodeOtherTotalDuration/1000,mDecodeFrameTotalCount,
|
|
mDecodeOKTotalCount, mDecodeNoFrameTotalCount,
|
|
mDecodeNoBitstreamTotalCount, mDecodeOtherTotalCount,
|
|
mDecodeFrameSmallAverageDuration/1000, mDecodeFrameBigAverageDuration/1000,
|
|
mDecodeNoFrameAverageDuration/1000, mDecodeNoBitstreamAverageDuration/1000,
|
|
mConvertTotalDuration/1000, mConvertTotalCount, mConvertAverageDuration/1000);
|
|
}
|
|
#endif
|
|
|
|
logd("~omx_dec done!");
|
|
}
|
|
|
|
typedef void PluginInitFunc(void);
|
|
|
|
void InitPlugin(char *pName)
|
|
{
|
|
PluginInitFunc *PluginInit = NULL;
|
|
void *libFd = dlopen(pName,RTLD_NOW);
|
|
if(libFd == NULL)
|
|
{
|
|
logd("load library %s fail!\n",pName);
|
|
}
|
|
else
|
|
{
|
|
logd("load library %s success!\n",pName);
|
|
}
|
|
|
|
PluginInit = (PluginInitFunc *)dlsym(libFd,"CedarPluginVDInit");
|
|
if(PluginInit != NULL)
|
|
{
|
|
PluginInit();
|
|
}
|
|
else
|
|
{
|
|
logd("no CedarPluginVDInit in %s\n",pName);
|
|
}
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING pName)
|
|
{
|
|
OMX_ERRORTYPE eRet = OMX_ErrorNone;
|
|
int err;
|
|
OMX_U32 nIndex;
|
|
char calling_process[256];
|
|
memset(calling_process, 0, sizeof(calling_process));
|
|
logi("(f:%s, l:%d) name = %s", __FUNCTION__, __LINE__, pName);
|
|
AddVDPlugin();
|
|
strncpy((char*)m_cName, pName, OMX_MAX_STRINGNAME_SIZE);
|
|
|
|
|
|
if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.mjpeg",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.mjpeg", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingMJPEG;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MJPEG;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.mpeg1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.mpeg1", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingMPEG1;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MPEG1;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.mpeg2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingMPEG2;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MPEG2;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.mpeg4",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingMPEG4;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_XVID;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.msmpeg4v1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole, "video_decoder.msmpeg4v1", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingMSMPEG4V1;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MSMPEG4V1;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.msmpeg4v2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole, "video_decoder.msmpeg4v2", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingMSMPEG4V2;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MSMPEG4V2;
|
|
}
|
|
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.msmpeg4v3",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole, "video_decoder.msmpeg4v3", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingMSMPEG4V3;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_DIVX3;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.divx4",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole, "video_decoder.divx4", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingDIVX4;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_DIVX4;
|
|
}
|
|
#if 0
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.rx",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole, "video_decoder.rx", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingRX;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_RX;
|
|
}
|
|
#endif
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.avs",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole, "video_decoder.avs", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingAVS;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_AVS;
|
|
}
|
|
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.divx",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingDIVX;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_DIVX5;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.xvid",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole, "video_decoder.xvid", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingXVID;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_XVID;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.h263",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE);
|
|
logv("\n H263 Decoder selected");
|
|
m_eCompressionFormat = OMX_VIDEO_CodingH263;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_H263;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.s263",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.s263", OMX_MAX_STRINGNAME_SIZE);
|
|
logv("\n H263 Decoder selected");
|
|
m_eCompressionFormat = OMX_VIDEO_CodingS263;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_SORENSSON_H263;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.rxg2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.rxg2", OMX_MAX_STRINGNAME_SIZE);
|
|
logv("\n H263 Decoder selected");
|
|
m_eCompressionFormat = OMX_VIDEO_CodingRXG2;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_RXG2;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.wmv1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.wmv1", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingWMV1;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_WMV1;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.wmv2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.wmv2", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingWMV2;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_WMV2;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.vc1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingWMV;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_WMV3;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.vp6",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.vp6", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingVP6; //OMX_VIDEO_CodingVPX
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_VP6;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.vp8",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingVP8; //OMX_VIDEO_CodingVPX
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_VP8;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.vp9",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingVP9; //OMX_VIDEO_CodingVPX
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_VP9;
|
|
mVp9orH265SoftDecodeFlag = OMX_TRUE;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.avc",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE);
|
|
m_eCompressionFormat = OMX_VIDEO_CodingAVC;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_H264;
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.hevc",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char *)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
|
|
logv("\n H263 Decoder selected");
|
|
m_eCompressionFormat = OMX_VIDEO_CodingHEVC;
|
|
m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_H265;
|
|
mVp9orH265SoftDecodeFlag = OMX_TRUE;
|
|
}
|
|
else
|
|
{
|
|
logv("\nERROR:Unknown Component\n");
|
|
eRet = OMX_ErrorInvalidComponentName;
|
|
return eRet;
|
|
}
|
|
|
|
// Initialize component data structures to default values
|
|
OMX_CONF_INIT_STRUCT_PTR(&m_sPortParam, OMX_PORT_PARAM_TYPE);
|
|
m_sPortParam.nPorts = 0x2;
|
|
m_sPortParam.nStartPortNumber = 0x0;
|
|
|
|
// Initialize the video parameters for input port
|
|
OMX_CONF_INIT_STRUCT_PTR(&m_sInPortDefType, OMX_PARAM_PORTDEFINITIONTYPE);
|
|
m_sInPortDefType.nPortIndex = 0x0;
|
|
m_sInPortDefType.bEnabled = OMX_TRUE;
|
|
m_sInPortDefType.bPopulated = OMX_FALSE;
|
|
m_sInPortDefType.eDomain = OMX_PortDomainVideo;
|
|
m_sInPortDefType.format.video.nFrameWidth = 0;
|
|
m_sInPortDefType.format.video.nFrameHeight = 0;
|
|
m_sInPortDefType.eDir = OMX_DirInput;
|
|
m_sInPortDefType.nBufferCountMin = NUM_IN_BUFFERS;
|
|
m_sInPortDefType.nBufferCountActual = NUM_IN_BUFFERS;
|
|
#ifdef __ANDROID__
|
|
getCallingProcessName(calling_process);
|
|
if (strcmp(calling_process, HW_VIDEO_CALL_APK) == 0)
|
|
{
|
|
m_sInPortDefType.nBufferCountMin = 8;
|
|
m_sInPortDefType.nBufferCountActual = 8;
|
|
logv("HW_VIDOE_CALL:%s,F:%s,L:%d",HW_VIDEO_CALL_APK,__FUNCTION__,__LINE__);
|
|
}
|
|
#endif
|
|
m_sInPortDefType.nBufferSize = OMX_VIDEO_DEC_INPUT_BUFFER_SIZE;
|
|
m_sInPortDefType.format.video.eCompressionFormat = m_eCompressionFormat;
|
|
m_sInPortDefType.format.video.cMIMEType = (OMX_STRING)"";
|
|
|
|
m_sInPortDefType.nBufferSize \
|
|
= omx_vdec_align(m_sInPortDefType.nBufferSize, ANDROID_SHMEM_ALIGN);
|
|
|
|
// Initialize the video parameters for output port
|
|
OMX_CONF_INIT_STRUCT_PTR(&m_sOutPortDefType, OMX_PARAM_PORTDEFINITIONTYPE);
|
|
m_sOutPortDefType.nPortIndex = 0x1;
|
|
m_sOutPortDefType.bEnabled = OMX_TRUE;
|
|
m_sOutPortDefType.bPopulated = OMX_FALSE;
|
|
m_sOutPortDefType.eDomain = OMX_PortDomainVideo;
|
|
m_sOutPortDefType.format.video.cMIMEType = (OMX_STRING)"YUV420";
|
|
m_sOutPortDefType.format.video.nFrameWidth = 176;
|
|
m_sOutPortDefType.format.video.nFrameHeight = 144;
|
|
m_sOutPortDefType.format.video.nStride = 176;
|
|
m_sOutPortDefType.format.video.nSliceHeight = 144;
|
|
m_sOutPortDefType.eDir = OMX_DirOutput;
|
|
m_sOutPortDefType.nBufferCountMin = NUM_OUT_BUFFERS;
|
|
m_sOutPortDefType.nBufferCountActual = NUM_OUT_BUFFERS;
|
|
|
|
if(bUseShareBuffer)
|
|
{
|
|
m_sOutPortDefType.bBuffersContiguous = OMX_TRUE;
|
|
}
|
|
else
|
|
{
|
|
m_sOutPortDefType.bBuffersContiguous = OMX_FALSE;
|
|
}
|
|
|
|
if (strcmp(calling_process, HW_VIDEO_CALL_APK) == 0)
|
|
{
|
|
m_sOutPortDefType.nBufferCountMin = 6;
|
|
m_sOutPortDefType.nBufferCountActual = 6;
|
|
logv("HW_VIDOE_CALL:%s,F:%s,L:%d",HW_VIDEO_CALL_APK,__FUNCTION__,__LINE__);
|
|
}
|
|
m_sOutPortDefType.nBufferSize
|
|
= (OMX_U32)(m_sOutPortDefType.format.video.nFrameWidth*
|
|
m_sOutPortDefType.format.video.nFrameHeight*3/2);
|
|
#if CONF_OMX_ENABLE_EXTERN_MEM
|
|
m_sOutPortDefType.format.video.eColorFormat = OMX_COLOR_FormatYVU420Planar;
|
|
#else
|
|
m_sOutPortDefType.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
|
|
#endif
|
|
// Initialize the video compression format for input port
|
|
OMX_CONF_INIT_STRUCT_PTR(&m_sInPortFormatType, OMX_VIDEO_PARAM_PORTFORMATTYPE);
|
|
m_sInPortFormatType.nPortIndex = 0x0;
|
|
m_sInPortFormatType.nIndex = 0x0;
|
|
m_sInPortFormatType.eCompressionFormat = m_eCompressionFormat;
|
|
|
|
// Initialize the compression format for output port
|
|
OMX_CONF_INIT_STRUCT_PTR(&m_sOutPortFormatType, OMX_VIDEO_PARAM_PORTFORMATTYPE);
|
|
m_sOutPortFormatType.nPortIndex = 0x1;
|
|
m_sOutPortFormatType.nIndex = 0x0;
|
|
#if CONF_OMX_ENABLE_EXTERN_MEM
|
|
m_sOutPortFormatType.eColorFormat = OMX_COLOR_FormatYVU420Planar;
|
|
#else
|
|
m_sOutPortFormatType.eColorFormat = OMX_COLOR_FormatYUV420Planar;
|
|
#endif
|
|
OMX_CONF_INIT_STRUCT_PTR(&m_sPriorityMgmtType, OMX_PRIORITYMGMTTYPE);
|
|
|
|
OMX_CONF_INIT_STRUCT_PTR(&m_sInBufSupplierType, OMX_PARAM_BUFFERSUPPLIERTYPE );
|
|
m_sInBufSupplierType.nPortIndex = 0x0;
|
|
|
|
OMX_CONF_INIT_STRUCT_PTR(&m_sOutBufSupplierType, OMX_PARAM_BUFFERSUPPLIERTYPE );
|
|
m_sOutBufSupplierType.nPortIndex = 0x1;
|
|
|
|
// Initialize the input buffer list
|
|
memset(&(m_sInBufList), 0x0, sizeof(BufferList));
|
|
|
|
m_sInBufList.pBufArr
|
|
= (OMX_BUFFERHEADERTYPE*)malloc(sizeof(OMX_BUFFERHEADERTYPE) *
|
|
m_sInPortDefType.nBufferCountActual);
|
|
if(m_sInBufList.pBufArr == NULL)
|
|
{
|
|
eRet = OMX_ErrorInsufficientResources;
|
|
goto EXIT;
|
|
}
|
|
|
|
memset(m_sInBufList.pBufArr, 0,
|
|
sizeof(OMX_BUFFERHEADERTYPE) * m_sInPortDefType.nBufferCountActual);
|
|
for (nIndex = 0; nIndex < m_sInPortDefType.nBufferCountActual; nIndex++)
|
|
{
|
|
OMX_CONF_INIT_STRUCT_PTR (&m_sInBufList.pBufArr[nIndex], OMX_BUFFERHEADERTYPE);
|
|
}
|
|
|
|
|
|
m_sInBufList.pBufHdrList
|
|
= (OMX_BUFFERHEADERTYPE**)malloc(sizeof(OMX_BUFFERHEADERTYPE*) *
|
|
m_sInPortDefType.nBufferCountActual);
|
|
if(m_sInBufList.pBufHdrList == NULL)
|
|
{
|
|
eRet = OMX_ErrorInsufficientResources;
|
|
goto EXIT;
|
|
}
|
|
|
|
m_sInBufList.nSizeOfList = 0;
|
|
m_sInBufList.nAllocSize = 0;
|
|
m_sInBufList.nWritePos = 0;
|
|
m_sInBufList.nReadPos = 0;
|
|
m_sInBufList.nAllocBySelfFlags = 0;
|
|
m_sInBufList.nSizeOfList = 0;
|
|
m_sInBufList.nBufArrSize = m_sInPortDefType.nBufferCountActual;
|
|
m_sInBufList.eDir = OMX_DirInput;
|
|
|
|
// Initialize the output buffer list
|
|
memset(&m_sOutBufList, 0x0, sizeof(BufferList));
|
|
|
|
m_sOutBufList.pBufArr
|
|
= (OMX_BUFFERHEADERTYPE*)malloc(sizeof(OMX_BUFFERHEADERTYPE) *
|
|
m_sOutPortDefType.nBufferCountActual);
|
|
if(m_sOutBufList.pBufArr == NULL)
|
|
{
|
|
eRet = OMX_ErrorInsufficientResources;
|
|
goto EXIT;
|
|
}
|
|
|
|
memset(m_sOutBufList.pBufArr, 0,
|
|
sizeof(OMX_BUFFERHEADERTYPE) * m_sOutPortDefType.nBufferCountActual);
|
|
for (nIndex = 0; nIndex < m_sOutPortDefType.nBufferCountActual; nIndex++)
|
|
{
|
|
OMX_CONF_INIT_STRUCT_PTR(&m_sOutBufList.pBufArr[nIndex], OMX_BUFFERHEADERTYPE);
|
|
}
|
|
|
|
m_sOutBufList.pBufHdrList
|
|
= (OMX_BUFFERHEADERTYPE**)malloc(sizeof(OMX_BUFFERHEADERTYPE*) *
|
|
m_sOutPortDefType.nBufferCountActual);
|
|
if(m_sOutBufList.pBufHdrList == NULL)
|
|
{
|
|
eRet = OMX_ErrorInsufficientResources;
|
|
goto EXIT;
|
|
}
|
|
|
|
m_sOutBufList.nSizeOfList = 0;
|
|
m_sOutBufList.nAllocSize = 0;
|
|
m_sOutBufList.nWritePos = 0;
|
|
m_sOutBufList.nReadPos = 0;
|
|
m_sOutBufList.nAllocBySelfFlags = 0;
|
|
m_sOutBufList.nSizeOfList = 0;
|
|
m_sOutBufList.nBufArrSize = m_sOutPortDefType.nBufferCountActual;
|
|
m_sOutBufList.eDir = OMX_DirOutput;
|
|
|
|
|
|
//*init the cache buffer list
|
|
memset(&m_sCacheBufList, 0x0, sizeof(BufferList));
|
|
m_sCacheBufList.pBufHdrList
|
|
= (OMX_BUFFERHEADERTYPE**)malloc(sizeof(OMX_BUFFERHEADERTYPE*) *OMX_CACHE_BUFF_NUM);
|
|
if(m_sCacheBufList.pBufHdrList == NULL)
|
|
{
|
|
eRet = OMX_ErrorInsufficientResources;
|
|
goto EXIT;
|
|
}
|
|
m_sCacheBufList.nSizeOfList = 0;
|
|
m_sCacheBufList.nAllocSize = OMX_CACHE_BUFF_NUM;
|
|
m_sCacheBufList.nWritePos = 0;
|
|
m_sCacheBufList.nReadPos = 0;
|
|
m_sCacheBufList.nAllocBySelfFlags = 0;
|
|
m_sCacheBufList.nBufArrSize = OMX_CACHE_BUFF_NUM;
|
|
m_sCacheBufList.eDir = OMX_DirOutput;
|
|
//* create a decoder.
|
|
|
|
/*
|
|
m_decoder = CreateVideoDecoder();
|
|
if(m_decoder == NULL)
|
|
{
|
|
logv(" can not create video decoder.");
|
|
eRet = OMX_ErrorInsufficientResources;
|
|
goto EXIT;
|
|
}
|
|
*/
|
|
|
|
//*set omx cts flag to flush the last frame in h264
|
|
//m_decoder->ioctrl(m_decoder, CEDARV_COMMAND_SET_OMXCTS_DECODER, 1);
|
|
|
|
// Create the component thread
|
|
err = pthread_create(&m_thread_id, NULL, ComponentThread, this);
|
|
if( err || !m_thread_id )
|
|
{
|
|
eRet = OMX_ErrorInsufficientResources;
|
|
goto EXIT;
|
|
}
|
|
|
|
// Create vdrv thread
|
|
err = pthread_create(&m_vdrv_thread_id, NULL, ComponentVdrvThread, this);
|
|
if( err || !m_vdrv_thread_id )
|
|
{
|
|
eRet = OMX_ErrorInsufficientResources;
|
|
goto EXIT;
|
|
}
|
|
|
|
err = pthread_create(&m_render_thread_id, NULL, RenderThread, this);
|
|
if( err || !m_render_thread_id )
|
|
{
|
|
eRet = OMX_ErrorInsufficientResources;
|
|
goto EXIT;
|
|
}
|
|
|
|
|
|
mDecodeFrameTotalDuration = 0;
|
|
mDecodeOKTotalDuration = 0;
|
|
mDecodeNoFrameTotalDuration = 0;
|
|
mDecodeNoBitstreamTotalDuration = 0;
|
|
mDecodeOtherTotalDuration = 0;
|
|
mDecodeFrameTotalCount = 0;
|
|
mDecodeOKTotalCount = 0;
|
|
mDecodeNoFrameTotalCount = 0;
|
|
mDecodeNoBitstreamTotalCount = 0;
|
|
mDecodeOtherTotalCount = 0;
|
|
mDecodeFrameSmallAverageDuration = 0;
|
|
mDecodeFrameBigAverageDuration = 0;
|
|
mDecodeNoFrameAverageDuration = 0;
|
|
mDecodeNoBitstreamAverageDuration = 0;
|
|
|
|
mConvertTotalDuration = 0;
|
|
mConvertTotalCount = 0;
|
|
mConvertAverageDuration = 0;
|
|
EXIT:
|
|
return eRet;
|
|
}
|
|
|
|
|
|
OMX_ERRORTYPE omx_vdec::get_component_version(OMX_IN OMX_HANDLETYPE pHComp,
|
|
OMX_OUT OMX_STRING pComponentName,
|
|
OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
|
|
OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
|
|
OMX_OUT OMX_UUIDTYPE* pComponentUUID)
|
|
{
|
|
CEDARC_UNUSE(pComponentUUID);
|
|
logv("(f:%s, l:%d) ", __FUNCTION__, __LINE__);
|
|
if (!pHComp || !pComponentName || !pComponentVersion || !pSpecVersion)
|
|
{
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
strcpy((char*)pComponentName, (char*)m_cName);
|
|
|
|
pComponentVersion->s.nVersionMajor = 1;
|
|
pComponentVersion->s.nVersionMinor = 1;
|
|
pComponentVersion->s.nRevision = 0;
|
|
pComponentVersion->s.nStep = 0;
|
|
|
|
pSpecVersion->s.nVersionMajor = 1;
|
|
pSpecVersion->s.nVersionMinor = 1;
|
|
pSpecVersion->s.nRevision = 0;
|
|
pSpecVersion->s.nStep = 0;
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
|
|
OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE pHComp,
|
|
OMX_IN OMX_COMMANDTYPE eCmd,
|
|
OMX_IN OMX_U32 uParam1,
|
|
OMX_IN OMX_PTR pCmdData)
|
|
{
|
|
CEDARC_UNUSE(pHComp);
|
|
ThrCmdType eCmdNative;
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
logv("(f:%s, l:%d) ", __FUNCTION__, __LINE__);
|
|
|
|
if(m_state == OMX_StateInvalid)
|
|
{
|
|
logd("ERROR: Send Command in Invalid State\n");
|
|
return OMX_ErrorInvalidState;
|
|
}
|
|
|
|
if (eCmd == OMX_CommandMarkBuffer && pCmdData == NULL)
|
|
{
|
|
logd("ERROR: Send OMX_CommandMarkBuffer command but pCmdData invalid.");
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
switch (eCmd)
|
|
{
|
|
case OMX_CommandStateSet:
|
|
logv(" COMPONENT_SEND_COMMAND: OMX_CommandStateSet");
|
|
eCmdNative = MAIN_THREAD_CMD_SET_STATE;
|
|
break;
|
|
|
|
case OMX_CommandFlush:
|
|
logv(" COMPONENT_SEND_COMMAND: OMX_CommandFlush");
|
|
eCmdNative = MAIN_THREAD_CMD_FLUSH;
|
|
if ((int)uParam1 > 1 && (int)uParam1 != -1)
|
|
{
|
|
logd("Error: Send OMX_CommandFlush command but uParam1 invalid.");
|
|
return OMX_ErrorBadPortIndex;
|
|
}
|
|
break;
|
|
|
|
case OMX_CommandPortDisable:
|
|
logv(" COMPONENT_SEND_COMMAND: OMX_CommandPortDisable");
|
|
eCmdNative = MAIN_THREAD_CMD_STOP_PORT;
|
|
break;
|
|
|
|
case OMX_CommandPortEnable:
|
|
logv(" COMPONENT_SEND_COMMAND: OMX_CommandPortEnable");
|
|
eCmdNative = MAIN_THREAD_CMD_RESTART_PORT;
|
|
break;
|
|
|
|
case OMX_CommandMarkBuffer:
|
|
logv(" COMPONENT_SEND_COMMAND: OMX_CommandMarkBuffer");
|
|
eCmdNative = MAIN_THREAD_CMD_MARK_BUF;
|
|
if (uParam1 > 0)
|
|
{
|
|
logd("Error: Send OMX_CommandMarkBuffer command but uParam1 invalid.");
|
|
return OMX_ErrorBadPortIndex;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
logw("(f:%s, l:%d) ignore other command[0x%x]", __FUNCTION__, __LINE__, eCmd);
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
msg.messageId = eCmdNative;
|
|
msg.params[0] = (uintptr_t)uParam1;
|
|
|
|
CdcMessageQueuePostMessage(mqMainThread, &msg);
|
|
|
|
return eError;
|
|
}
|
|
|
|
|
|
OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE pHComp,
|
|
OMX_IN OMX_INDEXTYPE eParamIndex,
|
|
OMX_INOUT OMX_PTR pParamData)
|
|
{
|
|
CEDARC_UNUSE(pHComp);
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
|
|
logi("(f:%s, l:%d) eParamIndex = 0x%x", __FUNCTION__, __LINE__, eParamIndex);
|
|
if(m_state == OMX_StateInvalid)
|
|
{
|
|
logv("Get Param in Invalid State\n");
|
|
return OMX_ErrorInvalidState;
|
|
}
|
|
|
|
if(pParamData == NULL)
|
|
{
|
|
logv("Get Param in Invalid pParamData \n");
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
switch(eParamIndex)
|
|
{
|
|
case OMX_IndexParamVideoInit:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamVideoInit");
|
|
memcpy(pParamData, &m_sPortParam, sizeof(OMX_PORT_PARAM_TYPE));
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamPortDefinition:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamPortDefinition");
|
|
if (((OMX_PARAM_PORTDEFINITIONTYPE *)(pParamData))->nPortIndex
|
|
== m_sInPortDefType.nPortIndex)
|
|
{
|
|
memcpy(pParamData, &m_sInPortDefType, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
|
|
logv(" get_OMX_IndexParamPortDefinition: m_sInPortDefType.nPortIndex[%d]",
|
|
(int)m_sInPortDefType.nPortIndex);
|
|
}
|
|
else if (((OMX_PARAM_PORTDEFINITIONTYPE*)(pParamData))->nPortIndex
|
|
== m_sOutPortDefType.nPortIndex)
|
|
{
|
|
memcpy(pParamData, &m_sOutPortDefType, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
|
|
logv("(omx_vdec, f:%s, l:%d) OMX_IndexParamPortDefinition, width = %d, \
|
|
height = %d, align = %d, nPortIndex[%d], nBufferCountActual[%d], \
|
|
nBufferCountMin[%d], nBufferSize[%d]", __FUNCTION__, __LINE__,
|
|
(int)m_sOutPortDefType.format.video.nFrameWidth,
|
|
(int)m_sOutPortDefType.format.video.nFrameHeight,
|
|
(int)m_sOutPortDefType.nBufferAlignment,
|
|
(int)m_sOutPortDefType.nPortIndex,
|
|
(int)m_sOutPortDefType.nBufferCountActual,
|
|
(int)m_sOutPortDefType.nBufferCountMin, (int)m_sOutPortDefType.nBufferSize);
|
|
#ifdef CONF_OMX_ENABLE_ALIGN
|
|
if (m_sOutPortDefType.format.video.nFrameWidth != m_sInPortDefType.format.video.nFrameWidth) {
|
|
((OMX_PARAM_PORTDEFINITIONTYPE*)(pParamData))->format.video.nFrameWidth = m_sInPortDefType.format.video.nFrameWidth ;
|
|
}
|
|
if (m_sOutPortDefType.format.video.nFrameHeight != m_sInPortDefType.format.video.nFrameHeight) {
|
|
((OMX_PARAM_PORTDEFINITIONTYPE*)(pParamData))->format.video.nFrameHeight = m_sInPortDefType.format.video.nFrameHeight ;
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
eError = OMX_ErrorBadPortIndex;
|
|
logw(" get_OMX_IndexParamPortDefinition: error. pParamData->nPortIndex=[%d]",
|
|
(int)((OMX_PARAM_PORTDEFINITIONTYPE*)(pParamData))->nPortIndex);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamVideoPortFormat:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamVideoPortFormat");
|
|
if (((OMX_VIDEO_PARAM_PORTFORMATTYPE *)(pParamData))->nPortIndex
|
|
== m_sInPortFormatType.nPortIndex)
|
|
{
|
|
if (((OMX_VIDEO_PARAM_PORTFORMATTYPE*)(pParamData))->nIndex
|
|
> m_sInPortFormatType.nIndex)
|
|
{
|
|
eError = OMX_ErrorNoMore;
|
|
}
|
|
else
|
|
{
|
|
memcpy(pParamData, &m_sInPortFormatType,
|
|
sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
|
|
}
|
|
}
|
|
else if (((OMX_VIDEO_PARAM_PORTFORMATTYPE*)(pParamData))->nPortIndex
|
|
== m_sOutPortFormatType.nPortIndex)
|
|
{
|
|
if (((OMX_VIDEO_PARAM_PORTFORMATTYPE*)(pParamData))->nIndex
|
|
> m_sOutPortFormatType.nIndex)
|
|
{
|
|
eError = OMX_ErrorNoMore;
|
|
}
|
|
else
|
|
{
|
|
memcpy(pParamData, &m_sOutPortFormatType,
|
|
sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
|
|
}
|
|
}
|
|
else
|
|
eError = OMX_ErrorBadPortIndex;
|
|
|
|
logv("OMX_IndexParamVideoPortFormat, eError[0x%x]", eError);
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamStandardComponentRole:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamStandardComponentRole");
|
|
OMX_PARAM_COMPONENTROLETYPE* comp_role;
|
|
|
|
comp_role = (OMX_PARAM_COMPONENTROLETYPE *) pParamData;
|
|
comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
|
|
comp_role->nSize = sizeof(*comp_role);
|
|
|
|
strncpy((char*)comp_role->cRole, (const char*)m_cRole, OMX_MAX_STRINGNAME_SIZE);
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamPriorityMgmt:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamPriorityMgmt");
|
|
memcpy(pParamData, &m_sPriorityMgmtType, sizeof(OMX_PRIORITYMGMTTYPE));
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamCompBufferSupplier:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamCompBufferSupplier");
|
|
OMX_PARAM_BUFFERSUPPLIERTYPE* pBuffSupplierParam
|
|
= (OMX_PARAM_BUFFERSUPPLIERTYPE*)pParamData;
|
|
|
|
if (pBuffSupplierParam->nPortIndex == 1)
|
|
{
|
|
pBuffSupplierParam->eBufferSupplier = m_sOutBufSupplierType.eBufferSupplier;
|
|
}
|
|
else if (pBuffSupplierParam->nPortIndex == 0)
|
|
{
|
|
pBuffSupplierParam->eBufferSupplier = m_sInBufSupplierType.eBufferSupplier;
|
|
}
|
|
else
|
|
{
|
|
eError = OMX_ErrorBadPortIndex;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamAudioInit:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamAudioInit");
|
|
OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) pParamData;
|
|
|
|
audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
|
|
audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
|
|
audioPortParamType->nPorts = 0;
|
|
audioPortParamType->nStartPortNumber = 0;
|
|
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamImageInit:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamImageInit");
|
|
OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) pParamData;
|
|
|
|
imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
|
|
imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
|
|
imagePortParamType->nPorts = 0;
|
|
imagePortParamType->nStartPortNumber = 0;
|
|
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamOtherInit:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamOtherInit");
|
|
OMX_PORT_PARAM_TYPE *otherPortParamType = (OMX_PORT_PARAM_TYPE *) pParamData;
|
|
|
|
otherPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
|
|
otherPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
|
|
otherPortParamType->nPorts = 0;
|
|
otherPortParamType->nStartPortNumber = 0;
|
|
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamVideoAvc:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamVideoAvc");
|
|
logv("get_parameter: OMX_IndexParamVideoAvc, do nothing.\n");
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamVideoH263:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamVideoH263");
|
|
logv("get_parameter: OMX_IndexParamVideoH263, do nothing.\n");
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamVideoMpeg4:
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: OMX_IndexParamVideoMpeg4");
|
|
logv("get_parameter: OMX_IndexParamVideoMpeg4, do nothing.\n");
|
|
break;
|
|
}
|
|
case OMX_IndexParamVideoProfileLevelQuerySupported:
|
|
{
|
|
VIDEO_PROFILE_LEVEL_TYPE* pProfileLevel = NULL;
|
|
OMX_U32 nNumberOfProfiles = 0;
|
|
OMX_VIDEO_PARAM_PROFILELEVELTYPE *pParamProfileLevel
|
|
= (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pParamData;
|
|
|
|
pParamProfileLevel->nPortIndex = m_sInPortDefType.nPortIndex;
|
|
|
|
/* Choose table based on compression format */
|
|
switch(m_sInPortDefType.format.video.eCompressionFormat)
|
|
{
|
|
case OMX_VIDEO_CodingH263:
|
|
pProfileLevel = SupportedH263ProfileLevels;
|
|
nNumberOfProfiles
|
|
= sizeof(SupportedH263ProfileLevels) / sizeof (VIDEO_PROFILE_LEVEL_TYPE);
|
|
break;
|
|
|
|
case OMX_VIDEO_CodingMPEG4:
|
|
pProfileLevel = SupportedMPEG4ProfileLevels;
|
|
nNumberOfProfiles
|
|
= sizeof(SupportedMPEG4ProfileLevels) / sizeof (VIDEO_PROFILE_LEVEL_TYPE);
|
|
break;
|
|
|
|
case OMX_VIDEO_CodingAVC:
|
|
if (mIsFromCts == true){
|
|
pProfileLevel = CTSSupportedAVCProfileLevels;
|
|
nNumberOfProfiles
|
|
= sizeof(CTSSupportedAVCProfileLevels) / sizeof (VIDEO_PROFILE_LEVEL_TYPE);
|
|
}else{
|
|
pProfileLevel = SupportedAVCProfileLevels;
|
|
nNumberOfProfiles
|
|
= sizeof(SupportedAVCProfileLevels) / sizeof (VIDEO_PROFILE_LEVEL_TYPE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
logw("OMX_IndexParamVideoProfileLevelQuerySupported, Format[0x%x] not support",
|
|
m_sInPortDefType.format.video.eCompressionFormat);
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
if(((int)pParamProfileLevel->nProfileIndex < 0)
|
|
|| (pParamProfileLevel->nProfileIndex >= (nNumberOfProfiles - 1)))
|
|
{
|
|
logw("pParamProfileLevel->nProfileIndex[0x%x] error!",
|
|
(unsigned int)pParamProfileLevel->nProfileIndex);
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
/* Point to table entry based on uIndex */
|
|
pProfileLevel += pParamProfileLevel->nProfileIndex;
|
|
|
|
/* -1 indicates end of table */
|
|
if(pProfileLevel->nProfile != -1)
|
|
{
|
|
pParamProfileLevel->eProfile = pProfileLevel->nProfile;
|
|
pParamProfileLevel->eLevel = pProfileLevel->nLevel;
|
|
eError = OMX_ErrorNone;
|
|
}
|
|
else
|
|
{
|
|
logw("pProfileLevel->nProfile error!");
|
|
eError = OMX_ErrorNoMore;
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
if((AW_VIDEO_EXTENSIONS_INDEXTYPE)eParamIndex
|
|
== AWOMX_IndexParamVideoGetAndroidNativeBufferUsage)
|
|
{
|
|
logv(" COMPONENT_GET_PARAMETER: AWOMX_IndexParamVideoGetAndroidNativeBufferUsage");
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
logv("get_parameter: unknown param %08x\n", eParamIndex);
|
|
eError =OMX_ErrorUnsupportedIndex;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return eError;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE pHComp,
|
|
OMX_IN OMX_INDEXTYPE eParamIndex,
|
|
OMX_IN OMX_PTR pParamData)
|
|
{
|
|
CEDARC_UNUSE(pHComp);
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
|
|
logi("(f:%s, l:%d) eParamIndex = 0x%x", __FUNCTION__, __LINE__, eParamIndex);
|
|
if(m_state == OMX_StateInvalid)
|
|
{
|
|
logv("Set Param in Invalid State\n");
|
|
return OMX_ErrorInvalidState;
|
|
}
|
|
|
|
if(pParamData == NULL)
|
|
{
|
|
logv("Get Param in Invalid pParamData \n");
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
switch(eParamIndex)
|
|
{
|
|
case OMX_IndexParamPortDefinition:
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: OMX_IndexParamPortDefinition");
|
|
if (((OMX_PARAM_PORTDEFINITIONTYPE *)(pParamData))->nPortIndex
|
|
== m_sInPortDefType.nPortIndex)
|
|
{
|
|
logv("set_OMX_IndexParamPortDefinition, m_sInPortDefType.nPortIndex=%d",
|
|
(int)m_sInPortDefType.nPortIndex);
|
|
|
|
//* TODO for any new IC
|
|
OMX_PARAM_PORTDEFINITIONTYPE * para = (OMX_PARAM_PORTDEFINITIONTYPE *)pParamData;
|
|
//* now only h3 support H265 4k decode
|
|
if ((CdcGetSysinfoChipId() != SI_CHIP_H3)
|
|
&& (para->format.video.eCompressionFormat == OMX_VIDEO_CodingHEVC)
|
|
&& ((para->format.video.nFrameWidth > 1920)
|
|
|| (para->format.video.nFrameHeight > 1088)))
|
|
{
|
|
logw("ChipId: %d, H265 decode do not support over 1080p,\
|
|
but this video is %lux%lu",
|
|
CdcGetSysinfoChipId(), para->format.video.nFrameWidth,
|
|
para->format.video.nFrameHeight);
|
|
return OMX_ErrorUnsupportedSetting;
|
|
}
|
|
|
|
//* H3s/H2 do not support 4k decode
|
|
if ((CdcGetSysinfoChipId() == SI_CHIP_H3s || CdcGetSysinfoChipId() == SI_CHIP_H2)
|
|
&& ((para->format.video.nFrameWidth > 1920)
|
|
|| (para->format.video.nFrameHeight > 1088)))
|
|
{
|
|
logw("ChipId: %d, decode do not support over 1080p, but this video is %lux%lu",
|
|
CdcGetSysinfoChipId(), para->format.video.nFrameWidth,
|
|
para->format.video.nFrameHeight);
|
|
return OMX_ErrorUnsupportedSetting;
|
|
}
|
|
|
|
if(((OMX_PARAM_PORTDEFINITIONTYPE *)(pParamData))->nBufferCountActual
|
|
!= m_sInPortDefType.nBufferCountActual)
|
|
{
|
|
int nBufCnt;
|
|
int nIndex;
|
|
|
|
|
|
pthread_mutex_lock(&m_inBufMutex);
|
|
|
|
if(m_sInBufList.pBufArr != NULL)
|
|
free(m_sInBufList.pBufArr);
|
|
|
|
if(m_sInBufList.pBufHdrList != NULL)
|
|
free(m_sInBufList.pBufHdrList);
|
|
|
|
nBufCnt = ((OMX_PARAM_PORTDEFINITIONTYPE *)(pParamData))->nBufferCountActual;
|
|
logv("x allocate %d buffers.", nBufCnt);
|
|
|
|
m_sInBufList.pBufArr
|
|
= (OMX_BUFFERHEADERTYPE*)malloc(sizeof(OMX_BUFFERHEADERTYPE)* nBufCnt);
|
|
m_sInBufList.pBufHdrList
|
|
= (OMX_BUFFERHEADERTYPE**)malloc(sizeof(OMX_BUFFERHEADERTYPE*)* nBufCnt);
|
|
for (nIndex = 0; nIndex < nBufCnt; nIndex++)
|
|
{
|
|
OMX_CONF_INIT_STRUCT_PTR (&m_sInBufList.pBufArr[nIndex],
|
|
OMX_BUFFERHEADERTYPE);
|
|
}
|
|
|
|
m_sInBufList.nSizeOfList = 0;
|
|
m_sInBufList.nAllocSize = 0;
|
|
m_sInBufList.nWritePos = 0;
|
|
m_sInBufList.nReadPos = 0;
|
|
m_sInBufList.nAllocBySelfFlags = 0;
|
|
m_sInBufList.nSizeOfList = 0;
|
|
m_sInBufList.nBufArrSize = nBufCnt;
|
|
m_sInBufList.eDir = OMX_DirInput;
|
|
|
|
pthread_mutex_unlock(&m_inBufMutex);
|
|
}
|
|
|
|
memcpy(&m_sInPortDefType, pParamData, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
|
|
|
|
m_streamInfo.nWidth = m_sInPortDefType.format.video.nFrameWidth;
|
|
m_streamInfo.nHeight = m_sInPortDefType.format.video.nFrameHeight;
|
|
|
|
// the folllowing values are not right,
|
|
// we should get offset in first time getVideoPicture
|
|
mVideoRect.nTop = 0;
|
|
mVideoRect.nLeft = 0;
|
|
mVideoRect.nWidth = m_sInPortDefType.format.video.nFrameWidth;
|
|
mVideoRect.nHeight = m_sInPortDefType.format.video.nFrameHeight;
|
|
|
|
// init vdecoder here
|
|
if(mIsCyber)
|
|
{
|
|
//*if mdecoder had closed before, we should create it
|
|
if(m_decoder==NULL)
|
|
{
|
|
//AddVDPlugin();
|
|
m_decoder = CreateVideoDecoder();
|
|
}
|
|
|
|
//* set video stream info.
|
|
VConfig m_videoConfig;
|
|
memset(&m_videoConfig,0,sizeof(VConfig));
|
|
|
|
//*set yv12
|
|
m_videoConfig.eOutputPixelFormat = PIXEL_FORMAT_YV12;
|
|
|
|
m_videoConfig.memops = MemAdapterGetOpsS();
|
|
//* palloc fbm in InitializeVideoDecode,
|
|
// shorten the time of first frame decoding
|
|
m_videoConfig.bSupportPallocBufBeforeDecode = 1;
|
|
m_streamInfo.nWidth = m_sInPortDefType.format.video.nFrameWidth;
|
|
m_streamInfo.nHeight = m_sInPortDefType.format.video.nFrameHeight;
|
|
logd("input w: %d, m_streamInfo.nHeight: %d",
|
|
m_streamInfo.nWidth, m_streamInfo.nHeight);
|
|
|
|
//FIXME :m_useAndroidBuffer not set in this time
|
|
//if(m_useAndroidBuffer)
|
|
{
|
|
m_videoConfig.nAlignStride = mGpuAlignStride;
|
|
}
|
|
|
|
// omx decoder make out buffer no more than 1920x1080
|
|
if (m_streamInfo.nWidth > 1920
|
|
&& m_streamInfo.nHeight > 1088)
|
|
{
|
|
m_videoConfig.bScaleDownEn = 1;
|
|
m_videoConfig.nHorizonScaleDownRatio = 1;
|
|
m_videoConfig.nVerticalScaleDownRatio = 1;
|
|
}
|
|
|
|
if(m_streamInfo.eCodecFormat == VIDEO_CODEC_FORMAT_WMV3
|
|
|| m_streamInfo.eCodecFormat == VIDEO_CODEC_FORMAT_H264)
|
|
{
|
|
logd("*** pSelf->m_streamInfo.bIsFramePackage to 1 when it is vc1");
|
|
m_streamInfo.bIsFramePackage = 1;
|
|
}
|
|
|
|
// display error frame for cyber
|
|
m_videoConfig.bDispErrorFrame = 1;
|
|
logd("++++++++ m_videoConfig.bDispErrorFrame: %d",
|
|
m_videoConfig.bDispErrorFrame);
|
|
//*not use deinterlace
|
|
m_videoConfig.nDeInterlaceHoldingFrameBufferNum = 0;
|
|
//*gpu and decoder not share buffer
|
|
m_videoConfig.nDisplayHoldingFrameBufferNum = 0;
|
|
m_videoConfig.nRotateHoldingFrameBufferNum
|
|
= NUM_OF_PICTURES_KEEPPED_BY_ROTATE;
|
|
m_videoConfig.nDecodeSmoothFrameBufferNum
|
|
= NUM_OF_PICTURES_FOR_EXTRA_SMOOTH;
|
|
|
|
if(InitializeVideoDecoder(m_decoder, &(m_streamInfo),&m_videoConfig) != 0)
|
|
{
|
|
DestroyVideoDecoder(m_decoder);
|
|
m_decoder = NULL;
|
|
loge("Idle transition failed, set_vstream_info() return fail.\n");
|
|
}
|
|
}
|
|
}
|
|
else if (((OMX_PARAM_PORTDEFINITIONTYPE *)(pParamData))->nPortIndex
|
|
== m_sOutPortDefType.nPortIndex)
|
|
{
|
|
logv("set_OMX_IndexParamPortDefinition, m_sOutPortDefType.nPortIndex=%d",
|
|
(int)m_sOutPortDefType.nPortIndex);
|
|
if(((OMX_PARAM_PORTDEFINITIONTYPE *)(pParamData))->nBufferCountActual
|
|
!= m_sOutPortDefType.nBufferCountActual)
|
|
{
|
|
int nBufCnt;
|
|
int nIndex;
|
|
|
|
pthread_mutex_lock(&m_outBufMutex);
|
|
|
|
if(m_sOutBufList.pBufArr != NULL)
|
|
free(m_sOutBufList.pBufArr);
|
|
|
|
if(m_sOutBufList.pBufHdrList != NULL)
|
|
free(m_sOutBufList.pBufHdrList);
|
|
|
|
nBufCnt = ((OMX_PARAM_PORTDEFINITIONTYPE *)(pParamData))->nBufferCountActual;
|
|
logv("x allocate %d buffers.", nBufCnt);
|
|
|
|
//*Initialize the output buffer list
|
|
m_sOutBufList.pBufArr
|
|
= (OMX_BUFFERHEADERTYPE*) malloc(sizeof(OMX_BUFFERHEADERTYPE) * nBufCnt);
|
|
m_sOutBufList.pBufHdrList
|
|
= (OMX_BUFFERHEADERTYPE**) malloc(sizeof(OMX_BUFFERHEADERTYPE*) * nBufCnt);
|
|
for (nIndex = 0; nIndex < nBufCnt; nIndex++)
|
|
{
|
|
OMX_CONF_INIT_STRUCT_PTR (&m_sOutBufList.pBufArr[nIndex],
|
|
OMX_BUFFERHEADERTYPE);
|
|
}
|
|
|
|
m_sOutBufList.nSizeOfList = 0;
|
|
m_sOutBufList.nAllocSize = 0;
|
|
m_sOutBufList.nWritePos = 0;
|
|
m_sOutBufList.nReadPos = 0;
|
|
m_sOutBufList.nAllocBySelfFlags = 0;
|
|
m_sOutBufList.nSizeOfList = 0;
|
|
m_sOutBufList.nBufArrSize = nBufCnt;
|
|
m_sOutBufList.eDir = OMX_DirOutput;
|
|
|
|
m_sCacheBufList.nSizeOfList = 0;
|
|
m_sCacheBufList.nAllocSize = OMX_CACHE_BUFF_NUM;
|
|
m_sCacheBufList.nWritePos = 0;
|
|
m_sCacheBufList.nReadPos = 0;
|
|
m_sCacheBufList.nAllocBySelfFlags = 0;
|
|
m_sCacheBufList.nBufArrSize = OMX_CACHE_BUFF_NUM;
|
|
m_sCacheBufList.eDir = OMX_DirOutput;
|
|
|
|
|
|
//* compute the extra outbuffer num needed by nativeWindow
|
|
if(mExtraOutBufferNum == 0)
|
|
{
|
|
mExtraOutBufferNum
|
|
= ((OMX_PARAM_PORTDEFINITIONTYPE*)(pParamData))->nBufferCountActual - \
|
|
m_sOutPortDefType.nBufferCountActual;
|
|
|
|
if(mExtraOutBufferNum < 0)
|
|
{
|
|
loge("error: mExtraOutBufferNum is %ld, modify it to 4\n", mExtraOutBufferNum);
|
|
mExtraOutBufferNum = DISPLAY_HOLH_BUFFER_NUM_DEFAULT;
|
|
}
|
|
}
|
|
logv("gqy===mExtraOutBufferNum = %d", (int)mExtraOutBufferNum);
|
|
pthread_mutex_unlock(&m_outBufMutex);
|
|
}
|
|
|
|
//* we post the sem if ComponentVdrvThread wait for m_semExtraOutBufferNum
|
|
if(mExtraOutBufferNum != 0)
|
|
{
|
|
tryPostSem(&m_semExtraOutBufferNum);
|
|
}
|
|
|
|
memcpy(&m_sOutPortDefType, pParamData, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
|
|
|
|
// set video width and height to 32 align
|
|
if(mIsCyber)
|
|
{
|
|
m_sOutPortDefType.format.video.nFrameWidth
|
|
= (m_sOutPortDefType.format.video.nFrameWidth+31) & ~31;
|
|
m_sOutPortDefType.format.video.nFrameHeight
|
|
= (m_sOutPortDefType.format.video.nFrameHeight+31) & ~31;
|
|
}
|
|
|
|
//check some key parameter
|
|
OMX_U32 buffer_size = (m_sOutPortDefType.format.video.nFrameWidth *
|
|
m_sOutPortDefType.format.video.nFrameHeight) * 3 / 2;
|
|
if(buffer_size != m_sOutPortDefType.nBufferSize)
|
|
{
|
|
logw("set_parameter, OMX_IndexParamPortDefinition, OutPortDef : change \
|
|
nBufferSize[%d] to [%d] to suit frame width[%d] and height[%d]",
|
|
(int)m_sOutPortDefType.nBufferSize, (int)buffer_size,
|
|
(int)m_sOutPortDefType.format.video.nFrameWidth,
|
|
(int)m_sOutPortDefType.format.video.nFrameHeight);
|
|
m_sOutPortDefType.nBufferSize = buffer_size;
|
|
}
|
|
|
|
logv("(omx_vdec, f:%s, l:%d) OMX_IndexParamPortDefinition, width = %d, \
|
|
height = %d, nPortIndex[%d], nBufferCountActual[%d], nBufferCountMin[%d], \
|
|
nBufferSize[%d]", __FUNCTION__, __LINE__,
|
|
(int)m_sOutPortDefType.format.video.nFrameWidth,
|
|
(int)m_sOutPortDefType.format.video.nFrameHeight,
|
|
(int)m_sOutPortDefType.nPortIndex,
|
|
(int)m_sOutPortDefType.nBufferCountActual,
|
|
(int)m_sOutPortDefType.nBufferCountMin, (int)m_sOutPortDefType.nBufferSize);
|
|
}
|
|
else
|
|
{
|
|
logw("set_OMX_IndexParamPortDefinition, error, paramPortIndex=%d",
|
|
(int)((OMX_PARAM_PORTDEFINITIONTYPE *)(pParamData))->nPortIndex);
|
|
eError = OMX_ErrorBadPortIndex;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamVideoPortFormat:
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: OMX_IndexParamVideoPortFormat");
|
|
|
|
if (((OMX_VIDEO_PARAM_PORTFORMATTYPE *)(pParamData))->nPortIndex
|
|
== m_sInPortFormatType.nPortIndex)
|
|
{
|
|
if (((OMX_VIDEO_PARAM_PORTFORMATTYPE *)(pParamData))->nIndex
|
|
> m_sInPortFormatType.nIndex)
|
|
{
|
|
eError = OMX_ErrorNoMore;
|
|
}
|
|
else
|
|
{
|
|
memcpy(&m_sInPortFormatType, pParamData,
|
|
sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
|
|
}
|
|
}
|
|
else if (((OMX_VIDEO_PARAM_PORTFORMATTYPE*)(pParamData))->nPortIndex
|
|
== m_sOutPortFormatType.nPortIndex)
|
|
{
|
|
if (((OMX_VIDEO_PARAM_PORTFORMATTYPE*)(pParamData))->nIndex
|
|
> m_sOutPortFormatType.nIndex)
|
|
{
|
|
eError = OMX_ErrorNoMore;
|
|
}
|
|
else
|
|
{
|
|
memcpy(&m_sOutPortFormatType, pParamData,
|
|
sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
|
|
}
|
|
}
|
|
else
|
|
eError = OMX_ErrorBadPortIndex;
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamStandardComponentRole:
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: OMX_IndexParamStandardComponentRole");
|
|
OMX_PARAM_COMPONENTROLETYPE *comp_role;
|
|
comp_role = (OMX_PARAM_COMPONENTROLETYPE *) pParamData;
|
|
logv("set_parameter: OMX_IndexParamStandardComponentRole %s\n", comp_role->cRole);
|
|
|
|
if((m_state == OMX_StateLoaded)
|
|
/* && !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)*/)
|
|
{
|
|
logv("Set Parameter called in valid state");
|
|
}
|
|
else
|
|
{
|
|
logv("Set Parameter called in Invalid State\n");
|
|
return OMX_ErrorIncorrectStateOperation;
|
|
}
|
|
|
|
if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.mjpeg",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.mjpeg",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.mjpeg",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.mpeg1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((char*)comp_role->cRole, "video_decoder.mpeg1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.mpeg1", OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.mpeg2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((char*)comp_role->cRole, "video_decoder.mpeg2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.mpeg4",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError = OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.msmpeg4v1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.msmpeg4v1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.msmpeg4v1",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError = OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.msmpeg4v2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.msmpeg4v2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.msmpeg4v2",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError = OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.msmpeg4v3",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.msmpeg4v3",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.msmpeg4v3",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError = OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.divx4",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx4",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.divx4",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError = OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
#if 0
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.rx",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.rx",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.rx",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError = OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
#endif
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.avs",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.avs",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.avs",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError = OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.divx",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError = OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.xvid",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.xvid",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.xvid",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError = OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.h263",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.h263", OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.s263",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.s263",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.s263", OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.rxg2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.rxg2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.rxg2", OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.wmv1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.wmv1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.wmv1",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.wmv2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.wmv2",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.wmv2",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.vc1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.vp6",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((char*)comp_role->cRole, "video_decoder.vp6",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.vp6", OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.vp8",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((char*)comp_role->cRole, "video_decoder.vp8",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.vp9",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((char*)comp_role->cRole, "video_decoder.vp9",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.avc",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((char*)comp_role->cRole, "video_decoder.avc",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.avc", OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.hevc",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if(!strncmp((const char*)comp_role->cRole,"video_decoder.hevc",
|
|
OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
strncpy((char*)m_cRole,"video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown Index %s\n", comp_role->cRole);
|
|
eError =OMX_ErrorUnsupportedSetting;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
logv("Setparameter: unknown param %s\n", m_cName);
|
|
eError = OMX_ErrorInvalidComponentName;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamPriorityMgmt:
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: OMX_IndexParamPriorityMgmt");
|
|
if(m_state != OMX_StateLoaded)
|
|
{
|
|
logv("Set Parameter called in Invalid State\n");
|
|
return OMX_ErrorIncorrectStateOperation;
|
|
}
|
|
|
|
OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) pParamData;
|
|
|
|
m_sPriorityMgmtType.nGroupID = priorityMgmtype->nGroupID;
|
|
m_sPriorityMgmtType.nGroupPriority = priorityMgmtype->nGroupPriority;
|
|
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamCompBufferSupplier:
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: OMX_IndexParamCompBufferSupplier");
|
|
OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType
|
|
= (OMX_PARAM_BUFFERSUPPLIERTYPE*) pParamData;
|
|
|
|
logv("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
|
|
bufferSupplierType->eBufferSupplier);
|
|
if(bufferSupplierType->nPortIndex == 0)
|
|
m_sInBufSupplierType.eBufferSupplier = bufferSupplierType->eBufferSupplier;
|
|
else if(bufferSupplierType->nPortIndex == 1)
|
|
m_sOutBufSupplierType.eBufferSupplier = bufferSupplierType->eBufferSupplier;
|
|
else
|
|
eError = OMX_ErrorBadPortIndex;
|
|
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamVideoAvc:
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: OMX_IndexParamVideoAvc");
|
|
logv("set_parameter: OMX_IndexParamVideoAvc, do nothing.\n");
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamVideoH263:
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: OMX_IndexParamVideoH263");
|
|
logv("set_parameter: OMX_IndexParamVideoH263, do nothing.\n");
|
|
break;
|
|
}
|
|
|
|
case OMX_IndexParamVideoMpeg4:
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: OMX_IndexParamVideoMpeg4");
|
|
logv("set_parameter: OMX_IndexParamVideoMpeg4, do nothing.\n");
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
#ifdef __ANDROID__
|
|
if((AW_VIDEO_EXTENSIONS_INDEXTYPE)eParamIndex
|
|
== AWOMX_IndexParamVideoUseAndroidNativeBuffer2)
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: AWOMX_IndexParamVideoUseAndroidNativeBuffer2");
|
|
logv("set_parameter: AWOMX_IndexParamVideoUseAndroidNativeBuffer2, do nothing.\n");
|
|
m_useAndroidBuffer = OMX_TRUE;
|
|
break;
|
|
}
|
|
else if((AW_VIDEO_EXTENSIONS_INDEXTYPE)eParamIndex
|
|
== AWOMX_IndexParamVideoEnableAndroidNativeBuffers)
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: AWOMX_IndexParamVideoEnableAndroidNativeBuffers");
|
|
logv("set_parameter: AWOMX_IndexParamVideoEnableAndroidNativeBuffers,\
|
|
set m_useAndroidBuffer to OMX_TRUE\n");
|
|
|
|
EnableAndroidNativeBuffersParams *EnableAndroidBufferParams
|
|
= (EnableAndroidNativeBuffersParams*) pParamData;
|
|
logv(" enbleParam = %d\n",EnableAndroidBufferParams->enable);
|
|
if(1==EnableAndroidBufferParams->enable)
|
|
{
|
|
m_useAndroidBuffer = OMX_TRUE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
//* not perfectly support the meta data, so forbid it.
|
|
#if 0
|
|
else if((AW_VIDEO_EXTENSIONS_INDEXTYPE)eParamIndex
|
|
== AWOMX_IndexParamVideoUseStoreMetaDataInBuffer)
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: AWOMX_IndexParamVideoUseStoreMetaDataInBuffer");
|
|
|
|
StoreMetaDataInBuffersParams *pStoreMetaData
|
|
= (StoreMetaDataInBuffersParams*)pParamData;
|
|
if(pStoreMetaData->nPortIndex != 1)
|
|
{
|
|
logd("error: not support set AWOMX_IndexParamVideoUseStoreMetaDataInBuffer \
|
|
for inputPort");
|
|
eError = OMX_ErrorUnsupportedIndex;
|
|
}
|
|
if(pStoreMetaData->nPortIndex==1 && pStoreMetaData->bStoreMetaData==OMX_TRUE)
|
|
{
|
|
logv("***set m_storeOutputMetaDataFlag to TRUE");
|
|
m_storeOutputMetaDataFlag = OMX_TRUE;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONF_KITKAT_AND_NEWER
|
|
else if((AW_VIDEO_EXTENSIONS_INDEXTYPE)eParamIndex
|
|
==AWOMX_IndexParamVideoUsePrepareForAdaptivePlayback)
|
|
{
|
|
logv(" COMPONENT_SET_PARAMETER: \
|
|
AWOMX_IndexParamVideoUsePrepareForAdaptivePlayback");
|
|
|
|
PrepareForAdaptivePlaybackParams *pPlaybackParams;
|
|
pPlaybackParams = (PrepareForAdaptivePlaybackParams *)pParamData;
|
|
|
|
if(pPlaybackParams->nPortIndex==1 && pPlaybackParams->bEnable==OMX_TRUE)
|
|
{
|
|
logv("set adaptive playback ,maxWidth = %d, maxHeight = %d",
|
|
(int)pPlaybackParams->nMaxFrameWidth,
|
|
(int)pPlaybackParams->nMaxFrameHeight);
|
|
|
|
m_maxWidth = pPlaybackParams->nMaxFrameWidth;
|
|
m_maxHeight = pPlaybackParams->nMaxFrameHeight;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
else
|
|
{
|
|
logv("Setparameter: unknown param %d\n", eParamIndex);
|
|
eError = OMX_ErrorUnsupportedIndex;
|
|
break;
|
|
}
|
|
#else
|
|
logv("Setparameter: unknown param %d\n", eParamIndex);
|
|
eError = OMX_ErrorUnsupportedIndex;
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
return eError;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE pHComp,
|
|
OMX_IN OMX_INDEXTYPE eConfigIndex,
|
|
OMX_INOUT OMX_PTR pConfigData)
|
|
{
|
|
CEDARC_UNUSE(pHComp);
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
|
|
logv("(f:%s, l:%d) uIndex = %d", __FUNCTION__, __LINE__, eConfigIndex);
|
|
if (m_state == OMX_StateInvalid)
|
|
{
|
|
logv("get_config in Invalid State\n");
|
|
return OMX_ErrorInvalidState;
|
|
}
|
|
|
|
switch (eConfigIndex)
|
|
{
|
|
case OMX_IndexConfigCommonOutputCrop:
|
|
{
|
|
if(!mCropEnable)
|
|
{
|
|
logv("get_config: unknown param %d\n",eConfigIndex);
|
|
eError = OMX_ErrorUnsupportedIndex;
|
|
break;
|
|
}
|
|
OMX_CONFIG_RECTTYPE *pRect = (OMX_CONFIG_RECTTYPE *)pConfigData;
|
|
|
|
logw("+++++ get display crop: top[%d],left[%d],width[%d],height[%d]",
|
|
(int)mVideoRect.nTop,(int)mVideoRect.nLeft,
|
|
(int)mVideoRect.nWidth,(int)mVideoRect.nHeight);
|
|
|
|
OMX_CONFIG_RECTTYPE mCallbackVideoRect;
|
|
memcpy(&mCallbackVideoRect, &mVideoRect, sizeof(OMX_CONFIG_RECTTYPE));
|
|
|
|
//* on GPU_IMG, gpu will display (1*Height and 1*widht ) invaild data more.
|
|
//* we avoid it here.
|
|
#ifdef CONFIG_IMG_GPU
|
|
if(mVideoRect.nTop != 0)
|
|
{
|
|
mCallbackVideoRect.nTop = mVideoRect.nTop + 1;
|
|
mCallbackVideoRect.nHeight = mVideoRect.nHeight - 1;
|
|
}
|
|
|
|
if(mVideoRect.nLeft != 0)
|
|
{
|
|
mCallbackVideoRect.nLeft = mVideoRect.nLeft + 1;
|
|
mCallbackVideoRect.nWidth = mVideoRect.nWidth - 1;
|
|
}
|
|
#endif
|
|
|
|
if(mCallbackVideoRect.nWidth != 0 && mCallbackVideoRect.nHeight != 0)
|
|
{
|
|
memcpy(pRect,&mCallbackVideoRect,sizeof(OMX_CONFIG_RECTTYPE));
|
|
}
|
|
else
|
|
{
|
|
logw("the crop is invalid!");
|
|
eError = OMX_ErrorUnsupportedIndex;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
logv("get_config: unknown param %d\n",eConfigIndex);
|
|
eError = OMX_ErrorUnsupportedIndex;
|
|
}
|
|
}
|
|
|
|
return eError;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE pHComp,
|
|
OMX_IN OMX_INDEXTYPE eConfigIndex,
|
|
OMX_IN OMX_PTR pConfigData)
|
|
{
|
|
CEDARC_UNUSE(pHComp);
|
|
CEDARC_UNUSE(pConfigData);
|
|
logv("(f:%s, l:%d) uIndex = %d", __FUNCTION__, __LINE__, eConfigIndex);
|
|
|
|
if(m_state == OMX_StateInvalid)
|
|
{
|
|
logv("set_config in Invalid State\n");
|
|
return OMX_ErrorInvalidState;
|
|
}
|
|
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
|
|
if (m_state == OMX_StateExecuting)
|
|
{
|
|
logv("set_config: Ignore in Executing state\n");
|
|
return eError;
|
|
}
|
|
|
|
switch(eConfigIndex)
|
|
{
|
|
default:
|
|
{
|
|
eError = OMX_ErrorUnsupportedIndex;
|
|
}
|
|
}
|
|
|
|
return eError;
|
|
}
|
|
|
|
|
|
OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE pHComp,
|
|
OMX_IN OMX_STRING pParamName,
|
|
OMX_OUT OMX_INDEXTYPE* pIndexType)
|
|
{
|
|
unsigned int nIndex;
|
|
OMX_ERRORTYPE eError = OMX_ErrorUndefined;
|
|
|
|
logv("(f:%s, l:%d) param name = %s", __FUNCTION__, __LINE__, pParamName);
|
|
if(m_state == OMX_StateInvalid)
|
|
{
|
|
logv("Get Extension uIndex in Invalid State\n");
|
|
return OMX_ErrorInvalidState;
|
|
}
|
|
|
|
if(pHComp == NULL)
|
|
return OMX_ErrorBadParameter;
|
|
|
|
for(nIndex = 0; nIndex < sizeof(sVideoDecCustomParams)/sizeof(VIDDEC_CUSTOM_PARAM); nIndex++)
|
|
{
|
|
if(strcmp((char *)pParamName, (char *)&(sVideoDecCustomParams[nIndex].cCustomParamName))
|
|
== 0)
|
|
{
|
|
*pIndexType = sVideoDecCustomParams[nIndex].nCustomParamIndex;
|
|
eError = OMX_ErrorNone;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return eError;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE pHComp, OMX_OUT OMX_STATETYPE* pState)
|
|
{
|
|
CEDARC_UNUSE(pHComp);
|
|
logv("(f:%s, l:%d) ", __FUNCTION__, __LINE__);
|
|
|
|
if(pHComp == NULL || pState == NULL)
|
|
return OMX_ErrorBadParameter;
|
|
|
|
*pState = m_state;
|
|
logv("COMPONENT_GET_STATE, state[0x%x]", m_state);
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE pHComp,
|
|
OMX_IN OMX_U32 uPort,
|
|
OMX_IN OMX_HANDLETYPE pPeerComponent,
|
|
OMX_IN OMX_U32 uPeerPort,
|
|
OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup)
|
|
{
|
|
CEDARC_UNUSE(pHComp);
|
|
CEDARC_UNUSE(uPort);
|
|
CEDARC_UNUSE(pPeerComponent);
|
|
CEDARC_UNUSE(uPeerPort);
|
|
CEDARC_UNUSE(pTunnelSetup);
|
|
logi(" COMPONENT_TUNNEL_REQUEST");
|
|
|
|
logw("Error: component_tunnel_request Not Implemented\n");
|
|
return OMX_ErrorNotImplemented;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::use_buffer(OMX_IN OMX_HANDLETYPE pHComponent,
|
|
OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
|
|
OMX_IN OMX_U32 nPortIndex,
|
|
OMX_IN OMX_PTR pAppPrivate,
|
|
OMX_IN OMX_U32 nSizeBytes,
|
|
OMX_IN OMX_U8* pBuffer)
|
|
{
|
|
OMX_PARAM_PORTDEFINITIONTYPE* pPortDef;
|
|
OMX_U32 nIndex = 0x0;
|
|
|
|
logv("(f:%s, l:%d) PortIndex[%d], nSizeBytes[%d], pBuffer[%p]",
|
|
__FUNCTION__, __LINE__, (int)nPortIndex, (int)nSizeBytes, pBuffer);
|
|
if(pHComponent == NULL || ppBufferHdr == NULL || pBuffer == NULL)
|
|
{
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
if (nPortIndex == m_sInPortDefType.nPortIndex)
|
|
pPortDef = &m_sInPortDefType;
|
|
else if (nPortIndex == m_sOutPortDefType.nPortIndex)
|
|
pPortDef = &m_sOutPortDefType;
|
|
else
|
|
return OMX_ErrorBadParameter;
|
|
|
|
if (m_state!=OMX_StateLoaded
|
|
&& m_state!=OMX_StateWaitForResources
|
|
&& pPortDef->bEnabled!=OMX_FALSE)
|
|
{
|
|
logw("pPortDef[%d]->bEnabled=%d, m_state=0x%x, Can't use_buffer!",
|
|
(int)nPortIndex, pPortDef->bEnabled, m_state);
|
|
return OMX_ErrorIncorrectStateOperation;
|
|
}
|
|
logv("pPortDef[%d]->bEnabled=%d, m_state=0x%x, can use_buffer.",
|
|
(int)nPortIndex, pPortDef->bEnabled, m_state);
|
|
|
|
if(pPortDef->bPopulated)
|
|
return OMX_ErrorBadParameter;
|
|
|
|
// Find an empty position in the BufferList and allocate memory for the buffer header.
|
|
// Use the buffer passed by the client to initialize the actual buffer
|
|
// inside the buffer header.
|
|
if (nPortIndex == m_sInPortDefType.nPortIndex)
|
|
{
|
|
if (nSizeBytes != pPortDef->nBufferSize)
|
|
return OMX_ErrorBadParameter;
|
|
|
|
logv("use_buffer, m_sInPortDefType.nPortIndex=[%d]", (int)m_sInPortDefType.nPortIndex);
|
|
pthread_mutex_lock(&m_inBufMutex);
|
|
|
|
if((OMX_S32)m_sInBufList.nAllocSize >= m_sInBufList.nBufArrSize)
|
|
{
|
|
pthread_mutex_unlock(&m_inBufMutex);
|
|
return OMX_ErrorInsufficientResources;
|
|
}
|
|
|
|
nIndex = m_sInBufList.nAllocSize;
|
|
m_sInBufList.nAllocSize++;
|
|
|
|
m_sInBufList.pBufArr[nIndex].pBuffer = pBuffer;
|
|
m_sInBufList.pBufArr[nIndex].nAllocLen = nSizeBytes;
|
|
m_sInBufList.pBufArr[nIndex].pAppPrivate = pAppPrivate;
|
|
m_sInBufList.pBufArr[nIndex].nInputPortIndex = nPortIndex;
|
|
m_sInBufList.pBufArr[nIndex].nOutputPortIndex = 0xFFFFFFFE;
|
|
*ppBufferHdr = &m_sInBufList.pBufArr[nIndex];
|
|
if (m_sInBufList.nAllocSize == pPortDef->nBufferCountActual)
|
|
pPortDef->bPopulated = OMX_TRUE;
|
|
|
|
pthread_mutex_unlock(&m_inBufMutex);
|
|
}
|
|
else
|
|
{
|
|
#ifdef CONF_KITKAT_AND_NEWER
|
|
if(m_storeOutputMetaDataFlag==OMX_TRUE)
|
|
{
|
|
if(nSizeBytes != sizeof(VideoDecoderOutputMetaData))
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
else
|
|
{
|
|
if(nSizeBytes != pPortDef->nBufferSize)
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
#else
|
|
if(nSizeBytes != pPortDef->nBufferSize)
|
|
return OMX_ErrorBadParameter;
|
|
#endif
|
|
|
|
logv("use_buffer, m_sOutPortDefType.nPortIndex=[%d]",
|
|
(int)m_sOutPortDefType.nPortIndex);
|
|
pthread_mutex_lock(&m_outBufMutex);
|
|
|
|
if((OMX_S32)m_sOutBufList.nAllocSize >= m_sOutBufList.nBufArrSize)
|
|
{
|
|
pthread_mutex_unlock(&m_outBufMutex);
|
|
return OMX_ErrorInsufficientResources;
|
|
}
|
|
pPortDef->nBufferSize = nSizeBytes;
|
|
nIndex = m_sOutBufList.nAllocSize;
|
|
m_sOutBufList.nAllocSize++;
|
|
|
|
m_sOutBufList.pBufArr[nIndex].pBuffer = pBuffer;
|
|
m_sOutBufList.pBufArr[nIndex].nAllocLen = nSizeBytes;
|
|
m_sOutBufList.pBufArr[nIndex].pAppPrivate = pAppPrivate;
|
|
m_sOutBufList.pBufArr[nIndex].nInputPortIndex = 0xFFFFFFFE;
|
|
m_sOutBufList.pBufArr[nIndex].nOutputPortIndex = nPortIndex;
|
|
*ppBufferHdr = &m_sOutBufList.pBufArr[nIndex];
|
|
if (m_sOutBufList.nAllocSize == pPortDef->nBufferCountActual)
|
|
pPortDef->bPopulated = OMX_TRUE;
|
|
|
|
pthread_mutex_unlock(&m_outBufMutex);
|
|
}
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE pHComponent,
|
|
OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
|
|
OMX_IN OMX_U32 nPortIndex,
|
|
OMX_IN OMX_PTR pAppPrivate,
|
|
OMX_IN OMX_U32 nSizeBytes)
|
|
{
|
|
OMX_S8 nIndex = 0x0;
|
|
OMX_PARAM_PORTDEFINITIONTYPE* pPortDef;
|
|
|
|
//logi(" COMPONENT_ALLOCATE_BUFFER");
|
|
logi("(f:%s, l:%d) nPortIndex[%d], nSizeBytes[%d]",
|
|
__FUNCTION__, __LINE__, (int)nPortIndex, (int)nSizeBytes);
|
|
if(pHComponent == NULL || ppBufferHdr == NULL)
|
|
return OMX_ErrorBadParameter;
|
|
|
|
if (nPortIndex == m_sInPortDefType.nPortIndex)
|
|
pPortDef = &m_sInPortDefType;
|
|
else
|
|
{
|
|
if (nPortIndex == m_sOutPortDefType.nPortIndex)
|
|
pPortDef = &m_sOutPortDefType;
|
|
else
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
// if (!pPortDef->bEnabled)
|
|
// return OMX_ErrorIncorrectStateOperation;
|
|
|
|
if (m_state != OMX_StateLoaded
|
|
&& m_state!=OMX_StateWaitForResources
|
|
&& pPortDef->bEnabled!=OMX_FALSE)
|
|
{
|
|
logw("pPortDef[%d]->bEnabled=%d, m_state=0x%x, Can't allocate_buffer!",
|
|
(int)nPortIndex, pPortDef->bEnabled, m_state);
|
|
return OMX_ErrorIncorrectStateOperation;
|
|
}
|
|
logv("pPortDef[%d]->bEnabled=%d, m_state=0x%x, can allocate_buffer.",
|
|
(int)nPortIndex, pPortDef->bEnabled, m_state);
|
|
|
|
if (nSizeBytes != pPortDef->nBufferSize || pPortDef->bPopulated)
|
|
return OMX_ErrorBadParameter;
|
|
|
|
// Find an empty position in the BufferList and allocate memory for the buffer header
|
|
// and the actual buffer
|
|
if (nPortIndex == m_sInPortDefType.nPortIndex)
|
|
{
|
|
logv("allocate_buffer, m_sInPortDefType.nPortIndex[%d]",
|
|
(int)m_sInPortDefType.nPortIndex);
|
|
pthread_mutex_lock(&m_inBufMutex);
|
|
|
|
if((OMX_S32)m_sInBufList.nAllocSize >= m_sInBufList.nBufArrSize)
|
|
{
|
|
pthread_mutex_unlock(&m_inBufMutex);
|
|
return OMX_ErrorInsufficientResources;
|
|
}
|
|
|
|
nIndex = m_sInBufList.nAllocSize;
|
|
|
|
m_sInBufList.pBufArr[nIndex].pBuffer = (OMX_U8*)malloc(nSizeBytes);
|
|
|
|
if (!m_sInBufList.pBufArr[nIndex].pBuffer)
|
|
{
|
|
pthread_mutex_unlock(&m_inBufMutex);
|
|
return OMX_ErrorInsufficientResources;
|
|
}
|
|
|
|
m_sInBufList.nAllocBySelfFlags |= (1<<nIndex);
|
|
|
|
m_sInBufList.pBufArr[nIndex].nAllocLen = nSizeBytes;
|
|
m_sInBufList.pBufArr[nIndex].pAppPrivate = pAppPrivate;
|
|
m_sInBufList.pBufArr[nIndex].nInputPortIndex = nPortIndex;
|
|
m_sInBufList.pBufArr[nIndex].nOutputPortIndex = 0xFFFFFFFE;
|
|
*ppBufferHdr = &m_sInBufList.pBufArr[nIndex];
|
|
|
|
m_sInBufList.nAllocSize++;
|
|
|
|
if (m_sInBufList.nAllocSize == pPortDef->nBufferCountActual)
|
|
pPortDef->bPopulated = OMX_TRUE;
|
|
|
|
pthread_mutex_unlock(&m_inBufMutex);
|
|
}
|
|
else
|
|
{
|
|
logv("allocate_buffer, m_sOutPortDefType.nPortIndex[%d]",
|
|
(int)m_sOutPortDefType.nPortIndex);
|
|
pthread_mutex_lock(&m_outBufMutex);
|
|
|
|
if((OMX_U32)m_sOutBufList.nBufArrSize != pPortDef->nBufferCountActual)
|
|
{
|
|
int nBufCnt;
|
|
int nIndex;
|
|
if(m_sOutBufList.pBufArr != NULL)
|
|
free(m_sOutBufList.pBufArr);
|
|
if(m_sOutBufList.pBufHdrList != NULL)
|
|
free(m_sOutBufList.pBufHdrList);
|
|
|
|
nBufCnt = (int)pPortDef->nBufferCountActual;
|
|
logd("x allocate %d buffers.", nBufCnt);
|
|
|
|
//*Initialize the output buffer list
|
|
m_sOutBufList.pBufArr
|
|
= (OMX_BUFFERHEADERTYPE*) malloc(sizeof(OMX_BUFFERHEADERTYPE) * nBufCnt);
|
|
m_sOutBufList.pBufHdrList
|
|
= (OMX_BUFFERHEADERTYPE**) malloc(sizeof(OMX_BUFFERHEADERTYPE*) * nBufCnt);
|
|
for (nIndex = 0; nIndex < nBufCnt; nIndex++)
|
|
{
|
|
OMX_CONF_INIT_STRUCT_PTR (&m_sOutBufList.pBufArr[nIndex],
|
|
OMX_BUFFERHEADERTYPE);
|
|
}
|
|
|
|
m_sOutBufList.nSizeOfList = 0;
|
|
m_sOutBufList.nAllocSize = 0;
|
|
m_sOutBufList.nWritePos = 0;
|
|
m_sOutBufList.nReadPos = 0;
|
|
m_sOutBufList.nAllocBySelfFlags = 0;
|
|
m_sOutBufList.nSizeOfList = 0;
|
|
m_sOutBufList.nBufArrSize = nBufCnt;
|
|
m_sOutBufList.eDir = OMX_DirOutput;
|
|
}
|
|
|
|
if((OMX_S32)m_sOutBufList.nAllocSize >= m_sOutBufList.nBufArrSize)
|
|
{
|
|
pthread_mutex_unlock(&m_outBufMutex);
|
|
return OMX_ErrorInsufficientResources;
|
|
}
|
|
|
|
nIndex = m_sOutBufList.nAllocSize;
|
|
if(bUseShareBuffer)
|
|
{
|
|
OMX_U8* pOutBuffer = (OMX_U8*)OMX_MemPalloc(memops,nSizeBytes);
|
|
m_sOutBufList.pBufArr[nIndex].pBuffer = pOutBuffer;
|
|
|
|
logv("gqy===inndex = %d, pOutBuffer = %p", nIndex, pOutBuffer);
|
|
}
|
|
else
|
|
m_sOutBufList.pBufArr[nIndex].pBuffer = (OMX_U8*)malloc(nSizeBytes);
|
|
if (!m_sOutBufList.pBufArr[nIndex].pBuffer)
|
|
{
|
|
pthread_mutex_unlock(&m_outBufMutex);
|
|
return OMX_ErrorInsufficientResources;
|
|
}
|
|
|
|
m_sOutBufList.nAllocBySelfFlags |= (1<<nIndex);
|
|
|
|
m_sOutBufList.pBufArr[nIndex].nAllocLen = nSizeBytes;
|
|
m_sOutBufList.pBufArr[nIndex].pAppPrivate = pAppPrivate;
|
|
m_sOutBufList.pBufArr[nIndex].nInputPortIndex = 0xFFFFFFFE;
|
|
m_sOutBufList.pBufArr[nIndex].nOutputPortIndex = nPortIndex;
|
|
*ppBufferHdr = &m_sOutBufList.pBufArr[nIndex];
|
|
|
|
m_sOutBufList.nAllocSize++;
|
|
|
|
if (m_sOutBufList.nAllocSize == pPortDef->nBufferCountActual)
|
|
pPortDef->bPopulated = OMX_TRUE;
|
|
|
|
pthread_mutex_unlock(&m_outBufMutex);
|
|
}
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE pHComponent,
|
|
OMX_IN OMX_U32 nPortIndex,
|
|
OMX_IN OMX_BUFFERHEADERTYPE* pBufferHdr)
|
|
{
|
|
OMX_PARAM_PORTDEFINITIONTYPE* pPortDef;
|
|
OMX_S32 nIndex;
|
|
|
|
logi("(f:%s, l:%d) nPortIndex = %d, pBufferHdr = %p, m_state=0x%x",
|
|
__FUNCTION__, __LINE__, (int)nPortIndex, pBufferHdr, m_state);
|
|
if(pHComponent == NULL || pBufferHdr == NULL)
|
|
return OMX_ErrorBadParameter;
|
|
|
|
// Match the pBufferHdr to the appropriate entry in the BufferList
|
|
// and free the allocated memory
|
|
if (nPortIndex == m_sInPortDefType.nPortIndex)
|
|
{
|
|
pPortDef = &m_sInPortDefType;
|
|
|
|
pthread_mutex_lock(&m_inBufMutex);
|
|
|
|
for(nIndex = 0; nIndex < m_sInBufList.nBufArrSize; nIndex++)
|
|
{
|
|
if(pBufferHdr == &m_sInBufList.pBufArr[nIndex])
|
|
break;
|
|
}
|
|
|
|
if(nIndex == m_sInBufList.nBufArrSize)
|
|
{
|
|
pthread_mutex_unlock(&m_inBufMutex);
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
if(m_sInBufList.nAllocBySelfFlags & (1<<nIndex))
|
|
{
|
|
free(m_sInBufList.pBufArr[nIndex].pBuffer);
|
|
m_sInBufList.pBufArr[nIndex].pBuffer = NULL;
|
|
m_sInBufList.nAllocBySelfFlags &= ~(1<<nIndex);
|
|
}
|
|
|
|
m_sInBufList.nAllocSize--;
|
|
|
|
if(m_sInBufList.nAllocSize == 0)
|
|
pPortDef->bPopulated = OMX_FALSE;
|
|
|
|
pthread_mutex_unlock(&m_inBufMutex);
|
|
}
|
|
else if (nPortIndex == m_sOutPortDefType.nPortIndex)
|
|
{
|
|
pPortDef = &m_sOutPortDefType;
|
|
|
|
pthread_mutex_lock(&m_outBufMutex);
|
|
|
|
for(nIndex = 0; nIndex < m_sOutBufList.nBufArrSize; nIndex++)
|
|
{
|
|
logv("pBufferHdr = %p, &m_sOutBufList.pBufArr[%d] = %p",
|
|
pBufferHdr, (int)nIndex, &m_sOutBufList.pBufArr[nIndex]);
|
|
if(pBufferHdr == &m_sOutBufList.pBufArr[nIndex])
|
|
break;
|
|
}
|
|
|
|
logv("uIndex = %d", (int)nIndex);
|
|
|
|
if(nIndex == m_sOutBufList.nBufArrSize)
|
|
{
|
|
pthread_mutex_unlock(&m_outBufMutex);
|
|
return OMX_ErrorBadParameter;
|
|
}
|
|
|
|
if(m_sOutBufList.nAllocBySelfFlags & (1<<nIndex))
|
|
{
|
|
if(bUseShareBuffer)
|
|
OMX_MemPfree(memops,m_sOutBufList.pBufArr[nIndex].pBuffer);
|
|
else
|
|
free(m_sOutBufList.pBufArr[nIndex].pBuffer);
|
|
m_sOutBufList.pBufArr[nIndex].pBuffer = NULL;
|
|
m_sOutBufList.nAllocBySelfFlags &= ~(1<<nIndex);
|
|
}
|
|
|
|
m_sOutBufList.nAllocSize--;
|
|
|
|
if(m_sOutBufList.nAllocSize == 0)
|
|
{
|
|
pPortDef->bPopulated = OMX_FALSE;
|
|
memset(&mOutputBufferInfo, 0,
|
|
sizeof(OMXOutputBufferInfoT)*OMX_MAX_VIDEO_BUFFER_NUM);
|
|
mNeedReSetToDecoderBufferNum = 0;
|
|
mSetToDecoderBufferNum = 0;
|
|
}
|
|
|
|
pthread_mutex_unlock(&m_outBufMutex);
|
|
}
|
|
else
|
|
return OMX_ErrorBadParameter;
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE pHComponent,
|
|
OMX_IN OMX_BUFFERHEADERTYPE* pBufferHdr)
|
|
{
|
|
mEmptyBufCnt++;
|
|
if(mEmptyBufCnt >= PRINT_FRAME_CNT)
|
|
{
|
|
logi("vdec, empty_this_buffer %d times",PRINT_FRAME_CNT);
|
|
mEmptyBufCnt = 0;
|
|
}
|
|
logv("vdec ***emptyThisBuffer: pts = %lld , videoFormat = %d",
|
|
pBufferHdr->nTimeStamp,
|
|
m_eCompressionFormat);
|
|
|
|
if(pHComponent == NULL || pBufferHdr == NULL)
|
|
return OMX_ErrorBadParameter;
|
|
|
|
if (!m_sInPortDefType.bEnabled)
|
|
return OMX_ErrorIncorrectStateOperation;
|
|
|
|
if (pBufferHdr->nInputPortIndex != 0x0 || pBufferHdr->nOutputPortIndex != OMX_NOPORT)
|
|
return OMX_ErrorBadPortIndex;
|
|
|
|
if (m_state != OMX_StateExecuting && m_state != OMX_StatePause)
|
|
return OMX_ErrorIncorrectStateOperation;
|
|
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
msg.messageId = MAIN_THREAD_CMD_EMPTY_BUF;
|
|
msg.params[0] = (uintptr_t)pBufferHdr;
|
|
|
|
CdcMessageQueuePostMessage(mqMainThread, &msg);
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE pHComponent,
|
|
OMX_IN OMX_BUFFERHEADERTYPE* pBufferHdr)
|
|
{
|
|
mFillBufCnt++;
|
|
if(mFillBufCnt >= PRINT_FRAME_CNT)
|
|
{
|
|
logi("vdec, fill_this_buffer %d times",PRINT_FRAME_CNT);
|
|
mFillBufCnt = 0;
|
|
}
|
|
logv("vdec (f:%s, l:%d) ", __FUNCTION__, __LINE__);
|
|
if(pHComponent == NULL || pBufferHdr == NULL)
|
|
return OMX_ErrorBadParameter;
|
|
|
|
if (!m_sOutPortDefType.bEnabled)
|
|
return OMX_ErrorIncorrectStateOperation;
|
|
|
|
if (pBufferHdr->nOutputPortIndex != 0x1 || pBufferHdr->nInputPortIndex != OMX_NOPORT)
|
|
return OMX_ErrorBadPortIndex;
|
|
|
|
if (m_state != OMX_StateExecuting && m_state != OMX_StatePause)
|
|
return OMX_ErrorIncorrectStateOperation;
|
|
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
msg.messageId = MAIN_THREAD_CMD_FILL_BUF;
|
|
msg.params[0] = (uintptr_t)pBufferHdr;
|
|
|
|
CdcMessageQueuePostMessage(mqMainThread, &msg);
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE pHComp,
|
|
OMX_IN OMX_CALLBACKTYPE* pCallbacks,
|
|
OMX_IN OMX_PTR pAppData)
|
|
{
|
|
logv("(f:%s, l:%d) ", __FUNCTION__, __LINE__);
|
|
|
|
if(pHComp == NULL || pCallbacks == NULL || pAppData == NULL)
|
|
return OMX_ErrorBadParameter;
|
|
memcpy(&m_Callbacks, pCallbacks, sizeof(OMX_CALLBACKTYPE));
|
|
m_pAppData = pAppData;
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE pHComp)
|
|
{
|
|
//logv(" COMPONENT_DEINIT");
|
|
CEDARC_UNUSE(pHComp);
|
|
logv("(f:%s, l:%d) ", __FUNCTION__, __LINE__);
|
|
OMX_ERRORTYPE eError = OMX_ErrorNone;
|
|
OMX_S32 nIndex = 0;
|
|
|
|
// In case the client crashes, check for nAllocSize parameter.
|
|
// If this is greater than zero, there are elements in the list that are not free'd.
|
|
// In that case, free the elements.
|
|
if (m_sInBufList.nAllocSize > 0)
|
|
{
|
|
for(nIndex=0; nIndex<m_sInBufList.nBufArrSize; nIndex++)
|
|
{
|
|
if(m_sInBufList.pBufArr[nIndex].pBuffer != NULL)
|
|
{
|
|
if(m_sInBufList.nAllocBySelfFlags & (1<<nIndex))
|
|
{
|
|
free(m_sInBufList.pBufArr[nIndex].pBuffer);
|
|
m_sInBufList.pBufArr[nIndex].pBuffer = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_sInBufList.pBufArr != NULL)
|
|
free(m_sInBufList.pBufArr);
|
|
|
|
if (m_sInBufList.pBufHdrList != NULL)
|
|
free(m_sInBufList.pBufHdrList);
|
|
|
|
memset(&m_sInBufList, 0, sizeof(struct _BufferList));
|
|
m_sInBufList.nBufArrSize = m_sInPortDefType.nBufferCountActual;
|
|
}
|
|
|
|
if (m_sOutBufList.nAllocSize > 0)
|
|
{
|
|
for(nIndex=0; nIndex<m_sOutBufList.nBufArrSize; nIndex++)
|
|
{
|
|
if(m_sOutBufList.pBufArr[nIndex].pBuffer != NULL)
|
|
{
|
|
if(m_sOutBufList.nAllocBySelfFlags & (1<<nIndex))
|
|
{
|
|
if(bUseShareBuffer)
|
|
OMX_MemPfree(memops,m_sOutBufList.pBufArr[nIndex].pBuffer);
|
|
//VideoDecoderFreeIonBuf(m_decoder, m_sOutBufList.pBufArr[nIndex].pBuffer);
|
|
else
|
|
free(m_sOutBufList.pBufArr[nIndex].pBuffer);
|
|
m_sOutBufList.pBufArr[nIndex].pBuffer = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_sOutBufList.pBufArr != NULL)
|
|
free(m_sOutBufList.pBufArr);
|
|
|
|
if (m_sOutBufList.pBufHdrList != NULL)
|
|
free(m_sOutBufList.pBufHdrList);
|
|
|
|
memset(&m_sOutBufList, 0, sizeof(struct _BufferList));
|
|
m_sOutBufList.nBufArrSize = m_sOutPortDefType.nBufferCountActual;
|
|
}
|
|
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
msg.messageId = MAIN_THREAD_CMD_STOP;
|
|
|
|
CdcMessageQueuePostMessage(mqMainThread, &msg);
|
|
|
|
tryPostSem(&m_semExtraOutBufferNum);
|
|
// Wait for thread to exit so we can get the status into "error"
|
|
pthread_join(m_render_thread_id, (void**)&eError);
|
|
pthread_join(m_vdrv_thread_id, (void**)&eError);
|
|
pthread_join(m_thread_id, (void**)&eError);
|
|
|
|
logd("(f:%s, l:%d) three threads exit!", __FUNCTION__, __LINE__);
|
|
|
|
if(m_decoder != NULL)
|
|
{
|
|
DestroyVideoDecoder(m_decoder);
|
|
m_decoder = NULL;
|
|
}
|
|
|
|
return eError;
|
|
}
|
|
|
|
|
|
OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE pHComp,
|
|
OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
|
|
OMX_IN OMX_U32 uPort,
|
|
OMX_IN OMX_PTR pAppData,
|
|
OMX_IN void* pEglImage)
|
|
{
|
|
CEDARC_UNUSE(pHComp);
|
|
CEDARC_UNUSE(ppBufferHdr);
|
|
CEDARC_UNUSE(uPort);
|
|
CEDARC_UNUSE(pAppData);
|
|
CEDARC_UNUSE(pEglImage);
|
|
logw("Error : use_EGL_image: Not Implemented \n");
|
|
return OMX_ErrorNotImplemented;
|
|
}
|
|
|
|
|
|
OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE pHComp,
|
|
OMX_OUT OMX_U8* pRole,
|
|
OMX_IN OMX_U32 uIndex)
|
|
{
|
|
CEDARC_UNUSE(pHComp);
|
|
//logv(" COMPONENT_ROLE_ENUM");
|
|
logv("(f:%s, l:%d) ", __FUNCTION__, __LINE__);
|
|
OMX_ERRORTYPE eRet = OMX_ErrorNone;
|
|
|
|
if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if((0 == uIndex) && pRole)
|
|
{
|
|
strncpy((char *)pRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE);
|
|
logv("component_role_enum: pRole %s\n", pRole);
|
|
}
|
|
else
|
|
{
|
|
eRet = OMX_ErrorNoMore;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if((0 == uIndex) && pRole)
|
|
{
|
|
strncpy((char *)pRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
|
|
logv("component_role_enum: pRole %s\n",pRole);
|
|
}
|
|
else
|
|
{
|
|
logv("\n No more roles \n");
|
|
eRet = OMX_ErrorNoMore;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if((0 == uIndex) && pRole)
|
|
{
|
|
strncpy((char *)pRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
|
|
logv("component_role_enum: pRole %s\n",pRole);
|
|
}
|
|
else
|
|
{
|
|
logv("\n No more roles \n");
|
|
eRet = OMX_ErrorNoMore;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if((0 == uIndex) && pRole)
|
|
{
|
|
strncpy((char *)pRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
|
|
logv("component_role_enum: pRole %s\n",pRole);
|
|
}
|
|
else
|
|
{
|
|
logv("\n No more roles \n");
|
|
eRet = OMX_ErrorNoMore;
|
|
}
|
|
}
|
|
else if(!strncmp((char*)m_cName, "OMX.allwinner.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE))
|
|
{
|
|
if((0 == uIndex) && pRole)
|
|
{
|
|
strncpy((char *)pRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
|
|
logv("component_role_enum: pRole %s\n",pRole);
|
|
}
|
|
else
|
|
{
|
|
logv("\n No more roles \n");
|
|
eRet = OMX_ErrorNoMore;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
logd("\nERROR:Querying pRole on Unknown Component\n");
|
|
eRet = OMX_ErrorInvalidComponentName;
|
|
}
|
|
|
|
return eRet;
|
|
}
|
|
|
|
static inline void setStateLoaded(omx_vdec* pSelf)
|
|
{
|
|
OMX_U32 nTimeout = 0x0;
|
|
if (pSelf->m_state == OMX_StateIdle || pSelf->m_state == OMX_StateWaitForResources)
|
|
{
|
|
while (1)
|
|
{
|
|
//*Transition happens only when the ports are unpopulated
|
|
if (!pSelf->m_sInPortDefType.bPopulated && !pSelf->m_sOutPortDefType.bPopulated)
|
|
{
|
|
pSelf->m_state = OMX_StateLoaded;
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandStateSet,
|
|
pSelf->m_state, NULL);
|
|
//* close decoder
|
|
//* TODO.
|
|
break;
|
|
}
|
|
else if (nTimeout++ > OMX_MAX_TIMEOUTS)
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError, OMX_ErrorInsufficientResources,
|
|
0 , NULL);
|
|
logw("Transition to loaded failed\n");
|
|
break;
|
|
}
|
|
usleep(OMX_TIMEOUT*1000);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError, OMX_ErrorIncorrectStateTransition,
|
|
0 , NULL);
|
|
}
|
|
|
|
}
|
|
static inline void setStateIdle(omx_vdec* pSelf)
|
|
{
|
|
OMX_U32 nTimeout = 0x0;
|
|
|
|
if (pSelf->m_state == OMX_StateInvalid)
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError, OMX_ErrorIncorrectStateTransition,
|
|
0 , NULL);
|
|
}
|
|
else
|
|
{
|
|
//*Return buffers if currently in pause and executing
|
|
if (pSelf->m_state == OMX_StatePause || pSelf->m_state == OMX_StateExecuting)
|
|
{
|
|
pthread_mutex_lock(&pSelf->m_inBufMutex);
|
|
|
|
while (pSelf->m_sInBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sInBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.EmptyBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sInBufList.pBufHdrList[pSelf->m_sInBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sInBufList.nReadPos >= pSelf->m_sInBufList.nBufArrSize)
|
|
pSelf->m_sInBufList.nReadPos = 0;
|
|
}
|
|
|
|
pSelf->m_sInBufList.nReadPos = 0;
|
|
pSelf->m_sInBufList.nWritePos = 0;
|
|
|
|
pthread_mutex_unlock(&pSelf->m_inBufMutex);
|
|
|
|
|
|
pthread_mutex_lock(&pSelf->m_outBufMutex);
|
|
OMX_S32 i;
|
|
for(i=0; i < OMX_MAX_VIDEO_BUFFER_NUM; i++)
|
|
{
|
|
if(pSelf->mOutBufferKeepInOmx[i] != NULL)
|
|
{
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->mOutBufferKeepInOmx[i]);
|
|
pSelf->mOutBufferKeepInOmx[i] = NULL;
|
|
}
|
|
}
|
|
|
|
while (pSelf->m_sOutBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sOutBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sOutBufList.pBufHdrList[pSelf->m_sOutBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sOutBufList.nReadPos >= pSelf->m_sOutBufList.nBufArrSize)
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
}
|
|
while (pSelf->m_sCacheBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sCacheBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sCacheBufList.pBufHdrList[pSelf->m_sCacheBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sCacheBufList.nReadPos >= pSelf->m_sCacheBufList.nBufArrSize)
|
|
pSelf->m_sCacheBufList.nReadPos = 0;
|
|
}
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
pSelf->m_sOutBufList.nWritePos = 0;
|
|
pSelf->m_sCacheBufList.nReadPos = 0;
|
|
pSelf->m_sCacheBufList.nWritePos = 0;
|
|
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
|
|
msg.messageId = RENDER_THREAD_CMD_PAUSE;
|
|
CdcMessageQueuePostMessage(pSelf->mqRenderThread, &msg);
|
|
logd("(f:%s, l:%d) wait for pause render ", __FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_render_cmd_lock, -1);
|
|
logd("(f:%s, l:%d) wait for pause render done!", __FUNCTION__, __LINE__);
|
|
|
|
msg.messageId = VDRV_THREAD_CMD_CLOSE_VDECODER;
|
|
CdcMessageQueuePostMessage(pSelf->mqVdrvThread, &msg);
|
|
sem_post(&pSelf->m_sem_vbs_input);
|
|
sem_post(&pSelf->m_sem_frame_output);
|
|
logd("(f:%s, l:%d) wait for VDRV_THREAD_CMD_CLOSE_VDECODER", __FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_vdrv_cmd_lock, -1);
|
|
logd("(f:%s, l:%d) wait for VDRV_THREAD_CMD_CLOSE_VDECODER done!", __FUNCTION__, __LINE__);
|
|
if(pSelf->bUseShareBuffer== OMX_TRUE)//sharebuffer
|
|
{
|
|
OMX_U32 i;
|
|
for(i = 0; i < OMX_MAX_VIDEO_BUFFER_NUM; i++)
|
|
{
|
|
if(pSelf->mOutputBufferInfo[i].mStatus == OWNED_BY_DECODER
|
|
|| pSelf->mOutputBufferInfo[i].mStatus == OWNED_BY_US)
|
|
{
|
|
logd("fillBufferDone when quit: i[%d],pHeadBufInfo[%p],mStatus[%d]",
|
|
(int)i,pSelf->mOutputBufferInfo[i].pHeadBufInfo,
|
|
(int)pSelf->mOutputBufferInfo[i].mStatus);
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->mOutputBufferInfo[i].pHeadBufInfo);
|
|
}
|
|
|
|
if(pSelf->mOutputBufferInfo[i].mStatus != 0)
|
|
pSelf->mOutputBufferInfo[i].mStatus = OWNED_BY_RENDER;
|
|
}
|
|
}
|
|
}
|
|
else //OMX_StateLoaded -> OMX_StateIdle
|
|
{
|
|
//*we not create decoder here
|
|
#if 0
|
|
if(pSelf->bUseShareBuffer == OMX_TRUE
|
|
/* || pSelf->m_eCompressionFormat == OMX_VIDEO_CodingAVC*/)
|
|
{
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
msg.messageId = VDRV_THREAD_CMD_PREPARE_VDECODER;
|
|
|
|
CdcMessageQueuePostMessage(pSelf->mqVdrvThread, &msg);
|
|
sem_post(&pSelf->m_sem_vbs_input);
|
|
sem_post(&pSelf->m_sem_frame_output);
|
|
logd("(f:%s, l:%d) wait for OMX_VdrvCommand_PrepareVdecLib",
|
|
__FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_vdrv_cmd_lock, -1);
|
|
logd("(f:%s, l:%d) wait for OMX_VdrvCommand_PrepareVdecLib done!",
|
|
__FUNCTION__, __LINE__);
|
|
msg.messageId = RENDER_THREAD_CMD_START;
|
|
CdcMessageQueuePostMessage(pSelf->mqRenderThread, &msg);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
//*Ports have to be populated before transition completes
|
|
if ((!pSelf->m_sInPortDefType.bEnabled && !pSelf->m_sOutPortDefType.bEnabled) ||
|
|
(pSelf->m_sInPortDefType.bPopulated && pSelf->m_sOutPortDefType.bPopulated))
|
|
{
|
|
pSelf->m_state = OMX_StateIdle;
|
|
//*wake up vdrvThread
|
|
sem_post(&pSelf->m_sem_vbs_input);
|
|
sem_post(&pSelf->m_sem_frame_output);
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandStateSet,
|
|
pSelf->m_state, NULL);
|
|
|
|
//* Open decoder
|
|
//* TODO.
|
|
break;
|
|
}
|
|
else if (nTimeout++ > OMX_MAX_TIMEOUTS)
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError, OMX_ErrorInsufficientResources,
|
|
0 , NULL);
|
|
logw("Idle transition failed\n");
|
|
break;
|
|
}
|
|
|
|
usleep(OMX_TIMEOUT*1000);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
static inline void setStateExecuting(omx_vdec* pSelf)
|
|
{
|
|
//*Transition can only happen from pause or idle state
|
|
if (pSelf->m_state == OMX_StateIdle || pSelf->m_state == OMX_StatePause)
|
|
{
|
|
//*Return buffers if currently in pause
|
|
if (pSelf->m_state == OMX_StatePause)
|
|
{
|
|
pthread_mutex_lock(&pSelf->m_inBufMutex);
|
|
|
|
while (pSelf->m_sInBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sInBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.EmptyBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sInBufList.pBufHdrList[pSelf->m_sInBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sInBufList.nReadPos >= pSelf->m_sInBufList.nBufArrSize)
|
|
pSelf->m_sInBufList.nReadPos = 0;
|
|
}
|
|
|
|
pSelf->m_sInBufList.nReadPos = 0;
|
|
pSelf->m_sInBufList.nWritePos = 0;
|
|
|
|
pthread_mutex_unlock(&pSelf->m_inBufMutex);
|
|
|
|
OMX_S32 i;
|
|
for(i=0; i < OMX_MAX_VIDEO_BUFFER_NUM; i++)
|
|
{
|
|
if(pSelf->mOutBufferKeepInOmx[i] != NULL)
|
|
{
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->mOutBufferKeepInOmx[i]);
|
|
pSelf->mOutBufferKeepInOmx[i] = NULL;
|
|
}
|
|
}
|
|
pthread_mutex_lock(&pSelf->m_outBufMutex);
|
|
|
|
while (pSelf->m_sOutBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sOutBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sOutBufList.pBufHdrList[pSelf->m_sOutBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sOutBufList.nReadPos >= pSelf->m_sOutBufList.nBufArrSize)
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
}
|
|
while (pSelf->m_sCacheBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sCacheBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sCacheBufList.pBufHdrList[pSelf->m_sCacheBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sCacheBufList.nReadPos >= pSelf->m_sCacheBufList.nBufArrSize)
|
|
pSelf->m_sCacheBufList.nReadPos = 0;
|
|
}
|
|
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
pSelf->m_sOutBufList.nWritePos = 0;
|
|
pSelf->m_sCacheBufList.nReadPos = 0;
|
|
pSelf->m_sCacheBufList.nWritePos = 0;
|
|
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
}
|
|
|
|
pSelf->m_state = OMX_StateExecuting;
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandStateSet,
|
|
pSelf->m_state, NULL);
|
|
}
|
|
else
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError, OMX_ErrorIncorrectStateTransition,
|
|
0 , NULL);
|
|
}
|
|
|
|
pSelf->nInBufEos = OMX_FALSE;
|
|
pSelf->pMarkData = NULL;
|
|
pSelf->hMarkTargetComponent = NULL;
|
|
}
|
|
|
|
static inline void controlSetState(omx_vdec* pSelf, OMX_U32 cmddata)
|
|
{
|
|
//*transitions/pCallbacks made based on state transition table
|
|
// cmddata contains the target state
|
|
switch ((OMX_STATETYPE)(cmddata))
|
|
{
|
|
case OMX_StateInvalid:
|
|
pSelf->m_state = OMX_StateInvalid;
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError, OMX_ErrorInvalidState,
|
|
0 , NULL);
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandStateSet,
|
|
pSelf->m_state, NULL);
|
|
break;
|
|
|
|
case OMX_StateLoaded:
|
|
setStateLoaded(pSelf);
|
|
break;
|
|
|
|
case OMX_StateIdle:
|
|
setStateIdle(pSelf);
|
|
break;
|
|
|
|
case OMX_StateExecuting:
|
|
setStateExecuting(pSelf);
|
|
break;
|
|
|
|
case OMX_StatePause:
|
|
// Transition can only happen from idle or executing state
|
|
if (pSelf->m_state == OMX_StateIdle || pSelf->m_state == OMX_StateExecuting)
|
|
{
|
|
pSelf->m_state = OMX_StatePause;
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandStateSet,
|
|
pSelf->m_state, NULL);
|
|
}
|
|
else
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError, OMX_ErrorIncorrectStateTransition,
|
|
0 , NULL);
|
|
}
|
|
|
|
break;
|
|
|
|
case OMX_StateWaitForResources:
|
|
if (pSelf->m_state == OMX_StateLoaded)
|
|
{
|
|
pSelf->m_state = OMX_StateWaitForResources;
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandStateSet,
|
|
pSelf->m_state, NULL);
|
|
}
|
|
else
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError, OMX_ErrorIncorrectStateTransition,
|
|
0 , NULL);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError,
|
|
OMX_ErrorIncorrectStateTransition, 0 , NULL);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
static inline void controlStopPort(omx_vdec* pSelf, OMX_U32 cmddata)
|
|
{
|
|
logd(" stop port command, cmddata = %d.", (int)cmddata);
|
|
OMX_U32 nTimeout = 0x0;
|
|
//*Stop Port(s)
|
|
// cmddata contains the port index to be stopped.
|
|
// It is assumed that 0 is input and 1 is output port for this component
|
|
// The cmddata value -1 means that both input and output ports will be stopped.
|
|
if (cmddata == 0x0 || (OMX_S32)cmddata == -1)
|
|
{
|
|
//*Return all input buffers
|
|
pthread_mutex_lock(&pSelf->m_inBufMutex);
|
|
|
|
while (pSelf->m_sInBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sInBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.EmptyBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sInBufList.pBufHdrList[pSelf->m_sInBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sInBufList.nReadPos >= pSelf->m_sInBufList.nBufArrSize)
|
|
pSelf->m_sInBufList.nReadPos = 0;
|
|
}
|
|
|
|
pSelf->m_sInBufList.nReadPos = 0;
|
|
pSelf->m_sInBufList.nWritePos = 0;
|
|
|
|
pthread_mutex_unlock(&pSelf->m_inBufMutex);
|
|
|
|
//*Disable port
|
|
pSelf->m_sInPortDefType.bEnabled = OMX_FALSE;
|
|
}
|
|
|
|
if (cmddata == 0x1 || (OMX_S32)cmddata == -1)
|
|
{
|
|
//*Return all output buffers
|
|
OMX_U32 i;
|
|
for(i=0; i < OMX_MAX_VIDEO_BUFFER_NUM; i++)
|
|
{
|
|
if(pSelf->mOutBufferKeepInOmx[i] != NULL)
|
|
{
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->mOutBufferKeepInOmx[i]);
|
|
pSelf->mOutBufferKeepInOmx[i] = NULL;
|
|
}
|
|
}
|
|
pthread_mutex_lock(&pSelf->m_outBufMutex);
|
|
|
|
while (pSelf->m_sOutBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sOutBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sOutBufList.pBufHdrList[pSelf->m_sOutBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sOutBufList.nReadPos >= pSelf->m_sOutBufList.nBufArrSize)
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
}
|
|
while (pSelf->m_sCacheBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sCacheBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sCacheBufList.pBufHdrList[pSelf->m_sCacheBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sCacheBufList.nReadPos >= pSelf->m_sCacheBufList.nBufArrSize)
|
|
pSelf->m_sCacheBufList.nReadPos = 0;
|
|
}
|
|
|
|
//* return the output buffer in mOutputBufferInfo
|
|
if(pSelf->bUseShareBuffer== OMX_TRUE)//sharebuffer
|
|
{
|
|
for(i = 0; i < OMX_MAX_VIDEO_BUFFER_NUM/*pSelf->m_sOutBufList.nAllocSize*/; i++)
|
|
{
|
|
if(pSelf->mOutputBufferInfo[i].mStatus == OWNED_BY_DECODER
|
|
|| pSelf->mOutputBufferInfo[i].mStatus == OWNED_BY_US)
|
|
{
|
|
logi("fillBufferDone when stop: i[%d],pHeadBufInfo[%p],mStatus[%d]",
|
|
(int)i,pSelf->mOutputBufferInfo[i].pHeadBufInfo,
|
|
(int)pSelf->mOutputBufferInfo[i].mStatus);
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->mOutputBufferInfo[i].pHeadBufInfo);
|
|
}
|
|
}
|
|
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
pSelf->m_sOutBufList.nWritePos = 0;
|
|
|
|
pSelf->m_sCacheBufList.nReadPos = 0;
|
|
pSelf->m_sCacheBufList.nWritePos = 0;
|
|
memset(&pSelf->mOutputBufferInfo, 0,
|
|
sizeof(OMXOutputBufferInfoT)*OMX_MAX_VIDEO_BUFFER_NUM);
|
|
pSelf->mNeedReSetToDecoderBufferNum = 0;
|
|
pSelf->mSetToDecoderBufferNum = 0;
|
|
}
|
|
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
pSelf->m_sOutBufList.nWritePos = 0;
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
|
|
// Disable port
|
|
pSelf->m_sOutPortDefType.bEnabled = OMX_FALSE;
|
|
}
|
|
|
|
// Wait for all buffers to be freed
|
|
while (1)
|
|
{
|
|
if (cmddata == 0x0 && !pSelf->m_sInPortDefType.bPopulated)
|
|
{
|
|
//*Return cmdcomplete event if input unpopulated
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
|
0x0, NULL);
|
|
break;
|
|
}
|
|
|
|
if (cmddata == 0x1 && !pSelf->m_sOutPortDefType.bPopulated)
|
|
{
|
|
//*Return cmdcomplete event if output unpopulated
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
|
0x1, NULL);
|
|
break;
|
|
}
|
|
|
|
if ((OMX_S32)cmddata == -1
|
|
&& !pSelf->m_sInPortDefType.bPopulated
|
|
&& !pSelf->m_sOutPortDefType.bPopulated)
|
|
{
|
|
//*Return cmdcomplete event if inout & output unpopulated
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
|
0x0, NULL);
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
|
0x1, NULL);
|
|
break;
|
|
}
|
|
|
|
//* Here , we sleep 500 ms.
|
|
//* In the duration , if not all buffers be freed, we also return OMX_EventCmdComplete
|
|
if (nTimeout++ > OMX_MAX_TIMEOUTS_STOP_PORT)
|
|
{
|
|
logw("timeOut when wait for all buffer to be freed in stopPort command! \
|
|
But we also return OMX_EventCmdComplete!");
|
|
if(cmddata == 0x0)
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
|
0x0, NULL);
|
|
break;
|
|
}
|
|
else if(cmddata == 0x1)
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
|
0x1, NULL);
|
|
break;
|
|
}
|
|
else if((OMX_S32)cmddata == -1)
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
|
0x0, NULL);
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortDisable,
|
|
0x1, NULL);
|
|
break;
|
|
}
|
|
|
|
//pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
// OMX_EventError,
|
|
// OMX_ErrorPortUnresponsiveDuringDeallocation,
|
|
// 0 , NULL);
|
|
//break;
|
|
}
|
|
|
|
usleep(OMX_TIMEOUT*1000);
|
|
}
|
|
}
|
|
|
|
static inline void controlRestartPort(omx_vdec* pSelf, OMX_U32 cmddata)
|
|
{
|
|
logd(" restart port command.pSelf->m_state[%d]", pSelf->m_state);
|
|
|
|
//*Restart Port(s)
|
|
// cmddata contains the port uIndex to be restarted.
|
|
// It is assumed that 0 is input and 1 is output port for this component.
|
|
// The cmddata value -1 means both input and output ports will be restarted.
|
|
|
|
/*
|
|
if (cmddata == 0x0 || (OMX_S32)cmddata == -1)
|
|
pSelf->m_sInPortDefType.bEnabled = OMX_TRUE;
|
|
|
|
if (cmddata == 0x1 || (OMX_S32)cmddata == -1)
|
|
pSelf->m_sOutPortDefType.bEnabled = OMX_TRUE;
|
|
*/
|
|
|
|
// Wait for port to be populated
|
|
OMX_U32 nTimeout = 0x0;
|
|
while (1)
|
|
{
|
|
// Return cmdcomplete event if input port populated
|
|
if (cmddata == 0x0
|
|
&& (pSelf->m_state == OMX_StateLoaded || pSelf->m_sInPortDefType.bPopulated))
|
|
{
|
|
pSelf->m_sInPortDefType.bEnabled = OMX_TRUE;
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortEnable,
|
|
0x0, NULL);
|
|
break;
|
|
}
|
|
// Return cmdcomplete event if output port populated
|
|
else if (cmddata == 0x1
|
|
&& (pSelf->m_state == OMX_StateLoaded || pSelf->m_sOutPortDefType.bPopulated))
|
|
{
|
|
pSelf->m_sOutPortDefType.bEnabled = OMX_TRUE;
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortEnable,
|
|
0x1, NULL);
|
|
break;
|
|
}
|
|
// Return cmdcomplete event if input and output ports populated
|
|
else if ((OMX_S32)cmddata == -1
|
|
&& (pSelf->m_state == OMX_StateLoaded
|
|
|| (pSelf->m_sInPortDefType.bPopulated
|
|
&& pSelf->m_sOutPortDefType.bPopulated)))
|
|
{
|
|
pSelf->m_sInPortDefType.bEnabled = OMX_TRUE;
|
|
pSelf->m_sOutPortDefType.bEnabled = OMX_TRUE;
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortEnable,
|
|
0x0, NULL);
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandPortEnable,
|
|
0x1, NULL);
|
|
break;
|
|
}
|
|
else if (nTimeout++ > OMX_MAX_TIMEOUTS)
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError,
|
|
OMX_ErrorPortUnresponsiveDuringAllocation, 0, NULL);
|
|
break;
|
|
}
|
|
|
|
usleep(OMX_TIMEOUT*1000);
|
|
}
|
|
|
|
if(pSelf->port_setting_match == OMX_FALSE)
|
|
pSelf->port_setting_match = OMX_TRUE;
|
|
}
|
|
|
|
static inline void controlFlush(omx_vdec* pSelf, OMX_U32 cmddata)
|
|
{
|
|
logi(" flush command.");
|
|
|
|
//*Flush port(s)
|
|
// cmddata contains the port uIndex to be flushed.
|
|
// It is assumed that 0 is input and 1 is output port for this component
|
|
// The cmddata value -1 means that both input and output ports will be flushed.
|
|
|
|
//if request flush input and output port, we reset decoder!
|
|
if(cmddata == OMX_ALL || cmddata == 0x1 || (OMX_S32)cmddata == -1)
|
|
{
|
|
logi(" flush all port! we reset decoder!");
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
|
|
msg.messageId = RENDER_THREAD_CMD_PAUSE;
|
|
CdcMessageQueuePostMessage(pSelf->mqRenderThread, &msg);
|
|
logi("(f:%s, l:%d) wait for pause render ", __FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_render_cmd_lock, -1);
|
|
logi("(f:%s, l:%d) wait for pause render done!", __FUNCTION__, __LINE__);
|
|
|
|
msg.messageId = VDRV_THREAD_CMD_FLUSH_VDECODER;
|
|
|
|
CdcMessageQueuePostMessage(pSelf->mqVdrvThread, &msg);
|
|
sem_post(&pSelf->m_sem_vbs_input);
|
|
sem_post(&pSelf->m_sem_frame_output);
|
|
logi("(f:%s, l:%d) wait for VDRV_THREAD_CMD_FLUSH_VDECODER",
|
|
__FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_vdrv_cmd_lock, -1);
|
|
logi("(f:%s, l:%d) wait for VDRV_THREAD_CMD_FLUSH_VDECODER done!",
|
|
__FUNCTION__, __LINE__);
|
|
|
|
msg.messageId = RENDER_THREAD_CMD_EXECUT;
|
|
CdcMessageQueuePostMessage(pSelf->mqRenderThread, &msg);
|
|
}
|
|
if (cmddata == 0x0 || (OMX_S32)cmddata == -1)
|
|
{
|
|
logi("Return all input buffers and send cmdcomplete");
|
|
pthread_mutex_lock(&pSelf->m_inBufMutex);
|
|
|
|
while (pSelf->m_sInBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sInBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.EmptyBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sInBufList.pBufHdrList[pSelf->m_sInBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sInBufList.nReadPos >= pSelf->m_sInBufList.nBufArrSize)
|
|
pSelf->m_sInBufList.nReadPos = 0;
|
|
}
|
|
|
|
pSelf->m_sInBufList.nReadPos = 0;
|
|
pSelf->m_sInBufList.nWritePos = 0;
|
|
pthread_mutex_unlock(&pSelf->m_inBufMutex);
|
|
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandFlush,
|
|
0x0, NULL);
|
|
}
|
|
|
|
if (cmddata == 0x1 || (OMX_S32)cmddata == -1)
|
|
{
|
|
logi("Return all output buffers and send cmdcomplete");
|
|
|
|
OMX_U32 i;
|
|
for(i=0; i < OMX_MAX_VIDEO_BUFFER_NUM; i++)
|
|
{
|
|
if(pSelf->mOutBufferKeepInOmx[i] != NULL)
|
|
{
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->mOutBufferKeepInOmx[i]);
|
|
pSelf->mOutBufferKeepInOmx[i] = NULL;
|
|
}
|
|
}
|
|
pthread_mutex_lock(&pSelf->m_outBufMutex);
|
|
|
|
while (pSelf->m_sOutBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sOutBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sOutBufList.pBufHdrList[pSelf->m_sOutBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sOutBufList.nReadPos >= pSelf->m_sOutBufList.nBufArrSize)
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
}
|
|
while (pSelf->m_sCacheBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sCacheBufList.nSizeOfList--;
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->m_sCacheBufList.pBufHdrList[pSelf->m_sCacheBufList.nReadPos++]);
|
|
|
|
if (pSelf->m_sCacheBufList.nReadPos >= pSelf->m_sCacheBufList.nBufArrSize)
|
|
pSelf->m_sCacheBufList.nReadPos = 0;
|
|
}
|
|
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
|
|
//* return the output buffer in mOutputBufferInfo
|
|
if(pSelf->bUseShareBuffer== OMX_TRUE)//sharebuffer
|
|
{
|
|
OMX_BOOL out_buffer_flag = OMX_FALSE;
|
|
for(i = 0; i < OMX_MAX_VIDEO_BUFFER_NUM; i++)
|
|
{
|
|
OutBufferStatus out_buffer_status = pSelf->mOutputBufferInfo[i].mStatus;
|
|
out_buffer_flag = \
|
|
pSelf->mOutputBufferInfo[i].mUseDecoderBufferToSetEosFlag;
|
|
if(out_buffer_status == OWNED_BY_DECODER)
|
|
{
|
|
logi("fillBufferDone when flush: i[%d],pHeadBufInfo[%p],mStatus[%d]"
|
|
,(int)i,pSelf->mOutputBufferInfo[i].pHeadBufInfo,
|
|
(int)out_buffer_status);
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->mOutputBufferInfo[i].pHeadBufInfo);
|
|
}
|
|
else if(out_buffer_status == OWNED_BY_RENDER
|
|
&& out_buffer_flag == OMX_FALSE)
|
|
{
|
|
logi("** return pic when flush,i[%lu],pPic[%p]",
|
|
i,pSelf->mOutputBufferInfo[i].pVideoPicture);
|
|
if(pSelf->mOutputBufferInfo[i].pVideoPicture != NULL)
|
|
{
|
|
ReturnPicture(pSelf->m_decoder,
|
|
pSelf->mOutputBufferInfo[i].pVideoPicture);
|
|
tryPostSem(&pSelf->m_sem_frame_output);
|
|
}
|
|
}
|
|
else if(out_buffer_status == OWNED_BY_US)
|
|
{
|
|
if(pSelf->mOutputBufferInfo[i].pVideoPicture != NULL)
|
|
{
|
|
logi("fillBufferDone when flush: i[%d],pHeadBufInfo[%p],mStatus[%d]",
|
|
(int)i,pSelf->mOutputBufferInfo[i].pHeadBufInfo,
|
|
(int)out_buffer_status);
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp,
|
|
pSelf->m_pAppData,
|
|
pSelf->mOutputBufferInfo[i].pHeadBufInfo);
|
|
ReturnPicture(pSelf->m_decoder,
|
|
pSelf->mOutputBufferInfo[i].pVideoPicture);
|
|
tryPostSem(&pSelf->m_sem_frame_output);
|
|
}
|
|
}
|
|
}
|
|
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
pSelf->m_sOutBufList.nWritePos = 0;
|
|
pSelf->m_sCacheBufList.nReadPos = 0;
|
|
pSelf->m_sCacheBufList.nWritePos = 0;
|
|
|
|
memset(&pSelf->mOutputBufferInfo, 0,
|
|
sizeof(OMXOutputBufferInfoT)*OMX_MAX_VIDEO_BUFFER_NUM);
|
|
pSelf->mNeedReSetToDecoderBufferNum += pSelf->mSetToDecoderBufferNum;
|
|
pSelf->mSetToDecoderBufferNum = 0;
|
|
|
|
SetVideoFbmBufRelease(pSelf->m_decoder);
|
|
}
|
|
else
|
|
{
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
pSelf->m_sOutBufList.nWritePos = 0;
|
|
}
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventCmdComplete, OMX_CommandFlush,
|
|
0x1, NULL);
|
|
}
|
|
}
|
|
|
|
static inline void controlFillBuf(omx_vdec* pSelf, OMX_U32 cmddata)
|
|
{
|
|
//*Fill buffer
|
|
|
|
OMX_BUFFERHEADERTYPE* pTmpBufferHeader = NULL;
|
|
pthread_mutex_lock(&pSelf->m_outBufMutex);
|
|
if(pSelf->bUseShareBuffer && pSelf->m_useAndroidBuffer == 0)
|
|
{
|
|
logv("gqy=== cache lis size: %d, allcoSize: %d, writepos: %d, readpos:%d",
|
|
(int)pSelf->m_sCacheBufList.nSizeOfList,
|
|
(int)pSelf->m_sCacheBufList.nAllocSize,
|
|
(int)pSelf->m_sCacheBufList.nWritePos,
|
|
(int)pSelf->m_sCacheBufList.nReadPos);
|
|
if(pSelf->m_sCacheBufList.nSizeOfList < pSelf->m_sCacheBufList.nAllocSize)
|
|
{
|
|
|
|
pSelf->m_sCacheBufList.nSizeOfList++;
|
|
|
|
pSelf->m_sCacheBufList.pBufHdrList[pSelf->m_sCacheBufList.nWritePos++]
|
|
= ((OMX_BUFFERHEADERTYPE*) cmddata);
|
|
if (pSelf->m_sCacheBufList.nWritePos >= (OMX_S32)pSelf->m_sCacheBufList.nAllocSize)
|
|
pSelf->m_sCacheBufList.nWritePos = 0;
|
|
}
|
|
if(((OMX_S32)pSelf->m_sCacheBufList.nSizeOfList >= (OMX_CACHE_BUFF_NUM - 1)))
|
|
{
|
|
pTmpBufferHeader = \
|
|
pSelf->m_sCacheBufList.pBufHdrList[pSelf->m_sCacheBufList.nReadPos];
|
|
pSelf->m_sCacheBufList.nSizeOfList--;
|
|
pSelf->m_sCacheBufList.nReadPos++;
|
|
|
|
if (pSelf->m_sCacheBufList.nReadPos >= (OMX_S32)pSelf->m_sCacheBufList.nAllocSize)
|
|
pSelf->m_sCacheBufList.nReadPos = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pTmpBufferHeader = ((OMX_BUFFERHEADERTYPE*) cmddata);
|
|
}
|
|
if (pSelf->m_sOutBufList.nSizeOfList < pSelf->m_sOutBufList.nAllocSize && pTmpBufferHeader != NULL)
|
|
{
|
|
pSelf->m_sOutBufList.nSizeOfList++;
|
|
pSelf->m_sOutBufList.pBufHdrList[pSelf->m_sOutBufList.nWritePos++]
|
|
= pTmpBufferHeader;
|
|
|
|
if (pSelf->m_sOutBufList.nWritePos >= (OMX_S32)pSelf->m_sOutBufList.nAllocSize)
|
|
pSelf->m_sOutBufList.nWritePos = 0;
|
|
}
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
}
|
|
|
|
static inline void controlEmptyBuf(omx_vdec* pSelf, OMX_U32 cmddata)
|
|
{
|
|
OMX_BUFFERHEADERTYPE* pTmpInBufHeader = (OMX_BUFFERHEADERTYPE*) cmddata;
|
|
OMX_TICKS nInterval;
|
|
|
|
//*Empty buffer
|
|
pthread_mutex_lock(&pSelf->m_inBufMutex);
|
|
if(0 == pTmpInBufHeader->nTimeStamp)
|
|
{
|
|
logv("why cur vbs input nTimeStamp=0? prevPts=%lld", pSelf->m_nInportPrevTimeStamp);
|
|
if(pSelf->m_nInportPrevTimeStamp > 0)
|
|
{
|
|
logv("fix cur vbs input nTimeStamp from 0 to -1");
|
|
pTmpInBufHeader->nTimeStamp = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(pSelf->m_nInportPrevTimeStamp)
|
|
{
|
|
//*compare pts to decide if jump
|
|
nInterval = pTmpInBufHeader->nTimeStamp - pSelf->m_nInportPrevTimeStamp;
|
|
if(nInterval < -AWOMX_PTS_JUMP_THRESH || nInterval > AWOMX_PTS_JUMP_THRESH)
|
|
{
|
|
logd("pts jump [%lld]us, prev[%lld],cur[%lld],need reset vdeclib",
|
|
nInterval, pSelf->m_nInportPrevTimeStamp, pTmpInBufHeader->nTimeStamp);
|
|
pSelf->m_JumpFlag = OMX_TRUE;
|
|
}
|
|
|
|
pSelf->m_nInportPrevTimeStamp = pTmpInBufHeader->nTimeStamp;
|
|
}
|
|
else //*first InBuf data
|
|
{
|
|
pSelf->m_nInportPrevTimeStamp = pTmpInBufHeader->nTimeStamp;
|
|
}
|
|
}
|
|
|
|
if (pSelf->m_sInBufList.nSizeOfList < pSelf->m_sInBufList.nAllocSize)
|
|
{
|
|
pSelf->m_sInBufList.nSizeOfList++;
|
|
pSelf->m_sInBufList.pBufHdrList[pSelf->m_sInBufList.nWritePos++]
|
|
= ((OMX_BUFFERHEADERTYPE*) cmddata);
|
|
|
|
if (pSelf->m_sInBufList.nWritePos >= (OMX_S32)pSelf->m_sInBufList.nAllocSize)
|
|
pSelf->m_sInBufList.nWritePos = 0;
|
|
}
|
|
|
|
logv("(omx_vdec, f:%s, l:%d) nTimeStamp[%lld], nAllocLen[%d], nFilledLen[%d],\
|
|
nOffset[%d], nFlags[0x%x], nOutputPortIndex[%d], nInputPortIndex[%d]",
|
|
__FUNCTION__, __LINE__,
|
|
pTmpInBufHeader->nTimeStamp,
|
|
(int)pTmpInBufHeader->nAllocLen,
|
|
(int)pTmpInBufHeader->nFilledLen,
|
|
(int)pTmpInBufHeader->nOffset,
|
|
(int)pTmpInBufHeader->nFlags,
|
|
(int)pTmpInBufHeader->nOutputPortIndex,
|
|
(int)pTmpInBufHeader->nInputPortIndex);
|
|
|
|
pthread_mutex_unlock(&pSelf->m_inBufMutex);
|
|
|
|
//*Mark current buffer if there is outstanding command
|
|
if (pSelf->pMarkBuf)
|
|
{
|
|
((OMX_BUFFERHEADERTYPE *)(cmddata))->hMarkTargetComponent = &pSelf->mOmxCmp;
|
|
((OMX_BUFFERHEADERTYPE *)(cmddata))->pMarkData = pSelf->pMarkBuf->pMarkData;
|
|
pSelf->pMarkBuf = NULL;
|
|
}
|
|
}
|
|
|
|
static inline int vdecoderPrepare(omx_vdec* pSelf)
|
|
{
|
|
logd("(f:%s, l:%d)(VDRV_THREAD_CMD_PREPARE_VDECODER)", __FUNCTION__, __LINE__);
|
|
|
|
// If the parameter states a transition to the same state
|
|
// raise a same state transition error.
|
|
if (pSelf->m_state != OMX_StateExecuting)
|
|
{
|
|
logw("fatal error! when vdrv VDRV_THREAD_CMD_PREPARE_VDECODER, m_state[0x%x] \
|
|
should be OMX_StateExecuting", pSelf->m_state);
|
|
}
|
|
|
|
//*if mdecoder had closed before, we should create it
|
|
if(pSelf->m_decoder==NULL)
|
|
{
|
|
//AddVDPlugin();
|
|
pSelf->m_decoder = CreateVideoDecoder();
|
|
}
|
|
|
|
//* set video stream info.
|
|
|
|
if(pSelf->bUseShareBuffer == OMX_TRUE)
|
|
pSelf->m_videoConfig.bGpuBufValid = 1;
|
|
|
|
//*set yv12
|
|
pSelf->m_videoConfig.eOutputPixelFormat = PIXEL_FORMAT_YV12;
|
|
pSelf->m_videoConfig.memops = MemAdapterGetOpsS();
|
|
|
|
if(pSelf->m_useAndroidBuffer || pSelf->bUseShareBuffer)
|
|
{
|
|
pSelf->m_videoConfig.nAlignStride = pSelf->mGpuAlignStride;
|
|
|
|
//m_videoConfig.nAlignStride = 16;
|
|
}
|
|
#if (SCALEDOWN_WHEN_RESOLUTION_MOER_THAN_1080P)
|
|
// omx decoder make out buffer no more than 1920x1080
|
|
if (pSelf->m_streamInfo.nWidth > 1920
|
|
&& pSelf->m_streamInfo.nHeight > 1088)
|
|
{
|
|
pSelf->m_videoConfig.bScaleDownEn = 1;
|
|
pSelf->m_videoConfig.nHorizonScaleDownRatio = 1;
|
|
pSelf->m_videoConfig.nVerticalScaleDownRatio = 1;
|
|
}
|
|
#endif
|
|
if(pSelf->m_streamInfo.eCodecFormat == VIDEO_CODEC_FORMAT_WMV3)
|
|
{
|
|
logd("*** pSelf->m_streamInfo.bIsFramePackage to 1 when it is vc1");
|
|
pSelf->m_streamInfo.bIsFramePackage = 1;
|
|
}
|
|
|
|
|
|
if(pSelf->bUseShareBuffer == OMX_TRUE)
|
|
{
|
|
pSelf->mExtraOutBufferNum = 0;
|
|
}
|
|
/*
|
|
else
|
|
{
|
|
logd(" wait for m_semExtraOutBufferNum");
|
|
SemTimedWait(&pSelf->m_semExtraOutBufferNum, -1);
|
|
logd(" wait for m_semExtraOutBufferNum done");
|
|
}*/
|
|
pSelf->m_streamInfo.bIsFramePackage = 1;
|
|
|
|
pSelf->m_videoConfig.nDeInterlaceHoldingFrameBufferNum = 0;//*not use deinterlace
|
|
pSelf->m_videoConfig.nDisplayHoldingFrameBufferNum = 0;//*gpu and decoder not share buffer
|
|
pSelf->m_videoConfig.nRotateHoldingFrameBufferNum = NUM_OF_PICTURES_KEEPPED_BY_ROTATE;
|
|
pSelf->m_videoConfig.nDecodeSmoothFrameBufferNum = NUM_OF_PICTURES_FOR_EXTRA_SMOOTH + OMX_CACHE_BUFF_NUM;
|
|
if(InitializeVideoDecoder(pSelf->m_decoder, &(pSelf->m_streamInfo), &pSelf->m_videoConfig) != 0)
|
|
{
|
|
DestroyVideoDecoder(pSelf->m_decoder);
|
|
pSelf->m_decoder = NULL;
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError, OMX_ErrorHardware,
|
|
0 , NULL);
|
|
loge("Idle transition failed, set_vstream_info() return fail.\n");
|
|
return OMX_RESULT_ERROR;
|
|
}
|
|
return OMX_RESULT_OK;
|
|
}
|
|
|
|
static inline void vdecoderDecodeStream(omx_vdec* pSelf)
|
|
{
|
|
int decodeResult;
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
#if (OPEN_STATISTICS)
|
|
nTimeUs1 = OMX_GetNowUs();
|
|
#endif
|
|
|
|
decodeResult = DecodeVideoStream(pSelf->m_decoder,0,0,0,0);
|
|
logv("***decodeResult = %d",decodeResult);
|
|
|
|
#if (OPEN_STATISTICS)
|
|
nTimeUs2 = OMX_GetNowUs();
|
|
|
|
if(decodeResult == CEDARV_RESULT_FRAME_DECODED
|
|
|| decodeResult == CEDARV_RESULT_KEYFRAME_DECODED)
|
|
{
|
|
pSelf->mDecodeFrameTotalDuration += (nTimeUs2-nTimeUs1);
|
|
pSelf->mDecodeFrameTotalCount++;
|
|
}
|
|
else if(decodeResult == CEDARV_RESULT_OK)
|
|
{
|
|
pSelf->mDecodeOKTotalDuration += (nTimeUs2-nTimeUs1);
|
|
pSelf->mDecodeOKTotalCount++;
|
|
}
|
|
else if(decodeResult == CEDARV_RESULT_NO_FRAME_BUFFER)
|
|
{
|
|
pSelf->mDecodeNoFrameTotalDuration += (nTimeUs2-nTimeUs1);
|
|
pSelf->mDecodeNoFrameTotalCount++;
|
|
}
|
|
else if(decodeResult == CEDARV_RESULT_NO_BITSTREAM)
|
|
{
|
|
pSelf->mDecodeNoBitstreamTotalDuration += (nTimeUs2-nTimeUs1);
|
|
pSelf->mDecodeNoBitstreamTotalCount++;
|
|
}
|
|
else
|
|
{
|
|
pSelf->mDecodeOtherTotalDuration += (nTimeUs2-nTimeUs1);
|
|
pSelf->mDecodeOtherTotalCount++;
|
|
}
|
|
#endif
|
|
|
|
if(decodeResult == VDECODE_RESULT_KEYFRAME_DECODED ||
|
|
decodeResult == VDECODE_RESULT_FRAME_DECODED ||
|
|
decodeResult == VDECODE_RESULT_OK)
|
|
{
|
|
//*do nothing
|
|
}
|
|
else if(decodeResult == VDECODE_RESULT_NO_FRAME_BUFFER)
|
|
{
|
|
logv("(f:%s, l:%d) no_frame_buffer, wait!", __FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_sem_frame_output, 20);
|
|
logv("(f:%s, l:%d) no_frame_buffer, wait_done!", __FUNCTION__, __LINE__);
|
|
}
|
|
else if(decodeResult == VDECODE_RESULT_NO_BITSTREAM || decodeResult == VDECODE_RESULT_CONTINUE)
|
|
{
|
|
if(pSelf->nInputEosFlag)
|
|
{
|
|
pSelf->nInputEosFlag = OMX_FALSE;
|
|
|
|
//*set eos to decoder ,decoder should flush all fbm
|
|
int mRet = 0;
|
|
int mDecodeCount = 0;
|
|
while(mRet != VDECODE_RESULT_NO_BITSTREAM)
|
|
{
|
|
mRet = DecodeVideoStream(pSelf->m_decoder,1,0,0,0);
|
|
if(mRet == VDECODE_RESULT_RESOLUTION_CHANGE)
|
|
goto resolution_change;
|
|
usleep(5*1000);
|
|
mDecodeCount++;
|
|
if(mDecodeCount > 1000)
|
|
{
|
|
logw(" decoder timeOut when set eos to decoder!");
|
|
break;
|
|
}
|
|
}
|
|
|
|
//*set eof flag, MediaCodec use this flag
|
|
// to determine whether a playback is finished.
|
|
|
|
logv("(f:%s, l:%d) when eos, vdrvtask meet no_bitstream, \
|
|
all frames have decoded, notify ComponentThread eos!",
|
|
__FUNCTION__, __LINE__);
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
msg.messageId = MAIN_THREAD_CMD_VDRV_NOTIFY_EOS;
|
|
|
|
CdcMessageQueuePostMessage(pSelf->mqMainThread, &msg);
|
|
logv("(f:%s, l:%d) no_vbsinput_buffer, eos wait!", __FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_sem_vbs_input, 20);
|
|
logv("(f:%s, l:%d) no_vbsinput_buffer, eos wait_done!", __FUNCTION__, __LINE__);
|
|
}
|
|
else
|
|
{
|
|
logv("(f:%s, l:%d) no_vbsinput_buffer, wait!", __FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_sem_vbs_input, 20);
|
|
logv("(f:%s, l:%d) no_vbsinput_buffer, wait_done!", __FUNCTION__, __LINE__);
|
|
}
|
|
}
|
|
else if(decodeResult == VDECODE_RESULT_RESOLUTION_CHANGE)
|
|
{
|
|
resolution_change:
|
|
logd("set nResolutionChangeVdrvThreadFlag to 1, decode detect resolution change");
|
|
pSelf->nResolutionChangeVdrvThreadFlag = OMX_TRUE;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
msg.messageId = MAIN_THREAD_CMD_VDRV_RESOLUTION_CHANGE;
|
|
msg.params[0] = 1;
|
|
CdcMessageQueuePostMessage(pSelf->mqMainThread, &msg);
|
|
}
|
|
else if(decodeResult < 0)
|
|
{
|
|
logw("decode fatal error[%d]", decodeResult);
|
|
//* report a fatal error.
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError, OMX_ErrorHardware,
|
|
0, NULL);
|
|
}
|
|
else
|
|
{
|
|
logd("decode ret[%d], ignore? why?", decodeResult);
|
|
}
|
|
}
|
|
|
|
static inline void decoderResolutionChange(omx_vdec* pSelf)
|
|
{
|
|
logv("***ReopenVideoEngine!");
|
|
VConfig m_videoConfig;
|
|
memset(&m_videoConfig,0,sizeof(VConfig));
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
pSelf->bFlushAllFrameFlag = OMX_TRUE;
|
|
|
|
SemTimedWait(&pSelf->m_semFlushAllFrame, -1);
|
|
|
|
msg.messageId = RENDER_THREAD_CMD_PAUSE;
|
|
CdcMessageQueuePostMessage(pSelf->mqRenderThread, &msg);
|
|
SemTimedWait(&pSelf->m_render_cmd_lock, -1);
|
|
|
|
ReopenVideoEngine(pSelf->m_decoder, &(pSelf->m_videoConfig), &(pSelf->m_streamInfo));
|
|
pSelf->mResolutionChangeFlag = OMX_FALSE;
|
|
pSelf->nVdrvResolutionChangeFlag = OMX_FALSE;
|
|
pSelf->mHadGetVideoFbmBufInfoFlag = OMX_FALSE;
|
|
tryPostSem(&pSelf->m_semResolutionChange);
|
|
|
|
msg.messageId = RENDER_THREAD_CMD_EXECUT;
|
|
CdcMessageQueuePostMessage(pSelf->mqRenderThread, &msg);
|
|
return ;
|
|
}
|
|
|
|
|
|
static inline int detectFirstStreamData(omx_vdec* pSelf)
|
|
{
|
|
OMX_BUFFERHEADERTYPE* pInBufHdr = NULL;
|
|
pInBufHdr = pSelf->m_sInBufList.pBufHdrList[pSelf->m_sInBufList.nReadPos];
|
|
|
|
if(pInBufHdr == NULL)
|
|
{
|
|
logd("(f:%s, l:%d) fatal error! pInBufHdr is NULL, check code!",
|
|
__FUNCTION__, __LINE__);
|
|
return OMX_RESULT_ERROR;
|
|
}
|
|
|
|
pSelf->mFirstInputDataFlag = OMX_FALSE;
|
|
logv("*** the first pInBufHdr->nFlags = 0x%x",(int)pInBufHdr->nFlags);
|
|
if (pInBufHdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
|
|
{
|
|
if(pSelf->m_streamInfo.pCodecSpecificData)
|
|
free(pSelf->m_streamInfo.pCodecSpecificData);
|
|
pSelf->m_streamInfo.nCodecSpecificDataLen = pInBufHdr->nFilledLen;
|
|
pSelf->m_streamInfo.pCodecSpecificData
|
|
= (char*)malloc(pSelf->m_streamInfo.nCodecSpecificDataLen);
|
|
memset(pSelf->m_streamInfo.pCodecSpecificData,0,
|
|
pSelf->m_streamInfo.nCodecSpecificDataLen);
|
|
memcpy(pSelf->m_streamInfo.pCodecSpecificData,
|
|
pInBufHdr->pBuffer,pSelf->m_streamInfo.nCodecSpecificDataLen);
|
|
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
msg.messageId = VDRV_THREAD_CMD_PREPARE_VDECODER;
|
|
|
|
CdcMessageQueuePostMessage(pSelf->mqVdrvThread, &msg);
|
|
sem_post(&pSelf->m_sem_vbs_input);
|
|
sem_post(&pSelf->m_sem_frame_output);
|
|
logd("(f:%s, l:%d) wait for VDRV_THREAD_CMD_PREPARE_VDECODER",
|
|
__FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_vdrv_cmd_lock, -1);
|
|
logd("(f:%s, l:%d) wait for VDRV_THREAD_CMD_PREPARE_VDECODER done!",
|
|
__FUNCTION__, __LINE__);
|
|
|
|
|
|
msg.messageId = RENDER_THREAD_CMD_START;
|
|
CdcMessageQueuePostMessage(pSelf->mqRenderThread, &msg);
|
|
|
|
pSelf->m_sInBufList.nSizeOfList--;
|
|
pSelf->m_sInBufList.nReadPos++;
|
|
if (pSelf->m_sInBufList.nReadPos >= (OMX_S32)pSelf->m_sInBufList.nAllocSize)
|
|
pSelf->m_sInBufList.nReadPos = 0;
|
|
|
|
pSelf->m_Callbacks.EmptyBufferDone(&pSelf->mOmxCmp, pSelf->m_pAppData, pInBufHdr);
|
|
}
|
|
else
|
|
{
|
|
if(!pSelf->mIsCyber)
|
|
{
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
msg.messageId = VDRV_THREAD_CMD_PREPARE_VDECODER;
|
|
|
|
CdcMessageQueuePostMessage(pSelf->mqVdrvThread, &msg);
|
|
sem_post(&pSelf->m_sem_vbs_input);
|
|
sem_post(&pSelf->m_sem_frame_output);
|
|
logd("(f:%s, l:%d) wait for VDRV_THREAD_CMD_PREPARE_VDECODER",
|
|
__FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_vdrv_cmd_lock, -1);
|
|
logd("(f:%s, l:%d) wait for VDRV_THREAD_CMD_PREPARE_VDECODER done!",
|
|
__FUNCTION__, __LINE__);
|
|
|
|
msg.messageId = RENDER_THREAD_CMD_START;
|
|
CdcMessageQueuePostMessage(pSelf->mqRenderThread, &msg);
|
|
}
|
|
}
|
|
return OMX_RESULT_OK;
|
|
}
|
|
|
|
static inline int checkResolutionChange(omx_vdec* pSelf, VideoPicture* picture)
|
|
{
|
|
//*here, we callback buffer_widht and buffer_height to ACodec
|
|
|
|
int width_align = 0;
|
|
int height_align = 0;
|
|
OMX_CONFIG_RECTTYPE mCurVideoRect;
|
|
memset(&mCurVideoRect, 0, sizeof(OMX_CONFIG_RECTTYPE));
|
|
|
|
if(pSelf->mIsFirstGetOffset)
|
|
{
|
|
pSelf->mVideoRect.nLeft = picture->nLeftOffset;
|
|
pSelf->mVideoRect.nTop = picture->nTopOffset;
|
|
pSelf->mVideoRect.nWidth = picture->nRightOffset - picture->nLeftOffset;
|
|
pSelf->mVideoRect.nHeight = picture->nBottomOffset - picture->nTopOffset;
|
|
pSelf->mIsFirstGetOffset = false;
|
|
}
|
|
|
|
mCurVideoRect.nLeft = picture->nLeftOffset;
|
|
mCurVideoRect.nTop = picture->nTopOffset;
|
|
mCurVideoRect.nWidth = picture->nRightOffset - picture->nLeftOffset;
|
|
mCurVideoRect.nHeight = picture->nBottomOffset - picture->nTopOffset;
|
|
|
|
if(pSelf->mCropEnable)
|
|
{
|
|
width_align = picture->nWidth;
|
|
height_align = picture->nHeight;
|
|
}
|
|
else
|
|
{
|
|
width_align = picture->nRightOffset - picture->nLeftOffset;
|
|
height_align = picture->nBottomOffset - picture->nTopOffset;
|
|
if(width_align <= 0 || height_align <= 0)
|
|
{
|
|
width_align = picture->nWidth;
|
|
height_align = picture->nHeight;
|
|
}
|
|
}
|
|
|
|
//* make the height to 2 align
|
|
height_align = (height_align + 1) & ~1;
|
|
|
|
if((OMX_U32)width_align != pSelf->m_sOutPortDefType.format.video.nFrameWidth
|
|
|| (OMX_U32)height_align != pSelf->m_sOutPortDefType.format.video.nFrameHeight
|
|
|| (mCurVideoRect.nLeft != pSelf->mVideoRect.nLeft)
|
|
|| (mCurVideoRect.nTop != pSelf->mVideoRect.nTop)
|
|
|| (mCurVideoRect.nWidth != pSelf->mVideoRect.nWidth)
|
|
|| (mCurVideoRect.nHeight != pSelf->mVideoRect.nHeight))
|
|
{
|
|
logw(" port setting changed -- old info : widht = %d, height = %d, \
|
|
mVideoRect: %d, %d, %d, %d ",
|
|
(int)pSelf->m_sOutPortDefType.format.video.nFrameWidth,
|
|
(int)pSelf->m_sOutPortDefType.format.video.nFrameHeight,
|
|
(int)pSelf->mVideoRect.nTop,(int)pSelf->mVideoRect.nLeft,
|
|
(int)pSelf->mVideoRect.nWidth,(int)pSelf->mVideoRect.nHeight);
|
|
logw(" port setting changed -- new info : widht = %d, height = %d, \
|
|
mVideoRect: %d, %d, %d, %d ",
|
|
(int)width_align, (int)height_align,
|
|
(int)mCurVideoRect.nTop,(int)mCurVideoRect.nLeft,
|
|
(int)mCurVideoRect.nWidth,(int)mCurVideoRect.nHeight);
|
|
|
|
memcpy(&pSelf->mVideoRect, &mCurVideoRect, sizeof(OMX_CONFIG_RECTTYPE));
|
|
pSelf->m_sOutPortDefType.format.video.nFrameHeight = height_align;
|
|
pSelf->m_sOutPortDefType.format.video.nFrameWidth = width_align;
|
|
pSelf->m_sOutPortDefType.format.video.nStride = width_align;
|
|
pSelf->m_sOutPortDefType.format.video.nSliceHeight = height_align;
|
|
pSelf->m_sOutPortDefType.nBufferSize = height_align*width_align *3/2;
|
|
pSelf->port_setting_match = OMX_FALSE;
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventPortSettingsChanged, 0x01, 0, NULL);
|
|
return OMX_RESOLUTION_CHANGE;
|
|
}
|
|
return OMX_RESULT_OK;
|
|
}
|
|
|
|
static inline void copyPictureDataToAndroidBuffer(omx_vdec* pSelf,
|
|
VideoPicture* picture,
|
|
OMX_BUFFERHEADERTYPE* pOutBufHdr)
|
|
{
|
|
int64_t nTimeUs1 = 0;
|
|
int64_t nTimeUs2 = 0;
|
|
OutPutBufferInfo mOutPutBufferInfo;
|
|
memset(&mOutPutBufferInfo, 0 ,sizeof(OutPutBufferInfo));
|
|
|
|
#ifdef __ANDROID__
|
|
|
|
#if (OPEN_STATISTICS)
|
|
nTimeUs1 = OMX_GetNowUs();
|
|
#endif
|
|
|
|
void* dst;
|
|
buffer_handle_t pBufferHandle = NULL;
|
|
|
|
android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
|
|
|
|
//*when lock gui buffer, we must according gui buffer's width and height, not by decoder!
|
|
android::Rect bounds(pSelf->m_sOutPortDefType.format.video.nFrameWidth,
|
|
pSelf->m_sOutPortDefType.format.video.nFrameHeight);
|
|
|
|
#ifdef CONF_KITKAT_AND_NEWER
|
|
if(pSelf->m_storeOutputMetaDataFlag ==OMX_TRUE)
|
|
{
|
|
VideoDecoderOutputMetaData *pMetaData
|
|
= (VideoDecoderOutputMetaData*)pOutBufHdr->pBuffer;
|
|
pBufferHandle = pMetaData->pHandle;
|
|
}
|
|
else
|
|
pBufferHandle = (buffer_handle_t)pOutBufHdr->pBuffer;
|
|
#else
|
|
pBufferHandle = (buffer_handle_t)pOutBufHdr->pBuffer;
|
|
#endif
|
|
|
|
if(0 != mapper.lock(pBufferHandle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst))
|
|
{
|
|
logw("Lock GUIBuf fail!");
|
|
}
|
|
|
|
//TransformMB32ToYV12(&picture, dst);
|
|
|
|
if(pSelf->mCropEnable)
|
|
{
|
|
memcpy(dst,picture->pData0,picture->nWidth*picture->nHeight*3/2);
|
|
}
|
|
else
|
|
{
|
|
mOutPutBufferInfo.pAddr = dst;
|
|
mOutPutBufferInfo.nWidth = pSelf->m_sOutPortDefType.format.video.nFrameWidth;
|
|
mOutPutBufferInfo.nHeight = pSelf->m_sOutPortDefType.format.video.nFrameHeight;
|
|
if(pSelf->mVp9orH265SoftDecodeFlag==OMX_TRUE)
|
|
TransformYV12ToYV12Soft(picture, &mOutPutBufferInfo);
|
|
else
|
|
TransformYV12ToYV12Hw(picture, &mOutPutBufferInfo);
|
|
}
|
|
|
|
if(0 != mapper.unlock(pBufferHandle))
|
|
{
|
|
logw("Unlock GUIBuf fail!");
|
|
}
|
|
|
|
#if (OPEN_STATISTICS)
|
|
nTimeUs2 = OMX_GetNowUs();
|
|
pSelf->mConvertTotalDuration += (nTimeUs2-nTimeUs1);
|
|
pSelf->mConvertTotalCount++;
|
|
#endif
|
|
#endif
|
|
return ;
|
|
}
|
|
|
|
static inline void sendStreamDataToDecoder(omx_vdec* pSelf)
|
|
{
|
|
char* pBuf0;
|
|
char* pBuf1;
|
|
int size0;
|
|
int size1;
|
|
int require_size;
|
|
unsigned char* pData;
|
|
VideoStreamDataInfo DataInfo;
|
|
OMX_BUFFERHEADERTYPE* pInBufHdr = NULL;
|
|
//int nSemVal;
|
|
//int nRetSemGetValue;
|
|
int ret = -1;
|
|
|
|
memset(&DataInfo, 0, sizeof(VideoStreamDataInfo));
|
|
pInBufHdr = pSelf->m_sInBufList.pBufHdrList[pSelf->m_sInBufList.nReadPos];
|
|
|
|
if(pInBufHdr == NULL)
|
|
{
|
|
logd("(f:%s, l:%d) fatal error! pInBufHdr is NULL, check code!",
|
|
__FUNCTION__, __LINE__);
|
|
return ;
|
|
}
|
|
|
|
//*add stream to decoder.
|
|
require_size = pInBufHdr->nFilledLen;
|
|
ret = RequestVideoStreamBuffer(pSelf->m_decoder, require_size,
|
|
&pBuf0, &size0, &pBuf1, &size1,0);
|
|
if(ret != 0)
|
|
{
|
|
logv("(f:%s, l:%d)req vbs fail! maybe vbs buffer is full! require_size[%d]",
|
|
__FUNCTION__, __LINE__, require_size);
|
|
return ;
|
|
}
|
|
|
|
DataInfo.nLength = require_size;
|
|
DataInfo.bIsFirstPart = 1;
|
|
DataInfo.bIsLastPart = 1;
|
|
DataInfo.pData = pBuf0;
|
|
if(pInBufHdr->nTimeStamp >= 0)
|
|
{
|
|
DataInfo.nPts = pInBufHdr->nTimeStamp;
|
|
DataInfo.bValid = 1;
|
|
}
|
|
else
|
|
{
|
|
DataInfo.nPts = -1;
|
|
DataInfo.bValid = 0;
|
|
}
|
|
|
|
if(require_size <= size0)
|
|
{
|
|
pData = pInBufHdr->pBuffer + pInBufHdr->nOffset;
|
|
memcpy(pBuf0, pData, require_size);
|
|
}
|
|
else
|
|
{
|
|
pData = pInBufHdr->pBuffer + pInBufHdr->nOffset;
|
|
memcpy(pBuf0, pData, size0);
|
|
pData += size0;
|
|
memcpy(pBuf1, pData, require_size - size0);
|
|
}
|
|
SubmitVideoStreamData(pSelf->m_decoder, &DataInfo,0);
|
|
|
|
//*Check for EOS flag
|
|
if (pInBufHdr)
|
|
{
|
|
if ((pInBufHdr->nFlags & OMX_BUFFERFLAG_EOS))
|
|
{
|
|
//*Copy flag to output buffer header
|
|
pSelf->nInBufEos = OMX_TRUE;
|
|
usleep(5*1000);
|
|
if(pSelf->m_OutputNum > 0)
|
|
{
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
msg.messageId = VDRV_THREAD_CMD_EndOfStream;
|
|
|
|
CdcMessageQueuePostMessage(pSelf->mqVdrvThread, &msg);
|
|
sem_post(&pSelf->m_sem_vbs_input);
|
|
sem_post(&pSelf->m_sem_frame_output);
|
|
logd("(f:%s) wait for VDRV_THREAD_CMD_EndOfStream", __FUNCTION__);
|
|
SemTimedWait(&pSelf->m_vdrv_cmd_lock, -1);
|
|
logd("(f:%s) wait for VDRV_THREAD_CMD_EndOfStream done!", __FUNCTION__);
|
|
logd(" set up nInBufEos flag.");
|
|
//*Trigger event handler
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventBufferFlag, 0x1,
|
|
pInBufHdr->nFlags, NULL);
|
|
//*Clear flag
|
|
pInBufHdr->nFlags = 0;
|
|
pSelf->nInBufEos = OMX_FALSE;
|
|
}
|
|
}
|
|
//*Check for mark buffers
|
|
if (pInBufHdr->pMarkData)
|
|
{
|
|
if (pSelf->pMarkData == NULL && pSelf->hMarkTargetComponent == NULL)
|
|
{
|
|
pSelf->pMarkData = pInBufHdr->pMarkData;
|
|
pSelf->hMarkTargetComponent = pInBufHdr->hMarkTargetComponent;
|
|
}
|
|
}
|
|
//*Trigger event handler
|
|
if (pInBufHdr->hMarkTargetComponent == &pSelf->mOmxCmp && pInBufHdr->pMarkData)
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventMark, 0, 0, pInBufHdr->pMarkData);
|
|
}
|
|
}
|
|
|
|
pSelf->m_Callbacks.EmptyBufferDone(&pSelf->mOmxCmp, pSelf->m_pAppData, pInBufHdr);
|
|
//*notify vdrvThread vbs input
|
|
tryPostSem(&pSelf->m_sem_vbs_input);
|
|
|
|
//* check if there is a input bit stream.
|
|
pthread_mutex_lock(&pSelf->m_inBufMutex);
|
|
|
|
pSelf->m_sInBufList.nSizeOfList--;
|
|
pSelf->m_sInBufList.nReadPos++;
|
|
if (pSelf->m_sInBufList.nReadPos >= (OMX_S32)pSelf->m_sInBufList.nAllocSize)
|
|
pSelf->m_sInBufList.nReadPos = 0;
|
|
|
|
/*for cts, using for synchronization between inputbuffer and outputbuffer*/
|
|
pSelf->m_InputNum ++;
|
|
if ((pSelf->mIsFromCts == true)/* && ((pSelf->m_InputNum - pSelf->m_OutputNum) > 3)*/)
|
|
{
|
|
usleep(20000);
|
|
}
|
|
else
|
|
{
|
|
usleep(10000);
|
|
}
|
|
pthread_mutex_unlock(&pSelf->m_inBufMutex);
|
|
|
|
}
|
|
|
|
static OMX_BUFFERHEADERTYPE* drainOutBufferProgressive(omx_vdec* pSelf)
|
|
{
|
|
OMX_U32 i = 0;
|
|
int64_t nTransformTimeBefore;
|
|
int64_t nTransformTimeAfter;
|
|
VideoPicture* pPicture = NULL;
|
|
OMX_BUFFERHEADERTYPE* pOutBufHdr = NULL;
|
|
|
|
if(pSelf->bUseShareBuffer == OMX_TRUE)
|
|
{
|
|
//* get the output buffer
|
|
pPicture = RequestPicture(pSelf->m_decoder, 0);
|
|
logv("gqy==========*** get picture[%p]",pPicture);
|
|
if(pPicture == NULL)
|
|
{
|
|
logw("the pPicture is null when request displayer picture!");
|
|
return NULL;
|
|
}
|
|
logv("*** picture info: w(%d),h(%d),offset,t(%d),b(%d),l(%d),r(%d)",
|
|
pPicture->nWidth,pPicture->nHeight,
|
|
pPicture->nTopOffset,pPicture->nBottomOffset,
|
|
pPicture->nLeftOffset,pPicture->nRightOffset);
|
|
OMX_MemFlushCache(pSelf->memops, pPicture->pData0,
|
|
pPicture->nWidth*pPicture->nHeight*3/2);
|
|
|
|
pSelf->mVideoRect.nLeft = pPicture->nLeftOffset;
|
|
pSelf->mVideoRect.nTop = pPicture->nTopOffset;
|
|
pSelf->mVideoRect.nWidth = pPicture->nRightOffset - pPicture->nLeftOffset;
|
|
pSelf->mVideoRect.nHeight = pPicture->nBottomOffset - pPicture->nTopOffset;
|
|
|
|
for(i = 0;i<pSelf->m_sOutBufList.nAllocSize;i++)
|
|
{
|
|
if(pSelf->mOutputBufferInfo[i].pVideoPicture == pPicture)
|
|
break;
|
|
}
|
|
|
|
if(i == pSelf->m_sOutBufList.nAllocSize)
|
|
{
|
|
loge("the picture request from decoder is not match");
|
|
abort();
|
|
}
|
|
|
|
//* we should return buffer to decoder if it was used as set eos to render
|
|
if(pSelf->mOutputBufferInfo[i].mUseDecoderBufferToSetEosFlag == OMX_TRUE)
|
|
{
|
|
logw("detect the buffer had been used to set eos to render,\
|
|
here, we not callback again!");
|
|
pSelf->mOutputBufferInfo[i].mStatus = OWNED_BY_RENDER;
|
|
pSelf->mOutputBufferInfo[i].mUseDecoderBufferToSetEosFlag = OMX_FALSE;
|
|
return NULL;
|
|
}
|
|
|
|
pOutBufHdr = pSelf->mOutputBufferInfo[i].pHeadBufInfo;
|
|
|
|
pSelf->mOutputBufferInfo[i].mStatus = OWNED_BY_RENDER;
|
|
logv("gqy=====render the picture========= i: %d, poutBufHdr = %p",
|
|
(int)i, pOutBufHdr);
|
|
//omxPrintOutListStatusDebug(pSelf);
|
|
//* set output buffer info
|
|
pOutBufHdr->nTimeStamp = pPicture->nPts;
|
|
pOutBufHdr->nOffset = 0;
|
|
|
|
}
|
|
else
|
|
{
|
|
pPicture = NextPictureInfo(pSelf->m_decoder,0);
|
|
if(pPicture == NULL)
|
|
return NULL;
|
|
|
|
if(checkResolutionChange(pSelf, pPicture) == OMX_RESOLUTION_CHANGE)
|
|
{
|
|
return NULL;
|
|
}
|
|
logv("gqy=============next");
|
|
pthread_mutex_lock(&pSelf->m_outBufMutex);
|
|
if(pSelf->m_sOutBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sOutBufList.nSizeOfList--;
|
|
pOutBufHdr = pSelf->m_sOutBufList.pBufHdrList[pSelf->m_sOutBufList.nReadPos++];
|
|
if (pSelf->m_sOutBufList.nReadPos >= (OMX_S32)pSelf->m_sOutBufList.nAllocSize)
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
}
|
|
else
|
|
pOutBufHdr = NULL;
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
|
|
if(pOutBufHdr == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pPicture = RequestPicture(pSelf->m_decoder, 0);
|
|
|
|
#if (OPEN_STATISTICS)
|
|
nTransformTimeBefore = OMX_GetNowUs();
|
|
#endif
|
|
|
|
OutPutBufferInfo mOutPutBufferInfo;
|
|
mOutPutBufferInfo.pAddr = pOutBufHdr->pBuffer;
|
|
mOutPutBufferInfo.nWidth = pSelf->m_sOutPortDefType.format.video.nFrameWidth;
|
|
mOutPutBufferInfo.nHeight = pSelf->m_sOutPortDefType.format.video.nFrameHeight;
|
|
|
|
OMX_MemFlushCache(pSelf->memops, pPicture->pData0,
|
|
pPicture->nWidth*pPicture->nHeight*3/2);
|
|
if(pSelf->mVp9orH265SoftDecodeFlag==OMX_TRUE)
|
|
TransformYV12ToYUV420Soft(pPicture, &mOutPutBufferInfo);
|
|
else
|
|
TransformYV12ToYUV420(pPicture, &mOutPutBufferInfo); // YUV420 planar
|
|
|
|
#if (OPEN_STATISTICS)
|
|
nTransformTimeAfter = OMX_GetNowUs();
|
|
pSelf->mConvertTotalDuration += (nTransformTimeAfter - nTransformTimeBefore);
|
|
pSelf->mConvertTotalCount++;
|
|
#endif
|
|
|
|
pOutBufHdr->nTimeStamp = pPicture->nPts;
|
|
pOutBufHdr->nOffset = 0;
|
|
|
|
ReturnPicture(pSelf->m_decoder, pPicture);
|
|
|
|
tryPostSem(&pSelf->m_sem_frame_output);
|
|
}
|
|
|
|
return pOutBufHdr;
|
|
|
|
}
|
|
|
|
void drainPicture(omx_vdec* pSelf)
|
|
{
|
|
OMX_U32 i = 0;
|
|
int64_t nTransformTimeBefore;
|
|
int64_t nTransformTimeAfter;
|
|
OMX_BUFFERHEADERTYPE* pOutBufHdr = NULL;
|
|
|
|
pOutBufHdr = drainOutBufferProgressive(pSelf);
|
|
|
|
if(pOutBufHdr == NULL)
|
|
return ;
|
|
|
|
|
|
#ifdef CONF_KITKAT_AND_NEWER
|
|
if(pSelf->m_storeOutputMetaDataFlag==OMX_TRUE)
|
|
pOutBufHdr->nFilledLen = sizeof(VideoDecoderOutputMetaData);
|
|
else
|
|
pOutBufHdr->nFilledLen = (pSelf->m_sOutPortDefType.format.video.nFrameWidth *
|
|
pSelf->m_sOutPortDefType.format.video.nFrameHeight)*3/2;
|
|
#else
|
|
pOutBufHdr->nFilledLen = (pSelf->m_sOutPortDefType.format.video.nFrameWidth *
|
|
pSelf->m_sOutPortDefType.format.video.nFrameHeight)*3/2;
|
|
#endif
|
|
|
|
//* Check for mark buffers
|
|
if (pSelf->pMarkData != NULL && pSelf->hMarkTargetComponent != NULL)
|
|
{
|
|
if(!ValidPictureNum(pSelf->m_decoder,0))
|
|
{
|
|
pOutBufHdr->pMarkData = pSelf->pMarkData;
|
|
pOutBufHdr->hMarkTargetComponent = pSelf->hMarkTargetComponent;
|
|
pSelf->pMarkData = NULL;
|
|
pSelf->hMarkTargetComponent = NULL;
|
|
}
|
|
}
|
|
|
|
logi("****FillBufferDone is called, nSizeOfList[%d], pts[%lld],\
|
|
nAllocLen[%d], nFilledLen[%d], nOffset[%d], nFlags[0x%x], \
|
|
nOutputPortIndex[%d], nInputPortIndex[%d]",
|
|
(int)pSelf->m_sOutBufList.nSizeOfList,pOutBufHdr->nTimeStamp,
|
|
(int)pOutBufHdr->nAllocLen,(int)pOutBufHdr->nFilledLen,
|
|
(int)pOutBufHdr->nOffset,(int)pOutBufHdr->nFlags,
|
|
(int)pOutBufHdr->nOutputPortIndex,(int)pOutBufHdr->nInputPortIndex);
|
|
|
|
pSelf->m_OutputNum ++;
|
|
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp, pSelf->m_pAppData, pOutBufHdr);
|
|
pOutBufHdr = NULL;
|
|
return ;
|
|
}
|
|
|
|
static int OmxVideoRequestOutputBuffer(omx_vdec* pSelf,
|
|
VideoPicture* pPicBufInfo,
|
|
OMX_BUFFERHEADERTYPE* pOutBufHdr,
|
|
OMX_BOOL mInitBufferFlag)
|
|
{
|
|
logv("*** OmxVideoRequestOutputBuffer: mInitBufferFlag(%d)",mInitBufferFlag);
|
|
|
|
OMX_U32 i;
|
|
int mYsize;
|
|
|
|
if(pOutBufHdr == NULL)
|
|
{
|
|
loge(" the pOutBufHdr is null when request OutPut Buffer");
|
|
return -1;
|
|
}
|
|
|
|
//* init the buffer
|
|
if(mInitBufferFlag == OMX_TRUE)
|
|
{
|
|
for(i = 0;i<pSelf->m_sOutBufList.nAllocSize;i++)
|
|
{
|
|
if(pSelf->mOutputBufferInfo[i].pHeadBufInfo == NULL)
|
|
break;
|
|
}
|
|
|
|
char* nVirAddress = (char*)pOutBufHdr->pBuffer;
|
|
char* nPhyAddress = (char*)OMX_MemGetPhysicAddress(pSelf->memops,nVirAddress);
|
|
nPhyAddress -= pSelf->nPhyOffset;
|
|
|
|
pSelf->mOutputBufferInfo[i].nVirAddrSize = pOutBufHdr->nAllocLen;
|
|
pSelf->mOutputBufferInfo[i].nBufFd = i;
|
|
pSelf->mOutputBufferInfo[i].pBufVirAddr = nVirAddress;
|
|
pSelf->mOutputBufferInfo[i].pBufPhyAddr = nPhyAddress;
|
|
pSelf->mOutputBufferInfo[i].pHeadBufInfo = pOutBufHdr;
|
|
}
|
|
|
|
for(i = 0;i<pSelf->m_sOutBufList.nAllocSize;i++)
|
|
{
|
|
if(pSelf->mOutputBufferInfo[i].pHeadBufInfo == pOutBufHdr)
|
|
break;
|
|
}
|
|
|
|
if(i == pSelf->m_sOutBufList.nAllocSize)
|
|
{
|
|
loge("*** the buffer address is not match");
|
|
abort();
|
|
}
|
|
mYsize = (pSelf->m_sOutPortDefType.format.video.nFrameWidth*
|
|
pSelf->m_sOutPortDefType.format.video.nFrameHeight);
|
|
pPicBufInfo->pData0 = pSelf->mOutputBufferInfo[i].pBufVirAddr;
|
|
pPicBufInfo->pData1 = pPicBufInfo->pData0 + mYsize;
|
|
pPicBufInfo->phyYBufAddr = (uintptr_t)pSelf->mOutputBufferInfo[i].pBufPhyAddr;
|
|
pPicBufInfo->phyCBufAddr = pPicBufInfo->phyYBufAddr + mYsize;
|
|
pPicBufInfo->nBufId = i;
|
|
pPicBufInfo->pPrivate = NULL;
|
|
pPicBufInfo->nBufFd = pSelf->mOutputBufferInfo[i].nBufFd;
|
|
pPicBufInfo->nWidth = pSelf->m_sOutPortDefType.format.video.nFrameWidth;
|
|
pPicBufInfo->nHeight = pSelf->m_sOutPortDefType.format.video.nFrameHeight;
|
|
pPicBufInfo->nLineStride = pSelf->m_sOutPortDefType.format.video.nFrameWidth;
|
|
pPicBufInfo->pMetaData = NULL;
|
|
|
|
pSelf->mOutputBufferInfo[i].mStatus = OWNED_BY_DECODER;
|
|
logv("gqy=====return the pictue========== i: %d", (int)i);
|
|
|
|
//omxPrintOutListStatusDebug(pSelf);
|
|
#if 0
|
|
if(pSelf->mIs4KAlignFlag == OMX_TRUE)
|
|
{
|
|
uintptr_t tmpAddr = (uintptr_t)pPicBufInfo->pData1;
|
|
tmpAddr = (tmpAddr + 4095) & ~4095;
|
|
|
|
pPicBufInfo->pData1 = (char *)tmpAddr;
|
|
pPicBufInfo->phyCBufAddr = (pPicBufInfo->phyCBufAddr + 4095) & ~4095;
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
static inline int OmxGetVideoFbmBufInfo(omx_vdec* pSelf)
|
|
{
|
|
FbmBufInfo* pFbmBufInfo = GetVideoFbmBufInfo(pSelf->m_decoder);
|
|
|
|
logv("pFbmBufInfo = %p, m_decoder(%p)",pFbmBufInfo,pSelf->m_decoder);
|
|
|
|
if(pFbmBufInfo != NULL)
|
|
{
|
|
logi("video buffer info: nWidth[%d],nHeight[%d],nBufferCount[%d],ePixelFormat[%d]",
|
|
pFbmBufInfo->nBufWidth,pFbmBufInfo->nBufHeight,
|
|
pFbmBufInfo->nBufNum,pFbmBufInfo->ePixelFormat);
|
|
logi("video buffer info: nAlignValue[%d],bProgressiveFlag[%d],bIsSoftDecoderFlag[%d]",
|
|
pFbmBufInfo->nAlignValue,pFbmBufInfo->bProgressiveFlag,
|
|
pFbmBufInfo->bIsSoftDecoderFlag);
|
|
|
|
if(pFbmBufInfo->nBufNum > (OMX_MAX_VIDEO_BUFFER_NUM - 2))
|
|
pFbmBufInfo->nBufNum = OMX_MAX_VIDEO_BUFFER_NUM - 2;
|
|
|
|
pSelf->mOutBufferNumDecoderNeed = pFbmBufInfo->nBufNum;
|
|
pSelf->mOutBufferKeepInOmxNum = 0;
|
|
|
|
OMX_BOOL bBufferNumMatchFlag = OMX_FALSE;
|
|
if(pFbmBufInfo->nBufWidth >= 3840 || pFbmBufInfo->nBufHeight >= 2160)
|
|
{
|
|
//* as buffer size is too big, we should not palloc redundance buffer
|
|
if(pSelf->m_sOutPortDefType.nBufferCountActual == (OMX_U32)pFbmBufInfo->nBufNum)
|
|
bBufferNumMatchFlag = OMX_TRUE;
|
|
}
|
|
else
|
|
{
|
|
//* if init-buffer-num is equal to or more than real-buffer-num,
|
|
//* not callback the event "OMX_EventPortSettingsChanged" to avoid remalloc buffer
|
|
//* which cost some time
|
|
if(pSelf->m_sOutPortDefType.nBufferCountActual >= (OMX_U32)pFbmBufInfo->nBufNum)
|
|
bBufferNumMatchFlag = OMX_TRUE;
|
|
}
|
|
logv("*** bBufferNumMatchFlag = %d",bBufferNumMatchFlag);
|
|
OMX_U32 nInitWidht = pSelf->m_sOutPortDefType.format.video.nFrameWidth;
|
|
OMX_U32 nInitHeight = pSelf->m_sOutPortDefType.format.video.nFrameHeight;
|
|
OMX_U32 nInitBufferSize = pSelf->m_sOutPortDefType.nBufferSize;
|
|
if(bBufferNumMatchFlag == OMX_TRUE
|
|
&& nInitWidht == (OMX_U32)pFbmBufInfo->nBufWidth
|
|
&& nInitHeight == (OMX_U32)pFbmBufInfo->nBufHeight
|
|
/*
|
|
&& nInitBufferSize == (OMX_U32)(pFbmBufInfo->nBufWidth*pFbmBufInfo->nBufHeight*3/2)*/)
|
|
{
|
|
if(pSelf->m_sOutPortDefType.nBufferCountActual > (OMX_U32)pFbmBufInfo->nBufNum)
|
|
{
|
|
pSelf->mOutBufferKeepInOmxNum
|
|
= pSelf->m_sOutPortDefType.nBufferCountActual - pFbmBufInfo->nBufNum;
|
|
}
|
|
logd("m_sOutPortDefType is already matched, mOutBufferKeepInOmxNum = %ld",
|
|
pSelf->mOutBufferKeepInOmxNum);
|
|
return 0;
|
|
}
|
|
logd("************** port setting change ************");
|
|
logd("**** buffer num: %lu, %d; w&h: %lu, %lu, %d, %d",
|
|
pSelf->m_sOutPortDefType.nBufferCountActual,
|
|
pFbmBufInfo->nBufNum,
|
|
nInitWidht, nInitHeight,
|
|
pFbmBufInfo->nBufWidth,
|
|
pFbmBufInfo->nBufHeight);
|
|
|
|
pSelf->port_setting_match = OMX_FALSE;
|
|
|
|
pSelf->mVideoRect.nLeft = pFbmBufInfo->nLeftOffset;
|
|
pSelf->mVideoRect.nTop = pFbmBufInfo->nTopOffset;
|
|
pSelf->mVideoRect.nWidth = pFbmBufInfo->nRightOffset - pFbmBufInfo->nLeftOffset;
|
|
pSelf->mVideoRect.nHeight = pFbmBufInfo->nBottomOffset - pFbmBufInfo->nTopOffset;
|
|
#ifdef CONF_OMX_ENABLE_EXTERN_MEM
|
|
SunxiMemSetActualSize(pSelf->memops,pSelf->mVideoRect.nWidth,pSelf->mVideoRect.nHeight);
|
|
#endif
|
|
pSelf->m_sOutPortDefType.nBufferCountMin
|
|
= pFbmBufInfo->nBufNum - pSelf->mExtraOutBufferNum;
|
|
pSelf->m_sOutPortDefType.nBufferCountActual
|
|
= pFbmBufInfo->nBufNum - pSelf->mExtraOutBufferNum;
|
|
pSelf->m_sOutPortDefType.nBufferAlignment = pSelf->mGpuAlignStride;
|
|
pSelf->m_sOutPortDefType.format.video.nFrameWidth = pFbmBufInfo->nBufWidth;
|
|
pSelf->m_sOutPortDefType.format.video.nFrameHeight = pFbmBufInfo->nBufHeight;
|
|
pSelf->m_sOutPortDefType.format.video.nStride = pFbmBufInfo->nBufWidth;
|
|
pSelf->m_sOutPortDefType.format.video.nSliceHeight = pFbmBufInfo->nBufHeight;
|
|
pSelf->m_sOutPortDefType.nBufferSize = pFbmBufInfo->nBufWidth*pFbmBufInfo->nBufHeight *3/2;
|
|
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventPortSettingsChanged, 0x01, 0, NULL);
|
|
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
static inline int OmxReturnBufferToDecoder(omx_vdec* pSelf)
|
|
{
|
|
OMX_U32 i = 0;
|
|
int mRet = -1;
|
|
OMX_BOOL mInitBufferFlag = OMX_FALSE;
|
|
VideoPicture mVideoPicture;
|
|
VideoPicture* pVideoPicture = NULL;
|
|
OMX_BUFFERHEADERTYPE* pOutBufHdr = NULL;
|
|
OMX_S32 nForbitUseFlag = 0;
|
|
memset(&mVideoPicture, 0, sizeof(VideoPicture));
|
|
|
|
if(pSelf->mNeedReSetToDecoderBufferNum > 0)
|
|
{
|
|
pthread_mutex_lock(&pSelf->m_outBufMutex);
|
|
|
|
pOutBufHdr = pSelf->m_sOutBufList.pBufHdrList[pSelf->m_sOutBufList.nReadPos];
|
|
logv("gqy=== readpos = %d", (int)pSelf->m_sOutBufList.nReadPos);
|
|
for(i=0; i< pSelf->m_sOutBufList.nAllocSize; i++)
|
|
{
|
|
if(pOutBufHdr == pSelf->mOutputBufferInfo[i].pHeadBufInfo)
|
|
break;
|
|
}
|
|
|
|
if(i < pSelf->m_sOutBufList.nAllocSize)
|
|
mInitBufferFlag = OMX_FALSE;
|
|
else
|
|
mInitBufferFlag = OMX_TRUE;
|
|
|
|
if(mInitBufferFlag == OMX_TRUE)
|
|
{
|
|
if(RequestReleasePicture(pSelf->m_decoder) != NULL)
|
|
{
|
|
mRet = OmxVideoRequestOutputBuffer(pSelf, &mVideoPicture,
|
|
pOutBufHdr, mInitBufferFlag);
|
|
if(mRet == 0)
|
|
{
|
|
pSelf->mSetToDecoderBufferNum++;
|
|
pSelf->mNeedReSetToDecoderBufferNum--;
|
|
pVideoPicture = ReturnRelasePicture(pSelf->m_decoder,
|
|
&mVideoPicture, 0);
|
|
pSelf->mOutputBufferInfo[mVideoPicture.nBufId].pVideoPicture = pVideoPicture;
|
|
}
|
|
else
|
|
{
|
|
loge("request output buffer error!");
|
|
abort();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
logw("** can not reqeust release picture");
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mRet = OmxVideoRequestOutputBuffer(pSelf, &mVideoPicture, pOutBufHdr, mInitBufferFlag);
|
|
if(mRet == 0)
|
|
{
|
|
//* we should not return to decoder again if it had been used to set eos to render
|
|
if(pSelf->mOutputBufferInfo[i].mUseDecoderBufferToSetEosFlag == OMX_TRUE)
|
|
{
|
|
pSelf->mOutputBufferInfo[i].mUseDecoderBufferToSetEosFlag = OMX_FALSE;
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
return 0;
|
|
}
|
|
pVideoPicture = pSelf->mOutputBufferInfo[i].pVideoPicture;
|
|
ReturnPicture(pSelf->m_decoder, pVideoPicture);
|
|
tryPostSem(&pSelf->m_sem_frame_output);
|
|
}
|
|
}
|
|
|
|
pSelf->m_sOutBufList.nSizeOfList--;
|
|
pSelf->m_sOutBufList.nReadPos++;
|
|
if (pSelf->m_sOutBufList.nReadPos >= (OMX_S32)pSelf->m_sOutBufList.nAllocSize)
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
|
|
}
|
|
else
|
|
{
|
|
pthread_mutex_lock(&pSelf->m_outBufMutex);
|
|
|
|
if(pSelf->m_sOutBufList.nSizeOfList> 0)
|
|
{
|
|
pSelf->m_sOutBufList.nSizeOfList--;
|
|
pOutBufHdr = pSelf->m_sOutBufList.pBufHdrList[pSelf->m_sOutBufList.nReadPos++];
|
|
if (pSelf->m_sOutBufList.nReadPos >= (OMX_S32)pSelf->m_sOutBufList.nAllocSize)
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
}
|
|
else
|
|
pOutBufHdr = NULL;
|
|
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
|
|
if(pOutBufHdr != NULL)
|
|
{
|
|
for(i=0; i< pSelf->m_sOutBufList.nAllocSize; i++)
|
|
{
|
|
if(pOutBufHdr == pSelf->mOutputBufferInfo[i].pHeadBufInfo)
|
|
break;
|
|
}
|
|
|
|
if(i < pSelf->m_sOutBufList.nAllocSize)
|
|
mInitBufferFlag = OMX_FALSE;
|
|
else
|
|
mInitBufferFlag = OMX_TRUE;
|
|
|
|
// omxPrintOutListStatusDebug(pSelf);
|
|
mRet = OmxVideoRequestOutputBuffer(pSelf, &mVideoPicture, pOutBufHdr, mInitBufferFlag);
|
|
if(mRet == 0)
|
|
{
|
|
if(mInitBufferFlag == OMX_TRUE)
|
|
{
|
|
pSelf->mSetToDecoderBufferNum++;
|
|
pVideoPicture = SetVideoFbmBufAddress(pSelf->m_decoder,
|
|
&mVideoPicture, 0);
|
|
//*notify vdrvThread free frame
|
|
tryPostSem(&pSelf->m_sem_frame_output);
|
|
|
|
pSelf->mOutputBufferInfo[mVideoPicture.nBufId].pVideoPicture = pVideoPicture;
|
|
logi("*** call SetVideoFbmBufAddress: pVideoPicture(%p)",pVideoPicture);
|
|
}
|
|
else
|
|
{
|
|
//* we should not return to decoder again
|
|
//* if it had been used to set eos to render
|
|
if(pSelf->mOutputBufferInfo[i].mUseDecoderBufferToSetEosFlag == OMX_TRUE)
|
|
{
|
|
pSelf->mOutputBufferInfo[i].mUseDecoderBufferToSetEosFlag = OMX_FALSE;
|
|
return 0;
|
|
}
|
|
pVideoPicture = pSelf->mOutputBufferInfo[i].pVideoPicture;
|
|
ReturnPicture(pSelf->m_decoder, pVideoPicture);
|
|
tryPostSem(&pSelf->m_sem_frame_output);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
static inline void processOutputEosFlag(omx_vdec* pSelf)
|
|
{
|
|
OMX_BUFFERHEADERTYPE* pOutBufHdr = NULL;
|
|
//*set eos flag, MediaCodec use this flag
|
|
// to determine whether a playback is finished.
|
|
pthread_mutex_lock(&pSelf->m_outBufMutex);
|
|
if(pSelf->m_sOutBufList.nSizeOfList > 0)
|
|
{
|
|
while (pSelf->m_sOutBufList.nSizeOfList > 0)
|
|
{
|
|
pSelf->m_sOutBufList.nSizeOfList--;
|
|
pOutBufHdr = pSelf->m_sOutBufList.pBufHdrList[pSelf->m_sOutBufList.nReadPos++];
|
|
if (pSelf->m_sOutBufList.nReadPos >= (OMX_S32)pSelf->m_sOutBufList.nAllocSize)
|
|
{
|
|
pSelf->m_sOutBufList.nReadPos = 0;
|
|
}
|
|
|
|
if(pOutBufHdr==NULL)
|
|
continue;
|
|
|
|
if (pOutBufHdr->nFilledLen != 0)
|
|
{
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp, pSelf->m_pAppData, pOutBufHdr);
|
|
pOutBufHdr = NULL;
|
|
}
|
|
else
|
|
{
|
|
pOutBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp, pSelf->m_pAppData, pOutBufHdr);
|
|
pOutBufHdr = NULL;
|
|
pSelf->nInBufEos = OMX_FALSE;
|
|
pSelf->nVdrvNotifyEosFlag = OMX_FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(pSelf->bUseShareBuffer == OMX_TRUE)
|
|
{
|
|
OMX_U32 i = 0;
|
|
for(i = 0; i<pSelf->m_sOutBufList.nAllocSize; i++)
|
|
{
|
|
if(pSelf->mOutputBufferInfo[i].mStatus == OWNED_BY_DECODER)
|
|
break;
|
|
}
|
|
if(i == pSelf->m_sOutBufList.nAllocSize)
|
|
{
|
|
logw("** have no buffer to set eos, try again");
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
//abort();
|
|
return ;
|
|
}
|
|
logd("*** set out eos(use buffer owned by decoder), pic = %p",
|
|
pSelf->mOutputBufferInfo[i].pVideoPicture);
|
|
OMX_BUFFERHEADERTYPE* pOutBufHdr = pSelf->mOutputBufferInfo[i].pHeadBufInfo;
|
|
pOutBufHdr->nFilledLen = 0;
|
|
pOutBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
|
|
pSelf->m_Callbacks.FillBufferDone(&pSelf->mOmxCmp, pSelf->m_pAppData, pOutBufHdr);
|
|
pSelf->nVdrvNotifyEosFlag = OMX_FALSE;
|
|
pSelf->nInBufEos = OMX_FALSE;
|
|
pSelf->mOutputBufferInfo[i].mStatus = OWNED_BY_RENDER;
|
|
pSelf->mOutputBufferInfo[i].mUseDecoderBufferToSetEosFlag = OMX_TRUE;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&pSelf->m_outBufMutex);
|
|
return ;
|
|
}
|
|
|
|
static inline int processThreadCommand(omx_vdec* pSelf, CdcMessage* pMsg)
|
|
{
|
|
int cmd = pMsg->messageId;
|
|
uintptr_t cmddata = pMsg->params[0];
|
|
logv("processThreadCommand cmd = %d", cmd);
|
|
|
|
//*State transition command
|
|
if (cmd == MAIN_THREAD_CMD_SET_STATE)
|
|
{
|
|
logd(" set state command, cmd = %d, cmddata = %d.", (int)cmd, (int)cmddata);
|
|
//*If the parameter states a transition to the same state
|
|
// raise a same state transition error.
|
|
if (pSelf->m_state == (OMX_STATETYPE)(cmddata))
|
|
{
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventError, OMX_ErrorSameState, 0 , NULL);
|
|
}
|
|
else
|
|
{
|
|
controlSetState(pSelf, (OMX_U32)cmddata);
|
|
}
|
|
}
|
|
else if (cmd == MAIN_THREAD_CMD_STOP_PORT)
|
|
{
|
|
controlStopPort(pSelf, (OMX_U32)cmddata);
|
|
}
|
|
else if (cmd == MAIN_THREAD_CMD_RESTART_PORT)
|
|
{
|
|
controlRestartPort(pSelf, (OMX_U32)cmddata);
|
|
}
|
|
else if (cmd == MAIN_THREAD_CMD_FLUSH)
|
|
{
|
|
controlFlush(pSelf, (OMX_U32)cmddata);
|
|
}
|
|
else if (cmd == MAIN_THREAD_CMD_STOP)
|
|
{
|
|
logd(" stop command.");
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
|
|
msg.messageId = RENDER_THREAD_CMD_EXIT;
|
|
CdcMessageQueuePostMessage(pSelf->mqRenderThread, &msg);
|
|
logd("(f:%s, l:%d) wait for quit render ", __FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_render_cmd_lock, -1);
|
|
logd("(f:%s, l:%d) wait for quit render done!", __FUNCTION__, __LINE__);
|
|
|
|
msg.messageId = VDRV_THREAD_CMD_STOP_VDECODER;
|
|
|
|
CdcMessageQueuePostMessage(pSelf->mqVdrvThread, &msg);
|
|
sem_post(&pSelf->m_sem_vbs_input);
|
|
sem_post(&pSelf->m_sem_frame_output);
|
|
logd("(f:%s, l:%d) wait for VDRV_THREAD_CMD_STOP_VDECODER", __FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_vdrv_cmd_lock, -1);
|
|
logd("(f:%s, l:%d) wait for VDRV_THREAD_CMD_STOP_VDECODER done!", __FUNCTION__, __LINE__);
|
|
//*Kill thread
|
|
return OMX_RESULT_EXIT;
|
|
}
|
|
else if (cmd == MAIN_THREAD_CMD_FILL_BUF)
|
|
{
|
|
controlFillBuf(pSelf, (OMX_U32)cmddata);
|
|
}
|
|
else if (cmd == MAIN_THREAD_CMD_EMPTY_BUF)
|
|
{
|
|
controlEmptyBuf(pSelf, (OMX_U32)cmddata);
|
|
}
|
|
else if (cmd == MAIN_THREAD_CMD_MARK_BUF)
|
|
{
|
|
if (!pSelf->pMarkBuf)
|
|
pSelf->pMarkBuf = (OMX_MARKTYPE *)(cmddata);
|
|
}
|
|
else if(cmd == MAIN_THREAD_CMD_VDRV_NOTIFY_EOS)
|
|
{
|
|
pSelf->nVdrvNotifyEosFlag = OMX_TRUE;
|
|
}
|
|
else if(cmd == MAIN_THREAD_CMD_VDRV_RESOLUTION_CHANGE)
|
|
{
|
|
//pSelf->mResolutionChangeFlag = (OMX_BOOL)cmddata;
|
|
pSelf->nResolutionChangeNativeThreadFlag = (OMX_BOOL)cmddata;
|
|
logd(" set nResolutionChangeNativeThreadFlag to %d",
|
|
(int)pSelf->nResolutionChangeNativeThreadFlag);
|
|
}
|
|
else
|
|
{
|
|
logw("(f:%s, l:%d) ", __FUNCTION__, __LINE__);
|
|
}
|
|
return OMX_RESULT_OK;
|
|
}
|
|
|
|
static inline int processVdrvThreadCommand(omx_vdec* pSelf, CdcMessage* pMsg)
|
|
{
|
|
int cmd = pMsg->messageId;
|
|
logd("(f:%s, l:%d) vdrvThread receive cmd[0x%x]", __FUNCTION__, __LINE__, cmd);
|
|
// State transition command
|
|
//now omx_vdec's m_state = OMX_StateLoaded, OMX_StateLoaded->OMX_StateIdle
|
|
if (cmd == VDRV_THREAD_CMD_PREPARE_VDECODER)
|
|
{
|
|
vdecoderPrepare(pSelf);
|
|
}
|
|
// now omx_vdec's m_state = OMX_StateLoaded, OMX_StateIdle->OMX_StateLoaded
|
|
else if (cmd == VDRV_THREAD_CMD_CLOSE_VDECODER)
|
|
{
|
|
logd("(f:%s, l:%d)(VDRV_THREAD_CMD_CLOSE_VDECODER)", __FUNCTION__, __LINE__);
|
|
//* stop and close decoder.
|
|
if(pSelf->m_decoder != NULL)
|
|
{
|
|
DestroyVideoDecoder(pSelf->m_decoder);
|
|
pSelf->m_decoder = NULL;
|
|
pSelf->mFirstInputDataFlag = OMX_TRUE;
|
|
}
|
|
}
|
|
else if (cmd == VDRV_THREAD_CMD_FLUSH_VDECODER)
|
|
{
|
|
logd("(f:%s, l:%d)(VDRV_THREAD_CMD_FLUSH_VDECODER)", __FUNCTION__, __LINE__);
|
|
if(pSelf->m_decoder)
|
|
{
|
|
|
|
ResetVideoDecoder(pSelf->m_decoder);
|
|
}
|
|
else
|
|
{
|
|
logw(" fatal error, m_decoder is not malloc when flush all ports!");
|
|
}
|
|
}
|
|
else if (cmd == VDRV_THREAD_CMD_STOP_VDECODER)
|
|
{
|
|
logd("(f:%s, l:%d)(VDRV_THREAD_CMD_STOP_VDECODER)", __FUNCTION__, __LINE__);
|
|
return OMX_RESULT_EXIT;
|
|
}
|
|
else if (cmd == VDRV_THREAD_CMD_EndOfStream)
|
|
{
|
|
logd("(f:%s, l:%d)(VDRV_THREAD_CMD_EndOfStream)", __FUNCTION__, __LINE__);
|
|
pSelf->nInputEosFlag = OMX_TRUE;
|
|
}
|
|
else
|
|
{
|
|
logw("(f:%s, l:%d)fatal error! unknown OMX_VDRV_COMMANDTYPE[0x%x]",
|
|
__FUNCTION__, __LINE__, cmd);
|
|
}
|
|
return OMX_RESULT_OK;
|
|
}
|
|
|
|
static inline int processRenderThreadCommand(omx_vdec* pSelf, CdcMessage* pMsg)
|
|
{
|
|
int ret = OMX_RESULT_OK;
|
|
int cmd = pMsg->messageId;
|
|
logv("(f:%s, l:%d) ****** new RenderThread receive cmd[0x%x]", __FUNCTION__, __LINE__, cmd);
|
|
switch(cmd)
|
|
{
|
|
case RENDER_THREAD_CMD_START:
|
|
case RENDER_THREAD_CMD_EXECUT:
|
|
ret = OMX_RESULT_EXECUT;
|
|
break;
|
|
case RENDER_THREAD_CMD_PAUSE:
|
|
logd("(f:%s, l:%d)(OMX_RenderCommand_Pause)", __FUNCTION__, __LINE__);
|
|
ret = OMX_RESULT_PAUSE;
|
|
break;
|
|
case RENDER_THREAD_CMD_EXIT:
|
|
logd("(f:%s, l:%d)(OMX_RenderCommand_Stop)", __FUNCTION__, __LINE__);
|
|
ret = OMX_RESULT_EXIT;
|
|
break;
|
|
default:
|
|
logw("(f:%s, l:%d)fatal error! unknown OMX_RENDER_COMMANDTYPE[0x%x]",
|
|
__FUNCTION__, __LINE__, cmd);
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static void* RenderThread(void* pThreadData)
|
|
{
|
|
int ret;
|
|
|
|
// Variables related to decoder buffer handling
|
|
OMX_BUFFERHEADERTYPE* pInBufHdr = NULL;
|
|
OMX_BUFFERHEADERTYPE* pOutBufHdr = NULL;
|
|
OMX_U8* pInBuf = NULL;
|
|
OMX_U32 nInBufSize;
|
|
OMX_BOOL bPause = OMX_TRUE;
|
|
int nSemVal;
|
|
int nRetSemGetValue;
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
|
|
// Recover the pointer to my component specific data
|
|
omx_vdec* pSelf = static_cast<omx_vdec*>(pThreadData);
|
|
|
|
int validNumber;
|
|
while (1)
|
|
{
|
|
if(CdcMessageQueueTryGetMessage(pSelf->mqRenderThread, &msg, 10) == 0)
|
|
{
|
|
ret = processRenderThreadCommand(pSelf, &msg);
|
|
if(ret == OMX_RESULT_EXIT)
|
|
{
|
|
goto EXIT;
|
|
}
|
|
else if(ret == OMX_RESULT_PAUSE)
|
|
{
|
|
bPause = OMX_TRUE;
|
|
tryPostSem(&pSelf->m_render_cmd_lock);
|
|
continue;
|
|
}
|
|
else if(ret == OMX_RESULT_EXECUT)
|
|
{
|
|
bPause = OMX_FALSE;
|
|
}
|
|
}
|
|
|
|
//*Buffer processing
|
|
// Only happens when the component is in executing state.
|
|
if ((pSelf->m_state == OMX_StateExecuting &&
|
|
pSelf->m_sInPortDefType.bEnabled &&
|
|
pSelf->m_sOutPortDefType.bEnabled &&
|
|
pSelf->port_setting_match &&
|
|
(pSelf->mResolutionChangeFlag == OMX_FALSE) &&
|
|
(bPause == OMX_FALSE)) || pSelf->bFlushAllFrameFlag)
|
|
{
|
|
if(pSelf->m_decoder == NULL)
|
|
continue ;
|
|
//*check if there is a picture to output.
|
|
if((validNumber = ValidPictureNum(pSelf->m_decoder,0)) != 0)
|
|
{
|
|
drainPicture(pSelf);
|
|
}
|
|
|
|
logv("LINE %d, nVdrvNotifyEosFlag %d", __LINE__, pSelf->nVdrvNotifyEosFlag);
|
|
if(pSelf->nVdrvNotifyEosFlag && (validNumber == 0))
|
|
{
|
|
processOutputEosFlag(pSelf);
|
|
}
|
|
if(pSelf->bFlushAllFrameFlag && (validNumber == 0))
|
|
{
|
|
pSelf->bFlushAllFrameFlag = OMX_FALSE;
|
|
tryPostSem(&pSelf->m_semFlushAllFrame);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
usleep(2000);
|
|
}
|
|
}
|
|
|
|
EXIT:
|
|
logd("exit render!\n");
|
|
tryPostSem(&pSelf->m_render_cmd_lock);
|
|
return (void*)OMX_ErrorNone;
|
|
}
|
|
|
|
|
|
/*
|
|
* Component Thread
|
|
* The ComponentThread function is exeuted in a separate pThread and
|
|
* is used to implement the actual component functions.
|
|
*/
|
|
/*****************************************************************************/
|
|
static void* ComponentThread(void* pThreadData)
|
|
{
|
|
int decodeResult;
|
|
|
|
// Variables related to decoder buffer handling
|
|
OMX_BUFFERHEADERTYPE* pInBufHdr = NULL;
|
|
OMX_BUFFERHEADERTYPE* pOutBufHdr = NULL;
|
|
OMX_U8* pInBuf = NULL;
|
|
OMX_U32 nInBufSize;
|
|
|
|
int nSemVal;
|
|
int nRetSemGetValue;
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
|
|
// Recover the pointer to my component specific data
|
|
omx_vdec* pSelf = static_cast<omx_vdec*>(pThreadData);
|
|
|
|
char calling_process[256];
|
|
|
|
while (1)
|
|
{
|
|
get_new_command:
|
|
if(CdcMessageQueueTryGetMessage(pSelf->mqMainThread, &msg, 5) == 0)
|
|
{
|
|
process_command:
|
|
if(processThreadCommand(pSelf, &msg) == OMX_RESULT_EXIT)
|
|
{
|
|
goto EXIT;
|
|
}
|
|
}
|
|
|
|
//*Buffer processing
|
|
// Only happens when the component is in executing state.
|
|
if (pSelf->m_state == OMX_StateExecuting &&
|
|
pSelf->m_sInPortDefType.bEnabled &&
|
|
pSelf->m_sOutPortDefType.bEnabled &&
|
|
pSelf->port_setting_match &&
|
|
(pSelf->mResolutionChangeFlag == OMX_FALSE))
|
|
{
|
|
if(OMX_TRUE == pSelf->m_JumpFlag)
|
|
{
|
|
logd("reset vdeclib for jump!");
|
|
//pSelf->m_decoder->ioctrl(pSelf->m_decoder, CEDARV_COMMAND_JUMP, 0);
|
|
pSelf->m_JumpFlag = OMX_FALSE;
|
|
}
|
|
|
|
//*if the first-input-data is configure-data, we should cpy to decoder
|
|
// as init-data. here we send commad to VdrvThread to create decoder
|
|
if(pSelf->mFirstInputDataFlag==OMX_TRUE && pSelf->m_sInBufList.nSizeOfList>0)
|
|
{
|
|
if(detectFirstStreamData(pSelf) == OMX_RESULT_ERROR)
|
|
goto EXIT;
|
|
}
|
|
|
|
if(pSelf->m_decoder == NULL)
|
|
continue ;
|
|
int nVbvStreamNum = VideoStreamFrameNum(pSelf->m_decoder, 0);
|
|
logv("** nVbvStreamNum = %d", nVbvStreamNum);
|
|
//*fill buffer first
|
|
//while(0==ValidPictureNum(pSelf->m_decoder,0) && pSelf->m_sInBufList.nSizeOfList>0)
|
|
if(nVbvStreamNum < 20 && pSelf->m_sInBufList.nSizeOfList>0)
|
|
{
|
|
sendStreamDataToDecoder(pSelf);
|
|
}
|
|
else if((pSelf->nInBufEos == OMX_TRUE) && (pSelf->m_OutputNum > 0))
|
|
{
|
|
usleep(5*1000);
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
msg.messageId = VDRV_THREAD_CMD_EndOfStream;
|
|
CdcMessageQueuePostMessage(pSelf->mqVdrvThread, &msg);
|
|
sem_post(&pSelf->m_sem_vbs_input);
|
|
sem_post(&pSelf->m_sem_frame_output);
|
|
logd("(f:%s) wait for VDRV_THREAD_CMD_EndOfStream", __FUNCTION__);
|
|
SemTimedWait(&pSelf->m_vdrv_cmd_lock, -1);
|
|
logd("(f:%s) wait for VDRV_THREAD_CMD_EndOfStream done!", __FUNCTION__);
|
|
pSelf->m_Callbacks.EventHandler(&pSelf->mOmxCmp, pSelf->m_pAppData,
|
|
OMX_EventBufferFlag, 0x1,
|
|
OMX_BUFFERFLAG_EOS, NULL);
|
|
pSelf->nInBufEos = OMX_FALSE;
|
|
}
|
|
if(pSelf->bUseShareBuffer == OMX_TRUE)
|
|
{
|
|
//*3. get video fbm buf info
|
|
while(pSelf->mHadGetVideoFbmBufInfoFlag == OMX_FALSE)
|
|
{
|
|
logw("*** get video fbm buf info!");
|
|
if(OmxGetVideoFbmBufInfo(pSelf) == 0)
|
|
{
|
|
pSelf->mHadGetVideoFbmBufInfoFlag = OMX_TRUE;
|
|
goto get_new_command;
|
|
}
|
|
else
|
|
{
|
|
if(pSelf->nVdrvNotifyEosFlag) //for cts test
|
|
{
|
|
processOutputEosFlag(pSelf);
|
|
}
|
|
if(CdcMessageQueueTryGetMessage(pSelf->mqMainThread, &msg, 20) == 0)
|
|
{
|
|
logw("*** get new command when get video fbm-buf-info");
|
|
goto process_command;
|
|
}
|
|
}
|
|
}
|
|
|
|
logv("***mSetToDecoderBufferNum(%lu),nAllocSize(%lu),min(%lu),ac[%lu]",
|
|
pSelf->mSetToDecoderBufferNum,pSelf->m_sOutBufList.nAllocSize,
|
|
pSelf->m_sOutPortDefType.nBufferCountMin,
|
|
pSelf->m_sOutPortDefType.nBufferCountActual);
|
|
//*4. return buffer to decoder.
|
|
//* we should not return buffer to decoder when detect eos,
|
|
//* or we cannot callback eos to ACodec.
|
|
if(pSelf->nVdrvNotifyEosFlag == OMX_FALSE)
|
|
{
|
|
while(pSelf->m_sOutBufList.nSizeOfList > 0)
|
|
{
|
|
if(OmxReturnBufferToDecoder(pSelf) != 0)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if(pSelf->nResolutionChangeNativeThreadFlag == OMX_TRUE)
|
|
{
|
|
logd("set pSelf->mResolutionChangeFlag to 1");
|
|
pSelf->mResolutionChangeFlag = OMX_TRUE;
|
|
pSelf->nResolutionChangeNativeThreadFlag = OMX_FALSE;
|
|
|
|
logd("(f:%s, l:%d) wait for m_semResolutionChange", __FUNCTION__, __LINE__);
|
|
SemTimedWait(&pSelf->m_semResolutionChange, -1);
|
|
logd("(f:%s, l:%d) wait for m_semResolutionChange done!",
|
|
__FUNCTION__, __LINE__);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
EXIT:
|
|
return (void*)OMX_ErrorNone;
|
|
}
|
|
|
|
static void* ComponentVdrvThread(void* pThreadData)
|
|
{
|
|
int nSemVal;
|
|
int nRetSemGetValue;
|
|
int nStopFlag = 0;
|
|
CdcMessage msg;
|
|
memset(&msg, 0, sizeof(CdcMessage));
|
|
|
|
// Recover the pointer to my component specific data
|
|
omx_vdec* pSelf = static_cast<omx_vdec*>(pThreadData);
|
|
|
|
while (1)
|
|
{
|
|
if(CdcMessageQueueTryGetMessage(pSelf->mqVdrvThread, &msg, 0) == 0)
|
|
{
|
|
process_vdrv_cmd:
|
|
if(processVdrvThreadCommand(pSelf, &msg) == OMX_RESULT_EXIT)
|
|
nStopFlag = 1;
|
|
|
|
tryPostSem(&pSelf->m_vdrv_cmd_lock);
|
|
}
|
|
|
|
if(nStopFlag)
|
|
{
|
|
logd("vdrvThread detect nStopFlag[%d], exit!", nStopFlag);
|
|
goto EXIT;
|
|
}
|
|
|
|
//*Buffer processing
|
|
// Only happens when the component is in executing state.
|
|
if ((pSelf->m_state == OMX_StateExecuting || pSelf->m_state == OMX_StatePause)
|
|
&&(pSelf->m_decoder!=NULL)
|
|
&&(pSelf->nResolutionChangeVdrvThreadFlag == OMX_FALSE))
|
|
{
|
|
vdecoderDecodeStream(pSelf);
|
|
}
|
|
else
|
|
{
|
|
if(pSelf->mResolutionChangeFlag == OMX_TRUE)
|
|
{
|
|
decoderResolutionChange(pSelf);
|
|
pSelf->nResolutionChangeVdrvThreadFlag = OMX_FALSE;
|
|
}
|
|
if(CdcMessageQueueTryGetMessage(pSelf->mqVdrvThread, &msg, 10) == 0)
|
|
goto process_vdrv_cmd;
|
|
}
|
|
}
|
|
|
|
EXIT:
|
|
logd("***notify: exit the componentVdrvThread!");
|
|
return (void*)OMX_ErrorNone;
|
|
}
|