static int create_packed_conf(EncState *s){ ogg_packet p; theora_state *tstate=&s->tstate; mblk_t *h,*t; if (theora_encode_header(tstate,&p)!=0){ ms_error("theora_encode_header() error."); return -1; } h=allocb(p.bytes,0); memcpy(h->b_wptr,p.packet,p.bytes); h->b_wptr+=p.bytes; if (theora_encode_tables(tstate,&p)!=0){ ms_error("theora_encode_tables error."); freemsg(h); return -1; } t=allocb(p.bytes,0); memcpy(t->b_wptr,p.packet,p.bytes); t->b_wptr+=p.bytes; h->b_cont=t; msgpullup(h,-1); s->packed_conf=h; return 0; }
/* * Put XOFF/ XON message on write queue * * Requires Lock (( M: Mandatory, P: Prohibited, A: Allowed )) * -. uinst_t->lock : M [RW_READER or RW_WRITER] * -. uinst_t->u_lock : A * -. uinst_t->l_lock : A * -. uinst_t->c_lock : A */ int oplmsu_cmn_put_xoffxon(queue_t *queue, int data) { mblk_t *mp; int rval = SUCCESS; /* Send M_START */ if ((mp = allocb(0, BPRI_LO)) != NULL) { mp->b_datap->db_type = M_START; putq(queue, mp); /* Send M_DATA(XOFF, XON) */ if ((mp = allocb(sizeof (int), BPRI_LO)) != NULL) { *(uint_t *)mp->b_rptr = data; mp->b_wptr = mp->b_rptr + sizeof (int); putq(queue, mp); } else { rval = FAILURE; } } else { rval = FAILURE; } return (rval); }
mblk_t* ms_yuv_buf_alloc_from_buffer(int w, int h, mblk_t* buffer) { const int header_size =sizeof(mblk_video_header); mblk_t *msg=allocb(header_size,0); // write width/height in header mblk_video_header* hdr = (mblk_video_header*)msg->b_wptr; hdr->w = w; hdr->h = h; msg->b_rptr += header_size; msg->b_wptr += header_size; // append real image buffer msg->b_cont = buffer; buffer->b_datap->db_ref++; return msg; }
mblk_t * ms_yuv_buf_alloc(YuvBuf *buf, int w, int h){ int size=(w*h*3)/2; const int header_size =sizeof(mblk_video_header); const int padding=16; mblk_t *msg=allocb(header_size + size+padding,0); // write width/height in header mblk_video_header* hdr = (mblk_video_header*)msg->b_wptr; hdr->w = w; hdr->h = h; msg->b_rptr += header_size; msg->b_wptr += header_size; yuv_buf_init(buf,w,h,msg->b_wptr); msg->b_wptr+=size; return msg; }
mblk_t * ms_yuv_buf_alloc(YuvBuf *buf, int w, int h){ int size=(w * (h & 0x1 ? h+1 : h) *3)/2; /*swscale doesn't like odd numbers of line*/ const int header_size = sizeof(mblk_video_header); const int padding=16; mblk_t *msg=allocb(header_size + size+padding,0); // write width/height in header mblk_video_header* hdr = (mblk_video_header*)msg->b_wptr; hdr->w = w; hdr->h = h; msg->b_rptr += header_size; msg->b_wptr += header_size; yuv_buf_init(buf,w,h,msg->b_wptr); msg->b_wptr+=size; return msg; }
static mblk_t *crop_or_pad(V4lState *s, mblk_t *pic){ int size=s->vsize.width*s->vsize.height; mblk_t *newpic; if (s->pix_fmt==MS_YUV420P) size=size*3/2; else if (s->pix_fmt==MS_YUYV) size=size*2; else if (s->pix_fmt==MS_UYVY) size=size*2; else if (s->pix_fmt==MS_RGB24) size=size*3; else ms_fatal("crop_or_pad: unsupported pixel format."); newpic=allocb(size,0); memset(newpic->b_wptr,0,size); pic_copy(newpic->b_wptr, s->vsize.width, s->vsize.height, pic->b_rptr,s->got_vsize.width,s->got_vsize.height,s->pix_fmt); newpic->b_wptr+=size; return newpic; }
static void volume_process(MSFilter *f){ mblk_t *m; Volume *v=(Volume*)f->data; float target_gain; /* Important notice: any processes called herein can modify v->target_gain, at * end of this function apply_gain() is called, thus: later process calls can * override this target gain, and order must be well thought out */ if (v->agc_enabled || v->peer!=NULL){ mblk_t *om; int nbytes=v->nsamples*2; ms_bufferizer_put_from_queue(v->buffer,f->inputs[0]); while(ms_bufferizer_get_avail(v->buffer)>=nbytes){ om=allocb(nbytes,0); ms_bufferizer_read(v->buffer,om->b_wptr,nbytes); om->b_wptr+=nbytes; update_energy((int16_t*)om->b_rptr, v->nsamples, v); target_gain = v->static_gain; if (v->peer) /* this ptr set = echo limiter enable flag */ target_gain = volume_echo_avoider_process(v, om); /* Multiply with gain from echo limiter, not "choose smallest". Why? * Remote talks, local echo suppress via mic path, but still audible in * remote speaker. AGC operates fully, too (local speaker close to local mic!); * having agc gain reduction also contribute to total reduction makes sense. */ if (v->agc_enabled) target_gain/= volume_agc_process(v, om); if (v->noise_gate_enabled) volume_noise_gate_process(v, v->level_pk, om); apply_gain(v, om, target_gain); ms_queue_put(f->outputs[0],om); } }else{ /*light processing: no agc. Work in place in the input buffer*/ while((m=ms_queue_get(f->inputs[0]))!=NULL){ update_energy((int16_t*)m->b_rptr, (m->b_wptr - m->b_rptr) / 2, v); target_gain = v->static_gain; if (v->noise_gate_enabled) volume_noise_gate_process(v, v->level_pk, m); apply_gain(v, m, target_gain); ms_queue_put(f->outputs[0],m); } } }
/* * got_errchunk is set B_TRUE only if called from validate_init_params(), when * an ERROR chunk is already prepended the size of which needs updating for * additional unrecognized parameters. Other callers either prepend the ERROR * chunk with the correct size after calling this function, or they are calling * to add an invalid parameter to an INIT_ACK chunk, in that case no ERROR chunk * exists, the CAUSE blocks go into the INIT_ACK directly. * * *errmp will be non-NULL both when adding an additional CAUSE block to an * existing prepended COOKIE ERROR chunk (processing params of an INIT_ACK), * and when adding unrecognized parameters after the first, to an INIT_ACK * (processing params of an INIT chunk). */ void sctp_add_unrec_parm(sctp_parm_hdr_t *uph, mblk_t **errmp, boolean_t got_errchunk) { mblk_t *mp; sctp_parm_hdr_t *ph; size_t len; int pad; sctp_chunk_hdr_t *ecp; len = sizeof (*ph) + ntohs(uph->sph_len); if ((pad = len % SCTP_ALIGN) != 0) { pad = SCTP_ALIGN - pad; len += pad; } mp = allocb(len, BPRI_MED); if (mp == NULL) { return; } ph = (sctp_parm_hdr_t *)(mp->b_rptr); ph->sph_type = htons(PARM_UNRECOGNIZED); ph->sph_len = htons(len - pad); /* copy in the unrecognized parameter */ bcopy(uph, ph + 1, ntohs(uph->sph_len)); if (pad != 0) bzero((mp->b_rptr + len - pad), pad); mp->b_wptr = mp->b_rptr + len; if (*errmp != NULL) { /* * Update total length if an ERROR chunk, then link * this CAUSE block to the possible chain of CAUSE * blocks attached to the ERROR chunk or INIT_ACK * being created. */ if (got_errchunk) { /* ERROR chunk already prepended */ ecp = (sctp_chunk_hdr_t *)((*errmp)->b_rptr); ecp->sch_len = htons(ntohs(ecp->sch_len) + len); } linkb(*errmp, mp); } else { *errmp = mp; } }
mblk_t * resize_yuv_small(unsigned char *pict, int w, int h, int scale){ int i,j,id,jd; int nh,nw; unsigned char *smallpict; int ysize,usize,ydsize,udsize; int smallpict_sz; unsigned char *dptr,*sptr; mblk_t *smallb; nw=w/scale; nh=h/scale; ysize=w*h; usize=ysize/4; ydsize=nw*nh; udsize=ydsize/4; smallpict_sz=(ydsize*3)/2; smallb=allocb(smallpict_sz,0); smallpict=smallb->b_wptr; smallb->b_wptr+=smallpict_sz; dptr=smallpict; sptr=pict; for (j=0,jd=0;j<nh;j++,jd+=scale){ for (i=0,id=0;i<nw;i++,id+=scale){ dptr[(j*nw) + i]=sptr[(jd*w)+id]; } } nh=nh/2; nw=nw/2; w=w/2; h=h/2; dptr+=ydsize; sptr+=ysize; for (j=0,jd=0;j<nh;j++,jd+=scale){ for (i=0,id=0;i<nw;i++,id+=scale){ dptr[(j*nw) + i]=sptr[(jd*w)+id]; } } dptr+=udsize; sptr+=usize; for (j=0,jd=0;j<nh;j++,jd+=scale){ for (i=0,id=0;i<nw;i++,id+=scale){ dptr[(j*nw) + i]=sptr[(jd*w)+id]; } } return smallb; }
/* given a queue, makes a single block with header_len reserved space in the * block main body, and the contents of [offset, len + offset) pointed to in the * new blocks ext_data. */ struct block *qclone(struct queue *q, int header_len, int len, uint32_t offset) { int ret; struct block *newb = allocb(header_len); /* the while loop should rarely be used: it would require someone * concurrently adding to the queue. */ do { /* TODO: RCU: protecting the q list (b->next) (need read lock) */ spin_lock_irqsave(&q->lock); ret = __blist_clone_to(q->bfirst, newb, len, offset); spin_unlock_irqsave(&q->lock); if (ret) block_add_extd(newb, ret, KMALLOC_WAIT); } while (ret); return newb; }
/* * Allocate a message block * * Requires Lock (( M: Mandatory, P: Prohibited, A: Allowed )) * -. uinst_t->lock : M [RW_READER] * -. uinst_t->u_lock : A * -. uinst_t->l_lock : P * -. uinst_t->c_lock : P */ int oplmsu_cmn_allocmb(queue_t *q, mblk_t *mp, mblk_t **nmp, size_t size, int rw_flag) { int rval = SUCCESS; ASSERT(RW_READ_HELD(&oplmsu_uinst->lock)); if ((*nmp = (mblk_t *)allocb(size, BPRI_LO)) == NULL) { oplmsu_cmn_bufcall(q, mp, size, rw_flag); rval = FAILURE; } else { (*nmp)->b_wptr = (*nmp)->b_rptr + size; } return (rval); }
void alsa_read_process(MSFilter *obj){ AlsaReadData *ad=(AlsaReadData*)obj->data; mblk_t *om=NULL; int samples=(160*ad->rate)/8000; ms_mutex_lock(&ad->mutex); while (ms_bufferizer_get_avail(ad->bufferizer)>=samples*2){ om=allocb(samples*2,0); ms_bufferizer_read(ad->bufferizer,om->b_wptr,samples*2); om->b_wptr+=samples*2; /*ms_message("alsa_read_process: Outputing %i bytes",size);*/ ms_queue_put(obj->outputs[0],om); } ms_mutex_unlock(&ad->mutex); }
struct block *devbread(struct chan *c, long n, uint32_t offset) { ERRSTACK(1); struct block *bp; bp = allocb(n); if (bp == 0) error(Enomem); if (waserror()) { freeb(bp); nexterror(); } bp->wp += devtab[c->type].read(c, bp->wp, n, offset); poperror(); return bp; }
Block* devbread(Chan *c, long n, ulong offset) { Block *bp; bp = allocb(n); if(bp == 0) error(Enomem); if(waserror()) { freeb(bp); nexterror(); } bp->wp += devtab[c->type]->read(c, bp->wp, n, offset); poperror(); return bp; }
static Block* allocfb(Frame *f) { int len; Block *b; len = f->nhdr + f->dlen; if(len < ETHERMINTU) len = ETHERMINTU; b = allocb(len); memmove(b->wp, f->hdr, f->nhdr); if(f->dlen) memmove(b->wp + f->nhdr, f->dp, f->dlen); b->wp += len; return b; }
/* * Download firmware or set register to the device by default ctrl pipe */ static int keyspan_write_memory(keyspan_pipe_t *pipe, uint16_t addr, uchar_t *buf, uint16_t len, uint8_t bRequest) { mblk_t *data; usb_ctrl_setup_t setup; usb_cb_flags_t cb_flags; usb_cr_t cr; uint8_t retry = 0; /* reuse previous mblk if possible */ if ((data = allocb(len, BPRI_HI)) == NULL) { return (USB_FAILURE); } bcopy(buf, data->b_rptr, len); setup.bmRequestType = USB_DEV_REQ_TYPE_VENDOR; /* This is a req defined by hardware vendor. */ setup.bRequest = bRequest; setup.wValue = addr; setup.wIndex = 0; setup.wLength = len; setup.attrs = 0; while (usb_pipe_ctrl_xfer_wait(pipe->pipe_handle, &setup, &data, &cr, &cb_flags, 0) != USB_SUCCESS) { /* KEYSPAN_RETRY */ if (++retry > 3) { if (data) { freemsg(data); } return (USB_FAILURE); } } if (data) { freemsg(data); } return (USB_SUCCESS); }
/* * copy from offset in the queue */ struct block *qcopy_old(struct queue *q, int len, uint32_t offset) { int sofar; int n; struct block *b, *nb; uint8_t *p; nb = allocb(len); spin_lock_irqsave(&q->lock); /* go to offset */ b = q->bfirst; for (sofar = 0;; sofar += n) { if (b == NULL) { spin_unlock_irqsave(&q->lock); return nb; } n = BLEN(b); if (sofar + n > offset) { p = b->rp + offset - sofar; n -= offset - sofar; break; } QDEBUG checkb(b, "qcopy"); b = b->next; } /* copy bytes from there */ for (sofar = 0; sofar < len;) { if (n > len - sofar) n = len - sofar; PANIC_EXTRA(b); memmove(nb->wp, p, n); qcopycnt += n; sofar += n; nb->wp += n; b = b->next; if (b == NULL) break; n = BLEN(b); p = b->rp; } spin_unlock_irqsave(&q->lock); return nb; }
// allocate buffer of newlen elements, placing old data at given offset (in #elts) // newlen: new length (#elts), including offset // oldlen: old length (#elts), excluding offset // offs: new offset static void array_resize_buffer(jl_array_t *a, size_t newlen, size_t oldlen, size_t offs) { size_t es = a->elsize; size_t nbytes = newlen * es; size_t offsnb = offs * es; size_t oldnbytes = oldlen * es; size_t oldoffsnb = a->offset * es; if (es == 1) nbytes++; assert(!a->isshared || a->how==3); char *newdata; if (a->how == 2) { // already malloc'd - use realloc newdata = (char*)jl_gc_managed_realloc((char*)a->data - oldoffsnb, nbytes, oldnbytes+oldoffsnb, a->isaligned, (jl_value_t*)a); if (offs != a->offset) { memmove(&newdata[offsnb], &newdata[oldoffsnb], oldnbytes); } } else { if ( #ifdef _P64 nbytes >= MALLOC_THRESH #else es > 4 #endif ) { newdata = (char*)jl_gc_managed_malloc(nbytes); jl_gc_track_malloced_array(a); a->how = 2; a->isaligned = 1; } else { newdata = (char*)allocb(nbytes); a->how = 1; } memcpy(newdata + offsnb, (char*)a->data, oldnbytes); } a->data = newdata + offsnb; a->isshared = 0; if (a->ptrarray || es==1) memset(newdata+offsnb+oldnbytes, 0, nbytes-oldnbytes-offsnb); if (a->how == 1) jl_gc_wb_buf(a, newdata); a->maxsize = newlen; }
/* * copy from offset in the queue */ Block* qcopy(Queue *q, int len, ulong offset) { int sofar; int n; Block *b, *nb; uchar *p; nb = allocb(len); ilock(q); /* go to offset */ b = q->bfirst; for(sofar = 0; ; sofar += n){ if(b == nil){ iunlock(q); return nb; } n = BLEN(b); if(sofar + n > offset){ p = b->rp + offset - sofar; n -= offset - sofar; break; } QDEBUG checkb(b, "qcopy"); b = b->next; } /* copy bytes from there */ for(sofar = 0; sofar < len;){ if(n > len - sofar) n = len - sofar; memmove(nb->wp, p, n); qcopycnt += n; sofar += n; nb->wp += n; b = b->next; if(b == nil) break; n = BLEN(b); p = b->rp; } iunlock(q); return nb; }
static void enc_process(MSFilter *f){ EncState *s=(EncState*)f->data; mblk_t *im; int16_t buf[160]; while((im=ms_queue_get(f->inputs[0]))!=NULL){ ms_bufferizer_put(s->bufferizer,im); } while(ms_bufferizer_read(s->bufferizer,(uint8_t*)buf,sizeof(buf))==sizeof(buf)) { mblk_t *om=allocb(33,0); gsm_encode(s->state,(gsm_signal*)buf,(gsm_byte*)om->b_wptr); om->b_wptr+=33; mblk_set_timestamp_info(om,s->ts); ms_queue_put(f->outputs[0],om); s->ts+=sizeof(buf)/2; } }
static void dtmfgen_process(MSFilter *f){ mblk_t *m; DtmfGenState *s=(DtmfGenState*)f->data; int nsamples; ms_filter_lock(f); if (ms_queue_empty(f->inputs[0])){ s->nosamples_time+=f->ticker->interval; if ((s->dtmf!=0 || s->silence!=0) && s->nosamples_time>NO_SAMPLES_THRESHOLD){ /*after 100 ms without stream we decide to generate our own sample instead of writing into incoming stream samples*/ nsamples=(f->ticker->interval*s->rate)/1000; m=allocb(nsamples*2,0); if (s->silence==0){ if (s->pos==0){ MSDtmfGenEvent ev; ev.tone_start_time=f->ticker->time; ev.tone_name[0]=s->dtmf; ev.tone_name[1]='\0'; ms_filter_notify(f,MS_DTMF_GEN_EVENT,&ev); } write_dtmf(s,(int16_t*)m->b_wptr,nsamples); }else{ memset(m->b_wptr,0,nsamples*2); s->silence-=f->ticker->interval; if (s->silence<0) s->silence=0; } m->b_wptr+=nsamples*2; ms_queue_put(f->outputs[0],m); } }else{ s->nosamples_time=0; if (s->interval > 0) { s->silence-=f->ticker->interval; if (s->silence<0) s->silence=0; } else s->silence=0; while((m=ms_queue_get(f->inputs[0]))!=NULL){ if (s->dtmf!=0 && s->silence==0){ nsamples=(m->b_wptr-m->b_rptr)/2; write_dtmf(s, (int16_t*)m->b_rptr,nsamples); } ms_queue_put(f->outputs[0],m); } } ms_filter_unlock(f); }
ssize_t sctp_link_abort(mblk_t *mp, uint16_t serror, char *details, size_t len, int iserror, boolean_t tbit) { size_t alen; mblk_t *amp; sctp_chunk_hdr_t *acp; sctp_parm_hdr_t *eph; ASSERT(mp != NULL && mp->b_cont == NULL); alen = sizeof (*acp) + (serror != 0 ? (sizeof (*eph) + len) : 0); amp = allocb(alen, BPRI_MED); if (amp == NULL) { return (-1); } amp->b_wptr = amp->b_rptr + alen; /* Chunk header */ acp = (sctp_chunk_hdr_t *)amp->b_rptr; acp->sch_id = iserror ? CHUNK_ERROR : CHUNK_ABORT; acp->sch_flags = 0; acp->sch_len = htons(alen); if (tbit) SCTP_SET_TBIT(acp); linkb(mp, amp); if (serror == 0) { return (alen); } eph = (sctp_parm_hdr_t *)(acp + 1); eph->sph_type = htons(serror); eph->sph_len = htons(len + sizeof (*eph)); if (len > 0) { bcopy(details, eph + 1, len); } /* XXX pad */ return (alen); }
/* Send dummy STUN packet to open NAT ports ASAP. */ static void send_stun_packet(RtpSession *s) { StunMessage msg; mblk_t *mp; char buf[STUN_MAX_MESSAGE_SIZE]; int len = STUN_MAX_MESSAGE_SIZE; memset(&msg, 0, sizeof(StunMessage)); stunBuildReqSimple(&msg, NULL, FALSE, FALSE, 1); len = stunEncodeMessage(&msg, buf, len, NULL); if (len > 0) { mp = allocb(len, BPRI_MED); memcpy(mp->b_wptr, buf, len); mp->b_wptr += len; rtp_session_sendm_with_ts(s, mp, 0); } }
static void x264_nals_to_msgb(x264_nal_t *xnals, int num_nals, MSQueue * nalus){ int i; mblk_t *m; /*int bytes;*/ for (i=0;i<num_nals;++i){ m=allocb(xnals[i].i_payload+10,0); memcpy(m->b_wptr,xnals[i].p_payload+4,xnals[i].i_payload-4); m->b_wptr+=xnals[i].i_payload-4; if (xnals[i].i_type==7) { ms_message("A SPS is being sent."); }else if (xnals[i].i_type==8) { ms_message("A PPS is being sent."); } ms_queue_put(nalus,m); } }
mblk_t *msgb_allocator_alloc(msgb_allocator_t *a, int size){ queue_t *q=&a->q; mblk_t *m,*found=NULL; /*lookup for an unused msgb (data block with ref count ==1)*/ for(m=qbegin(q);!qend(q,m);m=qnext(q,m)){ if (m->b_datap->db_ref==1 && m->b_datap->db_lim-m->b_datap->db_base>=size){ found=m; break; } } if (found==NULL){ found=allocb(size,0); putq(q,found); } return dupb(found); }
/* * get next block from a queue (up to a limit) */ struct block *qbread(struct queue *q, int len) { ERRSTACK(1); struct block *b, *nb; int n; qlock(&q->rlock); if (waserror()) { qunlock(&q->rlock); nexterror(); } spin_lock_irqsave(&q->lock); if (!qwait(q)) { /* queue closed */ spin_unlock_irqsave(&q->lock); qunlock(&q->rlock); poperror(); return NULL; } /* if we get here, there's at least one block in the queue */ b = qremove(q); n = BLEN(b); /* split block if it's too big and this is not a message queue */ nb = b; if (n > len) { PANIC_EXTRA(b); if ((q->state & Qmsg) == 0) { n -= len; b = allocb(n); memmove(b->wp, nb->rp + len, n); b->wp += n; qputback(q, b); } nb->wp = nb->rp + len; } /* restart producer */ qwakeup_iunlock(q); poperror(); qunlock(&q->rlock); return nb; }
static inline mblk_t * oce_rx_bcopy(struct oce_dev *dev, struct oce_rq *rq, struct oce_nic_rx_cqe *cqe) { mblk_t *mp; int pkt_len; int alloc_len; int32_t frag_cnt = 0; int frag_size; oce_rq_bdesc_t *rqbd; unsigned char *rptr; uint32_t cur_index; oce_ring_buffer_t *ring; oce_rq_bdesc_t **shadow_rq; int cnt = 0; _NOTE(ARGUNUSED(dev)); shadow_rq = rq->shadow_ring; pkt_len = cqe->u0.s.pkt_size; alloc_len = pkt_len + OCE_RQE_BUF_HEADROOM; frag_cnt = cqe->u0.s.num_fragments & 0x7; mp = allocb(alloc_len, BPRI_HI); if (mp == NULL) { return (NULL); } mp->b_rptr += OCE_RQE_BUF_HEADROOM; rptr = mp->b_rptr; mp->b_wptr = mp->b_rptr + pkt_len; ring = rq->ring; cur_index = ring->cidx; for (cnt = 0; cnt < frag_cnt; cnt++) { rqbd = shadow_rq[cur_index]; frag_size = (pkt_len > rq->cfg.frag_size) ? rq->cfg.frag_size : pkt_len; (void) DBUF_SYNC(rqbd->rqb, DDI_DMA_SYNC_FORCPU); bcopy(rqbd->rqb->base + OCE_RQE_BUF_HEADROOM, rptr, frag_size); rptr += frag_size; pkt_len -= frag_size; cur_index = GET_Q_NEXT(cur_index, 1, ring->num_items); } (void) oce_rq_charge(rq, frag_cnt, B_TRUE); return (mp); }
static void *alloc_array_buffer(size_t nbytes, int isunboxed) { void *data; if (nbytes > 0) { if (isunboxed) { data = alloc_pod(nbytes); } else { data = allocb(nbytes); memset(data, 0, nbytes); } } else { data = NULL; } return data; }
static void filter_process(MSFilter *f){ isac_decoder_t* obj = (isac_decoder_t*)f->data; mblk_t* im; int count = 0; im = ms_queue_get( f->inputs[0] ); while( im != NULL ){ decode(f, im); freemsg(im); count++; im = ms_queue_get( f->inputs[0] ); } if( ms_concealer_context_is_concealement_required(obj->plc_ctx, f->ticker->time) ) { WebRtc_Word16 flen = (obj->ptime == 30) ? ISAC_30MS_SAMPLE_COUNT : ISAC_60MS_SAMPLE_COUNT; mblk_t* plc_blk = allocb(flen*2, 0 ); // ms_message("PLC for %d ms", obj->ptime); // interpolate 1 frame for 30ms ptime, 2 frames for 60ms WebRtc_Word16 ret = WebRtcIsacfix_DecodePlc(obj->isac, (WebRtc_Word16*)plc_blk->b_wptr, (obj->ptime == 30) ? 1 : 2); if( ret < 0 ) { ms_error("WebRtcIsacfix_DecodePlc error: %d", WebRtcIsacfix_GetErrorCode(obj->isac) ); freeb(plc_blk); } else { plc_blk->b_wptr += ret*2; obj->seq_nb++; // insert this interpolated block into the output, with correct args: mblk_set_cseq(plc_blk, obj->seq_nb ); mblk_set_plc_flag(plc_blk, 1); // this one's a PLC packet ms_queue_put(f->outputs[0], plc_blk); ms_concealer_inc_sample_time(obj->plc_ctx, f->ticker->time, obj->ptime, FALSE); } } }
static void uftdi_rxerr_put(mblk_t **rx_mpp, mblk_t *data, uint8_t lsr) { uchar_t errflg; if (lsr & FTDI_LSR_STATUS_BI) { /* * parity and framing errors only "count" if they * occur independently of a break being received. */ lsr &= ~(uint8_t)(FTDI_LSR_STATUS_PE | FTDI_LSR_STATUS_FE); } errflg = ((lsr & FTDI_LSR_STATUS_OE) ? DS_OVERRUN_ERR : 0) | ((lsr & FTDI_LSR_STATUS_PE) ? DS_PARITY_ERR : 0) | ((lsr & FTDI_LSR_STATUS_FE) ? DS_FRAMING_ERR : 0) | ((lsr & FTDI_LSR_STATUS_BI) ? DS_BREAK_ERR : 0); /* * If there's no actual data, we send a NUL character along * with the error flags. Otherwise, the data mblk contains * some number of highly questionable characters. * * According to FTDI tech support, there is no synchronous * error reporting i.e. we cannot assume that only the * first character in the mblk is bad -- so we treat all * of them them as if they have the error noted in the LSR. */ do { mblk_t *mp; uchar_t c = (MBLKL(data) == 0) ? '\0' : *data->b_rptr++; if ((mp = allocb(2, BPRI_HI)) != NULL) { DB_TYPE(mp) = M_BREAK; *mp->b_wptr++ = errflg; *mp->b_wptr++ = c; uftdi_put_tail(rx_mpp, mp); } else { /* * low memory - just discard the bad data */ data->b_rptr = data->b_wptr; break; } } while (MBLKL(data) > 0); }