/* Copyright (c) 2016, 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. * */ /* * ======== audioStreamInpDec.c ======== */ #include #include #include "procsdk_audio_typ.h" #include "audioStreamInpProc.h" #include "audioStreamProc_common.h" #include "aspMsg_common.h" #include "aspMsg_master.h" #include "asperr.h" #include "common.h" #include "as1-f2.h" #include "ioConfig.h" //TODO: remove this header #include "ioBuff.h" #include "ioPhy.h" #include "ioData.h" extern void asitPostInfoEvent(); // TODO: remove extern void asitPostDecEvent(); // TODO: remove enum { DEC_STATE_INFO_SND, DEC_STATE_INFO_ACK_DECODE_SND, DEC_STATE_DECODE_ACK, DEC_STATE_QUIT }; static Int decodeInit(const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg, Int sourceSelect); static Int decDecodeComplete(const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg); static Int decErrorCheck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg, Int sourceSelect); static Int decInfoSnd(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg); static Int decInfoAck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg); static Int decDecodeAck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg); static Int decDecodeSnd(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg); static Int decDecodeFinalTest(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg); Int decCheckMajorAu(PAF_AST_Config *pAstCfg); Int AspMsgSnd(UInt32 sndCmd, char *sndMsgBuf); Int AspMsgAck(UInt32 ackCmd, char *ackMsgBuf); extern UInt32 gCbWrtAfErrCnt; Int decDecodeInit( const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg, Int sourceSelect) { Int errno; errno = decodeInit(pP, pAsitCfg, sourceSelect); if(errno) { decDecodeComplete(pP, pAsitCfg); return ASIP_ERR_DECODE_INIT; } pAsitCfg->inpDec.majorAuFound = FALSE; return ASIP_NO_ERR; } // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- Int decDecodeFsm( const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg, Int sourceSelect, UInt decMsg) { asipDecProc_t *pDec; Int decErr, decDone; pDec = &pAsitCfg->inpDec; TRACE_VERBOSE1("Entering decDecodeFsm with decMsg %d.", decMsg); decErr = decErrorCheck(pP, pQ, pAsitCfg, sourceSelect); if(decErr == DEC_ERR_ASPERR_ABORT) { return decErr; } else if(decErr != DEC_NO_ERR) { pDec->state = DEC_STATE_QUIT; } else { ; // No error } // It is possible to go through the FSM multiple times: // - Multiple messages may be received, INPDATA and DECACK. In this case, // the FSM will process DECACK in state DEC_STATE_DECODE_ACK and then // INPDATA in state DEC_STATE_INFO_SND. // - DECACK is received after INPDATA. In this case, after DECACK is // processed, we will spoof decMsg with INPDATA so that FSM will run // again and process INPDATA in DEC_STATE_INFO_SND. do { switch(pDec->state) { case DEC_STATE_INFO_SND: if(decMsg != DEC_MSGMSK_INPDATA) { // Only DEC_MSGMSK_INPDATA is expected in this state decErr = DEC_ERR_WRONG_MSG; } else { decMsg &= ~DEC_MSGMSK_INPDATA; // clear bit mask // Prepare and send INFO to decoder decErr = decInfoSnd(pP, pQ, pAsitCfg); if(decErr == DEC_NO_ERR) { pDec->state = DEC_STATE_INFO_ACK_DECODE_SND; TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_INFO_SND done."); } } break; case DEC_STATE_INFO_ACK_DECODE_SND: //if(decMsg != DEC_MSGMSK_INFOACK) { // only DEC_MSGMSK_INFOACK is expected in this state if((decMsg&DEC_MSGMSK_INFOACK) != DEC_MSGMSK_INFOACK) { // During debugging, it is possible that INPDATA and INFOACK // come at the same time (e.g. due to breaking point). decErr = DEC_ERR_WRONG_MSG; } else { decMsg &= ~DEC_MSGMSK_INFOACK; // clear the bit mask // Process the INFO acknowledgment from decoder decErr = decInfoAck(pP, pQ, pAsitCfg); if(decErr == DEC_NO_ERR) { // Don't start decode until major access unit is found. if(!pDec->majorAuFound) { // Do we want to still check major AU after it is found? // In old code, it was not checked again after it was found. pDec->majorAuFound = decCheckMajorAu(pAsitCfg->pAstCfg); } if(pDec->majorAuFound) { // Major access unit is found. Send message to decoder to decode now. decErr = decDecodeSnd(pP, pQ, pAsitCfg); if(decErr == DEC_NO_ERR) { pDec->state = DEC_STATE_DECODE_ACK; // Initialize decodeAckDelayed to FALSE - normally // DECODE ACK comes after INPDATA. pDec->decodeAckDelayed = FALSE; TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_INFO_ACK_DECODE_SND done and going to DEC_STATE_DECODE_ACK."); } } else { // No major access unit - go back to INFO. pDec->frame++; pDec->state = DEC_STATE_INFO_SND; TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_INFO_ACK_DECODE_SND done and going to DEC_STATE_INFO_SND."); } } } break; case DEC_STATE_DECODE_ACK: // Two different messages may be received: DECACK (decode acknowledgment) // or INPDATA (input data ready). if(decMsg & DEC_MSGMSK_DECACK) { decMsg &= ~DEC_MSGMSK_DECACK; // Process DECODE ACK from decoder decErr = decDecodeAck(pP, pQ, pAsitCfg); if(decErr == DEC_NO_ERR) { // Decode finishes. Conduct final test. decErr = decDecodeFinalTest(pP, pQ, pAsitCfg); if(decErr == DEC_NO_ERR) { pDec->frame++; pDec->state = DEC_STATE_INFO_SND; TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_DECODE_ACK done and going to DEC_STATE_INFO_SND."); // Check if DECACK comes late (after INPDATA) if(pDec->decodeAckDelayed) { pDec->decodeAckDelayed = FALSE; // Need to prepare and send INFO to decoder immediately. // Becuase INPUT_DATA message is already received, // we're just spoofing the message with INPDATA to // run the FSM one more time. decMsg |= DEC_MSGMSK_INPDATA; TRACE_VERBOSE0("decDecodeFsm: Info was delayed."); } } } } else if(decMsg & DEC_MSGMSK_INPDATA) { // If we're here, it means decode acknowledgment from decoder // is delayed, i.e., a new frame of input data is ready before // current frame decoding is finished. decMsg &= ~DEC_MSGMSK_INPDATA; // Do nothing but set a flag to postpone action. pDec->decodeAckDelayed = TRUE; TRACE_VERBOSE0("decDecodeFsm: receiving INPDATA in DEC_STATE_DECODE_ACK"); } else { decErr = DEC_ERR_WRONG_MSG; } break; case DEC_STATE_QUIT: //gAsipQuitCnt++; TRACE_VERBOSE0("decDecodeFsm: state: DEC_STATE_QUIT"); break; default: break; } /* switch */ // Loop through the FSM one more time if: // - there are more real or spoofed messages to process, // - and there is no error. if((decMsg==0) || (decErr!=DEC_NO_ERR)) { decDone = TRUE; } else { decDone = FALSE; } } while(!decDone); // Error handling - complete decoding if(decErr != DEC_NO_ERR) { TRACE_VERBOSE1("decDecodeFsm: decErr %d, calling decDecodeComplete.", decErr); decDecodeComplete(pP, pAsitCfg); TRACE_VERBOSE0("decDecodeFsm: decDecodeComplete done."); } return decErr; } /* decDecodeFsm */ Int decErrorCheck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg, Int sourceSelect ) { Int retVal, getVal, zMD; Int8 sourceConfig; retVal = DEC_NO_ERR; // Check if source has configured to NONE zMD = pAsitCfg->pAstCfg->masterDec; sourceConfig = sharedMemReadInt8(&(pAsitCfg->pAstCfg->xDec[zMD].decodeStatus.sourceSelect), GATEMP_INDEX_DEC); if (sourceConfig == PAF_SOURCE_NONE || sourceSelect == PAF_SOURCE_NONE) { TRACE_VERBOSE0("decDecodeFsm: sourceSelect == PAF_SOURCE_NONE"); retVal = DEC_ERR_SOURCE_NONE; } // Process commands (decode) getVal = pP->fxns->decodeCommand(pP, pQ, pAsitCfg); if (getVal == ASPERR_QUIT) { TRACE_VERBOSE0("decDecodeFsm. %d: state = QUIT"); retVal = DEC_ERR_ASPERR_QUIT; } else if (getVal == ASPERR_ABORT) { TRACE_VERBOSE0("decDecodeFsm. %d: return getVal"); // Return here if ASPERR_ABORT retVal = DEC_ERR_ASPERR_ABORT; } else { ; // No error } return retVal; } /* decErrorCheck */ Int decCheckMajorAu(PAF_AST_Config *pAstCfg) { Int8 sourceDecode, sampleRate; Int zMD; zMD = pAstCfg->masterDec; sourceDecode = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode), GATEMP_INDEX_DEC); sampleRate = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sampleRate), GATEMP_INDEX_DEC); if ( ( (sourceDecode == PAF_SOURCE_THD) || (sourceDecode == PAF_SOURCE_DXP) || (sourceDecode == PAF_SOURCE_DTSHD) ) &&( sampleRate == PAF_SAMPLERATE_UNKNOWN) ) { return FALSE; } else { return TRUE; } } /* decCheckMajorAu*/ // ----------------------------------------------------------------------------- // ASIT Decoding Function - Reinitialization of Decode // // Name: decDecodeInit // Purpose: Decoding Function for reinitializing the decoding process. // From: AST Parameter Function -> decodeProcessing // Uses: See code. // States: x // Return: Error number in standard or SIO form (0 on success). // Trace: Message Log "trace" in Debug Project Configuration reports: // * State information as per parent. // // ----------------------------------------------------------------------------- static Int decodeInit( const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg, Int sourceSelect) { PAF_AST_Config *pAstCfg; PAF_AST_IoInp *pInp; //PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */ Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* decode/encode counter */ Int errno; /* error number */ Int zI, zS; Int argIdx; Int8 tempVar8; char decMsgBuf[ASP_MSG_BUF_LEN]; pAstCfg = pAsitCfg->pAstCfg; // get pointer to AST common (shared) configuration pInp = pAsitCfg->pIoInp; as = pAstCfg->as; (void)as; // clear compiler warning in case not used with tracing disabled //pCbCtl = &pAsitCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control // reset frameCount for (z=DECODE1; z < DECODEN; z++) { tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.mode), GATEMP_INDEX_DEC); if (tempVar8) { sharedMemWriteInt(&(pAstCfg->xDec[z].decodeStatus.frameCount), (Int)0, GATEMP_INDEX_DEC); } } // loop through all supported inputs for (z=DECODE1; z < DECODEN; z++) { zI = pP->inputsFromDecodes[z]; zS = pP->streamsFromDecodes[z]; (void)zS; // clear compiler warning in case not used with tracing disabled tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.mode), GATEMP_INDEX_DEC); if (pInp[zI].hIoPhy && tempVar8) { Uns gear; TRACE_VERBOSE1("AS%d: PAF_ASIT_decodeInit: initializing decode", as+zS); // write back Dec configuration Cache_wb(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0); Cache_wait(); // send dec activate message to slave argIdx = 0; // set decIdx (zone index) *(Int32 *)&decMsgBuf[argIdx] = z; if(AspMsgSend(ASP_SLAVE_DEC_ACTIVATE, ASP_MASTER_DEC_ACTIVATE_DONE, decMsgBuf, NULL) != ASP_MSG_NO_ERR) { TRACE_TERSE0("decodeInit: error in sending DEC_ACTIVATE message "); SW_BREAKPOINT; // temporary return ASIP_ERR_DECODE_MSG; // temporary } // send dec reset message to slave argIdx = 0; // set decIdx *(Int32 *)&decMsgBuf[argIdx] = z; if(AspMsgSend(ASP_SLAVE_DEC_RESET, ASP_MASTER_DEC_RESET_DONE, decMsgBuf, decMsgBuf) != ASP_MSG_NO_ERR) { TRACE_TERSE0("decodeInit: error in sending DEC_RESET message "); SW_BREAKPOINT; // temporary return ASIP_ERR_DECODE_MSG; // temporary } else { argIdx = 0; // get decErrno errno = *(Int32 *)&decMsgBuf[argIdx]; } // invalidate Dec configuration Cache_inv(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0); Cache_wait(); if (errno != 0) { return ASIP_ERR_DECODE_MSG; } gear = (Uns)sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.aspGearControl), GATEMP_INDEX_DEC); tempVar8 = gear < GEARS ? gear : 0; sharedMemWriteInt8(&(pAstCfg->xDec[z].decodeStatus.aspGearStatus), tempVar8, GATEMP_INDEX_DEC); // Compute decoder frame length based on source selection // JXU: what does this function do? why does it only return PCM frame length? /*frameLength = getFrameLengthSourceSel(pP, sourceSelect); pAstCfg->xDec[z].decodeControl.frameLength = frameLength; pAstCfg->xDec[z].decodeInStruct.sampleCount = frameLength; pAstCfg->xDec[z].decodeControl.sampleRate = PAF_SAMPLERATE_UNKNOWN;*/ /* if (z != zMD) { // JXTODO: implement similar thing with new I/O if (errno = SIO_idle(pAstCfg->xInp[zI].hRxSio)) { return errno; } } */ /*//JXTODO: find out if frameLength needs to be passed to I/O DATA or I/O PHY. ioDataCtl.code = IODATA_CTL_SET_PCM_FRAME_LENGTH; ioDataCtl.param.frameLengthPcm = frameLength; ioDataControl(pInp[zI].hIoData, &ioDataCtl); */ //JXTODO: do we need to update input status here again? if (errno = asitUpdateInputStatus(pInp[zI].pRxParams, &pAstCfg->xInp[zI].inpBufStatus, &pAstCfg->xInp[zI].inpBufConfig)) { return ASIP_ERR_INPUT_CFG; } } /* end of if(hIoPhy && decodeStatus.mode) */ } /* end of for (z=DECODE1; z < DECODEN; z++) */ pAsitCfg->inpDec.frame = 0; pAsitCfg->inpDec.block = 0; pAsitCfg->inpDec.state = DEC_STATE_INFO_SND; return ASIP_NO_ERR; } /* decDecodeInit */ Int decDecodeComplete( const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* decode/encode counter */ Int argIdx; Int8 tempVar8; char decMsgBuf[ASP_MSG_BUF_LEN]; pAstCfg = pAsitCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; (void)as; // clear compiler warning in case not used with tracing disabled for (z=DECODE1; z < DECODEN; z++) { tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.mode), GATEMP_INDEX_DEC); if (pAsitCfg->pIoInp[z].hIoPhy && tempVar8) { TRACE_VERBOSE1("decDecodeComplete: AS%d: finalizing decode", as+z); // FL: send dec deactivate message to slave argIdx = 0; // set decIdx *(Int32 *)&decMsgBuf[argIdx] = z; if(AspMsgSend(ASP_SLAVE_DEC_DEACTIVATE, ASP_MASTER_DEC_DEACTIVATE_DONE, decMsgBuf, NULL) != ASP_MSG_NO_ERR) { TRACE_TERSE0("decodeComplete: error in sending DEC_DEACTIVATE message."); SW_BREAKPOINT; return DEC_ERR_COMPLETE_MSG; } } else { TRACE_VERBOSE1("decDecodeComplete: AS%d: processing decode ", as+z); } } return DEC_NO_ERR; } /* decDecodeComplete */ // ----------------------------------------------------------------------------- // Decoding Function - Frame-Final Processing // // Name: decDecodeFinalTest // Purpose: Decoding Function for determining whether processing of the // current frame is complete. // From: AST Parameter Function -> decodeProcessing // Uses: See code. // States: x // Return: 0 if incomplete, and 1 if complete. // Trace: None. // Int decDecodeFinalTest( const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg ) { PAF_AST_Config *pAstCfg; Int zMD; Int sourceSelect; Int sourceProgram; Int8 tempVar8, temp2Var8; pAstCfg = pAsitCfg->pAstCfg; // get pointer to AST common (shared) configuration zMD = pAstCfg->masterDec; sourceSelect = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect), GATEMP_INDEX_DEC); sourceProgram = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram), GATEMP_INDEX_DEC); if ((sourceSelect == PAF_SOURCE_NONE) || (sourceSelect == PAF_SOURCE_PASS)) { return DEC_ERR_DECODE_FINAL; } // The following allows for Force modes to switch without command deferral. This might // be better suited for inclusion in DIB_requestFrame, but for now will reside here. if ((sourceSelect == PAF_SOURCE_SNG) || (sourceSelect > PAF_SOURCE_BITSTREAM)) { if (sourceSelect == PAF_SOURCE_DTSALL) { if (sourceProgram != PAF_SOURCE_DTS11 && sourceProgram != PAF_SOURCE_DTS12 && sourceProgram != PAF_SOURCE_DTS13 && sourceProgram != PAF_SOURCE_DTS14 && sourceProgram != PAF_SOURCE_DTS16 && sourceProgram != PAF_SOURCE_DTSHD) { return DEC_ERR_DECODE_FINAL; } } else if (sourceSelect == PAF_SOURCE_PCMAUTO) { if (sourceProgram != PAF_SOURCE_PCM) { return DEC_ERR_DECODE_FINAL; } } else { tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode), GATEMP_INDEX_DEC); temp2Var8 = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect), GATEMP_INDEX_DEC); if (temp2Var8 != tempVar8) { return DEC_ERR_DECODE_FINAL; } } } return DEC_NO_ERR; } //decDecodeFinalTest Int decInfoSnd( const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg ) { PAF_AST_Config *pAstCfg; PAF_AST_IoInp *pInp; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* input/decode/stream counter */ Int errno; /* error number */ Int zD, zI, zS, zX; Int argIdx; Int8 tempVar8; char decMsgBuf[ASP_MSG_BUF_LEN]; pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration pInp = pAsitCfg->pIoInp; as = pAstCfg->as; // Set decode control: sample rate, emphasis for (z=INPUT1; z < INPUTN; z++) { zD = z; for (zX = DECODE1; zX < DECODEN; zX++) { if (pP->inputsFromDecodes[zX] == z) { zD = zX; break; } } if (pInp[z].hIoPhy) { //determine associated decoder if (pAstCfg->xInp[z].inpBufStatus.sampleRateStatus != pAstCfg->xDec[zD].decodeControl.sampleRate) { if (pAstCfg->xDec[zD].decodeControl.sampleRate == PAF_SAMPLERATE_UNKNOWN) { pAstCfg->xDec[zD].decodeControl.sampleRate = pAstCfg->xInp[z].inpBufStatus.sampleRateStatus; } else { //TRACE_TERSE1("decDecodeInfo: AS%d: return error ASPERR_INFO_RATECHANGE", as+pAstCfg->masterStr); TRACE_TERSE2("inpBufStatus.sampleRateStatus: 0x%x, decodeControl.sampleRate: 0x%x", pAstCfg->xInp[z].inpBufStatus.sampleRateStatus, pAstCfg->xDec[zD].decodeControl.sampleRate); // return (ASPERR_INFO_RATECHANGE); } } tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[zD].decodeStatus.sourceDecode), GATEMP_INDEX_DEC); pAstCfg->xDec[zD].decodeControl.emphasis = tempVar8 != PAF_SOURCE_PCM ? PAF_IEC_PREEMPHASIS_NO // fix for Mantis ID #119 : pAstCfg->xInp[z].inpBufStatus.emphasisStatus; } else { pAstCfg->xDec[zD].decodeControl.sampleRate = PAF_SAMPLERATE_UNKNOWN; pAstCfg->xDec[zD].decodeControl.emphasis = PAF_IEC_PREEMPHASIS_UNKNOWN; } } /* end of for (z=INPUT1; z < INPUTN; z++) */ // Decode info for (z=DECODE1; z < DECODEN; z++) { zI = pP->inputsFromDecodes[z]; zS = pP->streamsFromDecodes[z]; (void)zS; // clear compiler warning in case not used with tracing disabled tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.mode), GATEMP_INDEX_DEC); if (pInp[zI].hIoPhy && tempVar8) { TRACE_GEN2("PAF_ASIT_decodeInfo: AS%d: processing frame %d -- info", as+zS, pAsitCfg->inpDec.frame); if (errno = asitUpdateInputStatus(pInp[zI].pRxParams, &pAstCfg->xInp[zI].inpBufStatus, &pAstCfg->xInp[zI].inpBufConfig)) { TRACE_TERSE1("asitUpdateInputStatus return error errno 0x%x.", errno); return DEC_ERR_INFO_SNDMSG; } #if 0 // debug // capture input buffer capIb(pAstCfg->xInp[zI].pInpBuf); gCapIb_cnt++; #endif // write back Inp configuration Cache_wb(&pAstCfg->xInp[zI], sizeof(PAF_AST_InpBuf), Cache_Type_ALLD, 0); // write back Dec configuration Cache_wb(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0); Cache_wait(); // send info message to slave argIdx = 0; // set decIdx *(Int32 *)&decMsgBuf[argIdx] = z; if(AspMsgSnd(ASP_SLAVE_DEC_INFO, decMsgBuf) != ASP_MSG_NO_ERR) { TRACE_TERSE0("decodeInfo: error in sending DEC_INFO message "); SW_BREAKPOINT; // temporary return -1; // temporary } /* else { argIdx = 0; // get decErrno errno = *(Int32 *)&decMsgBuf[argIdx]; } if (errno) { TRACE_TERSE1("decInfoSndMSg return error errno 0x%x.", errno); return DEC_ERR_INFO_SNDMSG; } */ } } // z=DECODE1 to DECODEN ////////////////////////////////////////////////////////////////////////////// asitPostInfoEvent(); ////////////////////////////////////////////////////////////////////////////// return ASIP_NO_ERR; } /* decInfoSnd() */ Int decInfoAck( const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg ) { PAF_AST_Config *pAstCfg; PAF_AST_IoInp *pInp; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* input/decode/stream counter */ Int errno; /* error number */ Int zI, zS; Int zMD; Int zMS; Int argIdx; Int8 tempVar8; Int tempVar; char decMsgBuf[ASP_MSG_BUF_LEN]; pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration pInp = pAsitCfg->pIoInp; as = pAstCfg->as; zMD = pAstCfg->masterDec; zMS = pAstCfg->masterStr; (void)zMS; (void)as; // clear compiler warning in case not used with tracing disabled // Decode info for (z=DECODE1; z < DECODEN; z++) { zI = pP->inputsFromDecodes[z]; zS = pP->streamsFromDecodes[z]; (void)zS; // clear compiler warning in case not used with tracing disabled tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.mode), GATEMP_INDEX_DEC); if (pInp[zI].hIoPhy && tempVar8) { // FL: acknowledge info message from slave argIdx = 0; // set decIdx *(Int32 *)&decMsgBuf[argIdx] = z; if(AspMsgAck(ASP_MASTER_DEC_INFO_DONE, decMsgBuf) != ASP_MSG_NO_ERR) { TRACE_TERSE0("decodeInfo: error in receiving DEC_INFO message "); SW_BREAKPOINT; // temporary return -1; // temporary } else { argIdx = 0; // get decErrno errno = *(Int32 *)&decMsgBuf[argIdx]; } // invalidate Dec configuration Cache_inv(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0); Cache_wait(); if (errno) { TRACE_TERSE1("decInfoAck return error errno 0x%x.", errno); return DEC_ERR_INFO_ACKMSG; } // increment decoded frame count tempVar = sharedMemReadInt(&(pAstCfg->xDec[z].decodeStatus.frameCount), GATEMP_INDEX_DEC); tempVar += 1; sharedMemWriteInt(&(pAstCfg->xDec[z].decodeStatus.frameCount), tempVar, GATEMP_INDEX_DEC); } } // z=DECODE1 to DECODEN // query IB for latest sourceProgram (needed if we started decoding due to a force mode) tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.mode), GATEMP_INDEX_DEC); if (tempVar8) { sharedMemWriteInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram), pInp[zMD].sourceProgram, GATEMP_INDEX_DEC); } // since now decoding update decode status for all enabled decoders for (z=DECODE1; z < DECODEN; z++) { tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.mode), GATEMP_INDEX_DEC); if (tempVar8) { tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.sourceProgram), GATEMP_INDEX_DEC); sharedMemWriteInt8(&(pAstCfg->xDec[z].decodeStatus.sourceDecode), tempVar8, GATEMP_INDEX_DEC); tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.sourceSelect), GATEMP_INDEX_DEC); if (tempVar8 == PAF_SOURCE_SNG) { tempVar8 = PAF_SOURCE_SNG; sharedMemWriteInt8(&(pAstCfg->xDec[z].decodeStatus.sourceDecode), tempVar8, GATEMP_INDEX_DEC); } } } return ASIP_NO_ERR; } static Int decDecodeSnd(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg) { PAF_AST_Config *pAstCfg; PAF_AST_IoInp *pInp; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* decode/stream counter */ Int argIdx; Int cbErrno, errno; char decMsgBuf[ASP_MSG_BUF_LEN]; pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration pInp = pAsitCfg->pIoInp; as = pAstCfg->as; (void)as; // clear compiler warning in case not used with tracing disabled // Decode data for (z=DECODE1; z < DECODEN; z++) { Int zI = pP->inputsFromDecodes[z]; Int zS = pP->streamsFromDecodes[z]; (void)zS; // clear compiler warning in case not used with tracing disabled if ( pInp[zI].hIoPhy && pAstCfg->xDec[z].decodeStatus.mode ) { TRACE_GEN2("PAF_ASIT_decodeDecode: AS%d: decodeDecode: processing block %d -- decode", as+zS, pAsitCfg->inpDec.block); TRACE_VERBOSE3("PAF_ASIT_decodeDecode: AS%d: decodeDecode: decoding from 0x%x (base) 0x%x (ptr)", as+zS, (IArg)pAstCfg->xInp[z].pInpBuf->base.pVoid, (IArg)pAstCfg->xInp[z].pInpBuf->head.pVoid); #if 0 // debug // capture input buffer capIbPcm(pAstCfg->xInp[z].pInpBuf); #endif // write back Dec configuration Cache_wb(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0); Cache_wait(); // send decode message to slave errno = 0; argIdx = 0; // set decIdx *(Int32 *)&decMsgBuf[argIdx] = z; if(AspMsgSnd(ASP_SLAVE_DEC_DECODE, decMsgBuf) != ASP_MSG_NO_ERR) { TRACE_TERSE0("decodeDecode: error in sending DEC_DECODE message "); SW_BREAKPOINT; // temporary return -1; // temporary } /* else { argIdx = 0; // get decErrno errno = *(Int32 *)&decMsgBuf[argIdx]; argIdx += sizeof(Int32); // get cbErrno cbErrno = *(Int32 *)&decMsgBuf[argIdx]; if (cbErrno != 0) { gCbWrtAfErrCnt++; TRACE_TERSE1("CB write error=%d", cbErrno); //SW_BREAKPOINT; // temporary } if(errno) { TRACE_TERSE1("decDecodeSnd return error errno 0x%x.", errno); return DEC_ERR_DECODE_SNDMSG; } }*/ } // hIoPhy && decodeStatus.mode else { TRACE_VERBOSE2("AS%d: PAF_ASIT_decodeDecode: processing block %d -- decode ", as+zS, pAsitCfg->inpDec.block); } } // z=DECODE1 to DECODEN ////////////////////////////////////////////////////////////////////////////// asitPostDecEvent(); ////////////////////////////////////////////////////////////////////////////// return ASIP_NO_ERR; } /* decDecodeSnd() */ static Int decDecodeAck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg) { PAF_AST_Config *pAstCfg; PAF_AST_IoInp *pInp; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* decode/stream counter */ Int errno; /* error number */ Int argIdx; Int cbErrno; char decMsgBuf[ASP_MSG_BUF_LEN]; pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration pInp = pAsitCfg->pIoInp; as = pAstCfg->as; (void)as; // clear compiler warning in case not used with tracing disabled // Decode data for (z=DECODE1; z < DECODEN; z++) { Int zI = pP->inputsFromDecodes[z]; Int zS = pP->streamsFromDecodes[z]; (void)zS; // clear compiler warning in case not used with tracing disabled if ( pInp[zI].hIoPhy && pAstCfg->xDec[z].decodeStatus.mode ) { // FL: send decode message to slave errno = 0; argIdx = 0; // set decIdx *(Int32 *)&decMsgBuf[argIdx] = z; errno = AspMsgAck(ASP_MASTER_DEC_DECODE_DONE, decMsgBuf); if(errno != ASP_MSG_NO_ERR) { TRACE_TERSE0("decodeDecode: error in sending DEC_DECODE message "); SW_BREAKPOINT; // temporary return -1; // temporary } else { argIdx = 0; // get decErrno errno = *(Int32 *)&decMsgBuf[argIdx]; argIdx += sizeof(Int32); // get cbErrno cbErrno = *(Int32 *)&decMsgBuf[argIdx]; if (cbErrno != 0) { gCbWrtAfErrCnt++; TRACE_TERSE1("CB write error=%d", cbErrno); //SW_BREAKPOINT; // temporary } } // invalidate Dec configuration Cache_inv(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0); Cache_wait(); if(errno) { TRACE_TERSE1("decDecodeAck return error errno 0x%x.", errno); return DEC_ERR_DECODE_ACKMSG; } #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA) as_traceChannels(pAsitCfg, z); #endif } // hIoPhy && decodeStatus.mode else { TRACE_VERBOSE2("AS%d: PAF_ASIT_decodeDecode: processing block %d -- decode ", as+zS, pAsitCfg->inpDec.block); } } // z=DECODE1 to DECODEN return ASIP_NO_ERR; } /* decDecodeAck */ /************************************************************************************ * ASP message sending function. Refer to aspMsg_master.h for detailed description. ************************************************************************************/ Int AspMsgSnd(UInt32 sndCmd, char *sndMsgBuf) { ASP_Msg* pAspMsg; /* Messaging */ Int status; // allocate message pAspMsg = (ASP_Msg *)MessageQ_alloc(hAspMsgMaster->heapId, hAspMsgMaster->msgSize); if (pAspMsg == NULL) { TRACE_TERSE0("MessageQ_alloc() failure."); return (ASP_MSG_ERR_QUEUE_ALLOC); } // set the return address in the message header and fill in message payload MessageQ_setReplyQueue(hAspMsgMaster->masterQue, (MessageQ_Msg)pAspMsg); pAspMsg->cmd = sndCmd; pAspMsg->procId = hAspMsgMaster->masterProcId; pAspMsg->messageId = hAspMsgMaster->messageId & ~(1<<31); pAspMsg->expectResp = TRUE; // copy the message provided by caller if(sndMsgBuf != NULL) { memcpy(pAspMsg->buf, sndMsgBuf, ASP_MSG_BUF_LEN*sizeof(char)); } // send the message TRACE_TERSE3("ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId); status = MessageQ_put(hAspMsgMaster->slaveQue, (MessageQ_Msg)pAspMsg); if (status != MessageQ_S_SUCCESS) { TRACE_TERSE0("MessageQ_put() failure."); MessageQ_free((MessageQ_Msg)pAspMsg); return (ASP_MSG_ERR_QUEUE_PUT); } status = MessageQ_free((MessageQ_Msg)pAspMsg); if (status != MessageQ_S_SUCCESS) { TRACE_TERSE0("MessageQ_free() failure."); return (ASP_MSG_ERR_QUEUE_FREE); } // No error in messaging operation, even though there // may be error in returned (acknowledgement) message. return (ASP_MSG_NO_ERR); } /* AspMsgSnd */ /************************************************************************************ * ASP message sending function. Refer to aspMsg_master.h for detailed description. ************************************************************************************/ Int AspMsgAck(UInt32 ackCmd, char *ackMsgBuf) { ASP_Msg* pAspMsg; /* Messaging */ Int status; // allocate message pAspMsg = (ASP_Msg *)MessageQ_alloc(hAspMsgMaster->heapId, hAspMsgMaster->msgSize); if (pAspMsg == NULL) { TRACE_TERSE0("MessageQ_alloc() failure."); return (ASP_MSG_ERR_QUEUE_ALLOC); } // wait for complete message from slave status = MessageQ_get(hAspMsgMaster->masterQue, (MessageQ_Msg *)&pAspMsg, MessageQ_FOREVER); if (status != MessageQ_S_SUCCESS) { TRACE_TERSE0("MessageQ_get() failure."); MessageQ_free((MessageQ_Msg)pAspMsg); return (ASP_MSG_ERR_QUEUE_GET); } // check if returned message is valid if ((pAspMsg->procId != hAspMsgMaster->slaveProcId) || (pAspMsg->cmd != ackCmd) || (pAspMsg->messageId != (hAspMsgMaster->messageId | ((UInt32)1<<31)))) { TRACE_TERSE3("ERROR: ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId); MessageQ_free((MessageQ_Msg)pAspMsg); return(ASP_MSG_ERR_ACKNOWLEDGE); } hAspMsgMaster->messageId = (hAspMsgMaster->messageId + 1) & ~(1<<31); TRACE_TERSE3("ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId); // get the returned message if(ackMsgBuf != NULL) { memcpy(ackMsgBuf, pAspMsg->buf, ASP_MSG_BUF_LEN*sizeof(char)); } // free the message status = MessageQ_free((MessageQ_Msg)pAspMsg); if (status != MessageQ_S_SUCCESS) { TRACE_TERSE0("MessageQ_free() failure."); return (ASP_MSG_ERR_QUEUE_FREE); } // No error in messaging operation, even though there // may be error in returned (acknowledgement) message. return (ASP_MSG_NO_ERR); } /* AspMsgAck */ #if 0 Int asipDecodeProcessing( const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pC, Int sourceSelect) { PAF_AST_Config *pAstCfg; Int errno, retVal; /* error number */ Int zMD; pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration zMD = pAstCfg->masterDec; retVal = ASIP_NO_ERR; //pAstCfg->xInp[0].inpBufStatus.sampleRateStatus = PAF_SAMPLERATE_192000HZ; //JXTODO: make this correct errno = decDecodeInfo(pP, pQ, pC); if (errno != ASIP_NO_ERR) { //gAsipInfo1_PrimaryErrCnt++; TRACE_TERSE1("INFO1: errno 0x%x after decodeInfo, primary timing", errno); retVal = ASIP_ERR_DECODE_INFO; } else { // Don't start decode until major access unit is found. Int8 sourceDecode, sampleRate; sourceDecode = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode), GATEMP_INDEX_DEC); sampleRate = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sampleRate), GATEMP_INDEX_DEC); if ( ( (sourceDecode == PAF_SOURCE_THD) || (sourceDecode == PAF_SOURCE_DXP) || (sourceDecode == PAF_SOURCE_DTSHD) ) && ( sampleRate == PAF_SAMPLERATE_UNKNOWN) ) { /* do nothing and return - waiting for major access unit */ pC->inpDec.frame++; retVal = ASIP_NO_ERR; } else { errno = decDecodeData(pP, pQ, pC, sourceSelect); if (errno != ASIP_NO_ERR) { //gAsipDecodeErrCnt++; TRACE_TERSE1("PAF_ASIT_decodeProcessing: state: DECODE. decodeDecode err 0x%04x", errno); retVal = ASIP_ERR_DECODE_DATA; } else { errno = pP->fxns->decodeFinalTest(pP, pQ, pC, pC->inpDec.frame, pC->inpDec.block); if (errno) { retVal = ASIP_ERR_DECODE_FINAL; } else { retVal = ASIP_NO_ERR; } } } } return retVal; } /* asipDecodeProcessing */ #endif #if 0 // ----------------------------------------------------------------------------- // ASIT Processing Function - Decode Processing // // Name: asipDecodeProcessing // Purpose: // Return: Error number in standard form (0 on success). // ----------------------------------------------------------------------------- Int asipDecodeProcessing( const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ, PAF_ASIT_Config *pAsitCfg, Int sourceSelect) { PAF_AST_Config *pAstCfg; asipDecProc_t *pDec; Int decError, retVal, getVal; /* error number */ Int zMD, decDone; Int8 tempVar8; pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration zMD = pAstCfg->masterDec; pDec = &pAsitCfg->inpDec; retVal = ASIP_NO_ERR; // Initialization for decode processing if(!pDec->initDone) { // Initialize decoder and send message to decoder retVal = decDecodeInit(pP, pAsitCfg, pAsitCfg->pIoInp[zMD].sourceSelect); if(retVal != ASIP_NO_ERR) { decDecodeComplete(pP, pAsitCfg); return retVal; } pDec->initDone = TRUE; } // Check if source has configured to NONE tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect), GATEMP_INDEX_DEC); if (tempVar8 == PAF_SOURCE_NONE || sourceSelect == PAF_SOURCE_NONE) { TRACE_VERBOSE0("PAF_ASIT_decodeProcessing: sourceSelect == PAF_SOURCE_NONE"); pAsitCfg->inpDec.state = QUIT; // skip processing, quit decoding retVal = ASIP_ERR_DECODE_QUIT; } // Process commands (decode) getVal = pP->fxns->decodeCommand(pP, pQ, pAsitCfg); if (getVal) { retVal = ASIP_ERR_DECODE_COMMAND; if (getVal == ASPERR_QUIT) { TRACE_VERBOSE0("PAF_ASIT_decodeProcessing. %d: state = QUIT"); // Don't return if ASPERR_QUIT, but skip decode processing and quit pAsitCfg->inpDec.state = QUIT; } else if (getVal == ASPERR_ABORT) { TRACE_VERBOSE0("PAF_ASIT_decodeProcessing. %d: return getVal"); // Return here if ASPERR_ABORT return retVal; } else { /* ignore */; } } do { decDone = TRUE; switch(pAsitCfg->inpDec.state) { case INFO1: decError = decDecodeInfo(pP, pQ, pAsitCfg); if (decError) { //gAsipInfo1_PrimaryErrCnt++; TRACE_TERSE1("INFO1: decError 0x%x after decodeInfo, primary timing", decError); retVal = ASIP_ERR_DECODE_INFO1; } else { // Don't start decode until major access unit is found. Int8 sourceDecode, sampleRate; sourceDecode = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode), GATEMP_INDEX_DEC); sampleRate = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sampleRate), GATEMP_INDEX_DEC); if ( ( (sourceDecode == PAF_SOURCE_THD) || (sourceDecode == PAF_SOURCE_DXP) || (sourceDecode == PAF_SOURCE_DTSHD) ) && ( sampleRate == PAF_SAMPLERATE_UNKNOWN) ) { //gMajorAuMissed++; // debug pAsitCfg->inpDec.frame++; //pAsitCfg->inpDec.state = INFO1; // stay in this state } else { decError = pP->fxns->decodeInfo1(pP, pQ, pAsitCfg, pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block); if(decError) { retVal = ASIP_ERR_DECODE_INFO1; } else { pAsitCfg->inpDec.state = DECODE; decDone = FALSE; // go to DECODE state before return } } } break; case INFO2: decError = decDecodeInfo(pP, pQ, pAsitCfg); if (decError) { //gAsipInfo1_PrimaryErrCnt++; TRACE_TERSE1("INFO2: decError 0x%x after decodeInfo, primary timing", decError); retVal = ASIP_ERR_DECODE_INFO2; } else { pAsitCfg->inpDec.state = DECODE; decDone = FALSE; // go to DECODE state before return } break; case DECODE: decError = decDecodeData(pP, pQ, pAsitCfg, sourceSelect); if (decError) { //gAsipDecodeErrCnt++; TRACE_TERSE1("PAF_ASIT_decodeProcessing: state: DECODE. decodeDecode err 0x%04x", decError); retVal = ASIP_ERR_DECODE_DATA; } else { decError = pP->fxns->decodeFinalTest(pP, pQ, pAsitCfg, pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block); if (decError) { retVal = ASIP_ERR_DECODE_FINAL; } else { pAsitCfg->inpDec.frame++; pAsitCfg->inpDec.state = INFO2; } } break; case QUIT: //gAsipQuitCnt++; Log_info0("TaskAsip: state=QUIT"); // Quit: // - Set error number registers. // - Exit state machine to "decode complete" processing. TRACE_VERBOSE0("PAF_ASIT_decodeProcessing: state: QUIT"); break; default: break; } /* switch */ } while (!decDone); if(retVal != ASIP_NO_ERR) { decDecodeComplete(pP, pAsitCfg); } return retVal; } /* asipDecodeProcessing */ #endif /* Nothing past this line */