/* printf("take: 0x%08X (%d)\n", (int) ret, i-1); */ return ret; } #ifdef BUFFER_INSTRUMENTATION /* [ */ void MpBuf_delRefX(MpBufPtr b, int line) #else /* BUFFER_INSTRUMENTATION ] [ */ void MpBuf_delRef(MpBufPtr b) #define line (-1) #endif /* BUFFER_INSTRUMENTATION ] */ { MpBufPoolPtr l; #ifdef BUFFER_INSTRUMENTATION /* [ */ int this_time = incr_time_stamp(); #endif /* BUFFER_INSTRUMENTATION ] */ int n; if (NULL == b) { return; } if (MpBuf_invalid(b, FALSE, TRUE)) { Zprintf("MpBuf_delRef(0x%X): invalid! line: %d\n", (int) b, line, 0,0,0,0); // assert(!MpBuf_invalid(b, FALSE, TRUE)); return; } l = b->pPool; n = b - l->table; if ((n < 0) || (n >= l->allocCnt)) { Zprintf("MpBuf_delRef: attempt to free 0x%X (%d) @%d\n", (int) b, n, line, 0,0,0); } else if (1 != b->status) { l->mpMutex->acquire(); b->status = 2; l->mpMutex->release(); Zprintf("MpBuf_delRef: attempt to free a free buffer" " -- 0x%X (%d) @%d\n", (int) b, n, line, 0,0,0); } else { Nprintf("!%d(%d)\n ", b - l->table, line,0,0,0,0); l->mpMutex->acquire(); b->refCnt--; if (0 == b->refCnt) { b->status = 0; b->speech = MP_SPEECH_UNKNOWN; #ifdef BUFFER_INSTRUMENTATION /* [ */ l->nfree++; b->line_freed = line; b->time_freed = this_time; #endif /* BUFFER_INSTRUMENTATION ] */ } l->mpMutex->release(); } #undef line } /* MpBuf_delRef, MpBuf_delRefX */ #ifdef BUFFER_INSTRUMENTATION /* [ */ void MpBuf_addRefX(MpBufPtr b, int line) #else /* BUFFER_INSTRUMENTATION ] [ */ void MpBuf_addRef(MpBufPtr b) #define line (-1) #endif /* BUFFER_INSTRUMENTATION ] */ { MpBufPoolPtr l; int n; if (NULL == b) { return; } if (MpBuf_invalid(b, FALSE, TRUE)) { Zprintf("MpBuf_addRef(0x%X): invalid! line: %d\n", (int) b, line, 0,0,0,0); return; } l = b->pPool; n = b - l->table; if ((n < 0) || (n >= l->allocCnt)) { Zprintf("MpBuf_addRef: attempt to free 0x%X (%d) @%d\n", (int) b, n, line, 0,0,0); } else if (1 != b->status) { l->mpMutex->acquire(); b->status = 2; l->mpMutex->release(); Zprintf("MpBuf_addRef: attempt to add ref to a free buffer" " -- 0x%X (%d) @%d\n", (int) b, n, line, 0,0,0); } else { Nprintf("!%d(%d)\n ", b - l->table, line,0,0,0,0); l->mpMutex->acquire(); b->refCnt++; l->mpMutex->release(); } #undef line } /* MpBuf_addRef, MpBuf_addRefX */ #ifdef BUFFER_INSTRUMENTATION /* [ */ void MpBuf_touchX(MpBufPtr b, int line) { MpBufPoolPtr l; int this_time; int n; if (NULL == b) return; // allow and ignore NULL pointers l = b->pPool; this_time = incr_time_stamp(); n = b - l->table; if ((n < 0) || (n >= l->allocCnt)) { Zprintf( "bufTouch: attempt to touch a bad buffer -- 0x%X (%d) @%d\n", (int) b, n, line, 0,0,0); } else if (1 != b->status) { l->mpMutex->acquire(); b->status = 2; l->mpMutex->release(); Zprintf( "bufTouch: attempt to touch a free buffer -- 0x%X (%d) @%d(%d)\n", (int) b, n, line, buffer_time_stamp, 0,0); dump1Buf(b); } else { l->mpMutex->acquire(); b->touched_by = line; b->touched_at = this_time; l->mpMutex->release(); } }
void dump1Pool(MpBufPoolPtr P, int skipFree) { // MpBufPoolPtr l = pool; #ifdef BUFFER_INSTRUMENTATION /* [ */ MpBufPtr t; int i; #endif /* BUFFER_INSTRUMENTATION ] */ OsLock lock(*(P->mpMutex)); Zprintf(" Buffer table Dump(0x%X): count=%d mutex=0x%X *table=0x%X\n", (int) P, P->allocCnt, (int) P->mpMutex, (int) P->table, 0,0); Zprintf(" size=%d eachLen=%d cacheAlign=%d last=%d", P->size, P->eachLen, P->cacheAlignment, P->lastTaken, 0, 0); #ifdef BUFFER_INSTRUMENTATION /* [ */ Zprintf(" nf=%d mf=%d\n", P->nfree, P->minfree, 0,0,0,0); #else /* BUFFER_INSTRUMENTATION ] [ */ Zprintf("\n", 0,0,0,0,0,0); #endif /* BUFFER_INSTRUMENTATION ] */ #ifdef BUFFER_INSTRUMENTATION /* [ */ t = &(P->table[0]); for (i=0; i<P->allocCnt; i++) { if (-1 != (t->line_taken)) { if ((!skipFree) || (0 != t->status)) dump1Buf(t); } t++; } #endif /* BUFFER_INSTRUMENTATION ] */ }
/* printf("take: 0x%08X (%d)\n", (int) ret, i-1); */ return ret; } #ifdef BUFFER_INSTRUMENTATION /* [ */ void MpBuf_delRefX(MpBufPtr b, int line) #else /* BUFFER_INSTRUMENTATION ] [ */ void MpBuf_delRef(MpBufPtr b) #define line (-1) #endif /* BUFFER_INSTRUMENTATION ] */ { MpBufPoolPtr l; #ifdef BUFFER_INSTRUMENTATION /* [ */ int this_time = incr_time_stamp(); #endif /* BUFFER_INSTRUMENTATION ] */ int n; if (NULL == b) { return; } if (MpBuf_invalid(b, FALSE, TRUE)) { Zprintf("MpBuf_delRef(0x%X): invalid! line: %d\n", (int) b, line, 0,0,0,0); // assert(!MpBuf_invalid(b, FALSE, TRUE)); return; } l = b->pPool; n = b - l->table; if ((n < 0) || (n >= l->allocCnt)) { Zprintf("MpBuf_delRef: attempt to free 0x%X (%d) @%d\n", (int) b, n, line, 0,0,0); } else if (1 != b->status) { l->mpMutex->acquire(); b->status = 2; l->mpMutex->release(); Zprintf("MpBuf_delRef: attempt to free a free buffer" " -- 0x%X (%d) @%d\n", (int) b, n, line, 0,0,0); } else { Nprintf("!%d(%d)\n ", b - l->table, line,0,0,0,0); l->mpMutex->acquire(); b->refCnt--; if (0 == b->refCnt) { b->status = 0; b->speech = MP_SPEECH_UNKNOWN; #ifdef BUFFER_INSTRUMENTATION /* [ */ l->nfree++; b->line_freed = line; b->time_freed = this_time; #endif /* BUFFER_INSTRUMENTATION ] */ } l->mpMutex->release(); } #undef line } /* MpBuf_delRef, MpBuf_delRefX */
MpBufPtr MpBuf_allowMods(MpBufPtr b) { MpBufPtr t; if (NULL == b) { return NULL; } if (MpBuf_invalid(b, FALSE, TRUE)) { Zprintf("MpBuf_allowMod(0x%X): invalid!\n", (int) b, 0,0,0,0,0); return NULL; } if (1 == b->refCnt) { return b; } t = MpBuf_getBuf(b->pPool, MpBuf_getNumSamples(b), MpBuf_getOffset(b), MpBuf_getFormat(b)); if (NULL == t) { return NULL; } memcpy((void*) MpBuf_getSamples(t), (void*) MpBuf_getSamples(b), MpBuf_getByteLen(t)); MpBuf_setOsTC(t, MpBuf_getOsTC(b)); MpBuf_setContentLen(t, MpBuf_getContentLen(b)); MpBuf_delRef(b); return t; } /* MpBuf_allowMods */
static void complainAdd(const char *n1, int p1, const char *n2, int p2, const char *n3, int p3) { Zprintf("MpFlowGraphBase::handleAddLink(%s:%d, %s:%d)\n" " %s:%d is already connected!\n", n1, p1, n2, p2, n3, p3); }
MSG_Q_ID startLogging(int nmsgs, int maxlen) { MpMisc.LogQ = msgQCreate(nmsgs, maxlen, MSG_Q_FIFO); if (NULL == MpMisc.LogQ) { osPrintf("cannot create LogQ! Quitting\n"); } else { Zprintf("logQ is 0x%X\n", (int) MpMisc.LogQ, 0,0,0,0,0); taskSpawn("Logger", logTaskPrio, 0, 8192, (FUNCPTR) printTask, 0, 0, 0,0,0,0,0,0,0,0); } return MpMisc.LogQ; }
intptr_t showMpMisc(int justAddress) { Zprintf("&MpMisc = 0x%p\n", &MpMisc, 0,0,0,0,0); if (!justAddress) { Zprintf(" MicQ=0x%p, SpkQ=0x%p, EchoQ=0x%p, silence=0x%p\n" " micMuteStatus=%d, spkrMuteStatus=%d,", MpMisc.pMicQ, MpMisc.pSpkQ, MpMisc.pEchoQ, MpMisc.XXXsilence, MpMisc.micMuteStatus, MpMisc.spkrMuteStatus); Zprintf(" audio_on=%d\n frameSamples=%d," " frameBytes=%d, sampleBytes=%d,", MpMisc.audio_on, MpMisc.frameSamples, MpMisc.frameBytes, MpMisc.sampleBytes, 0,0); Zprintf(" rtpMaxBytes=%d\n UcbPool=0x%p, RtpPool=0x%p, RtcpPool=0x%p\n", MpMisc.rtpMaxBytes, MpMisc.UcbPool, MpMisc.RtpPool, MpMisc.RtcpPool, 0,0); #ifdef _VXWORKS /* [ */ Zprintf(" mem_page_size=%d, mem_page_mask=0x%08X\n" "LogQ=0x%p, logMsgLimit=%d, logMsgSize=%d\n", MpMisc.mem_page_size, MpMisc.mem_page_mask, MpMisc.LogQ, MpMisc.logMsgLimit, MpMisc.logMsgSize, 0); #endif /* _VXWORKS ] */ Zprintf(" Latency: maxMic=%d, maxSpkr=%d, minRtp=%d\n", MpMisc.max_mic_buffers, MpMisc.max_spkr_buffers, MpMisc.min_rtp_packets, 0,0,0); } return (intptr_t) &MpMisc; }
// Handle the FLOWGRAPH_REMOVE_LINK message. // Returns TRUE if the message was handled, otherwise FALSE. UtlBoolean MpFlowGraphBase::handleRemoveLink(MpResource* pFrom, int outPortIdx) { int connectedPort; MpResource* pConnectedResource; // make sure the resource is part of this flow graph if (pFrom->getFlowGraph() != this) { Zprintf("handleRemoveLink: pFrom->getFlowGraph() != this: 0x%p != 0x%p\n", (pFrom->getFlowGraph()), this, 0,0,0,0); assert(FALSE); return FALSE; } // get information about the downstream end of the link pFrom->getOutputInfo(outPortIdx, pConnectedResource, connectedPort); // disconnect the upstream end of the link if (pFrom->disconnectOutput(outPortIdx) == FALSE) { Zprintf("handleRemoveLink: disconnectOutput(0x%p, %d) failed\n", pFrom, outPortIdx, 0,0,0,0); assert(FALSE); // couldn't disconnect return FALSE; } // disconnect the downstream end of the link if (pConnectedResource->disconnectInput(connectedPort) == FALSE) { Zprintf("handleRemoveLink: disconnectInput(0x%p, %d) failed\n", pConnectedResource, connectedPort, 0,0,0,0); assert(FALSE); // couldn't disconnect return FALSE; } mLinkCnt--; mRecomputeOrder = TRUE; return TRUE; }
/* printf("take: 0x%08X (%d)\n", (int) ret, i-1); */ return ret; } #ifdef BUFFER_INSTRUMENTATION /* [ */ void MpBuf_delRefX(MpBufPtr b, int line) #else /* BUFFER_INSTRUMENTATION ] [ */ void MpBuf_delRef(MpBufPtr b) #define line (-1) #endif /* BUFFER_INSTRUMENTATION ] */ { MpBufPoolPtr l; #ifdef BUFFER_INSTRUMENTATION /* [ */ int this_time = incr_time_stamp(); #endif /* BUFFER_INSTRUMENTATION ] */ int n; if (NULL == b) { return; } if (MpBuf_invalid(b, FALSE, TRUE)) { Zprintf("MpBuf_delRef(0x%X): invalid! line: %d\n", (int) b, line, 0,0,0,0); // assert(!MpBuf_invalid(b, FALSE, TRUE)); return; } l = b->pPool; n = b - l->table; if ((n < 0) || (n >= l->allocCnt)) { Zprintf("MpBuf_delRef: attempt to free 0x%X (%d) @%d\n", (int) b, n, line, 0,0,0); } else if (1 != b->status) { l->mpMutex->acquire(); b->status = 2; l->mpMutex->release(); Zprintf("MpBuf_delRef: attempt to free a free buffer" " -- 0x%X (%d) @%d\n", (int) b, n, line, 0,0,0); } else { Nprintf("!%d(%d)\n ", b - l->table, line,0,0,0,0); l->mpMutex->acquire(); b->refCnt--; if (0 == b->refCnt) { b->status = 0; b->speech = MP_SPEECH_UNKNOWN; #ifdef BUFFER_INSTRUMENTATION /* [ */ l->nfree++; b->line_freed = line; b->time_freed = this_time; #endif /* BUFFER_INSTRUMENTATION ] */ } l->mpMutex->release(); } #undef line } /* MpBuf_delRef, MpBuf_delRefX */ #ifdef BUFFER_INSTRUMENTATION /* [ */ void MpBuf_addRefX(MpBufPtr b, int line) #else /* BUFFER_INSTRUMENTATION ] [ */ void MpBuf_addRef(MpBufPtr b) #define line (-1) #endif /* BUFFER_INSTRUMENTATION ] */ { MpBufPoolPtr l; int n; if (NULL == b) { return; } if (MpBuf_invalid(b, FALSE, TRUE)) { Zprintf("MpBuf_addRef(0x%X): invalid! line: %d\n", (int) b, line, 0,0,0,0); return; } l = b->pPool; n = b - l->table; if ((n < 0) || (n >= l->allocCnt)) { Zprintf("MpBuf_addRef: attempt to free 0x%X (%d) @%d\n", (int) b, n, line, 0,0,0); } else if (1 != b->status) { l->mpMutex->acquire(); b->status = 2; l->mpMutex->release(); Zprintf("MpBuf_addRef: attempt to add ref to a free buffer" " -- 0x%X (%d) @%d\n", (int) b, n, line, 0,0,0); } else { Nprintf("!%d(%d)\n ", b - l->table, line,0,0,0,0); l->mpMutex->acquire(); b->refCnt++; l->mpMutex->release(); } #undef line } /* MpBuf_addRef, MpBuf_addRefX */
static int MpBuf_invalidX(MpBufPtr b, int forMods, int allocated, int line) { int n; MpBufPoolPtr p; if ((((unsigned int) b) < LowBufTable) || (((unsigned int) b) > HighBufTable)) { Zprintf("\nMpBuf_invalid(0x%X): Outside tables (line: %d)\n", (int) b, line, 0,0,0,0); return TRUE; } p = b->pPool; // $$$ could add a check that p points to one of the active pools... n = b - p->table; if ((n < 0 ) || (n > p->allocCnt)) { Zprintf("\nMpBuf_invalid(0x%X): Outside table (p=0x%X," " n=%d, t=0x%X) line: %d\n", (int) b, (int) p, n, (int) (p->table), line, 0); return TRUE; } if (forMods && (1 != b->refCnt)) { Zprintf("\nMpBuf_invalid(0x%X): reference count(%d) != 1 (line: %d)\n", (int) b, b->refCnt, line, 0,0,0); return TRUE; } if (allocated && (1 > b->refCnt)) { Zprintf("\nMpBuf_invalid(0x%X): reference count(%d) < 1 (line: %d)\n", (int) b, b->refCnt, line, 0,0,0); return TRUE; } return FALSE; }
OsStatus MpBuf_setContentLen(MpBufPtr b, int numBytes) { if (MpBuf_invalid(b, TRUE, TRUE)) { return OS_INVALID_ARGUMENT; } if ((numBytes < 0) || (numBytes > MpBuf_getByteLen(b))) { Zprintf("MpBuf_setContentLen(0x%X, %d): contentLen invalid (max=%d)\n", (int) b, numBytes, MpBuf_getByteLen(b), 0,0,0); return OS_INVALID_ARGUMENT; } b->contentLen = numBytes; return OS_SUCCESS; }
/* //////////////////////////// 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); }
STATUS MpBufPool_delete(MpBufPoolPtr pool, int force) { int i; int refs; MpBufPtr buf; if (NULL == pool) { return OS_SUCCESS; } if (NULL == pool->mpMutex) { free(pool); return OS_SUCCESS; } pool->mpMutex->acquire(); refs = 0; buf = pool->table; if (NULL != buf) { for (i=0; i<pool->allocCnt; i++) { refs += (0 == buf++->refCnt) ? 0 : 1; } } if (0 != refs) { if (0 == force) { return OS_BUSY; } else { Zprintf("MpBufPool_delete(0x%X): %d buffers still in use!\n", (int) pool, refs, 0,0,0,0); } } if (NULL != pool->table) { free(pool->table); } pool->table = NULL; if (NULL != pool->MpBufPoolData) { free(pool->MpBufPoolData); } pool->MpBufPoolData = NULL; pool->mpMutex->release(); delete pool->mpMutex; free(pool); return OS_SUCCESS; }
OsStatus MpBuf_setNumSamples(MpBufPtr b, int num) { if (MpBuf_invalid(b, TRUE, TRUE)) { return OS_INVALID_ARGUMENT; } if ((num < 0) || (num > MpBuf_getByteLen(b))) { Zprintf("MpBuf_setNumSamples(0x%X, %d): numSamples invalid (max=%d)\n", (int) b, num, MpBuf_getByteLen(b), 0,0,0); return OS_INVALID_ARGUMENT; } // $$$ Should we make sure that the num is consistent with the // alignment requirements of the payload type? b->numSamples = num; return OS_SUCCESS; }
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; }
void dump1Buf(MpBufPtr t) { #ifdef BUFFER_INSTRUMENTATION /* [ */ MpBufPoolPtr l = t->pPool; int i; char str[80], state; OsLock lock(*(t->pPool->mpMutex)); i = t - l->table; switch (t->status) { case 0: state = '-'; break; case 1: state = '+'; break; default: state = '!'; break; } sprintf(str, "%3d: %c 0x%X->0x%X %4d(%06d)", i, state, (int) t, (int) t->pStorage, t->line_taken, t->time_taken); Zprintf("%s %4d(%06d) %4d(%06d)\n", (int) str, t->line_freed, t->time_freed, t->touched_by, t->touched_at, 0); #endif /* BUFFER_INSTRUMENTATION ] */ }
intptr_t showMpMisc(int justAddress) { Zprintf("&MpMisc = 0x%X\n", (int) &MpMisc, 0,0,0,0,0); if (!justAddress) { Zprintf(" MicQ=0x%X, SpkQ=0x%X, EchoQ=0x%X, silence=0x%X\n" (int) MpMisc.pMicQ, (int) MpMisc.pSpkQ, (int) MpMisc.pEchoQ, (int) MpMisc.mpFgSilence, 0, 0, 0); Zprintf(" \n frameSamples=%d, frameBytes=%d, sampleBytes=%d,", MpMisc.frameSamples, MpMisc.frameBytes, MpMisc.sampleBytes, 0,0,0); Zprintf(" rtpMaxBytes=%d\n RawAudioPool=0x%X, RtpPool=0x%X, RtcpPool=0x%X\n", MpMisc.rtpMaxBytes, (int) MpMisc.RawAudioPool, (int) MpMisc.RtpPool, (int) MpMisc.RtcpPool, 0,0); #ifdef _VXWORKS /* [ */ Zprintf(" mem_page_size=%d, mem_page_mask=0x%08X\n" "LogQ=0x%X, logMsgLimit=%d, logMsgSize=%d\n", MpMisc.mem_page_size, MpMisc.mem_page_mask, (int) MpMisc.LogQ, MpMisc.logMsgLimit, MpMisc.logMsgSize, 0); #endif /* _VXWORKS ] */ Zprintf(" Latency: maxMic=%d, maxSpkr=%d" MpMisc.max_mic_buffers, MpMisc.max_spkr_buffers, 0,0,0,0,0); } return (intptr_t) &MpMisc; }
OsStatus MpBuf_init(int samplesPerFrame, int numAudioBuffers) { LowBufTable = 0xffffffff; HighBufTable = 0; #ifdef BUFFER_INSTRUMENTATION /* [ */ spCounterMutex = new OsMutex(OsMutex::Q_PRIORITY); #endif /* BUFFER_INSTRUMENTATION ] */ MpMisc.UcbPool = MpBufPool_MpBufPool(0, samplesPerFrame*sizeof(Sample), numAudioBuffers, 0); Nprintf("MpBuf_init: MpMisc.UcbPool = 0x%X\n", (int) MpMisc.UcbPool, 0,0,0,0,0); if (NULL == MpMisc.UcbPool) { return OS_NO_MEMORY; } MpMisc.DMAPool = MpBufPool_MpBufPool(0, 8*samplesPerFrame*sizeof(Sample), 64, 32); Nprintf("MpBuf_init: MpMisc.DMAPool = 0x%X\n", (int) MpMisc.DMAPool, 0,0,0,0,0); if (NULL == MpMisc.DMAPool) { return OS_NO_MEMORY; } /*************************************************************************/ /* * Go get a buffer and fill with silence. We will use this for muting * either or both of input and output, and whenever we are starved for * audio data. */ #ifdef N_SPARE_BUFS /* [ */ /* For debugging... get a few buffers and set them aside... */ { MpBufPtr sb; int i, j, n; Sample* dst; for (i=0; i<N_SPARE_BUFS; i++) { sb = MpBuf_getBuf(MpMisc.UcbPool, samplesPerFrame, 0, MP_FMT_T12); if (NULL == sb) { Zprintf("\n\nMpBuf_init: MpBuf_getBuf failed, quitting!\n\n\n", 0,0,0,0,0,0); MpBufPool_delete(MpMisc.UcbPool, 1); MpMisc.UcbPool = NULL; return OS_LIMIT_REACHED; } dst = MpBuf_getSamples(sb); n = MpBuf_getByteLen(sb) / sizeof(Sample); MpBuf_setNumSamples(sb, n); for (j=0; j<n; j++) { *dst++ = (i<<8) + j; } MpBuf_setSpeech(sb, (enum MpBufSpeech) MP_SPEECH_SPARE); spareBufs[i] = sb; } showSpareBufs(0, "MpBuf_Init: "); } #endif /* N_SPARE_BUFS ] */ { MpBufPtr sb; sb = MpBuf_getBuf(MpMisc.UcbPool, samplesPerFrame, 0, MP_FMT_T12); if (NULL == sb) { Zprintf("\n\nMpBuf_init: MpBuf_getBuf failed, quitting!\n\n\n", 0,0,0,0,0,0); MpBufPool_delete(MpMisc.UcbPool, 1); MpMisc.UcbPool = NULL; return OS_LIMIT_REACHED; } memset(MpBuf_getSamples(sb), 0, MpBuf_getByteLen(sb)); MpBuf_setSpeech(sb, MP_SPEECH_SILENT); MpMisc.XXXsilence = sb; Zprintf("MpBuf_init: MpMisc.silence = 0x%X\n", (int) MpMisc.XXXsilence, 0,0,0,0,0); } /*************************************************************************/ /* * Go get a DMA buffer and fill with silence. We will use this for muting * either or both of input and output, and whenever we are starved for * audio data. */ { MpBufPtr sb; sb = MpBuf_getBuf(MpMisc.DMAPool, 8*samplesPerFrame, 0, MP_FMT_T12); if (NULL == sb) { Zprintf("\n\nMpBuf_init: MpBuf_getBuf failed (DMA), quitting!\n\n\n", 0,0,0,0,0,0); MpBufPool_delete(MpMisc.DMAPool, 1); MpMisc.DMAPool = NULL; return OS_LIMIT_REACHED; } memset(MpBuf_getSamples(sb), 0, MpBuf_getByteLen(sb)); MpBuf_setSpeech(sb, MP_SPEECH_SILENT); MpMisc.XXXlongSilence = sb; Zprintf("MpBuf_init: MpMisc.longSilence = 0x%X\n", (int) MpMisc.XXXlongSilence, 0,0,0,0,0); } /*************************************************************************/ /* * generate a buffer called comfort noise buffer. Even though the zero * initiation is not necessary, we do it as the silence buffer for safety. */ { MpBufPtr cnb; cnb = MpBuf_getBuf(MpMisc.UcbPool, samplesPerFrame, 0, MP_FMT_T12); if (NULL == cnb) { Zprintf("\n\nMpBuf_init: MpBuf_getBuf failed, quitting!\n\n\n", 0,0,0,0,0,0); MpBufPool_delete(MpMisc.UcbPool, 1); MpMisc.UcbPool = NULL; return OS_LIMIT_REACHED; } memset(MpBuf_getSamples(cnb), 0, MpBuf_getByteLen(cnb)); MpBuf_setSpeech(cnb, MP_SPEECH_COMFORT_NOISE); MpMisc.comfortNoise = cnb; Zprintf("MpBuf_init: MpMisc.comfortNoise = 0x%X\n", (int) MpMisc.comfortNoise, 0,0,0,0,0); } /*************************************************************************/ 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; }
OsStatus mpStartUp(int sampleRate, int samplesPerFrame, int numAudioBuffers, OsConfigDb* pConfigDb, const size_t numCodecPaths, const UtlString codecPaths[]) { // TODO: // This should be broken down into separate arguments for: // Max number of flowgraphs // Max number of calls // Max calls/streams per flowgraph // Buffers used/stream or used/flowgraph // Approximate based upon current media interface initialization int maxCalls = numAudioBuffers / 16; #ifdef _VXWORKS int defSilenceSuppressLevel = 10000; #else int defSilenceSuppressLevel = 0; #endif OsStatus resCode; UtlBoolean silenceSuppressFlag; UtlString silenceSuppressEnable; int silenceSuppressLevel; assert(samplesPerFrame >= 8); showMpMisc(TRUE); RTL_START(100000000); setExternalRtlCollector(sRealtimeLogCollector); // First initialize static codecs mpStaticCodecInitializer(); MpCodecFactory* pcf = MpCodecFactory::getMpCodecFactory(); if(numCodecPaths != 0) { size_t i; for(i = 0; i < numCodecPaths; i++) { pcf->loadAllDynCodecs(codecPaths[i].data(), CODEC_PLUGINS_FILTER); } } else { pcf->loadAllDynCodecs(CODEC_PLUGIN_PATH, CODEC_PLUGINS_FILTER); } #ifdef _VXWORKS /* [ */ /* Rashly assumes page size is a power of two */ MpMisc.mem_page_size = goGetThePageSize(); MpMisc.mem_page_mask = MpMisc.mem_page_size - 1; #endif /* _VXWORKS ] */ MpMisc.sampleBytes = sizeof(MpAudioSample); MpMisc.frameSamples = samplesPerFrame; MpMisc.frameBytes = MpMisc.sampleBytes * MpMisc.frameSamples; MpMisc.rtpMaxBytes = /* sizeof(struct RtpHeader) */ 12 + (((sampleRate + 24) / 25) * MpMisc.sampleBytes); // Create buffer for audio data in mediagraph MpMisc.RawAudioPool = new MpBufPool( samplesPerFrame*sizeof(MpAudioSample) + MpArrayBuf::getHeaderSize(), numAudioBuffers, "RawAudioPool"); Nprintf( "mpStartUp: MpMisc.RawAudioPool = 0x%X\n" , (int) MpMisc.RawAudioPool, 0,0,0,0,0); if (NULL == MpMisc.RawAudioPool) { return OS_NO_MEMORY; } // Create buffer for audio headers int audioBuffers = MpMisc.RawAudioPool->getNumBlocks(); MpMisc.AudioHeadersPool = new MpBufPool(sizeof(MpAudioBuf), audioBuffers, "AudioHeadersPool"); Nprintf( "mpStartUp: MpMisc.AudioHeadersPool = 0x%X\n" , (int) MpMisc.AudioHeadersPool, 0,0,0,0,0); if (NULL == MpMisc.AudioHeadersPool) { // TODO:: Think about proper resource deallocation on fail in mpStartUp() return OS_NO_MEMORY; } MpAudioBuf::smpDefaultPool = MpMisc.AudioHeadersPool; /* * Go get a buffer and fill with silence. We will use this for muting * either or both of input and output, and whenever we are starved for * audio data. */ { MpAudioBufPtr sb = MpMisc.RawAudioPool->getBuffer(); if (!sb.isValid()) { Zprintf("\n\mpStartUp:" " MpBufPool::getBuffer() failed, quitting!\n\n\n", 0,0,0,0,0,0); delete MpMisc.RawAudioPool; MpMisc.RawAudioPool = NULL; return OS_LIMIT_REACHED; } sb->setSamplesNumber(samplesPerFrame); memset(sb->getSamplesWritePtr(), 0, sb->getSamplesNumber()*sizeof(MpAudioSample)); sb->setSpeechType(MP_SPEECH_SILENT); MpMisc.mpFgSilence = sb; Zprintf("mpStartUp: MpMisc.silence = 0x%X\n", (int) MpMisc.mpFgSilence, 0,0,0,0,0); }
MpBufPoolPtr MpBufPool_MpBufPool(int poolSize, int maxBufferLen, int numBuffers, int cacheAlign) { int i; int n; int totalBytes; int numBufs; int numBytes; int bufBytes; char *b; char *storage; MpBufPoolPtr pool; MpBufPtr bufs; #ifdef BUFFER_INSTRUMENTATION /* [ */ if (20 > bufferPoolCreates++) { Zprintf("MpBufPool_MpBufPool(%d, %d, %d, %d)\n", poolSize, maxBufferLen, numBuffers, cacheAlign, 0,0); } #endif /* BUFFER_INSTRUMENTATION ] */ pool = (MpBufPoolPtr) malloc(sizeof(MpBufPool)); if (NULL == pool) { Zprintf("MpBufPool: unable to malloc %d bytes!\n", sizeof(MpBufPool), 0,0,0,0,0); return NULL; } memset((char *) pool, 0, sizeof(MpBufPool)); pool->cacheAlignment = cacheAlign; pool->mpMutex = new OsMutex(OsMutex::Q_PRIORITY); if (NULL == pool->mpMutex) { Zprintf("MpBufPool: unable to create Mutex!\n", 0,0,0,0,0,0); free(pool); return NULL; } pool->mpMutex->acquire(); numBufs = poolSize / maxBufferLen; if (numBufs < MIN_BUFFER_COUNT) { numBufs = numBuffers; } if (numBufs < MIN_BUFFER_COUNT) { Zprintf("MpBufPool: request to create %d buffers: too few (<%d)\n", numBufs, MIN_BUFFER_COUNT, 0,0,0,0); pool->mpMutex->release(); delete pool->mpMutex; free(pool); return NULL; } totalBytes = numBufs * sizeof(MpBuf); bufs = (MpBufPtr) malloc(totalBytes); if (NULL == bufs) { Zprintf("MpBufPool: unable to malloc %d bytes!\n", numBufs * sizeof(MpBuf), 0,0,0,0,0); pool->mpMutex->release(); delete pool->mpMutex; free(pool); return NULL; } memset((char *) bufs, 0, totalBytes); pool->table = bufs; if (((unsigned int) bufs) < LowBufTable) { LowBufTable = (unsigned int) bufs; } if (((unsigned int) (bufs + numBufs)) > HighBufTable) { HighBufTable = (unsigned int) (bufs + numBufs); } if (0 == cacheAlign) { bufBytes = maxBufferLen; numBytes = numBufs * bufBytes; } else { /* * The number of bytes in each buffer must be a * multiple of the data cache line size */ /* round up the buffer size, and the total buffer space */ i = (maxBufferLen + cacheAlign - 1) / cacheAlign; bufBytes = cacheAlign * i; numBytes = numBufs * bufBytes + cacheAlign - 1; } storage = (char *) malloc(numBytes); if (NULL == storage) { Zprintf("MpBufPool: unable to malloc %d bytes!\n", numBytes, 0,0,0,0,0); free(bufs); pool->mpMutex->release(); delete pool->mpMutex; free(pool); return NULL; } pool->MpBufPoolData = storage; totalBytes += numBytes; pool->eachLen = bufBytes; pool->size = sizeof(MpBufPool); pool->allocCnt = numBufs; pool->allocSize = totalBytes; pool->maxAllocCnt = 0; pool->maxAllocSize = 0; pool->lastTaken = 0; if (0 == cacheAlign) { b = storage; } else { /* round up the base of the first buffer */ i = (unsigned int) storage; n = i % cacheAlign; if (0 != n) { n = cacheAlign - n; } b = storage + n; } #ifdef BUFFER_INSTRUMENTATION /* [ */ if (20 > bufferPoolCreates) { Zprintf("buffer data base address = 0x%X (0x%X) (%d)\n", (int) b, (int) (pool->MpBufPoolData), b - (char *)(pool->MpBufPoolData), 0,0,0); } #endif /* BUFFER_INSTRUMENTATION ] */ init_bufs(numBufs, bufBytes, pool, b, bufs); #ifdef BUFFER_INSTRUMENTATION /* [ */ pool->nfree = numBufs; pool->minfree = numBufs; if (20 > bufferPoolCreates) { #ifdef _VXWORKS /* [ */ int x; x = StartLogging(); #endif /* _VXWORKS ] */ dumpBufs(1); #ifdef _VXWORKS /* [ */ if (0 == x) StopLogging(0); #endif /* _VXWORKS ] */ } #endif /* BUFFER_INSTRUMENTATION ] */ pool->mpMutex->release(); return pool; }
// Handle the FLOWGRAPH_REMOVE_RESOURCE message. // Returns TRUE if the message was handled, otherwise FALSE. UtlBoolean MpFlowGraphBase::handleRemoveResource(MpResource* pResource) { UtlBoolean found; int i; UtlString* pDictKey; UtlString* pKey; // make sure this resource is part of this flow graph if (pResource->getFlowGraph() != this) { Zprintf("handleRemoveResource:\n" " pResource=0x%p, pResource->getFlowGraph()=0x%p, this=0x%p\n", pResource, (pResource->getFlowGraph()), this, 0,0,0); assert(FALSE); return FALSE; } // remove all input links from this resource if (disconnectAllInputs(pResource) == FALSE) { assert(FALSE); return FALSE; } // remove all output links from this resource if (disconnectAllOutputs(pResource) == FALSE) { assert(FALSE); return FALSE; } // remove the entry from the dictionary for this resource OsSysLog::add(FAC_MP, PRI_DEBUG, "MpFlowGraphBase::handleRemoveResource %s\n", pResource->getName().data()); pKey = new UtlString(pResource->getName()); pDictKey = (UtlString*) mResourceDict.remove(pKey); delete pKey; if (pDictKey == NULL) { assert(FALSE); // no entry found for the resource return FALSE; } delete pDictKey; // get rid of the dictionary key for the entry // remove the resource from the unsorted array of resources for this graph found = FALSE; for (i=0; i < mResourceCnt; i++) { if (found) { // shift entries following the mUnsorted[i-1] = mUnsorted[i]; // deleted resource down by one } else if (mUnsorted[i] == pResource) { found = TRUE; mUnsorted[i] = NULL; // clear the entry } } if (!found) { assert(FALSE); // didn't find the entry return FALSE; } pResource->setFlowGraph(NULL); // remove the reference to this flow graph mResourceCnt--; mUnsorted[mResourceCnt] = NULL; mRecomputeOrder = TRUE; return TRUE; }
int MprToNet::writeRtp(int payloadType, UtlBoolean markerState, unsigned char* payloadData, int payloadOctets, unsigned int timestamp, void* csrcList) { struct rtpHeader* ph; int pad, l; int sendret; int len; ph = (struct rtpHeader*) (payloadData - sizeof(struct rtpHeader));//$$$ //$$$ Line above will need to adjust for CSRC list someday... len = payloadOctets; Lprintf("Enter rW: %d, %d\n", len, timestamp, 0,0,0,0); if (NULL == mpRtpSocket) {return 0;} mSeqNum++; #ifdef DEBUG /* [ */ if (NumberOfRtpWrites++ < 10) Zprintf("rW: %d, %d, %d\n", len, ts, h->mpt, 0,0,0); #endif /* DEBUG ] */ ph->vpxcc = 2<<6; // h->vpxcc; ph->mpt = (payloadType & 0x7f) | (markerState ? 0x80 : 0); ph->seq = htons(0xffff&mSeqNum); ph->timestamp = htonl(mTimestampDelta + timestamp); ph->ssrc = mSSRC; #ifdef ENABLE_PACKET_HACKING /* [ */ adjustRtpPacket(ph); #endif /* ENABLE_PACKET_HACKING ] */ pad = doPadRtp ? ((4 - (3 & len)) & 3) : 0; switch (pad) { case 3: payloadData[len+1] = 0; /* fall through */ case 2: payloadData[len] = 0; /* fall through */ case 1: payloadData[len+pad-1] = pad; ph->vpxcc |= (1<<5); Lprintf("writeRtp: adding %d pad bytes\n", pad, 0,0,0,0,0); /* fall through */ case 0: break; } #ifdef INCLUDE_RTCP /* [ */ // Update the Accumulated statistics kept for an inbound RTP packet. // These statistics comprise a Sender Report that is sent out periodically // to the originating site mpiRTPAccumulator->IncrementCounts(len); #endif /* INCLUDE_RTCP ] */ l = sizeof(struct rtpHeader) + len + pad; #ifdef DROP_SOME_PACKETS /* [ */ if (dropCount++ == dropLimit) { dropCount = 0; sendret = l; } else { sendret = mpRtpSocket->write((char *) ph, l); } #else /* DROP_SOME_PACKETS ] [*/ sendret = mpRtpSocket->write((char *) ph, l); #endif /* DROP_SOME_PACKETS ] */ if (l != sendret) { if (5 > mNumRtpWriteErrors++) { Zprintf("Exit rW: send(0x%p 0x%p %d) returned %d," " errno=%d (at %d)\n", mpRtpSocket, ph, l, sendret, errno, *pOsTC); } switch (errno) { /* insert other benign errno values here */ case 0: case 55: // Network disconnected, continue and hope it comes back break; default: // close(fd); MAYBE: mpRtpSocket->close() ? // mpRtpSocket = NULL; break; } } return (l == sendret) ? len : sendret; }
int showBufs(MpBufPoolPtr l, int line) { int i, col, num_used = 0; int i0, i1, i2, i3, i4, i5; const char *fmt; #ifdef _VXWORKS /* [ */ static int last_counter = 0; #endif /* _VXWORKS ] */ if (0 == l) l = MpMisc.UcbPool; i0 = i1 = i2 = i3 = i4 = i5 = 0; #ifdef _VXWORKS /* [ */ i = *pOsTC; Zprintf("%d:(0x%08X-0x%08X)\n ", line, i, i - last_counter, 0,0,0); last_counter = i; #else /* _VXWORKS ] */ Zprintf("%d:\n ", line, 0,0,0,0,0); #endif /* _VXWORKS ] */ col = 0; for (i=0; i<l->allocCnt; ) { switch(l->allocCnt - i) { case 1: fmt = "%d\n"; i0 = l->table[i++].status; break; case 2: fmt = "%d%d\n"; i0 = l->table[i++].status; i1 = l->table[i++].status; break; case 3: fmt = "%d%d%d\n"; i0 = l->table[i++].status; i1 = l->table[i++].status; i2 = l->table[i++].status; break; case 4: fmt = "%d%d%d%d\n"; i0 = l->table[i++].status; i1 = l->table[i++].status; i2 = l->table[i++].status; i3 = l->table[i++].status; break; case 5: fmt = "%d%d%d%d%d\n"; i0 = l->table[i++].status; i1 = l->table[i++].status; i2 = l->table[i++].status; i3 = l->table[i++].status; i4 = l->table[i++].status; break; case 6: fmt = "%d%d%d%d%d%d\n"; i0 = l->table[i++].status; i1 = l->table[i++].status; i2 = l->table[i++].status; i3 = l->table[i++].status; i4 = l->table[i++].status; i5 = l->table[i++].status; break; default: fmt = "%d%d%d%d%d%d"; i0 = l->table[i++].status; i1 = l->table[i++].status; i2 = l->table[i++].status; i3 = l->table[i++].status; i4 = l->table[i++].status; i5 = l->table[i++].status; break; } col += Zprintf(fmt, i0, i1, i2, i3, i4, i5) + 0; if (col > 70) { col = Zprintf("\n ", 0,0,0,0,0,0) - 1; } } for (i=0; i<l->allocCnt; ) { if (l->table[i++].status) num_used++; } return num_used; }
UtlBoolean MprBridge::doProcessFrame(MpBufPtr inBufs[], MpBufPtr outBufs[], int inBufsSize, int outBufsSize, UtlBoolean isEnabled, int samplesPerFrame, int samplesPerSecond) { int i; int inIdx; int outIdx; int n; int scale; int inputs; int N = samplesPerFrame; MpBufPtr in; MpBufPtr out; Sample* input; Sample* output; Sample* outstart; if (0 == outBufsSize) { Zprintf("MprBridge::doPF: outBufsSize = %d! (inBufsSize=%d)\n", outBufsSize, inBufsSize, 0,0,0,0); return FALSE; } if (inBufsSize != outBufsSize) { Zprintf("MprBridge::doPF: outBufsSize(%d) != inBufsSize(%d)\n", outBufsSize, inBufsSize, 0,0,0,0); return FALSE; } if (0 == inBufsSize) return FALSE; // no input buffers, not allowed for (i=0; i < outBufsSize; i++) { outBufs[i] = NULL; } if (!isEnabled) { // Disabled. Mix all remote inputs onto local speaker, and copy // our local microphone to all remote outputs. // First, count how many contributing inputs inputs = 0; for (inIdx=1; inIdx < inBufsSize; inIdx++) { if (isPortActive(inIdx)) { if((MpBuf_getSpeech(inBufs[inIdx]) != MP_SPEECH_SILENT) && (MpBuf_getSpeech(inBufs[inIdx]) != MP_SPEECH_COMFORT_NOISE)) inputs++; } } if (inputs > 0) { // Compute a scale factor to renormalize (approximately) scale = 0; while (inputs > 1) { scale++; inputs = inputs >> 1; } out = MpBuf_getBuf(MpMisc.UcbPool, N, 0, MP_FMT_T12); if (NULL == out) { Zprintf( "MprBridge::doPF(line #%d): MpBuf_getBuf() returned NULL!\n", __LINE__, 0,0,0,0,0); return FALSE; } outstart = MpBuf_getSamples(out); memset((char *) outstart, 0, N * sizeof(Sample)); for (inIdx=1; inIdx < inBufsSize; inIdx++) { if (isPortActive(inIdx)) { output = outstart; //Mix only non-silent audio if((MpBuf_getSpeech(inBufs[inIdx]) != MP_SPEECH_COMFORT_NOISE) && (MpBuf_getSpeech(inBufs[inIdx]) != MP_SPEECH_SILENT) ) { input = MpBuf_getSamples(inBufs[inIdx]); n = min(MpBuf_getNumSamples(inBufs[inIdx]), samplesPerFrame); for (i=0; i<n; i++) *output++ += (*input++) >> scale; } } }