int WebRtcNetEQ_McuReset(MCUInst_t *inst) { #ifdef NETEQ_ATEVENT_DECODE int ok; #endif /* MCU/DSP Communication layer */ inst->pw16_readAddress = NULL; inst->pw16_writeAddress = NULL; inst->main_inst = NULL; inst->one_desc = 0; inst->BufferStat_inst.Automode_inst.extraDelayMs = 0; inst->BufferStat_inst.Automode_inst.minimum_delay_ms = 0; inst->BufferStat_inst.Automode_inst.maximum_delay_ms = 10000; inst->NetEqPlayoutMode = kPlayoutOn; inst->av_sync = 0; WebRtcNetEQ_DbReset(&inst->codec_DB_inst); memset(&inst->PayloadSplit_inst, 0, sizeof(SplitInfo_t)); /* Clear the Packet buffer and the pointer to memory storage */ WebRtcNetEQ_PacketBufferFlush(&inst->PacketBuffer_inst); inst->PacketBuffer_inst.memorySizeW16 = 0; inst->PacketBuffer_inst.maxInsertPositions = 0; /* Clear the decision and delay history */ memset(&inst->BufferStat_inst, 0, sizeof(BufstatsInst_t)); #ifdef NETEQ_ATEVENT_DECODE ok = WebRtcNetEQ_DtmfDecoderInit(&inst->DTMF_inst, 8000, 560); if (ok != 0) { return ok; } #endif inst->NoOfExpandCalls = 0; inst->current_Codec = -1; inst->current_Payload = -1; inst->millisecondsPerCall = 10; inst->timestampsPerCall = inst->millisecondsPerCall * 8; inst->fs = 8000; inst->first_packet = 1; WebRtcNetEQ_ResetMcuInCallStats(inst); WebRtcNetEQ_ResetWaitingTimeStats(inst); WebRtcNetEQ_ResetMcuJitterStat(inst); WebRtcNetEQ_ResetAutomode(&(inst->BufferStat_inst.Automode_inst), inst->PacketBuffer_inst.maxInsertPositions); return 0; }
/* * Signals the MCU that DSP status data is available. */ int WebRtcNetEQ_SignalMcu(MCUInst_t *inst) { int i_bufferpos, i_res; WebRtc_UWord16 uw16_instr; DSP2MCU_info_t dspInfo; WebRtc_Word16 *blockPtr, blockLen; WebRtc_UWord32 uw32_availableTS; RTPPacket_t temp_pkt; WebRtc_Word32 w32_bufsize, w32_tmp; WebRtc_Word16 payloadType = -1; WebRtc_Word16 wantedNoOfTimeStamps; WebRtc_Word32 totalTS; WebRtc_Word16 oldPT, latePacketExist = 0; WebRtc_UWord32 oldTS, prevTS, uw32_tmp; WebRtc_UWord16 prevSeqNo; WebRtc_Word16 nextSeqNoAvail; WebRtc_Word16 fs_mult, w16_tmp; WebRtc_Word16 lastModeBGNonly = 0; #ifdef NETEQ_DELAY_LOGGING int temp_var; #endif int playDtmf = 0; fs_mult = WebRtcSpl_DivW32W16ResW16(inst->fs, 8000); /* Increment counter since last statistics report */ inst->lastReportTS += inst->timestampsPerCall; /* Increment waiting time for all packets. */ WebRtcNetEQ_IncrementWaitingTimes(&inst->PacketBuffer_inst); /* Read info from DSP so we now current status */ WEBRTC_SPL_MEMCPY_W8(&dspInfo,inst->pw16_readAddress,sizeof(DSP2MCU_info_t)); /* Set blockPtr to first payload block */ blockPtr = &inst->pw16_writeAddress[3]; /* Clear instruction word and number of lost samples (2*WebRtc_Word16) */ inst->pw16_writeAddress[0] = 0; inst->pw16_writeAddress[1] = 0; inst->pw16_writeAddress[2] = 0; if ((dspInfo.lastMode & MODE_AWAITING_CODEC_PTR) != 0) { /* * Make sure state is adjusted so that a codec update is * performed when first packet arrives. */ if (inst->new_codec != 1) { inst->current_Codec = -1; } dspInfo.lastMode = (dspInfo.lastMode ^ MODE_AWAITING_CODEC_PTR); } #ifdef NETEQ_STEREO if ((dspInfo.lastMode & MODE_MASTER_DTMF_SIGNAL) != 0) { playDtmf = 1; /* force DTMF decision */ dspInfo.lastMode = (dspInfo.lastMode ^ MODE_MASTER_DTMF_SIGNAL); } if ((dspInfo.lastMode & MODE_USING_STEREO) != 0) { if (inst->usingStereo == 0) { /* stereo mode changed; reset automode instance to re-synchronize statistics */ WebRtcNetEQ_ResetAutomode(&(inst->BufferStat_inst.Automode_inst), inst->PacketBuffer_inst.maxInsertPositions); } inst->usingStereo = 1; dspInfo.lastMode = (dspInfo.lastMode ^ MODE_USING_STEREO); } else { inst->usingStereo = 0; } #endif /* detect if BGN_ONLY flag is set in lastMode */ if ((dspInfo.lastMode & MODE_BGN_ONLY) != 0) { lastModeBGNonly = 1; /* remember flag */ dspInfo.lastMode ^= MODE_BGN_ONLY; /* clear the flag */ } if ((dspInfo.lastMode == MODE_RFC3389CNG) || (dspInfo.lastMode == MODE_CODEC_INTERNAL_CNG) || (dspInfo.lastMode == MODE_EXPAND)) { /* * If last mode was CNG (or Expand, since this could be covering up for a lost CNG * packet), increase the CNGplayedTS counter. */ inst->BufferStat_inst.uw32_CNGplayedTS += inst->timestampsPerCall; if (dspInfo.lastMode == MODE_RFC3389CNG) { /* remember that RFC3389CNG is on (needed if CNG is interrupted by DTMF) */ inst->BufferStat_inst.w16_cngOn = CNG_RFC3389_ON; } else if (dspInfo.lastMode == MODE_CODEC_INTERNAL_CNG) { /* remember that internal CNG is on (needed if CNG is interrupted by DTMF) */ inst->BufferStat_inst.w16_cngOn = CNG_INTERNAL_ON; } } /* Update packet size from previously decoded packet */ if (dspInfo.frameLen > 0) { inst->PacketBuffer_inst.packSizeSamples = dspInfo.frameLen; } /* Look for late packet (unless codec has changed) */ if (inst->new_codec != 1) { if (WebRtcNetEQ_DbIsMDCodec((enum WebRtcNetEQDecoder) inst->current_Codec)) { WebRtcNetEQ_PacketBufferFindLowestTimestamp(&inst->PacketBuffer_inst, inst->timeStamp, &uw32_availableTS, &i_bufferpos, 1, &payloadType); if ((inst->new_codec != 1) && (inst->timeStamp == uw32_availableTS) && (inst->timeStamp < dspInfo.playedOutTS) && (i_bufferpos != -1) && (WebRtcNetEQ_DbGetPayload(&(inst->codec_DB_inst), (enum WebRtcNetEQDecoder) inst->current_Codec) == payloadType)) { int waitingTime; temp_pkt.payload = blockPtr + 1; i_res = WebRtcNetEQ_PacketBufferExtract(&inst->PacketBuffer_inst, &temp_pkt, i_bufferpos, &waitingTime); if (i_res < 0) { /* error returned */ return i_res; } WebRtcNetEQ_StoreWaitingTime(inst, waitingTime); *blockPtr = temp_pkt.payloadLen; /* set the flag if this is a redundant payload */ if (temp_pkt.rcuPlCntr > 0) { *blockPtr = (*blockPtr) | (DSP_CODEC_RED_FLAG); } blockPtr += ((temp_pkt.payloadLen + 1) >> 1) + 1; /* * Close the data with a zero size block, in case we will not write any * more data. */ *blockPtr = 0; inst->pw16_writeAddress[0] = (inst->pw16_writeAddress[0] & 0xf0ff) | DSP_CODEC_ADD_LATE_PKT; latePacketExist = 1; } }