static void process_red_packet(RealTimeTextSinkData *stream, mblk_t *packet) { int seqno = mblk_get_cseq(packet); uint8_t *payload = packet->b_rptr; size_t payloadsize = msgdsize(packet); int redgen = 0; int pos = 0; int redneeded; int readstart; /* check how many is red, also check if its the right payload for the red */ ms_debug("red seqno:%i", seqno); while ((pos < (int)payloadsize) && (payload[pos] & (1 << 7))) { redgen++; if (((int)payload[pos] & 0x7F) != stream->pt_t140) { ms_warning("invalid red packet"); return; } pos += 4; } ms_debug("red redgen:%i",redgen); if ((int)payload[pos] != stream->pt_t140) { ms_warning("invalid red packet"); return; } if (stream->flags & TS_FLAG_NOTFIRST) { redneeded = red_needed(seqno, stream->prevseqno); } else { redneeded = 0; } if (redneeded < 0) { ms_warning("packet arrived out of order"); return; } ms_debug("red redneeded:%i", redneeded); if (redneeded > redgen) { /* we need more red than we got */ stream->inbufsize = 3; insert_lost_char(stream->inbuf); redneeded = redgen; } /* loop over unneeded red */ readstart = redgen * 4 + 1; for (pos = 0; pos < (redgen - redneeded) * 4; pos += 4) { readstart += (((uint32_t)payload[pos + 2] << 8) | (uint32_t)payload[pos + 3]) & 0x3FF; } if (read_t140_data(stream, &payload[readstart], payloadsize - readstart)) { ms_debug("error reading"); return; /* return without updating seqno */ } stream->prevseqno = seqno; }
static void decode(MSFilter *f, mblk_t *im) { isac_decoder_t* obj = (isac_decoder_t*)f->data; WebRtc_Word16 samples_nb, ret; WebRtc_Word16 speech_type; // needed but not used.. // im is one packet from the encoder, so it's either 30 or 60 ms of audio ret = WebRtcIsacfix_ReadFrameLen( (const WebRtc_Word16*)im->b_rptr, &samples_nb); // ms_message("WebRtcIsacfix_ReadFrameLen -> %d", samples_nb); if( ret == 0 ) { mblk_t *om = allocb(samples_nb*2, 0); mblk_meta_copy(im, om); obj->ptime = (samples_nb == ISAC_30MS_SAMPLE_COUNT) ? 30 : 60; // update ptime // ms_message("DECODED om datap @%p", om->b_datap); ret = WebRtcIsacfix_Decode(obj->isac, (const WebRtc_UWord16*)im->b_rptr, (im->b_wptr - im->b_rptr), (WebRtc_Word16*)om->b_wptr, &speech_type ); if( ret < 0 ) { ms_error( "WebRtcIsacfix_Decode error: %d", WebRtcIsacfix_GetErrorCode(obj->isac) ); freeb(om); } else { // ms_message("Decoded %d samples", ret); om->b_wptr+= ret*2; mblk_set_plc_flag(om, 0); ms_queue_put(f->outputs[0], om); } } else { ms_error( "WebRtcIsacfix_ReadFrameLen failed: %d", WebRtcIsacfix_GetErrorCode(obj->isac) ); } obj->seq_nb = mblk_get_cseq(im); ms_concealer_inc_sample_time(obj->plc_ctx, f->ticker->time, obj->ptime, TRUE); return; }
static void process_t140_packet(RealTimeTextSinkData *stream, mblk_t *packet) { int seqno = mblk_get_cseq(packet); uint8_t *payload = packet->b_rptr; size_t payloadsize = msgdsize(packet); ms_debug("t140 seqno:%i", seqno); if (stream->flags & TS_FLAG_NOTFIRST) { int t = red_needed(seqno, stream->prevseqno); if (t < 0) { ms_warning("packet arrived out of order"); return; } else if (t > 0) { stream->inbufsize = 3; insert_lost_char(stream->inbuf); } } if (read_t140_data(stream, payload, (int)payloadsize)) { return; /* return without updatting seqno */ } stream->prevseqno = seqno; }
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); } } }