Example #1
0
DvevmStRetCode
dvtb_MPEG4Enc1Encode(DvevmStMPEG4Enc1Info *ve, int* encDuration)
{
    XDAS_Int32 status = -1;
    DvevmStTime timeStmpBfrEnc, timeStmpAftrEnc;
    DvevmStRetCode retCode = DVEVM_ST_SUCCESS;

    ASSERT(ve != NULL);
    ASSERT(ve->ceHdl != NULL);
    ASSERT(ve->venc1Hdl != NULL);

    timeStmpBfrEnc = dvtb_getTime( );
    status = VIDENC1_process(ve->venc1Hdl, &ve->inBufDesc, &ve->outBufDesc, (IVIDENC1_InArgs *) (&ve->venc1InArgs), (IVIDENC1_OutArgs *) (&ve->venc1OutArgs));
    timeStmpAftrEnc = dvtb_getTime( );
    *encDuration = ((timeStmpAftrEnc.tv_sec * NUM_MICROSECS_IN_SEC) + timeStmpAftrEnc.tv_usec) - ((timeStmpBfrEnc.tv_sec * NUM_MICROSECS_IN_SEC) + timeStmpBfrEnc.tv_usec);

    if (status != VIDENC1_EOK)
    {
        SYS_ERROR("Video Encode Process failed (%d), Codec Error : %d\n", (int) status, (int) ve->venc1OutArgs.videncOutArgs.extendedError);
        retCode = DVEVM_ST_FAIL;
    }

    if (DVEVM_ST_FAIL != retCode)
        dvtb_MPEG4Enc1ProcessDebug(&ve->venc1OutArgs);

    return retCode;
}
Example #2
0
//changed by zeng
int ALG_vidEncRun(void *hndl, ALG_VidEncRunPrm *prm, ALG_VidEncRunStatus *runStatus, CallBackSetOSDPixel func)
{
  ALG_VidEncObj *pObj = (ALG_VidEncObj*)hndl;
  IVIDEO1_BufDescIn  inBufDesc;
  XDM_BufDesc        outBufDesc;
  XDAS_Int32         status;
  VIDENC1_InArgs   	 inArgs;
  VIDENC1_OutArgs    outArgs;
  IH264VENC_InArgs 	 h264InArgs;
  IH264VENC_OutArgs  h264OutArgs;
  XDAS_Int32         offset;
  XDAS_Int32         outBufSizeArray[2];
  XDAS_UInt8         *dst[2],i=0;
  static unsigned long h264Timestamp = 0;

  runStatus->bytesGenerated = 0;
  runStatus->isKeyFrame     = FALSE;
  runStatus->numMB          = 0;

  if(pObj==NULL)
    return OSA_EFAIL;

  if(pObj->createPrm.codec==ALG_VID_CODEC_MJPEG)
  {
    ALG_JpgEncRunPrm jpgRun;
    ALG_JpgEncRunStatus jpgStatus;

    jpgRun.inStartX = prm->inStartX;
    jpgRun.inStartY = prm->inStartY;
    jpgRun.inAddr   = prm->inAddr;
    jpgRun.outAddr  = prm->outAddr;
    jpgRun.outDataMaxSize = prm->outDataMaxSize;

    jpgRun.snapEnable = prm->snapEnable;
	strcpy(jpgRun.snapFilename, prm->snapFilename);

	OSA_mutexLock(&vnf_imcop_lock);
	OSA_mutexLock(&vicp_imcop_lock);

        status = ALG_jpgEncRun(pObj->hJpgEncode, &jpgRun, &jpgStatus, NULL);

	OSA_mutexUnlock(&vnf_imcop_lock);
	OSA_mutexUnlock(&vicp_imcop_lock);

    runStatus->isKeyFrame     = TRUE;

    if(status!=OSA_SOK) {

      return OSA_EFAIL;
    }

    runStatus->bytesGenerated = jpgStatus.bytesGenerated;

    return OSA_SOK;
  }

  offset = pObj->createPrm.offsetH * pObj->createPrm.offsetV;

  if(prm->outDataMaxSize==0)
    prm->outDataMaxSize = pObj->createPrm.width*pObj->createPrm.height*2;

  outBufSizeArray[0] = prm->outDataMaxSize;

  prm->inStartY = OSA_floor(prm->inStartY, 2);
  prm->inStartX = OSA_floor(prm->inStartX, 2);

  inBufDesc.numBufs       = 2;
  inBufDesc.frameWidth    = OSA_align(pObj->createPrm.width, 16);
  inBufDesc.frameHeight   = OSA_align(pObj->createPrm.height, 16);
  inBufDesc.framePitch    = pObj->createPrm.offsetH;

  inBufDesc.bufDesc[0].bufSize = pObj->createPrm.offsetH*inBufDesc.frameHeight ;
  inBufDesc.bufDesc[0].buf     = (XDAS_Int8*)(prm->inAddr + prm->inStartY*pObj->createPrm.offsetH + prm->inStartX);
  inBufDesc.bufDesc[0].accessMask = 0;

  inBufDesc.bufDesc[1].bufSize = pObj->createPrm.offsetH*inBufDesc.frameHeight/2;
  inBufDesc.bufDesc[1].buf     = (XDAS_Int8*)(prm->inAddr + offset + prm->inStartY*pObj->createPrm.offsetH/2 + prm->inStartX);
  inBufDesc.bufDesc[1].accessMask = 0;

  if(prm->snapEnable) {
  	OSA_fileWriteVideoData(prm->snapFilename, (Uint8 *)inBufDesc.bufDesc[0].buf, (Uint8 *)inBufDesc.bufDesc[1].buf,
  		inBufDesc.frameWidth, inBufDesc.frameHeight, inBufDesc.framePitch);
  }

  if( pObj->MV_Size == 0 )
  {
	  outBufDesc.numBufs  = 1;
	  outBufDesc.bufSizes = outBufSizeArray;
	  outBufDesc.bufs     = (XDAS_Int8 **) &prm->outAddr;
  }
  else {

	dst[0]	           = prm->outAddr;
	dst[1]             = pObj->MV_Addr;
	outBufSizeArray[1] = pObj->MV_Size;

	outBufDesc.numBufs  = 2;
	outBufDesc.bufSizes = outBufSizeArray;
	outBufDesc.bufs     = dst;
  }

	inArgs.size         		= sizeof(VIDENC1_InArgs);
	inArgs.inputID 				= 1;
	inArgs.topFieldFirstFlag	= 0;

	if(pObj->createPrm.codec==ALG_VID_CODEC_H264)
	{
		h264InArgs.videncInArgs 			= inArgs;
		h264InArgs.videncInArgs.size 		= sizeof(IH264VENC_InArgs);
		h264InArgs.roiParameters.numOfROI 	= (prm->roiPrm.numROI>=MAX_ROI)?MAX_ROI:prm->roiPrm.numROI;
		for(i=0;i<h264InArgs.roiParameters.numOfROI;i++)
		{
			h264InArgs.roiParameters.listROI[i].topLeft.x = prm->roiPrm.roiInfo[i].topLeft_x;
			h264InArgs.roiParameters.listROI[i].topLeft.y = prm->roiPrm.roiInfo[i].topLeft_y;
			h264InArgs.roiParameters.listROI[i].bottomRight.x = prm->roiPrm.roiInfo[i].bottomRight_x;
			h264InArgs.roiParameters.listROI[i].bottomRight.y = prm->roiPrm.roiInfo[i].bottomRight_y;
			h264InArgs.roiParameters.roiPriority[i] = prm->roiPrm.roiInfo[i].roiPriority;

			printf("ROI[%d]=(%d,%d,%d,%d)roiPriority=%d\n" , i, prm->roiPrm.roiInfo[i].topLeft_x , prm->roiPrm.roiInfo[i].topLeft_y ,
				prm->roiPrm.roiInfo[i].bottomRight_x , prm->roiPrm.roiInfo[i].bottomRight_y ,prm->roiPrm.roiInfo[i].roiPriority );
			CheckROIBoundary(&h264InArgs.roiParameters.listROI[i].topLeft, pObj->createPrm.width, pObj->createPrm.height);
			CheckROIBoundary(&h264InArgs.roiParameters.listROI[i].bottomRight, pObj->createPrm.width, pObj->createPrm.height);

			switch(prm->roiPrm.roiInfo[i].roiType)
			{
				case ALG_VID_ENC_ROI_TYPE_FACE:
					h264InArgs.roiParameters.roiType[i] = FACE_OBJECT;
					break;
				case ALG_VID_ENC_ROI_TYPE_PRIVACYMASK:
					h264InArgs.roiParameters.roiType[i] = PRIVACY_MASK;
					break;
				case ALG_VID_ENC_ROI_TYPE_FOREGROUND:
					h264InArgs.roiParameters.roiType[i] = FOREGROUND_OBJECT;
					break;
				default: // No other Types currently supported
					h264InArgs.roiParameters.roiType[i] = DEFAULT_OBJECT;
					break;
			}
		}
		h264InArgs.timeStamp 			= h264Timestamp;
		h264InArgs.insertUserData 		= XDAS_FALSE;
		h264InArgs.lengthUserData 		= 0;
		h264InArgs.numOutputDataUnits 	= 0;
		h264Timestamp = h264Timestamp + 2;
	}

	if(pObj->createPrm.codec == ALG_VID_CODEC_H264)
	{
    	h264OutArgs.videncOutArgs.size = sizeof(IH264VENC_OutArgs);
	}
    else {
    	outArgs.size = sizeof(VIDENC1_OutArgs);
    }

	if(pObj->createPrm.codec!=ALG_VID_CODEC_H264)
	{
  		OSA_mutexLock(&vnf_imcop_lock);
  		OSA_mutexLock(&vicp_imcop_lock);
	}
	else {
		/*
		Can be commented if pObj->params_h264.enableDDRbuff = 1;
		This way, VICP functions can be ran in parallel with H.264.
		But since DDR version of H.264 is slower, only useful
		if you need to hide VICP processing behind H.264 to
		meet system fps target.
		*/
		if (pObj->params_h264.enableDDRbuff== 0)
			OSA_mutexLock(&vicp_imcop_lock);
  	}

    //OSA_printf("\n Entering Encode process \n");
	if( NULL != func ){
		func(inBufDesc.frameWidth, inBufDesc.frameHeight, inBufDesc.bufDesc[0].buf, inBufDesc.bufDesc[1].buf);
	}

    if(pObj->createPrm.codec==ALG_VID_CODEC_H264)
        status = VIDENC1_process(pObj->hEncode, &inBufDesc, &outBufDesc, (VIDENC1_InArgs*)&h264InArgs, (IVIDENC1_OutArgs*)&h264OutArgs);
    else
        status = VIDENC1_process(pObj->hEncode, &inBufDesc, &outBufDesc, &inArgs, &outArgs);

    //OSA_printf("\n Exiting Encode process : %d %d \n", status, VIDENC1_EOK);

	if(pObj->createPrm.codec!=ALG_VID_CODEC_H264)
	{
		OSA_mutexUnlock(&vicp_imcop_lock);
		OSA_mutexUnlock(&vnf_imcop_lock);
	}
	else {
		/*   Can be commented if pObj->params_h264.enableDDRbuff = 1;
		This way, VICP functions can be ran in parallel with H.264.
		But since DDR version of H.264 is slower, only useful
		if you need to hide VICP processing behind H.264 to
		meet system fps target.
		*/
		if (pObj->params_h264.enableDDRbuff== 0)
			OSA_mutexUnlock(&vicp_imcop_lock);
	}

    if(pObj->createPrm.codec==ALG_VID_CODEC_H264) {
		if (status != VIDENC1_EOK){
			//OSA_printf("CODEC RUN FAIL ERROR CODE: %d %d %d\n", status, h264OutArgs.videncOutArgs.extendedError, h264OutArgs.videncOutArgs.bytesGenerated);
			return OSA_EFAIL;
		}
		runStatus->bytesGenerated 	= h264OutArgs.videncOutArgs.bytesGenerated;
		runStatus->temporalId 		= GetSVCtemporalId(pObj->params_h264.numTemporalLayers,
	                                  					h264OutArgs.videncOutArgs.encodedFrameType,
									  					h264OutArgs.videncOutArgs.bytesGenerated);

		if(h264OutArgs.videncOutArgs.encodedFrameType==IVIDEO_I_FRAME || h264OutArgs.videncOutArgs.encodedFrameType==IVIDEO_IDR_FRAME)
			runStatus->isKeyFrame = TRUE;
	}
	else {
		if (status != VIDENC1_EOK){
			//OSA_printf("CODEC RUN FAIL ERROR CODE: %d %d %d\n", status, outArgs.extendedError, outArgs.bytesGenerated);
			return OSA_EFAIL;
		}
		runStatus->bytesGenerated = outArgs.bytesGenerated;

		if(outArgs.encodedFrameType==IVIDEO_I_FRAME || outArgs.encodedFrameType==IVIDEO_IDR_FRAME)
			runStatus->isKeyFrame = TRUE;
	}

	return OSA_SOK;
}
Example #3
0
/*
 *  ======== encode_decode ========
 */
static Void encode_decode(VIDENC1_Handle enc, VIDDEC2_Handle dec, FILE *in,
    FILE *out)
{
    Int                         n;
    Int32                       status;

    VIDDEC2_InArgs              decInArgs;
    VIDDEC2_OutArgs             decOutArgs;
    VIDDEC2_DynamicParams       decDynParams;
    VIDDEC2_Status              decStatus;

    VIDENC1_InArgs              encInArgs;
    VIDENC1_OutArgs             encOutArgs;
    VIDENC1_DynamicParams       encDynParams;
    VIDENC1_Status              encStatus;

    IVIDEO1_BufDescIn           encInBufDesc;

    XDM_BufDesc                 encOutBufDesc;
    XDAS_Int8                  *encoded[XDM_MAX_IO_BUFFERS];
    XDAS_Int32                  encBufSizes[XDM_MAX_IO_BUFFERS];

    XDM1_BufDesc                decInBufDesc;

    XDM_BufDesc                 decOutBufDesc;
    XDAS_Int8                  *dst[XDM_MAX_IO_BUFFERS];
    XDAS_Int32                  outBufSizes[XDM_MAX_IO_BUFFERS];

    /* clear and initialize the buffer descriptors */
    memset(encoded, 0, sizeof(encoded[0]) * XDM_MAX_IO_BUFFERS);
    memset(dst,     0, sizeof(dst[0])     * XDM_MAX_IO_BUFFERS);

    encoded[0] = encodedBuf;
    dst[0]     = outBuf;

    encInBufDesc.numBufs = encOutBufDesc.numBufs = decInBufDesc.numBufs =
        decOutBufDesc.numBufs = 1;

    encOutBufDesc.bufSizes  = encBufSizes;
    decOutBufDesc.bufSizes  = outBufSizes;

    encInBufDesc.bufDesc[0].bufSize = encBufSizes[0] =
        decInBufDesc.descs[0].bufSize = outBufSizes[0] = NSAMPLES;

    encInBufDesc.bufDesc[0].buf = inBuf;
    encOutBufDesc.bufs = encoded;
    decInBufDesc.descs[0].buf = encoded[0];
    decOutBufDesc.bufs     = dst;

    encInBufDesc.frameWidth     = 0;  /* TODO */
    encInBufDesc.frameHeight    = 0;  /* TODO */
    encInBufDesc.framePitch     = 0;  /* TODO */

    /* initialize all "sized" fields */
    encInArgs.size    = sizeof(encInArgs);
    decInArgs.size    = sizeof(decInArgs);
    encOutArgs.size   = sizeof(encOutArgs);
    decOutArgs.size   = sizeof(decOutArgs);
    encDynParams.size = sizeof(encDynParams);
    decDynParams.size = sizeof(decDynParams);
    encStatus.size    = sizeof(encStatus);
    decStatus.size    = sizeof(decStatus);

    /*
     * Note that we use versionBuf in both the encoder and decoder.  In this
     * application, this is okay, as there is always only one user of
     * the buffer.  Not all applications can make this assumption.
     */
    encStatus.data.buf     = decStatus.data.buf     = versionBuf;
    encStatus.data.bufSize = decStatus.data.bufSize = MAXVERSIONSIZE;

    /* if the codecs support it, dump their versions */
    status = VIDDEC2_control(dec, XDM_GETVERSION, &decDynParams, &decStatus);
    Log_print1(Diags_USER1, "[+1] Decoder version:  %s",
            (IArg)((status == VIDDEC2_EOK ? ((char *)decStatus.data.buf) :
            "[unknown]")));

    status = VIDENC1_control(enc, XDM_GETVERSION, &encDynParams, &encStatus);
    Log_print1(Diags_USER1, "[+1] Encoder version:  %s",
            (IArg)((status == VIDENC1_EOK ? ((char *)encStatus.data.buf) :
            "[unknown]")));

    /*
     * This app expects the encoder to provide 1 buf in and get 1 buf out,
     * and the buf sizes of the in and out buffer must be able to handle
     * NSAMPLES bytes of data.
     */
    status = VIDENC1_control(enc, XDM_GETSTATUS, &encDynParams, &encStatus);
    if (status != VIDENC1_EOK) {
        /* failure, report error and exit */
        Log_print1(Diags_USER7, "[+7] encode control status = %ld",
                (IArg)status);
        return;
    }

    /* Validate this encoder codec will meet our buffer requirements */
    if ((encInBufDesc.numBufs < encStatus.bufInfo.minNumInBufs) ||
        (IFRAMESIZE < encStatus.bufInfo.minInBufSize[0]) ||
        (encOutBufDesc.numBufs < encStatus.bufInfo.minNumOutBufs) ||
        (EFRAMESIZE < encStatus.bufInfo.minOutBufSize[0])) {

        /* failure, report error and exit */
        Log_print0(Diags_USER7, "[+7] Error:  encoder codec feature conflict");
        return;
    }

    status = VIDDEC2_control(dec, XDM_GETSTATUS, &decDynParams, &decStatus);
    if (status != VIDDEC2_EOK) {
        /* failure, report error and exit */
        Log_print1(Diags_USER7, "[+7] decode control status = %ld",
                (IArg)status);
        return;
    }

    /* Validate this decoder codec will meet our buffer requirements */
    if ((decInBufDesc.numBufs < decStatus.bufInfo.minNumInBufs) ||
        (EFRAMESIZE < decStatus.bufInfo.minInBufSize[0]) ||
        (decOutBufDesc.numBufs < decStatus.bufInfo.minNumOutBufs) ||
        (OFRAMESIZE < decStatus.bufInfo.minOutBufSize[0])) {

        /* failure, report error and exit */
        Log_print0(Diags_USER7,
                "[+7] App-> ERROR: decoder does not meet buffer requirements.");
        return;
    }

    /*
     * Read complete frames from in, encode, decode, and write to out.
     */
    for (n = 0; fread(inBuf, IFRAMESIZE, 1, in) == 1; n++) {

#ifdef CACHE_ENABLED
#if defined(xdc_target__isaCompatible_64P) || \
    defined(xdc_target__isaCompatible_64T)
        /*
         *  fread() on this processor is implemented using CCS's stdio, which
         *  is known to write into the cache, not physical memory.  To meet
         *  XDAIS DMA Rule 7, we must writeback the cache into physical
         *  memory.  Also, per DMA Rule 7, we must invalidate the buffer's
         *  cache before providing it to any xDAIS algorithm.
         */
        Memory_cacheWbInv(inBuf, IFRAMESIZE);
#else
#error Unvalidated config - add appropriate fread-related cache maintenance
#endif
        /* Per DMA Rule 7, our output buffer cache lines must be cleaned */
        Memory_cacheInv(encodedBuf, EFRAMESIZE);
#endif

        Log_print1(Diags_USER1, "[+1] App-> Processing frame %d...", (IArg)n);

        /*
         * Encode the frame.
         *
         * Note, inputID == 0 is an error.  This example doesn't account
         * for the case where 'n + 1' wraps to zero.
         */
        encInArgs.inputID = n + 1;
        status = VIDENC1_process(enc, &encInBufDesc, &encOutBufDesc, &encInArgs,
            &encOutArgs);

        Log_print2(Diags_USER2,
                "[+2] App-> Encoder frame %d process returned - 0x%x)",
                (IArg)n, (IArg)status);

        if (status != VIDENC1_EOK) {
            Log_print3(Diags_USER7,
                    "[+7] App-> Encoder frame %d processing FAILED, status = 0x%x, "
                    "extendedError = 0x%x",
                    (IArg)n, (IArg)status, (IArg)(encOutArgs.extendedError));
            break;
        }

        /*
         * So far, so good.  Validate our assumption that the encoder
         * provided encodedBuf as it's encOutArgs->encodedBuf.buf.  If
         * that's not the case, we may be dealing with a codec that's
         * giving us out of order frames... and this simple app
         * doesn't support that.
         */
        if (encOutArgs.encodedBuf.buf != encodedBuf) {
            Log_print0(Diags_USER7,
                    "[+7] App-> Internal error.  Unsupported encoder");
            break;
        }

#ifdef CACHE_ENABLED
        /*
         * Conditionally writeback the encoded buf from the previous
         * call.  Also, as encodedBuf is an inBuf to the next process
         * call, conditionally invalidate it as well.
         */
        if (XDM_ISACCESSMODE_WRITE(encOutArgs.encodedBuf.accessMask)) {
            Memory_cacheWbInv(encodedBuf, EFRAMESIZE);
        }

        /*
         * Per DMA Rule 7, our output buffer cache lines (for the
         * upcoming decoder) must be cleaned.
         */
        Memory_cacheInv(outBuf, OFRAMESIZE);
#endif

        /* decode the frame */
        decInArgs.numBytes = EFRAMESIZE;
        decInArgs.inputID = 1;  /* typically this varies by each frame */
        status = VIDDEC2_process(dec, &decInBufDesc, &decOutBufDesc,
            &decInArgs, &decOutArgs);

        Log_print2(Diags_USER2,
                "[+2] App-> Decoder frame %d process returned - 0x%x)",
                (IArg)n, (IArg)status);

        if (status != VIDDEC2_EOK) {
            Log_print2(Diags_USER7,
                    "[+7] App-> Decoder frame %d processing FAILED, status ="
                    " 0x%x", (IArg)n, (IArg)status);
            break;
        }

        /* again, validate our assumption that we don't get out-of-order bufs */
        if (decOutArgs.decodedBufs.bufDesc[0].buf != outBuf) {
            Log_print0(Diags_USER7,
                    "[+7] App-> Internal error.  Unsupported decoder");
            break;
        }

#ifdef CACHE_ENABLED
        /* Conditionally writeback the decoded buf */
        if (XDM_ISACCESSMODE_WRITE(
                decOutArgs.decodedBufs.bufDesc[0].accessMask)) {
            Memory_cacheWb(outBuf, OFRAMESIZE);
        }
#endif

        /* write to file */
        fwrite(dst[0], OFRAMESIZE, 1, out);
    }

    Log_print1(Diags_USER1, "[+1] %d frames encoded/decoded", (IArg)n);
}
Example #4
0
Void *deiThrFxn(Void *arg)
{
	DeiEnv *envp = (DeiEnv *) arg;
	Void *status = THREAD_SUCCESS;

	Uint32 sysRegBase = 0;

	VIDENC1_Handle hDei = NULL;
	IDEI_Params deiParams;

	Uint16 frame_width = 0, frame_height = 0;
	Uint16 threshold_low = 0, threshold_high = 0;

	IVIDEO1_BufDescIn inBufDesc;	
	XDM_BufDesc outBufDesc;	
	XDAS_Int8 *outbufs[2];	
	XDAS_Int32 outBufSizeArray[2];
	VIDENC1_InArgs inArgs;
	IDEI_OutArgs outArgs;	
	Uint32 bufferSize;

	CMEM_AllocParams cmemPrm;
	Uint32 prevBufAddr, outBufAddr;

	Buffer_Handle cBuf, dBuf;

	Int ret = 0;

	int fd = -1;
	dm365mmap_params_t dm365mmap_params;
	pthread_mutex_t Dmai_DM365dmaLock = PTHREAD_MUTEX_INITIALIZER;

	/* ▼▼▼▼▼ Initialization ▼▼▼▼▼ */
	DM365MM_init(); printf("\n"); /* dm365mm issue */
	sysRegBase = DM365MM_mmap(0x01C40000, 0x4000);

	CMEM_init();
	cmemPrm.type = CMEM_HEAP;
	cmemPrm.flags = CMEM_NONCACHED;
	cmemPrm.alignment = 32;
	prevBufAddr = (Uint32)CMEM_alloc(IN_OUT_BUF_SIZE, &cmemPrm);
	outBufAddr = (Uint32)CMEM_alloc(IN_OUT_BUF_SIZE, &cmemPrm);

	frame_width = 720;
	frame_height = 576;
	threshold_low = 16;
	threshold_high = 20;

	/* Create DEI instance */	
	deiParams.videncParams.size = sizeof(IDEI_Params);
	deiParams.frameHeight = frame_height;
	deiParams.frameWidth = frame_width; 
	deiParams.inLineOffset = frame_width;
	deiParams.outLineOffset = (frame_width - 8);	
	deiParams.threshold_low = threshold_low;
	deiParams.threshold_high = threshold_high;

	deiParams.inputFormat = XDM_YUV_422ILE;	
	deiParams.outputFormat = XDM_YUV_420SP;
	
	deiParams.q_num = 1;
	deiParams.askIMCOPRes = 0; 
	deiParams.sysBaseAddr = sysRegBase;

	hDei = VIDENC1_create(envp->hEngine, "dei", (VIDENC1_Params *)&deiParams);						  
    if(hDei == NULL)
	{
		ERR("DEI alg creation failed\n");
        cleanup(THREAD_FAILURE);		
	}

	fd = open("/dev/dm365mmap", O_RDWR | O_SYNC);

	

	Rendezvous_meet(envp->hRendezvousInit);
	/* ▲▲▲▲▲ Initialization ▲▲▲▲▲ */
	while (1) {

		if (Fifo_get(envp->hFromCaptureFifo, &cBuf) < 0) {
			ERR("Failed to get buffer from capture thread\n");
			cleanup(THREAD_FAILURE);
		}

		if (Fifo_get(envp->hFromDisplayFifo, &dBuf) < 0) {
			ERR("Failed to get buffer from display thread\n");
			cleanup(THREAD_FAILURE);
		}

		inBufDesc.numBufs = 4;

		bufferSize = (frame_width * frame_height);
		
		inBufDesc.bufDesc[0].bufSize = bufferSize;
		inBufDesc.bufDesc[0].buf = (XDAS_Int8 *)Buffer_getUserPtr(cBuf);
		inBufDesc.bufDesc[0].accessMask = 0;

		inBufDesc.bufDesc[1].bufSize = bufferSize;
		inBufDesc.bufDesc[1].buf = (XDAS_Int8 *)(Buffer_getUserPtr(cBuf) + bufferSize);
		inBufDesc.bufDesc[1].accessMask = 0;

		inBufDesc.bufDesc[2].bufSize = bufferSize;
		inBufDesc.bufDesc[2].buf = (XDAS_Int8 *)prevBufAddr;
		inBufDesc.bufDesc[2].accessMask = 0;

		inBufDesc.bufDesc[3].bufSize = bufferSize;
		inBufDesc.bufDesc[3].buf = (XDAS_Int8 *)(prevBufAddr + bufferSize);
		inBufDesc.bufDesc[3].accessMask = 0;	
		
		/* Output buffers */
		outBufDesc.numBufs = 2;
		outbufs[0] = (XDAS_Int8*)outBufAddr;
		outbufs[1] = (XDAS_Int8*)(outBufAddr + bufferSize);
		outBufSizeArray[0] = bufferSize;
		outBufSizeArray[1] = bufferSize / 2;

		outBufDesc.bufSizes = outBufSizeArray;
		outBufDesc.bufs = outbufs;

		inArgs.size = sizeof(VIDENC1_InArgs);
		outArgs.videncOutArgs.size = sizeof(IDEI_OutArgs);

		ret = VIDENC1_process((VIDENC1_Handle)hDei,
								 &inBufDesc,
								 &outBufDesc,
								 &inArgs,
								 (IVIDENC1_OutArgs *)&outArgs);
		if (ret != VIDENC1_EOK) {
			ERR("DEI process failed\n");
			cleanup(THREAD_FAILURE);
		}

		dm365mmap_params.src = CMEM_getPhys(outbufs[0]);
		dm365mmap_params.srcmode = 0;
		dm365mmap_params.dst = Buffer_getPhysicalPtr(dBuf);
		dm365mmap_params.dstmode = 0;
		dm365mmap_params.srcbidx = 712;
		dm365mmap_params.dstbidx = 704;
		dm365mmap_params.acnt = 704;
		dm365mmap_params.bcnt = 576;
		dm365mmap_params.ccnt = 1;
		dm365mmap_params.bcntrld = dm365mmap_params.bcnt;
		dm365mmap_params.syncmode = 1;

		pthread_mutex_lock(&Dmai_DM365dmaLock);
		if (ioctl(fd, DM365MMAP_IOCMEMCPY, &dm365mmap_params) == -1) {
        	ERR("memcpy: Failed to do memcpy\n");
        	cleanup(THREAD_FAILURE);
    	}
		pthread_mutex_unlock(&Dmai_DM365dmaLock);

    	dm365mmap_params.src = CMEM_getPhys(outbufs[1]);
    	dm365mmap_params.srcmode = 0;
    	dm365mmap_params.dst = Buffer_getPhysicalPtr(dBuf) + (Buffer_getSize(dBuf) * 2 / 3);
    	dm365mmap_params.dstmode = 0;
    	dm365mmap_params.srcbidx = 712;
		dm365mmap_params.dstbidx = 704;
    	dm365mmap_params.acnt = 712;
    	dm365mmap_params.bcnt = 570 / 2;
    	dm365mmap_params.ccnt = 1;
    	dm365mmap_params.bcntrld = dm365mmap_params.bcnt;
    	dm365mmap_params.syncmode = 1;

		pthread_mutex_lock(&Dmai_DM365dmaLock);
		if (ioctl(fd, DM365MMAP_IOCMEMCPY, &dm365mmap_params) == -1) {
        	ERR("memcpy: Failed to do memcpy\n");
        	cleanup(THREAD_FAILURE);
    	}
		pthread_mutex_unlock(&Dmai_DM365dmaLock);
    	Buffer_setNumBytesUsed(dBuf, 704 * 576 * 3 / 2);

    	dm365mmap_params.src = Buffer_getPhysicalPtr(cBuf);
    	dm365mmap_params.srcmode = 0;
    	dm365mmap_params.dst = prevBufAddr;
    	dm365mmap_params.dstmode = 0;
    	dm365mmap_params.srcbidx = 1440;
		dm365mmap_params.dstbidx = 1440;
    	dm365mmap_params.acnt = 1440;
    	dm365mmap_params.bcnt = 576;
    	dm365mmap_params.ccnt = 1;
    	dm365mmap_params.bcntrld = dm365mmap_params.bcnt;
    	dm365mmap_params.syncmode = 1;

    	pthread_mutex_lock(&Dmai_DM365dmaLock);
		if (ioctl(fd, DM365MMAP_IOCMEMCPY, &dm365mmap_params) == -1) {
        	ERR("memcpy: Failed to do memcpy\n");
        	cleanup(THREAD_FAILURE);
    	}
		pthread_mutex_unlock(&Dmai_DM365dmaLock);

		/* Send buffer to display thread */
		if (Fifo_put(envp->hToDisplayFifo, dBuf) < 0) {
			ERR("Failed to send buffer to dei thread\n");
			cleanup(THREAD_FAILURE);
		}

		/* Send buffer to display thread */
		if (Fifo_put(envp->hToCaptureFifo, cBuf) < 0) {
			ERR("Failed to send buffer to dei thread\n");
			cleanup(THREAD_FAILURE);
		}

	}

cleanup:
	Rendezvous_force(envp->hRendezvousInit);
	Rendezvous_meet(envp->hRendezvousCleanup);

	/* Delete DEI ALG instance */
	VIDENC1_delete(hDei);

	DM365MM_ummap(sysRegBase,0x4000);

	DM365MM_exit();

	if (fd > 0) {   
        close(fd);
    }

	return status;
}
/*
 *  ======== call ========
 */
static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg)
{
    _VIDENC1_Msg *msg  = (_VIDENC1_Msg *)visaMsg;
    VIDENC1_Handle handle = (VIDENC1_Handle)visaHandle;
    Int i;
    IVIDEO1_BufDescIn inBufs;
    XDM_BufDesc outBufs;
    IVIDENC1_OutArgs *pOutArgs;
    IVIDENC1_Status *pStatus;
    IVIDENC1_CodecClassConfig *codecClassConfig;
    Int numBufs;

    /* get stub/skeleton config data; can be NULL (for old codecs) */
    codecClassConfig = (IVIDENC1_CodecClassConfig *)
                        VISA_getCodecClassConfig( visaHandle );


    /* perform the requested VIDENC1 operation by parsing message. */
    switch (msg->visa.cmd) {

        case _VIDENC1_CPROCESS: {
            /* unmarshall inBufs and outBufs */
            inBufs           = msg->cmd.process.inBufs;

            outBufs.bufs     = msg->cmd.process.outBufs;
            outBufs.numBufs  = msg->cmd.process.numOutBufs;
            outBufs.bufSizes = msg->cmd.process.outBufSizes;

            if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) {
                /* invalidate cache for all input buffers */
                for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) {
                    if (inBufs.bufDesc[i].buf != NULL) {
                        /* valid member of sparse array,
                         * invalidate it unless user configured it not to
                         */
                        if (codecClassConfig != NULL &&
                                codecClassConfig->manageInBufsCache[i] ==
                                FALSE) {
                            /* do nothing, i.e. don't invalidate */
                        } else {
                            Memory_cacheInv(inBufs.bufDesc[i].buf,
                                    inBufs.bufDesc[i].bufSize);
                        }

                        if (++numBufs == inBufs.numBufs) {
                            break;
                        }
                    }
                }

                /* invalidate cache for all output buffers */
                for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) {
                    if (outBufs.bufs[i] != NULL) {
                        /* valid member of sparse array,
                         * invalidate it unless user configured it not to
                         */
                        if (codecClassConfig != NULL &&
                                codecClassConfig->manageOutBufsCache[i] ==
                                FALSE) {
                            /* do nothing, i.e. don't invalidate */
                        } else {
                            Memory_cacheInv(outBufs.bufs[i],
                                    outBufs.bufSizes[i]);
                        }

                        if (++numBufs == outBufs.numBufs) {
                            break;
                        }
                    }
                }
            } /* SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB */

            /* unmarshall outArgs based on the "size" of inArgs */
            pOutArgs = (IVIDENC1_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) +
                msg->cmd.process.inArgs.size);

            /*
             * Note, there's no need to invalidate cache for
             * pOutArgs->encodedBuf bufs nor pOutArgs->reconBufs bufs as they're
             * not _really_ OUT buffers.  Rather they're references to
             * the _real_ OUT buffers that are provided in outBufs - which
             * were already invalidated above.
             */

            /* make the process call */
            msg->visa.status = VIDENC1_process(handle,
                &inBufs, &outBufs, &(msg->cmd.process.inArgs), pOutArgs);

            if (SKEL_cachingPolicy == SKEL_WBINVALL) {
                Memory_cacheWbInvAll();
            }
            else if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) {
                /* writeback cache for encoded buffer */
                if ((pOutArgs->encodedBuf.buf != NULL) &&
                        (XDM_ISACCESSMODE_WRITE(pOutArgs->encodedBuf.accessMask))) {
                    Memory_cacheWb(pOutArgs->encodedBuf.buf,
                            pOutArgs->encodedBuf.bufSize);

                    /*
                     * Since we've cacheWb this buffer, we arguably should
                     * reflect this cache state and clear the WRITE bit in
                     * the .accessMask field.  However, we know the stub
                     * doesn't propogate this field to the calling app, so
                     * this extra buffer management detail isn't necessary:
                     *
                     * XDM_CLEARACCESSMODE_WRITE(pOutArgs->encodedBuf.accessMask);
                     */
                }

                /* writeback cache for recon buffers  */
                for (i = 0; ((i < pOutArgs->reconBufs.numBufs) &&
                             (i < IVIDEO_MAX_YUV_BUFFERS)); i++) {
                    if ((pOutArgs->reconBufs.bufDesc[i].buf != NULL) &&
                            (XDM_ISACCESSMODE_WRITE(
                                pOutArgs->reconBufs.bufDesc[i].accessMask))) {

                        Memory_cacheWb(pOutArgs->reconBufs.bufDesc[i].buf,
                                pOutArgs->reconBufs.bufDesc[i].bufSize);

                        /*
                         * Since we've cacheWb this buffer, we arguably should
                         * reflect this cache state and clear the WRITE bit in
                         * the .accessMask field.  However, we know the stub
                         * doesn't propogate this field to the calling app, so
                         * this extra buffer management detail isn't necessary:
                         *
                         * XDM_CLEARACCESSMODE_WRITE(
                         *         pOutArgs->reconBufs.bufDesc[i].accessMask);
                         */
                    }
                }
            }

            /*
             * Note that any changes to individual outBufs[i] values made by
             * the codec will automatically update msg->cmd.process.outBufs
             * as we pass the outBufs array by reference.
             */

            break;
        }

        case _VIDENC1_CCONTROL: {
            /* unmarshall status based on the "size" of params */
            pStatus = (IVIDENC1_Status *)((UInt)(&(msg->cmd.control.params)) +
                msg->cmd.control.params.size);

            /* invalidate data buffer */
            if (pStatus->data.buf != NULL) {
                Memory_cacheInv(pStatus->data.buf, pStatus->data.bufSize);
            }

            msg->visa.status = VIDENC1_control(handle, msg->cmd.control.id,
                &(msg->cmd.control.params), pStatus);

            /* writeback data buffer */
            if ((pStatus->data.buf != NULL) &&
                XDM_ISACCESSMODE_WRITE(pStatus->data.accessMask)) {

                Memory_cacheWb(pStatus->data.buf, pStatus->data.bufSize);

                /*
                 * Since we've cacheWb this buffer, we arguably should
                 * reflect this cache state and clear the WRITE bit in
                 * the .accessMask field.  However, we know the stub
                 * doesn't propogate this field to the calling app, so
                 * this extra buffer management detail isn't necessary:
                 *
                 * XDM_CLEARACCESSMODE_WRITE(pStatus->data.accessMask);
                 */
            }

            break;
        }

        default: {
            msg->visa.status = VISA_EFAIL;

            break;
        }
    }
    return (VISA_EOK);
}