Browse Source

omx:upgrade omx components to adapt to OMX-IL CTS Base Profile Conformance Tests

Signed-off-by: Som Qin <som.qin@starfivetech.com>
Som Qin 1 year ago
parent
commit
22a4a90a15
34 changed files with 2686 additions and 869 deletions
  1. 9 10
      codaj12/jdi/linux/driver/jpu.c
  2. 31 1
      codaj12/sample/helper/jpuhelper.c
  3. 2 0
      omx-il/Makefile
  4. 103 0
      omx-il/component/helper/sf_semaphore.c
  5. 23 0
      omx-il/component/helper/sf_semaphore.h
  6. 68 0
      omx-il/component/helper/sf_thread.c
  7. 28 0
      omx-il/component/helper/sf_thread.h
  8. 62 75
      omx-il/component/image/common/SF_OMX_mjpeg_common.c
  9. 21 12
      omx-il/component/image/common/SF_OMX_mjpeg_common.h
  10. 490 190
      omx-il/component/image/dec/SF_OMX_Mjpeg_decoder.c
  11. 586 146
      omx-il/component/video/wave4/SF_OMX_Wave420L_encoder.c
  12. 9 9
      omx-il/component/video/wave4/SF_OMX_Wave420L_encoder.h
  13. 78 30
      omx-il/component/video/wave5/common/SF_OMX_video_common.c
  14. 16 0
      omx-il/component/video/wave5/common/SF_OMX_video_common.h
  15. 541 229
      omx-il/component/video/wave5/dec/SF_OMX_Vdec_decoder.c
  16. 3 3
      omx-il/component/video/wave5/enc/SF_OMX_Venc_encoder.c
  17. 37 76
      omx-il/core/SF_OMX_Core.c
  18. 39 8
      omx-il/core/SF_OMX_Core.h
  19. 61 0
      omx-il/include/khronos/OMX_ComponentExt.h
  20. 73 0
      omx-il/include/khronos/OMX_CoreExt.h
  21. 55 0
      omx-il/include/khronos/OMX_ImageExt.h
  22. 31 22
      omx-il/include/khronos/OMX_Types.h
  23. 73 7
      omx-il/tests/dec_test.c
  24. 67 21
      omx-il/tests/enc_test.c
  25. 69 20
      omx-il/tests/mjpeg_dec_test.c
  26. 1 0
      wave511/code/sample_v2/component/component.c
  27. 7 0
      wave511/code/sample_v2/component/component.h
  28. 4 1
      wave511/code/sample_v2/component_decoder/component_dec_decoder.c
  29. 63 7
      wave511/code/sample_v2/component_decoder/component_dec_renderer.c
  30. 7 0
      wave511/code/sample_v2/helper/main_helper.c
  31. 5 1
      wave511/code/sample_v2/helper/main_helper.h
  32. 1 1
      wave511/code/vdi/linux/driver/vdec.c
  33. 22 0
      wave511/code/vdi/linux/vdi.c
  34. 1 0
      wave511/code/vdi/vdi.h

+ 9 - 10
codaj12/jdi/linux/driver/jpu.c

@@ -160,6 +160,8 @@ static void jpu_clk_disable(jpu_clk_t *clk);
 static int jpu_clk_enable(jpu_clk_t *clk);
 static jpu_clk_t *jpu_clk_get(struct platform_device *pdev);
 static void jpu_clk_put(jpu_clk_t *clk);
+static int jpu_pmu_enable(struct device *dev);
+static void jpu_pmu_disable(struct device *dev);
 // end customer definition
 
 static jpudrv_buffer_t s_instance_pool = {0};
@@ -341,6 +343,8 @@ static int jpu_open(struct inode *inode, struct file *filp)
 {
     DPRINTK("[JPUDRV][+] %s\n", __func__);
 
+    jpu_clk_enable(s_jpu_clk);
+
     spin_lock(&s_jpu_lock);
 
     s_jpu_drv_context.open_count++;
@@ -465,10 +469,7 @@ static long jpu_ioctl(struct file *filp, u_int cmd, u_long arg)
                     break;
                 }
 
-                jbp->filp = filp;
-                spin_lock(&s_jpu_lock);
-                list_add(&jbp->list, &s_jbp_head);
-                spin_unlock(&s_jpu_lock);
+                kfree(jbp);
 
                 up(&s_jpu_sem);
             }
@@ -753,7 +754,7 @@ static int jpu_release(struct inode *inode, struct file *filp)
 
     DPRINTK("[JPUDRV][-] jpu_release\n");
 
-    jpu_hw_reset();
+    jpu_clk_disable(s_jpu_clk);
 
     return 0;
 }
@@ -900,7 +901,7 @@ static int jpu_probe(struct platform_device *pdev)
 
 #ifdef JPU_SUPPORT_CLOCK_CONTROL
 #else
-    jpu_clk_enable(s_jpu_clk);
+    jpu_pmu_enable(s_jpu_clk->dev);
 #endif
 
 
@@ -997,7 +998,7 @@ static int jpu_remove(struct platform_device *pdev)
     if (s_jpu_register.virt_addr)
         iounmap((void*)s_jpu_register.virt_addr);
 
-    jpu_clk_disable(s_jpu_clk);
+    jpu_pmu_disable(s_jpu_clk->dev);
     jpu_clk_put(s_jpu_clk);
 
 #endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
@@ -1340,7 +1341,7 @@ static int jpu_of_clk_get(struct platform_device *pdev, jpu_clk_t *jpu_clk)
 	jpu_clk->clks = jpu_clks;
 	jpu_clk->nr_clks = ARRAY_SIZE(jpu_clks);
 
-	jpu_clk->resets = devm_reset_control_array_get_exclusive(dev);
+	jpu_clk->resets = devm_reset_control_array_get_shared(dev);
 	if (IS_ERR(jpu_clk->resets)) {
 		ret = PTR_ERR(jpu_clk->resets);
 		dev_err(dev, "faied to get jpu reset controls\n");
@@ -1384,7 +1385,6 @@ static int jpu_clk_enable(jpu_clk_t *clk)
 {
 	int ret;
 
-	jpu_pmu_enable(clk->dev);
 	ret = clk_bulk_prepare_enable(clk->nr_clks, clk->clks);
 	if (ret)
 		dev_err(clk->dev, "enable clk error.\n");
@@ -1406,6 +1406,5 @@ static void jpu_clk_disable(jpu_clk_t *clk)
 		dev_err(clk->dev, "assert jpu error.\n");
 
 	clk_bulk_disable_unprepare(clk->nr_clks, clk->clks);
-	jpu_pmu_disable(clk->dev);
 }
 #endif /* STARFIVE_JPU_SUPPORT_CLOCK_CONTROL */

+ 31 - 1
codaj12/sample/helper/jpuhelper.c

@@ -106,6 +106,36 @@ static void TiledToLinear(Uint8* pSrc, Uint8* pDst, Uint32 width, Uint32 height,
     }
 }
 
+int SaveYuvImageHelper(
+    Uint8*          pYuv,
+    FrameBuffer*    fb,
+    CbCrInterLeave  interLeave,
+    PackedFormat    packed,
+    Uint32          picWidth,
+    Uint32          picHeight,
+    Uint32          bitDepth
+    )
+{
+    int frameSize;
+
+    if (pYuv == NULL) {
+        JLOG(ERR, "%s:%d pYuv is NULL\n", __FUNCTION__, __LINE__);
+        return 0;
+    }
+
+    frameSize = StoreYuvImageBurstFormat_V20(fb->strideC, pYuv, picWidth, picHeight, bitDepth,
+        fb->bufY,
+        fb->bufCb,
+        fb->bufCr,
+        fb->stride,
+        fb->format,
+        fb->endian,
+        interLeave,
+        packed);
+
+    return frameSize;
+}
+
 int StoreYuvImageBurstFormatWhenNotAligned(int chromaStride, Uint8 * dst, int picWidth, int picHeight, Uint32 bitDepth,
     Uint64 addrY, Uint64 addrCb, Uint64 addrCr, Uint32 stride, FrameFormat format, int endian, CbCrInterLeave interLeave, PackedFormat packed)
 {
@@ -247,7 +277,7 @@ int StoreYuvImageBurstFormatWhenNotAligned(int chromaStride, Uint8 * dst, int pi
     return size;
 }//lint !e429
 
-int SaveYuvImageHelper(
+int SaveYuvImageHelperDma(
     Uint8*          pYuv,
     FrameBuffer*    fb,
     CbCrInterLeave  interLeave,

+ 2 - 0
omx-il/Makefile

@@ -47,6 +47,8 @@ SOURCES_COMMON = SF_OMX_Core.c SF_OMX_video_common.c
 SOURCES_COMMON += SF_OMX_Vdec_decoder.c
 SOURCES_COMMON += SF_OMX_Wave420L_encoder.c
 SOURCES_COMMON += sf_queue.c
+SOURCES_COMMON += sf_thread.c
+SOURCES_COMMON += sf_semaphore.c
 #mjpeg
 SOURCES_COMMON += SF_OMX_mjpeg_common.c SF_OMX_Mjpeg_decoder.c
 #test

+ 103 - 0
omx-il/component/helper/sf_semaphore.c

@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#include "sf_semaphore.h"
+#include "SF_OMX_Core.h"
+
+OMX_ERRORTYPE SF_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle)
+{
+    sem_t *sema;
+
+    sema = (sem_t *)malloc(sizeof(sem_t));
+    if (!sema)
+        return OMX_ErrorInsufficientResources;
+
+    if (sem_init(sema, 0, 0) != 0) {
+        free(sema);
+        return OMX_ErrorUndefined;
+    }
+
+    *semaphoreHandle = (OMX_HANDLETYPE)sema;
+
+    LOG(SF_LOG_INFO,"SF_SemaphoreCreate %p\r\n", sema);
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SF_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_destroy(sema) != 0)
+        return OMX_ErrorUndefined;
+
+    free(sema);
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SF_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+    FunctionIn();
+    LOG(SF_LOG_INFO,"SF_SemaphoreWait %p\r\n", semaphoreHandle);
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_wait(sema) != 0)
+        return OMX_ErrorUndefined;
+
+    FunctionOut();
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SF_SemaphorePost(OMX_HANDLETYPE semaphoreHandle)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+
+    FunctionIn();
+    LOG(SF_LOG_INFO,"SF_SemaphorePost %p\r\n", semaphoreHandle);
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_post(sema) != 0)
+        return OMX_ErrorUndefined;
+
+    FunctionOut();
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SF_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_init(sema, 0, val) != 0)
+        return OMX_ErrorUndefined;
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SF_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val)
+{
+    sem_t *sema = (sem_t *)semaphoreHandle;
+    int semaVal = 0;
+
+    if (sema == NULL)
+        return OMX_ErrorBadParameter;
+
+    if (sem_getvalue(sema, &semaVal) != 0)
+        return OMX_ErrorUndefined;
+
+    *val = (OMX_S32)semaVal;
+
+    return OMX_ErrorNone;
+}

+ 23 - 0
omx-il/component/helper/sf_semaphore.h

@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#ifndef SF_SEMAPHORE_H
+#define SF_SEMAPHORE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+
+OMX_ERRORTYPE SF_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle);
+OMX_ERRORTYPE SF_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle);
+OMX_ERRORTYPE SF_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle);
+OMX_ERRORTYPE SF_SemaphorePost(OMX_HANDLETYPE semaphoreHandle);
+OMX_ERRORTYPE SF_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val);
+OMX_ERRORTYPE SF_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val);
+
+#endif //SF_SEMAPHORE_H

+ 68 - 0
omx-il/component/helper/sf_thread.c

@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#include "sf_thread.h"
+#include "SF_OMX_Core.h"
+
+OMX_ERRORTYPE CreateThread(THREAD_HANDLE_TYPE **threadHandle, OMX_PTR function_name, OMX_PTR argument)
+{
+    FunctionIn();
+
+    int result = 0;
+    int detach_ret = 0;
+    THREAD_HANDLE_TYPE *thread;
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    thread = malloc(sizeof(THREAD_HANDLE_TYPE));
+    memset(thread, 0, sizeof(THREAD_HANDLE_TYPE));
+
+    pthread_attr_init(&thread->attr);
+    if (thread->stack_size != 0)
+        pthread_attr_setstacksize(&thread->attr, thread->stack_size);
+
+    /* set priority */
+    if (thread->schedparam.sched_priority != 0)
+        pthread_attr_setschedparam(&thread->attr, &thread->schedparam);
+
+    detach_ret = pthread_attr_setdetachstate(&thread->attr, PTHREAD_CREATE_JOINABLE);
+    if (detach_ret != 0)
+    {
+        free(thread);
+        *threadHandle = NULL;
+        ret = OMX_ErrorUndefined;
+        goto EXIT;
+    }
+
+    result = pthread_create(&thread->pthread, &thread->attr, function_name, (void *)argument);
+    /* pthread_setschedparam(thread->pthread, SCHED_RR, &thread->schedparam); */
+
+    switch (result)
+    {
+    case 0:
+        *threadHandle = thread;
+        ret = OMX_ErrorNone;
+        break;
+    case EAGAIN:
+        free(thread);
+        *threadHandle = NULL;
+        ret = OMX_ErrorInsufficientResources;
+        break;
+    default:
+        free(thread);
+        *threadHandle = NULL;
+        ret = OMX_ErrorUndefined;
+        break;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+void ThreadExit(void *value_ptr)
+{
+    pthread_exit(value_ptr);
+    return;
+}

+ 28 - 0
omx-il/component/helper/sf_thread.h

@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+#ifndef SF_THREAD_H
+#define SF_THREAD_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <pthread.h>
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+
+typedef struct _THREAD_HANDLE_TYPE
+{
+    pthread_t          pthread;
+    pthread_attr_t     attr;
+    struct sched_param schedparam;
+    int                stack_size;
+} THREAD_HANDLE_TYPE;
+
+
+OMX_ERRORTYPE CreateThread(THREAD_HANDLE_TYPE **threadHandle, OMX_PTR function_name, OMX_PTR argument);
+void ThreadExit(void *value_ptr);
+
+#endif //SF_THREAD_H

+ 62 - 75
omx-il/component/image/common/SF_OMX_mjpeg_common.c

@@ -184,8 +184,41 @@ OMX_ERRORTYPE InitMjpegStructorCommon(SF_OMX_COMPONENT *pSfOMXComponent)
         pPortDefinition->bEnabled = OMX_TRUE;
 
         pPortDefinition->eDir = (i == 0 ? OMX_DirInput : OMX_DirOutput);
+        pSfOMXComponent->assignedBufferNum[i] = 0;
     }
 
+    /* Set componentVersion */
+    pSfOMXComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pSfOMXComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pSfOMXComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pSfOMXComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pSfOMXComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pSfOMXComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pSfOMXComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pSfOMXComponent->specVersion.s.nStep         = STEP_NUMBER;
+
+    memset(pSfOMXComponent->markType, 0, sizeof(pSfOMXComponent->markType));
+    pSfOMXComponent->propagateMarkType.hMarkTargetComponent = NULL;
+    pSfOMXComponent->propagateMarkType.pMarkData = NULL;
+
+    for (int i = 0; i < 2; i++)
+    {
+        ret = SF_SemaphoreCreate(&pSfOMXComponent->portSemaphore[i]);
+        if (ret)
+            goto ERROR;
+        ret = SF_SemaphoreCreate(&pSfOMXComponent->portUnloadSemaphore[i]);
+        if (ret)
+            goto ERROR;
+        ret = SF_SemaphoreCreate(&pSfOMXComponent->portFlushSemaphore[i]);
+        if (ret)
+            goto ERROR;
+    }
+
+    ret = SF_SemaphoreCreate(&pSfCodaj12Implement->pauseOutSemaphore);
+    if (ret)
+        goto ERROR;
+
     // strcpy(pSfOMXComponent->portDefinition[1].format.image.cMIMEType, "JPEG");
     // pSfOMXComponent->portDefinition[1].format.image.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
     pSfOMXComponent->portDefinition[0].format.video.eColorFormat = OMX_COLOR_FormatUnused;
@@ -195,12 +228,20 @@ OMX_ERRORTYPE InitMjpegStructorCommon(SF_OMX_COMPONENT *pSfOMXComponent)
     pSfOMXComponent->portDefinition[1].format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
 
     memset(pSfOMXComponent->pBufferArray, 0, sizeof(pSfOMXComponent->pBufferArray));
-    pSfOMXComponent->memory_optimization = OMX_TRUE;
 
     FunctionOut();
 EXIT:
     return ret;
 ERROR:
+    for (int i = 0; i < 2; i++)
+    {
+        SF_SemaphoreTerminate(pSfOMXComponent->portSemaphore[i]);
+        SF_SemaphoreTerminate(pSfOMXComponent->portUnloadSemaphore[i]);
+        SF_SemaphoreTerminate(pSfOMXComponent->portFlushSemaphore[i]);
+    }
+
+    SF_SemaphoreTerminate(pSfCodaj12Implement->pauseOutSemaphore);
+
     if (pSfOMXComponent->pOMXComponent)
     {
         free(pSfOMXComponent->pOMXComponent);
@@ -220,6 +261,7 @@ static void sf_get_component_functions(SF_CODAJ12_FUNCTIONS *funcs, OMX_PTR *soh
     funcs->JPU_DecRegisterFrameBuffer = dlsym(sohandle, "JPU_DecRegisterFrameBuffer");
     funcs->JPU_DecGiveCommand = dlsym(sohandle, "JPU_DecGiveCommand");
     funcs->JPU_DecStartOneFrameBySerialNum = dlsym(sohandle, "JPU_DecStartOneFrameBySerialNum");
+    funcs->JPU_DecStartOneFrame = dlsym(sohandle, "JPU_DecStartOneFrame");
     funcs->JPU_DecGetOutputInfo = dlsym(sohandle, "JPU_DecGetOutputInfo");
     funcs->JPU_SWReset = dlsym(sohandle, "JPU_SWReset");
     funcs->JPU_DecSetRdPtrEx = dlsym(sohandle, "JPU_DecSetRdPtrEx");
@@ -236,6 +278,7 @@ static void sf_get_component_functions(SF_CODAJ12_FUNCTIONS *funcs, OMX_PTR *soh
     funcs->jdi_allocate_dma_memory = dlsym(sohandle, "jdi_allocate_dma_memory");
     funcs->jdi_free_dma_memory = dlsym(sohandle, "jdi_free_dma_memory");
     funcs->AllocateOneFrameBuffer = dlsym(sohandle, "AllocateOneFrameBuffer");
+    funcs->AllocateFrameBuffer = dlsym(sohandle, "AllocateFrameBuffer");
     funcs->FreeFrameBuffer = dlsym(sohandle, "FreeFrameBuffer");
     funcs->GetFrameBuffer = dlsym(sohandle, "GetFrameBuffer");
     funcs->GetFrameBufferCount = dlsym(sohandle, "GetFrameBufferCount");
@@ -243,6 +286,7 @@ static void sf_get_component_functions(SF_CODAJ12_FUNCTIONS *funcs, OMX_PTR *soh
     funcs->SetMaxLogLevel = dlsym(sohandle, "SetMaxLogLevel");
     funcs->AttachOneFrameBuffer = dlsym(sohandle, "AttachOneFrameBuffer");
     funcs->SaveYuvImageHelper = dlsym(sohandle, "SaveYuvImageHelper");
+    funcs->SaveYuvImageHelperDma = dlsym(sohandle, "SaveYuvImageHelperDma");
     FunctionOut();
 }
 
@@ -382,6 +426,7 @@ OMX_BOOL AttachOutputBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U8* pBuffer,
     return OMX_TRUE;
 
 }
+
 OMX_U8 *AllocateOutputBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nSizeBytes)
 {
     SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
@@ -535,68 +580,6 @@ OMX_U8 *AllocateOutputBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nSizeByt
     return virtAddr;
 }
 
-OMX_ERRORTYPE CreateThread(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument)
-{
-    FunctionIn();
-
-    int result = 0;
-    int detach_ret = 0;
-    THREAD_HANDLE_TYPE *thread;
-    OMX_ERRORTYPE ret = OMX_ErrorNone;
-
-    thread = malloc(sizeof(THREAD_HANDLE_TYPE));
-    memset(thread, 0, sizeof(THREAD_HANDLE_TYPE));
-
-    pthread_attr_init(&thread->attr);
-    if (thread->stack_size != 0)
-        pthread_attr_setstacksize(&thread->attr, thread->stack_size);
-
-    /* set priority */
-    if (thread->schedparam.sched_priority != 0)
-        pthread_attr_setschedparam(&thread->attr, &thread->schedparam);
-
-    detach_ret = pthread_attr_setdetachstate(&thread->attr, PTHREAD_CREATE_JOINABLE);
-    if (detach_ret != 0)
-    {
-        free(thread);
-        *threadHandle = NULL;
-        ret = OMX_ErrorUndefined;
-        goto EXIT;
-    }
-
-    result = pthread_create(&thread->pthread, &thread->attr, function_name, (void *)argument);
-    /* pthread_setschedparam(thread->pthread, SCHED_RR, &thread->schedparam); */
-
-    switch (result)
-    {
-    case 0:
-        *threadHandle = (OMX_HANDLETYPE)thread;
-        ret = OMX_ErrorNone;
-        break;
-    case EAGAIN:
-        free(thread);
-        *threadHandle = NULL;
-        ret = OMX_ErrorInsufficientResources;
-        break;
-    default:
-        free(thread);
-        *threadHandle = NULL;
-        ret = OMX_ErrorUndefined;
-        break;
-    }
-
-EXIT:
-    FunctionOut();
-
-    return ret;
-}
-
-void ThreadExit(void *value_ptr)
-{
-    pthread_exit(value_ptr);
-    return;
-}
-
 void CodaJ12FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPortNumber)
 {
     SF_CODAJ12_IMPLEMEMT *pSfCodaj12Implement = pSfOMXComponent->componentImpl;
@@ -619,26 +602,23 @@ void CodaJ12FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPortNumber)
             }
 
             pOMXBuffer = data.pBuffer;
-            LOG(SF_LOG_INFO, "Flush Buffer %p\r\n", pOMXBuffer);
+            LOG(SF_LOG_INFO, "get header %p from in q\r\n", pOMXBuffer);
             if (pOMXBuffer != NULL)
             {
                 pOMXBuffer->nFilledLen = 0;
                 pOMXBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+                LOG(SF_LOG_INFO, "Flush input Buffer header %p pBuffer %p\r\n", pOMXBuffer, pOMXBuffer->pBuffer);
                 pSfOMXComponent->callbacks->EmptyBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+                pSfOMXComponent->handlingBufferNum[OMX_INPUT_PORT_INDEX]--;
+                if((pSfOMXComponent->handlingBufferNum[OMX_INPUT_PORT_INDEX] == 0) && pSfOMXComponent->bPortFlushing[OMX_INPUT_PORT_INDEX])
+                {
+                    LOG(SF_LOG_INFO, "return all input buff\r\n");
+                    SF_SemaphorePost(pSfOMXComponent->portFlushSemaphore[OMX_INPUT_PORT_INDEX]);
+                }
             }
         }
         break;
     case OMX_OUTPUT_PORT_INDEX:
-        for(int i = 0; i < MCA_MAX_INDEX; i++){
-            pOMXBuffer = pSfCodaj12Implement->mesCacheArr[i].pBuffer;
-            LOG(SF_LOG_INFO, "Flush Buffer %p\r\n", pOMXBuffer);
-            if (pOMXBuffer != NULL)
-            {
-                pOMXBuffer->nFilledLen = 0;
-                pOMXBuffer->nFlags = OMX_BUFFERFLAG_EOS;
-                pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
-            }
-        }
         while (OMX_TRUE)
         {
             if (msgrcv(pSfCodaj12Implement->sOutputMessageQueue, (void *)&data, BUFSIZ, 0, IPC_NOWAIT) < 0)
@@ -648,12 +628,19 @@ void CodaJ12FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPortNumber)
             }
 
             pOMXBuffer = data.pBuffer;
-            LOG(SF_LOG_INFO, "Flush Buffer %p\r\n", pOMXBuffer);
+            LOG(SF_LOG_INFO, "get header %p from out q\r\n", pOMXBuffer);
             if (pOMXBuffer != NULL)
             {
                 pOMXBuffer->nFilledLen = 0;
                 pOMXBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+                LOG(SF_LOG_INFO, "Flush output Buffer header %p pBuffer %p\r\n", pOMXBuffer, pOMXBuffer->pBuffer);
                 pSfOMXComponent->callbacks->FillBufferDone(pSfOMXComponent->pOMXComponent, pSfOMXComponent->pAppData, pOMXBuffer);
+                pSfOMXComponent->handlingBufferNum[OMX_OUTPUT_PORT_INDEX]--;
+                if((pSfOMXComponent->handlingBufferNum[OMX_OUTPUT_PORT_INDEX] == 0) && pSfOMXComponent->bPortFlushing[OMX_OUTPUT_PORT_INDEX])
+                {
+                    LOG(SF_LOG_INFO, "return all output buff\r\n");
+                    SF_SemaphorePost(pSfOMXComponent->portFlushSemaphore[OMX_OUTPUT_PORT_INDEX]);
+                }
             }
         }
         break;

+ 21 - 12
omx-il/component/image/common/SF_OMX_mjpeg_common.h

@@ -10,6 +10,9 @@
 #include "OMX_Index.h"
 #include "OMX_IndexExt.h"
 #include "SF_OMX_Core.h"
+#include "sf_queue.h"
+#include "sf_thread.h"
+#include "sf_semaphore.h"
 #include "codaj12/jpuapi/jpuapi.h"
 #include "codaj12/jpuapi/jpuapifunc.h"
 #include "codaj12/sample/main_helper.h"
@@ -53,6 +56,7 @@ typedef struct _SF_CODAJ12_FUNCTIONS
     JpgRet (*JPU_DecRegisterFrameBuffer)(JpgDecHandle handle, FrameBuffer * bufArray, int num, int stride);
     JpgRet (*JPU_DecGiveCommand)(JpgDecHandle handle, JpgCommand cmd, void *param);
     JpgRet (*JPU_DecStartOneFrameBySerialNum)(JpgDecHandle handle, JpgDecParam *param,int bufferIndex);
+    JpgRet (*JPU_DecStartOneFrame)(JpgDecHandle handle, JpgDecParam *param);
     JpgRet (*JPU_DecGetOutputInfo)(JpgDecHandle handle, JpgDecOutputInfo *info);
     JpgRet (*JPU_SWReset)(JpgHandle handle);
     JpgRet (*JPU_DecSetRdPtrEx)(JpgDecHandle handle, PhysicalAddress addr, BOOL updateWrPtr);
@@ -76,27 +80,25 @@ typedef struct _SF_CODAJ12_FUNCTIONS
     // (Uint32 instIdx, Uint32 size, Uint32 *bufferIndex);
     (Uint32 instIdx, FrameFormat subsample, CbCrInterLeave cbcrIntlv,
      PackedFormat packed, Uint32 rotation, BOOL scalerOn, Uint32 width, Uint32 height, Uint32 bitDepth, Uint32 *bufferIndex);
+    int (*SaveYuvImageHelper)(Uint8* pYuv, FrameBuffer* fb, CbCrInterLeave interLeave, PackedFormat packed,
+                        Uint32 picWidth, Uint32 picHeight, Uint32 bitDepth);
+    int (*SaveYuvImageHelperDma)(Uint8* pYuv, FrameBuffer* fb, CbCrInterLeave interLeave, PackedFormat packed,
+                        Uint32 picWidth, Uint32 picHeight, Uint32 bitDepth);
+    int (*FreeOneFrameBuffer)(Uint32 instIdx, void* virt_addr);
     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);
-    int (*SaveYuvImageHelper)(Uint8* pYuv, FrameBuffer* fb, CbCrInterLeave interLeave, PackedFormat packed,
-                        Uint32 picWidth, Uint32 picHeight, Uint32 bitDepth);
+    BOOL (*AllocateFrameBuffer)(Uint32 instIdx, FrameFormat subsample, CbCrInterLeave cbcrIntlv, PackedFormat packed,
+                         Uint32 rotation, BOOL scalerOn, Uint32 width, Uint32 height, Uint32 bitDepth, Uint32 num);
     BOOL (*UpdateFrameBuffers)(Uint32 instIdx, Uint32 num, FRAME_BUF *frameBuf);
 
     // JPU Log
     void (*SetMaxLogLevel)(int level);
 } SF_CODAJ12_FUNCTIONS;
 
-typedef struct _THREAD_HANDLE_TYPE {
-    pthread_t          pthread;
-    pthread_attr_t     attr;
-    struct sched_param schedparam;
-    int                stack_size;
-} THREAD_HANDLE_TYPE;
-
 typedef struct Message
 {
     long msg_type;
@@ -119,12 +121,20 @@ typedef struct _SF_CODAJ12_IMPLEMEMT
     OMX_S32 sInputMessageQueue;
     OMX_S32 sOutputMessageQueue;
     OMX_S32 sBufferDoneQueue;
-    Message mesCacheArr[MCA_MAX_INDEX];
-    OMX_HANDLETYPE pProcessThread;
+    THREAD_HANDLE_TYPE *pProcessThread;
     OMX_BOOL bThreadRunning;
     OMX_STATETYPE currentState;
     FrameFormat frameFormat;
     OMX_BOOL allocBufFlag;
+    OMX_BOOL gotEos;
+    SF_Queue *CmdQueue;
+    SF_Queue *inPauseQ;
+    SF_Queue *outPauseQ;
+
+    OMX_HANDLETYPE pauseOutSemaphore;
+    THREAD_HANDLE_TYPE *pCmdThread;
+    OMX_BOOL bCmdRunning;
+    OMX_BOOL bPause;
 } SF_CODAJ12_IMPLEMEMT;
 
 enum port_index
@@ -143,7 +153,6 @@ OMX_ERRORTYPE GetStateMjpegCommon(OMX_IN OMX_HANDLETYPE hComponent, OMX_OUT OMX_
 OMX_ERRORTYPE InitMjpegStructorCommon(SF_OMX_COMPONENT *hComponent);
 OMX_BOOL AttachOutputBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U8* pBuffer, OMX_U32 nSizeBytes);
 OMX_U8* AllocateOutputBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nSizeBytes);
-OMX_ERRORTYPE CreateThread(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument);
 void ThreadExit(void *value_ptr);
 void CodaJ12FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPortNumber);
 

File diff suppressed because it is too large
+ 490 - 190
omx-il/component/image/dec/SF_OMX_Mjpeg_decoder.c


File diff suppressed because it is too large
+ 586 - 146
omx-il/component/video/wave4/SF_OMX_Wave420L_encoder.c


+ 9 - 9
omx-il/component/video/wave4/SF_OMX_Wave420L_encoder.h

@@ -18,6 +18,8 @@
 #include <errno.h>
 
 #include "sf_queue.h"
+#include "sf_thread.h"
+#include "sf_semaphore.h"
 #include "wave420l/sample/helper/main_helper.h"
 #include "wave420l/vpuapi/vpuapi.h"
 
@@ -35,8 +37,8 @@
 
 #define NUM_OF_PORTS 2
 
-#define DEFAULT_FRAME_WIDTH 3840
-#define DEFAULT_FRAME_HEIGHT 2160
+#define DEFAULT_FRAME_WIDTH 1920
+#define DEFAULT_FRAME_HEIGHT 1080
 #define DEFAULT_MJPEG_INPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3)
 #define DEFAULT_MJPEG_OUTPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3)
 #define DEFAULT_FRAMERATE 30
@@ -93,13 +95,6 @@ typedef struct _SF_W420L_FUNCTIONS
     void (*PrintVpuStatus)(Uint32 coreIdx, Uint32 productId);
 }SF_W420L_FUNCTIONS;
 
-typedef struct _THREAD_HANDLE_TYPE
-{
-    pthread_t          pthread;
-    pthread_attr_t     attr;
-    struct sched_param schedparam;
-    int                stack_size;
-} THREAD_HANDLE_TYPE;
 
 typedef struct Message
 {
@@ -140,15 +135,20 @@ typedef struct _SF_WAVE420L_IMPLEMEMT
     EncOutputInfo       outputInfo;
     Int32               instIdx;
     Int32               coreIdx;
+    Uint32              tmpFramerate;
+    Uint64              tmpCounter;
     SF_Queue            *EmptyQueue;
     SF_Queue            *FillQueue;
     SF_Queue            *CmdQueue;
+    SF_Queue            *pauseQ;
+    OMX_HANDLETYPE      pauseSemaphore;
     OMX_VIDEO_PARAM_HEVCTYPE HEVCComponent[2];
 
     THREAD_HANDLE_TYPE *pProcessThread;
     THREAD_HANDLE_TYPE *pCmdThread;
     OMX_BOOL bThreadRunning;
     OMX_BOOL bCmdRunning;
+    OMX_BOOL bPause;
     OMX_STATETYPE currentState;
 } SF_WAVE420L_IMPLEMEMT;
 

+ 78 - 30
omx-il/component/video/wave5/common/SF_OMX_video_common.c

@@ -13,7 +13,7 @@ OMX_ERRORTYPE GetStateCommon(OMX_IN OMX_HANDLETYPE hComponent, OMX_OUT OMX_STATE
     OMX_COMPONENTTYPE *pOMXComponent = NULL;
     SF_OMX_COMPONENT *pSfOMXComponent = NULL;
     ComponentState state;
-    OMX_STATETYPE nextState;
+    OMX_STATETYPE comState;
     SF_WAVE5_IMPLEMEMT *pSfVideoImplement = NULL;
     FunctionIn();
     if (hComponent == NULL)
@@ -24,14 +24,19 @@ OMX_ERRORTYPE GetStateCommon(OMX_IN OMX_HANDLETYPE hComponent, OMX_OUT OMX_STATE
     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
     pSfOMXComponent = pOMXComponent->pComponentPrivate;
     pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
-    nextState = pSfOMXComponent->nextState;
+    comState = pSfOMXComponent->state;
     state = pSfVideoImplement->functions->ComponentGetState(pSfVideoImplement->hSFComponentExecoder);
     LOG(SF_LOG_INFO, "state = %d\r\n", state);
 
     switch (state)
     {
     case COMPONENT_STATE_CREATED:
-        *pState = OMX_StateIdle;
+        if (comState == OMX_StateLoaded)
+        {
+            *pState = OMX_StateLoaded;
+        }else{
+            *pState = OMX_StateIdle;
+        }
         break;
     case COMPONENT_STATE_NONE:
     case COMPONENT_STATE_TERMINATED:
@@ -39,9 +44,9 @@ OMX_ERRORTYPE GetStateCommon(OMX_IN OMX_HANDLETYPE hComponent, OMX_OUT OMX_STATE
         break;
     case COMPONENT_STATE_PREPARED:
     case COMPONENT_STATE_EXECUTED:
-        if (nextState == OMX_StateIdle || nextState == OMX_StateExecuting || nextState == OMX_StatePause)
+        if (comState == OMX_StateIdle || comState == OMX_StateExecuting || comState == OMX_StatePause)
         {
-            *pState = nextState;
+            *pState = comState;
         }
         break;
     default:
@@ -58,8 +63,12 @@ OMX_ERRORTYPE ComponentClearCommon(SF_OMX_COMPONENT *pSfOMXComponent)
 {
     SF_WAVE5_IMPLEMEMT *pSfVideoImplement = (SF_WAVE5_IMPLEMEMT *)pSfOMXComponent->componentImpl;
 
+    pSfVideoImplement->functions->ComponentRelease(pSfVideoImplement->hSFComponentFeeder);
     pSfVideoImplement->functions->ComponentRelease(pSfVideoImplement->hSFComponentExecoder);
+    pSfVideoImplement->functions->ComponentRelease(pSfVideoImplement->hSFComponentRender);
+    pSfVideoImplement->functions->ComponentDestroy(pSfVideoImplement->hSFComponentFeeder, NULL);
     pSfVideoImplement->functions->ComponentDestroy(pSfVideoImplement->hSFComponentExecoder, NULL);
+    pSfVideoImplement->functions->ComponentDestroy(pSfVideoImplement->hSFComponentRender, NULL);
     pSfVideoImplement->functions->DeInitLog();
     dlclose(pSfOMXComponent->soHandle);
     free(pSfVideoImplement->functions);
@@ -306,6 +315,7 @@ OMX_ERRORTYPE InitComponentStructorCommon(SF_OMX_COMPONENT *pSfOMXComponent)
         pHEVCComponent->nPortIndex = i;
         pHEVCComponent->nKeyFrameInterval = 30;
         pHEVCComponent->eProfile = OMX_VIDEO_HEVCProfileMain;
+        pSfOMXComponent->assignedBufferNum[i] = 0;
     }
 
     pSfOMXComponent->portDefinition[0].eDir = OMX_DirInput;
@@ -320,13 +330,43 @@ OMX_ERRORTYPE InitComponentStructorCommon(SF_OMX_COMPONENT *pSfOMXComponent)
     pSfOMXComponent->portDefinition[1].nBufferCountActual = VPU_OUTPUT_BUF_NUMBER;
     pSfOMXComponent->portDefinition[1].nBufferCountMin = VPU_OUTPUT_BUF_NUMBER;
 
+    /* Set componentVersion */
+    pSfOMXComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pSfOMXComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pSfOMXComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
+    pSfOMXComponent->componentVersion.s.nStep         = STEP_NUMBER;
+    /* Set specVersion */
+    pSfOMXComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
+    pSfOMXComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
+    pSfOMXComponent->specVersion.s.nRevision     = REVISION_NUMBER;
+    pSfOMXComponent->specVersion.s.nStep         = STEP_NUMBER;
+    /* Input port */
+
     memset(pSfOMXComponent->pBufferArray, 0, sizeof(pSfOMXComponent->pBufferArray));
-    pSfOMXComponent->memory_optimization = OMX_TRUE;
+
+    memset(pSfOMXComponent->markType, 0, sizeof(pSfOMXComponent->markType));
+    pSfOMXComponent->propagateMarkType.hMarkTargetComponent = NULL;
+    pSfOMXComponent->propagateMarkType.pMarkData = NULL;
+
+    for (int i = 0; i < 2; i++)
+    {
+        ret = SF_SemaphoreCreate(&pSfOMXComponent->portSemaphore[i]);
+        if (ret)
+            goto ERROR;
+        ret = SF_SemaphoreCreate(&pSfOMXComponent->portUnloadSemaphore[i]);
+        if (ret)
+            goto ERROR;
+    }
 
     FunctionOut();
 EXIT:
     return ret;
 ERROR:
+    for (int i = 0; i < 2; i++)
+    {
+        SF_SemaphoreTerminate(pSfOMXComponent->portSemaphore[i]);
+        SF_SemaphoreTerminate(pSfOMXComponent->portUnloadSemaphore[i]);
+    }
     if (pSfOMXComponent->pOMXComponent)
     {
         free(pSfOMXComponent->pOMXComponent);
@@ -368,20 +408,23 @@ OMX_ERRORTYPE FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPort)
     if (nPort == 0)
     {
         ComponentImpl *pFeederComponent = (ComponentImpl *)(pSfVideoImplement->hSFComponentFeeder);
-        OMX_U32 inputQueueCount = pSfVideoImplement->functions->Queue_Get_Cnt(pFeederComponent->srcPort.inputQ);
-        LOG(SF_LOG_PERF, "Flush %d buffers on inputPort\r\n", inputQueueCount);
-        if (inputQueueCount > 0)
+        if (pFeederComponent)
         {
-            PortContainerExternal *input = NULL;
-            while ((input = (PortContainerExternal*)pSfVideoImplement->functions->ComponentPortGetData(&pFeederComponent->srcPort)) != NULL)
+            OMX_U32 inputQueueCount = pSfVideoImplement->functions->Queue_Get_Cnt(pFeederComponent->srcPort.inputQ);
+            LOG(SF_LOG_PERF, "Flush %d buffers on inputPort\r\n", inputQueueCount);
+            if (inputQueueCount > 0)
             {
-                if (strstr(pSfOMXComponent->componentName, "OMX.sf.video_decoder") != NULL)
+                PortContainerExternal *input = NULL;
+                while ((input = (PortContainerExternal*)pSfVideoImplement->functions->ComponentPortGetData(&pFeederComponent->srcPort)) != NULL)
                 {
-                    pSfVideoImplement->functions->ComponentNotifyListeners(pFeederComponent, COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE, (void *)input);
-                }
-                else if (strstr(pSfOMXComponent->componentName, "OMX.sf.video_encoder") != NULL)
-                {
-                    pSfVideoImplement->functions->ComponentNotifyListeners(pFeederComponent, COMPONENT_EVENT_ENC_EMPTY_BUFFER_DONE, (void *)input);
+                    if (strstr(pSfOMXComponent->componentName, "sf.video_decoder") != NULL)
+                    {
+                        pSfVideoImplement->functions->ComponentNotifyListeners(pFeederComponent, COMPONENT_EVENT_DEC_EMPTY_BUFFER_DONE, (void *)input);
+                    }
+                    else if (strstr(pSfOMXComponent->componentName, "sf.video_encoder") != NULL)
+                    {
+                        pSfVideoImplement->functions->ComponentNotifyListeners(pFeederComponent, COMPONENT_EVENT_ENC_EMPTY_BUFFER_DONE, (void *)input);
+                    }
                 }
             }
         }
@@ -389,22 +432,25 @@ OMX_ERRORTYPE FlushBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U32 nPort)
     else if (nPort == 1)
     {
         ComponentImpl *pRendererComponent = (ComponentImpl *)(pSfVideoImplement->hSFComponentRender);
-        OMX_U32 OutputQueueCount = pSfVideoImplement->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ);
-        LOG(SF_LOG_PERF, "Flush %d buffers on outputPort\r\n", OutputQueueCount);
-        if (OutputQueueCount > 0)
+        if (pRendererComponent)
         {
-            PortContainerExternal *output = NULL;
-            while ((output = (PortContainerExternal*)pSfVideoImplement->functions->ComponentPortGetData(&pRendererComponent->sinkPort)) != NULL)
+            OMX_U32 OutputQueueCount = pSfVideoImplement->functions->Queue_Get_Cnt(pRendererComponent->sinkPort.inputQ);
+            LOG(SF_LOG_PERF, "Flush %d buffers on outputPort\r\n", OutputQueueCount);
+            if (OutputQueueCount > 0)
             {
-                output->nFlags = 0x1;
-                output->nFilledLen = 0;
-                if (strstr(pSfOMXComponent->componentName, "OMX.sf.video_decoder") != NULL)
-                {
-                    pSfVideoImplement->functions->ComponentNotifyListeners(pRendererComponent, COMPONENT_EVENT_DEC_FILL_BUFFER_DONE, (void *)output);
-                }
-                else if (strstr(pSfOMXComponent->componentName, "OMX.sf.video_encoder") != NULL)
+                PortContainerExternal *output = NULL;
+                while ((output = (PortContainerExternal*)pSfVideoImplement->functions->ComponentPortGetData(&pRendererComponent->sinkPort)) != NULL)
                 {
-                    pSfVideoImplement->functions->ComponentNotifyListeners(pRendererComponent, COMPONENT_EVENT_ENC_FILL_BUFFER_DONE, (void *)output);
+                    output->nFlags = 0x1;
+                    output->nFilledLen = 0;
+                    if (strstr(pSfOMXComponent->componentName, "sf.video_decoder") != NULL)
+                    {
+                        pSfVideoImplement->functions->ComponentNotifyListeners(pRendererComponent, COMPONENT_EVENT_DEC_FILL_BUFFER_DONE, (void *)output);
+                    }
+                    else if (strstr(pSfOMXComponent->componentName, "sf.video_encoder") != NULL)
+                    {
+                        pSfVideoImplement->functions->ComponentNotifyListeners(pRendererComponent, COMPONENT_EVENT_ENC_FILL_BUFFER_DONE, (void *)output);
+                    }
                 }
             }
         }
@@ -478,8 +524,10 @@ 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->GetRenderTotalBufferNumber = dlsym(sohandle, "GetRenderTotalBufferNumber");
     funcs->SetFeederTotalBufferNumber = dlsym(sohandle, "SetFeederTotalBufferNumber");
     funcs->WaitForExecoderReady = dlsym(sohandle, "WaitForExecoderReady");
+    funcs->RemapDMABuffer = dlsym(sohandle, "RemapDMABuffer");
     FunctionOut();
 }
 

+ 16 - 0
omx-il/component/video/wave5/common/SF_OMX_video_common.h

@@ -11,6 +11,9 @@
 #include "OMX_Index.h"
 #include "OMX_IndexExt.h"
 #include "SF_OMX_Core.h"
+#include "sf_queue.h"
+#include "sf_thread.h"
+#include "sf_semaphore.h"
 #include "wave511/sample_v2/component/component.h"
 #include "wave511/sample_v2/component_encoder/encoder_listener.h"
 #include "wave511/sample_v2/component_decoder/decoder_listener.h"
@@ -30,6 +33,7 @@
 #define DEFAULT_FRAME_HEIGHT 2160
 #define DEFAULT_VIDEO_INPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT) / 2
 #define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3) / 2
+#define MAX_INDEX 1
 
 typedef struct _SF_COMPONENT_FUNCTIONS
 {
@@ -94,8 +98,10 @@ 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);
+    Uint32 (*GetRenderTotalBufferNumber)(ComponentImpl* com);
     void (*SetFeederTotalBufferNumber)(ComponentImpl* com, Uint32 number);
     void (*WaitForExecoderReady)(ComponentImpl *com);
+    Uint64 (*RemapDMABuffer)(ComponentImpl* com, Uint64 virtAddress, Uint32 size);
 } SF_COMPONENT_FUNCTIONS;
 
 typedef struct _SF_WAVE5_IMPLEMEMT
@@ -109,6 +115,16 @@ typedef struct _SF_WAVE5_IMPLEMEMT
     void *lsnCtx;
     Uint16 *pusBitCode;
     CodStd bitFormat;
+    OMX_BOOL rev_eos;
+    SF_Queue *CmdQueue;
+    SF_Queue *inPauseQ;
+    SF_Queue *outPauseQ;
+    SF_Queue *inPortQ;
+    SF_Queue *outPortQ;
+    THREAD_HANDLE_TYPE *pCmdThread;
+    OMX_BOOL bCmdRunning;
+    OMX_U64 frame_array[MAX_INDEX];
+    OMX_U32 frame_array_index;
     OMX_VIDEO_PARAM_AVCTYPE AVCComponent[2];
     OMX_VIDEO_PARAM_HEVCTYPE HEVCComponent[2];
 }SF_WAVE5_IMPLEMEMT;

File diff suppressed because it is too large
+ 541 - 229
omx-il/component/video/wave5/dec/SF_OMX_Vdec_decoder.c


+ 3 - 3
omx-il/component/video/wave5/enc/SF_OMX_Venc_encoder.c

@@ -499,7 +499,7 @@ static OMX_ERRORTYPE SF_OMX_GetParameter(
         // ret = OMX_ErrorNotImplemented;
         break;
     default:
-
+        ret = OMX_ErrorUnsupportedIndex;
         break;
     }
 
@@ -720,7 +720,7 @@ static OMX_ERRORTYPE SF_OMX_SetParameter(
     case OMX_IndexParamVideoQuantization:
     case OMX_IndexParamVideoIntraRefresh:
     default:
-
+        ret = OMX_ErrorUnsupportedIndex;
         break;
     }
 
@@ -965,7 +965,7 @@ static OMX_ERRORTYPE SF_OMX_SendCommand(
     switch (Cmd)
     {
     case OMX_CommandStateSet:
-        pSfOMXComponent->nextState = nParam;
+        pSfOMXComponent->state = nParam;
         LOG(SF_LOG_INFO, "OMX dest state = %X\r\n", nParam);
         switch (nParam)
         {

+ 37 - 76
omx-il/core/SF_OMX_Core.c

@@ -122,22 +122,39 @@ OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
 
     for (i = 0; i < SF_OMX_COMPONENT_NUM; i++)
     {
-        pSf_omx_component = sf_omx_component_list[i];
-        if (pSf_omx_component == NULL)
+        if (sf_omx_component_list[i] == NULL)
         {
             ret = OMX_ErrorBadParameter;
             goto EXIT;
         }
-        if (strcmp(cComponentName, pSf_omx_component->componentName) == 0)
+        if (strncmp(cComponentName, sf_omx_component_list[i]->componentName, strlen(sf_omx_component_list[i]->componentName)) == 0)
         {
+            pSf_omx_component = malloc(sizeof(SF_OMX_COMPONENT));
+            if (!pSf_omx_component)
+            {
+                goto EXIT;
+            }
+            memcpy(pSf_omx_component, sf_omx_component_list[i], sizeof(SF_OMX_COMPONENT));
+
+            if (strstr(cComponentName, "internal") != NULL)
+            {
+                pSf_omx_component->memory_optimization = OMX_TRUE;
+            }
+            else
+            {
+                pSf_omx_component->memory_optimization = OMX_FALSE;
+            }
+
             ret = pSf_omx_component->SF_OMX_ComponentConstructor(pSf_omx_component);
             if (ret != OMX_ErrorNone)
             {
+                free(pSf_omx_component);
                 goto EXIT;
             }
             *pHandle = pSf_omx_component->pOMXComponent;
             pSf_omx_component->callbacks = pCallBacks;
             pSf_omx_component->pAppData = pAppData;
+            pSf_omx_component->state = OMX_StateLoaded;
             break;
         }
     }
@@ -153,6 +170,10 @@ OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hCompone
     SF_OMX_COMPONENT *pSfOMXComponent = (SF_OMX_COMPONENT *)pOMXComponent->pComponentPrivate;
     FunctionIn();
     ret = pSfOMXComponent->SF_OMX_ComponentClear(pSfOMXComponent);
+    if (!ret)
+    {
+        free(pSfOMXComponent);
+    }
 
     FunctionOut();
     return ret;
@@ -223,88 +244,28 @@ OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent(
     OMX_ERRORTYPE ret = OMX_ErrorNone;
     FunctionIn();
 
-    FunctionOut();
-    return ret;
-}
-
-OMX_ERRORTYPE ClearOMXBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer)
-{
-    OMX_U32 i = 0;
-    for (i = 0; i < sizeof(pSfOMXComponent->pBufferArray) / sizeof(pSfOMXComponent->pBufferArray[0]); i++)
-    {
-        if (pSfOMXComponent->pBufferArray[i] == pBuffer)
-        {
-            pSfOMXComponent->pBufferArray[i] = NULL;
-            LOG(SF_LOG_DEBUG, "Clear OMX buffer %p at index %d\r\n", pBuffer, i);
-            return OMX_ErrorNone;
-        }
-    }
-    if (i == sizeof(pSfOMXComponent->pBufferArray) / sizeof(pSfOMXComponent->pBufferArray[0]))
-    {
-        LOG(SF_LOG_ERR, "Could Not found omx buffer!\r\n");
-    }
-    return OMX_ErrorBadParameter;
-}
-
-OMX_U32 GetOMXBufferCount(SF_OMX_COMPONENT *pSfOMXComponent)
-{
-    OMX_U32 i = 0;
-    OMX_U32 count = 0;
-    for (i = 0; i < sizeof(pSfOMXComponent->pBufferArray) / sizeof(pSfOMXComponent->pBufferArray[0]); i++)
-    {
-        if (pSfOMXComponent->pBufferArray[i] != NULL)
-        {
-            LOG(SF_LOG_DEBUG, "find OMX buffer %p at index %d\r\n", pSfOMXComponent->pBufferArray[i], i);
-            count++;
-        }
-    }
-
-    return count;
-}
-
-OMX_ERRORTYPE StoreOMXBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer)
-{
-    OMX_U32 i = 0;
-    for (i = 0; i < sizeof(pSfOMXComponent->pBufferArray) / sizeof(pSfOMXComponent->pBufferArray[0]); i++)
-    {
-        if (pSfOMXComponent->pBufferArray[i] == NULL)
-        {
-            pSfOMXComponent->pBufferArray[i] = pBuffer;
-            LOG(SF_LOG_DEBUG, "Store OMX buffer %p at index %d\r\n", pBuffer, i);
-            return OMX_ErrorNone;
-        }
-    }
-    if (i == sizeof(pSfOMXComponent->pBufferArray))
-    {
-        LOG(SF_LOG_ERR, "Buffer arrary full!\r\n");
-    }
-    return OMX_ErrorInsufficientResources;
-}
-
-OMX_BUFFERHEADERTYPE *GetOMXBufferByAddr(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U8 *pAddr)
-{
-    OMX_U32 i = 0;
-    OMX_BUFFERHEADERTYPE *pOMXBuffer;
-    FunctionIn();
-    LOG(SF_LOG_INFO, "ADDR=%p\r\n", pAddr);
-    for (i = 0; i < sizeof(pSfOMXComponent->pBufferArray) / sizeof(pSfOMXComponent->pBufferArray[0]); i++)
+#if 0 //todo
+    for (int i = 0; i < SF_OMX_COMPONENT_NUM; i ++)
     {
-        pOMXBuffer = pSfOMXComponent->pBufferArray[i];
-        LOG(SF_LOG_DEBUG, "Compare OMX buffer %p at index %d with addr %p\r\n", pOMXBuffer, i, pAddr);
-        if (pOMXBuffer == NULL)
+        if (sf_omx_component_list[i] == NULL)
         {
-            continue;
+            break;
         }
-        if (pOMXBuffer->pBuffer == pAddr)
+        if (strcmp(sf_omx_component_list[i]->componentName, compName) == 0)
         {
-            return pOMXBuffer;
+            *pNumRoles = 1;
+            if (roles != NULL) {
+                strcpy((OMX_STRING)roles[0], sf_omx_component_list[i]->componentRule);
+            }
+            LOG(SF_LOG_INFO,"Get component %s, Role = %s\r\n", sf_omx_component_list[i]->componentName, sf_omx_component_list[i]->componentRule)
         }
     }
-    LOG(SF_LOG_ERR, "could not find buffer!\r\n");
+#endif
 
     FunctionOut();
-    return NULL;
+    return ret;
 }
+
 void SF_LogMsgAppend(int level, const char *format, ...)
 {
     va_list ptr;

+ 39 - 8
omx-il/core/SF_OMX_Core.h

@@ -36,12 +36,19 @@ void SF_LogMsgAppend(int level, const char *format, ...);
 #define FunctionIn()
 #define FunctionOut()
 #endif
-#define VPU_OUTPUT_BUF_NUMBER 7
-#define VPU_INPUT_BUF_NUMBER 3
+#define VPU_OUTPUT_BUF_NUMBER              12
+#define VPU_INPUT_BUF_NUMBER               5
+#define MAX_BUFF_NUM                       32
+
+#define VERSIONMAJOR_NUMBER                1
+#define VERSIONMINOR_NUMBER                0
+#define REVISION_NUMBER                    0
+#define STEP_NUMBER                        0
 
 typedef enum SF_BUFFER_TYPE
 {
     SF_BUFFER_NOMAL = 0,
+    SF_BUFFER_NOMAL_EXTERNAL,
     SF_BUFFER_DMA,
     SF_BUFFER_DMA_EXTERNAL,
     SF_BUFFER_DMA_FD,
@@ -49,17 +56,35 @@ typedef enum SF_BUFFER_TYPE
     SF_BUFFER_ALL,
 }SF_BUFFER_TYPE;
 
+/** This enum defines the transition states of the Component*/
+typedef enum OMX_TRANS_STATETYPE {
+    OMX_TransStateInvalid,
+    OMX_TransStateLoadedToIdle,
+    OMX_TransStateIdleToPause,
+    OMX_TransStatePauseToExecuting,
+    OMX_TransStateIdleToExecuting,
+    OMX_TransStateExecutingToIdle,
+    OMX_TransStateExecutingToPause,
+    OMX_TransStatePauseToIdle,
+    OMX_TransStateIdleToLoaded,
+    OMX_TransStateMax = 0X7FFFFFFF
+} OMX_TRANS_STATETYPE;
+
 typedef struct _SF_OMX_BUF_INFO
 {
     SF_BUFFER_TYPE type;
+    OMX_PTR remap_vaddr;
     OMX_U64 PhysicalAddress;
     OMX_S32 fd;
+    OMX_U32 index;
 }SF_OMX_BUF_INFO;
 
 typedef struct _SF_OMX_COMPONENT
 {
     OMX_STRING componentName;
     OMX_STRING libName;
+    OMX_VERSIONTYPE componentVersion;
+    OMX_VERSIONTYPE specVersion;
     OMX_COMPONENTTYPE *pOMXComponent;
     OMX_ERRORTYPE (*SF_OMX_ComponentConstructor)(struct _SF_OMX_COMPONENT *hComponent);
     OMX_ERRORTYPE (*SF_OMX_ComponentClear)(struct _SF_OMX_COMPONENT *hComponent);
@@ -82,11 +107,21 @@ typedef struct _SF_OMX_COMPONENT
     OMX_CALLBACKTYPE *callbacks;
     OMX_PTR pAppData;
     OMX_PARAM_PORTDEFINITIONTYPE portDefinition[2];
-    OMX_BUFFERHEADERTYPE *pBufferArray[64];
+    OMX_HANDLETYPE portSemaphore[2];
+    OMX_HANDLETYPE portUnloadSemaphore[2];
+    OMX_HANDLETYPE portFlushSemaphore[2];
+    OMX_BUFFERHEADERTYPE *pBufferArray[2][MAX_BUFF_NUM];
+    OMX_U32 assignedBufferNum[2];
+    OMX_U32 handlingBufferNum[2];
     OMX_STRING fwPath;
     OMX_STRING componentRule;
-    OMX_STATETYPE nextState;
+    OMX_STATETYPE state;
+    OMX_STATETYPE stateBeforePause;
+    OMX_TRANS_STATETYPE traningState;
+    OMX_MARKTYPE markType[2];
+    OMX_MARKTYPE propagateMarkType;
     OMX_BOOL memory_optimization;
+    OMX_BOOL bPortFlushing[2];
 } SF_OMX_COMPONENT;
 
 typedef struct _SF_PORT_PRIVATE
@@ -118,10 +153,6 @@ extern "C"
 #endif
 
 int GetNumberOfComponent();
-OMX_BUFFERHEADERTYPE *GetOMXBufferByAddr(SF_OMX_COMPONENT *pSfOMXComponent, OMX_U8 *pAddr);
-OMX_ERRORTYPE StoreOMXBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer);
-OMX_ERRORTYPE ClearOMXBuffer(SF_OMX_COMPONENT *pSfOMXComponent, OMX_BUFFERHEADERTYPE *pBuffer);
-OMX_U32 GetOMXBufferCount(SF_OMX_COMPONENT *pSfOMXComponent);
 
 #ifdef __cplusplus
 }

+ 61 - 0
omx-il/include/khronos/OMX_ComponentExt.h

@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_ComponentExt.h - OpenMax IL version 1.1.2
+ * The OMX_ComponentExt header file contains extensions to the definitions used
+ * by both the application and the component to access common items.
+ */
+
+#ifndef OMX_ComponentExt_h
+#define OMX_ComponentExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header must include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully 
+ */
+#include <OMX_Types.h>
+
+
+/** Set/query the commit mode */
+typedef struct OMX_CONFIG_COMMITMODETYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_BOOL bDeferred;
+} OMX_CONFIG_COMMITMODETYPE;
+
+/** Explicit commit */
+typedef struct OMX_CONFIG_COMMITTYPE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+} OMX_CONFIG_COMMITTYPE;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_ComponentExt_h */

+ 73 - 0
omx-il/include/khronos/OMX_CoreExt.h

@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_CoreExt.h - OpenMax IL version 1.1.2
+ * The OMX_CoreExt header file contains extensions to the definitions used
+ * by both the application and the component to access common items.
+ */
+
+#ifndef OMX_CoreExt_h
+#define OMX_CoreExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Core.h>
+
+/** Extensions to the standard IL errors. */ 
+typedef enum OMX_ERROREXTTYPE 
+{
+    OMX_ErrorInvalidMode = (OMX_S32) (OMX_ErrorKhronosExtensions + 0x00000001),
+    OMX_ErrorExtMax = 0x7FFFFFFF
+} OMX_ERROREXTTYPE;
+
+
+/** Event type extensions. */
+typedef enum OMX_EVENTEXTTYPE
+{
+    OMX_EventIndexSettingChanged = OMX_EventKhronosExtensions, /**< component signals the IL client of a change
+                                                                    in a param, config, or extension */
+    OMX_EventExtMax = 0x7FFFFFFF
+} OMX_EVENTEXTTYPE;
+
+
+/** Enable or disable a callback event. */
+typedef struct OMX_CONFIG_CALLBACKREQUESTTYPE {
+    OMX_U32 nSize;              /**< size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;   /**< OMX specification version information */
+    OMX_U32 nPortIndex;         /**< port that this structure applies to */
+    OMX_INDEXTYPE nIndex;       /**< the index the callback is requested for */
+    OMX_BOOL bEnable;           /**< enable (OMX_TRUE) or disable (OMX_FALSE) the callback */
+} OMX_CONFIG_CALLBACKREQUESTTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_CoreExt_h */
+/* File EOF */

+ 55 - 0
omx-il/include/khronos/OMX_ImageExt.h

@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_ImageExt.h - OpenMax IL version 1.1.2
+ * The OMX_ImageExt header file contains extensions to the
+ * definitions used by both the application and the component to
+ * access image items.
+ */
+
+#ifndef OMX_ImageExt_h
+#define OMX_ImageExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors.  The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Core.h>
+
+/** Enum for standard image codingtype extensions */
+typedef enum OMX_IMAGE_CODINGEXTTYPE {
+    OMX_IMAGE_CodingExtUnused = OMX_IMAGE_CodingKhronosExtensions,
+    OMX_IMAGE_CodingWEBP,         /**< WebP image format */
+} OMX_IMAGE_CODINGEXTTYPE;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_ImageExt_h */
+/* File EOF */

+ 31 - 22
omx-il/include/khronos/OMX_Types.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 The Khronos Group Inc.
+ * Copyright (c) 2016 The Khronos Group Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -31,6 +31,8 @@
 #ifndef OMX_Types_h
 #define OMX_Types_h
 
+#include <stdint.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -104,9 +106,9 @@ extern "C" {
  * Functions and structure related to the OMX IL core
  */
 
-/** @defgroup comp OpenMAX IL component
-* Functions and structure related to the OMX IL component
-*/
+ /** @defgroup comp OpenMAX IL component
+ * Functions and structure related to the OMX IL component
+ */
 
 /** @defgroup rpm Resource and Policy Management
  * Structures for resource and policy management of components
@@ -125,27 +127,27 @@ extern "C" {
  *  @ingroup core
  */
 
-/** @defgroup metadata Metadata handling
- *
- */
+ /** @defgroup metadata Metadata handling
+  *
+  */
 
 /** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */
-typedef unsigned char OMX_U8;
+typedef uint8_t OMX_U8;
 
 /** OMX_S8 is an 8 bit signed quantity that is byte aligned */
-typedef signed char OMX_S8;
+typedef int8_t OMX_S8;
 
 /** OMX_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */
-typedef unsigned short OMX_U16;
+typedef uint16_t OMX_U16;
 
 /** OMX_S16 is a 16 bit signed quantity that is 16 bit word aligned */
-typedef signed short OMX_S16;
+typedef int16_t OMX_S16;
 
 /** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */
-typedef unsigned long OMX_U32;
+typedef uint32_t OMX_U32;
 
 /** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */
-typedef signed long OMX_S32;
+typedef int32_t OMX_S32;
 
 
 /* Users with compilers that cannot accept the "long long" designation should
@@ -173,10 +175,10 @@ typedef signed   __int64  OMX_S64;
 #else /* WIN32 */
 
 /** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
-typedef unsigned long long OMX_U64;
+typedef uint64_t OMX_U64;
 
 /** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */
-typedef signed long long OMX_S64;
+typedef int64_t OMX_S64;
 
 #endif /* WIN32 */
 #endif
@@ -221,7 +223,8 @@ typedef unsigned char OMX_UUIDTYPE[128];
 /** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or
     an output port.  This enumeration is common across all component types.
  */
-typedef enum OMX_DIRTYPE {
+typedef enum OMX_DIRTYPE
+{
     OMX_DirInput,              /**< Port is an input port */
     OMX_DirOutput,             /**< Port is an output port */
     OMX_DirMax = 0x7FFFFFFF
@@ -230,7 +233,8 @@ typedef enum OMX_DIRTYPE {
 /** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering
     for numerical data (i.e. big endian, or little endian).
  */
-typedef enum OMX_ENDIANTYPE {
+typedef enum OMX_ENDIANTYPE
+{
     OMX_EndianBig, /**< big endian */
     OMX_EndianLittle, /**< little endian */
     OMX_EndianMax = 0x7FFFFFFF
@@ -240,7 +244,8 @@ typedef enum OMX_ENDIANTYPE {
 /** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data
     is signed or unsigned
  */
-typedef enum OMX_NUMERICALDATATYPE {
+typedef enum OMX_NUMERICALDATATYPE
+{
     OMX_NumericalDataSigned, /**< signed data */
     OMX_NumericalDataUnsigned, /**< unsigned data */
     OMX_NumercialDataMax = 0x7FFFFFFF
@@ -278,7 +283,8 @@ typedef struct OMX_BS32 {
 #ifndef OMX_SKIP64BIT
 typedef OMX_S64 OMX_TICKS;
 #else
-typedef struct OMX_TICKS {
+typedef struct OMX_TICKS
+{
     OMX_U32 nLowPart;    /** low bits of the signed 64 bit tick value */
     OMX_U32 nHighPart;   /** high bits of the signed 64 bit tick value */
 } OMX_TICKS;
@@ -290,7 +296,8 @@ typedef struct OMX_TICKS {
  */
 typedef void* OMX_HANDLETYPE;
 
-typedef struct OMX_MARKTYPE {
+typedef struct OMX_MARKTYPE
+{
     OMX_HANDLETYPE hMarkTargetComponent;   /**< The component that will
                                                 generate a mark event upon
                                                 processing the mark. */
@@ -332,8 +339,10 @@ typedef void* OMX_NATIVE_WINDOWTYPE;
     by accessing one of the structure elements to, for example, check only
     the Major revision.
  */
-typedef union OMX_VERSIONTYPE {
-    struct {
+typedef union OMX_VERSIONTYPE
+{
+    struct
+    {
         OMX_U8 nVersionMajor;   /**< Major version accessor element */
         OMX_U8 nVersionMinor;   /**< Minor version accessor element */
         OMX_U8 nRevision;       /**< Revision version accessor element */

+ 73 - 7
omx-il/tests/dec_test.c

@@ -44,11 +44,15 @@ typedef struct DecodeTestContext
     OMX_BUFFERHEADERTYPE *pInputBufferArray[64];
     OMX_BUFFERHEADERTYPE *pOutputBufferArray[64];
     AVFormatContext *avContext;
+    OMX_STATETYPE comState;
     int msgid;
 } DecodeTestContext;
 DecodeTestContext *decodeTestContext;
 static OMX_S32 FillInputBuffer(DecodeTestContext *decodeTestContext, OMX_BUFFERHEADERTYPE *pInputBuffer);
 
+static OMX_BOOL disableEVnt = OMX_FALSE;
+static OMX_BOOL useNormal = OMX_FALSE;
+
 static OMX_ERRORTYPE event_handler(
     OMX_HANDLETYPE hComponent,
     OMX_PTR pAppData,
@@ -69,6 +73,17 @@ static OMX_ERRORTYPE event_handler(
         OMX_GetParameter(pDecodeTestContext->hComponentDecoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
         OMX_U32 nOutputBufferSize = pOutputPortDefinition.nBufferSize;
         OMX_U32 nOutputBufferCount = pOutputPortDefinition.nBufferCountMin;
+
+        printf("allocate %u output buffers size %u\r\n", nOutputBufferCount, nOutputBufferSize);
+
+        printf("enable output port and alloc buffer\n");
+
+        printf("======================================\r\n");
+        printf("out put resolution [%dx%d]\r\n", pOutputPortDefinition.format.video.nFrameWidth, pOutputPortDefinition.format.video.nFrameHeight);
+        printf("======================================\r\n");
+
+        OMX_SendCommand(pDecodeTestContext->hComponentDecoder, OMX_CommandPortEnable, 1, NULL);
+
         for (int i = 0; i < nOutputBufferCount; i++)
         {
             OMX_BUFFERHEADERTYPE *pBuffer = NULL;
@@ -89,6 +104,25 @@ static OMX_ERRORTYPE event_handler(
         }
     }
     break;
+    case OMX_EventCmdComplete:
+    {
+        switch ((OMX_COMMANDTYPE)(nData1))
+        {
+        case OMX_CommandStateSet:
+        {
+            pDecodeTestContext->comState = (OMX_STATETYPE)(nData2);
+        }
+        case OMX_CommandPortDisable:
+        {
+            if (nData2 == 1)
+                disableEVnt = OMX_TRUE;
+        }
+        break;
+        default:
+        break;
+        }
+    }
+    break;
     default:
         break;
     }
@@ -214,10 +248,11 @@ int main(int argc, char **argv)
         {"format", required_argument, NULL, 'f'},
         {"scaleW", required_argument, NULL, 'w'},
         {"scaleH", required_argument, NULL, 'h'},
+        {"normal", no_argument, NULL, 'n'},
         {"help", no_argument, NULL, '0'},
         {NULL, no_argument, NULL, 0},
     };
-    char *shortOpt = "i:o:f:w:h:";
+    char *shortOpt = "i:o:f:w:h:n";
     OMX_U32 c;
     OMX_S32 l;
 
@@ -259,6 +294,10 @@ int main(int argc, char **argv)
             printf("ScaleHeight: %s\r\n", optarg);
             decodeTestContext->ScaleHeight = atoi(optarg);
             break;
+        case 'n':
+            printf("use normal buffer\r\n");
+            useNormal = OMX_TRUE;
+            break;
         case '0':
         default:
             help();
@@ -310,7 +349,7 @@ int main(int argc, char **argv)
         printf("%s:%d failed to av_find_best_stream.\n", __FUNCTION__, __LINE__);
         return -1;
     }
-    printf("video index = %ld\r\n", videoIndex);
+    printf("video index = %d\r\n", videoIndex);
     decodeTestContext->avContext = avContext;
     /*get video info*/
     codecParameters = avContext->streams[videoIndex]->codecpar;
@@ -338,11 +377,17 @@ int main(int argc, char **argv)
     printf("get handle\r\n");
     if (codecParameters->codec_id == AV_CODEC_ID_H264)
     {
-        OMX_GetHandle(&hComponentDecoder, "OMX.sf.video_decoder.avc", decodeTestContext, &callbacks);
+        if (useNormal)
+            OMX_GetHandle(&hComponentDecoder, "OMX.sf.video_decoder.avc", decodeTestContext, &callbacks);
+        else
+            OMX_GetHandle(&hComponentDecoder, "OMX.sf.video_decoder.avc.internal", decodeTestContext, &callbacks);
     }
     else if (codecParameters->codec_id == AV_CODEC_ID_HEVC)
     {
-        OMX_GetHandle(&hComponentDecoder, "OMX.sf.video_decoder.hevc", decodeTestContext, &callbacks);
+        if (useNormal)
+            OMX_GetHandle(&hComponentDecoder, "OMX.sf.video_decoder.hevc.internal", decodeTestContext, &callbacks);
+        else
+            OMX_GetHandle(&hComponentDecoder, "OMX.sf.video_decoder.hevc.internal", decodeTestContext, &callbacks);
     }
     if (hComponentDecoder == NULL)
     {
@@ -381,6 +426,12 @@ int main(int argc, char **argv)
     }
     OMX_SetParameter(hComponentDecoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
 
+    disableEVnt = OMX_FALSE;
+    OMX_SendCommand(hComponentDecoder, OMX_CommandPortDisable, 1, NULL);
+    printf("wait for output port disable\r\n");
+    while (!disableEVnt);
+    printf("output port disabled\r\n");
+
     OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
 
     OMX_PARAM_PORTDEFINITIONTYPE pInputPortDefinition;
@@ -400,9 +451,17 @@ int main(int argc, char **argv)
         OMX_BUFFERHEADERTYPE *pBuffer = NULL;
         OMX_AllocateBuffer(hComponentDecoder, &pBuffer, 0, NULL, nInputBufferSize);
         decodeTestContext->pInputBufferArray[i] = pBuffer;
+    }
+
+    printf("wait for Component idle\r\n");
+    while (decodeTestContext->comState != OMX_StateIdle);
+    printf("Component in idle\r\n");
+
+    for (int i = 0; i < nInputBufferCount; i++)
+    {
         /*Fill Input Buffer*/
-        FillInputBuffer(decodeTestContext, pBuffer);
-        OMX_EmptyThisBuffer(hComponentDecoder, pBuffer);
+        FillInputBuffer(decodeTestContext, decodeTestContext->pInputBufferArray[i]);
+        OMX_EmptyThisBuffer(hComponentDecoder, decodeTestContext->pInputBufferArray[i]);
     }
 
     fb = fopen(decodeTestContext->sOutputFilePath, "wb+");
@@ -412,6 +471,7 @@ int main(int argc, char **argv)
         goto end;
     }
 
+    printf("start process\r\n");
     OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateExecuting, NULL);
 
     /*wait until decode finished*/
@@ -455,7 +515,13 @@ int main(int argc, char **argv)
 
 end:
     /*free resource*/
-    OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
+    if (decodeTestContext->comState == OMX_StateExecuting)
+    {
+        OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
+        printf("wait for Component idle\r\n");
+        while (decodeTestContext->comState != OMX_StateIdle);
+        printf("Component in idle\r\n");
+    }
     OMX_FreeHandle(hComponentDecoder);
     OMX_Deinit();
     if (fb)

+ 67 - 21
omx-il/tests/enc_test.c

@@ -48,14 +48,18 @@ typedef struct EncodeTestContext
     OMX_U32 nBitrate;
     OMX_U32 nFrameRate;
     OMX_U32 nNumPFrame;
+    OMX_STATETYPE comState;
     OMX_BUFFERHEADERTYPE *pInputBufferArray[64];
     OMX_BUFFERHEADERTYPE *pOutputBufferArray[64];
     int msgid;
 } EncodeTestContext;
 EncodeTestContext *encodeTestContext;
 static FILE *fb = NULL;
+static OMX_BOOL inputEndFlag = OMX_FALSE;
 static OMX_S32 FillInputBuffer(EncodeTestContext *encodeTestContext, OMX_BUFFERHEADERTYPE *pInputBuffer);
 
+static OMX_BOOL disableEVnt;
+
 static OMX_ERRORTYPE event_handler(
     OMX_HANDLETYPE hComponent,
     OMX_PTR pAppData,
@@ -76,6 +80,10 @@ static OMX_ERRORTYPE event_handler(
         OMX_GetParameter(pEncodeTestContext->hComponentEncoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
         OMX_U32 nOutputBufferSize = pOutputPortDefinition.nBufferSize;
         OMX_U32 nOutputBufferCount = pOutputPortDefinition.nBufferCountMin;
+
+        printf("enable output port and alloc buffer\n");
+        OMX_SendCommand(pEncodeTestContext->hComponentEncoder, OMX_CommandPortEnable, 1, NULL);
+
         for (int i = 0; i < nOutputBufferCount; i++)
         {
             OMX_BUFFERHEADERTYPE *pBuffer = NULL;
@@ -96,6 +104,25 @@ static OMX_ERRORTYPE event_handler(
         }
     }
     break;
+    case OMX_EventCmdComplete:
+    {
+        switch ((OMX_COMMANDTYPE)(nData1))
+        {
+        case OMX_CommandStateSet:
+        {
+            pEncodeTestContext->comState = (OMX_STATETYPE)(nData2);
+        }
+        case OMX_CommandPortDisable:
+        {
+            if (nData2 == 1)
+                disableEVnt = OMX_TRUE;
+        }
+        break;
+        default:
+        break;
+        }
+    }
+    break;
     default:
         break;
     }
@@ -114,7 +141,7 @@ static void help()
     printf("                 -c <cformat>          color format i420/nv12/nv21 \r\n");
     printf("                 -b <bitrate>          (optional) set bit rate \r\n");
     printf("                 -v <frame rate>       (optional) set frame rate \r\n");
-    printf("                 -g <num>              (optional) Number of P frames between each I frame for h264 only \r\n\r\n");
+    printf("                 -g <num>              (optional) Number of P frames between each I frame\r\n\r\n");
     printf("./video_enc_test --help: show this message\r\n");
 }
 
@@ -127,7 +154,7 @@ static OMX_ERRORTYPE fill_output_buffer_done_handler(
 
     Message data;
     data.msg_type = 1;
-    if ((pBuffer->nFlags) & (OMX_BUFFERFLAG_EOS == OMX_BUFFERFLAG_EOS))
+    if (pBuffer->nFlags & OMX_BUFFERFLAG_EOS)
     {
         data.msg_flag = -1;
     }
@@ -165,7 +192,6 @@ static void signal_handle(int sig)
 {
     printf("[%s,%d]: receive sig=%d \n", __FUNCTION__, __LINE__, sig);
 
-
     OMX_FreeHandle(encodeTestContext->hComponentEncoder);
     OMX_Deinit();
     if (fb)
@@ -188,20 +214,20 @@ static OMX_S32 FillInputBuffer(EncodeTestContext *encodeTestContext, OMX_BUFFERH
     OMX_U32 size = encodeTestContext->nFrameBufferSize;
     OMX_U32 count;
 
+    if (inputEndFlag)
+    {
+        pInputBuffer->nFlags = 0;
+        pInputBuffer->nFilledLen = 0;
+        return 0;
+    }
+
     count = fread(pInputBuffer->pBuffer, 1, size, fp);
     if (count < size)
     {
-        Message data;
-        data.msg_type = 1;
-        data.msg_flag = -1;
         pInputBuffer->nFlags = 0x1;
         pInputBuffer->nFilledLen = 0;
         count = 0;
-
-        if (msgsnd(encodeTestContext->msgid, (void *)&data, sizeof(data) - sizeof(data.msg_type), 0) == -1)
-        {
-            fprintf(stderr, "msgsnd failed\n");
-        }
+        inputEndFlag = OMX_TRUE;
     }
     else
     {
@@ -335,11 +361,7 @@ int main(int argc, char **argv)
     callbacks.FillBufferDone = fill_output_buffer_done_handler;
     callbacks.EmptyBufferDone = empty_buffer_done_handler;
     printf("get handle %s\r\n", encodeTestContext->sOutputFormat);
-    if (strstr(encodeTestContext->sOutputFormat, "h264") != NULL)
-    {
-        OMX_GetHandle(&hComponentEncoder, "OMX.sf.video_encoder.avc", encodeTestContext, &callbacks);
-    }
-    else if (strstr(encodeTestContext->sOutputFormat, "h265") != NULL)
+    if (strstr(encodeTestContext->sOutputFormat, "h265") != NULL)
     {
         OMX_GetHandle(&hComponentEncoder, "OMX.sf.video_encoder.hevc", encodeTestContext, &callbacks);
     }
@@ -416,6 +438,12 @@ int main(int argc, char **argv)
     OMX_U32 nInputBufferSize = pInputPortDefinition.nBufferSize;
     OMX_U32 nInputBufferCount = pInputPortDefinition.nBufferCountActual;
 
+    disableEVnt = OMX_FALSE;
+    OMX_SendCommand(hComponentEncoder, OMX_CommandPortDisable, 1, NULL);
+    printf("wait for output port disable\r\n");
+    while (!disableEVnt);
+    printf("output port disabled\r\n");
+
     OMX_SendCommand(hComponentEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
 
     for (int i = 0; i < nInputBufferCount; i++)
@@ -423,12 +451,23 @@ int main(int argc, char **argv)
         OMX_BUFFERHEADERTYPE *pBuffer = NULL;
         OMX_AllocateBuffer(hComponentEncoder, &pBuffer, 0, NULL, nInputBufferSize);
         encodeTestContext->pInputBufferArray[i] = pBuffer;
+    }
+
+    printf("wait for Component idle\r\n");
+    while (encodeTestContext->comState != OMX_StateIdle);
+    printf("Component in idle\r\n");
+
+    for (int i = 0; i < nInputBufferCount; i++)
+    {
         /*Fill Input Buffer*/
-        FillInputBuffer(encodeTestContext, pBuffer);
-        OMX_EmptyThisBuffer(hComponentEncoder, pBuffer);
+        FillInputBuffer(encodeTestContext, encodeTestContext->pInputBufferArray[i]);
+        if (encodeTestContext->pInputBufferArray[i]->nFilledLen || encodeTestContext->pInputBufferArray[i]->nFlags)
+            OMX_EmptyThisBuffer(hComponentEncoder, encodeTestContext->pInputBufferArray[i]);
     }
+
     fb = fopen(encodeTestContext->sOutputFilePath, "wb+");
 
+    printf("start process\r\n");
     OMX_SendCommand(hComponentEncoder, OMX_CommandStateSet, OMX_StateExecuting, NULL);
 
     /*wait until decode finished*/
@@ -446,14 +485,15 @@ int main(int argc, char **argv)
         {
             OMX_BUFFERHEADERTYPE *pBuffer = data.pBuffer;
             FillInputBuffer(encodeTestContext, pBuffer);
-            OMX_EmptyThisBuffer(encodeTestContext->hComponentEncoder, pBuffer);
+            if (pBuffer->nFilledLen || pBuffer->nFlags)
+                OMX_EmptyThisBuffer(encodeTestContext->hComponentEncoder, pBuffer);
         }
         break;
         case 1:
         {
             OMX_BUFFERHEADERTYPE *pBuffer = data.pBuffer;
             fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, fb);
-            if ((pBuffer->nFlags) & (OMX_BUFFERFLAG_EOS == OMX_BUFFERFLAG_EOS))
+            if (pBuffer->nFlags & OMX_BUFFERFLAG_EOS)
             {
                 goto end;
             }
@@ -472,7 +512,13 @@ int main(int argc, char **argv)
 
 end:
     /*free resource*/
-    OMX_SendCommand(hComponentEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
+    if (encodeTestContext->comState == OMX_StateExecuting)
+    {
+        OMX_SendCommand(hComponentEncoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
+        printf("wait for Component idle\r\n");
+        while (encodeTestContext->comState != OMX_StateIdle);
+        printf("Component in idle\r\n");
+    }
     OMX_FreeHandle(hComponentEncoder);
     OMX_Deinit();
     if (fb)

+ 69 - 20
omx-il/tests/mjpeg_dec_test.c

@@ -43,6 +43,7 @@ typedef struct DecodeTestContext
     OMX_BUFFERHEADERTYPE *pInputBufferArray[64];
     OMX_BUFFERHEADERTYPE *pOutputBufferArray[64];
     AVFormatContext *avContext;
+    OMX_STATETYPE comState;
     int msgid;
     OMX_S32 RoiLeft;
     OMX_S32 RoiTop;
@@ -56,6 +57,8 @@ typedef struct DecodeTestContext
 DecodeTestContext *decodeTestContext;
 static OMX_S32 FillInputBuffer(DecodeTestContext *decodeTestContext, OMX_BUFFERHEADERTYPE *pInputBuffer);
 
+static OMX_BOOL disableEVnt;
+
 static OMX_ERRORTYPE event_handler(
     OMX_HANDLETYPE hComponent,
     OMX_PTR pAppData,
@@ -76,10 +79,16 @@ static OMX_ERRORTYPE event_handler(
         OMX_GetParameter(pDecodeTestContext->hComponentDecoder, OMX_IndexParamPortDefinition, &pOutputPortDefinition);
         OMX_U32 nOutputBufferSize = pOutputPortDefinition.nBufferSize;
         OMX_U32 nOutputBufferCount = pOutputPortDefinition.nBufferCountMin;
-        printf("allocate %lu output buffers size %lu\r\n", nOutputBufferCount, nOutputBufferSize);
+        printf("allocate %u output buffers size %u\r\n", nOutputBufferCount, nOutputBufferSize);
+
+        printf("enable output port and alloc buffer\n");
+
         printf("======================================\r\n");
-        printf("out put resolution [%ldx%ld]\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");
+
+        OMX_SendCommand(pDecodeTestContext->hComponentDecoder, OMX_CommandPortEnable, 1, NULL);
+
         for (int i = 0; i < nOutputBufferCount; i++)
         {
             OMX_BUFFERHEADERTYPE *pBuffer = NULL;
@@ -100,6 +109,25 @@ static OMX_ERRORTYPE event_handler(
         }
     }
     break;
+    case OMX_EventCmdComplete:
+    {
+        switch ((OMX_COMMANDTYPE)(nData1))
+        {
+        case OMX_CommandStateSet:
+        {
+            pDecodeTestContext->comState = (OMX_STATETYPE)(nData2);
+        }
+        case OMX_CommandPortDisable:
+        {
+            if (nData2 == 1)
+                disableEVnt = OMX_TRUE;
+        }
+        break;
+        default:
+        break;
+        }
+    }
+    break;
     default:
         break;
     }
@@ -108,17 +136,17 @@ static OMX_ERRORTYPE event_handler(
 
 static void help()
 {
-    printf("omx_mjpeg_dec_test - omx mjpg hardware decode unit test case\r\n\r\n");
+    printf("mjpeg_dec_test - omx mjpg hardware decode unit test case\r\n\r\n");
     printf("Usage:\r\n\r\n");
-    printf("./omx_mjpeg_dec_test -i <input file>               input file \r\n");
-    printf("                     -o <output file>              output file\r\n");
-    printf("                     -f <format>                   nv12/nv21/i420/i422/nv16/nv61/yuyv/yvyu/uyvy/vyuy/i444/yuv444packed \r\n");
-    printf("                     --roi=<x>,<y>,<w>,<h>         (optional) roi coord and width/height(from left top)\r\n");
-    printf("                     --mirror=<0/1/2/3>            (optional) mirror 0(none), 1(V), 2(H), 3(VH)\r\n");
-    printf("                     --scaleH=<0/1/2/3>            (optional) Horizontal downscale: 0(none), 1(1/2), 2(1/4), 3(1/8)\r\n");
-    printf("                     --scaleV=<0/1/2/3>            (optional) Vertical downscale  : 0(none), 1(1/2), 2(1/4), 3(1/8)\r\n");
-    printf("                     --rotation=<0/90/180/270>     (optional) rotation 0, 90, 180, 270\r\n\r\n");
-    printf("./omx_mjpeg_dec_test --help: show this message\r\n");
+    printf("./mjpeg_dec_test -i <input file>               input file \r\n");
+    printf("                 -o <output file>              output file\r\n");
+    printf("                 -f <format>                   nv12/nv21/i420/i422/nv16/nv61/yuyv/yvyu/uyvy/vyuy/i444/yuv444packed \r\n");
+    printf("                 --roi=<x>,<y>,<w>,<h>         (optional) roi coord and width/height(from left top)\r\n");
+    printf("                 --mirror=<0/1/2/3>            (optional) mirror 0(none), 1(V), 2(H), 3(VH)\r\n");
+    printf("                 --scaleH=<0/1/2/3>            (optional) Horizontal downscale: 0(none), 1(1/2), 2(1/4), 3(1/8)\r\n");
+    printf("                 --scaleV=<0/1/2/3>            (optional) Vertical downscale  : 0(none), 1(1/2), 2(1/4), 3(1/8)\r\n");
+    printf("                 --rotation=<0/90/180/270>     (optional) rotation 0, 90, 180, 270\r\n\r\n");
+    printf("./mjpeg_dec_test --help: show this message\r\n");
 }
 
 static OMX_ERRORTYPE fill_output_buffer_done_handler(
@@ -201,7 +229,7 @@ static OMX_S32 FillInputBuffer(DecodeTestContext *decodeTestContext, OMX_BUFFERH
     pInputBuffer->nFlags = 0x10;
     pInputBuffer->nFilledLen = avpacket->size;
     memcpy(pInputBuffer->pBuffer, avpacket->data, avpacket->size);
-    printf("%s, address = %p, size = %lu, flag = %lx\r\n",
+    printf("%s, address = %p, size = %u, flag = %x\r\n",
         __FUNCTION__, pInputBuffer->pBuffer, pInputBuffer->nFilledLen, pInputBuffer->nFlags);
     return avpacket->size;
 }
@@ -382,7 +410,7 @@ int main(int argc, char **argv)
         printf("%s:%d failed to av_find_best_stream.\n", __FUNCTION__, __LINE__);
         return -1;
     }
-    printf("image index = %lu\r\n", imageIndex);
+    printf("image index = %u\r\n", imageIndex);
     decodeTestContext->avContext = avContext;
     /*get image info*/
     codecParameters = avContext->streams[imageIndex]->codecpar;
@@ -533,6 +561,12 @@ int main(int argc, char **argv)
         OMX_SetConfig(hComponentDecoder, OMX_IndexConfigCommonScale, &ScaleConfig);
     }
 
+    disableEVnt = OMX_FALSE;
+    OMX_SendCommand(hComponentDecoder, OMX_CommandPortDisable, 1, NULL);
+    printf("wait for output port disable\r\n");
+    while (!disableEVnt);
+    printf("output port disabled\r\n");
+
     OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
 
     OMX_PARAM_PORTDEFINITIONTYPE pInputPortDefinition;
@@ -552,11 +586,20 @@ int main(int argc, char **argv)
         OMX_BUFFERHEADERTYPE *pBuffer = NULL;
         OMX_AllocateBuffer(hComponentDecoder, &pBuffer, 0, NULL, nInputBufferSize);
         decodeTestContext->pInputBufferArray[i] = pBuffer;
+    }
+
+    printf("wait for Component idle\r\n");
+    while (decodeTestContext->comState != OMX_StateIdle);
+    printf("Component in idle\r\n");
+
+    for (int i = 0; i < nInputBufferCount; i++)
+    {
         /*Fill Input Buffer*/
-        FillInputBuffer(decodeTestContext, pBuffer);
-        OMX_EmptyThisBuffer(hComponentDecoder, pBuffer);
+        FillInputBuffer(decodeTestContext, decodeTestContext->pInputBufferArray[i]);
+        OMX_EmptyThisBuffer(hComponentDecoder, decodeTestContext->pInputBufferArray[i]);
     }
 
+
     fb = fopen(decodeTestContext->sOutputFilePath, "wb+");
     if (!fb)
     {
@@ -564,6 +607,7 @@ int main(int argc, char **argv)
         goto end;
     }
 
+    printf("start process\r\n");
     OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateExecuting, NULL);
 
     /*wait until decode finished*/
@@ -587,7 +631,7 @@ int main(int argc, char **argv)
         case 1:
         {
             OMX_BUFFERHEADERTYPE *pBuffer = data.pBuffer;
-            printf("write %lu buffers to file\r\n", pBuffer->nFilledLen);
+            printf("write %u buffers to file\r\n", pBuffer->nFilledLen);
             size_t size = fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, fb);
             int error = ferror(fb);
             printf("write error = %d\r\n", error);
@@ -611,13 +655,18 @@ int main(int argc, char **argv)
 
 end:
     /*free resource*/
-    OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
+    if (decodeTestContext->comState == OMX_StateExecuting)
+    {
+        OMX_SendCommand(hComponentDecoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
+        printf("wait for Component idle\r\n");
+        while (decodeTestContext->comState != OMX_StateIdle);
+        printf("Component in idle\r\n");
+    }
     OMX_FreeHandle(hComponentDecoder);
     OMX_Deinit();
     avformat_close_input(&avContext);
     avformat_free_context(avContext);
-    if (fb)
-    {
+    if (fb){
         fclose(fb);
     }
 }

+ 1 - 0
wave511/code/sample_v2/component/component.c

@@ -384,6 +384,7 @@ static void DoThreadWork(void* arg)
         DoYourJob(com);
         osal_msleep(2); // To yield schedule
     }
+    ComponentNotifyListeners(com, COMPONENT_EVENT_TERMINATED, NULL);
 
     com->state = COMPONENT_STATE_TERMINATED;
 }

+ 7 - 0
wave511/code/sample_v2/component/component.h

@@ -155,6 +155,8 @@ typedef struct PortContainerExternal
                                      buffer */
     Uint32 nOffset;            /**< start offset of valid data in bytes from
                                      the start of the buffer */
+    void*  pAppPrivate;        /**< pointer to any data the application
+                                     wants to associate with this buffer */
     Uint32 nBufferIndex;
     Uint32 nTickCount;         /**< Optional entry that the component and
                                      application can update with a tick count
@@ -173,6 +175,7 @@ typedef struct PortContainerExternal
                                      of the preceding buffer to the timestamp
                                      of the preceding buffer.*/
     Uint32  nFlags;           /**< buffer specific flags */
+    Uint32  index;
 } PortContainerExternal;
 
 typedef struct PortContainerES {
@@ -327,6 +330,9 @@ typedef struct {
     TestEncConfig   testEncConfig;
     EncOpenParam    encOpenParam;
     ENC_CFG         encCfg;
+#ifdef USE_FEEDING_METHOD_BUFFER
+    BOOL            MemoryOptimization;
+#endif
 } CNMComponentConfig;
 
 
@@ -336,6 +342,7 @@ typedef struct {
 /* ------------------------------------------------ */
 #define COMPONENT_EVENT_SLEEP                   (1ULL<<0)       /*!<< The third parameter of listener is NULL. */
 #define COMPONENT_EVENT_WAKEUP                  (1ULL<<1)       /*!<< The third parameter of listener is NULL. */
+#define COMPONENT_EVENT_TERMINATED              (1ULL<<2)
 #define COMPONENT_EVENT_COMMON_ALL              0xffffULL
 /* ------------------------------------------------ */
 /* ---------------- DECODER EVENTS ---------------- */

+ 4 - 1
wave511/code/sample_v2/component_decoder/component_dec_decoder.c

@@ -590,7 +590,10 @@ static CNMComponentParamRet GetParameterDecoder(ComponentImpl* from, ComponentIm
             fbNum->linearNum = 0;
         }
 #ifdef USE_FEEDING_METHOD_BUFFER
-        fbNum->linearNum = 9;
+        if(fbNum->linearNum >= 8)
+            fbNum->linearNum += 4;
+        else
+            fbNum->linearNum += 2;
 #endif
         break;
     case GET_PARAM_DEC_BITSTREAM_BUF_POS:

+ 63 - 7
wave511/code/sample_v2/component_decoder/component_dec_renderer.c

@@ -46,8 +46,9 @@ typedef struct {
     FILE*                       fpOutput[OUTPUT_FP_NUMBER];
 #ifdef USE_FEEDING_METHOD_BUFFER
     BOOL                        MemoryOptimization;
-    int                         totalBufferNumber;
-    int                         currentBufferNumber;
+    BOOL                        useBufferExternal;
+    Uint32                      totalBufferNumber;
+    Uint32                      currentBufferNumber;
     FrameBuffer                 pLinearFrame[MAX_REG_FRAME];
     vpu_buffer_t                pLinearFbMem[MAX_REG_FRAME];
 #endif
@@ -242,7 +243,6 @@ static BOOL FlushFrameBuffers(ComponentImpl* com, Uint32* flushedIndexes)
     return TRUE;
 }
 
-
 #ifdef USE_FEEDING_METHOD_BUFFER
 void SetRenderTotalBufferNumber(ComponentImpl* com, Uint32 number)
 {
@@ -250,6 +250,12 @@ void SetRenderTotalBufferNumber(ComponentImpl* com, Uint32 number)
     ctx->fbCount.linearNum = ctx->totalBufferNumber = number;
 }
 
+Uint32 GetRenderTotalBufferNumber(ComponentImpl* com)
+{
+    RendererContext*     ctx            = (RendererContext*)com->context;
+    return ctx->totalBufferNumber;
+}
+
 void* AllocateFrameBuffer2(ComponentImpl* com, Uint32 size)
 {
     RendererContext*     ctx            = (RendererContext*)com->context;
@@ -277,6 +283,21 @@ void* AllocateFrameBuffer2(ComponentImpl* com, Uint32 size)
     return ret;
 }
 
+Uint64 RemapDMABuffer(ComponentImpl* com, Uint64 virtAddress, Uint32 size)
+{
+    RendererContext*     ctx;
+    if (!com)
+        return 0;
+    ctx = (RendererContext*)com->context;
+
+    if (ctx->handle == NULL) {
+        ctx->MemoryOptimization = FALSE;
+        return 0;
+    }
+
+    return RemapVaddr(ctx->handle, virtAddress, size);
+}
+
 BOOL AttachDMABuffer(ComponentImpl* com, Uint64 virtAddress, Uint32 size)
 {
     BOOL ret = FALSE;
@@ -301,6 +322,7 @@ BOOL AttachDMABuffer(ComponentImpl* com, Uint64 virtAddress, Uint32 size)
     }
     ret = AttachDecDMABuffer(ctx->handle, &ctx->testDecConfig, virtAddress, size, &ctx->pLinearFrame[i], &ctx->pLinearFbMem[i]);
     ctx->currentBufferNumber ++;
+    ctx->useBufferExternal = TRUE;
     return ret;
 }
 #endif
@@ -321,8 +343,22 @@ static BOOL AllocateFrameBuffer(ComponentImpl* com)
     osal_memset((void*)ctx->pFbMem, 0x00, sizeof(ctx->pFbMem));
     osal_memset((void*)ctx->pFrame, 0x00, sizeof(ctx->pFrame));
 
+#ifdef USE_FEEDING_METHOD_BUFFER
+    if (!ctx->MemoryOptimization || Queue_Get_Cnt(com->sinkPort.inputQ))
+    {
+        compressedNum  = ctx->fbCount.nonLinearNum;
+        linearNum      = ctx->totalBufferNumber;
+        ctx->fbCount.linearNum = ctx->totalBufferNumber;
+    }
+    else{
+        compressedNum  = ctx->fbCount.nonLinearNum;
+        linearNum      = ctx->fbCount.linearNum;
+        ctx->totalBufferNumber = linearNum;
+    }
+#else
     compressedNum  = ctx->fbCount.nonLinearNum;
     linearNum      = ctx->fbCount.linearNum;
+#endif
 
     if (compressedNum == 0 && linearNum == 0) {
         VLOG(ERR, "%s:%d The number of framebuffers are zero. compressed %d, linear: %d\n",
@@ -516,7 +552,7 @@ static BOOL ExecuteRenderer(ComponentImpl* com, PortContainer* in, PortContainer
                 VLOG(INFO, "pBuffer = %p, dmaBuffer = %p, index = %d/%d\n", output->pBuffer, dmaBuffer, count, total_count);
                 if (count >= total_count)
                 {
-                    VLOG(INFO, "A wrong Frame Found\n");
+                    VLOG(ERR, "A wrong Frame Found\n");
                     output->nFilledLen = 0;
                     break;
                 }
@@ -528,7 +564,11 @@ static BOOL ExecuteRenderer(ComponentImpl* com, PortContainer* in, PortContainer
             }
         }
         output->nFilledLen = sizeYuv;
-        output->nFlags = srcData->decInfo.indexFrameDisplay;
+        output->index = srcData->decInfo.indexFrameDisplay;
+
+        if(srcData->last)
+            output->nFlags |= 0x1;
+
         if(ComponentPortGetData(&com->sinkPort))
         {
             ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_FILL_BUFFER_DONE, (void *)output);
@@ -565,6 +605,7 @@ static BOOL ExecuteRenderer(ComponentImpl* com, PortContainer* in, PortContainer
 
     if (srcData->last == TRUE) {
 #ifdef USE_FEEDING_METHOD_BUFFER
+        ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_DECODED_ALL, NULL);
         while ((output = (PortContainerExternal*)ComponentPortGetData(&com->sinkPort)) != NULL)
         {
             output->nFlags = 0x1;
@@ -610,6 +651,10 @@ static void ReleaseRenderer(ComponentImpl* com)
     Uint32           coreIdx = ctx->testDecConfig.coreIdx;
     Uint32           i;
 
+#ifdef USE_FEEDING_METHOD_BUFFER
+    if (!ctx->useBufferExternal)
+    {
+#endif
     for (i=0; i<MAX_REG_FRAME; i++) {
         if (ctx->pFbMem[i].size) {
             if (i < ctx->fbCount.linearNum)
@@ -618,6 +663,9 @@ static void ReleaseRenderer(ComponentImpl* com)
                 vdi_free_dma_memory(coreIdx, &ctx->pFbMem[i], DEC_FB_LINEAR, ctx->handle->instIndex);
         }
     }
+#ifdef USE_FEEDING_METHOD_BUFFER
+    }
+#endif
 
     for (i=0; i<MAX_REG_FRAME; i++) {
         if (ctx->pPPUFrame[i].size) vdi_free_dma_memory(coreIdx, &ctx->pPPUFbMem[i], DEC_ETC, ctx->handle->instIndex);
@@ -660,8 +708,16 @@ static Component CreateRenderer(ComponentImpl* com, CNMComponentConfig* componen
     ctx->ppuQ              = Queue_Create(MAX_REG_FRAME, sizeof(FrameBuffer));
 
 #ifdef USE_FEEDING_METHOD_BUFFER
-    ctx->MemoryOptimization = TRUE;
-    ctx->totalBufferNumber = 7;
+    if (componentParam->MemoryOptimization)
+    {
+        ctx->MemoryOptimization = TRUE;
+    }
+    else
+    {
+        ctx->MemoryOptimization = FALSE;
+    }
+
+    ctx->totalBufferNumber = 12;
     ctx->currentBufferNumber = 0;
 #endif
     return (Component)com;

+ 7 - 0
wave511/code/sample_v2/helper/main_helper.c

@@ -1162,6 +1162,13 @@ void *AllocateDecFrameBuffer2(DecHandle decHandle, TestDecConfig* config, Uint32
     return (void *)vb->virt_addr;
 }
 
+Uint64 RemapVaddr(DecHandle decHandle, Uint64 virtAddress, Uint32 size)
+{
+    Uint32 coreIndex = VPU_HANDLE_CORE_INDEX(decHandle);
+
+    return (Uint64)vdi_remap_vaddr(coreIndex, virtAddress, size);
+}
+
 BOOL AttachDecDMABuffer(DecHandle decHandle, TestDecConfig* config, Uint64 virtAddress, Uint32 size, FrameBuffer* retFbArray, vpu_buffer_t* retFbAddrs)
 {
     RetCode                 ret;

+ 5 - 1
wave511/code/sample_v2/helper/main_helper.h

@@ -1509,7 +1509,11 @@ Uint32 CalcScaleDown(
     Uint32 scaledValue
     );
 
-
+Uint64 RemapVaddr(
+    DecHandle decHandle,
+    Uint64 virtAddress,
+    Uint32 size
+    );
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

+ 1 - 1
wave511/code/vdi/linux/driver/vdec.c

@@ -844,7 +844,7 @@ static long vpu_ioctl(struct file *filp, u_int cmd, u_long arg)
                                 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);
+                                printk("attach phy address = %lx, virt = %lx\r\n", phys, virt);
                                 vbp->vb.phys_addr = phys;
                                 vbp->vb.base = virt;
                             }

+ 22 - 0
wave511/code/vdi/linux/vdi.c

@@ -1044,6 +1044,28 @@ int vdi_virt_to_phys(unsigned long core_idx, vpu_buffer_t *vb)
     return 0;
 }
 
+void* vdi_remap_vaddr(unsigned long coreIndex, unsigned long virtAddress, unsigned int size)
+{
+    vpu_buffer_t            vb;
+    vdi_info_t              *vdi;
+    void                    *vaddr;
+
+    if (coreIndex >= MAX_NUM_VPU_CORE)
+        return NULL;
+
+    vb.virt_addr = virtAddress;
+    vb.size = size;
+
+    vdi = &s_vdi_info[coreIndex];
+
+    vdi_virt_to_phys(coreIndex, &vb);
+
+    vaddr = (void *)mmap(NULL, vb.size, PROT_READ | PROT_WRITE,
+        MAP_SHARED, vdi->vpu_fd, DRAM_MEM2SYS(vb.phys_addr));
+
+    return vaddr;
+}
+
 int vdi_allocate_dma_memory(unsigned long core_idx, vpu_buffer_t *vb, int memTypes, int instIndex)
 {
     vdi_info_t *vdi;

+ 1 - 0
wave511/code/vdi/vdi.h

@@ -117,6 +117,7 @@ extern "C" {
     int vdi_dettach_dma_memory(unsigned long core_idx, vpu_buffer_t *vb);
     void* vdi_map_virt2(unsigned long core_idx, int size, PhysicalAddress bufY);
     int vdi_virt_to_phys(unsigned long core_idx, vpu_buffer_t *vb);
+    void* vdi_remap_vaddr(unsigned long coreIndex, unsigned long virtAddress, unsigned int size);
 
 #ifdef SUPPORT_MULTI_INST_INTR
     int vdi_wait_interrupt(unsigned long coreIdx, unsigned int instIdx, int timeout);

Some files were not shown because too many files changed in this diff