Browse Source

wave521: Add use-buffer
wave521: Adjust buffer management for v4l2src case

Signed-off-by: sw.multimedia <sw.multimedia@starfivetech.com>

sw.multimedia 2 years ago
parent
commit
85130c8365

+ 1 - 0
soft_3rdpart/omx-il/component/video/common/SF_OMX_video_common.c

@@ -478,6 +478,7 @@ static void sf_get_component_functions(SF_COMPONENT_FUNCTIONS *funcs, OMX_PTR *s
     funcs->AllocateFrameBuffer2 = dlsym(sohandle, "AllocateFrameBuffer2");
     funcs->AttachDMABuffer = dlsym(sohandle, "AttachDMABuffer");
     funcs->SetRenderTotalBufferNumber = dlsym(sohandle, "SetRenderTotalBufferNumber");
+    funcs->SetFeederTotalBufferNumber = dlsym(sohandle, "SetFeederTotalBufferNumber");
     funcs->WaitForExecoderReady = dlsym(sohandle, "WaitForExecoderReady");
     FunctionOut();
 }

+ 3 - 2
soft_3rdpart/omx-il/component/video/common/SF_OMX_video_common.h

@@ -94,8 +94,9 @@ typedef struct _SF_COMPONENT_FUNCTIONS
     void* (*AllocateFrameBuffer2)(ComponentImpl* com, Uint32 size);
     BOOL (*AttachDMABuffer)(ComponentImpl* com, Uint64 virtAddress, Uint32 size);
     void (*SetRenderTotalBufferNumber)(ComponentImpl* com, Uint32 number);
-    void (*WaitForExecoderReady)(ComponentImpl *com);
-}SF_COMPONENT_FUNCTIONS;
+    void (*SetFeederTotalBufferNumber)(ComponentImpl* com, Uint32 number);
+    void (*WaitForExecoderReady)(ComponentImpl *com)
+} SF_COMPONENT_FUNCTIONS;
 
 typedef struct _SF_WAVE5_IMPLEMEMT
 {

+ 25 - 11
soft_3rdpart/omx-il/component/video/enc/SF_OMX_Venc_encoder.c

@@ -82,6 +82,7 @@ static void OnEventArrived(Component com, unsigned long event, void *data, void
         pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
         LOG(SF_LOG_PERF, "OMX empty one buffer, address = %p, size = %d, nTimeStamp = %d, nFlags = %X\r\n",
         pOMXBuffer->pBuffer, pOMXBuffer->nFilledLen, pOMXBuffer->nTimeStamp, pOMXBuffer->nFlags);
+        ClearOMXBuffer(pSfOMXComponent, pOMXBuffer);
         break;
     case COMPONENT_EVENT_ENC_FILL_BUFFER_DONE:
     {
@@ -123,6 +124,7 @@ static void OnEventArrived(Component com, unsigned long event, void *data, void
         ComponentImpl *pRendererComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentRender;
         LOG(SF_LOG_PERF, "output queue count=%d/%d\r\n", pSfVideoImplement->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ),
                                                     pSfOMXComponent->portDefinition[1].nBufferCountActual);
+        ClearOMXBuffer(pSfOMXComponent, pOMXBuffer);
     }
     break;
     case COMPONENT_EVENT_ENC_REGISTER_FB:
@@ -183,6 +185,9 @@ static OMX_ERRORTYPE SF_OMX_EmptyThisBuffer(
     free(pPortContainerExternal);
     pFeederComponent->pause = OMX_FALSE;
 
+    ret = StoreOMXBuffer(pSfOMXComponent, pBuffer);
+    LOG(SF_LOG_PERF, "buffer count = %d\r\n", GetOMXBufferCount(pSfOMXComponent));
+
 EXIT:
     FunctionOut();
 
@@ -224,13 +229,15 @@ static OMX_ERRORTYPE SF_OMX_FillThisBuffer(
                                                         pSfOMXComponent->portDefinition[1].nBufferCountActual);
     free(pPortContainerExternal);
     pRendererComponent->pause = OMX_FALSE;
+    ret = StoreOMXBuffer(pSfOMXComponent, pBuffer);
+    LOG(SF_LOG_PERF, "buffer count = %d\r\n", GetOMXBufferCount(pSfOMXComponent));
 EXIT:
     FunctionOut();
 
     return ret;
 }
 
-static OMX_U64 nOutBufIndex = 0;
+static OMX_U64 nInputBufIndex = 0;
 
 static OMX_ERRORTYPE SF_OMX_UseBuffer(
     OMX_IN OMX_HANDLETYPE hComponent,
@@ -243,7 +250,8 @@ static OMX_ERRORTYPE SF_OMX_UseBuffer(
     OMX_ERRORTYPE ret = OMX_ErrorNone;
     OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
     SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
-
+    SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
+    ComponentImpl *pComponentFeeder = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
     FunctionIn();
 
     if (hComponent == NULL)
@@ -251,7 +259,11 @@ static OMX_ERRORTYPE SF_OMX_UseBuffer(
         ret = OMX_ErrorBadParameter;
         goto EXIT;
     }
-
+    if (pSfVideoImplement->functions->AttachDMABuffer(pComponentFeeder, (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)
     {
@@ -263,8 +275,12 @@ static OMX_ERRORTYPE SF_OMX_UseBuffer(
     temp_bufferHeader->pAppPrivate = pAppPrivate;
     temp_bufferHeader->pBuffer = pBuffer;
     *ppBufferHdr = temp_bufferHeader;
-
-    ret = StoreOMXBuffer(pSfOMXComponent, temp_bufferHeader);
+    if (nPortIndex == 0)
+    {
+        temp_bufferHeader->pInputPortPrivate = (OMX_PTR)nInputBufIndex;
+        nInputBufIndex ++;
+    }
+    LOG(SF_LOG_INFO, "pBuffer address = %p, nInputBufIndex = %d\r\n", temp_bufferHeader->pBuffer, (int)temp_bufferHeader->pInputPortPrivate);
 EXIT:
     FunctionOut();
 
@@ -320,8 +336,8 @@ static OMX_ERRORTYPE SF_OMX_AllocateBuffer(
         else
         {
             LOG(SF_LOG_PERF, "Use DMA buffer\r\n");
-            temp_bufferHeader->pInputPortPrivate = (OMX_PTR)nOutBufIndex;
-            nOutBufIndex ++;
+            temp_bufferHeader->pInputPortPrivate = (OMX_PTR)nInputBufIndex;
+            nInputBufIndex ++;
         }
     }
     else if (nPortIndex == 1)
@@ -339,8 +355,6 @@ static OMX_ERRORTYPE SF_OMX_AllocateBuffer(
     }
     *ppBuffer = temp_bufferHeader;
     LOG(SF_LOG_INFO, "pBuffer address = %p\r\n", temp_bufferHeader->pBuffer);
-    ret = StoreOMXBuffer(pSfOMXComponent, temp_bufferHeader);
-    LOG(SF_LOG_PERF, "alloc size = %d, buffer count = %d\r\n",nSizeBytes, GetOMXBufferCount(pSfOMXComponent));
 
     FunctionOut();
 
@@ -538,6 +552,7 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
             {
                 LOG(SF_LOG_INFO, "Set input buffer count = %d\r\n", nBufferCountActual);
                 ComponentImpl *pFeederComponent = (ComponentImpl *)pSfVideoImplement->hSFComponentFeeder;
+                pSfVideoImplement->functions->SetFeederTotalBufferNumber(pFeederComponent, nBufferCountActual);
                 pSfVideoImplement->functions->ComponentPortDestroy(&pFeederComponent->srcPort);
                 pSfVideoImplement->functions->ComponentPortCreate(&pFeederComponent->srcPort, pSfVideoImplement->hSFComponentFeeder,
                                                                 nBufferCountActual, sizeof(PortContainerExternal));
@@ -546,7 +561,7 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
             memcpy(&pSfOMXComponent->portDefinition[portIndex], pPortDefinition, pPortDefinition->nSize);
             pInputPort->format.video.nStride = width;
             pInputPort->format.video.nSliceHeight = height;
-            pInputPort->nBufferSize = width * height * 2;
+            pInputPort->nBufferSize = width * height * 3 / 2;
             LOG(SF_LOG_INFO, "Set eColorFormat to %d\r\n", eColorFormat);
             switch (eColorFormat)
             {
@@ -1113,7 +1128,6 @@ static OMX_ERRORTYPE SF_OMX_FreeBuffer(
     OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
     SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
     FunctionIn();
-    ClearOMXBuffer(pSfOMXComponent, pBufferHdr);
     LOG(SF_LOG_PERF, "buffer count = %d\r\n", GetOMXBufferCount(pSfOMXComponent));
     free(pBufferHdr);
 

+ 86 - 0
soft_3rdpart/wave521/code/sample_v2/component_encoder/component_enc_feeder.c

@@ -126,6 +126,92 @@ static CNMComponentParamRet SetParameterYuvFeeder(ComponentImpl* from, Component
     return (result == TRUE) ? CNM_COMPONENT_PARAM_SUCCESS : CNM_COMPONENT_PARAM_FAILURE;
 }
 
+BOOL GetAllocInfo(ComponentImpl* com, Uint32 size)
+{
+    YuvFeederContext*       ctx = (YuvFeederContext*)com->context;
+    EncOpenParam            encOpenParam = ctx->encOpenParam;
+    FrameBufferAllocInfo    fbAllocInfo;
+    Uint32                  fbWidth = 0;
+    Uint32                  fbHeight = 0;
+    Uint32                  fbStride = 0;
+    SRC_FB_TYPE             srcFbType = SRC_FB_TYPE_YUV;
+    TiledMapType            mapType;
+
+    osal_memset(&fbAllocInfo, 0x00, sizeof(FrameBufferAllocInfo));
+    //Buffers for source frames
+    if (PRODUCT_ID_W_SERIES(ctx->productID)) {
+        fbWidth = VPU_ALIGN8(encOpenParam.picWidth);
+        fbHeight = VPU_ALIGN8(encOpenParam.picHeight);
+        fbAllocInfo.endian  = encOpenParam.sourceEndian;
+    } else {
+        //CODA
+        fbWidth = VPU_ALIGN16(encOpenParam.picWidth);
+        fbHeight = VPU_ALIGN16(encOpenParam.picHeight);
+        fbAllocInfo.endian  = encOpenParam.frameEndian;
+    }
+
+
+    if (SRC_FB_TYPE_YUV == srcFbType) {
+        mapType = LINEAR_FRAME_MAP;
+    }
+    fbStride = CalcStride(fbWidth, fbHeight, (FrameBufferFormat)encOpenParam.srcFormat, encOpenParam.cbcrInterleave, mapType, FALSE);
+
+    fbAllocInfo.format  = (FrameBufferFormat)encOpenParam.srcFormat;
+    fbAllocInfo.cbcrInterleave = encOpenParam.cbcrInterleave;
+    fbAllocInfo.mapType = mapType;
+    fbAllocInfo.stride  = fbStride;
+    fbAllocInfo.height  = fbHeight;
+    fbAllocInfo.size    = size;
+    fbAllocInfo.type    = FB_TYPE_PPU;
+    fbAllocInfo.num     = ctx->fbCount.srcFbNum;
+    fbAllocInfo.nv21    = encOpenParam.nv21;
+
+    if (PRODUCT_ID_NOT_W_SERIES(ctx->productID)) {
+        fbAllocInfo.lumaBitDepth = 8;
+        fbAllocInfo.chromaBitDepth = 8;
+    }
+    ctx->srcFbAllocInfo = fbAllocInfo;
+
+    return TRUE;
+}
+
+void SetFeederTotalBufferNumber(ComponentImpl* com, Uint32 number)
+{
+    YuvFeederContext*     ctx            = (YuvFeederContext*)com->context;
+    ctx->totalBufferNumber = number;
+}
+
+BOOL AttachDMABuffer(ComponentImpl* com, void *pBuffer, Uint32 size)
+{
+    YuvFeederContext*       ctx = (YuvFeederContext*)com->context;
+    EncOpenParam            encOpenParam = ctx->encOpenParam;
+
+    int i = 0;
+    GetAllocInfo(com, size);
+
+    for (i = 0;i < ENC_SRC_BUF_NUM; i ++){
+        if (ctx->pFbSrcMem[i].phys_addr == 0)
+        {
+            VLOG(INFO, "Found empty frame at index %d\r\n", i);
+            break;
+        }
+    }
+    if (i == MAX_REG_FRAME)
+    {
+        VLOG(ERR, "Could not found empty frame at index\r\n");
+        return FALSE;
+    }
+
+    if (FALSE == AttachFBMemory(encOpenParam.coreIdx, &ctx->pFbSrcMem[i], &ctx->pFbSrc[i], pBuffer, size)) {
+        VLOG(ERR, "failed to attach source buffers\n");
+        return FALSE;
+    }
+    ctx->pFbSrcMem[i].virt_addr = (unsigned long)pBuffer;
+    ctx->currentBufferNumber ++;
+
+    return TRUE;
+}
+
 void* AllocateFrameBuffer2(ComponentImpl* com, Uint32 size)
 {
     YuvFeederContext*       ctx = (YuvFeederContext*)com->context;

+ 19 - 0
soft_3rdpart/wave521/code/sample_v2/helper/main_helper.c

@@ -1343,6 +1343,25 @@ BOOL AllocateDecFrameBuffer(
     return TRUE;
 }
 
+BOOL AttachFBMemory(Uint32 coreIdx, vpu_buffer_t *pFbMem, FrameBuffer* pFb, void *pBuffer, Uint32 size)
+{
+    pFbMem->size = size;
+    pFbMem->virt_addr = (unsigned long)pBuffer;
+    
+
+    vdi_virt_to_phys(coreIdx, pFbMem);
+    vdi_attach_dma_memory(coreIdx, pFbMem);
+    VLOG(INFO, "base addr = %lx virt addr= %lx phys addr = %x\r\n", pFbMem->base, pFbMem->virt_addr, pFbMem->phys_addr);
+    
+    pFb->bufY = pFbMem->phys_addr;
+    pFb->bufCb = (PhysicalAddress)-1;
+    pFb->bufCr = (PhysicalAddress)-1;
+    pFb->size = size;
+    pFb->updateFbInfo = TRUE;
+    
+    return TRUE;
+}
+
 BOOL AllocFBMemory(Uint32 coreIdx, vpu_buffer_t *pFbMem, FrameBuffer* pFb,Uint32 memSize, Uint32 memNum, Int32 memTypes, Int32 instIndex)
 {
     Uint32 i =0;

+ 56 - 0
soft_3rdpart/wave521/code/vdi/linux/driver/venc.c

@@ -647,6 +647,62 @@ static long vpu_ioctl(struct file *filp, u_int cmd, u_long arg)
 	struct vpu_drv_context_t *dev = (struct vpu_drv_context_t *)filp->private_data;
 
 	switch (cmd) {
+	case VDI_IOCTL_GET_PHYSICAL_MEMORY:
+        {
+            vpudrv_buffer_pool_t *vbp;
+            if ((ret = down_interruptible(&s_vpu_sem)) == 0) {
+                vbp = kzalloc(sizeof(*vbp), GFP_KERNEL);
+                if (!vbp) {
+                    up(&s_vpu_sem);
+                    return -ENOMEM;
+                }
+                ret = copy_from_user(&(vbp->vb), (vpudrv_buffer_t *)arg, sizeof(vpudrv_buffer_t));
+                if (ret) {
+                    kfree(vbp);
+                    up(&s_vpu_sem);
+                    return -EFAULT;
+                }
+
+                void *user_address = (void *)vbp->vb.virt_addr;
+                struct task_struct *my_struct = get_current();
+                struct mm_struct *mm = my_struct->mm;
+                unsigned long address = (unsigned long)user_address;
+                pgd_t *pgd = pgd_offset(mm, address);
+
+                if (!pgd_none(*pgd) && !pgd_bad(*pgd)) {
+                    p4d_t *p4d = p4d_offset(pgd, address);
+                    pud_t *pud = pud_offset(p4d, address);
+                    if (!pud_none(*pud) && !pud_bad(*pud)) {
+                        pmd_t *pmd = pmd_offset(pud, address);
+                        if (!pmd_none(*pmd) && !pmd_bad(*pmd)) {
+                            pte_t *pte = pte_offset_map(pmd, address);
+                            if (!pte_none(*pte)) {
+                                struct page *pg = pte_page(*pte);
+                                unsigned long phys = page_to_phys(pg);
+                                unsigned long virt = (unsigned long)phys_to_virt(phys);
+                                printk("phy address = %lx, virt = %lx\r\n", phys, virt);
+                                vbp->vb.phys_addr = phys;
+                                vbp->vb.base = virt;
+                            }
+                            pte_unmap(pte);
+                        }
+                    }
+                }
+                ret = copy_to_user((void __user *)arg, &(vbp->vb), sizeof(vpudrv_buffer_t));
+                if (ret) {
+                    kfree(vbp);
+                    ret = -EFAULT;
+                    up(&s_vpu_sem);
+                    break;
+                }
+                vbp->filp = filp;
+                spin_lock(&s_vpu_lock);
+                list_add(&vbp->list, &s_vbp_head);
+                spin_unlock(&s_vpu_lock);
+                up(&s_vpu_sem);
+            }
+        }
+        break;
 	case VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY:
 		{
 			vpudrv_buffer_pool_t *vbp;

+ 1 - 0
soft_3rdpart/wave521/code/vdi/linux/driver/vpu.h

@@ -22,6 +22,7 @@
 #define VDI_IOCTL_GET_REGISTER_INFO			_IO(VDI_IOCTL_MAGIC, 12)
 #define VDI_IOCTL_GET_FREE_MEM_SIZE			_IO(VDI_IOCTL_MAGIC, 13)
 #define VDI_IOCTL_FLUSH_DCACHE				_IO(VDI_IOCTL_MAGIC, 14)
+#define VDI_IOCTL_GET_PHYSICAL_MEMORY		_IO(VDI_IOCTL_MAGIC, 15)
 
 #define DRAM_MEM2SYS(addr) ((addr) > 0x80000000 && (addr) < 0x87FFFFFFF ? ((addr)+0xF80000000):(addr))
 #define ioremap_nocache ioremap

+ 29 - 0
soft_3rdpart/wave521/code/vdi/linux/vdi.c

@@ -943,6 +943,35 @@ int vdi_read_memory(unsigned long core_idx, PhysicalAddress addr, unsigned char
     return len;
 }
 
+int vdi_virt_to_phys(unsigned long core_idx, vpu_buffer_t *vb)
+{
+    vdi_info_t *vdi;
+    vpudrv_buffer_t vdb;
+
+#ifdef SUPPORT_MULTI_CORE_IN_ONE_DRIVER
+    core_idx = 0;
+#endif
+    if (core_idx >= MAX_NUM_VPU_CORE)
+        return -1;
+
+    vdi = &s_vdi_info[core_idx];
+
+    if(!vdi || vdi->vpu_fd==-1 || vdi->vpu_fd == 0x00)
+        return -1;
+
+    osal_memset(&vdb, 0x00, sizeof(vpudrv_buffer_t));
+    vdb.virt_addr = vb->virt_addr;
+    if (ioctl(vdi->vpu_fd, VDI_IOCTL_GET_PHYSICAL_MEMORY, &vdb) < 0)
+    {
+        VLOG(ERR, "[VDI] fail to GET_PHYSICAL_MEMORY\n");
+        return -1;
+    }
+    vb->phys_addr = (unsigned long)vdb.phys_addr;
+    vb->base = (unsigned long)vdb.base;
+    VLOG(INFO, "get phy = %#x vb->phy = %#x, base=%lx\n", vdb.phys_addr, vb->phys_addr, vb->base);
+    return 0;
+}
+
 int vdi_allocate_dma_memory(unsigned long core_idx, vpu_buffer_t *vb, int memTypes, int instIndex)
 {
     vdi_info_t *vdi;