void MpdPtAVT::signalKeyDown(MpBufPtr pPacket) { struct avtPacket* pAvt; unsigned int ts; OsStatus ret; pAvt = (struct avtPacket*) MpBuf_getStorage(pPacket); ts = pAvt->rh.timestamp; OsSysLog::add(FAC_MP, PRI_INFO, "MpdPtAVT(%p) Start Rcv Tone key=%d" " dB=%d TS=0x%08x\n", this, pAvt->key, pAvt->dB, ntohl(ts)); OsSysLog::add(FAC_MP, PRI_INFO, "MpdPtAVT::signalKeyDown mpRecorder = %p, mpNotify = %p", mpRecorder, mpNotify); if (mpRecorder) mpRecorder->termDtmf(pAvt->key); if (NULL != mpNotify) { ret = mpNotify->signal((pAvt->key) << 16 | (mToneDuration & 0xffff)); if (OS_SUCCESS != ret) { if (OS_ALREADY_SIGNALED == ret) { OsSysLog::add(FAC_MP, PRI_ERR, "MpdPtAVT(%p) Signal Start returned OS_ALREADY_SIGNALED", this); } else { OsSysLog::add(FAC_MP, PRI_ERR, "MpdPtAVT(%p) Signal Start returned %d", this, ret); } } } mCurrentToneKey = pAvt->key; mCurrentToneSignature = ts; mToneDuration = 0; }
OsStatus MpBuf_setSamples(MpBufPtr b, Sample *first) { if (MpBuf_invalid(b, TRUE, TRUE)) { return OS_INVALID_ARGUMENT; } return MpBuf_setOffset(b, ((char *) first - MpBuf_getStorage(b))); }
/* //////////////////////////// PRIVATE /////////////////////////////////// */ MprDejitter* MprDecode::getMyDejitter(void) { assert(NULL != mpMyDJ); return mpMyDJ; } #ifdef DEBUG /* [ */ static void showRtpPacket(MpBufPtr rtp) { struct rtpHeader rh, *rp; int len; rp = (struct rtpHeader *) (MpBuf_getStorage(rtp)); memcpy((char *) &rh, (char *) rp, sizeof(struct rtpHeader)); rh.vpxcc = rp->vpxcc; rh.mpt = rp->mpt; rh.seq = ntohs(rp->seq); rh.timestamp = ntohl(rp->timestamp); rh.ssrc = ntohl(rp->ssrc); len = MpBuf_getNumSamples(rtp) - sizeof(struct rtpHeader); Zprintf("RcvRTP: %02X, %02X, %d, %d, %08X, and %d bytes of data\n", rh.vpxcc, rh.mpt, rh.seq, rh.timestamp, rh.ssrc, len); }
void MprDecode::pushIntoJitterBuffer(MpBufPtr pPacket, int packetLen) { int res; JB_inst* pJBState = mpConnection->getJBinst(); unsigned char* pHeader = (unsigned char*)MpBuf_getStorage(pPacket); res = JB_RecIn(pJBState, pHeader, packetLen, 0); if (0 != res) { osPrintf( "\n\n *** JB_RecIn(0x%p, 0x%p, %d) returned %d\n", pJBState, pHeader, packetLen, res); osPrintf(" pt=%d, Ts=%d, Seq=%d (%2X %2X)\n\n", MprDejitter::getPayloadType(pPacket), MprDejitter::getTimestamp(pPacket), MprDejitter::getSeqNum(pPacket), *pHeader, *(pHeader+1)); } }
OsStatus MpBuf_setOffset(MpBufPtr b, int offset) { if (MpBuf_invalid(b, TRUE, TRUE)) { return OS_INVALID_ARGUMENT; } if ((offset < 0) || (offset > MpBuf_getByteLen(b))) { Zprintf("MpBuf_setOffset(0x%X, %d): Offset invalid (max=%d)\n", (int) b, offset, MpBuf_getByteLen(b), 0,0,0); return OS_INVALID_ARGUMENT; } // $$$ Should we make sure that the offset is consistent with the // alignment requirements of the payload type? b->pSamples = (Sample *) (MpBuf_getStorage(b) + offset); b->offset = offset; return OS_SUCCESS; }
int MpdGIPSPCMA::decodeIn(MpBufPtr pPacket) { int thisLen; unsigned char* pHeader; thisLen = MpBuf_getContentLen(pPacket); pHeader = (unsigned char*)MpBuf_getStorage(pPacket); if (invalidLen(thisLen, pHeader)) { /* DISCARD AN ODD LENGTH PACKET */ osPrintf("MpdGIPSPCMU::decodeIn - BAD packet, SEQ#%d," " payload is %d bytes\n", MprDejitter::getSeqNum(pPacket), thisLen); return OS_SUCCESS; /* (nobody cares, don't rock the boat!) */ thisLen = 0; } return thisLen; }
void MpdPtAVT::signalKeyUp(MpBufPtr pPacket) { struct avtPacket* pAvt; unsigned int samples; unsigned int ts; OsStatus ret; pAvt = (struct avtPacket*) MpBuf_getStorage(pPacket); ts = pAvt->rh.timestamp; samples = pAvt->samplesSwapped; samples = ntohs(samples); if ((-1) != mCurrentToneKey) { OsSysLog::add(FAC_MP, PRI_INFO, "MpdPtAVT(%p) Stop Rcv Tone key=%d" " dB=%d TS=0x%08x+%d last key=%d\n", this, pAvt->key, pAvt->dB, ntohl(mCurrentToneSignature), mToneDuration, mCurrentToneKey); mPrevToneSignature = mCurrentToneSignature; if (NULL != mpNotify) { ret = mpNotify->signal(0x80000000 | (0x3fff0000 & (mCurrentToneKey << 16)) | (mToneDuration & 0xffff)); if (OS_SUCCESS != ret) { if (OS_ALREADY_SIGNALED == ret) { OsSysLog::add(FAC_MP, PRI_ERR, "MpdPtAVT(%p) Signal Stop returned OS_ALREADY_SIGNALED", this); } else { OsSysLog::add(FAC_MP, PRI_ERR, "MpdPtAVT(%p) Signal Stop returned %d", this, ret); } } } if (mpRecorder) { mpRecorder->termDtmf(-1); } } mCurrentToneKey = -1; mCurrentToneSignature = 0; mToneDuration = 0; }
unsigned int MprDejitter::getPayloadType(MpBufPtr pRtp) { assert(NULL != pRtp); return (0x7f & (((struct rtpHeader*) MpBuf_getStorage(pRtp))->mpt)); }
unsigned int MprDejitter::getTimestamp(MpBufPtr pRtp) { assert(NULL != pRtp); return ntohl(((struct rtpHeader*) MpBuf_getStorage(pRtp))->timestamp); }
unsigned short MprDejitter::getSeqNum(MpBufPtr pRtp) { assert(NULL != pRtp); return ntohs(((struct rtpHeader*) MpBuf_getStorage(pRtp))->seq); }
/*************************************************************************/ MpMisc.RtpPool = MpBufPool_MpBufPool(0, NETWORK_MTU, rtpNBufs, 0); Nprintf("MpBuf_init: MpMisc.RtpPool = 0x%X\n", (int) MpMisc.RtpPool, 0,0,0,0,0); if (NULL == MpMisc.RtpPool) { MpBufPool_delete(MpMisc.UcbPool, 1); MpMisc.UcbPool = NULL; return OS_NO_MEMORY; } MpMisc.RtcpPool = MpBufPool_MpBufPool(0, MAX_RTCP_PACKET_LEN, rtcpNBufs, 0); Nprintf("MpBuf_init: MpMisc.RtcpPool = 0x%X\n", (int) MpMisc.RtcpPool, 0,0,0,0,0); if (NULL == MpMisc.RtcpPool) { MpBufPool_delete(MpMisc.UcbPool, 1); MpMisc.UcbPool = NULL; MpBufPool_delete(MpMisc.RtpPool, 1); MpMisc.RtpPool = NULL; return OS_NO_MEMORY; } return OS_SUCCESS; } #ifdef BUFFER_INSTRUMENTATION /* [ */ volatile int bufHang, doHang = 1; int we_are_logging = 0; int bufUnHang(int x) { int was = bufHang; bufHang = 0; doHang = x; return was; } int forceLogging(int on) { int was = we_are_logging; we_are_logging = on; return was; } int incr_time_stamp() { OsLock lock(*spCounterMutex); return buffer_time_stamp++; } #endif /* BUFFER_INSTRUMENTATION ] */ void MpBuf_insertSawTooth(MpBufPtr b) { int i, n; Sample *s; if (NULL == b) return; if (!MpBuf_invalid(b, TRUE, TRUE)) { s = MpBuf_getSamples(b); n = MpBuf_getNumSamples(b); for (i=0; i<n; i++) *s++ = ((0xf & i) << 12); } } #ifdef BUFFER_INSTRUMENTATION /* [ */ MpBufPtr MpBuf_getBufX(MpBufPoolPtr Pool, int initSamples, int initOffset, MpBufFormat initFormat, int line) #else /* BUFFER_INSTRUMENTATION ] [ */ MpBufPtr MpBuf_getBufY(MpBufPoolPtr Pool, int initSamples, int initOffset, MpBufFormat initFormat) #endif /* BUFFER_INSTRUMENTATION ] */ { int i; int n; MpBufPtr ret, t; MpBufPoolPtr l = Pool; OsLock lock(*(Pool->mpMutex)); #ifdef BUFFER_INSTRUMENTATION /* [ */ int this_time = incr_time_stamp(); #endif /* BUFFER_INSTRUMENTATION ] */ ret = NULL; n = l->lastTaken; t = &(l->table[n]); for (i=0; ((NULL==ret) && (i<l->allocCnt)); i++) { if (n >= l->allocCnt) { n = 0; t = l->table; } if (0 == t->status) { n++; if (n >= l->allocCnt) { n = 0; } l->lastTaken = n; ret = t; ret->status = 1; ret->speech = MP_SPEECH_UNKNOWN; ret->refCnt = 1; MpBuf_setFormat(ret, initFormat); MpBuf_setOffset(ret, initOffset); MpBuf_setNumSamples(ret, initSamples); MpBuf_setOsTC(ret, 0); #define CLEAR_BUFFER #undef CLEAR_BUFFER #ifdef CLEAR_BUFFER /* [ */ memset(MpBuf_getStorage(ret), 0, MpBuf_getByteLen(ret)); #endif /* CLEAR_BUFFER ] */ #define INSERT_SAWTOOTH #undef INSERT_SAWTOOTH #ifdef INSERT_SAWTOOTH /* [ */ MpBuf_insertSawTooth(ret); #endif /* INSERT_SAWTOOTH ] */ #ifdef BUFFER_INSTRUMENTATION /* [ */ ret->line_taken = line; ret->time_taken = this_time; #endif /* BUFFER_INSTRUMENTATION ] */ } t++; n++; } #ifdef BUFFER_INSTRUMENTATION /* [ */ if (NULL != ret) l->nfree--; if (l->nfree < l->minfree) { l->minfree = l->nfree; if (2 < (l->allocCnt)) { showBufs(Pool, line); } if (15 < (l->allocCnt - l->nfree)) { /* dumpBufs(0); */ } } #endif /* BUFFER_INSTRUMENTATION ] */ Nprintf(" +%02d(%d)\n", i-1, line, 0,0,0,0); Nprintf("take: 0x%08X (%d), at %d\n", (int) ret, i-1, line, 0,0,0); /* printf("take: 0x%08X (%d)\n", (int) ret, i-1); */ return ret; }
int MpdPtAVT::decodeIn(MpBufPtr pPacket) { struct avtPacket* pAvt; unsigned int samples; unsigned int ts; pAvt = (struct avtPacket*) MpBuf_getStorage(pPacket); dumpRawAvtPacket(pAvt, this); ts = pAvt->rh.timestamp; if (-1 != mCurrentToneKey) { // if previous tone still active if (mCurrentToneSignature != ts) { // and we have not seen this if (0 != mToneDuration) { // and its duration > 0 OsSysLog::add(FAC_MP, PRI_INFO, "++++ MpdPtAVT(%p) SYNTHESIZING KEYUP for old key (%d)" " duration=%d ++++\n", this, mCurrentToneKey, mToneDuration); signalKeyUp(pPacket); } } } // Key Down (start of tone) if ((0x80 == (0x80 & (pAvt->rh.mpt))) && (ts != mCurrentToneSignature)) { // start bit marked OsSysLog::add(FAC_MP, PRI_INFO, "++++ MpdPtAVT(%p) RECEIVED KEYDOWN" " (marker bit set), duration=%d, TSs: old=0x%08x, new=0x%08x," " delta=%d; mCurrentToneKey=%d ++++", this, mToneDuration, ntohl(mPrevToneSignature), ntohl(ts), ntohl(ts) - ntohl(mPrevToneSignature), mCurrentToneKey); signalKeyDown(pPacket); samples = pAvt->samplesSwapped; mToneDuration = (ntohs(samples) & 0xffff); } else if ((mPrevToneSignature != ts) && (-1 == mCurrentToneKey)) { // key up interpreted as key down if no previous start tone received OsSysLog::add(FAC_MP, PRI_INFO, "++++ MpdPtAVT(%p) RECEIVED KEYDOWN" " (lost packets?) duration=%d; TSs: old=0x%08x, new=0x%08x," " delta=%d; ++++\n", this, mToneDuration, ntohl(mPrevToneSignature), ntohl(ts), ntohl(ts) - ntohl(mPrevToneSignature)); signalKeyDown(pPacket); samples = pAvt->samplesSwapped; mToneDuration = (ntohs(samples) & 0xffff); } else { samples = pAvt->samplesSwapped; mToneDuration = (ntohs(samples) & 0xffff); if (mToneDuration && (0x80 != (0x80 & (pAvt->dB)))) { OsSysLog::add(FAC_MP, PRI_INFO, "++++ MpdPtAVT(%p) RECEIVED packet, not KEYDOWN, set duration to zero" " duration=%d; TSs: old=0x%08x, new=0x%08x," " delta=%d; ++++\n", this, mToneDuration, ntohl(mPrevToneSignature), ntohl(ts), ntohl(ts) - ntohl(mPrevToneSignature)); mToneDuration = 0; } } // Key Up (end of tone) if (0x80 == (0x80 & (pAvt->dB))) { OsSysLog::add(FAC_MP, PRI_INFO, "++++ MpdPtAVT(%p) RECEIVED KEYUP" " duration=%d, TS=0x%08x ++++\n", this, mToneDuration, ntohl(ts)); signalKeyUp(pPacket); } return MpBuf_getContentLen(pPacket); }
UtlBoolean MprDecode::doProcessFrame(MpBufPtr inBufs[], MpBufPtr outBufs[], int inBufsSize, int outBufsSize, UtlBoolean isEnabled, int samplesPerFrame, int samplesPerSecond) { #ifdef DEBUG_DECODING /* [ */ static int numFramesForWarnings = 0; static int numWarnings = 0; #endif /* DEBUG_DECODING ] */ MpBufPtr rtp; MpBufPtr out; #ifdef DEBUG_DECODING /* [ */ numFramesForWarnings++; #endif /* DEBUG_DECODING ] */ MpDecoderBase* pCurDec; Sample* pSamples = NULL; mFrameCounter++; if (0 == outBufsSize) return FALSE; if (!isEnabled) { mPreloading = 1; *outBufs = MpBuf_getFgSilence(); return TRUE; } { MprDejitter* pDej = getMyDejitter(); int packetLen; int pt; while (NULL != (rtp = pDej->pullPacket())) { pt = MprDejitter::getPayloadType(rtp); pCurDec = mpConnection->mapPayloadType(pt); if (NULL != pCurDec) { unsigned char* pRtpH; pRtpH = ((unsigned char*) MpBuf_getStorage(rtp)) + 1; if (0x80 == (0x80 & *pRtpH)) { if ((mFrameLastMarkerNotice + MARKER_WAIT_FRAMES) < mFrameCounter) { mNumMarkerNotices = 0; } if (mNumMarkerNotices++ < MAX_MARKER_NOTICES) { // osPrintf("MprDecode: RTP marker bit ON\n"); mFrameLastMarkerNotice = mFrameCounter; } } packetLen = pCurDec->decodeIn(rtp); if (packetLen > 0) { pushIntoJitterBuffer(rtp, packetLen); } } MpBuf_delRef(rtp); } } out = MpBuf_getBuf(MpMisc.UcbPool, samplesPerFrame, 0, MP_FMT_T12); if (out) { pSamples = MpBuf_getSamples(out); memset(pSamples, 0, samplesPerFrame * sizeof(Sample)); MpBuf_setSpeech(out, MP_SPEECH_SILENT); } JB_inst* pJBState = mpConnection->getJBinst(); if (pJBState) { // This should be a JB_something or other. However the only // current choices is a short or long equivalant and this needs // to be a plain old int: int outLen; int res; res = JB_RecOut(pJBState, pSamples, &outLen); MpBuf_setSpeech(out, MP_SPEECH_UNKNOWN); } *outBufs = out; Nprintf("Decode_doPF: returning 0x%p\n", out, 0,0,0,0,0); return TRUE; }