This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Not able to run the Jpeg Encoder in a loop

Hi All,

I am trying to develop an application on DM365 which does Jpeg encoding successively in a loop.  I am using DVSDK v2_10_01_18 and framework component v2_24.

I could able to encode one image using my application. But when I call the application in a loop I am getting the following errors,

ERROR: assertion violation: SemMP_posix.c, line 360
ERROR: assertion violation: LockMP_posix.c, line 90
ERROR: assertion violation: LockMP_posix.c, line 189
ERROR: assertion violation: LockMP_posix.c, line 190
ERROR: assertion violation: LockMP_posix.c, line 191

Could any one help me to resolve this. 

 

Thanks in advance,

Jai,

 

My application is as follows,

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <strings.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <signal.h>
#include <xdc/std.h>
#include <ti/sdo/ce/Engine.h>

#include <ti/sdo/ce/trace/gt.h>
#include <ti/sdo/ce/CERuntime.h>

#include <ti/sdo/ce/video1/videnc1.h>
#include <ti/sdo/ce/image1/imgenc1.h>
#include <ti/sdo/codecs/jpegenc/ijpegenc.h>
#include <ti/sdo/fc/ires/addrspace/ires_addrspace.h>
#include <ti/sdo/fc/ires/addrspace/iresman_addrspace.h>
#include <ti/sdo/fc/ires/hdvicp/iresman_hdvicp.h>
#include <ti/sdo/fc/ires/hdvicp/ires_hdvicp.h>

#include <ti/sdo/dmai/Dmai.h>
#include <ti/sdo/dmai/BufferGfx.h>

#include <ti/sdo/fc/rman/rman.h>
#include <ti/sdo/fc/ires/iresman.h>
#include <ti/sdo/fc/ires/vicp/iresman_vicp2.h>
#include <ti/sdo/fc/ires/edma3chan/iresman_edma3Chan.h>
#include <ti/sdo/fc/ires/edma3chan/ires_edma3Chan.h>
#include <ti/sdo/fc/edma3/edma3_config.h>
#include <ti/sdo/edma3/rm/edma3_rm.h>
#include <ti/sdo/fc/ires/addrspace/ires_addrspace.h>
#include <ti/sdo/fc/ires/addrspace/iresman_addrspace.h>
#include <ti/sdo/linuxutils/cmem/include/cmem.h>

#define MAX_IMG_WIDTH   1024
#define MAX_IMG_HEIGHT  768

#define ORGBUF_OFFSET  (3)

#define LUMABUF_SIZE   (MAX_IMG_WIDTH * (MAX_IMG_HEIGHT+32))
#define CHROMABUF_SIZE (LUMABUF_SIZE) /* Support JPEG 4:4:4 */

#define ENCODED_DATA_BUFFER_SIZE (2 * MAX_IMG_WIDTH * MAX_IMG_HEIGHT)

static IIMGENC1_Params          params;
static IIMGENC1_DynamicParams   dynamicParams;
static CMEM_AllocParams memParams;
IIMGENC1_InArgs          inArgs;
IIMGENC1_OutArgs         outArgs;
XDM1_BufDesc            inBufDesc;
XDM1_BufDesc            outBufDesc;

/******************************************************************************
 * main
 ******************************************************************************/
Int main(Int argc, Char *argv[])
{
    int i;
    Int                 status              = EXIT_SUCCESS;
    FILE *fp_out;
    FILE *fp_in;
    int bytes_read = 0;
    IMGENC1_Handle/*IALG_Handle*/ handle;
    char   *algName = "jpegenc";
    int             bytesGenerated;
    unsigned char* Inbuf;
    unsigned char* Outbuf;
    Engine_Handle           hEngine             = NULL;
    IJPEGENC_Status          encStatus;
    int iresStatus;
    IRESMAN_Edma3ChanParams configParams;
    IRESMAN_VicpParams iresmanConfigParams;
    IRESMAN_AddrSpaceParams addrspaceConfigParams;

    for(i = 0; i < 2; i++) {
   
        bytesGenerated = 0;
        hEngine = NULL;
        handle  = NULL;
   
        fp_in = fopen("bream2_352_288_422_UYVY.yuv", "rb");
        if(fp_in == NULL)
        {
            printf("Input File not found \n");
            return -1;
        }
   
        fp_out = fopen("bream2_352_288_422_UYVY.jpg", "wb");
        if(fp_out == NULL)
        {  
            printf("Output File not found \n");
            return -1;
        }
   
        params.maxHeight                = 320;
        params.maxWidth                 = 384;
        params.maxScans                 = 15;
        params.dataEndianness           = 1;
        params.forceChromaFormat        = 2; /* 4:2:0 SP */
        params.size                     = sizeof(IIMGENC1_Params);
   
        dynamicParams.inputChromaFormat = 4; /* 4:2:2 UYVY Little endian Interleaved */
        dynamicParams.inputWidth        = 352;
        dynamicParams.inputHeight       = 288;
        dynamicParams.captureWidth      = 352;
        dynamicParams.numAU             = 0;
        dynamicParams.generateHeader    = 0;
        dynamicParams.qValue            = 97;
        dynamicParams.size              = sizeof(IIMGENC1_DynamicParams);
      
        /* Initialize Codec Engine runtime */
        CERuntime_init();
   
       /* Initialize Davinci Multimedia Application Interface */
       Dmai_init();

       memParams.type=CMEM_POOL;
       memParams.flags=CMEM_NONCACHED;
       memParams.alignment=256;
       CMEM_init();

       Inbuf  = CMEM_alloc((LUMABUF_SIZE*2+ORGBUF_OFFSET), &memParams);
       if(Inbuf == NULL)
       {
           return -1;
       }
       Outbuf = CMEM_alloc((ENCODED_DATA_BUFFER_SIZE), &memParams);
       if(Outbuf == NULL)
       {
            return -1;
       }
        memset(Outbuf, 0xaa, ENCODED_DATA_BUFFER_SIZE);
        memset(Inbuf, 0xaa, (LUMABUF_SIZE*2+ORGBUF_OFFSET));

        //Read the file
        bytes_read = fread(Inbuf, 1, dynamicParams.inputWidth * dynamicParams.inputHeight * 2, fp_in);

        printf("Encode demo started.\n");

        /* Reset, load, and start DSP Engine */
        hEngine = Engine_open("encode", NULL, NULL);
        if (hEngine == NULL) {
            printf("Failed to open codec engine \n");
            return -1;
         }

        if(RMAN_init() != IRES_OK)
        {
            printf("Cannot Init RMAN.\n");
            return -1;
        }
        else
        {
            printf("RMAN initialized.\n");
        }
   
        //DM365MM_init();

        printf("Registering VICP Protocols \n");
        iresmanConfigParams.baseConfig.allocFxn = RMAN_PARAMS.allocFxn;
        iresmanConfigParams.baseConfig.freeFxn  = RMAN_PARAMS.freeFxn;
        iresmanConfigParams.baseConfig.size  = sizeof(IRESMAN_VicpParams);
        if(RMAN_register(&IRESMAN_VICP2, (IRESMAN_Params *)&iresmanConfigParams) != IRES_OK)
        {
          printf("VICP Protocol regn failed\n");
        }
        else
        {
          printf("VICP Protocols registered.\n");
          configParams.baseConfig.allocFxn = RMAN_PARAMS.allocFxn;
          configParams.baseConfig.freeFxn  = RMAN_PARAMS.freeFxn;
          configParams.baseConfig.size  = sizeof(IRESMAN_Edma3ChanParams);
          if(RMAN_register(&IRESMAN_EDMA3CHAN, (IRESMAN_Params *)&configParams) != IRES_OK)
          {
            printf("EDMA3 Protocol regn failed\n");
          }
          else
          {
            printf("EDMA3 Protocols registered.\n");
          }
        }
#if 0
        {
            IRESMAN_HdVicpParams configParams;
            configParams.baseConfig.allocFxn = RMAN_PARAMS.allocFxn;
            configParams.baseConfig.freeFxn  = RMAN_PARAMS.freeFxn;
            configParams.baseConfig.size     = sizeof(IRESMAN_HdVicpParams);
            configParams.numResources = 1;
            if (RMAN_register(&IRESMAN_HDVICP, (IRESMAN_Params *)&configParams) != IRES_OK) {
                printf("HDVICP Protocol Registration Failed \n");
                return -1;
            }
        }
#endif   
        /* ADDRSPACE registering */
        /*
        *      * Supply initialization information for the ADDRSPACE RESMAN while
        *      registering
        *    */
        addrspaceConfigParams.baseConfig.allocFxn = RMAN_PARAMS.allocFxn;
        addrspaceConfigParams.baseConfig.freeFxn = RMAN_PARAMS.freeFxn;
        addrspaceConfigParams.baseConfig.size = sizeof(IRESMAN_AddrSpaceParams);;
   
        iresStatus = RMAN_register(&IRESMAN_ADDRSPACE, (IRESMAN_Params*)&addrspaceConfigParams);

        if (IRES_OK != iresStatus) {
            printf("ADDRSPACE Protocol Registration Failed \n");
            return -1;
        }
        printf("ADDRSPACE Protocol Registration Success \n");

        printf("\nhEngine = %d\n", hEngine);       
        handle = IMGENC1_create(hEngine, algName, &params);
        if (handle == NULL) {
            printf("Failed to open jpeg encode algorithm: %s (0x%x)\n",
                algName, Engine_getLastError(hEngine));
            return -1;
        }

        printf("IMGENC1_create SUCCESS\n");
        encStatus.imgencStatus.size = sizeof(encStatus);
        status = IMGENC1_control(handle, XDM_SETPARAMS, (IIMGENC1_DynamicParams *)&dynamicParams, (IIMGENC1_Status *)&encStatus);
        if (status != 0/*VIDENC1_EOK*/) {
            printf("\n IMGENC1_control failed\n");
            return -1;
        }
   
        printf("IMGENC1_control SUCCESS\n");
        inArgs.size                 = sizeof(IIMGENC1_InArgs);
        outArgs.size                = sizeof(IIMGENC1_OutArgs);

        inBufDesc.numBufs           = 1;
        inBufDesc.descs[0].bufSize  = 288*352*2;
        inBufDesc.descs[0].buf      = (XDAS_Int8 *)Inbuf;

        outBufDesc.numBufs          = 1;
        outBufDesc.descs[0].bufSize = 288*352*2;
        outBufDesc.descs[0].buf     = (XDAS_Int8 *)Outbuf;

        /* perform the image (JPEG) encoding */
        status = IMGENC1_process(handle, &inBufDesc, &outBufDesc, &inArgs, &outArgs);
        if(status != 0)
        {
            printf("IMGENC1_process FAILS  \n");
        }
        bytesGenerated = outArgs.bytesGenerated;
        printf("IMGENC1_process SUCCESS   %d\n", bytesGenerated);

        fwrite(Outbuf, 1, bytesGenerated, fp_out);

        fclose(fp_in);   
        fclose(fp_out);

        if( handle){
            IMGENC1_delete(handle);
        }
        if (hEngine) {
            Engine_close(hEngine);
        }

        //RMAN_unregister(&IRESMAN_HDVICP);
        RMAN_unregister(&IRESMAN_EDMA3CHAN);
        RMAN_unregister(&IRESMAN_VICP2);
        RMAN_unregister(&IRESMAN_ADDRSPACE);
        RMAN_exit();
   
        CMEM_free(Inbuf, &memParams);
        CMEM_free(Outbuf, &memParams);

        CMEM_exit();

       //CERuntime_exit();
    }
    return 0;
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


 


  • Jai said:

    I could able to encode one image using my application. But when I call the application in a loop I am getting the following errors,

    ERROR: assertion violation: SemMP_posix.c, line 360
    ERROR: assertion violation: LockMP_posix.c, line 90
    ERROR: assertion violation: LockMP_posix.c, line 189
    ERROR: assertion violation: LockMP_posix.c, line 190
    ERROR: assertion violation: LockMP_posix.c, line 191

    The LockMP assertions are just follow-ons caused by the original assertion in SemMP.  The SemMP assertion happens because the Linux semop() operation is returning -1.  To get further details on the failure, more information is contained in errno.  A typical error is EIDRM (43):
        " The semaphore identifier semid is removed from the system."

    I don't know if that is your error, or, if it is, why you would be getting that error when you rerun the app in the loop. 

    I believe Framework Components (FC) can be configured with different styles of semaphores, depending on the needs of the application.  SemMP allows multiple processes to contend for shared resources.  If there are not multiple processes sharing resources in your system then SemMP is overkill, and just Sem can be used.

    Regards,

    - Rob

  • Dear Bob,

    Thanks for the input.

    In my application Jpeg encoder resources are dedicated to only one process/task. So In the configuration file I have mentioned that

    RMAN.semCreateFxn = "Sem_create"
    RMAN.semDeleteFxn = "Sem_delete"
    RMAN.semPendFxn = "Sem_pend"
    RMAN.semPostFxn = "Sem_post"

    I am not sure, still why it is using SemMP.

    You have any idea on how to configure the FC / DVSDK to use Sem?

     

    Thanks & Regards

    Jai

     

  • I looked a little closer at your application.  I see that you're calling CERuntime_init() in the loop and CERuntime_exit() is commented out from the end of the loop.  I think you should be calling CERuntime_init() just once in your app, before the loop.

    The call to SemMP functions is probably coming from the ALG module, which is called from the Algorithm module.  I don't think you can change this, but it should work OK and is probably getting messed up by the multiple CERuntime_init() calls.

    Regards,

    - Rob

  • Hi Robert,

    Thanks...

    I have modified code such that, CERuntime_init( ) has called only once before the for loop and CERuntime_exit() is called after the loop.                                                                    

    Also I commented the line RMAN_unregister(&IRESMAN_VICP2); (But still I am registering IRESMAN_VICP2 every time in the loop)

    With this changes I am successfully able to run the code in  the for loop.

    My doubt is,

    1. Un-registering IRESMAN_VICP2 is not required? Since I am registering IRESMAN_VICP2 in the loop, is memory leak can exist?

    2. Even if removed registering IRESMAN_VICP2, still the code works fine. Is it means Jpeg encoder in not using VICP2??

    Please clarify...

     

    Regards

    Jai

     



     

  • Jai,

    You don't need to unregister IRESMAN_VICP2 explicitly since on RMAN_exit, this is done automatically. You should not see any memory leaks because of this, let me know if you have any more issues.

    We added a feature called "autoRegister" to the individual resource managers (IRESMAN_*) that registers a resource if it is declared in the server config file. That is, if in your cfg file you have something like this:-

    var VICP2 = xdc.useModule("ti.sdo.fc.ires.vicp.VICP2");

    This will automatically register the correct resource manager with the framework. This is why you can easily remove the register statement from your code and it still works. Now I'm not familiar with thecodec, so I'm not sure if hte jpeg encoder needs/uses the VICP2. For that you will have to refer to documentation, or you can look at the codec's xdc file (<CODEC>.xdc) and see if there's a line like this:-

    override readonly config String iresFxns = "<CODEC>_TI_IRES";

    You can look at the source files that define the above symbol to see if they request a VICP2 resource.

  • Gujan,

     

    Thanks a lot...

    I got my answer..

     

    Jai.

     

  • I also got the message "ERROR: assertion violation: SemMP_posix.c, line 360".

    Int SemMP_pend(SemMP_Handle sem, UInt32 timeout)
    {
    Int status = SemMP_EOK;
    struct sembuf semBuf;

    GT_2trace(curTrace, GT_ENTER,
    "Entered SemMP_pend> sem[0x%x] timeout[0x%x]\n", sem, timeout);

    /* Timeouts not supported yet */
    GT_assert(curTrace, timeout == SemMP_FOREVER);

    semBuf.sem_num = _SemMP_SEMCOUNT;
    semBuf.sem_op = -1;
    semBuf.sem_flg = SEM_UNDO;

    /* TODO: Figure out how to do timeout */
    if (semop(sem->id, &semBuf, 1) == -1) {
    status = SemMP_EFAIL;
    GT_1trace(curTrace, GT_7CLASS, "SemMP_pend [0x%x] failed\n", sem->id);
    GT_assert(curTrace, status == SemMP_EOK);
    }

    GT_2trace(curTrace, GT_ENTER, "Leaving SemMP_pend> sem[0x%x] status[%d]\n",
    sem, status);

    return (status);
    }

    My recommendation to start debugging is to print out the errno, after calling semop().

    #include <errno.h>
    #include <string.h>
    #include <stdio.h>
    ...
    if (semop(sem->id, &semBuf, 1) == -1) {
    int errsv = errno;
    status = SemMP_EFAIL;
    GT_1trace(curTrace, GT_7CLASS, "SemMP_pend [0x%x] failed\n", sem->id);
    printf("SemMP_pend() failed with errno %d (%s)\n", errsv, strerror(errsv));
    GT_assert(curTrace, status == SemMP_EOK);
    }

    In the context where I was getting this failure, errno kept being EINTR (Interrupted by system call), which forced me to changed the implementation of SemMP_pend() to protect against being interrupted from other signals.

    while (semop(sem->id, &semBuf, 1) == -1) {
    if (errno != EINTR) {
    status = SemMP_EFAIL;
    GT_1trace(curTrace, GT_7CLASS, "SemMP_pend [0x%x] failed\n", sem->id);
    GT_assert(curTrace, status == SemMP_EOK);
    }
    }

    This fixed my issue.