/* Copyright (c) 2017, Texas Instruments Incorporated - http://www.ti.com/ All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include // for memset() #include #include #include #include #include "aspDecOpCircBuf_common.h" // Initialize circular buffer control Int cbCtlInit( PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control Int8 numDecOpCb, // number of circular buffers PAF_AST_DecOpCircBuf **pXDecOpCb // address of decoder output circular buffer base pointer ) { #ifdef _TMS320C6X GateMP_Params gateParams; GateMP_Handle gateHandle; GateMP_Params_init(&gateParams); gateParams.localProtect = GateMP_LocalProtect_THREAD; gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM; gateParams.name = ASP_DECODE_CB_GATE_NAME; gateParams.regionId = ASP_DECODE_CB_GATE_REGION_ID; gateHandle = GateMP_create(&gateParams); if (gateHandle != NULL) { pCbCtl->gateHandle = gateHandle; } else { pCbCtl->gateHandle = NULL; return ASP_DECOP_CB_CTL_INIT_INV_GATE; } pCbCtl->numDecOpCb = numDecOpCb; // init number of circular buffers pCbCtl->pXDecOpCb = pXDecOpCb; // init base address of circular buffers return ASP_DECOP_CB_SOK; #elif defined(ARMCOMPILE) GateMP_Handle gateHandle; Int status; do { status = GateMP_open(ASP_DECODE_CB_GATE_NAME, &gateHandle); } while (status == GateMP_E_NOTFOUND); if (status == GateMP_S_SUCCESS) { pCbCtl->gateHandle = gateHandle; } else { pCbCtl->gateHandle = NULL; return ASP_DECOP_CB_CTL_INIT_INV_GATE; } pCbCtl->numDecOpCb = numDecOpCb; // init number of circular buffers pCbCtl->pXDecOpCb = pXDecOpCb; // init base address of circular buffers return ASP_DECOP_CB_SOK; #else #error "Unsupported platform" #endif } // Reset circular buffer Int cbReset( PAF_AST_DecOpCircBufCtl *pCbCtl, Int8 cbIdx ) { IArg key; GateMP_Handle gateHandle; PAF_AST_DecOpCircBuf *pCb; PAF_AudioFrame *pAfCb; Int8 n; Int8 i; // Get gate handle gateHandle = pCbCtl->gateHandle; // Enter gate key = GateMP_enter(gateHandle); // Get circular buffer base pointer pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]); // Invalidate circular buffer configuration Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0); Cache_wait(); // Initialize CB primed flag pCb->primedFlag = 0; // Initialize delta samples pCb->deltaSamps = 0; // Reset circular buffer: // - AF write, read indices if (pCb->sourceSel == PAF_SOURCE_PCM) { pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM; pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM; } else if (pCb->sourceSel == PAF_SOURCE_DDP) { pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP; pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP; } else if (pCb->sourceSel == PAF_SOURCE_THD) { pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD; pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD; } else { // // Currently unsupported source select // return ASP_DECOP_CB_RESET_INV_SOURCE_SEL; } // Reset circular buffer: // - PCM read index // - Private metadata read index // - number of PCM samples in CB pCb->pcmRdIdx = 0; pCb->prvMdRdIdx = 0; pCb->numPcmSampsPerCh = 0; // initialize circular buffer current number of frames pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx; for (n=0; nmaxNumAfCb; n++) { pAfCb = &pCb->afCb[n]; // Clear PCM data for (i=0; imaxAFChanNum; i++) { memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount); pAfCb->data.samsiz[i] = 0; } // Clear metadata pAfCb->bsMetadata_type = PAF_bsMetadata_none; /* non zero if metadata is attached. */ pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */ pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */ pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */ for (i=0; ipafPrivateMetadata[i].offset = 0; pAfCb->pafPrivateMetadata[i].size = 0; } } // reset stats pCb->readAfWriterInactiveCnt = 0; pCb->readAfNdCnt = 0; pCb->wrtAfReaderInactiveCnt = 0; pCb->wrtAfZeroSampsCnt = 0; pCb->errAfUndCnt = 0; pCb->errAfOvrCnt = 0; pCb->errPcmUndCnt = 0; pCb->errPcmOvrCnt = 0; // Write back circular buffer configuration Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0); // Write back AF circular buffer Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0); for (n=0; nmaxNumAfCb; n++) { pAfCb = &pCb->afCb[n]; for (i=0; imaxAFChanNum; i++) { Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0); } } Cache_wait(); // Leave the gate GateMP_leave(gateHandle, key); return ASP_DECOP_CB_SOK; } // Get circular buffer statistics Int cbGetStats( PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control Int8 cbIdx, // decoder output circular buffer index PAF_AST_DecOpCircBufStats *pCbStats // decoder output circular buffer statistics ) { IArg key; GateMP_Handle gateHandle; PAF_AST_DecOpCircBuf *pCb; // Get gate handle gateHandle = pCbCtl->gateHandle; // Enter gate key = GateMP_enter(gateHandle); // Get circular buffer base pointer pCb = &(*pCbCtl->pXDecOpCb)[cbIdx]; // Invalidate circular buffer configuration. Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0); Cache_wait(); // Populate statistics pCbStats->readAfWriterInactiveCnt = pCb->readAfWriterInactiveCnt; pCbStats->readAfNdCnt = pCb->readAfNdCnt; pCbStats->wrtAfReaderInactiveCnt = pCb->wrtAfReaderInactiveCnt; pCbStats->wrtAfZeroSampsCnt = pCb->wrtAfZeroSampsCnt; pCbStats->errAfUndCnt = pCb->errAfUndCnt; pCbStats->errAfOvrCnt = pCb->errAfOvrCnt; pCbStats->errPcmUndCnt = pCb->errPcmUndCnt; pCbStats->errPcmOvrCnt = pCb->errPcmOvrCnt; // Leave the gate GateMP_leave(gateHandle, key); return ASP_DECOP_CB_SOK; } // Output log of circular buffer control variables (debug) Int cbLog( PAF_AST_DecOpCircBufCtl *pCbCtl, Int8 cbIdx, Int8 fullLog, char *locInfo ) { IArg key; GateMP_Handle gateHandle; PAF_AST_DecOpCircBuf *pCb; // Get gate handle gateHandle = pCbCtl->gateHandle; // Enter gate key = GateMP_enter(gateHandle); // Get circular buffer base pointer pCb = &(*pCbCtl->pXDecOpCb)[cbIdx]; // Invalidate circular buffer configuration. Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0); Cache_wait(); Log_info1("CB: %s", (IArg)locInfo); Log_info3("CB: readerActiveFlag=%d, writerActiveFlag=%d, drainFlag=%d", pCb->readerActiveFlag, pCb->writerActiveFlag, pCb->drainFlag); Log_info5("CB: afRdIdx=%d, pcmRdIdx=%d, prvMdRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx, pCb->prvMdRdIdx, pCb->afWrtIdx, pCb->numAfCb); if (fullLog) { Log_info1("CB: maxNumAfCb=%d", pCb->maxNumAfCb); Log_info2("CB: decOpFrameLen=%d, strFrameLen=%d", pCb->decOpFrameLen, pCb->strFrameLen); //Log_info1("cbWriteInit=%d", pCb->cbWriteAfInit); } // Leave the gate GateMP_leave(gateHandle, key); return ASP_DECOP_CB_SOK; }