Browse Source

Fix the problem of out of order output of output port buffer

Signed-off-by: sw.multimedia <sw.multimedia@starfivetech.com>
sw.multimedia 2 years ago
parent
commit
efd6042e3f

+ 260 - 0
soft_3rdpart/codaj12/jpuapi/jpuapi.c

@@ -990,6 +990,266 @@ JpgRet JPU_DecStartOneFrame(JpgDecHandle handle, JpgDecParam *param)
     return JPG_RET_SUCCESS;
 }
 
+JpgRet JPU_DecStartOneFrameBySerialNum(JpgDecHandle handle, JpgDecParam *param,int bufferIndex)
+{
+    JpgInst * pJpgInst;
+    JpgDecInfo * pDecInfo;
+    JpgRet ret;
+    Uint32 val;
+    PhysicalAddress rdPtr, wrPtr;
+    BOOL    is12Bit     = FALSE;
+    BOOL    ppuEnable   = FALSE;
+    Int32 instRegIndex;
+    BOOL bTableInfoUpdate;
+    ret = CheckJpgInstValidity(handle);
+    if (ret != JPG_RET_SUCCESS)
+        return ret;
+
+
+    pJpgInst = handle;
+    pDecInfo = &pJpgInst->JpgInfo->decInfo;
+    is12Bit  = (pDecInfo->bitDepth == 8) ? FALSE : TRUE;
+
+    if (pDecInfo->frameBufPool == 0) { // This means frame buffers have not been registered.
+        return JPG_RET_WRONG_CALL_SEQUENCE;
+    }
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        instRegIndex = pJpgInst->instIndex;
+    }
+    else {
+        instRegIndex = 0;
+    }
+
+    JpgEnterLock();
+    if (GetJpgPendingInstEx(pJpgInst->instIndex) == pJpgInst) {
+        JpgLeaveLock();
+        return JPG_RET_FRAME_NOT_COMPLETE;
+    }
+
+
+    if (pDecInfo->frameOffset < 0) {
+        SetJpgPendingInstEx(0, pJpgInst->instIndex);
+        return JPG_RET_EOS;
+    }
+
+    pDecInfo->q_prec0 = 0;
+    pDecInfo->q_prec1 = 0;
+    pDecInfo->q_prec2 = 0;
+    pDecInfo->q_prec3 = 0;
+
+    //check for stream empty case
+    if (pDecInfo->streamEndflag == 0) {
+        rdPtr = pDecInfo->streamRdPtr;
+        wrPtr = pDecInfo->streamWrPtr;
+        if (wrPtr == pDecInfo->streamBufStartAddr)
+            wrPtr = pDecInfo->streamBufEndAddr;
+        if (rdPtr > wrPtr) { // wrap-around case
+            if ( ((pDecInfo->streamBufEndAddr-rdPtr) + (wrPtr-pDecInfo->streamBufStartAddr)) <1024 ) {
+                JpgLeaveLock();
+                return JPG_RET_BIT_EMPTY;
+            }
+        }
+        else {
+            if (wrPtr - rdPtr < 1024) {
+                JpgLeaveLock();
+                return JPG_RET_BIT_EMPTY;
+            }
+        }
+    }
+
+    {
+        val = JpegDecodeHeader(pDecInfo);
+        if (val == 0) {
+            JpgLeaveLock();
+            return JPG_RET_FAILURE;
+        }
+
+        if (val == (Uint32)-2) {	// wrap around case
+            pDecInfo->frameOffset = 0;
+            pDecInfo->ecsPtr = 0;
+            val = JpegDecodeHeader(pDecInfo);
+            if (val == 0) {
+                JpgLeaveLock();
+                return JPG_RET_FAILURE;
+            }
+        }
+
+        if (val == (Uint32)-1) {	//stream empty case
+            if (pDecInfo->streamEndflag == 1) {
+                SetJpgPendingInstEx(0, pJpgInst->instIndex);
+                pDecInfo->frameOffset = -1;
+                if (pJpgInst->sliceInstMode == TRUE) {
+                    JpgLeaveLock();
+                }
+                return JPG_RET_EOS;
+            }
+            JpgLeaveLock();
+            return JPG_RET_BIT_EMPTY;
+        }
+    }
+
+    JpuWriteInstReg(instRegIndex, MJPEG_INTR_MASK_REG, ((~pDecInfo->intrEnableBit) & 0x3ff));
+    /* The registers related to the slice encoding should be clear */
+    JpuWriteInstReg(instRegIndex, MJPEG_SLICE_INFO_REG,    pDecInfo->alignedHeight);
+    JpuWriteInstReg(instRegIndex, MJPEG_SLICE_DPB_POS_REG, pDecInfo->alignedHeight);
+    JpuWriteInstReg(instRegIndex, MJPEG_SLICE_POS_REG,     0);
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_SETMB_REG,     0);
+
+    if (pDecInfo->streamRdPtr == pDecInfo->streamBufEndAddr) {
+        JpuWriteInstReg(instRegIndex, MJPEG_BBC_CUR_POS_REG, 0);
+        JpuWriteInstReg(instRegIndex, MJPEG_GBU_TCNT_REG, 0);
+        JpuWriteInstReg(instRegIndex, (MJPEG_GBU_TCNT_REG+4), 0);
+    }
+
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_WR_PTR_REG, pDecInfo->streamWrPtr);
+    if (pDecInfo->streamWrPtr == pDecInfo->streamBufStartAddr) {
+        JpuWriteInstReg(instRegIndex, MJPEG_BBC_END_ADDR_REG, pDecInfo->streamBufEndAddr);
+    }
+    else {
+        JpuWriteInstReg(instRegIndex, MJPEG_BBC_END_ADDR_REG, JPU_CEIL(256, pDecInfo->streamWrPtr));
+    }
+
+    JpuWriteInstReg(instRegIndex, MJPEG_BBC_BAS_ADDR_REG, pDecInfo->streamBufStartAddr);
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_TCNT_REG, 0);
+    JpuWriteInstReg(instRegIndex, (MJPEG_GBU_TCNT_REG+4), 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_ERRMB_REG, 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_CTRL_REG, is12Bit << 31 | pDecInfo->q_prec0 << 30 | pDecInfo->q_prec1 << 29 | pDecInfo->q_prec2 << 28 | pDecInfo->q_prec3 << 27 |
+                                                       pDecInfo->huffAcIdx << 13 | pDecInfo->huffDcIdx << 7 | pDecInfo->userHuffTab << 6 |
+                                                       (JPU_CHECK_WRITE_RESPONSE_BVALID_SIGNAL << 2) | 0);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_PIC_SIZE_REG, (pDecInfo->alignedWidth << 16) | pDecInfo->alignedHeight);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_OP_INFO_REG,  pDecInfo->busReqNum);
+    JpuWriteInstReg(instRegIndex, MJPEG_MCU_INFO_REG, (pDecInfo->mcuBlockNum&0x0f) << 17 | (pDecInfo->compNum&0x07) << 14    |
+                                                      (pDecInfo->compInfo[0]&0x3f) << 8  | (pDecInfo->compInfo[1]&0x0f) << 4 |
+                                                      (pDecInfo->compInfo[2]&0x0f));
+
+    //enable intlv NV12: 10, NV21: 11
+    //packedFormat:0 => 4'd0
+    //packedFormat:1,2,3,4 => 4, 5, 6, 7,
+    //packedFormat:5 => 8
+    //packedFormat:6 => 9
+    val = (pDecInfo->ofmt << 9) | (pDecInfo->frameEndian << 6) | ((pDecInfo->chromaInterleave==0)?0:(pDecInfo->chromaInterleave==1)?2:3);
+    if (pDecInfo->packedFormat == PACKED_FORMAT_NONE) {
+        val |= (0<<5) | (0<<4);
+    }
+    else if (pDecInfo->packedFormat == PACKED_FORMAT_444) {
+        val |= (1<<5) | (0<<4) | (0<<2);
+    }
+    else {
+        val |= (0<<5) | (1<<4) | ((pDecInfo->packedFormat-1)<<2);
+    }
+    val |= (pDecInfo->pixelJustification << 11);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_CONFIG_REG, val);
+    JpuWriteInstReg(instRegIndex, MJPEG_RST_INTVAL_REG, pDecInfo->rstIntval);
+
+    if (param) {
+        if (param->scaleDownRatioWidth > 0 )
+            pDecInfo->iHorScaleMode = param->scaleDownRatioWidth;
+        if (param->scaleDownRatioHeight > 0 )
+            pDecInfo->iVerScaleMode = param->scaleDownRatioHeight;
+    }
+    if (pDecInfo->iHorScaleMode | pDecInfo->iVerScaleMode)
+        val = ((pDecInfo->iHorScaleMode&0x3)<<2) | ((pDecInfo->iVerScaleMode&0x3)) | 0x10 ;
+    else {
+        val = 0;
+    }
+    JpuWriteInstReg(instRegIndex, MJPEG_SCL_INFO_REG, val);
+
+    bTableInfoUpdate = FALSE;
+    if (pDecInfo->userHuffTab) {
+        bTableInfoUpdate = TRUE;
+    }
+
+    if (bTableInfoUpdate == TRUE) {
+        if (is12Bit == TRUE){
+            if (!JpgDecHuffTabSetUp_12b(pDecInfo, instRegIndex)) {
+                JpgLeaveLock();
+                return JPG_RET_INVALID_PARAM;
+            }
+        }else{
+            if (!JpgDecHuffTabSetUp(pDecInfo, instRegIndex)) {
+                JpgLeaveLock();
+                return JPG_RET_INVALID_PARAM;
+            }
+        }
+    }
+
+    bTableInfoUpdate = TRUE; // it always should be TRUE for multi-instance
+    if (bTableInfoUpdate == TRUE) {
+        if (!JpgDecQMatTabSetUp(pDecInfo, instRegIndex)) {
+            JpgLeaveLock();
+            return JPG_RET_INVALID_PARAM;
+        }
+    }
+
+    JpgDecGramSetup(pDecInfo, instRegIndex);
+
+    if (pDecInfo->streamEndflag == 1) {
+        val = JpuReadInstReg(instRegIndex, MJPEG_BBC_STRM_CTRL_REG);
+        if ((val & (1UL << 31)) == 0 ) {
+            val = (pDecInfo->streamWrPtr-pDecInfo->streamBufStartAddr) / 256;
+            if ((pDecInfo->streamWrPtr-pDecInfo->streamBufStartAddr) % 256)
+                val = val + 1;
+            JpuWriteInstReg(instRegIndex, MJPEG_BBC_STRM_CTRL_REG, (1UL << 31 | val));
+        }
+    }
+    else {
+        JpuWriteInstReg(instRegIndex, MJPEG_BBC_STRM_CTRL_REG, 0);
+    }
+
+    JpuWriteInstReg(instRegIndex, MJPEG_RST_INDEX_REG, 0);	// RST index at the beginning.
+    JpuWriteInstReg(instRegIndex, MJPEG_RST_COUNT_REG, 0);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_DPCM_DIFF_Y_REG, 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPCM_DIFF_CB_REG, 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPCM_DIFF_CR_REG, 0);
+
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_FF_RPTR_REG, pDecInfo->bitPtr);
+    JpuWriteInstReg(instRegIndex, MJPEG_GBU_CTRL_REG, 3);
+
+    ppuEnable = (pDecInfo->rotationIndex > 0) || (pDecInfo->mirrorIndex > 0);
+    JpuWriteInstReg(instRegIndex, MJPEG_ROT_INFO_REG, (ppuEnable<<4) | (pDecInfo->mirrorIndex<<2) | pDecInfo->rotationIndex);
+
+    val = (Uint32)bufferIndex;
+    // JLOG(INFO, "%s: bufY = %lx bufCb = %lx bufCr = %lx stride = %d stride_c = %d\r\n", __FUNCTION__,
+    //     pDecInfo->frameBufPool[val].bufY, pDecInfo->frameBufPool[val].bufCb, pDecInfo->frameBufPool[val].bufCr, 
+    //     pDecInfo->stride, pDecInfo->stride_c);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_BASE00_REG, pDecInfo->frameBufPool[val].bufY);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_BASE01_REG, pDecInfo->frameBufPool[val].bufCb);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_BASE02_REG, pDecInfo->frameBufPool[val].bufCr);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_YSTRIDE_REG, pDecInfo->stride);
+    JpuWriteInstReg(instRegIndex, MJPEG_DPB_CSTRIDE_REG, pDecInfo->stride_c);
+
+    if (pDecInfo->roiEnable) {
+        JpuWriteInstReg(instRegIndex, MJPEG_CLP_INFO_REG, 1);
+        JpuWriteInstReg(instRegIndex, MJPEG_CLP_BASE_REG, pDecInfo->roiOffsetX << 16 | pDecInfo->roiOffsetY);	// pixel unit
+        JpuWriteInstReg(instRegIndex, MJPEG_CLP_SIZE_REG, (pDecInfo->roiFrameWidth << 16) | pDecInfo->roiFrameHeight); // pixel Unit
+    }
+    else {
+        JpuWriteInstReg(instRegIndex, MJPEG_CLP_INFO_REG, 0);
+    }
+
+    if (pJpgInst->loggingEnable)
+        jdi_log(JDI_LOG_CMD_PICRUN, 1, instRegIndex);
+
+    if (pJpgInst->sliceInstMode == TRUE) {
+        JpuWriteInstReg(instRegIndex, MJPEG_PIC_START_REG, (1<<JPG_DEC_SLICE_ENABLE_START_PIC));
+    }
+    else {
+        JpuWriteInstReg(instRegIndex, MJPEG_PIC_START_REG, (1<<JPG_ENABLE_START_PIC));
+    }
+
+    pDecInfo->decIdx++;
+
+    SetJpgPendingInstEx(pJpgInst, pJpgInst->instIndex);
+    if (pJpgInst->sliceInstMode == TRUE) {
+        JpgLeaveLock();
+    }
+    return JPG_RET_SUCCESS;
+}
+
 JpgRet JPU_DecGetOutputInfo(JpgDecHandle handle, JpgDecOutputInfo * info)
 {
     JpgInst*    pJpgInst;

+ 5 - 0
soft_3rdpart/codaj12/jpuapi/jpuapi.h

@@ -1053,6 +1053,11 @@ This means the stream ends.
     JpgRet JPU_DecStartOneFrame(
         JpgDecHandle handle,
         JpgDecParam *param );
+
+    JpgRet JPU_DecStartOneFrameBySerialNum(
+        JpgDecHandle handle,
+        JpgDecParam *param,
+        int bufferIndex );
 /**
 * @brief
 Application can get the information of output of decoding. The information

+ 1 - 1
soft_3rdpart/omx-il/component/image/common/SF_OMX_mjpeg_common.c

@@ -216,7 +216,7 @@ static void sf_get_component_functions(SF_CODAJ12_FUNCTIONS *funcs, OMX_PTR *soh
     funcs->JPU_DecRegisterFrameBuffer2 = dlsym(sohandle, "JPU_DecRegisterFrameBuffer2");
     funcs->JPU_DecRegisterFrameBuffer = dlsym(sohandle, "JPU_DecRegisterFrameBuffer");
     funcs->JPU_DecGiveCommand = dlsym(sohandle, "JPU_DecGiveCommand");
-    funcs->JPU_DecStartOneFrame = dlsym(sohandle, "JPU_DecStartOneFrame");
+    funcs->JPU_DecStartOneFrameBySerialNum = dlsym(sohandle, "JPU_DecStartOneFrameBySerialNum");
     funcs->JPU_DecGetOutputInfo = dlsym(sohandle, "JPU_DecGetOutputInfo");
     funcs->JPU_SWReset = dlsym(sohandle, "JPU_SWReset");
     funcs->JPU_DecSetRdPtrEx = dlsym(sohandle, "JPU_DecSetRdPtrEx");

+ 1 - 1
soft_3rdpart/omx-il/component/image/common/SF_OMX_mjpeg_common.h

@@ -48,7 +48,7 @@ typedef struct _SF_CODAJ12_FUNCTIONS
     JpgRet (*JPU_DecRegisterFrameBuffer2)(JpgDecHandle handle, FrameBuffer *bufArray, int stride);
     JpgRet (*JPU_DecRegisterFrameBuffer)(JpgDecHandle handle, FrameBuffer * bufArray, int num, int stride);
     JpgRet (*JPU_DecGiveCommand)(JpgDecHandle handle, JpgCommand cmd, void *param);
-    JpgRet (*JPU_DecStartOneFrame)(JpgDecHandle handle, JpgDecParam *param);
+    JpgRet (*JPU_DecStartOneFrameBySerialNum)(JpgDecHandle handle, JpgDecParam *param,int bufferIndex);
     JpgRet (*JPU_DecGetOutputInfo)(JpgDecHandle handle, JpgDecOutputInfo *info);
     JpgRet (*JPU_SWReset)(JpgHandle handle);
     JpgRet (*JPU_DecSetRdPtrEx)(JpgDecHandle handle, PhysicalAddress addr, BOOL updateWrPtr);

+ 10 - 29
soft_3rdpart/omx-il/component/image/dec/SF_OMX_Mjpeg_decoder.c

@@ -100,7 +100,6 @@ static OMX_ERRORTYPE SF_OMX_FillThisBuffer(
     // {
     //     return OMX_ErrorInsufficientResources;
     // }
-    StoreOMXBuffer(pSfOMXComponent, pBuffer);
     Message data;
     data.msg_type = 1;
     data.msg_flag = 0;
@@ -196,6 +195,8 @@ static OMX_ERRORTYPE SF_OMX_AllocateBuffer(
     if (nPortIndex == 1)
     {
         temp_bufferHeader->pBuffer = AllocateOutputBuffer(pSfOMXComponent, nSizeBytes);
+        temp_bufferHeader->pOutputPortPrivate = (OMX_PTR)nOutBufIndex;
+        nOutBufIndex ++;
         // temp_bufferHeader->nFilledLen = nSizeBytes;
     }
     else if (nPortIndex == 0)
@@ -721,7 +722,7 @@ static OMX_U32 FeedData(SF_OMX_COMPONENT *pSfOMXComponent)
     return nFilledLen;
 }
 
-static OMX_ERRORTYPE WaitForOutputBufferReady(SF_OMX_COMPONENT *pSfOMXComponent)
+static OMX_ERRORTYPE WaitForOutputBufferReady(SF_OMX_COMPONENT *pSfOMXComponent,OMX_BUFFERHEADERTYPE **ppOMXBuffer)
 {
     FunctionIn();
     OMX_ERRORTYPE ret = OMX_ErrorNone;
@@ -742,6 +743,7 @@ static OMX_ERRORTYPE WaitForOutputBufferReady(SF_OMX_COMPONENT *pSfOMXComponent)
         pSfCodaj12Implement->bThreadRunning = OMX_FALSE;
         ret = OMX_ErrorNoMore;
     }
+    *ppOMXBuffer = pOMXBuffer;
     FunctionOut();
     return ret;
 }
@@ -942,12 +944,15 @@ static void ProcessThread(void *args)
 
     while (pSfCodaj12Implement->bThreadRunning)
     {
-        if (WaitForOutputBufferReady(pSfOMXComponent) != OMX_ErrorNone)
+        OMX_BUFFERHEADERTYPE *pBuffer;
+
+        if (WaitForOutputBufferReady(pSfOMXComponent,&pBuffer) != OMX_ErrorNone)
         {
             continue;
         }
 
-        ret = pSfCodaj12Implement->functions->JPU_DecStartOneFrame(handle, &decParam);
+        LOG(SF_LOG_INFO, "pBuffer->pOutputPortPrivate:%d\r\n", (int)(pBuffer->pOutputPortPrivate));
+        ret = pSfCodaj12Implement->functions->JPU_DecStartOneFrameBySerialNum(handle, &decParam,(int)(pBuffer->pOutputPortPrivate));
         if (ret != JPG_RET_SUCCESS && ret != JPG_RET_EOS)
         {
             if (ret == JPG_RET_BIT_EMPTY)
@@ -962,7 +967,7 @@ static void ProcessThread(void *args)
                 continue;
             }
 
-            LOG(SF_LOG_ERR, "JPU_DecStartOneFrame failed Error code is 0x%x \n", ret);
+            LOG(SF_LOG_ERR, "JPU_DecStartOneFrameBySerialNum failed Error code is 0x%x \n", ret);
             return;
         }
         if (ret == JPG_RET_EOS)
@@ -1004,30 +1009,6 @@ static void ProcessThread(void *args)
             return;
         }
 
-        if (outputInfo.decodingSuccess == 0)
-            LOG(SF_LOG_ERR, "JPU_DecGetOutputInfo decode fail framdIdx %d \n", frameIdx);
-
-        LOG(SF_LOG_INFO, "%02d %04d  %8d     %8x %8x %10d  %8x  %8x %10d\n",
-            instIdx, frameIdx, outputInfo.indexFrameDisplay, outputInfo.bytePosFrameStart, outputInfo.ecsPtr, outputInfo.consumedByte,
-            outputInfo.rdPtr, outputInfo.wrPtr, outputInfo.frameCycle);
-
-        if (outputInfo.indexFrameDisplay == -1)
-            break;
-
-        FRAME_BUF *pFrame = pSfCodaj12Implement->functions->GetFrameBuffer(instIdx, outputInfo.indexFrameDisplay);
-        OMX_U8 *virtAddr = (OMX_U8 *)pFrame->vbY.virt_addr;
-        //TODO: Get OMX buffer by virt addr
-        OMX_BUFFERHEADERTYPE *pBuffer = GetOMXBufferByAddr(pSfOMXComponent, virtAddr);
-        if (pBuffer == NULL)
-        {
-            LOG(SF_LOG_ERR, "Could not find omx buffer by address\r\n");
-            LOG(SF_LOG_DEBUG, "OMX_EventBufferFlag IN\r\n");
-            pSfOMXComponent->callbacks->EventHandler(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, OMX_EventBufferFlag,
-                                    1, 1, NULL);
-            LOG(SF_LOG_DEBUG, "OMX_EventBufferFlag OUT\r\n");
-            goto end;
-        }
-        ClearOMXBuffer(pSfOMXComponent, pBuffer);
         switch (pSfCodaj12Implement->frameFormat)
         {
         case FORMAT_420: