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.

Can JPEG and MPEG4 run on DM355 simultaneity

Hi all,
 
I want to run JPEG and MPEG4 encode on DM355 board, and I wrote a demo referencing the code in ../DVSDK_1_00_30_xx/demo/encode/* and the code in ../DVSDK_1_00_30_xx/examples/jpegenc/*. After I run the demo, it said on the terminal:
/*********************************************************/
root@21:/opt/dvsdk# ./encode_test_jpeg -v 1.mpeg4 -r 640x576 -b 384000
Encode demo started.
 gpio control udp socket create ok! 
the /dev/modem is opened 
allocate modem buffer
fd = 17
Capturing 720x576 video (cropped to 640x576)
ERROR: can't open engine image
CMEMK Error: GETPHYS: Failed to convert virtual 0x4001cbe0 to physical.
CMEM Error: getPhys: Failed to get physical address of 0x4001cbe0
Encode Error: Failed to open video encode algorithm: mpeg4enc (0x0)
/******************************************************/
But when I run the encode demo and jpegenc demo respectively, they all right.
Why, can JPEG engine and MPEG4 engine open run on DM355 simultaneity , can they run JPEG and MPEG4 encode on DM355 simultaneity? If yes, what is wrong with my code? The following are my code:
/********************main.c**********************************/
...........................................
...........................................
    /* Set the thread to be fifo real time scheduled */
    if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
        ERR("Failed to set FIFO scheduling policy\n");
        cleanup(EXIT_FAILURE);
    }
////////////////////////////add jpeg thread/////////////////////////////////////////////
        schedParam.sched_priority = sched_get_priority_max(SCHED_FIFO) - 2;
        if (pthread_attr_setschedparam(&attr, &schedParam)) {
            ERR("Failed to set scheduler parameters\n");
            cleanup(EXIT_FAILURE);
        }
        jpegencEnv.hRendezvousInit    = &rendezvousInit;
        jpegencEnv.hRendezvousCleanup = &rendezvousCleanup;
        jpegencEnv.hRendezvousPrime   = &rendezvousPrime;
        jpegencEnv.hPause             = &pause;
if (pthread_create(&jpegThread, &attr, jpegencThrFxn, &jpegencEnv)) 
{
ERR("Failed to create GpioEnv thread\n");
cleanup(EXIT_FAILURE);
}
initMask |= JPEGTHREADCREATED;
////////////////////////////add jpeg thread end/////////////////////////////////////////////
    /* Create the video threads if a file name is supplied */
    if (args.videoFile) {
        /* Open the display input fifo */
        if (FifoUtil_open(&displayEnv.inFifo,
                          sizeof(DisplayBufferElement)) == FIFOUTIL_FAILURE) {
            ERR("Failed to open input fifo\n");
            cleanup(EXIT_FAILURE);
..............................
..............................
/********************jpegenc.c**********************************/
 
#include <xdc/std.h>
#include <ti/sdo/ce/Engine.h>
#include <ti/sdo/ce/osal/Memory.h>
#include <ti/sdo/ce/image1/imgenc1.h>
#include <ti/sdo/ce/trace/gt.h>
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <asm/types.h>
#include <linux/videodev.h>
#include <media/davinci_vpfe.h>
/* Demo headers */
#include <rendezvous.h>
#include <fifoutil.h>
#include <pause.h>
#include "encode.h"
#include "video.h"
#include "capture.h"
#include "writer.h"
#include "jpegenc.h"
/*
 *  The parameters for the encoding process. These can be changed to try
 *  different image sizes and JPEG features.
 */
#define SCANS          4
#define QVALUE         73
/* this example only supports YUV422 interleaved */
#define CHROMAFORMAT   XDM_YUV_422ILE
//#define CHROMAFORMAT   XDM_YUV_422P
#define JPEGENGINENAME "image"
/* Not a cached system, no buffer alignment constraints */
#define BUFALIGN Memory_DEFAULTALIGNMENT
static XDAS_Int8 *inBuf;
static XDAS_Int8 *encodedBuf;
static XDAS_Int32 inBufSize;
static XDAS_Int32 encodedBufSize;
static String progName     = "app";
static String encoderName  = "Jpegenc";
static String engineName   = "image";
static String image_base_name = "image";
// extern GT_Mask curMask;
static Int32 encode(IMGENC1_Handle hJpegenc, XDAS_Int8 * in, XDAS_Int8 * out );
void save( void * data, int len, char * basename, char * ext );
void *jpegencThrFxn(void *arg)
{
Engine_Handle  hEngine  = NULL;
IMGENC1_Handle  hJpegenc = NULL;
IMGENC1_Params  encParams;
IMGENC1_DynamicParams  dynParams;
IMGENC1_Status  imgStatus;
JpegencEnv *envp = (JpegencEnv *) arg;
void *status = THREAD_SUCCESS;
CaptureBufferElement ce;
//     IJPEGENC_DynamicParams      extDynParams;
char outFile[80];
int length;
    // Create a name for the output file
sprintf( outFile, "%s_%04d", image_base_name, 0 );
//  GT_0trace(curMask, GT_1CLASS, "Application started.\n");
/* open the Codec Engine */
if ((hEngine = Engine_open(JPEGENGINENAME, NULL, NULL)) == NULL) 
{
fprintf(stderr, "ERROR: can't open engine %s\n", engineName);
cleanup(THREAD_FAILURE);
}
printf("Engine Successfully Opend :\n");
/* allocate and initialize image encoder on the engine */
encParams.size = sizeof(IMGENC1_Params);
encParams.maxWidth = envp->imageWidth;
encParams.maxHeight = envp->imageHeight;
encParams.maxScans = SCANS;
encParams.dataEndianness = XDM_DEFAULT;
encParams.forceChromaFormat = CHROMAFORMAT;
if ((hJpegenc = IMGENC1_create(hEngine, encoderName, &encParams)) == NULL)
{
fprintf(stderr, "%s: error: can't open codec %s\n", progName, encoderName);
cleanup(THREAD_FAILURE);
}
printf("Codec Successfully Opend :\n");
/* set the parameters for jpeg encoding */
dynParams.size = sizeof(IMGENC1_DynamicParams);
dynParams.numAU = XDM_DEFAULT;
dynParams.inputChromaFormat = CHROMAFORMAT;
dynParams.inputHeight = envp->imageWidth / 2;
dynParams.inputWidth = envp->imageHeight / 2;
dynParams.captureWidth = 0;
dynParams.generateHeader = XDM_ENCODE_AU;
dynParams.qValue = QVALUE;
#if 0
/* set the extended parameters for encoding */
extDynParams.imgencDynamicParams = dynParams;
extDynParams.rstInterval = XDM_DEFAULT;
extDynParams.disableEOI = XDM_DEFAULT;
extDynParams.rotation = 90;
extDynParams.customQ = NULL;
imgStatus.size = sizeof(imgStatus);
    if (IMGENC1_control(hJpegenc, XDM_SETPARAMS, (IMGENC1_DynamicParams *)&extDynParams, &imgStatus) ==
        FAILURE) {
        fprintf(stderr, "%s: error: could not set PARAMS: 0x%x\n", progName,
            (unsigned int)imgStatus.extendedError);
        return FAILURE;
    }
#else
imgStatus.size = sizeof(imgStatus);
if (IMGENC1_control(hJpegenc, XDM_SETPARAMS, &dynParams, &imgStatus) == FAILURE) 
{
fprintf(stderr, "%s: error: could not set PARAMS: 0x%x\n", progName, (unsigned int)imgStatus.extendedError);
cleanup(THREAD_FAILURE);;
}
printf("Engine  PARAMS Successfully Set :\n");
#endif
    /* ask the codec for buffer sizes - these are typically conservative */
if (IMGENC1_control(hJpegenc, XDM_GETBUFINFO, &dynParams, &imgStatus) == FAILURE)
{
fprintf(stderr, "%s: error: could not get BUFINFO: 0x%x\n", progName, (unsigned int)imgStatus.extendedError);
cleanup(THREAD_FAILURE);;
}
printf("BUFINFO steps done :\n");
/* allocate input buffers based on GETBUFINFO */
inBufSize = imgStatus.bufInfo.minInBufSize[0];
printf("Req inbuf size,%x \n",inBufSize);
if ((inBuf = (XDAS_Int8 *)Memory_contigAlloc(inBufSize, BUFALIGN)) == NULL)
{
printf("Memory_ContigAlloc for inbuf Not done :\n");
}
/* allocate encoded buffers based on GETBUFINFO */
encodedBufSize = imgStatus.bufInfo.minOutBufSize[0];
printf("Req encodebuf size,%x \n",encodedBufSize);
if((encodedBuf = (XDAS_Int8 *)Memory_contigAlloc(encodedBufSize, BUFALIGN)) == NULL)
{
printf("Memory_ContigAlloc for encodeBuf Not done :\n");
}
if ((inBuf == NULL) || (encodedBuf == NULL)) 
{
printf("Memory_ContigAlloc Not done :\n");
cleanup(THREAD_FAILURE);
}
    /* Signal that initialization is done and wait for other threads */
Rendezvous_meet(envp->hRendezvousInit);
DBG("Entering video main loop.\n");
while (!gblGetQuit())
{
/* Pause processing? */
Pause_test(envp->hPause);
/* Get a buffer from the capture thread */
if (FifoUtil_get(envp->hCaptureOutFifo, &ce) == FIFOUTIL_FAILURE) 
{
ERR("Failed to put buffer in output fifo\n");
breakLoop(THREAD_FAILURE);
}
/* Is the capture thread flushing the pipe? */
if (ce.id == CAPTURE_FLUSH)
{
breakLoop(THREAD_SUCCESS);
}
/* Copy the data to where the encoder can access it */
printf("Copying data for encoder access\n");
// memcpy( inBuf, ce.virtBuf, inBufSize );
memcpy( inBuf, ce.physBuf, inBufSize );
printf("Data copied for encoder\n");
/* JpegEncode the captured video frame */
length = encode(hJpegenc, inBuf, encodedBuf );
printf("Images Saving....\n");
save( encodedBuf, length, outFile, "jpg" );
printf("Images Saved \n");
}
cleanup:
/* free buffers */
if (encodedBuf)
{
Memory_contigFree(encodedBuf, encodedBufSize);
}
if (inBuf)
{
Memory_contigFree(inBuf, inBufSize);
}
/* teardown the codec */
if (hJpegenc)
{
IMGENC1_delete(hJpegenc);
}
/* close the engine */
if (hEngine)
{
Engine_close(hEngine);
}
return status;
}
/*
 *  ======== encode ========
 */
static Int32 encode(IMGENC1_Handle hJpegenc, XDAS_Int8 * in, XDAS_Int8 * out )
{
Int32 status;
IMGENC1_InArgs encInArgs;
IMGENC1_OutArgs encOutArgs;
IMGENC1_DynamicParams encDynParams;
XDM1_BufDesc inBufDesc;
XDM1_BufDesc encodedBufDesc;
/* initialize buffer descriptors that hold input and output buffers */
inBufDesc.numBufs = 1;
inBufDesc.descs[0].bufSize = inBufSize;
inBufDesc.descs[0].buf = in;
encodedBufDesc.numBufs = 1;
encodedBufDesc.descs[0].bufSize = encodedBufSize;
encodedBufDesc.descs[0].buf = out;
/* the size field of Args and Params structs must be initialized */
encInArgs.size    = sizeof(encInArgs);
encOutArgs.size   = sizeof(encOutArgs);
encDynParams.size = sizeof(encDynParams);
    /* perform the image (JPEG) encoding */
printf("jpeg encoding starts\n");
status = IMGENC1_process( hJpegenc, &inBufDesc, &encodedBufDesc, &encInArgs, &encOutArgs);
printf("jpeg encoding Done\n");
if (status == IMGENC1_EOK) 
{
//  GT_2trace(curMask, GT_2CLASS,
//  "Encoder process returned - 0x%x, %d bytes\n", status,
//  encOutArgs.bytesGenerated
//  );
//  fwrite(encodedBuf, 1, encOutArgs.bytesGenerated, filename);
}
else
{
//  GT_2trace(curMask, GT_7CLASS,
//  "Encoder frame processing FAILED, status = 0x%x, "
//  "extendedError = 0x%x\n", status,
//  encOutArgs.extendedError);
return FAILURE;
}
return encOutArgs.bytesGenerated;
}
void save( void * data, int len, char * basename, char * ext )
{
char name[80];
FILE * out;
int ret;
sprintf( name, "%s.%s", basename, ext );
if ((out = fopen(name, "wb")) == NULL) {
fprintf(stderr, "ERROR: can't write to file %s\n", name);
} else {
ret = fwrite(data, 1, len, out);
if ( ret != len ) {
fprintf( stderr
,"ERROR: '%s' only wrote %d bytes, expected %d bytes\n"
,name
,ret
,len
);
} else {
fclose( out );
}
}
}
 
I will appreciate for your replies.
  • I do not believe it is possible to have both codecs open at the same time as they both rely on the MJCP hardware accelerator, thus for example if you had JPEG open and you tried to open MPEG there would be some sort of hardware conflict where both codecs are trying to use the same accelerator at the same time. The errors you are getting may be something else, though I would expect some sort of error if you tried to open a second codec. You could probably switch between them from the same program by closing one and than opening the other, though I have not tried this myself.

  • with proper configuration, JPEG and MPEG4 codec can be used in diferrent threads, but they can not work at the same time.

    For Example:

    Thread 1 : 720p JPEG encoding cost 23ms

    Thread 2: 720p MPEG4 one frame encoding cost 25ms

    Total Cost will be at least 49ms.