static void receiver_process(MSFilter * f) { ReceiverData *d = (ReceiverData *) f->data; mblk_t *m; uint32_t timestamp; if (d->session == NULL) return; if (d->reset_jb){ ms_message("Reseting jitter buffer"); rtp_session_resync(d->session); d->reset_jb=FALSE; } if (d->starting){ PayloadType *pt=rtp_profile_get_payload( rtp_session_get_profile(d->session), rtp_session_get_recv_payload_type(d->session)); if (pt && pt->type!=PAYLOAD_VIDEO) rtp_session_flush_sockets(d->session); d->starting=FALSE; } timestamp = (uint32_t) (f->ticker->time * (d->rate/1000)); while ((m = rtp_session_recvm_with_ts(d->session, timestamp)) != NULL) { mblk_set_timestamp_info(m, rtp_get_timestamp(m)); mblk_set_marker_info(m, rtp_get_markbit(m)); mblk_set_cseq(m, rtp_get_seqnumber(m)); rtp_get_payload(m,&m->b_rptr); ms_queue_put(f->outputs[0], m); } }
/*returns TRUE if the packet is ok to be sent to output queue*/ static bool_t receiver_check_payload_type(MSFilter *f, ReceiverData *d, mblk_t *m){ int ptn=rtp_get_payload_type(m); PayloadType *pt; if (ptn==d->current_pt) return TRUE; pt=rtp_profile_get_payload(rtp_session_get_profile(d->session), ptn); if (pt==NULL){ ms_warning("Discarding packet with unknown payload type %i",ptn); return FALSE; } if (strcasecmp(pt->mime_type,"CN")==0){ MSCngData cngdata; uint8_t *data=NULL; int datasize=rtp_get_payload(m, &data); if (data){ if (datasize<= sizeof(cngdata.data)){ memcpy(cngdata.data, data, datasize); cngdata.datasize=datasize; ms_filter_notify(f, MS_RTP_RECV_GENERIC_CN_RECEIVED, &cngdata); }else{ ms_warning("CN packet has unexpected size %i", datasize); } } return FALSE; } d->current_pt = ptn; return TRUE; }
static void receiver_process(MSFilter * f) { ReceiverData *d = (ReceiverData *) f->data; mblk_t *m; uint32_t timestamp; if (d->session == NULL) return; timestamp = (uint32_t) (f->ticker->time * (d->rate/1000)); while ((m = rtp_session_recvm_with_ts(d->session, timestamp)) != NULL) { mblk_set_timestamp_info(m, rtp_get_timestamp(m)); mblk_set_marker_info(m, rtp_get_markbit(m)); mblk_set_payload_type(m, rtp_get_payload_type(m)); rtp_get_payload(m,&m->b_rptr); ms_queue_put(f->outputs[0], m); } }
/** * Reads telephony events from a rtp packet. *@tab points to the beginning of the event buffer. * * @param session a rtp session from which telephony events are received. * @param packet a rtp packet as a mblk_t. * @param tab the address of a pointer. * @return the number of events in the packet if successfull, 0 if the packet did not contain telephony events. **/ int rtp_session_read_telephone_event(RtpSession *session, mblk_t *packet,telephone_event_t **tab) { int datasize; int num; int i; telephone_event_t *tev; rtp_header_t *hdr=(rtp_header_t*)packet->b_rptr; unsigned char *payload; if (hdr->paytype!=session->rcv.telephone_events_pt) return 0; /* this is not tel ev.*/ datasize=rtp_get_payload(packet,&payload); tev=*tab=(telephone_event_t*)payload; /* convert from network to host order what should be */ num=datasize/sizeof(telephone_event_t); for (i=0;i<num;i++) { tev[i].duration=ntohs(tev[i].duration); } return num; }
/* for high level telephony event callback */ void rtp_session_check_telephone_events(RtpSession *session, mblk_t *m0) { telephone_event_t *events,*evbuf; int num,num2; int i; rtp_header_t *hdr; mblk_t *cur_tev; unsigned char *payload; int datasize; hdr=(rtp_header_t*)m0->b_rptr; datasize=rtp_get_payload(m0,&payload); num=datasize/sizeof(telephone_event_t); events=(telephone_event_t*)payload; if (hdr->markbit==1) { /* this is a start of new events. Store the event buffer for later use*/ if (session->current_tev!=NULL) { freemsg(session->current_tev); session->current_tev=NULL; } session->current_tev=copymsg(m0); /* handle the case where the events are short enough to end within the packet that has the marker bit*/ notify_events_ended(session,events,num); } /* whatever there is a markbit set or not, we parse the packet and compare it to previously received one */ cur_tev=session->current_tev; if (cur_tev!=NULL) { /* first compare timestamp, they must be identical */ if (((rtp_header_t*)cur_tev->b_rptr)->timestamp== ((rtp_header_t*)m0->b_rptr)->timestamp) { datasize=rtp_get_payload(cur_tev,&payload); num2=datasize/sizeof(telephone_event_t); evbuf=(telephone_event_t*)payload; for (i=0;i<MIN(num,num2);i++) { if (events[i].E==1) { /* update events that have ended */ if (evbuf[i].E==0){ evbuf[i].E=1; /* this is a end of event, report it */ notify_tev(session,&events[i]); } } } } else { /* timestamp are not identical: this is not the same events*/ if (session->current_tev!=NULL) { freemsg(session->current_tev); session->current_tev=NULL; } session->current_tev=copymsg(m0); notify_events_ended(session,events,num); } } else { /* there is no pending events, but we did not received marked bit packet either the sending implementation is not compliant, either it has been lost, we must deal with it anyway.*/ session->current_tev=copymsg(m0); /* inform the application if there are tone ends */ notify_events_ended(session,events,num); } }
static void ms_opus_dec_process(MSFilter *f) { OpusDecData *d = (OpusDecData *)f->data; mblk_t *im; mblk_t *om; int frames; if (!d->state) ms_queue_flush(f->inputs[0]); /* decode available packets */ while ((im = ms_queue_get(f->inputs[0])) != NULL) { om = allocb(5760 * d->channels * SIGNAL_SAMPLE_SIZE, 0); /* 5760 is the maximum number of sample in a packet (120ms at 48KHz) */ frames = opus_decode(d->state, (const unsigned char *)im->b_rptr, im->b_wptr - im->b_rptr, (opus_int16 *)om->b_wptr, 5760, 0); if (frames < 0) { ms_warning("Opus decoder error: %s", opus_strerror(frames)); freemsg(om); } else { d->lastPacketLength = frames; // store the packet length for eventual PLC if next two packets are missing om->b_wptr += frames * d->channels * SIGNAL_SAMPLE_SIZE; mblk_meta_copy(im,om); ms_queue_put(f->outputs[0], om); /*ms_message("Opus: outputing a normal frame of %i bytes (%i samples,%i ms)",(int)(om->b_wptr-om->b_rptr),frames,frames*1000/d->samplerate);*/ d->sequence_number = mblk_get_cseq(im); // used to get eventual FEC information if next packet is missing ms_concealer_inc_sample_time(d->concealer,f->ticker->time, frames*1000/d->samplerate, 1); } freemsg(im); } /* Concealment if needed */ if (ms_concealer_context_is_concealement_required(d->concealer, f->ticker->time)) { int imLength = 0; uint8_t *payload = NULL; im = NULL; // try fec : info are stored in the next packet, do we have it? if (d->rtp_picker_context.picker) { /* FEC information is in the next packet, last valid packet was d->sequence_number, the missing one shall then be d->sequence_number+1, so check jitter buffer for d->sequence_number+2 */ /* but we may have the n+1 packet in the buffer and adaptative jitter control keeping it for later, in that case, just go for PLC */ if (d->rtp_picker_context.picker(&d->rtp_picker_context,d->sequence_number+1) == NULL) { /* missing packet is really missing */ im = d->rtp_picker_context.picker(&d->rtp_picker_context,d->sequence_number+2); /* try to get n+2 */ if (im) { imLength=rtp_get_payload(im,&payload); } } } om = allocb(5760 * d->channels * SIGNAL_SAMPLE_SIZE, 0); /* 5760 is the maximum number of sample in a packet (120ms at 48KHz) */ /* call to the decoder, we'll have either FEC or PLC, do it on the same length that last received packet */ if (payload) { // found frame to try FEC d->statsfec++; frames = opus_decode(d->state, payload, imLength, (opus_int16 *)om->b_wptr, d->lastPacketLength, 1); } else { // do PLC: PLC doesn't seem to be able to generate more than 960 samples (20 ms at 48000 Hz), get PLC until we have the correct number of sample //frames = opus_decode(d->state, NULL, 0, (opus_int16 *)om->b_wptr, d->lastPacketLength, 0); // this should have work if opus_decode returns the requested number of samples d->statsplc++; frames = 0; while (frames < d->lastPacketLength) { frames += opus_decode(d->state, NULL, 0, (opus_int16 *)(om->b_wptr + (frames*d->channels*SIGNAL_SAMPLE_SIZE)), d->lastPacketLength-frames, 0); } } if (frames < 0) { ms_warning("Opus decoder error in concealment: %s", opus_strerror(frames)); freemsg(om); } else { om->b_wptr += frames * d->channels * SIGNAL_SAMPLE_SIZE; /*ms_message("Opus: outputing a PLC frame of %i bytes (%i samples,%i ms)",(int)(om->b_wptr-om->b_rptr),frames,frames*1000/d->samplerate);*/ mblk_set_plc_flag(om,TRUE); ms_queue_put(f->outputs[0], om); d->sequence_number++; ms_concealer_inc_sample_time(d->concealer,f->ticker->time, frames*1000/d->samplerate, 0); } } }
static void ms_opus_dec_process(MSFilter *f) { OpusDecData *d = (OpusDecData *)f->data; mblk_t *im; mblk_t *om; int frames; /* decode available packets */ while ((im = ms_queue_get(f->inputs[0])) != NULL) { om = allocb(5760 * d->channels * SIGNAL_SAMPLE_SIZE, 0); /* 5760 is the maximum number of sample in a packet (120ms at 48KHz) */ frames = opus_decode(d->state, (const unsigned char *)im->b_rptr, im->b_wptr - im->b_rptr, (opus_int16 *)om->b_wptr, 5760, 0); if (frames < 0) { ms_warning("Opus decoder error: %s", opus_strerror(frames)); freemsg(om); } else { d->lastPacketLength = frames; // store the packet length for eventual PLC if next two packets are missing om->b_wptr += frames * d->channels * SIGNAL_SAMPLE_SIZE; ms_queue_put(f->outputs[0], om); d->sequence_number = mblk_get_cseq(im); // used to get eventual FEC information if next packet is missing ms_concealer_inc_sample_time(d->concealer,f->ticker->time, frames*1000/d->samplerate, 1); } freemsg(im); } /* Concealment if needed */ if (ms_concealer_context_is_concealement_required(d->concealer, f->ticker->time)) { int imLength = 0; im = NULL; uint8_t *payload = NULL; // try fec : info are stored in the next packet, do we have it? if (d->rtp_picker_context.picker) { im = d->rtp_picker_context.picker(&d->rtp_picker_context,d->sequence_number+1); if (im) { imLength=rtp_get_payload(im,&payload); d->statsfec++; } else { d->statsplc++; } } om = allocb(5760 * d->channels * SIGNAL_SAMPLE_SIZE, 0); /* 5760 is the maximum number of sample in a packet (120ms at 48KHz) */ /* call to the decoder, we'll have either FEC or PLC, do it on the same length that last received packet */ if (payload) { // found frame to try FEC frames = opus_decode(d->state, payload, imLength, (opus_int16 *)om->b_wptr, d->lastPacketLength, 1); } else { // do PLC: PLC doesn't seem to be able to generate more than 960 samples (20 ms at 48000 Hz), get PLC until we have the correct number of sample //frames = opus_decode(d->state, NULL, 0, (opus_int16 *)om->b_wptr, d->lastPacketLength, 0); // this should have work if opus_decode returns the requested number of samples frames = 0; while (frames < d->lastPacketLength) { frames += opus_decode(d->state, NULL, 0, (opus_int16 *)(om->b_wptr + (frames*d->channels*SIGNAL_SAMPLE_SIZE)), d->lastPacketLength-frames, 0); } } if (frames < 0) { ms_warning("Opus decoder error in concealment: %s", opus_strerror(frames)); freemsg(om); } else { om->b_wptr += frames * d->channels * SIGNAL_SAMPLE_SIZE; ms_queue_put(f->outputs[0], om); d->sequence_number++; ms_concealer_inc_sample_time(d->concealer,f->ticker->time, frames*1000/d->samplerate, 0); } } }