Int32 decodeIssue(AUDDEC1_Handle dec, int in, int out) { Int32 status; #ifdef CACHE_ENABLED /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(outBuf[out], OFRAMESIZE); #endif /* decode the frame */ decInArgs[in].numBytes = EFRAMESIZE; GT_4trace(curMask, GT_1CLASS, "App-> inBuf[%d]=%#x, outBuf[%d]=%#x\n", in, encodedBufDesc[in].descs[0].buf, out, outBufDesc[out].descs[0].buf); status = AUDDEC1_processAsync(dec, &encodedBufDesc[in], &outBufDesc[out], &decInArgs[in], &decOutArgs[out]); GT_1trace(curMask, GT_2CLASS, "App-> Decoder processAsync returned 0x%x\n", status); if (status != AUDDEC1_EOK) { GT_0trace(curMask, GT_7CLASS, "App-> Decoder processing FAILED\n"); } return status; }
Int32 encodeIssue(AUDENC1_Handle enc, int in, int out) { Int32 status; #if USE_ANCDATA /* we send the same data as inBuf as ancillory data */ memcpy(ancBuf[in], inBuf[in], ENCANCBUFSIZE); #endif /* 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[in], IFRAMESIZE); #else #error Unvalidated config - add appropriate fread-related cache maintenance #endif #if USE_ANCDATA /* ancBuf is an inBuf, filled via memcpy (i.e. CPU writes) */ Memory_cacheWbInv(ancBuf[in], ENCANCBUFSIZE); #endif /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(encodedBuf[out], EFRAMESIZE); #endif GT_4trace(curMask, GT_1CLASS, "App-> inBuf[%d]=%#x, outBuf[%d]=%#x\n", in, inBufDesc[in].descs[0].buf, out, encodedBufDesc[out].descs[0].buf); /* * Encode the frame. Note that .numInSamples is the number of * _samples_ not bytes. IFRAMESIZE is in 8-bit bytes, so there's a * little math here to get .numInSamples right. */ encInArgs[in].numInSamples = (IFRAMESIZE / (ENCBITSPERSAMPLE / (8 /* bits per byte */))); status = AUDENC1_processAsync(enc, &inBufDesc[in], &encodedBufDesc[out], &encInArgs[in], &encOutArgs[out]); GT_1trace(curMask, GT_2CLASS, "App-> Encoder processAsync returned 0x%x\n", status); if (status != AUDENC1_EOK) { GT_0trace(curMask, GT_7CLASS, "App-> Encodcer processing FAILED\n"); } return status; }
/* * ======== call ======== */ static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg) { _VIDDEC2FRONT_Msg *msg = (_VIDDEC2FRONT_Msg *)visaMsg; VIDDEC2FRONT_Handle handle = (VIDDEC2FRONT_Handle)visaHandle; // Int i, j; // XDM1_BufDesc inBufs; // XDM_BufDesc outBufs; IVIDDEC2FRONT_OutArgs *pOutArgs; IVIDDEC2FRONT_Status *pStatus; // IVIDDEC2_CodecClassConfig *codecClassConfig; // Int numBufs; #if 0 /* get stub/skeleton config data; can be NULL (for old codecs) */ codecClassConfig = (IVIDDEC2_CodecClassConfig *) VISA_getCodecClassConfig( visaHandle ); #endif /* perform the requested VIDDEC2 operation by parsing message. */ switch (msg->visa.cmd) { case _VIDDEC2FRONT_CPROCESS: { #if 0 /* 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; /* invalidate cache for all input buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (inBufs.descs[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.descs[i].buf, inBufs.descs[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; } } } #endif /* unmarshall outArgs based on the "size" of inArgs */ pOutArgs = (IVIDDEC2FRONT_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) + msg->cmd.process.inArgs.size); /* * Note, there's no need to invalidate cache for * pOutArgs->decodedBuf bufs nor pOutArgs->displayBufs * bufs as the app doesn't provide OUT buffers to the * algorithm via these fields. */ /* make the process call */ msg->visa.status = VIDDEC2FRONT_process(handle, &(msg->cmd.process.inArgs), &(msg->cmd.process.context), pOutArgs); #if 0 /* * Writeback cache for all output buffers: * - .decodedBufs * - .displayBufs * - .mbDataBuf */ for (i = 0; (i < pOutArgs->decodedBufs.numBufs) && (i < IVIDEO_MAX_YUV_BUFFERS); i++) { if ((pOutArgs->decodedBufs.bufDesc[i].buf != NULL) && (XDM_ISACCESSMODE_WRITE( pOutArgs->decodedBufs.bufDesc[i].accessMask))) { Memory_cacheWb(pOutArgs->decodedBufs.bufDesc[i].buf, pOutArgs->decodedBufs.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( * outArgs->decodedBufs.bufDesc[i].accessMask); */ } for (i = 0; (pOutArgs->outputID[i] != 0) && (i < IVIDDEC2_MAX_IO_BUFFERS); i++) { for (j = 0; j < pOutArgs->displayBufs[i].numBufs; j++) { if ((pOutArgs->displayBufs[i].bufDesc[j].buf != NULL) && (XDM_ISACCESSMODE_WRITE( pOutArgs->displayBufs[i].bufDesc[j].accessMask))) { Memory_cacheWb(pOutArgs->displayBufs[i].bufDesc[j].buf, pOutArgs->displayBufs[i].bufDesc[j].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( * outArgs->displayBufs.bufDesc[i].accessMask); */ } } } if ((pOutArgs->outputMbDataID != 0) && (pOutArgs->mbDataBuf.buf != NULL) && (XDM_ISACCESSMODE_WRITE(pOutArgs->mbDataBuf.accessMask))) { Memory_cacheWb(pOutArgs->mbDataBuf.buf, pOutArgs->mbDataBuf.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(outArgs->mbDataBuf.accessMask); */ } #endif /* * 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 _VIDDEC2FRONT_CCONTROL: { /* unmarshall status based on the "size" of params */ pStatus = (IVIDDEC2FRONT_Status *)((UInt)(&(msg->cmd.control.params)) + msg->cmd.control.params.size); #if 0 /* invalidate data buffer */ if (pStatus->data.buf != NULL) { Memory_cacheInv(pStatus->data.buf, pStatus->data.bufSize); } #endif msg->visa.status = VIDDEC2FRONT_control(handle, msg->cmd.control.id, &(msg->cmd.control.params), &(msg->cmd.control.context), pStatus); #if 0 /* 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); */ } #endif break; } default: { msg->visa.status = VISA_EFAIL; break; } } return (VISA_EOK); }
/* * ======== call ======== */ static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg) { _UNIVERSAL_Msg *msg = (_UNIVERSAL_Msg *)visaMsg; UNIVERSAL_Handle handle = (UNIVERSAL_Handle)visaHandle; Int i; XDM1_BufDesc inBufs, *pInBufs = &inBufs; XDM1_BufDesc outBufs, *pOutBufs = &outBufs; XDM1_BufDesc inOutBufs, *pInOutBufs = &inOutBufs; IUNIVERSAL_OutArgs *pOutArgs; IUNIVERSAL_Status *pStatus; Int numBufs; /* perform the requested UNIVERSAL operation by parsing message. */ switch (msg->visa.cmd) { case _UNIVERSAL_CPROCESS: { /* unmarshal buffers */ if (msg->cmd.process.inBufs.numBufs == 0) { pInBufs = NULL; } else { inBufs = msg->cmd.process.inBufs; if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) { /* invalidate cache for all input buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (inBufs.descs[i].buf != NULL) { /* valid member of sparse array, manage it */ Memory_cacheInv(inBufs.descs[i].buf, inBufs.descs[i].bufSize); if (++numBufs == inBufs.numBufs) { break; } } } } } if (msg->cmd.process.outBufs.numBufs == 0) { pOutBufs = NULL; } else { outBufs = msg->cmd.process.outBufs; if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) { /* invalidate cache for all output buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (outBufs.descs[i].buf != NULL) { /* valid member of sparse array, manage it */ Memory_cacheInv(outBufs.descs[i].buf, outBufs.descs[i].bufSize); if (++numBufs == outBufs.numBufs) { break; } } } } } if (msg->cmd.process.inOutBufs.numBufs == 0) { pInOutBufs = NULL; } else { inOutBufs = msg->cmd.process.inOutBufs; if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) { /* invalidate cache for all in/out buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (inOutBufs.descs[i].buf != NULL) { /* valid member of sparse array, manage it */ Memory_cacheInv(inOutBufs.descs[i].buf, inOutBufs.descs[i].bufSize); if (++numBufs == inOutBufs.numBufs) { break; } } } } } /* unmarshall outArgs based on the "size" of inArgs */ pOutArgs = (IUNIVERSAL_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) + msg->cmd.process.inArgs.size); /* make the process call */ msg->visa.status = UNIVERSAL_process(handle, pInBufs, pOutBufs, pInOutBufs, &(msg->cmd.process.inArgs), pOutArgs); if (SKEL_cachingPolicy == SKEL_WBINVALL) { Memory_cacheWbInvAll(); } else if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) { /* writeback cache for output buffers */ if (pOutBufs != NULL) { for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (outBufs.descs[i].buf != NULL) { if (XDM_ISACCESSMODE_WRITE(outBufs.descs[i] .accessMask)) { /* valid member of sparse array, written via CPU */ Memory_cacheWb(outBufs.descs[i].buf, outBufs.descs[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(outBufs.descs[i] * .accessMask); */ } if (++numBufs == outBufs.numBufs) { break; } } } } if (pInOutBufs != NULL) { /* writeback cache for in/out buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (inOutBufs.descs[i].buf != NULL) { if (XDM_ISACCESSMODE_WRITE(inOutBufs.descs[i] .accessMask)) { /* valid member of sparse array, written via CPU */ Memory_cacheWb(inOutBufs.descs[i].buf, inOutBufs.descs[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(inOutBufs.descs[i] * .accessMask); */ } if (++numBufs == inOutBufs.numBufs) { break; } } } } } break; } case _UNIVERSAL_CCONTROL: { /* unmarshall status based on the "size" of dynParams */ pStatus = (IUNIVERSAL_Status *)((UInt)(&(msg->cmd.control.dynParams)) + msg->cmd.control.dynParams.size); /* invalidate data buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (pStatus->data.descs[i].buf != NULL) { /* valid member of sparse array, manage it */ Memory_cacheInv(pStatus->data.descs[i].buf, pStatus->data.descs[i].bufSize); if (++numBufs == pStatus->data.numBufs) { break; } } } msg->visa.status = UNIVERSAL_control(handle, msg->cmd.control.id, &(msg->cmd.control.dynParams), pStatus); /* writeback data buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (pStatus->data.descs[i].buf != NULL) { if (XDM_ISACCESSMODE_WRITE(pStatus->data.descs[i] .accessMask)) { /* valid member of sparse array, manage it */ Memory_cacheWb(pStatus->data.descs[i].buf, pStatus->data.descs[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(pStatus->data.descs[i] * .accessMask); */ } if (++numBufs == pStatus->data.numBufs) { break; } } } break; } default: { msg->visa.status = VISA_EFAIL; break; } } return (VISA_EOK); }
/* * ======== call ======== */ static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg) { _VIDDEC_Msg *msg = (_VIDDEC_Msg *)visaMsg; VIDDEC_Handle handle = (VIDDEC_Handle)visaHandle; Int i; XDM_BufDesc inBufs, outBufs; IVIDDEC_OutArgs *pOutArgs; IVIDDEC_Status *pStatus; IVIDDEC_CodecClassConfig *codecClassConfig; /* get stub/skeleton config data; can be NULL (for old codecs) */ codecClassConfig = (IVIDDEC_CodecClassConfig *) VISA_getCodecClassConfig( visaHandle ); /* perform the requested VIDDEC operation by parsing message. */ switch (msg->visa.cmd) { case _VIDDEC_CPROCESS: { /* unmarshall inBufs and outBufs since they differ in shape * from what their flattened versions passed in the message */ inBufs.bufs = msg->cmd.process.inBufs; inBufs.numBufs = msg->cmd.process.numInBufs; inBufs.bufSizes = msg->cmd.process.inBufSizes; 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; i < inBufs.numBufs; i++) { if (codecClassConfig != NULL && codecClassConfig->manageInBufsCache[i] == FALSE) { continue; } Memory_cacheInv(inBufs.bufs[i], inBufs.bufSizes[i]); } /* invalidate cache for all output buffers */ for (i = 0; i < outBufs.numBufs; i++) { if (codecClassConfig != NULL && codecClassConfig->manageOutBufsCache[i] == FALSE) { continue; } Memory_cacheInv(outBufs.bufs[i], outBufs.bufSizes[i]); } } /* SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB */ /* unmarshall outArgs based on the "size" of inArgs */ pOutArgs = (IVIDDEC_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) + msg->cmd.process.inArgs.size); /* make the process call */ msg->visa.status = VIDDEC_process(handle, &inBufs, &outBufs, &(msg->cmd.process.inArgs), pOutArgs); if (SKEL_cachingPolicy == SKEL_WBINVALL) { Memory_cacheWbInvAll(); } else if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) { /* flush cache for all output buffers and outArgs buffers * (unless...) */ for (i = 0; i < outBufs.numBufs; i++) { if (codecClassConfig != NULL && codecClassConfig->manageOutBufsCache[i] == FALSE) { continue; } Memory_cacheWb(outBufs.bufs[i], outBufs.bufSizes[i]); } for (i = 0; i < pOutArgs->displayBufs.numBufs; i++) { if (codecClassConfig != NULL && codecClassConfig->manageDisplayBufsCache[i] == FALSE) { continue; } Memory_cacheWbInv(pOutArgs->displayBufs.bufs[i], pOutArgs->displayBufs.bufSizes[i]); } } /* * 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 _VIDDEC_CCONTROL: { /* unmarshall status based on the "size" of params */ pStatus = (IVIDDEC_Status *)((UInt)(&(msg->cmd.control.params)) + msg->cmd.control.params.size); msg->visa.status = VIDDEC_control(handle, msg->cmd.control.id, &(msg->cmd.control.params), pStatus); break; } default: { msg->visa.status = VISA_EFAIL; break; } } return (VISA_EOK); }
/* * ======== 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); }
/* * ======== encode_decode ======== */ static Void encode_decode(VIDENC_Handle enc, VIDDEC_Handle dec, FILE *in, FILE *out) { Int n; Int32 status; VIDDEC_InArgs decInArgs; VIDDEC_OutArgs decOutArgs; VIDDEC_DynamicParams decDynParams; VIDDEC_Status decStatus; VIDENC_InArgs encInArgs; VIDENC_OutArgs encOutArgs; VIDENC_DynamicParams encDynParams; VIDENC_Status encStatus; XDM_BufDesc inBufDesc; XDAS_Int8 *src[XDM_MAX_IO_BUFFERS]; XDAS_Int32 inBufSizes[XDM_MAX_IO_BUFFERS]; XDM_BufDesc encodedBufDesc; XDAS_Int8 *encoded[XDM_MAX_IO_BUFFERS]; XDAS_Int32 encBufSizes[XDM_MAX_IO_BUFFERS]; XDM_BufDesc outBufDesc; XDAS_Int8 *dst[XDM_MAX_IO_BUFFERS]; XDAS_Int32 outBufSizes[XDM_MAX_IO_BUFFERS]; /* clear and initialize the buffer descriptors */ memset(src, 0, sizeof(src[0]) * XDM_MAX_IO_BUFFERS); memset(encoded, 0, sizeof(encoded[0]) * XDM_MAX_IO_BUFFERS); memset(dst, 0, sizeof(dst[0]) * XDM_MAX_IO_BUFFERS); src[0] = inBuf; encoded[0] = encodedBuf; dst[0] = outBuf; inBufDesc.numBufs = encodedBufDesc.numBufs = outBufDesc.numBufs = 1; inBufDesc.bufSizes = inBufSizes; encodedBufDesc.bufSizes = encBufSizes; outBufDesc.bufSizes = outBufSizes; //Note , this declaration is tell the memtab how much need to allocate the buf sizes inBufSizes[0] = IFRAMESIZE; encBufSizes[0] = EFRAMESIZE; outBufSizes[0] = OFRAMESIZE; inBufDesc.bufs = src; encodedBufDesc.bufs = encoded; outBufDesc.bufs = dst; /* 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); /* * Query the encoder and decoder. * 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 = VIDENC_control(enc, XDM_GETSTATUS, &encDynParams, &encStatus); if (status != VIDENC_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; } //#if 0 status = VIDDEC_control(dec, XDM_GETSTATUS, &decDynParams, &decStatus); if (status != VIDDEC_EOK) { /* failure, report error and exit */ GT_1trace(curMask, GT_7CLASS, "decode control status = 0x%x\n", status); return; } //#endif /* 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. */ /* opencv create init image */ #ifdef USE_OPENCV_DISPLAY cvNamedWindow("sobel",CV_WINDOW_AUTOSIZE); cvResizeWindow("sobel",320,240);//怕畫面太大讓人看不完,所以顯示視窗設小一點 #endif CvSize size=cvSize(320,240); frame=cvCreateImage(size,IPL_DEPTH_8U,3); frame_gray=cvCreateImage(size,IPL_DEPTH_8U,1); frame_Smooth=cvCreateImage(size,IPL_DEPTH_8U,1); frame_sobel=cvCreateImage(size,IPL_DEPTH_16S,1); frame_sobel_8U=cvCreateImage(size,IPL_DEPTH_8U,1); /* v4l2 init */ int count=0; deviceOpen(); deviceInit(); /*start capturing*/ captureStart(); /*===============v4l2 grab frame by Camera======================*/ while(1){ mainLoop(); /*this is the v4l2grab frame*/ memcpy(inBuf,buffers[0].start,IFRAMESIZE); #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", count); /* encode the frame */ status = VIDENC_process(enc, &inBufDesc, &encodedBufDesc, &encInArgs, &encOutArgs); GT_2trace(curMask, GT_2CLASS, "App-> Encoder frame %d process returned - 0x%x)\n", count, 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 != VIDENC_EOK) { GT_3trace(curMask, GT_7CLASS, "App-> Encoder frame %d processing FAILED, status = 0x%x, " "extendedError = 0x%x\n", count, status, encOutArgs.extendedError); break; } /***************************decode part (Unuse)***********************************/ /************************** decode the frame**************************************/ status = VIDDEC_process(dec, &encodedBufDesc, &outBufDesc, &decInArgs, &decOutArgs); GT_2trace(curMask, GT_2CLASS, "App-> Decoder frame %d process returned - 0x%x)\n", n, status); if (status != VIDDEC_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(encodedBuf, EFRAMESIZE, 1, out); frame->imageData = encoded[0]; frame_gray->imageData = dst[0]; //cvCvtColor(frame,frame_gray,CV_BGR2GRAY); #ifdef USE_OPENCV_DISPLAY cvShowImage("sobel",frame_gray); int key=cvWaitKey(33); #endif //cvSaveImage("22.bmp",frame_gray,0); printf("the %d frame are completed \n",count); count++; }/*end while*/ #ifdef USE_OPENCV_DISPLAY cvDestroyWindow("sobel"); #endif cvReleaseImage(&frame); cvReleaseImage(&frame_gray); cvReleaseImage(&frame_Smooth); cvReleaseImage(&frame_sobel); cvReleaseImage(&frame_sobel_8U); GT_1trace(curMask, GT_1CLASS, "%d frames encoded/decoded\n", n); }
/* * ======== analyze ======== */ static Void analyze(VIDANALYTICS_Handle analyzer, FILE *in, FILE *out) { Int n; Int32 result; VIDANALYTICS_InArgs inArgs; VIDANALYTICS_OutArgs outArgs; VIDANALYTICS_DynamicParams dynParams; VIDANALYTICS_Status status; XDM1_BufDesc inBufDesc; XDM1_BufDesc outBufDesc; /* clear and initialize the buffer descriptors */ inBufDesc.numBufs = outBufDesc.numBufs = 1; inBufDesc.descs[0].bufSize = outBufDesc.descs[0].bufSize = NSAMPLES; inBufDesc.descs[0].buf = inBuf; outBufDesc.descs[0].buf = outBuf; /* initialize all "sized" fields */ inArgs.size = sizeof(inArgs); outArgs.size = sizeof(outArgs); dynParams.size = sizeof(dynParams); status.size = sizeof(status); /* if the codecs support it, dump their versions */ status.data.numBufs = 1; status.data.descs[0].buf = versionBuf; status.data.descs[0].bufSize = MAXVERSIONSIZE; result = VIDANALYTICS_control(analyzer, XDM_GETVERSION, &dynParams, &status); GT_1trace(curMask, GT_1CLASS, "Analyzer version: %s\n", (result == VIDANALYTICS_EOK ? ((char *)status.data.descs[0].buf) : "[unknown]")); /* * This app expects the analyzer to accept 1 buf in and provide 1 buf out, * and the buf sizes of the in and out buffer must be able to handle * NSAMPLES bytes of data. */ status.data.numBufs = 0; status.data.descs[0].buf = NULL; result = VIDANALYTICS_control(analyzer, XDM_GETBUFINFO, &dynParams, &status); if (result != VIDANALYTICS_EOK) { /* failure, report error and exit */ GT_1trace(curMask, GT_7CLASS, "VIDANALYTICS control status = %ld\n", status); return; } /* Validate this analyzer will meet our buffer requirements */ if ((inBufDesc.numBufs < status.bufInfo.minNumInBufs) || (IFRAMESIZE < status.bufInfo.minInBufSize[0]) || (outBufDesc.numBufs < status.bufInfo.minNumOutBufs) || (OFRAMESIZE < status.bufInfo.minOutBufSize[0])) { /* failure, report error and exit */ GT_0trace(curMask, GT_7CLASS, "Error: analyzer codec feature conflict\n"); return; } /* * Read complete frames from in, analyze, and write to out. */ for (n = 0; fread(inBuf, IFRAMESIZE, 1, in) == 1; n++) { #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(outBuf, OFRAMESIZE); #endif GT_1trace(curMask, GT_1CLASS, "App-> Processing frame %d...\n", n); /* * Analyze the frame. */ result = VIDANALYTICS_process(analyzer, &inBufDesc, &outBufDesc, &inArgs, &outArgs); GT_2trace(curMask, GT_2CLASS, "App-> Analyzer frame %d process returned - 0x%x)\n", n, result); if (result != VIDANALYTICS_EOK) { GT_3trace(curMask, GT_7CLASS, "App-> Analyzer frame %d processing FAILED, result = 0x%x, " "extendedError = 0x%x\n", n, result, outArgs.extendedError); break; } #ifdef CACHE_ENABLED /* * Conditionally writeback the analyzed buf from the previous * call. */ if (XDM_ISACCESSMODE_WRITE(outBufDesc.descs[0].accessMask)) { Memory_cacheWb(outBuf, OFRAMESIZE); } #endif /* write to file */ fwrite(outBufDesc.descs[0].buf, OFRAMESIZE, 1, out); } GT_1trace(curMask, GT_1CLASS, "%d frames analyzed\n", n); }
/****************************************************************************** * appMain ******************************************************************************/ Int appMain(Args * args) { IMGDEC1_Params params = Idec1_Params_DEFAULT; IMGDEC1_DynamicParams dynParams = Idec1_DynamicParams_DEFAULT; Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; Idec1_Handle hId = NULL; Engine_Handle hEngine = NULL; Time_Handle hTime = NULL; Buffer_Handle hInBuf = NULL; Buffer_Handle hOutBuf = NULL; FILE *outFile = NULL; FILE *inFile = NULL; Int numBytes = 0; Int ret = Dmai_EOK; Cpu_Device device; UInt32 time; printf("Starting application...\n"); if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create Time object\n"); goto cleanup; } } /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); /* Determine which device the application is running on */ if (Cpu_getDevice(NULL, &device) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to determine target board\n"); goto cleanup; } /* Open input file */ inFile = fopen(args->inFile, "rb"); if (inFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open file %s\n", args->inFile); goto cleanup; } /* Open output file */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create output file %s\n", args->outFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbuffer, _IOFBF, sizeof(vbuffer)) != 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to setvbuf on file descriptor\n"); goto cleanup; } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open codec engine %s\n", args->engineName); goto cleanup; } /* * Set output color format to UYVY or Planar output. * Here XDM_DEFUALT sets the output planar format to * the planar fromat of the encoded image. * */ switch (args->oColorSpace) { case ColorSpace_UYVY: params.forceChromaFormat = XDM_YUV_422ILE; break; case ColorSpace_NOTSET: params.forceChromaFormat = XDM_CHROMAFORMAT_DEFAULT; break; case ColorSpace_YUV444P: params.forceChromaFormat = XDM_YUV_444P; break; case ColorSpace_YUV422P: params.forceChromaFormat = XDM_YUV_422P; break; case ColorSpace_YUV420P: params.forceChromaFormat = XDM_YUV_420P; break; case ColorSpace_YUV420PSEMI: params.forceChromaFormat = XDM_YUV_420SP; break; case ColorSpace_GRAY: params.forceChromaFormat = ColorSpace_GRAY; break; default: ret = Dmai_EFAIL; fprintf(stderr,"Unsupported output color space %d.\n", args->oColorSpace); goto cleanup; } if ((device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) { params.maxHeight = VideoStd_720P_HEIGHT; params.maxWidth = VideoStd_720P_WIDTH; } if (device == Cpu_Device_DM6467) { params.maxHeight = VideoStd_720P_HEIGHT; params.maxWidth = VideoStd_720P_WIDTH; } /* Create the image decoder */ hId = Idec1_create(hEngine, args->codecName, ¶ms, &dynParams); if (hId == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create image decoder: %s\n", args->codecName); goto cleanup; } /* Align buffers to cache line boundary */ gfxAttrs.bAttrs.memParams.align = bAttrs.memParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { gfxAttrs.bAttrs.memParams.flags = bAttrs.memParams.flags = Memory_CACHED; } gfxAttrs.colorSpace = args->oColorSpace; gfxAttrs.dim.width = params.maxWidth; gfxAttrs.dim.height = params.maxHeight; gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(params.maxWidth, gfxAttrs.colorSpace); /* Create an output buffer for decoded data */ hOutBuf = Buffer_create( Dmai_roundUp(Idec1_getOutBufSize(hId), BUFSIZEALIGN), BufferGfx_getBufferAttrs(&gfxAttrs)); if (hOutBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create contiguous buffers\n"); goto cleanup; } /* Create an input buffer for encoded data */ hInBuf = Buffer_create(Dmai_roundUp(Idec1_getInBufSize(hId), BUFSIZEALIGN), &bAttrs); if (hInBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create contiguous buffers\n"); goto cleanup; } /* Read encoded image data */ numBytes = fread(Buffer_getUserPtr(hInBuf), 1, Idec1_getInBufSize(hId), inFile); Buffer_setNumBytesUsed(hInBuf, numBytes); if (args->benchmark) { if (Time_reset(hTime) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to reset timer\n"); goto cleanup; } } if (args->cache) { /* * To meet xDAIS DMA Rule 7, when input buffers are cached, we * must writeback the cache into physical memory. Also, per DMA * Rule 7, we must invalidate the output buffer from * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(Buffer_getUserPtr(hInBuf), Buffer_getSize(hInBuf)); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus \n", (Uns) time); } } printf("Decoding image...\n"); /* Decode the image frame */ ret = Idec1_process(hId, hInBuf, hOutBuf); if (ret < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to decode image buffer\n"); goto cleanup; } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Frame - Decode: %uus \n", (unsigned int)time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus ", (Uns) time); } } /* Write decoded image to a file */ if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_UYVY){ if (writeFrameUYVY(hOutBuf, outFile) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write image to file\n"); goto cleanup; } } else if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_YUV420PSEMI) { if (writeFrameSemiPlanar(hOutBuf, outFile) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write image to file\n"); goto cleanup; } } else if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_YUV420P || ColorSpace_YUV422P || ColorSpace_YUV444P || ColorSpace_GRAY){ /* For XDM_GRAY ignoring the color planes */ if (args->oColorSpace == ColorSpace_GRAY){ BufferGfx_setColorSpace (hOutBuf, ColorSpace_GRAY); } if (writeFramePlanar(hOutBuf, outFile) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write image to file\n"); goto cleanup; } } else { ret = Dmai_EFAIL; fprintf(stderr,"Invalid output colorspace.\n"); goto cleanup; } if (args->benchmark) { if (Time_total(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (unsigned int)time); } cleanup: /* Clean up the application */ if (hId) { Idec1_delete(hId); } if (hInBuf) { Buffer_delete(hInBuf); } if (hOutBuf) { Buffer_delete(hOutBuf); } if (hEngine) { Engine_close(hEngine); } if (hTime) { Time_delete(hTime); } if (inFile) { fclose(inFile); } if (outFile) { fclose(outFile); } printf("End of application.\n"); if (ret == Dmai_EFAIL) return 1; else return 0; }
/* * ======== call ======== */ static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg) { _AUDENC1_Msg *msg = (_AUDENC1_Msg *)visaMsg; AUDENC1_Handle handle = (AUDENC1_Handle)visaHandle; Int i; XDM1_BufDesc inBufs, outBufs; IAUDENC1_OutArgs *pOutArgs; IAUDENC1_Status *pStatus; Int numBufs; /* perform the requested AUDENC1 operation by parsing message. */ switch (msg->visa.cmd) { case _AUDENC1_CPROCESS: { /* unmarshal inBufs and outBufs */ inBufs = msg->cmd.process.inBufs; outBufs = msg->cmd.process.outBufs; if (SKEL_cachingPolicy == SKEL_LOCALBUFFERINVWB) { /* invalidate cache for all input buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (inBufs.descs[i].buf != NULL) { /* valid member of sparse array, manage it */ Memory_cacheInv(inBufs.descs[i].buf, inBufs.descs[i].bufSize); if (++numBufs == inBufs.numBufs) { break; } } } /* invalidate cache for buffers in inArgs */ if (msg->cmd.process.inArgs.ancData.buf != NULL) { Memory_cacheInv(msg->cmd.process.inArgs.ancData.buf, msg->cmd.process.inArgs.ancData.bufSize); } /* invalidate cache for all output buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (outBufs.descs[i].buf != NULL) { /* valid member of sparse array, manage it */ Memory_cacheInv(outBufs.descs[i].buf, outBufs.descs[i].bufSize); if (++numBufs == outBufs.numBufs) { break; } } } } /* unmarshall outArgs based on the "size" of inArgs */ pOutArgs = (IAUDENC1_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) + msg->cmd.process.inArgs.size); /* make the process call */ msg->visa.status = AUDENC1_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 all output buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if ((outBufs.descs[i].buf != NULL) && XDM_ISACCESSMODE_WRITE(outBufs.descs[i].accessMask)) { /* valid member of sparse array, written to via CPU */ Memory_cacheWb(outBufs.descs[i].buf, outBufs.descs[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(outBufs.descs[i].accessMask); */ if (++numBufs == outBufs.numBufs) { break; } } } } /* * 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 _AUDENC1_CCONTROL: { /* unmarshall status based on the "size" of params */ pStatus = (IAUDENC1_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 = AUDENC1_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); }
static int do_transcodeFrame(CodecEngine* _ce, const void* _srcFramePtr, size_t _srcFrameSize, void* _dstFramePtr, size_t _dstFrameSize, size_t* _dstFrameUsed) { if (_ce->m_srcBuffer == NULL || _ce->m_dstBuffer == NULL) return ENOTCONN; if (_srcFramePtr == NULL || _dstFramePtr == NULL) return EINVAL; if (_srcFrameSize > _ce->m_srcBufferSize || _dstFrameSize > _ce->m_dstBufferSize) return ENOSPC; VIDTRANSCODE_InArgs tcInArgs; memset(&tcInArgs, 0, sizeof(tcInArgs)); tcInArgs.size = sizeof(tcInArgs); tcInArgs.numBytes = _srcFrameSize; tcInArgs.inputID = 1; // must be non-zero, otherwise caching issues appear VIDTRANSCODE_OutArgs tcOutArgs; memset(&tcOutArgs, 0, sizeof(tcOutArgs)); tcOutArgs.size = sizeof(tcOutArgs); XDM1_BufDesc tcInBufDesc; memset(&tcInBufDesc, 0, sizeof(tcInBufDesc)); tcInBufDesc.numBufs = 1; tcInBufDesc.descs[0].buf = _ce->m_srcBuffer; tcInBufDesc.descs[0].bufSize = _srcFrameSize; XDM_BufDesc tcOutBufDesc; memset(&tcOutBufDesc, 0, sizeof(tcOutBufDesc)); XDAS_Int8* tcOutBufDesc_bufs[1]; XDAS_Int32 tcOutBufDesc_bufSizes[1]; tcOutBufDesc.numBufs = 1; tcOutBufDesc.bufs = tcOutBufDesc_bufs; tcOutBufDesc.bufs[0] = _ce->m_dstBuffer; tcOutBufDesc.bufSizes = tcOutBufDesc_bufSizes; tcOutBufDesc.bufSizes[0] = _dstFrameSize; memcpy(_ce->m_srcBuffer, _srcFramePtr, _srcFrameSize); Memory_cacheWbInv(_ce->m_srcBuffer, _ce->m_srcBufferSize); // invalidate and flush *whole* cache, not only written portion, just in case Memory_cacheInv(_ce->m_dstBuffer, _ce->m_dstBufferSize); // invalidate *whole* cache, not only expected portion, just in case XDAS_Int32 processResult = VIDTRANSCODE_process(_ce->m_vidtranscodeHandle, &tcInBufDesc, &tcOutBufDesc, &tcInArgs, &tcOutArgs); if (processResult != IVIDTRANSCODE_EOK) { fprintf(stderr, "VIDTRANSCODE_process(%zu -> %zu) failed: %"PRIi32"/%"PRIi32"\n", _srcFrameSize, _dstFrameSize, processResult, tcOutArgs.extendedError); return EILSEQ; } #warning Remove me after a while if everything is fine #if 0 // does not seems to be needed according to notes in CE skeletons (Wb is done by DSP side, not ARM) if (XDM_ISACCESSMODE_WRITE(tcOutArgs.encodedBuf[0].accessMask)) Memory_cacheWb(_ce->m_dstBuffer, _ce->m_dstBufferSize); #endif if (tcOutArgs.encodedBuf[0].bufSize > _dstFrameSize) { *_dstFrameUsed = _dstFrameSize; fprintf(stderr, "VIDTRANSCODE_process(%zu -> %zu) returned too large buffer %zu, truncated\n", _srcFrameSize, _dstFrameSize, *_dstFrameUsed); } else if (tcOutArgs.encodedBuf[0].bufSize < 0) { *_dstFrameUsed = 0; fprintf(stderr, "VIDTRANSCODE_process(%zu -> %zu) returned negative buffer size\n", _srcFrameSize, _dstFrameSize); } else *_dstFrameUsed = tcOutArgs.encodedBuf[0].bufSize; memcpy(_dstFramePtr, _ce->m_dstBuffer, *_dstFrameUsed); return 0; }
/* * ======== call ======== */ static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg) { _VIDENC2_Msg *msg = (_VIDENC2_Msg *)visaMsg; VIDENC2_Handle handle = (VIDENC2_Handle)visaHandle; Int i; IVIDEO2_BufDesc inBufs; XDM2_BufDesc outBufs; IVIDENC2_OutArgs *pOutArgs; IVIDENC2_Status *pStatus; IVIDENC2_CodecClassConfig *codecClassConfig; Int numBufs; /* get stub/skeleton config data; can be NULL (for old codecs) */ codecClassConfig = (IVIDENC2_CodecClassConfig *) VISA_getCodecClassConfig(visaHandle); /* perform the requested VIDENC2 operation by parsing message. */ switch (msg->visa.cmd) { case _VIDENC2_CPROCESS: { /* unmarshall inBufs and outBufs */ inBufs = msg->cmd.process.inBufs; outBufs = msg->cmd.process.outBufs; /* Should assert inBufs.numPlanes and inBufs.numMetaPlanes * are < 3. */ /* invalidate cache for all input plane buffers */ for (i = 0; i < inBufs.numPlanes; i++) { if (inBufs.planeDesc[i].buf != NULL) { if ((codecClassConfig != NULL) && (codecClassConfig->manageInBufsPlaneDescCache[i] == FALSE)) { /* do nothing, i.e. don't invalidate */ } else { if (inBufs.planeDesc[i].memType == XDM_MEMTYPE_ROW) { Memory_cacheInv(inBufs.planeDesc[i].buf, inBufs.planeDesc[i].bufSize.bytes); } else { /* TODO:H are tiled buffers cacheable? */ } } } } /* invalidate cache for all input meta plane buffers */ for (i = 0; i < inBufs.numMetaPlanes; i++) { if (inBufs.metadataPlaneDesc[i].buf != NULL) { if ((codecClassConfig != NULL) && (codecClassConfig->manageInBufsMetaPlaneDescCache[i] == FALSE)) { /* do nothing, i.e. don't invalidate */ } else { if (inBufs.metadataPlaneDesc[i].memType == XDM_MEMTYPE_ROW) { Memory_cacheInv(inBufs.metadataPlaneDesc[i].buf, inBufs.metadataPlaneDesc[i].bufSize.bytes); } else { /* TODO:H are tiled buffers cacheable? */ } } } } /* invalidate cache for all output buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (outBufs.descs[i].buf != 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 { if (outBufs.descs[i].memType == XDM_MEMTYPE_ROW) { Memory_cacheInv(outBufs.descs[i].buf, outBufs.descs[i].bufSize.bytes); } else { /* TODO:H are tiled buffers cacheable? */ } } if (++numBufs == outBufs.numBufs) { break; } } } /* unmarshall outArgs based on the "size" of inArgs */ pOutArgs = (IVIDENC2_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 = VIDENC2_process(handle, &inBufs, &outBufs, &(msg->cmd.process.inArgs), pOutArgs); #if 0 /* TODO! */ /* 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); */ } } #endif /* TODO! */ /* * 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 _VIDENC2_CCONTROL: { /* unmarshall status based on the "size" of params */ pStatus = (IVIDENC2_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 = VIDENC2_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); }
/****************************************************************************** * appMain ******************************************************************************/ Void appMain(Args * args) { VIDENC_Params params = Venc_Params_DEFAULT; VIDENC_DynamicParams dynParams = Venc_DynamicParams_DEFAULT; BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; Venc_Handle hVe = NULL; FILE *outFile = NULL; FILE *inFile = NULL; Engine_Handle hEngine = NULL; Time_Handle hTime = NULL; Int numFrame = 0; Buffer_Handle hOutBuf = NULL; Buffer_Handle hInBuf = NULL; ColorSpace_Type colorSpace; UInt32 time; printf("Starting application...\n"); /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { printf("Failed to create Time object\n"); goto cleanup; } } /* Open input file */ inFile = fopen(args->inFile, "rb"); if (inFile == NULL) { printf("Failed to open input file %s\n", args->inFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(inFile, vbufferIn, _IOFBF, sizeof(vbufferIn)) != 0) { printf("Failed to setvbuf on input file descriptor\n"); goto cleanup; } /* Open output file */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { printf("Failed to open output file %s\n", args->outFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbufferOut, _IOFBF, sizeof(vbufferOut)) != 0) { printf("Failed to setvbuf on output file descriptor\n"); goto cleanup; } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { printf("Failed to open codec engine: %s\n", args->engineName); goto cleanup; } params.maxWidth = args->width; params.maxHeight = args->height; /* Set up codec parameters depending on bit rate */ if (args->bitRate < 0) { /* Variable bit rate */ params.rateControlPreset = IVIDEO_NONE; /* * If variable bit rate use a bogus bit rate value (> 0) * since it will be ignored. */ params.maxBitRate = 2000000; } else { /* Constant bit rate */ params.rateControlPreset = IVIDEO_LOW_DELAY; params.maxBitRate = args->bitRate; } params.inputChromaFormat = XDM_YUV_422ILE; dynParams.targetBitRate = params.maxBitRate; dynParams.inputWidth = params.maxWidth; dynParams.inputHeight = params.maxHeight; /* Create the video encoder */ hVe = Venc_create(hEngine, args->codecName, ¶ms, &dynParams); if (hVe == NULL) { printf("Failed to create video encoder: %s\n", args->codecName); goto cleanup; } /* Only the UYVY colorspace is supported in this application */ colorSpace = ColorSpace_UYVY; /* Align buffers to cache line boundary */ gfxAttrs.bAttrs.memParams.align = bAttrs.memParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { gfxAttrs.bAttrs.memParams.flags = bAttrs.memParams.flags = Memory_CACHED; } /* Calculate the buffer attributes */ gfxAttrs.dim.width = args->width; gfxAttrs.dim.height = args->height; gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(args->width, colorSpace); gfxAttrs.colorSpace = colorSpace; /* Create input buffer */ hInBuf = Buffer_create(Dmai_roundUp(Venc_getInBufSize(hVe), BUFSIZEALIGN), BufferGfx_getBufferAttrs(&gfxAttrs)); if (hInBuf == NULL) { printf("Failed to allocate contiguous buffer\n"); goto cleanup; } /* Create output buffer */ hOutBuf = Buffer_create(Dmai_roundUp(Venc_getOutBufSize(hVe), BUFSIZEALIGN), &bAttrs); if (hOutBuf == NULL) { printf("Failed to create contiguous buffer\n"); goto cleanup; } while (numFrame++ < args->numFrames) { /* Read a yuv input frame */ printf("Frame %d: ", numFrame); if (readFrameUYVY(hInBuf, inFile) < 0) { goto cleanup; } if (args->benchmark) { if (Time_reset(hTime) < 0) { printf("Failed to reset timer\n"); goto cleanup; } } if (args->cache) { /* * To meet xDAIS DMA Rule 7, when input buffers are cached, we * must writeback the cache into physical memory. Also, per DMA * Rule 7, we must invalidate the output buffer from * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(Buffer_getUserPtr(hInBuf), Buffer_getSize(hInBuf)); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus \n", (Uns) time); } } /* Encode the video buffer */ if (Venc_process(hVe, hInBuf, hOutBuf) < 0) { printf("Failed to encode video buffer\n"); goto cleanup; } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get encode time\n"); goto cleanup; } printf("[%d] Encode: %uus\n", numFrame, (Uns)time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus \n", (Uns) time); } } /* Write the encoded frame to the file system */ if (Buffer_getNumBytesUsed(hOutBuf)) { if (fwrite(Buffer_getUserPtr(hOutBuf), Buffer_getNumBytesUsed(hOutBuf), 1, outFile) != 1) { printf("Failed to write encoded video data to file\n"); goto cleanup; } } if (args->benchmark) { if (Time_total(hTime, &time) < 0) { printf("Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (unsigned int)time); } } cleanup: /* Clean up the application */ if (hOutBuf) { Buffer_delete(hOutBuf); } if (hInBuf) { Buffer_delete(hInBuf); } if (hVe) { Venc_delete(hVe); } if (hEngine) { Engine_close(hEngine); } if (inFile) { fclose(inFile); } if (outFile) { fclose(outFile); } if (hTime) { Time_delete(hTime); } printf("End of application.\n"); return; }
/* * ======== encode_decode ======== */ static Void encode_decode(SPHENC_Handle enc, SPHDEC_Handle dec, FILE *in, FILE *out) { Int n; Int32 status; SPHDEC_InArgs decInArgs; SPHDEC_OutArgs decOutArgs; SPHDEC_DynamicParams decDynParams; SPHDEC_Status decStatus; SPHENC_InArgs encInArgs; SPHENC_OutArgs encOutArgs; SPHENC_DynamicParams encDynParams; SPHENC_Status encStatus; XDM_BufDesc inBufDesc; XDAS_Int8 *src[XDM_MAX_IO_BUFFERS]; XDAS_Int32 inBufSizes[XDM_MAX_IO_BUFFERS]; XDM_BufDesc encodedBufDesc; XDAS_Int8 *encoded[XDM_MAX_IO_BUFFERS]; XDAS_Int32 encBufSizes[XDM_MAX_IO_BUFFERS]; XDM_BufDesc outBufDesc; XDAS_Int8 *dst[XDM_MAX_IO_BUFFERS]; XDAS_Int32 outBufSizes[XDM_MAX_IO_BUFFERS]; /* clear and initialize the buffer descriptors */ memset(src, 0, sizeof(src[0]) * XDM_MAX_IO_BUFFERS); memset(encoded, 0, sizeof(encoded[0]) * XDM_MAX_IO_BUFFERS); memset(dst, 0, sizeof(dst[0]) * XDM_MAX_IO_BUFFERS); src[0] = inBuf; encoded[0] = encodedBuf; dst[0] = outBuf; inBufDesc.numBufs = encodedBufDesc.numBufs = outBufDesc.numBufs = 1; inBufDesc.bufSizes = inBufSizes; encodedBufDesc.bufSizes = encBufSizes; outBufDesc.bufSizes = outBufSizes; inBufSizes[0] = encBufSizes[0] = outBufSizes[0] = NSAMPLES; inBufDesc.bufs = src; encodedBufDesc.bufs = encoded; outBufDesc.bufs = dst; /* 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); /* * Query the encoder and decoder. * 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 = SPHENC_control(enc, XDM_GETBUFINFO, &encDynParams, &encStatus); if (status != SPHENC_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 = SPHDEC_control(dec, XDM_GETBUFINFO, &decDynParams, &decStatus); if (status != SPHDEC_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++) { #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 = SPHENC_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 != SPHENC_EOK) { GT_2trace(curMask, GT_7CLASS, "App-> Encoder frame %d processing FAILED, status = 0x%x\n", n, status); break; } /* decode the frame */ decInArgs.inBufferSize = encOutArgs.outbufferSize; status = SPHDEC_process(dec, &encodedBufDesc, &outBufDesc, &decInArgs, &decOutArgs); GT_2trace(curMask, GT_2CLASS, "App-> Decoder frame %d process returned - 0x%x\n", n, status); if (status != SPHDEC_EOK) { GT_2trace(curMask, GT_7CLASS, "App-> Decoder frame %d processing FAILED, status = 0x%x\n", n, status); break; } #ifdef CACHE_ENABLED /* Writeback the outBuf. */ Memory_cacheWb(outBuf, OFRAMESIZE); #endif /* write to file */ fwrite(dst[0], OFRAMESIZE, 1, out); } GT_1trace(curMask, GT_1CLASS, "%d frames encoded/decoded\n", n); }
/****************************************************************************** * main ******************************************************************************/ Int appMain(Args * args) { Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Loader_Attrs lAttrs = Loader_Attrs_DEFAULT; AUDDEC1_Params params = Adec1_Params_DEFAULT; AUDDEC1_DynamicParams dynParams = Adec1_DynamicParams_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; Adec1_Handle hAd1 = NULL; Loader_Handle hLoader = NULL; Engine_Handle hEngine = NULL; Buffer_Handle hOutBuf = NULL; Time_Handle hTime = NULL; Buffer_Handle hInBuf = NULL; FILE *outFile = NULL; Int numFrame = 0; UInt32 time; Int ret = Dmai_EOK; Cpu_Device device; printf("Starting application...\n"); if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to create Time object\n"); goto cleanup; } } /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); /* Determine which device the application is running on */ if (Cpu_getDevice(NULL, &device) < 0) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to determine target board\n"); goto cleanup; } /* Open the output file */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create output file %s\n", args->outFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbuffer, _IOFBF, sizeof(vbuffer)) != 0) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to setvbuf on file descriptor\n"); goto cleanup; } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to open codec engine %s\n", args->engineName); goto cleanup; } if (device == Cpu_Device_DM365 || device == Cpu_Device_OMAP3530 || device == Cpu_Device_DM368 || device == Cpu_Device_DM3730) { params.dataEndianness = XDM_LE_16; } /* Create the AUDDEC1 based audio decoder */ hAd1 = Adec1_create(hEngine, args->codecName, ¶ms, &dynParams); if (hAd1 == NULL) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to create audio decoder\n"); goto cleanup; } /* Align buffers to cache line boundary */ bAttrs.memParams.align = lAttrs.mParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { bAttrs.memParams.flags = lAttrs.mParams.flags = Memory_CACHED; } /* Ask the codec how much input data it needs */ lAttrs.readSize = Adec1_getInBufSize(hAd1); /* Make the total ring buffer larger */ lAttrs.readBufSize = Dmai_roundUp(lAttrs.readSize * 10, BUFSIZEALIGN); /* Increase the stdio buffer size for loader for better RTDX performance */ lAttrs.vBufSize = VBUFSIZE; /* Create the file loader */ hLoader = Loader_create(args->inFile, &lAttrs); if (hLoader == NULL) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to create loader\n"); goto cleanup; } /* Create an output buffer for decoded data */ hOutBuf = Buffer_create( Dmai_roundUp(Adec1_getOutBufSize(hAd1), BUFSIZEALIGN), &bAttrs); if (hOutBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to create contiguous buffers\n"); goto cleanup; } /* Prime the file loader */ Loader_prime(hLoader, &hInBuf); while (numFrame++ < args->numFrames) { if (args->benchmark) { if (Time_reset(hTime) < 0) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to reset timer\n"); goto cleanup; } } if (args->cache) { /* * To meet xDAIS DMA Rule 7, when input buffers are cached, we * must writeback the cache into physical memory. Also, per DMA * Rule 7, we must invalidate the output buffer from * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(Buffer_getUserPtr(hInBuf),Buffer_getSize(hInBuf)); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(Buffer_getUserPtr(hOutBuf),Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus ", (Uns) time); } } /* Decode the audio buffer */ ret = Adec1_process(hAd1, hInBuf, hOutBuf); if ((ret == Dmai_EFAIL)|| (ret == Dmai_EBITERROR && Buffer_getNumBytesUsed(hInBuf) == 0)) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to decode audio buffer\n"); goto cleanup; } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to get timer delta\n"); goto cleanup; } printf("Decode: %uus ", (Uns) time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus ", (Uns) time); } } /* Load a new frame from the file system */ Loader_getFrame(hLoader, hInBuf); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Loader: %uus\n", (Uns) time); } if (Buffer_getNumBytesUsed(hOutBuf)) { if (numFrame >= args->startFrame) { printf("Frame %d: ", numFrame); if (writeFrame(hOutBuf, outFile) < 0) { ret = Dmai_EFAIL; goto cleanup; } } } if (Buffer_getUserPtr(hInBuf) == NULL) { printf("Loader returned null, clip finished\n"); break; } if (args->benchmark) { if (Time_total(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (unsigned int)time); } } cleanup: /* Clean up the application */ if (hLoader) { Loader_delete(hLoader); } if (hAd1) { Adec1_delete(hAd1); } if (hOutBuf) { Buffer_delete(hOutBuf); } if (hEngine) { Engine_close(hEngine); } if (hTime) { Time_delete(hTime); } if (outFile) { fclose(outFile); } printf("End of application.\n"); if (ret == Dmai_EFAIL) return 1; else return 0; }
/* * ======== encode_decode ======== */ static Void encode_decode(SPHENC1_Handle enc, SPHDEC1_Handle dec, FILE *in, FILE *out) { Int n; Int32 status; SPHDEC1_InArgs decInArgs; SPHDEC1_OutArgs decOutArgs; SPHDEC1_DynamicParams decDynParams; SPHDEC1_Status decStatus; SPHENC1_InArgs encInArgs; SPHENC1_OutArgs encOutArgs; SPHENC1_DynamicParams encDynParams; SPHENC1_Status encStatus; XDM1_SingleBufDesc inBufDesc; XDM1_SingleBufDesc encodedBufDesc; XDM1_SingleBufDesc outBufDesc; /* init buffer descriptor settings that don't change during processing */ inBufDesc.bufSize = IFRAMESIZE; inBufDesc.buf = inBuf; encodedBufDesc.buf = encodedBuf; outBufDesc.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); /* * We never use the decoder or encoder's inArgs.data fields, so * initialize them NULL. */ decInArgs.data.buf = NULL; encInArgs.data.buf = NULL; /* * 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 = SPHDEC1_control(dec, XDM_GETVERSION, &decDynParams, &decStatus); GT_1trace(curMask, GT_1CLASS, "Decoder version: %s\n", (status == SPHDEC1_EOK ? ((char *)decStatus.data.buf) : "[unknown]")); status = SPHENC1_control(enc, XDM_GETVERSION, &encDynParams, &encStatus); GT_1trace(curMask, GT_1CLASS, "Encoder version: %s\n", (status == SPHENC1_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 = SPHENC1_control(enc, XDM_GETSTATUS, &encDynParams, &encStatus); if (status != SPHENC1_EOK) { /* failure, report error and exit */ GT_1trace(curMask, GT_7CLASS, "encode control status = %ld\n", status); return; } /* Validate this encoder codec will meet our buffer requirements */ if ((IFRAMESIZE < encStatus.bufInfo.minInBufSize[0]) || (EFRAMESIZE < encStatus.bufInfo.minOutBufSize[0])) { /* failure, report error and exit */ GT_0trace(curMask, GT_7CLASS, "Error: encoder codec feature conflict\n"); return; } status = SPHDEC1_control(dec, XDM_GETSTATUS, &decDynParams, &decStatus); if (status != SPHDEC1_EOK) { /* failure, report error and exit */ GT_1trace(curMask, GT_7CLASS, "decode control status = %ld\n", status); return; } /* Validate this decoder codec will meet our buffer requirements */ if ((EFRAMESIZE < decStatus.bufInfo.minInBufSize[0]) || (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++) { /* reset potentially changed 'output' buffers to actual buf sizes. */ encodedBufDesc.bufSize = EFRAMESIZE; outBufDesc.bufSize = OFRAMESIZE; #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, encodedBufDesc.bufSize); #endif GT_1trace(curMask, GT_1CLASS, "App-> Processing frame %d...\n", n); /* encode the frame */ status = SPHENC1_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, encodedBufDesc.bufSize); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(outBuf, outBufDesc.bufSize); #endif if (status != SPHENC1_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 */ status = SPHDEC1_process(dec, &encodedBufDesc, &outBufDesc, &decInArgs, &decOutArgs); GT_2trace(curMask, GT_2CLASS, "App-> Decoder frame %d process returned - 0x%x)\n", n, status); if (status != SPHDEC1_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, outBufDesc.bufSize); #endif /* write to file */ fwrite(outBuf, outBufDesc.bufSize, 1, out); } GT_1trace(curMask, GT_1CLASS, "%d frames encoded/decoded\n", n); }
/* * ======== call ======== */ static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg) { _VIDDEC3_Msg *msg = (_VIDDEC3_Msg *)visaMsg; VIDDEC3_Handle handle = (VIDDEC3_Handle)visaHandle; Int i; XDM2_BufDesc inBufs; XDM2_BufDesc outBufs; IVIDDEC3_OutArgs *pOutArgs; IVIDDEC3_Status *pStatus; IVIDDEC3_CodecClassConfig *codecClassConfig; Int numBufs; Bool success; /* get stub/skeleton config data; can be NULL (for old codecs) */ codecClassConfig = (IVIDDEC3_CodecClassConfig *)VISA_getCodecClassConfig(visaHandle); /* perform the requested VIDDEC2 operation by parsing message. */ switch (msg->visa.cmd) { case _VIDDEC3_CPROCESS: { /* unmarshall inBufs and outBufs */ inBufs = msg->cmd.process.inBufs; outBufs = msg->cmd.process.outBufs; /* invalidate cache for all input buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (inBufs.descs[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 { if (inBufs.descs[i].memType == XDM_MEMTYPE_RAW) { Memory_cacheInv(inBufs.descs[i].buf, inBufs.descs[i].bufSize.bytes); } else { /* TODO:H are tiled buffers cacheable? */ } } if (++numBufs == inBufs.numBufs) { break; } } } /* invalidate cache for all output buffers */ for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) { if (outBufs.descs[i].buf != 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 { if (outBufs.descs[i].memType == XDM_MEMTYPE_RAW) { Memory_cacheInv(outBufs.descs[i].buf, outBufs.descs[i].bufSize.bytes); } else { /* TODO:H are tiled buffers cacheable? */ } } if (++numBufs == outBufs.numBufs) { break; } } } /* unmarshall outArgs based on the "size" of inArgs */ pOutArgs = (IVIDDEC3_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) + msg->cmd.process.inArgs.size); /* * Note, there's no need to invalidate cache for * pOutArgs->decodedBuf bufs nor pOutArgs->displayBufs * bufs as the app doesn't provide OUT buffers to the * algorithm via these fields. */ /* make the process call */ msg->visa.status = VIDDEC3_process(handle, &inBufs, &outBufs, &(msg->cmd.process.inArgs), pOutArgs); /* * We probably should only be doing this if msg->visa.status * is IVIDDEC3_EOK or _EFAIL and .extendedError is non-fatal. */ /* * Writeback cache for all output buffers: * - .decodedBufs * - .displayBufs */ /* * ======== .decodedBufs ======== */ success = writebackVideo2BufDesc(&pOutArgs->decodedBufs); if (!success) { return (VISA_EFAIL); } /* * ======== .displayBufs ======== */ /* identify which mode the displayBufs are returned as */ if (pOutArgs->displayBufsMode == IVIDDEC3_DISPLAYBUFS_EMBEDDED) { /* the display buffers are embedded in the outArgs struct */ for (i = 0; (pOutArgs->outputID[i] != 0) && (i < IVIDEO2_MAX_IO_BUFFERS); i++) { success = writebackVideo2BufDesc( &(pOutArgs->displayBufs.bufDesc[i])); if (!success) { return (VISA_EFAIL); } } } else { /* the display buffers are pointed to in the outArgs struct */ for (i = 0; (pOutArgs->outputID[i] != 0) && (i < IVIDEO2_MAX_IO_BUFFERS); i++) { success = writebackVideo2BufDesc( pOutArgs->displayBufs.pBufDesc[i]); if (!success) { return (VISA_EFAIL); } } } /* * 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 _VIDDEC3_CCONTROL: { /* unmarshall status based on the "size" of params */ pStatus = (IVIDDEC3_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 = VIDDEC3_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); }
/****************************************************************************** * appMain ******************************************************************************/ Int appMain(Args * args) { VIDENC1_Params params = Venc1_Params_DEFAULT; VIDENC1_DynamicParams dynParams = Venc1_DynamicParams_DEFAULT; BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; Venc1_Handle hVe1 = NULL; FILE *outFile = NULL; FILE *reconFile = NULL; FILE *inFile = NULL; Engine_Handle hEngine = NULL; Time_Handle hTime = NULL; Bool flushed = FALSE; Bool mustExit = FALSE; BufTab_Handle hBufTab = NULL; Buffer_Handle hOutBuf = NULL; Buffer_Handle hFreeBuf = NULL; Buffer_Handle hInBuf = NULL; Buffer_Handle hReconBuf = NULL; Int numFrame = 0; Int flushCntr = 1; Int bufIdx; Int inBufSize, outBufSize; Cpu_Device device; Int numBufs; ColorSpace_Type colorSpace; UInt32 time; Int ret = Dmai_EOK; printf("Starting application...\n"); /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); /* Determine which device the application is running on */ if (Cpu_getDevice(NULL, &device) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to determine target board\n"); goto cleanup; } if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create Time object\n"); goto cleanup; } } /* Open the input file with raw yuv data */ inFile = fopen(args->inFile, "rb"); if (inFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open input file %s\n", args->inFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(inFile, vbufferIn, _IOFBF, sizeof(vbufferIn)) != 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to setvbuf on input file descriptor\n"); goto cleanup; } /* Open the output file where to put encoded data */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open output file %s\n", args->outFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbufferOut, _IOFBF, sizeof(vbufferOut)) != 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to setvbuf on output file descriptor\n"); goto cleanup; } /* Open the output file where to put reconstructed frames */ if (args->writeReconFrames) { reconFile = fopen(args->reconFile, "wb"); if (reconFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open output file %s\n", args->reconFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(reconFile, vbufferRecon, _IOFBF, sizeof(vbufferRecon)) != 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to setvbuf on output file descriptor\n"); goto cleanup; } } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open codec engine: %s\n", args->engineName); goto cleanup; } /* Set up codec parameters depending on bit rate */ if (args->bitRate < 0) { /* Variable bit rate */ params.rateControlPreset = IVIDEO_NONE; /* * If variable bit rate use a bogus bit rate value (> 0) * since it will be ignored. */ params.maxBitRate = 2000000; } else { /* Constant bit rate */ params.rateControlPreset = IVIDEO_LOW_DELAY; params.maxBitRate = args->bitRate; } /* Set up codec parameters depending on device */ switch (device) { case Cpu_Device_DM6467: params.inputChromaFormat = XDM_YUV_420SP; params.reconChromaFormat = XDM_CHROMA_NA; break; case Cpu_Device_DM355: params.inputChromaFormat = XDM_YUV_422ILE; params.reconChromaFormat = XDM_YUV_420P; break; case Cpu_Device_DM365: case Cpu_Device_DM368: params.inputChromaFormat = XDM_YUV_420SP; params.reconChromaFormat = XDM_YUV_420SP; break; case Cpu_Device_DM3730: params.rateControlPreset = IVIDEO_STORAGE; params.inputChromaFormat = XDM_YUV_422ILE; break; default: params.inputChromaFormat = XDM_YUV_422ILE; break; } params.maxWidth = args->width; params.maxHeight = args->height; /* Workaround for SDOCM00068944: h264fhdvenc fails to create codec when params.dataEndianness is set as XDM_BYTE */ if(device == Cpu_Device_DM6467) { if (!strcmp(args->codecName, "h264fhdvenc")) { params.dataEndianness = XDM_LE_32; } } params.maxInterFrameInterval = 1; dynParams.targetBitRate = params.maxBitRate; dynParams.inputWidth = params.maxWidth; dynParams.inputHeight = params.maxHeight; /* Create the video encoder */ hVe1 = Venc1_create(hEngine, args->codecName, ¶ms, &dynParams); if (hVe1 == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create video encoder: %s\n", args->codecName); goto cleanup; } /* Ask the codec how much input data it needs */ inBufSize = Venc1_getInBufSize(hVe1); /* Ask the codec how much space it needs for output data */ outBufSize = Venc1_getOutBufSize(hVe1); /* Which color space to use in the graphics buffers depends on the device */ colorSpace = ((device == Cpu_Device_DM6467)|| (device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) ? ColorSpace_YUV420PSEMI : ColorSpace_UYVY; /* Align buffers to cache line boundary */ gfxAttrs.bAttrs.memParams.align = bAttrs.memParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { gfxAttrs.bAttrs.memParams.flags = bAttrs.memParams.flags = Memory_CACHED; } gfxAttrs.dim.width = args->width; gfxAttrs.dim.height = args->height; if ((device == Cpu_Device_DM6467) || (device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) { gfxAttrs.dim.height = Dmai_roundUp(gfxAttrs.dim.height, CODECHEIGHTALIGN); } gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(args->width, colorSpace); gfxAttrs.colorSpace = colorSpace; if (inBufSize < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to calculate buffer attributes\n"); goto cleanup; } /* Number of input buffers required */ if(params.maxInterFrameInterval>1) { /* B frame support */ numBufs = params.maxInterFrameInterval; } else { numBufs = 1; } /* Create a table of input buffers of the size requested by the codec */ hBufTab = BufTab_create(numBufs, Dmai_roundUp(inBufSize, BUFSIZEALIGN), BufferGfx_getBufferAttrs(&gfxAttrs)); if (hBufTab == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to allocate contiguous buffers\n"); goto cleanup; } /* Set input buffer table */ Venc1_setBufTab(hVe1, hBufTab); /* Create the reconstructed frame buffer for raw yuv data */ if (args->writeReconFrames) { hReconBuf = Buffer_create(Dmai_roundUp(inBufSize, BUFSIZEALIGN), BufferGfx_getBufferAttrs(&gfxAttrs)); if (hReconBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to allocate contiguous buffer\n"); goto cleanup; } } /* Create the output buffer for encoded video data */ hOutBuf = Buffer_create(Dmai_roundUp(outBufSize, BUFSIZEALIGN), &bAttrs); if (hOutBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create contiguous buffer\n"); goto cleanup; } while (1) { /* Get a buffer for input */ hInBuf = BufTab_getFreeBuf(hBufTab); if (hInBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get a free contiguous buffer from BufTab\n"); BufTab_print(hBufTab); goto cleanup; } if (args->benchmark) { if (Time_reset(hTime) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to reset timer\n"); goto cleanup; } } /* Read a yuv input frame */ printf("\n Frame %d: ", numFrame); if ((device == Cpu_Device_DM6467)|| (device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) { if(args->sp) { if (readFrame420SP(hInBuf, inFile, args->height) < 0) { ret = Dmai_EFAIL; goto cleanup; } } else { if (readFrame420P(hInBuf, inFile, args->height) < 0) { ret = Dmai_EFAIL; goto cleanup; } } } else { if (readFrameUYVY(hInBuf, inFile) < 0) { ret = Dmai_EFAIL; mustExit = TRUE; } } if (++numFrame == args->numFrames||mustExit == TRUE) { if(!(params.maxInterFrameInterval>1)) { /* No B-frame support */ printf("... exiting \n"); goto cleanup; } /* * When encoding a stream with B-frames, ending the processing * requires to free the buffer held by the encoder. This is done by * flushing the encoder and performing a last process() call * with a dummy input buffer. */ printf("\n... exiting with flush (B-frame stream) \n"); flushCntr = params.maxInterFrameInterval-1; flushed = TRUE; Venc1_flush(hVe1); } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Read time: %uus\n", (Uns)time); } /* * Following flushing loop will iterate more than one time only * when the encoder completes processing by flushing the frames * held by the encoder. All flushed frames will be encoded as P * or I frames. */ for(bufIdx = 0; bufIdx < flushCntr; bufIdx++) { if (args->cache) { /* * To meet xDAIS DMA Rule 7, when input buffers are cached, we * must writeback the cache into physical memory. Also, per DMA * Rule 7, we must invalidate the output buffer from * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(Buffer_getUserPtr(hInBuf), Buffer_getSize(hInBuf)); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus \n", (Uns) time); } } /* Make sure the whole buffer is used for input */ BufferGfx_resetDimensions(hInBuf); /* Encode the video buffer */ if (Venc1_process(hVe1, hInBuf, hOutBuf) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to encode video buffer\n"); goto cleanup; } /* if encoder generated output content, free released buffer */ if (Buffer_getNumBytesUsed(hOutBuf)>0) { /* Get free buffer */ hFreeBuf = Venc1_getFreeBuf(hVe1); /* Free buffer */ BufTab_freeBuf(hFreeBuf); } /* if encoder did not generate output content */ else { /* if non B frame sequence */ /* encoder skipped frame probably exceeding target bitrate */ if (params.maxInterFrameInterval<=1) { /* free buffer */ printf(" Encoder generated 0 size frame\n"); BufTab_freeBuf(hInBuf); } } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get encode time\n"); goto cleanup; } printf("[%d] Encode: %uus\n", numFrame, (Uns)time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus \n", (Uns) time); } } /* Write the encoded frame to the file system */ if (Buffer_getNumBytesUsed(hOutBuf)) { if (fwrite(Buffer_getUserPtr(hOutBuf), Buffer_getNumBytesUsed(hOutBuf), 1, outFile) != 1) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write encoded video data to file\n"); goto cleanup; } } /* Write the reconstructed frame to the file system */ if (args->writeReconFrames) { processReconData(Venc1_getReconBufs(hVe1), hInBuf, hReconBuf); if (Buffer_getNumBytesUsed(hReconBuf)) { if (fwrite(Buffer_getUserPtr(hReconBuf), Buffer_getNumBytesUsed(hReconBuf), 1, reconFile) != 1) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write reconstructed frame to file\n"); goto cleanup; } } } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; printf("Failed to get timer delta\n"); goto cleanup; } printf("File write time: %uus\n", (Uns)time); if (Time_total(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (Uns)time); } } /* If the codec flushing completed, exit main thread */ if (flushed) { /* Free dummy input buffer used for flushing process() calls */ printf("freeing dummy input buffer ... \n"); BufTab_freeBuf(hInBuf); break; } } cleanup: /* Clean up the application */ if (hOutBuf) { Buffer_delete(hOutBuf); } if (hReconBuf) { Buffer_delete(hReconBuf); } if (hVe1) { Venc1_delete(hVe1); } if (hBufTab) { BufTab_delete(hBufTab); } if (hEngine) { Engine_close(hEngine); } if (inFile) { fclose(inFile); } if (outFile) { fclose(outFile); } if (reconFile) { fclose(reconFile); } if (hTime) { Time_delete(hTime); } printf("End of application.\n"); if (ret == Dmai_EFAIL) return 1; else return 0; }
/* * ======== processLoop ======== */ static Void processLoop(UNIVERSAL_Handle hUniversal, FILE *in, FILE *out, XDAS_Int8 *inBuf, XDAS_Int8 *outBuf, XDAS_Int8 *versionBuf) { Int n; Int32 status; UNIVERSAL_InArgs universalInArgs; UNIVERSAL_OutArgs universalOutArgs; UNIVERSAL_DynamicParams universalDynParams; UNIVERSAL_Status universalStatus; XDM1_BufDesc universalInBufDesc; XDM1_BufDesc universalOutBufDesc; /* initialize bufDescs */ universalInBufDesc.numBufs = universalOutBufDesc.numBufs = 1; universalInBufDesc.descs[0].bufSize = universalOutBufDesc.descs[0].bufSize = NSAMPLES; universalInBufDesc.descs[0].buf = inBuf; universalOutBufDesc.descs[0].buf = outBuf; /* initialize all "sized" fields */ universalInArgs.size = sizeof(universalInArgs); universalOutArgs.size = sizeof(universalOutArgs); universalDynParams.size = sizeof(universalDynParams); universalStatus.size = sizeof(universalStatus); /* if the codecs support it, dump their versions */ universalStatus.data.numBufs = 1; universalStatus.data.descs[0].buf = versionBuf; universalStatus.data.descs[0].bufSize = MAXVERSIONSIZE; universalStatus.data.descs[1].buf = NULL; #ifdef CACHE_ENABLED /* invalidate versionBuf it before the alg fills it */ Memory_cacheInv(versionBuf, MAXVERSIONSIZE); #endif status = UNIVERSAL_control(hUniversal, XDM_GETVERSION, &universalDynParams, &universalStatus); Log_print1(Diags_USER1, "[+1] Alg version: %s", (IArg)((status == UNIVERSAL_EOK ? ((char *)universalStatus.data.descs[0].buf) : "[unknown]"))); /* * Read complete frames from in, process them, 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(outBuf, OFRAMESIZE); #endif Log_print1(Diags_USER1, "[+1] App-> Processing frame %d...", (IArg)n); /* * Transcode the frame. * * Note, inputID == 0 is an error. This example doesn't account * for the case where 'n + 1' wraps to zero. */ status = UNIVERSAL_process(hUniversal, &universalInBufDesc, &universalOutBufDesc, NULL, &universalInArgs, &universalOutArgs); Log_print2(Diags_USER2, "[+2] App-> Alg frame %d process returned - 0x%x", (IArg)n, (IArg)status); if (status != UNIVERSAL_EOK) { Log_print3(Diags_USER7, "[+7] App-> Alg frame %d processing FAILED, status = 0x%x, " "extendedError = 0x%x", (IArg)n, (IArg)status, (IArg)(universalOutArgs.extendedError)); break; } #ifdef CACHE_ENABLED /* * Conditionally writeback the processed buf from the previous * call. This [pessimistic] writeback illustrates the general * situation where the subsequent access of outBuf (fwrite(), in * this case), is not known to be via CPU/cache or DMA/physical mem. * * An optimized system, where the access mode of outBufs known, * may be able to eliminate this writeback. */ if (XDM_ISACCESSMODE_WRITE(universalOutBufDesc.descs[0].accessMask)) { Memory_cacheWb(outBuf, OFRAMESIZE); } #endif /* write to file */ fwrite(outBuf, OFRAMESIZE, 1, out); } Log_print1(Diags_USER1, "[+1] %d frames processed", (IArg)n); }
/* * ======== call ======== */ static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg) { _VIDTRANSCODE_Msg *msg = (_VIDTRANSCODE_Msg *)visaMsg; VIDTRANSCODE_Handle handle = (VIDTRANSCODE_Handle)visaHandle; Int i; XDM1_BufDesc inBufs; XDM_BufDesc outBufs; IVIDTRANSCODE_OutArgs *pOutArgs; IVIDTRANSCODE_Status *pStatus; Int numBufs; /* perform the requested VIDTRANSCODE operation by parsing message. */ switch (msg->visa.cmd) { case _VIDTRANSCODE_CPROCESS: { /* unmarshal 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.descs[i].buf != NULL) { /* valid member of sparse array, manage it */ Memory_cacheInv(inBufs.descs[i].buf, inBufs.descs[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, manage it */ Memory_cacheInv(outBufs.bufs[i], outBufs.bufSizes[i]); if (++numBufs == outBufs.numBufs) { break; } } } } /* unmarshall outArgs based on the "size" of inArgs */ pOutArgs = (IVIDTRANSCODE_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) + msg->cmd.process.inArgs.size); /* * Note, there's no need to invalidate cache for * pOutArgs->encodedBuf 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 = VIDTRANSCODE_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 buffers */ for (i = 0; i < IVIDTRANSCODE_MAXOUTSTREAMS; i++) { if ((pOutArgs->outputID[0] != 0) && (pOutArgs->encodedBuf[i].buf != NULL) && XDM_ISACCESSMODE_WRITE(pOutArgs->encodedBuf[i].accessMask)) { Memory_cacheWb(pOutArgs->encodedBuf[i].buf, pOutArgs->encodedBuf[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.encodedBuf[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 _VIDTRANSCODE_CCONTROL: { /* unmarshall status based on the "size" of params */ pStatus = (IVIDTRANSCODE_Status *)((UInt)(&(msg->cmd.control.dynParams)) + msg->cmd.control.dynParams.size); /* invalidate data buffer */ if (pStatus->data.buf != NULL) { Memory_cacheInv(pStatus->data.buf, pStatus->data.bufSize); } msg->visa.status = VIDTRANSCODE_control(handle, msg->cmd.control.id, &(msg->cmd.control.dynParams), 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); }
/* * ======== 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); }
/* * ======== encode_decode ======== */ static Void encode_decode(AUDENC1_Handle enc, AUDDEC1_Handle dec, FILE *in, FILE *out) { Int n; Int32 status; AUDDEC1_InArgs decInArgs; AUDDEC1_OutArgs decOutArgs; AUDDEC1_DynamicParams decDynParams; AUDDEC1_Status decStatus; AUDENC1_InArgs encInArgs; AUDENC1_OutArgs encOutArgs; AUDENC1_DynamicParams encDynParams; AUDENC1_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); /* ancillary data to encode */ #if USE_ANCDATA encInArgs.ancData.buf = ancBuf; encInArgs.ancData.bufSize = ENCANCBUFSIZE; #else /* Be sure to initialize these to NULL! */ encInArgs.ancData.buf = NULL; encInArgs.ancData.bufSize = 0; #endif /* * 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 = AUDDEC1_control(dec, XDM_GETVERSION, &decDynParams, &decStatus); GT_1trace(curMask, GT_1CLASS, "Decoder version: %s\n", (status == AUDDEC1_EOK ? ((char *)decStatus.data.buf) : "[unknown]")); status = AUDENC1_control(enc, XDM_GETVERSION, &encDynParams, &encStatus); GT_1trace(curMask, GT_1CLASS, "Encoder version: %s\n", (status == AUDENC1_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 = AUDENC1_control(enc, XDM_GETBUFINFO, &encDynParams, &encStatus); if (status != AUDENC1_EOK) { /* failure, report error and exit */ GT_1trace(curMask, GT_7CLASS, "encode control status = %ld\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 = AUDDEC1_control(dec, XDM_GETBUFINFO, &decDynParams, &decStatus); if (status != AUDDEC1_EOK) { /* failure, report error and exit */ GT_1trace(curMask, GT_7CLASS, "decode control status = %ld\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 USE_ANCDATA /* we send the same data as inBuf as ancillory data */ memcpy(ancBuf, inBuf, ENCANCBUFSIZE); #endif /* 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 #if USE_ANCDATA /* ancBuf is an inBuf, filled via memcpy (i.e. CPU writes) */ Memory_cacheWbInv(ancBuf, ENCANCBUFSIZE); #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. Note that .numInSamples is the number of * _samples_ not bytes. IFRAMESIZE is in 8-bit bytes, so there's a * little math here to get .numInSamples right. */ encInArgs.numInSamples = (IFRAMESIZE / (ENCBITSPERSAMPLE / (8 /* bits per byte */))); status = AUDENC1_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 != AUDENC1_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 = EFRAMESIZE; status = AUDDEC1_process(dec, &encodedBufDesc, &outBufDesc, &decInArgs, &decOutArgs); GT_2trace(curMask, GT_2CLASS, "App-> Decoder frame %d process returned - 0x%x)\n", n, status); if (status != AUDDEC1_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); } GT_1trace(curMask, GT_1CLASS, "%d frames encoded/decoded\n", n); }
/****************************************************************************** * appMain ******************************************************************************/ Void appMain(Args * args) { Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; SPHENC1_Params params = Senc1_Params_DEFAULT; SPHENC1_DynamicParams dynParams = Senc1_DynamicParams_DEFAULT; Senc1_Handle hSe1 = NULL; Engine_Handle hEngine = NULL; Buffer_Handle hOutBuf = NULL; Buffer_Handle hInBuf = NULL; Time_Handle hTime = NULL; FILE *inFile = NULL; FILE *outFile = NULL; Int numFrame = 0; Int32 bytesRead; UInt32 time; printf("Starting application...\n"); if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { printf("Failed to create Time object\n"); goto cleanup; } } /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); /* Open the output file */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { printf("Failed to create output file %s\n", args->outFile); goto cleanup; } /* Open the input file */ inFile = fopen(args->inFile, "rb"); if (inFile == NULL) { printf("Failed to open input file %s\n", args->inFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbuffer, _IOFBF, sizeof(vbuffer)) != 0) { printf("Failed to setvbuf on file descriptor\n"); goto cleanup; } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { printf("Failed to open codec engine %s\n", args->engineName); goto cleanup; } params.compandingLaw = args->compandingLaw; /* Create the SPHENC1 based speech encoder */ hSe1 = Senc1_create(hEngine, args->codecName, ¶ms, &dynParams); if (hSe1 == NULL) { printf("Failed to create %s\n", args->codecName); goto cleanup; } /* Align buffers to cache line boundary */ bAttrs.memParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { bAttrs.memParams.flags = Memory_CACHED; } /* Create an output buffer for encoded data */ hOutBuf = Buffer_create( Dmai_roundUp(Senc1_getOutBufSize(hSe1), BUFSIZEALIGN), &bAttrs); if (hOutBuf == NULL) { printf("Failed to create contiguous buffer\n"); goto cleanup; } /* Create an input buffer for input data */ hInBuf = Buffer_create(Dmai_roundUp(Senc1_getInBufSize(hSe1), BUFSIZEALIGN), &bAttrs); if (hInBuf == NULL) { printf("Failed to create contiguous buffer\n"); goto cleanup; } while (numFrame++ < args->numFrames) { printf("Frame %d: ", numFrame); if (args->benchmark) { if (Time_reset(hTime) < 0) { printf("Failed to reset timer\n"); goto cleanup; } } /* Read raw PCM data from input file */ bytesRead = fread(Buffer_getUserPtr(hInBuf), 1, Senc1_getInBufSize(hSe1), inFile); if (bytesRead < Senc1_getInBufSize(hSe1)) { if (ferror(inFile)) { printf("Failed to read data from input file\n"); goto cleanup; } printf("Failed to read full frame %ld bytes, read %ld bytes\n", Senc1_getInBufSize(hSe1),bytesRead); goto cleanup; } Buffer_setNumBytesUsed(hInBuf, bytesRead); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Read: %uus ", (Uns) time); } if (args->cache) { /* * To meet xDAIS DMA Rule 7, when input buffers are cached, we * must writeback the cache into physical memory. Also, per DMA * Rule 7, we must invalidate the output buffer from * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(Buffer_getUserPtr(hInBuf), Buffer_getSize(hInBuf)); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus ", (Uns) time); } } /* Encode the speech buffer */ if (Senc1_process(hSe1, hInBuf, hOutBuf) < 0) { printf("Failed to encode speech buffer\n"); goto cleanup; } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Encode: %uus ", (Uns) time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus ", (Uns) time); } } printf("Write encoded speech data to output file \n"); /* Write the encoded frame to the file system */ if (Buffer_getNumBytesUsed(hOutBuf)) { if (fwrite(Buffer_getUserPtr(hOutBuf), Buffer_getNumBytesUsed(hOutBuf), 1, outFile) != 1) { printf("Failed to write encoded speech data to file\n"); goto cleanup; } } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Write: %uus ", (Uns) time); if (Time_total(hTime, &time) < 0) { printf("Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (unsigned int)time); } } cleanup: /* Clean up the application */ if (hSe1) { Senc1_delete(hSe1); } if (hInBuf) { Buffer_delete(hInBuf); } if (hOutBuf) { Buffer_delete(hOutBuf); } if (hEngine) { Engine_close(hEngine); } if (hTime) { Time_delete(hTime); } if (inFile) { fclose(inFile); } if (outFile) { fclose(outFile); } printf("End of application.\n"); return; }
/* * ======== call ======== */ static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg) { _AUDENC_Msg *msg = (_AUDENC_Msg *)visaMsg; AUDENC_Handle handle = (AUDENC_Handle)visaHandle; Int i; XDM_BufDesc inBufs, outBufs; IAUDENC_OutArgs *pOutArgs; IAUDENC_Status *pStatus; /* perform the requested AUDENC operation by parsing message. */ switch (msg->visa.cmd) { case _AUDENC_CPROCESS: { /* unmarshall inBufs and outBufs since they differ in shape * from what their flattened versions passed in the message */ inBufs.bufs = msg->cmd.process.inBufs; inBufs.numBufs = msg->cmd.process.numInBufs; inBufs.bufSizes = msg->cmd.process.inBufSizes; 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; i < inBufs.numBufs; i++) { Memory_cacheInv(inBufs.bufs[i], inBufs.bufSizes[i]); } /* invalidate cache for all output buffers */ for (i = 0; i < outBufs.numBufs; i++) { Memory_cacheInv(outBufs.bufs[i], outBufs.bufSizes[i]); } } /* unmarshall outArgs based on the "size" of inArgs */ pOutArgs = (IAUDENC_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) + msg->cmd.process.inArgs.size); /* make the process call */ msg->visa.status = AUDENC_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 all output buffers */ for (i = 0; i < outBufs.numBufs; i++) { Memory_cacheWb(outBufs.bufs[i], outBufs.bufSizes[i]); } } /* * 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 _AUDENC_CCONTROL: { /* unmarshall status based on the "size" of params */ pStatus = (IAUDENC_Status *)((UInt)(&(msg->cmd.control.params)) + msg->cmd.control.params.size); msg->visa.status = AUDENC_control(handle, msg->cmd.control.id, &(msg->cmd.control.params), pStatus); break; } default: { msg->visa.status = VISA_EFAIL; break; } } return (VISA_EOK); }
/* * ======== processLoop ======== */ static Void processLoop(UNIVERSAL_Handle hUniversal, FILE *in, FILE *out) { Int n; Int32 status; UNIVERSAL_InArgs universalInArgs; UNIVERSAL_OutArgs universalOutArgs; UNIVERSAL_DynamicParams universalDynParams; UNIVERSAL_Status universalStatus; XDM1_BufDesc universalInBufDesc; XDM1_BufDesc universalOutBufDesc; /* initialize bufDescs */ universalInBufDesc.numBufs = universalOutBufDesc.numBufs = 1; universalInBufDesc.descs[0].bufSize = universalOutBufDesc.descs[0].bufSize = NSAMPLES; universalInBufDesc.descs[0].buf = inBuf; universalOutBufDesc.descs[0].buf = outBuf; /* initialize all "sized" fields */ universalInArgs.size = sizeof(universalInArgs); universalOutArgs.size = sizeof(universalOutArgs); universalDynParams.size = sizeof(universalDynParams); universalStatus.size = sizeof(universalStatus); /* if the codecs support it, dump their versions */ universalStatus.data.numBufs = 1; universalStatus.data.descs[0].buf = versionBuf; universalStatus.data.descs[0].bufSize = MAXVERSIONSIZE; universalStatus.data.descs[1].buf = NULL; status = UNIVERSAL_control(hUniversal, XDM_GETVERSION, &universalDynParams, &universalStatus); GT_1trace(curMask, GT_1CLASS, "Alg version: %s\n", (status == UNIVERSAL_EOK ? ((char *)universalStatus.data.descs[0].buf) : "[unknown]")); /* * Read complete frames from in, process them, and write to out. */ for (n = 0; fread(inBuf, IFRAMESIZE, 1, in) == 1; n++) { #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(outBuf, OFRAMESIZE); #endif GT_1trace(curMask, GT_1CLASS, "App-> Processing frame %d...\n", n); /* * Transcode the frame. * * Note, inputID == 0 is an error. This example doesn't account * for the case where 'n + 1' wraps to zero. */ status = UNIVERSAL_process(hUniversal, &universalInBufDesc, &universalOutBufDesc, NULL, &universalInArgs, &universalOutArgs); GT_2trace(curMask, GT_2CLASS, "App-> Alg frame %d process returned - 0x%x)\n", n, status); if (status != UNIVERSAL_EOK) { GT_3trace(curMask, GT_7CLASS, "App-> Alg frame %d processing FAILED, status = 0x%x, " "extendedError = 0x%x\n", n, status, universalOutArgs.extendedError); break; } #ifdef CACHE_ENABLED /* * Conditionally writeback the processed buf from the previous * call. */ if (XDM_ISACCESSMODE_WRITE(universalOutBufDesc.descs[0].accessMask)) { Memory_cacheWb(outBuf, OFRAMESIZE); } #endif /* write to file */ fwrite(outBuf, OFRAMESIZE, 1, out); } GT_1trace(curMask, GT_1CLASS, "%d frames processed\n", n); }