Kaynağa Gözat

codaj12: implement codaj12 use buffer
codaj12: fix buffer count error && fix buffer crcb error
sf-omx-il: fix video block && fix buffer null except
sf-omx-il: fix gstreamer flush buffer fail on end
sf-omx-il: fix port config error
sf-omx-il: Add AdjustFrame function to adjust outsize != destsize
sf-omx-il: fix color format error

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

sw.multimedia 2 yıl önce
ebeveyn
işleme
c0c8c1b0ef

+ 64 - 0
soft_3rdpart/codaj12/jdi/linux/driver/jpu.c

@@ -382,6 +382,70 @@ static long jpu_ioctl(struct file *filp, u_int cmd, u_long arg)
             DPRINTK("[JPUDRV][-]JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n");
         }
         break;
+     case JDI_IOCTL_GET_PHYSICAL_MEMORY:
+        {
+            jpudrv_buffer_pool_t *jbp;
+
+            DPRINTK("[JPUDRV][+]JDI_IOCTL_GET_PHYSICAL_MEMORY\n");
+            if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
+                jbp = kzalloc(sizeof(jpudrv_buffer_pool_t), GFP_KERNEL);
+                if (!jbp) {
+                    up(&s_jpu_sem);
+                    return -ENOMEM;
+                }
+
+                ret = copy_from_user(&(jbp->jb), (jpudrv_buffer_t *)arg, sizeof(jpudrv_buffer_t));
+                if (ret)
+                {
+                    kfree(jbp);
+                    up(&s_jpu_sem);
+                    return -EFAULT;
+                }
+
+                void *user_address = (void *)jbp->jb.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);
+                                jbp->jb.phys_addr = phys;
+                                jbp->jb.base = virt;
+                            }
+                            pte_unmap(pte);
+                        }
+                    }
+                }
+                ret = copy_to_user((void __user *)arg, &(jbp->jb), sizeof(jpudrv_buffer_t));
+                if (ret)
+                {
+                    kfree(jbp);
+                    ret = -EFAULT;
+                    up(&s_jpu_sem);
+                    break;
+                }
+
+                jbp->filp = filp;
+                spin_lock(&s_jpu_lock);
+                list_add(&jbp->list, &s_jbp_head);
+                spin_unlock(&s_jpu_lock);
+
+                up(&s_jpu_sem);
+            }
+            DPRINTK("[JPUDRV][-]JDI_IOCTL_GET_PHYSICAL_MEMORY\n");
+        }
+        break;
     case JDI_IOCTL_FREE_PHYSICALMEMORY:
         {
             jpudrv_buffer_pool_t *jbp, *n;

+ 1 - 0
soft_3rdpart/codaj12/jdi/linux/driver/jpu.h

@@ -20,6 +20,7 @@
 #define JDI_IOCTL_CLOSE_INSTANCE                    _IO(JDI_IOCTL_MAGIC, 9)
 #define JDI_IOCTL_GET_INSTANCE_NUM                  _IO(JDI_IOCTL_MAGIC, 10)
 #define JDI_IOCTL_FLUSH_DCACHE                 		_IO(JDI_IOCTL_MAGIC, 11)
+#define JDI_IOCTL_GET_PHYSICAL_MEMORY               _IO(JDI_IOCTL_MAGIC, 12)
 
 #define MEM2SYS(addr) ((addr) > 0x80000000 && (addr) < 0x87FFFFFFF ? ((addr)+0xF80000000):(addr))
 

+ 40 - 0
soft_3rdpart/codaj12/jdi/linux/jdi.c

@@ -530,6 +530,46 @@ int jdi_read_memory(unsigned long addr, unsigned char *data, int len, int endian
     return len;
 }
 
+int jdi_attach_dma_memory(jpu_buffer_t *vb)
+{
+    jdi_info_t *jdi;
+    int i;
+    jpudrv_buffer_t jdb;
+
+    jdi = &s_jdi_info;
+
+    if(!jdi || jdi->jpu_fd==-1 || jdi->jpu_fd == 0x00)
+        return -1;
+
+    memset(&jdb, 0x00, sizeof(jpudrv_buffer_t));
+
+    jdb.virt_addr = vb->virt_addr;
+    if (ioctl(jdi->jpu_fd, JDI_IOCTL_GET_PHYSICAL_MEMORY, &jdb) < 0)
+    {
+        JLOG(ERR, "[JDI] fail to jdi_allocate_dma_memory size=%d\n", vb->size);
+        return -1;
+    }
+
+    vb->phys_addr = (unsigned long)jdb.phys_addr;
+    vb->base = (unsigned long)jdb.base;
+
+    jdi_lock();
+    for (i=0; i<MAX_JPU_BUFFER_POOL; i++)
+    {
+        if (jdi->jpu_buffer_pool[i].inuse == 0)
+        {
+            jdi->jpu_buffer_pool[i].jdb = jdb;
+            jdi->jpu_buffer_pool_count++;
+            jdi->jpu_buffer_pool[i].inuse = 1;
+            break;
+        }
+    }
+    jdi_unlock();
+    JLOG(INFO, "[JDI] jdi_attach_dma_memory, physaddr=%p, virtaddr=%p~%p, size=%d\n",
+         vb->phys_addr, vb->virt_addr, vb->virt_addr + vb->size, vb->size);
+    return 0;
+}
+
 int jdi_allocate_dma_memory(jpu_buffer_t *vb)
 {
     jdi_info_t *jdi;

+ 3 - 3
soft_3rdpart/codaj12/jpuapi/jpuapi.c

@@ -953,9 +953,9 @@ JpgRet JPU_DecStartOneFrame(JpgDecHandle handle, JpgDecParam *param)
     JpuWriteInstReg(instRegIndex, MJPEG_ROT_INFO_REG, (ppuEnable<<4) | (pDecInfo->mirrorIndex<<2) | pDecInfo->rotationIndex);
 
     val = (pDecInfo->frameIdx % pDecInfo->numFrameBuffers);
-    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);
+    // 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);

+ 79 - 0
soft_3rdpart/codaj12/sample/helper/jpuhelper.c

@@ -1134,6 +1134,85 @@ BOOL UpdateFrameBuffers(Uint32 instIdx, Uint32 num, FRAME_BUF *frameBuf)
     return TRUE;
 }
 
+BOOL AttachOneFrameBuffer(Uint32 instIdx, FrameFormat subsample, CbCrInterLeave cbcrIntlv, PackedFormat packed,
+                         Uint32 rotation, BOOL scalerOn, Uint32 width, Uint32 height, Uint32 bitDepth,
+                         void *virtAddress, Uint32 size, Uint32 *bufferIndex)
+{
+    fb_context *fb;
+    Uint32  fbLumaStride, fbLumaHeight, fbChromaStride, fbChromaHeight;
+    Uint32  fbLumaSize, fbChromaSize;
+    Uint32  fbSize;
+    Uint32  bytePerPixel = (bitDepth + 7)/8;
+    Uint32  i;
+
+
+    JLOG(INFO, "%s function in width, height = [%d, %d]\r\n", __FUNCTION__, width, height);
+    if (rotation == 90 || rotation == 270) {
+        if (subsample == FORMAT_422) subsample = FORMAT_440;
+        else if (subsample == FORMAT_440) subsample = FORMAT_422;
+    }
+
+    GetFrameBufStride(subsample, cbcrIntlv, packed, scalerOn, width, height, bytePerPixel, &fbLumaStride, &fbLumaHeight, &fbChromaStride, &fbChromaHeight);
+    fbLumaSize   = fbLumaStride * fbLumaHeight;
+    fbChromaSize = fbChromaStride * fbChromaHeight;
+
+    if (cbcrIntlv == CBCR_SEPARATED) {
+        /* fbChromaSize MUST be zero when format is packed mode */
+        fbSize = fbLumaSize + 2*fbChromaSize;
+
+    }
+    else {
+        /* Semi-planar */
+        fbSize = fbLumaSize + fbChromaSize;
+    }
+
+    fb = &s_fb[instIdx];
+    fb->vb_base.virt_addr = (unsigned long)virtAddress;
+    fb->vb_base.size = fbSize;
+    if (jdi_attach_dma_memory(&fb->vb_base) < 0) {
+        JLOG(ERR, "Fail to attach frame buffer\n");
+        return FALSE;
+    }
+    fb->last_addr = fb->vb_base.phys_addr;
+
+    i = fb->last_num;
+    JLOG(INFO, "%s: store on index %d\r\n", __FUNCTION__, i);
+    fb->frameBuf[i].Format = subsample;
+    fb->frameBuf[i].Index  = i;
+    fb->frameBuf[i].vbY.phys_addr = fb->vb_base.phys_addr;
+    fb->frameBuf[i].vbY.size = fbLumaSize;
+    // Store virt addr
+    fb->frameBuf[i].vbY.virt_addr = fb->vb_base.virt_addr;
+    
+    fb->last_addr += fb->frameBuf[i].vbY.size;
+    fb->last_addr = JPU_CEIL(8, fb->last_addr);
+    JLOG(INFO, "%s: fbChromaSize = %d, fbLumaSize = %d\r\n", __FUNCTION__, fbChromaSize, fbLumaSize);
+    if (fbChromaSize) {
+        fb->frameBuf[i].vbCb.phys_addr = fb->last_addr;
+        fb->frameBuf[i].vbCb.size = fbChromaSize;
+
+        fb->last_addr += fb->frameBuf[i].vbCb.size;
+        fb->last_addr = JPU_CEIL(8, fb->last_addr);
+
+        fb->frameBuf[i].vbCr.phys_addr = (cbcrIntlv == CBCR_SEPARATED) ? fb->last_addr : 0;
+        fb->frameBuf[i].vbCr.size      = (cbcrIntlv == CBCR_SEPARATED) ? fbChromaSize  : 0;
+
+        fb->last_addr += fb->frameBuf[i].vbCr.size;
+        fb->last_addr = JPU_CEIL(8, fb->last_addr);
+    }
+    JLOG(INFO, "%s vbCb = %x size = %d, vbCr = %x size = %d\r\n", __FUNCTION__, fb->frameBuf[i].vbCb.phys_addr,
+        fb->frameBuf[i].vbCb.size, fb->frameBuf[i].vbCr.phys_addr, fb->frameBuf[i].vbCr.size);
+    fb->frameBuf[i].strideY = fbLumaStride;
+    fb->frameBuf[i].strideC = fbChromaStride;
+
+    *bufferIndex = fb->last_num;
+    fb->last_num += 1;
+
+    JLOG(INFO, "%s function OUT, number = %d\r\n", __FUNCTION__, fb->last_num);
+    return TRUE;
+
+}
+
 void *AllocateOneFrameBuffer(Uint32 instIdx, FrameFormat subsample, CbCrInterLeave cbcrIntlv, PackedFormat packed,
                          Uint32 rotation, BOOL scalerOn, Uint32 width, Uint32 height, Uint32 bitDepth, Uint32 *bufferIndex)
 {

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

@@ -119,6 +119,12 @@ OMX_ERRORTYPE InitMjpegStructorCommon(SF_OMX_COMPONENT *pSfOMXComponent)
         LOG(SF_LOG_ERR, "get ipc_id error");
         return;
     }
+    pSfCodaj12Implement->sBufferDoneQueue = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
+    if (pSfCodaj12Implement->sBufferDoneQueue < 0)
+    {
+        LOG(SF_LOG_ERR, "get ipc_id error");
+        return;
+    }
 
     for (int i = 0; i < 2; i++)
     {
@@ -133,42 +139,62 @@ OMX_ERRORTYPE InitMjpegStructorCommon(SF_OMX_COMPONENT *pSfOMXComponent)
         // imagePortFormat->eColorFormat = OMX_COLOR_FormatUnused;  //TODO
 
         INIT_SET_SIZE_VERSION(pPortDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
-        // INIT_SET_SIZE_VERSION(pAVCComponent, OMX_VIDEO_PARAM_AVCTYPE);
-        // OMX_VIDEO_PARAM_AVCTYPE *pAVCComponent = &pSfOMXComponent->AVCComponent[i];
+
         pPortDefinition->nPortIndex = i;
-        // pPortDefinition->nBufferCountActual = VPU_OUTPUT_BUF_NUMBER;
         pPortDefinition->nBufferCountActual = (i == 0 ? CODAJ12_INPUT_BUF_NUMBER : CODAJ12_OUTPUT_BUF_NUMBER);
         pPortDefinition->nBufferCountMin = (i == 0 ? CODAJ12_INPUT_BUF_NUMBER : CODAJ12_OUTPUT_BUF_NUMBER);
         pPortDefinition->nBufferSize = (i == 0 ? DEFAULT_MJPEG_INPUT_BUFFER_SIZE : DEFAULT_MJPEG_OUTPUT_BUFFER_SIZE);
         pPortDefinition->eDomain = OMX_PortDomainVideo;
-        // TODO happer
-        // pPortDefinition->format.image.pNativeWindow = 0x0;
-        pPortDefinition->format.image.nFrameWidth = DEFAULT_FRAME_WIDTH;
-        pPortDefinition->format.image.nFrameHeight = DEFAULT_FRAME_HEIGHT;
-        pPortDefinition->format.image.nStride = DEFAULT_FRAME_WIDTH;
-        pPortDefinition->format.image.nSliceHeight = DEFAULT_FRAME_HEIGHT;
-        pPortDefinition->format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
-        pPortDefinition->format.image.cMIMEType = malloc(OMX_MAX_STRINGNAME_SIZE);
-
-        if (pPortDefinition->format.image.cMIMEType == NULL)
+
+        // pPortDefinition->format.image.nFrameWidth = DEFAULT_FRAME_WIDTH;
+        // pPortDefinition->format.image.nFrameHeight = DEFAULT_FRAME_HEIGHT;
+        // pPortDefinition->format.image.nStride = DEFAULT_FRAME_WIDTH;
+        // pPortDefinition->format.image.nSliceHeight = DEFAULT_FRAME_HEIGHT;
+        // pPortDefinition->format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
+        // pPortDefinition->format.image.cMIMEType = malloc(OMX_MAX_STRINGNAME_SIZE);
+
+        // if (pPortDefinition->format.image.cMIMEType == NULL)
+        // {
+        //     ret = OMX_ErrorInsufficientResources;
+        //     free(pPortDefinition->format.image.cMIMEType);
+        //     pPortDefinition->format.image.cMIMEType = NULL;
+        //     LOG(SF_LOG_ERR, "malloc fail\r\n");
+        //     goto ERROR;
+        // }
+        // memset(pPortDefinition->format.image.cMIMEType, 0, OMX_MAX_STRINGNAME_SIZE);
+        // pPortDefinition->format.image.pNativeRender = 0;
+        // pPortDefinition->format.image.bFlagErrorConcealment = OMX_FALSE;
+        // pPortDefinition->format.image.eColorFormat = OMX_COLOR_FormatUnused;
+
+        pPortDefinition->format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
+        pPortDefinition->format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
+        pPortDefinition->format.video.nStride = DEFAULT_FRAME_WIDTH;
+        pPortDefinition->format.video.nSliceHeight = DEFAULT_FRAME_HEIGHT;
+        pPortDefinition->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+        pPortDefinition->format.video.cMIMEType = malloc(OMX_MAX_STRINGNAME_SIZE);
+        pPortDefinition->format.video.xFramerate = 30;
+        if (pPortDefinition->format.video.cMIMEType == NULL)
         {
             ret = OMX_ErrorInsufficientResources;
-            free(pPortDefinition->format.image.cMIMEType);
-            pPortDefinition->format.image.cMIMEType = NULL;
+            free(pPortDefinition->format.video.cMIMEType);
+            pPortDefinition->format.video.cMIMEType = NULL;
             LOG(SF_LOG_ERR, "malloc fail\r\n");
             goto ERROR;
         }
-        memset(pPortDefinition->format.image.cMIMEType, 0, OMX_MAX_STRINGNAME_SIZE);
-        pPortDefinition->format.image.pNativeRender = 0;
-        pPortDefinition->format.image.bFlagErrorConcealment = OMX_FALSE;
-        pPortDefinition->format.image.eColorFormat = OMX_COLOR_FormatUnused;
+        memset(pPortDefinition->format.video.cMIMEType, 0, OMX_MAX_STRINGNAME_SIZE);
+        pPortDefinition->format.video.pNativeRender = 0;
+        pPortDefinition->format.video.bFlagErrorConcealment = OMX_FALSE;
+        pPortDefinition->format.video.eColorFormat = OMX_COLOR_FormatUnused;
+
         pPortDefinition->bEnabled = OMX_TRUE;
 
         pPortDefinition->eDir = (i == 0 ? OMX_DirInput : OMX_DirOutput);
     }
 
-    strcpy(pSfOMXComponent->portDefinition[1].format.image.cMIMEType, "JPEG");
-    pSfOMXComponent->portDefinition[1].format.image.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    // strcpy(pSfOMXComponent->portDefinition[1].format.image.cMIMEType, "JPEG");
+    // pSfOMXComponent->portDefinition[1].format.image.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+    strcpy(pSfOMXComponent->portDefinition[1].format.video.cMIMEType, "JPEG");
+    pSfOMXComponent->portDefinition[1].format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
 
     memset(pSfOMXComponent->pBufferArray, 0, sizeof(pSfOMXComponent->pBufferArray));
     pSfOMXComponent->memory_optimization = OMX_TRUE;
@@ -217,9 +243,138 @@ static void sf_get_component_functions(SF_CODAJ12_FUNCTIONS *funcs, OMX_PTR *soh
     funcs->GetFrameBufferCount = dlsym(sohandle, "GetFrameBufferCount");
     funcs->UpdateFrameBuffers = dlsym(sohandle, "UpdateFrameBuffers");
     funcs->SetMaxLogLevel = dlsym(sohandle, "SetMaxLogLevel");
+    funcs->AttachOneFrameBuffer = dlsym(sohandle, "AttachOneFrameBuffer");
     FunctionOut();
 }
 
+OMX_BOOL AttachOutputBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U8* pBuffer, OMX_U32 nSizeBytes)
+{
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    Int32 instIdx = pSfCodaj12Implement->instIdx;
+    JpgDecOpenParam *decOP = &pSfCodaj12Implement->decOP;
+    DecConfigParam *decConfig = pSfCodaj12Implement->config;
+    JpgDecInitialInfo *initialInfo = &pSfCodaj12Implement->initialInfo;
+    FrameBuffer *pFrameBuf = &pSfCodaj12Implement->frameBuf;
+    JpgDecHandle handle = pSfCodaj12Implement->handle;
+
+    Uint32 framebufWidth = 0, framebufHeight = 0, framebufStride = 0;
+    Uint32 decodingWidth, decodingHeight;
+    BOOL scalerOn = FALSE;
+    Uint32 bitDepth = 0;
+    FrameFormat subsample;
+    Uint32 temp;
+    OMX_U8 *virtAddr;
+    Uint32 bufferIndex;
+    JpgRet jpgret;
+
+    FunctionIn();
+    if (initialInfo->sourceFormat == FORMAT_420 || initialInfo->sourceFormat == FORMAT_422)
+        framebufWidth = JPU_CEIL(16, initialInfo->picWidth);
+    else
+        framebufWidth = JPU_CEIL(8, initialInfo->picWidth);
+
+    if (initialInfo->sourceFormat == FORMAT_420 || initialInfo->sourceFormat == FORMAT_440)
+        framebufHeight = JPU_CEIL(16, initialInfo->picHeight);
+    else
+        framebufHeight = JPU_CEIL(8, initialInfo->picHeight);
+
+    if (framebufWidth == 0 || framebufHeight == 0)
+    {
+        LOG(SF_LOG_WARN, "width or height == 0, use port parameters\r\n");
+        for (int i = 0; i < OMX_PORT_MAX; i ++)
+        {
+            OMX_PARAM_PORTDEFINITIONTYPE *pPort = &pSfOMXComponent->portDefinition[i];
+            framebufWidth = pPort->format.video.nFrameWidth;
+            framebufHeight = pPort->format.video.nFrameHeight;
+            if (framebufWidth > 0 && framebufHeight > 0)
+            {
+                LOG(SF_LOG_INFO, "Use port: %d\r\n", i);
+                break;
+            }
+        }
+        if (framebufWidth == 0 || framebufHeight == 0)
+        {
+            LOG(SF_LOG_ERR, "Can not get frame size\r\n");
+            return OMX_FALSE;
+        }
+    }
+    LOG(SF_LOG_DEBUG, "framebufWidth: %d, framebufHeight: %d\r\n", framebufWidth, framebufHeight);
+
+    decodingWidth = framebufWidth >> decConfig->iHorScaleMode;
+    decodingHeight = framebufHeight >> decConfig->iVerScaleMode;
+    if (decOP->packedFormat != PACKED_FORMAT_NONE && decOP->packedFormat != PACKED_FORMAT_444)
+    {
+        // When packed format, scale-down resolution should be multiple of 2.
+        decodingWidth = JPU_CEIL(2, decodingWidth);
+    }
+
+    subsample = pSfCodaj12Implement->frameFormat;
+    temp = decodingWidth;
+    decodingWidth = (decConfig->rotation == 90 || decConfig->rotation == 270) ? decodingHeight : decodingWidth;
+    decodingHeight = (decConfig->rotation == 90 || decConfig->rotation == 270) ? temp : decodingHeight;
+    if (decConfig->roiEnable == TRUE)
+    {
+        decodingWidth = framebufWidth = initialInfo->roiFrameWidth;
+        decodingHeight = framebufHeight = initialInfo->roiFrameHeight;
+    }
+
+    LOG(SF_LOG_DEBUG, "decodingWidth: %d, decodingHeight: %d\n", decodingWidth, decodingHeight);
+
+    if (decOP->rotation != 0 || decOP->mirror != MIRDIR_NONE)
+    {
+        if (decOP->outputFormat != FORMAT_MAX && decOP->outputFormat != initialInfo->sourceFormat)
+        {
+            LOG(SF_LOG_ERR, "The rotator cannot work with the format converter together.\n");
+            return OMX_FALSE;
+        }
+    }
+
+    LOG(SF_LOG_INFO, "<INSTANCE %d>\n", instIdx);
+    LOG(SF_LOG_INFO, "SOURCE PICTURE SIZE : W(%d) H(%d)\n", initialInfo->picWidth, initialInfo->picHeight);
+    LOG(SF_LOG_INFO, "SUBSAMPLE           : %d\n", subsample);
+
+    bitDepth = initialInfo->bitDepth;
+    scalerOn = (BOOL)(decConfig->iHorScaleMode || decConfig->iVerScaleMode);
+    // may be handle == NULL on ffmpeg case
+    if (bitDepth == 0)
+    {
+        bitDepth = 8;
+    }
+    LOG(SF_LOG_DEBUG, "AllocateOneFrameBuffer\r\n");
+    LOG_APPEND(SF_LOG_DEBUG, "instIdx = %d subsample = %d chromaInterleave = %d packedFormat = %d rotation = %d\r\n",
+                instIdx, subsample, decOP->chromaInterleave, decOP->packedFormat, decConfig->rotation);
+    LOG_APPEND(SF_LOG_DEBUG, "scalerOn = %d decodingWidth = %d decodingHeight = %d bitDepth = %d\r\n",
+                scalerOn, decodingWidth, decodingHeight, bitDepth);
+    if (pSfCodaj12Implement->functions->AttachOneFrameBuffer(instIdx, subsample, decOP->chromaInterleave,
+        decOP->packedFormat, decConfig->rotation,
+        scalerOn, decodingWidth, decodingHeight, bitDepth, pBuffer, nSizeBytes, &bufferIndex) == OMX_FALSE)
+    {
+        LOG(SF_LOG_ERR, "Fail to attach FrameBuffer\r\n");
+        return OMX_FALSE;
+    }
+
+     LOG(SF_LOG_INFO, "Allocate frame buffer %p, index = %d\r\n", virtAddr, bufferIndex);
+
+    //Register frame buffer
+    FRAME_BUF *pFrame = pSfCodaj12Implement->functions->GetFrameBuffer(instIdx, bufferIndex);
+    memcpy(&pSfCodaj12Implement->frame[bufferIndex], pFrame, sizeof(FRAME_BUF));
+    pFrameBuf[bufferIndex].bufY = pFrame->vbY.phys_addr;
+    pFrameBuf[bufferIndex].bufCb = pFrame->vbCb.phys_addr;
+    if (decOP->chromaInterleave == CBCR_SEPARATED)
+        pFrameBuf[bufferIndex].bufCr = pFrame->vbCr.phys_addr;
+    pFrameBuf[bufferIndex].stride = pFrame->strideY;
+    pFrameBuf[bufferIndex].strideC = pFrame->strideC;
+    pFrameBuf[bufferIndex].endian = decOP->frameEndian;
+    pFrameBuf[bufferIndex].format = (FrameFormat)pFrame->Format;
+    framebufStride = pFrameBuf[bufferIndex].stride;
+
+    // may be handle == NULL on ffmpeg case
+    jpgret = pSfCodaj12Implement->functions->JPU_DecRegisterFrameBuffer2(handle, &pFrameBuf[bufferIndex], framebufStride);
+    LOG(SF_LOG_DEBUG, "JPU_DecRegisterFrameBuffer2 ret = %d\r\n", jpgret);
+    FunctionOut();
+    return OMX_TRUE;
+
+}
 OMX_U8 *AllocateOutputBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nSizeBytes)
 {
     SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
@@ -422,13 +577,19 @@ void CodaJ12FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPortNumber)
     case OMX_INPUT_PORT_INDEX:
         while (OMX_TRUE)
         {
-            if (msgrcv(pSfCodaj12Implement->sInputMessageQueue, (void *)&data, BUFSIZ, 0, IPC_NOWAIT) == -1)
+            if (msgrcv(pSfCodaj12Implement->sInputMessageQueue, (void *)&data, BUFSIZ, 0, IPC_NOWAIT) < 0)
             {
-                break;
+                if (msgrcv(pSfCodaj12Implement->sBufferDoneQueue,  (void *)&data, BUFSIZ, 0, IPC_NOWAIT) < 0)
+                {
+                    LOG(SF_LOG_INFO, "No more buffer in input port\r\n");
+                    break;
+                }
             }
-            else
+
+            pOMXBuffer = data.pBuffer;
+            LOG(SF_LOG_INFO, "Flush Buffer %p\r\n", pOMXBuffer);
+            if (pOMXBuffer != NULL)
             {
-                pOMXBuffer = data.pBuffer;
                 pOMXBuffer->nFilledLen = 0;
                 pOMXBuffer->nFlags = OMX_BUFFERFLAG_EOS;
                 pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
@@ -438,13 +599,16 @@ void CodaJ12FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPortNumber)
     case OMX_OUTPUT_PORT_INDEX:
         while (OMX_TRUE)
         {
-            if (msgrcv(pSfCodaj12Implement->sOutputMessageQueue, (void *)&data, BUFSIZ, 0, IPC_NOWAIT) == -1)
+            if (msgrcv(pSfCodaj12Implement->sOutputMessageQueue, (void *)&data, BUFSIZ, 0, IPC_NOWAIT) < 0)
             {
+                LOG(SF_LOG_INFO, "No more buffer in output port\r\n");
                 break;
             }
-            else
+
+            pOMXBuffer = data.pBuffer;
+            LOG(SF_LOG_INFO, "Flush Buffer %p\r\n", pOMXBuffer);
+            if (pOMXBuffer != NULL)
             {
-                pOMXBuffer = data.pBuffer;
                 pOMXBuffer->nFilledLen = 0;
                 pOMXBuffer->nFlags = OMX_BUFFERFLAG_EOS;
                 pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
@@ -455,4 +619,4 @@ void CodaJ12FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPortNumber)
         break;
     }
     FunctionOut();
-}
+}

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

@@ -75,7 +75,9 @@ typedef struct _SF_CODAJ12_FUNCTIONS
     void (*FreeFrameBuffer)(int instIdx);
     FRAME_BUF *(*GetFrameBuffer)(int instIdx, int idx);
     Uint32 (*GetFrameBufferCount)(int instIdx);
-
+    BOOL (*AttachOneFrameBuffer)(Uint32 instIdx, FrameFormat subsample, CbCrInterLeave cbcrIntlv, PackedFormat packed,
+                         Uint32 rotation, BOOL scalerOn, Uint32 width, Uint32 height, Uint32 bitDepth,
+                         void *virtAddress, Uint32 size, Uint32 *bufferIndex);
     BOOL (*UpdateFrameBuffers)(Uint32 instIdx, Uint32 num, FRAME_BUF *frameBuf);
 
     // JPU Log
@@ -103,6 +105,7 @@ typedef struct _SF_CODAJ12_IMPLEMEMT
     FRAME_BUF frame[NUM_FRAME_BUF];
     OMX_S32 sInputMessageQueue;
     OMX_S32 sOutputMessageQueue;
+    OMX_S32 sBufferDoneQueue;
     OMX_HANDLETYPE pProcessThread;
     OMX_BOOL bThreadRunning;
     OMX_STATETYPE currentState;

+ 216 - 58
soft_3rdpart/omx-il/component/image/dec/SF_OMX_Mjpeg_decoder.c

@@ -7,6 +7,7 @@
 #include <string.h>
 #include "SF_OMX_mjpeg_common.h"
 #include "SF_OMX_Core.h"
+#include <sys/prctl.h>
 
 extern OMX_TICKS gInitTimeStamp;
 #define TEMP_DEBUG 1
@@ -39,20 +40,24 @@ static OMX_ERRORTYPE SF_OMX_EmptyThisBuffer(
 
     LOG(SF_LOG_DEBUG, "nFilledLen = %d, nFlags = %d, pBuffer = %p\r\n", pBuffer->nFilledLen, pBuffer->nFlags, pBuffer->pBuffer);
 
-    if (pBuffer->nFilledLen == 0)
+    if (pBuffer->nFilledLen == 0 || pBuffer->nFlags & 0x1 == 0x1)
     {
         bSendNULL = OMX_TRUE;
     }
-    else if (pBuffer->nFlags & 0x1 == 0x1)
+    else
     {
-        bSendMessage = OMX_TRUE;
-        bSendNULL = OMX_TRUE;
+        bSendNULL = OMX_FALSE;
+    }
+
+    if (pBuffer->pBuffer == NULL)
+    {
+        bSendMessage = OMX_FALSE;
     }
     else
     {
-        bSendNULL = OMX_FALSE;
         bSendMessage = OMX_TRUE;
     }
+
     Message data;
     data.msg_type = 1;
     data.msg_flag = 0;
@@ -130,6 +135,38 @@ static OMX_ERRORTYPE SF_OMX_UseBuffer(
     OMX_IN OMX_U8 *pBuffer)
 {
     OMX_ERRORTYPE ret = OMX_ErrorNone;
+    OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
+    SF_OMX_COMPONENT *pSfOMXComponent = pOMXComponent->pComponentPrivate;
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    FunctionIn();
+
+    if (hComponent == NULL)
+    {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+    if (AttachOutputBuffer(pSfOMXComponent, pBuffer, nSizeBytes) == OMX_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)
+    {
+        LOG(SF_LOG_ERR, "malloc fail\r\n");
+        return OMX_ErrorInsufficientResources;
+    }
+    memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
+    temp_bufferHeader->nAllocLen = nSizeBytes;
+    temp_bufferHeader->pAppPrivate = pAppPrivate;
+    temp_bufferHeader->pBuffer = pBuffer;
+    *ppBufferHdr = temp_bufferHeader;
+    if (nPortIndex == 1)
+    {
+        temp_bufferHeader->pOutputPortPrivate = (OMX_PTR)nOutBufIndex;
+        nOutBufIndex ++;
+    }
+    LOG(SF_LOG_DEBUG, "pBuffer address = %p, nOutBufIndex = %d\r\n", temp_bufferHeader->pBuffer, (int)temp_bufferHeader->pOutputPortPrivate);
 EXIT:
     FunctionOut();
 
@@ -259,6 +296,7 @@ static OMX_ERRORTYPE SF_OMX_GetParameter(
         LOG(SF_LOG_DEBUG, "Get parameter port %X\r\n",portIndex);
         LOG_APPEND(SF_LOG_DEBUG, "width = %d, height = %d\r\n", pSrcDefinition->format.video.nFrameWidth, pSrcDefinition->format.video.nFrameHeight);
         LOG_APPEND(SF_LOG_DEBUG, "eColorFormat = %d\r\n", pSrcDefinition->format.video.eColorFormat);
+        LOG_APPEND(SF_LOG_DEBUG, "xFramerate = %d\r\n", pSrcDefinition->format.video.xFramerate);
         LOG_APPEND(SF_LOG_DEBUG, "bufferSize = %d\r\n",pSrcDefinition->nBufferSize);
         LOG_APPEND(SF_LOG_DEBUG, "Buffer count = %d\r\n", pSrcDefinition->nBufferCountActual);
                          
@@ -351,18 +389,19 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
         DecConfigParam *decConfig = pSfMjpegImplement->config;
 
         OMX_U32 portIndex = pPortDefinition->nPortIndex;
-        OMX_U32 width = pPortDefinition->format.image.nFrameWidth;
-        OMX_U32 height = pPortDefinition->format.image.nFrameHeight;
+        OMX_U32 width = pPortDefinition->format.video.nFrameWidth;
+        OMX_U32 height = pPortDefinition->format.video.nFrameHeight;
         LOG(SF_LOG_INFO, "Set parameter on port %d\r\n", pPortDefinition->nPortIndex);
         LOG_APPEND(SF_LOG_DEBUG, "width = %d, height = %d\r\n",width, height);
         LOG_APPEND(SF_LOG_DEBUG, "eColorFormat = %d\r\n", pPortDefinition->format.video.eColorFormat);
+        LOG_APPEND(SF_LOG_DEBUG, "xFramerate = %d\r\n", pPortDefinition->format.video.xFramerate);
         LOG_APPEND(SF_LOG_DEBUG, "bufferSize = %d\r\n",pPortDefinition->nBufferSize);
         LOG_APPEND(SF_LOG_DEBUG, "Buffer count = %d\r\n", pPortDefinition->nBufferCountActual);
         if (portIndex == (OMX_U32)OMX_INPUT_PORT_INDEX)
         {
             memcpy(&pSfOMXComponent->portDefinition[portIndex], pPortDefinition, pPortDefinition->nSize);
-            pInputPort->format.image.nStride = width;
-            pInputPort->format.image.nSliceHeight = height;
+            pInputPort->format.video.nStride = width;
+            pInputPort->format.video.nSliceHeight = height;
             pInputPort->nBufferSize = width * height * 2;
         }
         else if (portIndex == (OMX_U32)(OMX_OUTPUT_PORT_INDEX))
@@ -374,20 +413,20 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
             */
             if (width <= 1)
             {
-                width = pInputPort->format.image.nFrameWidth;
+                width = pInputPort->format.video.nFrameWidth;
             }
             if (height <= 1)
             {
-                height = pInputPort->format.image.nFrameHeight;
+                height = pInputPort->format.video.nFrameHeight;
             }
             if (width > 0 && height > 0)
             {
-                int scalew = pInputPort->format.image.nFrameWidth / width;
-                int scaleh = pInputPort->format.image.nFrameHeight / height;
+                int scalew = pInputPort->format.video.nFrameWidth / width;
+                int scaleh = pInputPort->format.video.nFrameHeight / height;
                 if (scalew > 8 || scaleh > 8 || scalew < 1 || scaleh < 1)
                 {
-                    int nInputWidth = pInputPort->format.image.nFrameWidth;
-                    int nInputHeight = pInputPort->format.image.nFrameHeight;
+                    int nInputWidth = pInputPort->format.video.nFrameWidth;
+                    int nInputHeight = pInputPort->format.video.nFrameHeight;
                     LOG(SF_LOG_WARN, "Scaling should be 1 to 1/8 (down-scaling only)! Use input parameter. "
                                      "OutPut[%d, %d]. Input[%d, %d]\r\n",
                         width, height, nInputWidth, nInputHeight);
@@ -395,11 +434,11 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
                     height = nInputHeight;
                 }
 
-                pOutputPort->format.image.nFrameWidth = width;
-                pOutputPort->format.image.nFrameHeight = height;
-                pOutputPort->format.image.nStride = width;
-                pOutputPort->format.image.nSliceHeight = height;
-                switch (pOutputPort->format.image.eColorFormat)
+                pOutputPort->format.video.nFrameWidth = width;
+                pOutputPort->format.video.nFrameHeight = height;
+                pOutputPort->format.video.nStride = width;
+                pOutputPort->format.video.nSliceHeight = height;
+                switch (pOutputPort->format.video.eColorFormat)
                 {
                     case OMX_COLOR_FormatYUV420Planar:
                         pOutputPort->nBufferSize = (width * height * 3) / 2;
@@ -564,19 +603,6 @@ static OMX_ERRORTYPE InitDecoder(SF_OMX_COMPONENT *pSfOMXComponent)
     JpgDecOpenParam *decOP = &pSfCodaj12Implement->decOP;
     JpgDecHandle handle = pSfCodaj12Implement->handle;
 
-    // pSfCodaj12Implement->sInputMessageQueue = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
-    // if (pSfCodaj12Implement->sInputMessageQueue < 0)
-    // {
-    //     LOG(SF_LOG_ERR, "get ipc_id error");
-    //     return;
-    // }
-    // pSfCodaj12Implement->sOutputMessageQueue = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
-    // if (pSfCodaj12Implement->sOutputMessageQueue < 0)
-    // {
-    //     LOG(SF_LOG_ERR, "get ipc_id error");
-    //     return;
-    // }
-
     ret = pSfCodaj12Implement->functions->JPU_Init();
     if (ret != JPG_RET_SUCCESS && ret != JPG_RET_CALLED_BEFORE)
     {
@@ -604,6 +630,116 @@ ERR_DEC_INIT:
     return OMX_ErrorHardware;
 }
 
+static OMX_BOOL AdjustFrame(OMX_BUFFERHEADERTYPE* pBuffer, OMX_U32 nSrcWidth, OMX_U32 nSrcHeight,
+                            OMX_U32 nDestWidth, OMX_U32 nDestHeight)
+{
+    OMX_U32 nDeltaWidth = 0;
+    OMX_U32 nDeltaHeight = 0;
+
+    FunctionIn();
+
+    nDeltaWidth = nSrcWidth - nDestWidth;
+    nDeltaHeight = nSrcHeight - nDestHeight;
+
+    if (nDeltaWidth == 0 && nDeltaHeight == 0)
+    {
+        return OMX_TRUE;
+    }
+
+    if (nDeltaWidth != 0)
+    {
+        LOG(SF_LOG_ERR, "nSrcWidth != nDestWidth not supported\r\n");
+        return OMX_FALSE;
+    }
+
+    OMX_U8 *pDestCbCrStart = pBuffer->pBuffer + nDestHeight * nDestWidth;
+    OMX_U8 *pSrcCbCrStart = pBuffer->pBuffer + nDestHeight * nDestWidth + nDeltaHeight * nDestWidth;
+    OMX_U32 pCbCrSize =  nDestWidth * nDestHeight / 2;
+    LOG(SF_LOG_DEBUG, "pBuffer = %p, pDestCbCrStart = %p, pSrcCbCrStart = %p, pCbCrSize = %d\r\n",
+        pBuffer->pBuffer, pDestCbCrStart, pSrcCbCrStart, pCbCrSize);
+    memmove(pDestCbCrStart, pSrcCbCrStart, pCbCrSize);
+    pBuffer->nFilledLen = nDestHeight * nDestWidth * 3 / 2;
+
+    FunctionOut();
+
+    return OMX_TRUE;
+}
+
+static OMX_BOOL FillBufferDone(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    struct timeval tv;
+    static OMX_U32 dec_cnt = 0;
+    OMX_U32 fps = 0;
+    OMX_U64 diff_time = 0; // ms
+    static struct timeval tv_old = {0};
+
+    FunctionIn();
+
+    gettimeofday(&tv, NULL);
+    if (gInitTimeStamp == 0)
+    {
+        gInitTimeStamp = tv.tv_sec * 1000000 + tv.tv_usec;
+    }
+    pBuffer->nTimeStamp = tv.tv_sec * 1000000 + tv.tv_usec - gInitTimeStamp;
+
+    if (dec_cnt == 0) {
+        tv_old = tv;
+    }
+    if (dec_cnt++ >= 50) {
+        diff_time = (tv.tv_sec - tv_old.tv_sec) * 1000 + (tv.tv_usec - tv_old.tv_usec) / 1000;
+        fps = 1000  * (dec_cnt - 1) / diff_time;
+        dec_cnt = 0;
+        LOG(SF_LOG_WARN, "Decoding fps: %d \r\n", fps);
+    }
+
+    LOG(SF_LOG_PERF, "OMX finish one buffer, address = %p, size = %d, nTimeStamp = %d, nFlags = %X\r\n",
+            pBuffer->pBuffer, pBuffer->nFilledLen, pBuffer->nTimeStamp, pBuffer->nFlags);
+    // Following comment store data loal
+    // {
+    //     FILE *fb = fopen("./out.bcp", "ab+");
+    //     LOG(SF_LOG_INFO, "%p %d\r\n", pBuffer->pBuffer, pBuffer->nFilledLen);
+    //     fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, fb);
+    //     fclose(fb);
+    // }
+    pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pBuffer);
+    FunctionOut();
+    return OMX_TRUE;
+}
+static OMX_BOOL EmptyBufferDone(SF_OMX_COMPONENT *pSfOMXComponent)
+{
+    SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
+    OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
+    Message data;
+    ssize_t ret;
+
+    FunctionIn();
+    LOG(SF_LOG_INFO, "Wait for done used buffer\r\n");
+    ret = msgrcv(pSfCodaj12Implement->sBufferDoneQueue, (void *)&data, BUFSIZ, 0, IPC_NOWAIT);
+    if (ret < 0)
+    {
+        LOG(SF_LOG_ERR, "msgrcv failed ret = %x\r\n", ret);
+        return OMX_FALSE;
+    }
+    // switch (ret)
+    // {
+    // case ENOMSG:
+    //     LOG(SF_LOG_INFO, "msgrcv no message\n");
+    //     return OMX_TRUE;
+    // default:
+    //     LOG(SF_LOG_ERR, "msgrcv failed ret = %x\r\n", ret);
+    //     return OMX_FALSE;
+    // }
+    
+    pOMXBuffer = data.pBuffer;
+    //TODO: input/output Buffer done
+    LOG(SF_LOG_DEBUG, "EmptyBufferDone IN\r\n");
+    pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+    LOG(SF_LOG_DEBUG, "EmptyBufferDone OUT\r\n");
+
+    FunctionOut();
+    return OMX_TRUE;
+}
+
 static OMX_U32 FeedData(SF_OMX_COMPONENT *pSfOMXComponent)
 {
     FunctionIn();
@@ -611,7 +747,7 @@ static OMX_U32 FeedData(SF_OMX_COMPONENT *pSfOMXComponent)
     BSFeeder feeder = pSfCodaj12Implement->feeder;
     JpgDecHandle handle = pSfCodaj12Implement->handle;
     jpu_buffer_t *vbStream = &pSfCodaj12Implement->vbStream;
-    OMX_U32 nFilledLen;
+    OMX_U32 nFilledLen = 0;
 
     OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
     Message data;
@@ -622,18 +758,31 @@ static OMX_U32 FeedData(SF_OMX_COMPONENT *pSfOMXComponent)
         return 0;
     }
     pOMXBuffer = data.pBuffer;
-    if (pOMXBuffer == NULL || data.msg_flag == OMX_BUFFERFLAG_EOS)
+    // if (pOMXBuffer == NULL || data.msg_flag == OMX_BUFFERFLAG_EOS)
+    // {
+    //     return 0;
+    // }
+
+    if (pOMXBuffer != NULL)
     {
-        return 0;
-    }
+        if (pOMXBuffer->pBuffer != NULL && pOMXBuffer->nFilledLen > 0)
+        {
+            nFilledLen = pOMXBuffer->nFilledLen;
+            LOG(SF_LOG_INFO, "Address = %p, size = %d\r\n", pOMXBuffer->pBuffer, nFilledLen);
+            pSfCodaj12Implement->functions->BitstreamFeeder_SetData(feeder, pOMXBuffer->pBuffer, nFilledLen);
+            pSfCodaj12Implement->functions->BitstreamFeeder_Act(feeder, handle, vbStream);
+        }
+        LOG(SF_LOG_INFO, "Send %p to sBufferDoneQueue\r\n", pOMXBuffer);
+        if (msgsnd(pSfCodaj12Implement->sBufferDoneQueue, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
+        {
+            LOG(SF_LOG_ERR, "msgsnd failed\n");
+            return 0;
+        }
+    }  
 
-    nFilledLen = pOMXBuffer->nFilledLen;
-    LOG(SF_LOG_INFO, "Address = %p, size = %d\r\n", pOMXBuffer->pBuffer, nFilledLen);
-    pSfCodaj12Implement->functions->BitstreamFeeder_SetData(feeder, pOMXBuffer->pBuffer, nFilledLen);
-    pSfCodaj12Implement->functions->BitstreamFeeder_Act(feeder, handle, vbStream);
-    LOG(SF_LOG_DEBUG, "EmptyBufferDone IN\r\n");
-    pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
-    LOG(SF_LOG_DEBUG, "EmptyBufferDone OUT\r\n");
+    // LOG(SF_LOG_DEBUG, "EmptyBufferDone IN\r\n");
+    // pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+    // LOG(SF_LOG_DEBUG, "EmptyBufferDone OUT\r\n");
 
     // if (pOMXBuffer->nFlags & 0x1 == 0x1)
     // {
@@ -657,7 +806,8 @@ static OMX_ERRORTYPE WaitForOutputBufferReady(SF_OMX_COMPONENT *pSfOMXComponent)
         return OMX_ErrorInsufficientResources;
     }
     pOMXBuffer = data.pBuffer;
-    if (pOMXBuffer == NULL || data.msg_flag == OMX_BUFFERFLAG_EOS)
+    // if (pOMXBuffer == NULL || data.msg_flag == OMX_BUFFERFLAG_EOS)
+    if (pOMXBuffer == NULL)
     {
         LOG(SF_LOG_INFO, "Buffer end flag detected! \r\n");
         pSfCodaj12Implement->bThreadRunning = OMX_FALSE;
@@ -688,6 +838,7 @@ static void ProcessThread(void *args)
     JpgRet ret = JPG_RET_SUCCESS;
 
     FunctionIn();
+    prctl(PR_SET_NAME, pSfOMXComponent->componentName);
     LOG(SF_LOG_INFO, "vbStream phys_addr = %x, size = %d, virt_addr = %x\r\n", vbStream->phys_addr, vbStream->size, vbStream->virt_addr);
     decOP->streamEndian = decConfig->StreamEndian;
     decOP->frameEndian = decConfig->FrameEndian;
@@ -778,11 +929,12 @@ static void ProcessThread(void *args)
     } while (JPG_RET_SUCCESS != ret);
     //TODO:Set output info
     OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = &pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX];
-    pPortDefinition->format.image.nFrameWidth = initialInfo->picWidth;
-    pPortDefinition->format.image.nFrameHeight = initialInfo->picHeight;
-    pPortDefinition->format.image.nStride = initialInfo->picWidth;
-    pPortDefinition->format.image.nSliceHeight = initialInfo->picHeight;
-    pPortDefinition->format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
+    LOG(SF_LOG_DEBUG, "picWidth = %d, picHeight = %d\r\n", initialInfo->picWidth, initialInfo->picHeight);
+    pPortDefinition->format.video.nFrameWidth = initialInfo->picWidth;
+    pPortDefinition->format.video.nFrameHeight = initialInfo->picHeight;
+    pPortDefinition->format.video.nStride = initialInfo->picWidth;
+    pPortDefinition->format.video.nSliceHeight = initialInfo->picHeight;
+    pPortDefinition->format.video.eCompressionFormat = OMX_IMAGE_CodingUnused;
     switch (pSfCodaj12Implement->frameFormat)
     {
     case FORMAT_400:
@@ -821,6 +973,7 @@ static void ProcessThread(void *args)
     while (OMX_TRUE)
     {
         // LOG(SF_LOG_INFO, "GetFrameBufferCount addr = %p\r\n", pSfCodaj12Implement->functions->GetFrameBufferCount);
+        nBufferNumber = pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].nBufferCountActual;
         OMX_U32 number = pSfCodaj12Implement->functions->GetFrameBufferCount(instIdx);
         OMX_S32 oldNumber = -1;
         if (number < nBufferNumber)
@@ -850,10 +1003,11 @@ static void ProcessThread(void *args)
 
     FRAME_BUF *pFrame = pSfCodaj12Implement->frame;
     LOG(SF_LOG_INFO, "Update and regist %d FrameBuffers\r\n", nBufferNumber);
-    LOG(SF_LOG_DEBUG, "%20s%20s%20s\r\n", "virtAddr", "phyAddr", "size");
+    LOG(SF_LOG_DEBUG, "%20s%20s%20s%20s\r\n", "virtAddr", "Y", "CB", "CR");
     for (int i = 0; i < nBufferNumber; i ++)
     {
-        LOG_APPEND(SF_LOG_DEBUG, "%20X%20X%20X\r\n", pFrame[i].vbY.virt_addr, pFrame[i].vbY.phys_addr, pFrame[i].vbY.size);
+        LOG_APPEND(SF_LOG_DEBUG, "%20lX%20lX%20lX%20lX\r\n", pFrame[i].vbY.virt_addr,
+            pFrame[i].vbY.phys_addr, pFrame[i].vbCb.phys_addr, pFrame[i].vbCr.phys_addr);
     }
 
     // ffmpeg: may register frame buffer append
@@ -934,7 +1088,7 @@ static void ProcessThread(void *args)
             // }
         }
         //LOG(SF_LOG_INFO, "\t<->INSTANCE #%d JPU_WaitInterrupt\n", handle->instIndex);
-
+        EmptyBufferDone(pSfOMXComponent);
         if ((ret = pSfCodaj12Implement->functions->JPU_DecGetOutputInfo(handle, &outputInfo)) != JPG_RET_SUCCESS)
         {
             LOG(SF_LOG_ERR, "JPU_DecGetOutputInfo failed Error code is 0x%x \n", ret);
@@ -981,9 +1135,13 @@ static void ProcessThread(void *args)
             break;
         }
         
-        LOG(SF_LOG_DEBUG, "decPicSize = [%d %d], pBuffer = %p, nFilledLen = %d\r\n",
-            outputInfo.decPicWidth, outputInfo.decPicHeight, pBuffer->pBuffer, pBuffer->nFilledLen);
-        LOG(SF_LOG_DEBUG, "FillBufferDone IN\r\n");
+        LOG(SF_LOG_DEBUG, "decPicSize = [%d %d], pBuffer = %p\r\n",
+            outputInfo.decPicWidth, outputInfo.decPicHeight, pBuffer->pBuffer);
+        OMX_U32 nDestHeight = pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].format.video.nFrameHeight;
+        OMX_U32 nDestStride = pSfOMXComponent->portDefinition[OMX_OUTPUT_PORT_INDEX].format.video.nStride;
+        // AdjustFrame(pBuffer, outputInfo.decPicWidth, outputInfo.decPicHeight, nDestStride, nDestHeight);
+        FillBufferDone(pSfOMXComponent, pBuffer);
+        // LOG(SF_LOG_DEBUG, "FillBufferDone IN\r\n");
         // Following comment store data loal
         // {
         //     FILE *fb = fopen("./out.bcp", "ab+");
@@ -991,8 +1149,8 @@ static void ProcessThread(void *args)
         //     fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, fb);
         //     fclose(fb);
         // }
-        pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pBuffer);
-        LOG(SF_LOG_DEBUG, "FillBufferDone OUT\r\n");
+        // pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pBuffer);
+        // LOG(SF_LOG_DEBUG, "FillBufferDone OUT\r\n");
         if (outputInfo.numOfErrMBs)
         {
             Int32 errRstIdx, errPosX, errPosY;