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.

Segmentation fault at IMGENC1_process

I have the following function (see below) in my program and it gives me segmentation fault when calling IMGENC1_process. The function is called as follows:

        MakeYUV2JPEG("/mnt/ram/image.jpeg", display_buffers[2].user_addr,  2048, 1536, 75, display_buffers[0].user_addr);

where:

    display_buffers[2].user_addr is pointing to a (2048*1536*2+4096 bytes) buffer (allocated by CMEM)

    display_buffers[0].user_addr is pointing to a (1056*1536*4+4096 bytes) buffer (allocated by CMEM)

What could be the cause of segmentation fault?

Thank you.

====== my function =====

int MakeYUV2JPEG(char * filename, void * ptr, int width, int height, int Q, void * tmpbuf)
{
    Engine_Handle ceh;
    Engine_Error cerr;
    IMGENC1_Handle ieh;
    IIMGENC1_Params params;
    IIMGENC1_DynamicParams dynamicparams;
    IMGENC1_Status status;
    IIMGENC1_InArgs inargs;
    IIMGENC1_OutArgs outargs;
    FILE * afile;
   
    int res, i;

    params.size = sizeof(params);
   
    // init Code Engine (run-time variables)
    CERuntime_init();

    // open codec engine
    ceh = Engine_open("imgenc1_copy", NULL, &cerr);
    if (!ceh)
    {
        switch(cerr)
        {
            case Engine_EOK: printf("Open success\n"); break;
            case Engine_EEXIST: printf("Open name does not exist\n"); break;
            case Engine_ENOMEM: printf("Open can't allocate memory\n"); break;
            case Engine_EDSPLOAD: printf("Open can't load the DSP\n"); break;
            case Engine_ENOCOMM: printf("Open can't create a comm connection to DSP\n"); break;
            case Engine_ENOSERVER: printf("Open can't locate the server on the DSP\n"); break;
            case Engine_ECOMALLOC: printf("Open can't allocate communication buffer\n"); break;
            default: printf("Open error undefined\n");
        }
        CERuntime_exit();
        return -1;
    }
   
    // create JPEG encoder instance
    ieh = IMGENC1_create(ceh, "jpegenc", NULL);
    if (!ieh)
    {
        printf("Failed to create jpegenc instance\n");
        Engine_close(ceh);   
        CERuntime_exit();
        return -1;
    }

    dynamicparams.size = sizeof(dynamicparams);
    dynamicparams.numAU = XDM_DEFAULT;     // number of Access units to encode.
                        // (if want to feed the data in chunks to save buffer space)
    dynamicparams.inputChromaFormat = XDM_YUV_422P;    // format of the input data. see enum XDM_ChromaFormat for all formats
    dynamicparams.inputHeight = height;
    dynamicparams.inputWidth = width;
    dynamicparams.captureWidth = 0; // set to zero to use image width. don't know what it's for.
    dynamicparams.generateHeader = XDM_ENCODE_AU; // don't knwo what it's for but this is what dvtb used.
    dynamicparams.qValue = Q; // compress JPEG qith quality = 75%
   
    memset(&status, 0, sizeof(status));
    status.size = sizeof(status); // define the size of status structure

    res = IMGENC1_control(ieh, XDM_SETPARAMS, &dynamicparams, &status);
    if (res != IMGENC1_EOK)
    {
        printf("Error (%d), Extended Error (%d) in image Encoder Control:setparams\n", res, status.extendedError);
        IMGENC1_delete(ieh);
        Engine_close(ceh);   
        CERuntime_exit();
        return -1;
    }
    printf("CE params set OK\n");

    memset(&status, 0, sizeof(status));
    status.size = sizeof(status); // define the size of status structure
    res = IMGENC1_control(ieh, XDM_GETBUFINFO, &dynamicparams, &status);
    if (res != IMGENC1_EOK)
    {
        printf("Error (%d), Extended Error (%d) in image Encoder Control: getbufinfo\n", res, status.extendedError);
        IMGENC1_delete(ieh);
        Engine_close(ceh);   
        CERuntime_exit();
        return -1;
    }   
   
   
    printf("Input buffers needed: %d\n",(int)status.bufInfo.minNumInBufs);
    for(i=0;i<status.bufInfo.minNumInBufs;i++)
        printf("Input buffer %d size: %d\n",i, (int)status.bufInfo.minInBufSize[i]);

    printf("Output buffers needed: %d\n",(int)status.bufInfo.minNumOutBufs);
    for(i=0;i<status.bufInfo.minNumOutBufs;i++)
        printf("Output buffer %d size: %d\n",i, (int)status.bufInfo.minOutBufSize[i]);

    inargs.size = sizeof(inargs);
    outargs.size = sizeof(outargs);
   
    res = IMGENC1_process(ieh, ptr, tmpbuf, &inargs, &outargs) ;
    if (res != IMGENC1_EOK)
    {
        printf("Error encoding image\n");
        IMGENC1_delete(ieh);
        Engine_close(ceh);   
        CERuntime_exit();
        return -1;
    }
    printf("JPEG encoded: %d bytes\n",outargs.bytesGenerated);

    if ((afile = fopen(filename,"w")))
    {
        fwrite(tmpbuf, outargs.bytesGenerated, 1, afile);
        fclose(afile);
    }
   
    IMGENC1_delete(ieh);
   
    Engine_close(ceh);   

    CERuntime_exit();
    return 0;
}

==================

  • Here is what the function prints:

    CE params set OK
    Input buffers needed: 1
    Input buffer 0 size: 1
    Output buffers needed: 1
    Output buffer 0 size: 1
    Segmentation fault

  • Can you set CE_DEBUG=3 and post the log file?

    And/or can you run your app under gdb - that sometimes catches segfaults right at the source line causing it.

    Chris

  • Looking closer at the code, the args you're passing to IMGENC1_process() are incorrect.  Specifically, inBufs and outBufs are buffer descriptors, not raw pointers.  You'll need to pass buffer descriptors.

    I'm actually thinking if you ran with CE_CHECK=1, you might get lucky and see exactly this app programming error reported, too.

    Chris

  • Thanks for quick response. Don't know how I have overlooked this.

    Do you know why the the minimum size returned is 1 byte? (see print results, my second post)

  • The minimum size returned is codec specific so you're question might be better answered on the Codecs forum.

    Note that the returned value is the _minimum_ number of raw image bytes required for a successful image encode.  A really tiny one-byte image might not compress very well... ;)  ... but this codec seems to claim it can support it.  I'd also assume the image encoder supports images of larger dimensions as well.

    Chris

  • I am reposing my question. For some reason I got the email confirmation but I could not see it on the website.

    I fixed the code by adding the following:

    =======

        inbufdesc.numBufs = 1;
        inbufdesc.descs[0].buf = ptr;
        inbufdesc.descs[0].bufSize = width*height*2;
        outbufdesc.numBufs = 1;
        outbufdesc.descs[0].buf = tmpbuf;
        outbufdesc.descs[0].bufSize = width*height*2;
       
        res = IMGENC1_process(ieh, &inbufdesc, &outbufdesc, &inargs, &outargs) ;

    =====

    Now, it appear to run without errors and returns IMGENC1_EOK.

    However number of bytes generated is 6291456 bytes. (JPEG encoded: 6291456 bytes). The content of the buffer does not look like a JPEG file. Looks more like YUV data (I used that buffer to process the YUV data).

    What's wrong now?

  • Chris,

    Could it be that I used an incorrect line is .cfg file?

    I used: var encoder = xdc.useModule('ti.sdo.ce.examples.codecs.imgenc1_copy.IMGENC1_COPY');

    What is the correct string to use for JPEG encoding? ( I have DVSDK 3.1 for dm355)

  • Gennadiy Kiryukhin said:

    Could it be that I used an incorrect line is .cfg file?

    I used: var encoder = xdc.useModule('ti.sdo.ce.examples.codecs.imgenc1_copy.IMGENC1_COPY');

    Yes, that's the problem.  You're configuring one of our example 'copy' codecs into your system - that's not a real image encoder.  (That also explains why it returned 1 byte as a minimum input buffer)

    Gennadiy Kiryukhin said:
    What is the correct string to use for JPEG encoding? ( I have DVSDK 3.1 for dm355)

    I don't know.  The DM355 Codecs article was my first bet, but there aren't any details on JPEG Encoder there.  You could check your DVSDK docs - else you might have more success asking on the Codec Forum.

    Chris

  • Gennadiy Kiryukhin said:
    I am reposing my question. For some reason I got the email confirmation but I could not see it on the website.

    FYI, it "disappeared" because I moved it to the Codec Forum here - you should have received an email about it(?).  It then re-appeared here when you reposted it.

    We like to keep forum threads short and not wandering too much so we can mark them "Verified" and then typically not come back to check on them.  But I know these discussions are organic so it's just a loose rule.

    Chris

  • Hi,

    Dm355 codec packages include usually a sample application. For jpeg encoder this application should be located in packages/ti/sdo/codecs/jpegenc/apps/Client/Test/Src.

    I have an older version of the DVSDK 3.10 installed but I think it should be the same in the one you are using. This application does not use Codec Engine however it is still a helpful example to understand how to pass the codec parameters.

    The DVSDK 3.10 also includes some Codec Engine apps that show you how to use the jpeg encoder:

    1) The DMAI app image_encode_io1 located in dmai_2_10_00_12/packages/ti/sdo/dmai/apps/image_encode_io1.

    DMAI is a library that defines a set of APIs that abstract the Codec Engine APIs. The source to these APIs is located in packages/ti/sdo/dmai/ce. For JPEG encoder you may want to take a look at Ienc1.c

    For more information abou the DMAI please see http://processors.wiki.ti.com/index.php/Davinci_Multimedia_Application_Interface

    2) The DVTB app located in dvtb_4_20_10/packages/ti/sdo/dvtb/dm355.

    For example the dm355/dvtb_dm355.cfg will show you how to add the codec to your config file:

    var JPEGENC = xdc.useModule('ti.sdo.codecs.jpegenc.dm355.ce.JPEGENC');

    For more information about the DVTB please see  http://processors.wiki.ti.com/index.php/Digital_Video_Test_Bench_%28DVTB%29

    Thanks

    Cesar

  • I used dvtb config file and it has the following line.

    var JPEGENC = xdc.useModule('ti.sdo.codecs.jpegenc.ce.JPEGENC');

    I checked the path under dm355_codecs_03_10_00_02 and it seems to be correct.

    I have other problems though (the saga continues here):

    http://e2e.ti.com/support/embedded/f/356/t/88403.aspx