int ALG_jpgDecSetDynamicParams(ALG_JpgDecObj *pObj, Bool decodeHeader, Uint16 offsetH) { XDAS_Int32 status; pObj->dynamicParams.size = sizeof(pObj->dynamicParams); pObj->dynamicParams.numAU = XDM_DEFAULT; if(decodeHeader) pObj->dynamicParams.decodeHeader = XDM_PARSE_HEADER; else pObj->dynamicParams.decodeHeader = XDM_DECODE_AU; pObj->dynamicParams.displayWidth = offsetH; /* Set video decoder dynamic parameters */ pObj->decStatus.size = sizeof(pObj->decStatus); pObj->decStatus.data.buf = NULL; status = IMGDEC1_control(pObj->hDecode, XDM_SETPARAMS, &pObj->dynamicParams, &pObj->decStatus); if (status != IMGDEC1_EOK) { OSA_ERROR("XDM_SETPARAMS failed, status=%ld\n", status); return OSA_EFAIL; } pObj->decStatus.data.buf = NULL; status = IMGDEC1_control(pObj->hDecode, XDM_GETBUFINFO, &pObj->dynamicParams, &pObj->decStatus); if (status != IMGDEC1_EOK) { OSA_ERROR("XDM_GETBUFINFO failed, status=%ld\n", status); return OSA_EFAIL; } #ifdef ALG_DEBUG OSA_printf(" ALG: ImgDec: XDM_GETBUFINFO: min in bufs:%ld buf(0):%ld buf(1):%ld\n",pObj->decStatus.bufInfo.minNumInBufs,pObj->decStatus.bufInfo.minInBufSize[0], pObj->decStatus.bufInfo.minInBufSize[1]); #endif return OSA_SOK; }
DvevmStRetCode dvtb_jpegDec1Control(DvevmStJpegDec1Info *jpeg1) { int status = -1, i = 0; DvevmStRetCode retCode = DVEVM_ST_SUCCESS; ASSERT(jpeg1 != NULL); ASSERT(jpeg1->idec1Hdl != NULL); status = IMGDEC1_control(jpeg1->idec1Hdl, jpeg1->idec1Cmd, (IIMGDEC1_DynamicParams *) &jpeg1->idec1DynParams, (IIMGDEC1_Status *) &jpeg1->idec1Status); if (IMGDEC1_EOK != status) { SYS_ERROR("JPEG Decode Control failed (%d)\n", status); retCode = DVEVM_ST_FAIL; } else { SYS_DEBUG("JPEG Decode Control => Command : %d\n", jpeg1->idec1Cmd); dvtb_jpegDec1ControlDebug(&jpeg1->idec1Status); if (XDM_GETBUFINFO == jpeg1->idec1Cmd) { jpeg1->inBuf.numBufs = jpeg1->idec1Status.imgdecStatus.bufInfo.minNumInBufs; jpeg1->outBuf.numBufs = jpeg1->idec1Status.imgdecStatus.bufInfo.minNumOutBufs; for (i = 0; i < jpeg1->inBuf.numBufs; i++) { jpeg1->inBuf.bufSizes[i] = jpeg1->idec1Status.imgdecStatus.bufInfo.minInBufSize[i]; } for (i = 0; i < jpeg1->outBuf.numBufs; i++) { jpeg1->outBuf.bufSizes[i] = jpeg1->idec1Status.imgdecStatus.bufInfo.minOutBufSize[i]; } } } return retCode; }
/****************************************************************************** * Idec1_process ******************************************************************************/ Int Idec1_process(Idec1_Handle hId, Buffer_Handle hInBuf, Buffer_Handle hOutBuf) { BufferGfx_Dimensions dim; IMGDEC1_DynamicParams dynParams; IMGDEC1_InArgs inArgs; IMGDEC1_OutArgs outArgs; IMGDEC1_Status decStatus; XDM1_BufDesc inBufDesc; XDM1_BufDesc outBufDesc; XDAS_Int32 status; XDAS_Int8 * inPtr; XDAS_Int8 * outPtr; UInt32 offset = 0; UInt32 i; assert(hId); assert(hInBuf); assert(hOutBuf); assert(Buffer_getSize(hInBuf)); assert(Buffer_getUserPtr(hInBuf)); assert(Buffer_getUserPtr(hOutBuf)); assert(Buffer_getNumBytesUsed(hInBuf)); assert(Buffer_getSize(hOutBuf)); assert(Buffer_getType(hOutBuf) == Buffer_Type_GRAPHICS); BufferGfx_getDimensions(hOutBuf, &dim); inPtr = Buffer_getUserPtr(hInBuf); outPtr = Buffer_getUserPtr(hOutBuf); inArgs.size = sizeof(IMGDEC1_InArgs); inArgs.numBytes = Buffer_getNumBytesUsed(hInBuf); outArgs.size = sizeof(IMGDEC1_OutArgs); inBufDesc.numBufs = 1; outBufDesc.numBufs = hId->minNumOutBufs; inBufDesc.descs[0].buf = inPtr; inBufDesc.descs[0].bufSize = Buffer_getSize(hInBuf); for(i = 0; i < hId->minNumOutBufs; i++) { outBufDesc.descs[i].buf = (XDAS_Int8 *)((unsigned int)outPtr + offset); offset += hId->minOutBufSize[i]; outBufDesc.descs[i].bufSize = hId->minOutBufSize[i]; } /* Decode image buffer */ status = IMGDEC1_process(hId->hDecode, &inBufDesc, &outBufDesc, &inArgs, &outArgs); Buffer_setNumBytesUsed(hInBuf, outArgs.bytesConsumed); if (status != IMGDEC1_EOK) { if (XDM_ISFATALERROR(outArgs.extendedError)) { Dmai_err2("IMGDEC1_process() failed with error (%d ext: 0x%x)\n", (Int)status, (Uns) outArgs.extendedError); return Dmai_EFAIL; } else { Dmai_dbg1("IMGDEC1_process() non-fatal error 0x%x\n", (Uns) outArgs.extendedError); return Dmai_EBITERROR; } } /* Get the dynamic codec status */ decStatus.data.buf = NULL; decStatus.size = sizeof(IMGDEC1_Status); dynParams.size = sizeof(IMGDEC1_DynamicParams); status = IMGDEC1_control(hId->hDecode, XDM_GETSTATUS, &dynParams, &decStatus); if (status != IMGDEC1_EOK) { Dmai_err1("XDM_GETSTATUS failed, status=%d\n", status); return Dmai_EFAIL; } /* Set output Color Format */ switch (decStatus.outputChromaFormat) { case XDM_YUV_422ILE: BufferGfx_setColorSpace (hOutBuf, ColorSpace_UYVY); break; case XDM_YUV_420P: BufferGfx_setColorSpace (hOutBuf, ColorSpace_YUV420P); break; case XDM_YUV_422P: BufferGfx_setColorSpace (hOutBuf, ColorSpace_YUV422P); break; case XDM_YUV_444P: BufferGfx_setColorSpace (hOutBuf, ColorSpace_YUV444P); break; case XDM_GRAY: BufferGfx_setColorSpace (hOutBuf, ColorSpace_GRAY); break; default: printf("Unsupported output color space.\n"); return Dmai_EFAIL; } dim.x = dim.y = 0; dim.width = decStatus.outputWidth; dim.height = decStatus.outputHeight; dim.lineLength = decStatus.outputWidth * ColorSpace_getBpp(BufferGfx_getColorSpace(hOutBuf)) / 8; if (BufferGfx_setDimensions(hOutBuf, &dim) < 0) { Dmai_err0("Frame does not fit in allocated buffer\n"); return Dmai_EFAIL; } return Dmai_EOK; }
/****************************************************************************** * Idec1_create ******************************************************************************/ Idec1_Handle Idec1_create(Engine_Handle hEngine, Char *codecName, IMGDEC1_Params *params, IMGDEC1_DynamicParams *dynParams) { Idec1_Handle hId; IMGDEC1_Handle hDecode; IMGDEC1_Status decStatus; XDAS_Int32 status; if (hEngine == NULL || codecName == NULL || params == NULL || dynParams == NULL) { Dmai_err0("Cannot pass null for engine, codec name, params or " "dynamic params\n"); return NULL; } /* Allocate space for the object */ hId = (Idec1_Handle)calloc(1, sizeof(Idec1_Object)); if (hId == NULL) { Dmai_err0("Failed to allocate space for Idec1 Object\n"); return NULL; } /* Create image decoder instance */ hDecode = IMGDEC1_create(hEngine, codecName, params); if (hDecode == NULL) { Dmai_err0("Failed to open image decode algorithm\n"); free(hId); return NULL; } Dmai_dbg0("Image decoder instance created\n"); /* Set image decoder dynamic params */ decStatus.data.buf = NULL; decStatus.size = sizeof(IMGDEC1_Status); status = IMGDEC1_control(hDecode, XDM_SETPARAMS, dynParams, &decStatus); if (status != IMGDEC1_EOK) { Dmai_err0("XDM_SETPARAMS control failed\n"); IMGDEC1_delete(hDecode); free(hId); return NULL; } /* Get buffer information from image decoder */ status = IMGDEC1_control(hDecode, XDM_GETBUFINFO, dynParams, &decStatus); if (status != IMGDEC1_EOK) { Dmai_err0("XDM_GETBUFINFO control failed\n"); IMGDEC1_delete(hDecode); free(hId); return NULL; } Dmai_dbg1("Buffer size %u obtained from XDM_GETBUFINFO control call\n", (UInt) decStatus.bufInfo.minInBufSize[0]); hId->hDecode = hDecode; memcpy(hId->minInBufSize, decStatus.bufInfo.minInBufSize, sizeof(hId->minInBufSize)); hId->minNumInBufs = decStatus.bufInfo.minNumInBufs; memcpy(hId->minOutBufSize, decStatus.bufInfo.minOutBufSize, sizeof(hId->minOutBufSize)); hId->minNumOutBufs = decStatus.bufInfo.minNumOutBufs; return hId; }
int ALG_jpgDecRun(void *hndl, ALG_JpgDecRunPrm *prm, ALG_JpgDecRunStatus *runStatus) { ALG_JpgDecObj *pObj = (ALG_JpgDecObj*)hndl; XDM1_BufDesc inBufDesc; XDM1_BufDesc outBufDesc; XDAS_Int32 status; IMGDEC1_InArgs inArgs; IMGDEC1_OutArgs outArgs; Uint32 bytesPerPixel, offset; runStatus->bytesUsed = 0; runStatus->frameWidth = 0; runStatus->frameHeight = 0; if(pObj==NULL) return OSA_EFAIL; status = ALG_jpgDecSetDynamicParams(pObj, FALSE, prm->outOffsetH); if(status!=OSA_SOK) return status; offset = prm->outOffsetH * prm->outOffsetV; bytesPerPixel = 1; if(pObj->createPrm.dataFormat==ALG_VID_DATA_FORMAT_YUV422) { bytesPerPixel = 2; } inBufDesc.numBufs = 1; inBufDesc.descs[0].bufSize = prm->inDataSize; inBufDesc.descs[0].buf = (XDAS_Int8*)prm->inAddr; inBufDesc.descs[0].accessMask = 0; prm->outStartX = OSA_align(prm->outStartX, 2); prm->outStartY = OSA_align(prm->outStartY, 2); outBufDesc.numBufs = 1; outBufDesc.descs[0].buf = (XDAS_Int8*)(prm->outAddr + (prm->outStartY*prm->outOffsetH + prm->outStartX)*bytesPerPixel); outBufDesc.descs[0].bufSize = prm->outOffsetH*prm->outOffsetV*bytesPerPixel; outBufDesc.descs[0].accessMask = 0; if(pObj->createPrm.dataFormat==ALG_VID_DATA_FORMAT_YUV420) { outBufDesc.numBufs = 2; outBufDesc.descs[1].bufSize = outBufDesc.descs[0].bufSize/2; outBufDesc.descs[1].buf = (XDAS_Int8*)(prm->outAddr + offset + (prm->outStartY*prm->outOffsetH/2 + prm->outStartX)); outBufDesc.descs[1].accessMask = 0; } inArgs.size = sizeof(IMGDEC1_InArgs); inArgs.numBytes = inBufDesc.descs[0].bufSize; outArgs.size = sizeof(IMGDEC1_OutArgs); status = IMGDEC1_process(pObj->hDecode, &inBufDesc, &outBufDesc, &inArgs, &outArgs); if (status != IMGDEC1_EOK) return OSA_EFAIL; runStatus->bytesUsed = outArgs.bytesConsumed; pObj->decStatus.data.buf = NULL; status = IMGDEC1_control(pObj->hDecode, XDM_GETSTATUS, &pObj->dynamicParams, &pObj->decStatus); if (status != IMGDEC1_EOK) { OSA_ERROR("XDM_GETSTATUS failed, status=%ld\n", status); return OSA_EFAIL; } runStatus->frameWidth = pObj->decStatus.outputWidth; runStatus->frameHeight = pObj->decStatus.outputHeight; return OSA_SOK; }
/* * ======== encode_decode ======== */ static Void encode_decode(IMGENC1_Handle enc, IMGDEC1_Handle dec, FILE *in, FILE *out) { Int n; Int32 status; IMGDEC1_InArgs decInArgs; IMGDEC1_OutArgs decOutArgs; IMGDEC1_DynamicParams decDynParams; IMGDEC1_Status decStatus; IMGENC1_InArgs encInArgs; IMGENC1_OutArgs encOutArgs; IMGENC1_DynamicParams encDynParams; IMGENC1_Status encStatus; XDM1_BufDesc inBufDesc; XDM1_BufDesc encodedBufDesc; XDM1_BufDesc outBufDesc; /* initialize the buffer descriptors */ inBufDesc.numBufs = encodedBufDesc.numBufs = outBufDesc.numBufs = 1; inBufDesc.descs[0].bufSize = encodedBufDesc.descs[0].bufSize = outBufDesc.descs[0].bufSize = NSAMPLES; inBufDesc.descs[0].buf = inBuf; encodedBufDesc.descs[0].buf = encodedBuf; outBufDesc.descs[0].buf = outBuf; /* 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 = IMGDEC1_control(dec, XDM_GETVERSION, &decDynParams, &decStatus); GT_1trace(curMask, GT_1CLASS, "Decoder version: %s\n", (status == IMGDEC1_EOK ? ((char *)decStatus.data.buf) : "[unknown]")); status = IMGENC1_control(enc, XDM_GETVERSION, &encDynParams, &encStatus); GT_1trace(curMask, GT_1CLASS, "Encoder version: %s\n", (status == IMGENC1_EOK ? ((char *)encStatus.data.buf) : "[unknown]")); /* * This app expects the encoder to accept 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 = IMGENC1_control(enc, XDM_GETBUFINFO, &encDynParams, &encStatus); if (status != IMGENC1_EOK) { /* failure, report error and exit */ GT_1trace(curMask, GT_7CLASS, "encode control status = 0x%x\n", status); return; } /* Validate this encoder codec will meet our buffer requirements */ if ((inBufDesc.numBufs < encStatus.bufInfo.minNumInBufs) || (IFRAMESIZE < encStatus.bufInfo.minInBufSize[0]) || (encodedBufDesc.numBufs < encStatus.bufInfo.minNumOutBufs) || (EFRAMESIZE < encStatus.bufInfo.minOutBufSize[0])) { /* failure, report error and exit */ GT_0trace(curMask, GT_7CLASS, "Error: encoder codec feature conflict\n"); return; } status = IMGDEC1_control(dec, XDM_GETBUFINFO, &decDynParams, &decStatus); if (status != IMGDEC1_EOK) { /* failure, report error and exit */ GT_1trace(curMask, GT_7CLASS, "decode control status = 0x%x\n", status); return; } /* Validate this decoder codec will meet our buffer requirements */ if ((encodedBufDesc.numBufs < decStatus.bufInfo.minNumInBufs) || (EFRAMESIZE < decStatus.bufInfo.minInBufSize[0]) || (outBufDesc.numBufs < decStatus.bufInfo.minNumOutBufs) || (OFRAMESIZE < decStatus.bufInfo.minOutBufSize[0])) { /* failure, report error and exit */ GT_0trace(curMask, GT_7CLASS, "App-> ERROR: decoder does not meet buffer requirements.\n"); return; } /* * Read complete frames from in, encode, decode, and write to out. */ for (n = 0; fread(inBuf, IFRAMESIZE, 1, in) == 1; n++) { if (appPause) { printf("About to start frame %d. Press Enter to continue...\n", n); appPause = ('c' == getchar() ? 0 : 1); } /* Deal with cache issues, if necessary */ #ifdef CACHE_ENABLED #ifdef xdc_target__isaCompatible_64P /* * 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 GT_1trace(curMask, GT_1CLASS, "App-> Processing frame %d...\n", n); /* encode the frame */ status = IMGENC1_process(enc, &inBufDesc, &encodedBufDesc, &encInArgs, &encOutArgs); GT_2trace(curMask, GT_2CLASS, "App-> Encoder frame %d process returned - 0x%x)\n", n, status); #ifdef CACHE_ENABLED /* Writeback this outBuf from the previous call. Also, as encodedBuf * is an inBuf to the next process call, we must invalidate it also, to * clean buffer lines. */ Memory_cacheWbInv(encodedBuf, EFRAMESIZE); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(outBuf, OFRAMESIZE); #endif if (status != IMGENC1_EOK) { GT_3trace(curMask, GT_7CLASS, "App-> Encoder frame %d processing FAILED, status = 0x%x, " "extendedError = 0x%x\n", n, status, encOutArgs.extendedError); break; } /* decode the frame */ decInArgs.numBytes = encOutArgs.bytesGenerated; status = IMGDEC1_process(dec, &encodedBufDesc, &outBufDesc, &decInArgs, &decOutArgs); GT_2trace(curMask, GT_2CLASS, "App-> Decoder frame %d process returned - 0x%x)\n", n, status); if (status != IMGDEC1_EOK) { GT_3trace(curMask, GT_7CLASS, "App-> Decoder frame %d processing FAILED, status = 0x%x, " "extendedError = 0x%x\n", n, status, decOutArgs.extendedError); break; } #ifdef CACHE_ENABLED /* Writeback the outBuf. */ Memory_cacheWb(outBuf, OFRAMESIZE); #endif /* write to file */ fwrite(outBuf, OFRAMESIZE, 1, out); #ifdef USE_POWER_MANAGEMENT if (Global_usePowerManagement) { if (appPause) { printf("About to hibernate. Press Enter to continue...\n"); appPause = ('c' == getchar() ? 0 : 1); } LPM_Status lpmStat = LPM_SOK; GT_0trace(curMask, GT_2CLASS, "Turning DSP off\n"); lpmStat = LPM_setPowerState(lpmHandle, LPM_HIBERNATE); if (lpmStat != LPM_SOK) { fprintf(stderr, "Error: LPM_setPowerState() failed\n"); return; } if (appPause) { printf("DSP is off: Press Enter to continue...\n"); appPause = ('c' == getchar() ? 0 : 1); } else { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 200000; /* 200 msec */ if (select(0, NULL, NULL, NULL, &tv) == -1) { fprintf(stderr, "Error: select() failed\n"); return; } } GT_0trace(curMask, GT_1CLASS, "Turning DSP on\n"); lpmStat = LPM_resume(lpmHandle); if (lpmStat != LPM_SOK) { fprintf(stderr, "Error: LPM_resume() failed\n"); return; } if (appPause) { printf("DSP is on: Press Enter to continue...\n"); appPause = ('c' == getchar() ? 0 : 1); } } #endif } GT_1trace(curMask, GT_1CLASS, "%d frames encoded/decoded\n", n); }