|
@@ -9,9 +9,60 @@
|
|
|
#include "SF_OMX_Core.h"
|
|
|
|
|
|
extern OMX_TICKS gInitTimeStamp;
|
|
|
+
|
|
|
+static char* Event2Str(unsigned long event)
|
|
|
+{
|
|
|
+ char *event_str = NULL;
|
|
|
+ switch (event)
|
|
|
+ {
|
|
|
+ case COMPONENT_EVENT_DEC_OPEN:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_OPEN";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_ISSUE_SEQ:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_ISSUE_SEQ";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_COMPLETE_SEQ:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_COMPLETE_SEQ";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_REGISTER_FB:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_REGISTER_FB";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_READY_ONE_FRAME:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_READY_ONE_FRAME";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_START_ONE_FRAME:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_START_ONE_FRAME";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_INTERRUPT:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_INTERRUPT";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_GET_OUTPUT_INFO:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_GET_OUTPUT_INFO";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_DECODED_ALL:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_DECODED_ALL";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_CLOSE:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_CLOSE";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_RESET_DONE:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_RESET_DONE";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_FILL_BUFFER_DONE:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_FILL_BUFFER_DONE";
|
|
|
+ break;
|
|
|
+ case COMPONENT_EVENT_DEC_ALL:
|
|
|
+ event_str = "COMPONENT_EVENT_DEC_ALL";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return event_str;
|
|
|
+}
|
|
|
+
|
|
|
static void OnEventArrived(Component com, unsigned long event, void *data, void *context)
|
|
|
{
|
|
|
- SF_OMX_COMPONENT *pSfOMXComponent = GetSFOMXComponrntByComponent(com);
|
|
|
PortContainerExternal *pPortContainerExternal = (PortContainerExternal *)data;
|
|
|
OMX_BUFFERHEADERTYPE *pOMXBuffer;
|
|
|
static OMX_U32 dec_cnt = 0;
|
|
@@ -19,8 +70,10 @@ static void OnEventArrived(Component com, unsigned long event, void *data, void
|
|
|
OMX_U32 fps = 0;
|
|
|
OMX_U64 diff_time = 0; // ms
|
|
|
FunctionIn();
|
|
|
+ SF_OMX_COMPONENT *pSfOMXComponent = GetSFOMXComponrntByComponent(com);
|
|
|
+ char *event_str = Event2Str(event);
|
|
|
|
|
|
- LOG(SF_LOG_INFO, "event=%X\r\n", event);
|
|
|
+ LOG(SF_LOG_INFO, "event=%lX %s\r\n", event, event_str);
|
|
|
switch (event)
|
|
|
{
|
|
|
case COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE:
|
|
@@ -32,13 +85,22 @@ static void OnEventArrived(Component com, unsigned long event, void *data, void
|
|
|
{
|
|
|
struct timeval tv;
|
|
|
pOMXBuffer = GetOMXBufferByAddr(pSfOMXComponent, (OMX_U8 *)pPortContainerExternal->pBuffer);
|
|
|
+ if (pOMXBuffer == NULL)
|
|
|
+ {
|
|
|
+ LOG(SF_LOG_ERR, "Could not find omx buffer by address\r\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
gettimeofday(&tv, NULL);
|
|
|
+ if (gInitTimeStamp == 0)
|
|
|
+ {
|
|
|
+ gInitTimeStamp = tv.tv_sec * 1000000 + tv.tv_usec;
|
|
|
+ }
|
|
|
pOMXBuffer->nFilledLen = pPortContainerExternal->nFilledLen;
|
|
|
pOMXBuffer->nTimeStamp = tv.tv_sec * 1000000 + tv.tv_usec - gInitTimeStamp;
|
|
|
#if 0
|
|
|
{
|
|
|
FILE *fb = fopen("./out.bcp", "ab+");
|
|
|
- LOG(SF_LOG_INFO, "%d %d\r\n", pOMXBuffer->nFilledLen, pOMXBuffer->nOffset);
|
|
|
+ LOG(SF_LOG_INFO, "%p %d\r\n", pOMXBuffer->pBuffer, pOMXBuffer->nFilledLen);
|
|
|
fwrite(pOMXBuffer->pBuffer, 1, pOMXBuffer->nFilledLen, fb);
|
|
|
fclose(fb);
|
|
|
}
|
|
@@ -55,15 +117,23 @@ static void OnEventArrived(Component com, unsigned long event, void *data, void
|
|
|
LOG(SF_LOG_WARN, "Decoding fps: %d \r\n", fps);
|
|
|
}
|
|
|
|
|
|
- LOG(SF_LOG_PERF, "OMX finish one buffer\r\n");
|
|
|
+ LOG(SF_LOG_PERF, "OMX finish one buffer, address = %p, size = %d, nTimeStamp = %d, nFlags = %X\r\n",
|
|
|
+ pOMXBuffer->pBuffer, pOMXBuffer->nFilledLen, pOMXBuffer->nTimeStamp, pOMXBuffer->nFlags);
|
|
|
+ LOG(SF_LOG_INFO, "indexFrameDisplay = %d, OMXBuferFlag = %d, VPUBufferAddr = %p, OMXBufferAddr = %p\r\n",
|
|
|
+ pPortContainerExternal->nFlags, (OMX_U32)pOMXBuffer->pOutputPortPrivate, pPortContainerExternal->pAppPrivate, pOMXBuffer->pBuffer);
|
|
|
+ ComponentImpl *pRendererComponent = (ComponentImpl *)pSfOMXComponent->hSFComponentRender;
|
|
|
+ LOG(SF_LOG_PERF, "output queue count=%d/%d\r\n", pSfOMXComponent->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ),
|
|
|
+ pSfOMXComponent->portDefinition[1].nBufferCountActual);
|
|
|
+
|
|
|
pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
|
|
|
}
|
|
|
break;
|
|
|
case COMPONENT_EVENT_DEC_REGISTER_FB:
|
|
|
{
|
|
|
- struct timeval tv;
|
|
|
- gettimeofday(&tv, NULL);
|
|
|
- gInitTimeStamp = tv.tv_sec * 1000000 + tv.tv_usec;
|
|
|
+ FrameBuffer *frameBuffer = (FrameBuffer *)data;
|
|
|
+ LOG(SF_LOG_INFO, "Get Output width = %d, height = %d\r\n", frameBuffer->width, frameBuffer->height);
|
|
|
+ // pSfOMXComponent->portDefinition[1].format.video.nFrameWidth = frameBuffer->width;
|
|
|
+ // pSfOMXComponent->portDefinition[1].format.video.nFrameHeight = frameBuffer->height;
|
|
|
pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventPortSettingsChanged,
|
|
|
1, OMX_IndexParamPortDefinition, NULL);
|
|
|
}
|
|
@@ -114,7 +184,8 @@ static OMX_ERRORTYPE SF_OMX_EmptyThisBuffer(
|
|
|
free(pPortContainerExternal);
|
|
|
return OMX_ErrorInsufficientResources;
|
|
|
}
|
|
|
- LOG(SF_LOG_PERF, "input queue count=%d\r\n", pSfOMXComponent->functions->Queue_Get_Cnt(pFeederComponent->srcPort.inputQ));
|
|
|
+ LOG(SF_LOG_PERF, "input queue count=%d/%d\r\n", pSfOMXComponent->functions->Queue_Get_Cnt(pFeederComponent->srcPort.inputQ),
|
|
|
+ pSfOMXComponent->portDefinition[0].nBufferCountActual);
|
|
|
free(pPortContainerExternal);
|
|
|
|
|
|
pFeederComponent->pause = OMX_FALSE;
|
|
@@ -124,6 +195,10 @@ EXIT:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+#define MAX_INDEX 1
|
|
|
+static int frame_array[MAX_INDEX] = {-1};
|
|
|
+static int frame_array_index = 0;
|
|
|
+
|
|
|
static OMX_ERRORTYPE SF_OMX_FillThisBuffer(
|
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
|
OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
|
|
@@ -150,13 +225,24 @@ static OMX_ERRORTYPE SF_OMX_FillThisBuffer(
|
|
|
pPortContainerExternal->pBuffer = pBuffer->pBuffer;
|
|
|
pPortContainerExternal->nFilledLen = pBuffer->nAllocLen;
|
|
|
|
|
|
+ if (gInitTimeStamp != 0)
|
|
|
+ {
|
|
|
+ int clear = frame_array[frame_array_index];
|
|
|
+ pSfOMXComponent->functions->Render_DecClrDispFlag(pRendererComponent->context, clear);
|
|
|
+ frame_array[frame_array_index] = (int)pBuffer->pOutputPortPrivate;
|
|
|
+ LOG(SF_LOG_INFO, "store display flag: %d, clear display flag: %d\r\n", frame_array[frame_array_index], clear);
|
|
|
+ frame_array_index ++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (frame_array_index == MAX_INDEX) frame_array_index = 0;
|
|
|
if (pSfOMXComponent->functions->Queue_Enqueue(pRendererComponent->sinkPort.inputQ, (void *)pPortContainerExternal) == FALSE)
|
|
|
{
|
|
|
LOG(SF_LOG_ERR, "%p:%p FAIL\r\n", pRendererComponent->sinkPort.inputQ, pPortContainerExternal);
|
|
|
free(pPortContainerExternal);
|
|
|
return OMX_ErrorInsufficientResources;
|
|
|
}
|
|
|
- LOG(SF_LOG_PERF, "output queue count=%d\r\n", pSfOMXComponent->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ));
|
|
|
+ LOG(SF_LOG_PERF, "output queue count=%d/%d\r\n", pSfOMXComponent->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ),
|
|
|
+ pSfOMXComponent->portDefinition[1].nBufferCountActual);
|
|
|
free(pPortContainerExternal);
|
|
|
pRendererComponent->pause = OMX_FALSE;
|
|
|
EXIT:
|
|
@@ -165,6 +251,8 @@ EXIT:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int nOutBufIndex = 0;
|
|
|
+
|
|
|
static OMX_ERRORTYPE SF_OMX_UseBuffer(
|
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
|
OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
|
|
@@ -176,7 +264,7 @@ static OMX_ERRORTYPE SF_OMX_UseBuffer(
|
|
|
OMX_ERRORTYPE ret = OMX_ErrorNone;
|
|
|
OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
|
|
|
SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
|
|
|
-
|
|
|
+ ComponentImpl *pComponentRender = (ComponentImpl *)pSfOMXComponent->hSFComponentRender;
|
|
|
FunctionIn();
|
|
|
|
|
|
if (hComponent == NULL)
|
|
@@ -184,6 +272,11 @@ static OMX_ERRORTYPE SF_OMX_UseBuffer(
|
|
|
ret = OMX_ErrorBadParameter;
|
|
|
goto EXIT;
|
|
|
}
|
|
|
+ if (pSfOMXComponent->functions->AttachDMABuffer(pComponentRender, (Uint64)pBuffer, nSizeBytes) == FALSE)
|
|
|
+ {
|
|
|
+ LOG(SF_LOG_ERR, "Failed to attach dma buffer\r\n");
|
|
|
+ return OMX_ErrorInsufficientResources;
|
|
|
+ }
|
|
|
OMX_BUFFERHEADERTYPE *temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)malloc(sizeof(OMX_BUFFERHEADERTYPE));
|
|
|
if (temp_bufferHeader == NULL)
|
|
|
{
|
|
@@ -195,8 +288,14 @@ static OMX_ERRORTYPE SF_OMX_UseBuffer(
|
|
|
temp_bufferHeader->pAppPrivate = pAppPrivate;
|
|
|
temp_bufferHeader->pBuffer = pBuffer;
|
|
|
*ppBufferHdr = temp_bufferHeader;
|
|
|
-
|
|
|
+ if (nPortIndex == 1)
|
|
|
+ {
|
|
|
+ temp_bufferHeader->pOutputPortPrivate = (OMX_PTR)nOutBufIndex;
|
|
|
+ nOutBufIndex ++;
|
|
|
+ }
|
|
|
ret = StoreOMXBuffer(pSfOMXComponent, temp_bufferHeader);
|
|
|
+ LOG(SF_LOG_INFO, "pBuffer address = %p, nOutBufIndex = %d\r\n", temp_bufferHeader->pBuffer, (int)temp_bufferHeader->pOutputPortPrivate);
|
|
|
+ LOG(SF_LOG_PERF, "alloc size = %d, buffer count = %d\r\n",nSizeBytes, GetOMXBufferCount(pSfOMXComponent));
|
|
|
EXIT:
|
|
|
FunctionOut();
|
|
|
|
|
@@ -213,6 +312,7 @@ static OMX_ERRORTYPE SF_OMX_AllocateBuffer(
|
|
|
OMX_ERRORTYPE ret = OMX_ErrorNone;
|
|
|
OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
|
|
|
SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
|
|
|
+ ComponentImpl *pComponentRender = (ComponentImpl *)pSfOMXComponent->hSFComponentRender;
|
|
|
|
|
|
OMX_BUFFERHEADERTYPE *temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)malloc(sizeof(OMX_BUFFERHEADERTYPE));
|
|
|
if (temp_bufferHeader == NULL)
|
|
@@ -221,21 +321,47 @@ static OMX_ERRORTYPE SF_OMX_AllocateBuffer(
|
|
|
return OMX_ErrorInsufficientResources;
|
|
|
}
|
|
|
memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
|
|
|
- temp_bufferHeader->pBuffer = malloc(nSizeBytes);
|
|
|
+
|
|
|
+ temp_bufferHeader->nAllocLen = nSizeBytes;
|
|
|
+ temp_bufferHeader->pAppPrivate = pAppPrivate;
|
|
|
+ if (nPortIndex == 1)
|
|
|
+ {
|
|
|
+ // Alloc DMA memory first
|
|
|
+ if (pSfOMXComponent->memory_optimization)
|
|
|
+ {
|
|
|
+ temp_bufferHeader->pBuffer = pSfOMXComponent->functions->AllocateFrameBuffer2(pComponentRender, nSizeBytes);
|
|
|
+ }
|
|
|
+ // DMA Memory alloc fail, goto normal alloc
|
|
|
+ if (temp_bufferHeader->pBuffer == NULL)
|
|
|
+ {
|
|
|
+ pSfOMXComponent->memory_optimization = OMX_FALSE;
|
|
|
+ temp_bufferHeader->pBuffer = malloc(nSizeBytes);
|
|
|
+ memset(temp_bufferHeader->pBuffer, 0, nSizeBytes);
|
|
|
+ LOG(SF_LOG_PERF, "Use normal buffer\r\n");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ LOG(SF_LOG_PERF, "Use DMA buffer\r\n");
|
|
|
+ }
|
|
|
+ temp_bufferHeader->pOutputPortPrivate = (OMX_PTR)nOutBufIndex;
|
|
|
+ nOutBufIndex ++;
|
|
|
+ }
|
|
|
+ else if (nPortIndex == 0)
|
|
|
+ {
|
|
|
+ temp_bufferHeader->pBuffer = malloc(nSizeBytes);
|
|
|
+
|
|
|
+ memset(temp_bufferHeader->pBuffer, 0, nSizeBytes);
|
|
|
+ }
|
|
|
if (temp_bufferHeader->pBuffer == NULL)
|
|
|
{
|
|
|
free(temp_bufferHeader);
|
|
|
LOG(SF_LOG_ERR, "malloc fail\r\n");
|
|
|
return OMX_ErrorInsufficientResources;
|
|
|
}
|
|
|
- memset(temp_bufferHeader->pBuffer, 0, nSizeBytes);
|
|
|
- temp_bufferHeader->nAllocLen = nSizeBytes;
|
|
|
- temp_bufferHeader->pAppPrivate = pAppPrivate;
|
|
|
-
|
|
|
*ppBuffer = temp_bufferHeader;
|
|
|
-
|
|
|
+ LOG(SF_LOG_INFO, "pBuffer address = %p\r\n", temp_bufferHeader->pBuffer);
|
|
|
ret = StoreOMXBuffer(pSfOMXComponent, temp_bufferHeader);
|
|
|
- LOG(SF_LOG_PERF, "buffer count = %d\r\n", GetOMXBufferCount(pSfOMXComponent));
|
|
|
+ LOG(SF_LOG_PERF, "alloc size = %d, buffer count = %d\r\n",nSizeBytes, GetOMXBufferCount(pSfOMXComponent));
|
|
|
|
|
|
FunctionOut();
|
|
|
|
|
@@ -252,7 +378,7 @@ static OMX_ERRORTYPE SF_OMX_GetParameter(
|
|
|
SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
|
|
|
|
|
|
FunctionIn();
|
|
|
-
|
|
|
+ LOG(SF_LOG_INFO, "Get parameter on index %X\r\n", nParamIndex);
|
|
|
if (hComponent == NULL)
|
|
|
{
|
|
|
ret = OMX_ErrorBadParameter;
|
|
@@ -261,8 +387,12 @@ static OMX_ERRORTYPE SF_OMX_GetParameter(
|
|
|
switch ((OMX_U32)nParamIndex)
|
|
|
{
|
|
|
case OMX_IndexParamVideoInit:
|
|
|
-
|
|
|
- break;
|
|
|
+ {
|
|
|
+ OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
|
|
|
+ portParam->nPorts = 2;
|
|
|
+ portParam->nStartPortNumber = 0;
|
|
|
+ }
|
|
|
+ break;
|
|
|
case OMX_IndexParamVideoPortFormat:
|
|
|
{
|
|
|
OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
|
|
@@ -291,7 +421,10 @@ static OMX_ERRORTYPE SF_OMX_GetParameter(
|
|
|
{
|
|
|
OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
|
|
|
OMX_U32 portIndex = pPortDefinition->nPortIndex;
|
|
|
- memcpy(pPortDefinition, &pSfOMXComponent->portDefinition[portIndex], pPortDefinition->nSize);
|
|
|
+ OMX_PARAM_PORTDEFINITIONTYPE *pSrcDefinition = &pSfOMXComponent->portDefinition[portIndex];
|
|
|
+ LOG(SF_LOG_INFO, "Get parameter width = %d, height = %d from port %X\r\n",
|
|
|
+ pSrcDefinition->format.video.nFrameWidth, pSrcDefinition->format.video.nFrameHeight, portIndex);
|
|
|
+ memcpy(pPortDefinition, pSrcDefinition, pPortDefinition->nSize);
|
|
|
}
|
|
|
|
|
|
break;
|
|
@@ -343,7 +476,7 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
|
|
|
goto EXIT;
|
|
|
}
|
|
|
TestDecConfig *testConfig = pSfOMXComponent->testConfig;
|
|
|
-
|
|
|
+ LOG(SF_LOG_INFO, "Set parameter on index %X\r\n", nIndex);
|
|
|
switch ((OMX_U32)nIndex)
|
|
|
{
|
|
|
case OMX_IndexParamVideoPortFormat:
|
|
@@ -353,6 +486,7 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
|
|
|
case OMX_IndexParamVideoQuantization:
|
|
|
|
|
|
break;
|
|
|
+ break;
|
|
|
case OMX_IndexParamPortDefinition:
|
|
|
{
|
|
|
OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
|
|
@@ -364,30 +498,60 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
|
|
|
OMX_U32 height = pPortDefinition->format.video.nFrameHeight;
|
|
|
LOG(SF_LOG_INFO, "Set width = %d, height = %d on port %d\r\n", width, height, pPortDefinition->nPortIndex);
|
|
|
|
|
|
- memcpy(&pSfOMXComponent->portDefinition[portIndex], pPortDefinition, pPortDefinition->nSize);
|
|
|
+
|
|
|
|
|
|
if (portIndex == 0)
|
|
|
{
|
|
|
+ if (pPortDefinition->nBufferCountActual != pInputPort->nBufferCountActual)
|
|
|
+ {
|
|
|
+ LOG(SF_LOG_INFO, "Set input buffer count = %d\r\n", pPortDefinition->nBufferCountActual);
|
|
|
+ ComponentImpl *pFeederComponent = (ComponentImpl *)pSfOMXComponent->hSFComponentFeeder;
|
|
|
+ pSfOMXComponent->functions->ComponentPortDestroy(&pFeederComponent->srcPort);
|
|
|
+ pSfOMXComponent->functions->ComponentPortCreate(&pFeederComponent->srcPort, pSfOMXComponent->hSFComponentFeeder,
|
|
|
+ pPortDefinition->nBufferCountActual, sizeof(PortContainerExternal));
|
|
|
+ }
|
|
|
+
|
|
|
+ memcpy(&pSfOMXComponent->portDefinition[portIndex], pPortDefinition, pPortDefinition->nSize);
|
|
|
+
|
|
|
pInputPort->format.video.nStride = width;
|
|
|
pInputPort->format.video.nSliceHeight = height;
|
|
|
pInputPort->nBufferSize = width * height * 2;
|
|
|
- } else if (portIndex == 1)
|
|
|
+ }
|
|
|
+ else if (portIndex == 1)
|
|
|
{
|
|
|
- if (width == 1)
|
|
|
+ if (pPortDefinition->nBufferCountActual != pOutputPort->nBufferCountActual)
|
|
|
+ {
|
|
|
+ ComponentImpl *pRenderComponent = (ComponentImpl *)pSfOMXComponent->hSFComponentRender;
|
|
|
+ pSfOMXComponent->functions->SetRenderTotalBufferNumber(pRenderComponent, pPortDefinition->nBufferCountActual);
|
|
|
+ LOG(SF_LOG_INFO, "Set output buffer count = %d\r\n", pPortDefinition->nBufferCountActual);
|
|
|
+ pSfOMXComponent->functions->ComponentPortDestroy(&pRenderComponent->sinkPort);
|
|
|
+ pSfOMXComponent->functions->ComponentPortCreate(&pRenderComponent->sinkPort, pSfOMXComponent->hSFComponentRender,
|
|
|
+ pPortDefinition->nBufferCountActual, sizeof(PortContainerExternal));
|
|
|
+ }
|
|
|
+
|
|
|
+ memcpy(&pSfOMXComponent->portDefinition[portIndex], pPortDefinition, pPortDefinition->nSize);
|
|
|
+
|
|
|
+ /*
|
|
|
+ Some client may set '0' or '1' to output port, in this case use input port parameters
|
|
|
+ */
|
|
|
+ if (width <= 1)
|
|
|
{
|
|
|
width = pInputPort->format.video.nFrameWidth;
|
|
|
}
|
|
|
- if (height == 1)
|
|
|
+ if (height <= 1)
|
|
|
{
|
|
|
height = pInputPort->format.video.nFrameHeight;
|
|
|
}
|
|
|
- int scalew = pInputPort->format.video.nFrameWidth / width;
|
|
|
- int scaleh = pInputPort->format.video.nFrameHeight / height;
|
|
|
- if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1)
|
|
|
+ if (width > 0 && height > 0)
|
|
|
{
|
|
|
- LOG(SF_LOG_ERR, "Scaling should be 1 to 1/8 (down-scaling only)!\r\n");
|
|
|
- ret = OMX_ErrorBadParameter;
|
|
|
- goto EXIT;
|
|
|
+ int scalew = pInputPort->format.video.nFrameWidth / width;
|
|
|
+ int scaleh = pInputPort->format.video.nFrameHeight / height;
|
|
|
+ if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1)
|
|
|
+ {
|
|
|
+ LOG(SF_LOG_ERR, "Scaling should be 1 to 1/8 (down-scaling only)!\r\n");
|
|
|
+ ret = OMX_ErrorBadParameter;
|
|
|
+ goto EXIT;
|
|
|
+ }
|
|
|
}
|
|
|
pOutputPort->format.video.nFrameWidth = width;
|
|
|
pOutputPort->format.video.nFrameHeight = height;
|
|
@@ -424,12 +588,6 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
|
|
|
case OMX_IndexParamVideoHevc:
|
|
|
testConfig->bitFormat = 12;
|
|
|
break;
|
|
|
- case OMX_IndexConfigCommonInputCrop:
|
|
|
- memcpy(testConfig->inputPath, ComponentParameterStructure, strlen(ComponentParameterStructure));
|
|
|
- break;
|
|
|
- case OMX_IndexConfigCommonOutputCrop:
|
|
|
- memcpy(testConfig->outputPath, ComponentParameterStructure, strlen(ComponentParameterStructure));
|
|
|
- break;
|
|
|
default:
|
|
|
|
|
|
break;
|
|
@@ -602,18 +760,16 @@ static OMX_ERRORTYPE InitDecoder(SF_OMX_COMPONENT *pSfOMXComponent)
|
|
|
pSfOMXComponent->hSFComponentRender = pSfOMXComponent->functions->ComponentCreate("renderer", config);
|
|
|
|
|
|
ComponentImpl *pFeederComponent = (ComponentImpl *)pSfOMXComponent->hSFComponentFeeder;
|
|
|
- pSfOMXComponent->functions->ComponentPortCreate(&pFeederComponent->srcPort, pSfOMXComponent->hSFComponentFeeder, 5, sizeof(PortContainerExternal));
|
|
|
+ pSfOMXComponent->functions->ComponentPortCreate(&pFeederComponent->srcPort, pSfOMXComponent->hSFComponentFeeder, VPU_INPUT_BUF_NUMBER, sizeof(PortContainerExternal));
|
|
|
|
|
|
ComponentImpl *pRenderComponent = (ComponentImpl *)pSfOMXComponent->hSFComponentRender;
|
|
|
pSfOMXComponent->functions->ComponentPortDestroy(&pRenderComponent->sinkPort);
|
|
|
- pSfOMXComponent->functions->ComponentPortCreate(&pRenderComponent->sinkPort, pSfOMXComponent->hSFComponentRender, 5, sizeof(PortContainerExternal));
|
|
|
+ pSfOMXComponent->functions->ComponentPortCreate(&pRenderComponent->sinkPort, pSfOMXComponent->hSFComponentRender, VPU_OUTPUT_BUF_NUMBER, sizeof(PortContainerExternal));
|
|
|
|
|
|
if (pSfOMXComponent->functions->SetupDecListenerContext(pSfOMXComponent->lsnCtx, config, NULL) == TRUE)
|
|
|
{
|
|
|
pSfOMXComponent->functions->ComponentRegisterListener(pSfOMXComponent->hSFComponentExecoder,
|
|
|
COMPONENT_EVENT_DEC_ALL, pSfOMXComponent->functions->DecoderListener, (void *)pSfOMXComponent->lsnCtx);
|
|
|
- pSfOMXComponent->functions->ComponentRegisterListener(pSfOMXComponent->hSFComponentExecoder,
|
|
|
- COMPONENT_EVENT_DEC_REGISTER_FB, OnEventArrived, (void *)pSfOMXComponent->lsnCtx);
|
|
|
pSfOMXComponent->functions->ComponentRegisterListener(pSfOMXComponent->hSFComponentExecoder,
|
|
|
COMPONENT_EVENT_DEC_DECODED_ALL, OnEventArrived, (void *)pSfOMXComponent->lsnCtx);
|
|
|
pSfOMXComponent->functions->ComponentRegisterListener(pSfOMXComponent->hSFComponentFeeder,
|
|
@@ -633,6 +789,36 @@ static OMX_ERRORTYPE InitDecoder(SF_OMX_COMPONENT *pSfOMXComponent)
|
|
|
return OMX_ErrorNone;
|
|
|
}
|
|
|
|
|
|
+static OMX_ERRORTYPE FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent)
|
|
|
+{
|
|
|
+ ComponentImpl *pRendererComponent = pSfOMXComponent->hSFComponentRender;
|
|
|
+ ComponentImpl *pFeederComponent = pSfOMXComponent->hSFComponentFeeder;
|
|
|
+ OMX_U32 inputQueueCount = pSfOMXComponent->functions->Queue_Get_Cnt(pFeederComponent->srcPort.inputQ);
|
|
|
+ OMX_U32 OutputQueueCount = pSfOMXComponent->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ);
|
|
|
+
|
|
|
+ FunctionIn();
|
|
|
+ LOG(SF_LOG_PERF, "Flush %d-%d buffers on inputPort-outputPort\r\n", inputQueueCount, OutputQueueCount);
|
|
|
+ if (inputQueueCount > 0)
|
|
|
+ {
|
|
|
+ PortContainerExternal *input = NULL;
|
|
|
+ while ((input = (PortContainerExternal*)pSfOMXComponent->functions->ComponentPortGetData(&pFeederComponent->srcPort)) != NULL)
|
|
|
+ {
|
|
|
+ pSfOMXComponent->functions->ComponentNotifyListeners(pFeederComponent, COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE, (void *)input);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (OutputQueueCount > 0)
|
|
|
+ {
|
|
|
+ PortContainerExternal *output = NULL;
|
|
|
+ while ((output = (PortContainerExternal*)pSfOMXComponent->functions->ComponentPortGetData(&pRendererComponent->sinkPort)) != NULL)
|
|
|
+ {
|
|
|
+ output->nFlags = 0x1;
|
|
|
+ output->nFilledLen = 0;
|
|
|
+ pSfOMXComponent->functions->ComponentNotifyListeners(pRendererComponent, COMPONENT_EVENT_DEC_FILL_BUFFER_DONE, (void *)output);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ FunctionOut();
|
|
|
+}
|
|
|
+
|
|
|
static OMX_ERRORTYPE SF_OMX_SendCommand(
|
|
|
OMX_IN OMX_HANDLETYPE hComponent,
|
|
|
OMX_IN OMX_COMMANDTYPE Cmd,
|
|
@@ -654,24 +840,82 @@ static OMX_ERRORTYPE SF_OMX_SendCommand(
|
|
|
goto EXIT;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ LOG(SF_LOG_INFO, "cmd = %X, nParam = %X\r\n", Cmd, nParam);
|
|
|
switch (Cmd)
|
|
|
{
|
|
|
case OMX_CommandStateSet:
|
|
|
+ pSfOMXComponent->nextState = nParam;
|
|
|
+ LOG(SF_LOG_INFO, "OMX dest state = %X\r\n", nParam);
|
|
|
switch (nParam)
|
|
|
{
|
|
|
+ case OMX_StateLoaded:
|
|
|
+ if (pSfOMXComponent->hSFComponentExecoder == NULL)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pSFComponentDecoder = (ComponentImpl *)pSfOMXComponent->hSFComponentExecoder;
|
|
|
+ pSFComponentFeeder = (ComponentImpl *)pSfOMXComponent->hSFComponentFeeder;
|
|
|
+ pSFComponentRender = (ComponentImpl *)pSfOMXComponent->hSFComponentRender;
|
|
|
+ componentState = pSfOMXComponent->functions->ComponentGetState(pSfOMXComponent->hSFComponentExecoder);
|
|
|
+ LOG(SF_LOG_INFO, "VPU Current state = %X\r\n", componentState);
|
|
|
+ switch(componentState)
|
|
|
+ {
|
|
|
+ case COMPONENT_STATE_CREATED:
|
|
|
+ case COMPONENT_STATE_PREPARED:
|
|
|
+ case COMPONENT_STATE_EXECUTED:
|
|
|
+ case COMPONENT_STATE_TERMINATED:
|
|
|
+ if (pSfOMXComponent->functions->Queue_Get_Cnt(pSFComponentRender->sinkPort.inputQ) > 0 ||
|
|
|
+ pSfOMXComponent->functions->Queue_Get_Cnt(pSFComponentFeeder->srcPort.inputQ) > 0)
|
|
|
+ {
|
|
|
+ LOG(SF_LOG_ERR, "Buffer not flush!\r\n")
|
|
|
+ // ret = OMX_ErrorIncorrectStateTransition;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pSFComponentDecoder->terminate = OMX_TRUE;
|
|
|
+ pSFComponentFeeder->terminate = OMX_TRUE;
|
|
|
+ pSFComponentRender->terminate = OMX_TRUE;
|
|
|
+ break;
|
|
|
+ case COMPONENT_STATE_NONE:
|
|
|
+ default:
|
|
|
+ ret = OMX_ErrorIncorrectStateTransition;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
case OMX_StateIdle:
|
|
|
- ret = InitDecoder(pSfOMXComponent);
|
|
|
- if (ret != OMX_ErrorNone)
|
|
|
+ if (pSfOMXComponent->hSFComponentExecoder == NULL)
|
|
|
{
|
|
|
- goto EXIT;
|
|
|
+ ret = InitDecoder(pSfOMXComponent);
|
|
|
+ if (ret != OMX_ErrorNone)
|
|
|
+ {
|
|
|
+ goto EXIT;
|
|
|
+ }
|
|
|
}
|
|
|
pSFComponentDecoder = (ComponentImpl *)pSfOMXComponent->hSFComponentExecoder;
|
|
|
pSFComponentFeeder = (ComponentImpl *)pSfOMXComponent->hSFComponentFeeder;
|
|
|
pSFComponentRender = (ComponentImpl *)pSfOMXComponent->hSFComponentRender;
|
|
|
-
|
|
|
- pSFComponentDecoder->pause = OMX_TRUE;
|
|
|
- pSFComponentFeeder->pause = OMX_TRUE;
|
|
|
- pSFComponentRender->pause = OMX_TRUE;
|
|
|
+ componentState = pSfOMXComponent->functions->ComponentGetState(pSfOMXComponent->hSFComponentExecoder);
|
|
|
+ LOG(SF_LOG_INFO, "VPU Current state = %X\r\n", componentState);
|
|
|
+ switch(componentState)
|
|
|
+ {
|
|
|
+ case COMPONENT_STATE_NONE:
|
|
|
+ ret = OMX_ErrorIncorrectStateTransition;
|
|
|
+ break;
|
|
|
+ case COMPONENT_STATE_CREATED:
|
|
|
+ break;
|
|
|
+ case COMPONENT_STATE_PREPARED:
|
|
|
+ case COMPONENT_STATE_EXECUTED:
|
|
|
+ case COMPONENT_STATE_TERMINATED:
|
|
|
+ {
|
|
|
+ PortContainerExternal *pPortContainerExternal = NULL;
|
|
|
+ OMX_BUFFERHEADERTYPE *pOMXBuffer;
|
|
|
+ pSFComponentDecoder->pause = OMX_TRUE;
|
|
|
+ pSFComponentFeeder->pause = OMX_TRUE;
|
|
|
+ pSFComponentRender->pause = OMX_TRUE;
|
|
|
+ FlushBuffer(pSfOMXComponent);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
|
|
|
OMX_EventCmdComplete, OMX_CommandStateSet, nParam, NULL);
|
|
|
break;
|
|
@@ -686,33 +930,52 @@ static OMX_ERRORTYPE SF_OMX_SendCommand(
|
|
|
pSFComponentFeeder = (ComponentImpl *)pSfOMXComponent->hSFComponentFeeder;
|
|
|
pSFComponentRender = (ComponentImpl *)pSfOMXComponent->hSFComponentRender;
|
|
|
|
|
|
- pSFComponentDecoder->pause = OMX_FALSE;
|
|
|
- if (pSFComponentDecoder->thread == NULL)
|
|
|
- {
|
|
|
- LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentDecoder->name);
|
|
|
- componentState = pSfOMXComponent->functions->ComponentExecute(pSFComponentDecoder);
|
|
|
- LOG(SF_LOG_INFO, "ret = %d\r\n", componentState);
|
|
|
- }
|
|
|
- if (pSFComponentFeeder->thread == NULL)
|
|
|
- {
|
|
|
- LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentFeeder->name);
|
|
|
- componentState = pSfOMXComponent->functions->ComponentExecute(pSFComponentFeeder);
|
|
|
- LOG(SF_LOG_INFO, "ret = %d\r\n", componentState);
|
|
|
- }
|
|
|
- if (pSFComponentRender->thread == NULL)
|
|
|
+ componentState = pSfOMXComponent->functions->ComponentGetState(pSfOMXComponent->hSFComponentExecoder);
|
|
|
+ LOG(SF_LOG_INFO, "VPU Current state = %X\r\n", componentState);
|
|
|
+ switch(componentState)
|
|
|
{
|
|
|
- LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentRender->name);
|
|
|
- componentState = pSfOMXComponent->functions->ComponentExecute(pSFComponentRender);
|
|
|
- LOG(SF_LOG_INFO, "ret = %d\r\n", componentState);
|
|
|
+ case COMPONENT_STATE_NONE:
|
|
|
+ case COMPONENT_STATE_TERMINATED:
|
|
|
+ ret = OMX_ErrorIncorrectStateTransition;
|
|
|
+ break;
|
|
|
+ case COMPONENT_STATE_CREATED:
|
|
|
+ if (pSFComponentDecoder->thread == NULL)
|
|
|
+ {
|
|
|
+ LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentDecoder->name);
|
|
|
+ componentState = pSfOMXComponent->functions->ComponentExecute(pSFComponentDecoder);
|
|
|
+ LOG(SF_LOG_INFO, "ret = %d\r\n", componentState);
|
|
|
+ }
|
|
|
+ if (pSFComponentFeeder->thread == NULL)
|
|
|
+ {
|
|
|
+ LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentFeeder->name);
|
|
|
+ componentState = pSfOMXComponent->functions->ComponentExecute(pSFComponentFeeder);
|
|
|
+ LOG(SF_LOG_INFO, "ret = %d\r\n", componentState);
|
|
|
+ }
|
|
|
+ if (pSFComponentRender->thread == NULL)
|
|
|
+ {
|
|
|
+ LOG(SF_LOG_INFO, "execute component %s\r\n", pSFComponentRender->name);
|
|
|
+ componentState = pSfOMXComponent->functions->ComponentExecute(pSFComponentRender);
|
|
|
+ LOG(SF_LOG_INFO, "ret = %d\r\n", componentState);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case COMPONENT_STATE_PREPARED:
|
|
|
+ case COMPONENT_STATE_EXECUTED:
|
|
|
+ pSFComponentDecoder->pause = OMX_FALSE;
|
|
|
+ pSFComponentFeeder->pause = OMX_FALSE;
|
|
|
+ pSFComponentRender->pause = OMX_FALSE;
|
|
|
+ break;
|
|
|
}
|
|
|
+
|
|
|
break;
|
|
|
default:
|
|
|
+ ret = OMX_ErrorIncorrectStateTransition;
|
|
|
break;
|
|
|
}
|
|
|
pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
|
|
|
OMX_EventCmdComplete, OMX_CommandStateSet, nParam, NULL);
|
|
|
break;
|
|
|
case OMX_CommandFlush:
|
|
|
+ FlushBuffer(pSfOMXComponent);
|
|
|
pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData,
|
|
|
OMX_EventCmdComplete, OMX_CommandFlush, nParam, NULL);
|
|
|
break;
|
|
@@ -760,6 +1023,14 @@ static OMX_ERRORTYPE SF_OMX_FreeBuffer(
|
|
|
FunctionIn();
|
|
|
ClearOMXBuffer(pSfOMXComponent, pBufferHdr);
|
|
|
LOG(SF_LOG_PERF, "buffer count = %d\r\n", GetOMXBufferCount(pSfOMXComponent));
|
|
|
+ if (nPortIndex == 1) {
|
|
|
+ LOG(SF_LOG_INFO, "free %p on output buffer\r\n", pBufferHdr->pBuffer);
|
|
|
+ pBufferHdr->pBuffer = NULL;
|
|
|
+ } else {
|
|
|
+ free(pBufferHdr->pBuffer);
|
|
|
+ pBufferHdr->pBuffer = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
free(pBufferHdr);
|
|
|
|
|
|
FunctionOut();
|
|
@@ -868,7 +1139,8 @@ SF_OMX_COMPONENT sf_dec_decoder_h265 = {
|
|
|
.SF_OMX_ComponentClear = SF_OMX_ComponentClear,
|
|
|
.functions = NULL,
|
|
|
.bitFormat = STD_HEVC,
|
|
|
- .fwPath = "/lib/firmware/chagall.bin"};
|
|
|
+ .fwPath = "/lib/firmware/chagall.bin",
|
|
|
+ .componentRule = "video_decoder.hevc"};
|
|
|
|
|
|
SF_OMX_COMPONENT sf_dec_decoder_h264 = {
|
|
|
.componentName = "sf.dec.decoder.h264",
|
|
@@ -878,4 +1150,5 @@ SF_OMX_COMPONENT sf_dec_decoder_h264 = {
|
|
|
.SF_OMX_ComponentClear = SF_OMX_ComponentClear,
|
|
|
.functions = NULL,
|
|
|
.bitFormat = STD_AVC,
|
|
|
- .fwPath = "/lib/firmware/chagall.bin"};
|
|
|
+ .fwPath = "/lib/firmware/chagall.bin",
|
|
|
+ .componentRule = "video_decoder.avc"};
|