DvevmStRetCode dvtb_wmaEnc1Control(DvevmStWmaEnc1Info *ae) { DvevmStRetCode retCode = DVEVM_ST_SUCCESS; int status = -1, i = 0; ASSERT(ae != NULL); ASSERT(ae->aenc1Hdl != NULL); dvtb_wmacontrolenterDebug(ae); status = AUDENC1_control((AUDENC1_Handle) ae->aenc1Hdl, ae->aenc1Cmd, (IAUDENC1_DynamicParams *) &ae->aenc1DynParams, (IAUDENC1_Status *) &ae->aenc1Status); if (IAUDENC1_EOK != status) { SYS_ERROR("Audio Encode Control failed (%d)\n", status); retCode = DVEVM_ST_FAIL; } else { if (XDM_GETBUFINFO == ae->aenc1Cmd) { ae->inBuf.numBufs = ae->aenc1Status.audenc_status.bufInfo.minNumInBufs; ae->outBuf.numBufs = ae->aenc1Status.audenc_status.bufInfo.minNumOutBufs; for (i = 0; i < ae->inBuf.numBufs; i++) ae->inBuf.descs[i].bufSize = ae->aenc1Status.audenc_status.bufInfo.minInBufSize[i]; for (i = 0; i < ae->outBuf.numBufs; i++) ae->outBuf.descs[i].bufSize = ae->aenc1Status.audenc_status.bufInfo.minOutBufSize[i]; } SYS_DEBUG("Audio Encode Control => Command : %d\n", ae->aenc1Cmd); dvtb_wmacontrolexitDebug(ae); } return retCode; }
/* * ======== encode_decode ======== */ static Void encode_decode(AUDENC1_Handle enc, AUDDEC1_Handle dec, FILE *in, FILE *out) { Bool last; Int i; Int n; Int32 status; Int decProcessIn = 0; Int decWaitIn = 0; Int decProcessOut = 0; Int decWaitOut = 0; Int encProcessIn = 0; Int encProcessOut = 0; for (i = 0; i < NBUFFERS; i++) { inBufDesc[i].descs[0].buf = inBuf[i]; outBufDesc[i].descs[0].buf = outBuf[i]; encodedBufDesc[i].descs[0].buf = encodedBuf[i]; inBufDesc[i].numBufs = encodedBufDesc[i].numBufs = outBufDesc[i].numBufs = 1; inBufDesc[i].descs[0].bufSize = encodedBufDesc[i].descs[0].bufSize = outBufDesc[i].descs[0].bufSize = NSAMPLES; /* initialize all "sized" fields */ encInArgs[i].size = sizeof(encInArgs[i]); decInArgs[i].size = sizeof(decInArgs[i]); encOutArgs[i].size = sizeof(encOutArgs[i]); decOutArgs[i].size = sizeof(decOutArgs[i]); /* ancillary data to encode */ #if USE_ANCDATA encInArgs[i].ancData.buf = ancBuf[i]; encInArgs[i].ancData.bufSize = ENCANCBUFSIZE; #else /* Be sure to initialize these to NULL! */ encInArgs[i].ancData.buf = NULL; encInArgs[i].ancData.bufSize = 0; #endif } encodedBufDesc[NBUFFERS].descs[0].buf = encodedBuf[NBUFFERS]; encodedBufDesc[NBUFFERS].numBufs = 1; encodedBufDesc[NBUFFERS].descs[0].bufSize = NSAMPLES; encOutArgs[NBUFFERS].size = sizeof(encOutArgs[NBUFFERS]); decInArgs[NBUFFERS].size = sizeof(decInArgs[NBUFFERS]); 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 = 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[0].numBufs < encStatus.bufInfo.minNumInBufs) || (IFRAMESIZE < encStatus.bufInfo.minInBufSize[0]) || (encodedBufDesc[0].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[0].numBufs < decStatus.bufInfo.minNumInBufs) || (EFRAMESIZE < decStatus.bufInfo.minInBufSize[0]) || (outBufDesc[0].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[encProcessIn], IFRAMESIZE, 1, in) == 1; n++) { GT_1trace(curMask, GT_1CLASS, "App-> Processing encode frame %d...\n", n); status = encodeIssue(enc, encProcessIn, encProcessOut); if (status != AUDENC1_EOK) { goto done; } UPDATE_INDEX(encProcessIn, NBUFFERS); UPDATE_INDEX(encProcessOut, NBUFFERS + 1); if (n == 0) { /* * "Poor man's prologue" - need to feed encoder two buffers of * input before reclaiming encoded data. */ continue; } GT_1trace(curMask, GT_1CLASS, "App-> Waiting for encoded frame %d...\n", n - 1); status = encodeReclaim(enc, decProcessOut, decProcessIn); if (status != AUDENC1_EOK) { goto done; } GT_1trace(curMask, GT_1CLASS, "App-> Processing decode frame %d...\n", n - 1); status = decodeIssue(dec, decProcessIn, decProcessOut); if (status != AUDDEC1_EOK) { goto done; } UPDATE_INDEX(decProcessIn, NBUFFERS + 1); UPDATE_INDEX(decProcessOut, NBUFFERS); if (n == 1) { /* * "Poor man's prologue" - need to feed decoder two buffers of * input before reclaiming decoded data. */ continue; } GT_1trace(curMask, GT_1CLASS, "App-> Waiting for decoded frame %d...\n", n - 2); status = decodeReclaim(dec, decWaitIn, decWaitOut); if (status != AUDDEC1_EOK) { goto done; } GT_2trace(curMask, GT_1CLASS, "App-> Writing outBuf[%d]=%#x\n", decWaitOut, outBuf[decWaitOut]); /* write to file */ fwrite(outBuf[decWaitOut], OFRAMESIZE, 1, out); UPDATE_INDEX(decWaitIn, NBUFFERS + 1); UPDATE_INDEX(decWaitOut, NBUFFERS); } /* * Due to the buffering achieved with async calls, at this point we still * need to: * - drain one buffer from the encoder * - feed encoded buffer to the decoder * - drain two buffers from the decoder * - write decoded buffers to file */ GT_1trace(curMask, GT_1CLASS, "App-> Waiting for encoded frame %d...\n", n - 1); status = encodeReclaim(enc, decProcessOut, decProcessIn); if (status != AUDENC1_EOK) { goto done; } /* decode the frame */ GT_1trace(curMask, GT_1CLASS, "App-> Processing decode frame %d...\n", n - 1); status = decodeIssue(dec, decProcessIn, decProcessOut); if (status != AUDDEC1_EOK) { goto done; } UPDATE_INDEX(decProcessIn, NBUFFERS + 1); UPDATE_INDEX(decProcessOut, NBUFFERS); last = TRUE; last_frame: GT_1trace(curMask, GT_1CLASS, "App-> Waiting for decoded frame %d...\n", n - 2); status = decodeReclaim(dec, decWaitIn, decWaitOut); if (status != AUDDEC1_EOK) { goto done; } GT_2trace(curMask, GT_1CLASS, "App-> Writing outBuf[%d]=%#x\n", decWaitOut, outBuf[decWaitOut]); /* write to file */ fwrite(outBuf[decWaitOut], OFRAMESIZE, 1, out); UPDATE_INDEX(decWaitIn, NBUFFERS + 1); UPDATE_INDEX(decWaitOut, NBUFFERS); if (last) { /* * "Poor man's epilogue" - need to reclaim and write last * decoded buffer. */ n++; last = FALSE; goto last_frame; } done: GT_1trace(curMask, GT_1CLASS, "%d frames encoded/decoded\n", n - 2); }
/* * ======== 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); }
/* * ======== 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); }