Просмотр исходного кода

Merge branch 'CR_6961_OMX_Som.Qin' into 'jh7110-devel'

CR 6961 OMX: Fix issue where the bottom of 1080P video output from the decoder was blurr

See merge request sdk/soft_3rdpart!73
andy.hu 7 месяцев назад
Родитель
Сommit
b83dc39570
3 измененных файлов с 112 добавлено и 37 удалено
  1. 42 36
      omx-il/component/video/wave5/dec/SF_OMX_Vdec_decoder.c
  2. 2 0
      omx-il/core/SF_OMX_Core.h
  3. 68 1
      omx-il/tests/dec_test.c

+ 42 - 36
omx-il/component/video/wave5/dec/SF_OMX_Vdec_decoder.c

@@ -257,21 +257,28 @@ static void OnEventArrived(Component com, unsigned long event, void *data, void
     {
     {
         /*The width and height vpu return will align to 16, eg: 1080 will be 1088. so check scale value at first.*/
         /*The width and height vpu return will align to 16, eg: 1080 will be 1088. so check scale value at first.*/
         TestDecConfig *testConfig = (TestDecConfig *)pSfVideoImplement->testConfig;
         TestDecConfig *testConfig = (TestDecConfig *)pSfVideoImplement->testConfig;
-        OMX_U32 nWidth = testConfig->scaleDownWidth;
-        OMX_U32 nHeight = testConfig->scaleDownHeight;
-        if (nWidth <= 0 || nHeight <= 0)
+        DecHandle decHandle = NULL;
+        DecInitialInfo* pInfo;
+
+        pSfVideoImplement->functions->ComponentGetParameter(NULL, com, GET_PARAM_DEC_HANDLE, &decHandle);
+        pInfo = &decHandle->CodecInfo->decInfo.initialInfo;
+
+        if(testConfig->scaleDownWidth > 0 || testConfig->scaleDownHeight > 0)
         {
         {
-            /*If scale value not set, then get value from vpu*/
-            FrameBuffer *frameBuffer = (FrameBuffer *)data;
-            nWidth = frameBuffer->width;
-            nHeight = frameBuffer->height;
+            pSfOMXComponent->portDefinition[1].format.video.nFrameWidth = testConfig->scaleDownWidth;
+            pSfOMXComponent->portDefinition[1].format.video.nFrameHeight = testConfig->scaleDownHeight;
+            pSfOMXComponent->portDefinition[1].format.video.nStride = testConfig->scaleDownWidth;
+            pSfOMXComponent->portDefinition[1].format.video.nSliceHeight = testConfig->scaleDownHeight;
         }
         }
-
-        LOG(SF_LOG_INFO, "Get Output width = %d, height = %d\r\n", nWidth, nHeight);
-        pSfOMXComponent->portDefinition[1].format.video.nFrameWidth = nWidth;
-        pSfOMXComponent->portDefinition[1].format.video.nFrameHeight = nHeight;
-        pSfOMXComponent->portDefinition[1].format.video.nStride = nWidth;
-        pSfOMXComponent->portDefinition[1].format.video.nSliceHeight = nHeight;
+        else
+        {
+            pSfOMXComponent->portDefinition[1].format.video.nFrameWidth = pInfo->picCropRect.right;
+            pSfOMXComponent->portDefinition[1].format.video.nFrameHeight = pInfo->picCropRect.bottom;
+            pSfOMXComponent->portDefinition[1].format.video.nStride = pInfo->picWidth;
+            pSfOMXComponent->portDefinition[1].format.video.nSliceHeight = pInfo->picHeight;
+        }
+        LOG(SF_LOG_INFO, "Get Output width = %d, height = %d\r\n", pSfOMXComponent->portDefinition[1].format.video.nFrameWidth,
+                pSfOMXComponent->portDefinition[1].format.video.nFrameHeight);
 
 
         ComponentImpl *pRendererComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
         ComponentImpl *pRendererComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
         pSfOMXComponent->portDefinition[1].nBufferCountActual = pSfVideoImplement->functions->GetRenderTotalBufferNumber(pRendererComponent);
         pSfOMXComponent->portDefinition[1].nBufferCountActual = pSfVideoImplement->functions->GetRenderTotalBufferNumber(pRendererComponent);
@@ -283,14 +290,12 @@ static void OnEventArrived(Component com, unsigned long event, void *data, void
         case OMX_COLOR_FormatYUV420Planar:
         case OMX_COLOR_FormatYUV420Planar:
         case OMX_COLOR_FormatYUV420SemiPlanar:
         case OMX_COLOR_FormatYUV420SemiPlanar:
         case OMX_COLOR_FormatYVU420SemiPlanar:
         case OMX_COLOR_FormatYVU420SemiPlanar:
-            if (nWidth && nHeight) {
-                pSfOMXComponent->portDefinition[1].nBufferSize = (nWidth * nHeight * 3) / 2;
-            }
+                pSfOMXComponent->portDefinition[1].nBufferSize = (pSfOMXComponent->portDefinition[1].format.video.nStride
+                    * pSfOMXComponent->portDefinition[1].format.video.nSliceHeight * 3) / 2;
             break;
             break;
         default:
         default:
-            if (nWidth && nHeight) {
-                pSfOMXComponent->portDefinition[1].nBufferSize = nWidth * nHeight * 2;
-            }
+                pSfOMXComponent->portDefinition[1].nBufferSize = pSfOMXComponent->portDefinition[1].format.video.nStride
+                    * pSfOMXComponent->portDefinition[1].format.video.nSliceHeight * 2;
             break;
             break;
         }
         }
         pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventPortSettingsChanged,
         pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventPortSettingsChanged,
@@ -666,8 +671,8 @@ static OMX_ERRORTYPE SF_OMX_AllocateBuffer(
                 if (pSfOMXComponent->memory_optimization)
                 if (pSfOMXComponent->memory_optimization)
                 {
                 {
                     OMX_U32 nLinearBufferSize, nFrameWidth, nFrameHeight;
                     OMX_U32 nLinearBufferSize, nFrameWidth, nFrameHeight;
-                    nFrameWidth = OMX_ALIGN32(pSfOMXComponent->portDefinition[1].format.video.nFrameWidth);
-                    nFrameHeight = pSfOMXComponent->portDefinition[1].format.video.nFrameHeight;
+                    nFrameWidth = pSfOMXComponent->portDefinition[1].format.video.nStride;
+                    nFrameHeight = pSfOMXComponent->portDefinition[1].format.video.nSliceHeight;
                     nLinearBufferSize = nFrameWidth * nFrameHeight * 3 / 2;
                     nLinearBufferSize = nFrameWidth * nFrameHeight * 3 / 2;
                     nLinearBufferSize = (nLinearBufferSize > nSizeBytes)? nLinearBufferSize : nSizeBytes;
                     nLinearBufferSize = (nLinearBufferSize > nSizeBytes)? nLinearBufferSize : nSizeBytes;
                     temp_bufferHeader->pBuffer = pSfVideoImplement->functions->AllocateFrameBuffer2(pComponentRender, nLinearBufferSize);
                     temp_bufferHeader->pBuffer = pSfVideoImplement->functions->AllocateFrameBuffer2(pComponentRender, nLinearBufferSize);
@@ -1030,12 +1035,12 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
             pOutputPort->format.video.nFrameWidth = width;
             pOutputPort->format.video.nFrameWidth = width;
             pOutputPort->format.video.nFrameHeight = height;
             pOutputPort->format.video.nFrameHeight = height;
             pOutputPort->format.video.nStride = width;
             pOutputPort->format.video.nStride = width;
-            pOutputPort->format.video.nSliceHeight = height;
-            pTestDecConfig->scaleDownWidth = VPU_CEIL(width, 2);
-            pTestDecConfig->scaleDownHeight = VPU_CEIL(height, 2);
+            pOutputPort->format.video.nSliceHeight = OMX_ALIGN16(height);
+            pTestDecConfig->scaleDownWidth = 0;
+            pTestDecConfig->scaleDownHeight = 0;
             if (width && height)
             if (width && height)
-                    pOutputPort->nBufferSize = (width * height * 3) / 2;
-            LOG(SF_LOG_INFO, "Set scale = %d, %d\r\n", pTestDecConfig->scaleDownWidth , pTestDecConfig->scaleDownHeight);
+                    pOutputPort->nBufferSize = (pOutputPort->format.video.nStride * pOutputPort->format.video.nSliceHeight * 3) / 2;
+            LOG(SF_LOG_INFO, "Set resol = %d x %d, stride %d x %d\r\n", width, height, pOutputPort->format.video.nStride, pOutputPort->format.video.nSliceHeight);
         }
         }
         else if (portIndex == 1)
         else if (portIndex == 1)
         {
         {
@@ -1082,10 +1087,14 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
             pOutputPort->format.video.nFrameWidth = width;
             pOutputPort->format.video.nFrameWidth = width;
             pOutputPort->format.video.nFrameHeight = height;
             pOutputPort->format.video.nFrameHeight = height;
             pOutputPort->format.video.nStride = width;
             pOutputPort->format.video.nStride = width;
-            pOutputPort->format.video.nSliceHeight = height;
-            pTestDecConfig->scaleDownWidth = VPU_CEIL(width, 2);
-            pTestDecConfig->scaleDownHeight = VPU_CEIL(height, 2);
-            LOG(SF_LOG_INFO, "Set scale = %d, %d\r\n", pTestDecConfig->scaleDownWidth , pTestDecConfig->scaleDownHeight);
+            pOutputPort->format.video.nSliceHeight = OMX_ALIGN16(height);
+            LOG(SF_LOG_INFO, "Set resol = %d x %d, stride %d x %d\r\n", width, height, pOutputPort->format.video.nStride, pOutputPort->format.video.nSliceHeight);
+            if(width != pInputPort->format.video.nFrameWidth || height != pInputPort->format.video.nFrameHeight)
+            {
+                pTestDecConfig->scaleDownWidth = OMX_ALIGN2(width);
+                pTestDecConfig->scaleDownHeight = OMX_ALIGN2(height);
+                LOG(SF_LOG_INFO, "Set scale = %d, %d\r\n", pTestDecConfig->scaleDownWidth , pTestDecConfig->scaleDownHeight);
+            }
              /*
              /*
                 if cbcrInterleave is FALSE and nv21 is FALSE, the default dec format is I420
                 if cbcrInterleave is FALSE and nv21 is FALSE, the default dec format is I420
                 if cbcrInterleave is TRUE and nv21 is FALSE, then the dec format is NV12
                 if cbcrInterleave is TRUE and nv21 is FALSE, then the dec format is NV12
@@ -1098,19 +1107,19 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
                 pTestDecConfig->cbcrInterleave = FALSE;
                 pTestDecConfig->cbcrInterleave = FALSE;
                 pTestDecConfig->nv21 = FALSE;
                 pTestDecConfig->nv21 = FALSE;
                 if (width && height)
                 if (width && height)
-                    pOutputPort->nBufferSize = (width * height * 3) / 2;
+                    pOutputPort->nBufferSize = (pOutputPort->format.video.nStride * pOutputPort->format.video.nSliceHeight * 3) / 2;
                 break;
                 break;
             case OMX_COLOR_FormatYUV420SemiPlanar: //NV12
             case OMX_COLOR_FormatYUV420SemiPlanar: //NV12
                 pTestDecConfig->cbcrInterleave = TRUE;
                 pTestDecConfig->cbcrInterleave = TRUE;
                 pTestDecConfig->nv21 = FALSE;
                 pTestDecConfig->nv21 = FALSE;
                 if (width && height)
                 if (width && height)
-                    pOutputPort->nBufferSize = (width * height * 3) / 2;
+                    pOutputPort->nBufferSize = (pOutputPort->format.video.nStride * pOutputPort->format.video.nSliceHeight * 3) / 2;
                 break;
                 break;
             case OMX_COLOR_FormatYVU420SemiPlanar: //NV21
             case OMX_COLOR_FormatYVU420SemiPlanar: //NV21
                 pTestDecConfig->cbcrInterleave = TRUE;
                 pTestDecConfig->cbcrInterleave = TRUE;
                 pTestDecConfig->nv21 = TRUE;
                 pTestDecConfig->nv21 = TRUE;
                 if (width && height)
                 if (width && height)
-                    pOutputPort->nBufferSize = (width * height * 3) / 2;
+                    pOutputPort->nBufferSize = (pOutputPort->format.video.nStride * pOutputPort->format.video.nSliceHeight * 3) / 2;
                 break;
                 break;
             default:
             default:
                 LOG(SF_LOG_ERR, "Error to set parameter: %d, only nv12 nv21 i420 supported\r\n",
                 LOG(SF_LOG_ERR, "Error to set parameter: %d, only nv12 nv21 i420 supported\r\n",
@@ -1277,7 +1286,6 @@ static OMX_ERRORTYPE InitDecoder(SF_OMX_COMPONENT *pSfOMXComponent)
     char *fwPath = NULL;
     char *fwPath = NULL;
     SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
     SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
     OMX_PARAM_PORTDEFINITIONTYPE *pInputPort = &pSfOMXComponent->portDefinition[0];
     OMX_PARAM_PORTDEFINITIONTYPE *pInputPort = &pSfOMXComponent->portDefinition[0];
-    OMX_PARAM_PORTDEFINITIONTYPE *pOutputPort = &pSfOMXComponent->portDefinition[1];
 
 
     if (pSfVideoImplement->hSFComponentExecoder != NULL)
     if (pSfVideoImplement->hSFComponentExecoder != NULL)
     {
     {
@@ -1316,8 +1324,6 @@ static OMX_ERRORTYPE InitDecoder(SF_OMX_COMPONENT *pSfOMXComponent)
         LOG(SF_LOG_ERR, "Failed to load firmware: %s\n", fwPath);
         LOG(SF_LOG_ERR, "Failed to load firmware: %s\n", fwPath);
         return OMX_ErrorInsufficientResources;
         return OMX_ErrorInsufficientResources;
     }
     }
-    testConfig->scaleDownWidth = VPU_CEIL(pOutputPort->format.video.nFrameWidth, 2);
-    testConfig->scaleDownHeight = VPU_CEIL(pOutputPort->format.video.nFrameHeight, 2);
 
 
     config = pSfVideoImplement->config;
     config = pSfVideoImplement->config;
     memcpy(&(config->testDecConfig), testConfig, sizeof(TestDecConfig));
     memcpy(&(config->testDecConfig), testConfig, sizeof(TestDecConfig));

+ 2 - 0
omx-il/core/SF_OMX_Core.h

@@ -130,6 +130,8 @@ typedef struct _SF_PORT_PRIVATE
 } SF_PORT_PRIVATE;
 } SF_PORT_PRIVATE;
 
 
 #define OMX_ALIGN32(_x)  (((_x)+0x1f)&~0x1f)
 #define OMX_ALIGN32(_x)  (((_x)+0x1f)&~0x1f)
+#define OMX_ALIGN16(_x)  (((_x)+0xf)&~0xf)
+#define OMX_ALIGN2(_x)   (((_x)+0x1)&~0x1)
 
 
 #define PRINT_STUCT(a, b)                                   \
 #define PRINT_STUCT(a, b)                                   \
     do                                                      \
     do                                                      \

+ 68 - 1
omx-il/tests/dec_test.c

@@ -41,6 +41,11 @@ typedef struct DecodeTestContext
     char sOutputFormat[64];
     char sOutputFormat[64];
     OMX_U32 ScaleWidth;
     OMX_U32 ScaleWidth;
     OMX_U32 ScaleHeight;
     OMX_U32 ScaleHeight;
+    OMX_U32 OutputWidth;
+    OMX_U32 OutputHeight;
+    OMX_U32 OutputStride;
+    OMX_U32 OutputSlice;
+    OMX_COLOR_FORMATTYPE FormatType;
     OMX_BUFFERHEADERTYPE *pInputBufferArray[64];
     OMX_BUFFERHEADERTYPE *pInputBufferArray[64];
     OMX_BUFFERHEADERTYPE *pOutputBufferArray[64];
     OMX_BUFFERHEADERTYPE *pOutputBufferArray[64];
     AVFormatContext *avContext;
     AVFormatContext *avContext;
@@ -83,6 +88,11 @@ static OMX_ERRORTYPE event_handler(
         printf("out put resolution [%dx%d]\r\n", pOutputPortDefinition.format.video.nFrameWidth, pOutputPortDefinition.format.video.nFrameHeight);
         printf("out put resolution [%dx%d]\r\n", pOutputPortDefinition.format.video.nFrameWidth, pOutputPortDefinition.format.video.nFrameHeight);
         printf("======================================\r\n");
         printf("======================================\r\n");
 
 
+        pDecodeTestContext->OutputWidth = pOutputPortDefinition.format.video.nFrameWidth;
+        pDecodeTestContext->OutputHeight = pOutputPortDefinition.format.video.nFrameHeight;
+        pDecodeTestContext->OutputStride = pOutputPortDefinition.format.video.nStride;
+        pDecodeTestContext->OutputSlice = pOutputPortDefinition.format.video.nSliceHeight;
+
         OMX_SendCommand(pDecodeTestContext->hComponentDecoder, OMX_CommandPortEnable, 1, NULL);
         OMX_SendCommand(pDecodeTestContext->hComponentDecoder, OMX_CommandPortEnable, 1, NULL);
 
 
         for (int i = 0; i < nOutputBufferCount; i++)
         for (int i = 0; i < nOutputBufferCount; i++)
@@ -254,6 +264,62 @@ static OMX_S32 FillInputBuffer(DecodeTestContext *decodeTestContext, OMX_BUFFERH
     return avpacket->size;
     return avpacket->size;
 }
 }
 
 
+static OMX_S32 WriteOutputBuffer(DecodeTestContext *decodeTestContext, OMX_BUFFERHEADERTYPE *pInputBuffer, FILE *fb)
+{
+    OMX_U32 i, j, PlaneCnt = 0;
+    OMX_U32 srcWidth[3] = {0};
+    OMX_U32 srcStride[3] = {0};
+    OMX_U32 srcHeight[3] = {0};
+    OMX_U32 srcSlice[3] = {0};
+    OMX_U8 *pBuffer = pInputBuffer->pBuffer;
+
+    switch (decodeTestContext->FormatType)
+    {
+    case OMX_COLOR_FormatYUV420Planar :
+        PlaneCnt = 3;
+        srcWidth[0] = decodeTestContext->OutputWidth;
+        srcStride[0] = decodeTestContext->OutputStride;
+        srcHeight[0] = decodeTestContext->OutputHeight;
+        srcSlice[0] = decodeTestContext->OutputSlice;
+        srcWidth[1] = srcWidth[2] = srcWidth[0] / 2;
+        srcStride[1] = srcStride[2] = srcStride[0] / 2;
+        srcHeight[1] = srcHeight[2] = srcHeight[0] / 2;
+        srcSlice[1] = srcSlice[2] = srcSlice[0] /2 ;
+        break;
+    case OMX_COLOR_FormatYUV420SemiPlanar:
+    case OMX_COLOR_FormatYVU420SemiPlanar:
+        PlaneCnt = 2;
+        srcWidth[0] = decodeTestContext->OutputWidth;
+        srcStride[0] = decodeTestContext->OutputStride;
+        srcHeight[0] = decodeTestContext->OutputHeight;
+        srcSlice[0] = decodeTestContext->OutputSlice;
+        srcWidth[1] = srcWidth[0];
+        srcStride[1] = srcStride[0];
+        srcHeight[1] = srcHeight[0] / 2;
+        srcSlice[1] = srcSlice[0] / 2 ;
+        break;
+    default:
+        return -1;
+    }
+
+    for (i = 0; i < PlaneCnt; i++)
+    {
+        if (srcStride[i] > srcWidth[i])
+        {
+            for (j = 0; j < srcHeight[i]; i++)
+            fwrite(pBuffer + j * srcStride[i], 1, srcWidth[i], fb);
+
+        }
+        else
+        {
+            fwrite(pBuffer, 1, srcStride[i] * srcHeight[i], fb);
+        }
+        pBuffer += srcStride[i] * srcSlice[i];
+    }
+
+    return 0;
+}
+
 int main(int argc, char **argv)
 int main(int argc, char **argv)
 {
 {
     printf("=============================\r\n");
     printf("=============================\r\n");
@@ -460,6 +526,7 @@ int main(int argc, char **argv)
         printf("Unsupported color format!\r\n");
         printf("Unsupported color format!\r\n");
         goto end;
         goto end;
     }
     }
+    decodeTestContext->FormatType = pOutputPortDefinition.format.video.eColorFormat;
     OMX_SetParameter(hComponentDecoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
     OMX_SetParameter(hComponentDecoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
 
 
     disableEVnt = OMX_FALSE;
     disableEVnt = OMX_FALSE;
@@ -528,7 +595,7 @@ int main(int argc, char **argv)
         case 1:
         case 1:
         {
         {
             OMX_BUFFERHEADERTYPE *pBuffer = data.pBuffer;
             OMX_BUFFERHEADERTYPE *pBuffer = data.pBuffer;
-            fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, fb);
+            WriteOutputBuffer(decodeTestContext, pBuffer, fb);
             if ((pBuffer->nFlags) & (OMX_BUFFERFLAG_EOS == OMX_BUFFERFLAG_EOS))
             if ((pBuffer->nFlags) & (OMX_BUFFERFLAG_EOS == OMX_BUFFERFLAG_EOS))
             {
             {
                 goto end;
                 goto end;