/*** Encodes 8 kHz-sampled narrowband speech at a bit rate of or 16 kbit/s, uses 5 ms frames. The encoder receives 10 ms speech => 160 bytes. ***/ static void enc_process (MSFilter *f){ EncState *s=(EncState*)f->data; struct BV16_Bit_Stream bs; short *buf= NULL; mblk_t *inputMessage = NULL, *outputMessage = NULL; int frame_per_packet=s->ptime/5; int in_rcvd_bytes = 0; in_rcvd_bytes = SIGNAL_FRAME_SIZE * frame_per_packet; buf=(short*)alloca(in_rcvd_bytes); memset((void*)buf,0, in_rcvd_bytes ); while((inputMessage=ms_queue_get(f->inputs[0]))!=NULL){ ms_bufferizer_put(s->bufferizer,inputMessage); } /* process ptimes ms of data : (ptime in ms)/1000->ptime is seconds * 8000(sample rate) * 2(byte per sample) */ while(ms_bufferizer_get_avail(s->bufferizer)>= in_rcvd_bytes){ int bufferIndex; outputMessage = allocb(BITSTREAM_FRAME_SIZE*frame_per_packet,0); /* output bitStream is 80 bits long * number of samples */ /* process buffer in 5 ms frames but read everything first*/ ms_bufferizer_read(s->bufferizer,(uint8_t*)buf,in_rcvd_bytes); for (bufferIndex=0; bufferIndex<frame_per_packet; bufferIndex++) { BV16_Encode(&bs, &s->state, (short*)&buf[bufferIndex*FRSZ]); BV16_BitPack( (UWord8*)outputMessage->b_wptr, &bs ); outputMessage->b_wptr+=BITSTREAM_FRAME_SIZE; } mblk_set_timestamp_info(outputMessage,s->ts); ms_bufferizer_fill_current_metas(s->bufferizer, outputMessage); ms_queue_put(f->outputs[0],outputMessage); s->ts += FRSZ * frame_per_packet; } }
static void enc_process(MSFilter *f){ SpeexEncState *s=(SpeexEncState*)f->data; mblk_t *im; int nbytes; uint8_t *buf; int frame_per_packet=1; if (s->frame_size<=0) return; ms_filter_lock(f); if (s->ptime>=20) { frame_per_packet = s->ptime/20; } if (frame_per_packet<=0) frame_per_packet=1; if (frame_per_packet>7) /* 7*20 == 140 ms max */ frame_per_packet=7; nbytes=s->frame_size*2; buf=(uint8_t*)alloca(nbytes*frame_per_packet); while((im=ms_queue_get(f->inputs[0]))!=NULL){ ms_bufferizer_put(s->bufferizer,im); } while(ms_bufferizer_read(s->bufferizer,buf,nbytes*frame_per_packet)==nbytes*frame_per_packet){ mblk_t *om=allocb(nbytes*frame_per_packet,0);//too large... int k; SpeexBits bits; speex_bits_init(&bits); for (k=0;k<frame_per_packet;k++) { speex_encode_int(s->state,(int16_t*)(buf + (k*s->frame_size*2)),&bits); s->ts+=s->frame_size; } speex_bits_insert_terminator(&bits); k=speex_bits_write(&bits, (char*)om->b_wptr, nbytes*frame_per_packet); om->b_wptr+=k; mblk_set_timestamp_info(om,s->ts-s->frame_size); ms_bufferizer_fill_current_metas(s->bufferizer, om); ms_queue_put(f->outputs[0],om); speex_bits_destroy(&bits); } ms_filter_unlock(f); }
static void enc_process(MSFilter *f){ EncState *s=(EncState*)f->data; mblk_t *im,*om; int size=s->nsamples*2; int16_t samples[1610]; /* BLOCKL_MAX * 7 is the largest size for ptime == 140 */ float samples2[BLOCKL_MAX]; int i; int frame_per_packet=1; if (s->ptime>=20 && s->ms_per_frame>0 && s->ptime%s->ms_per_frame==0) { frame_per_packet = s->ptime/s->ms_per_frame; } if (frame_per_packet<=0) frame_per_packet=1; if (frame_per_packet>7) /* 7*20 == 140 ms max */ frame_per_packet=7; while((im=ms_queue_get(f->inputs[0]))!=NULL){ ms_bufferizer_put(s->bufferizer,im); } while(ms_bufferizer_read(s->bufferizer,(uint8_t*)samples,size*frame_per_packet)==(size*frame_per_packet)){ int k; om=allocb(s->nbytes*frame_per_packet,0); for (k=0;k<frame_per_packet;k++) { for (i=0;i<s->nsamples;i++){ samples2[i]=samples[i+(s->nsamples*k)]; } iLBC_encode((uint8_t*)om->b_wptr,samples2,&s->ilbc_enc); om->b_wptr+=s->nbytes; } s->ts+=s->nsamples*frame_per_packet; mblk_set_timestamp_info(om,s->ts); ms_bufferizer_fill_current_metas(s->bufferizer,om); ms_queue_put(f->outputs[0],om); } }
static void alaw_enc_process(MSFilter *obj){ AlawEncData *dt=(AlawEncData*)obj->data; MSBufferizer *bz=dt->bz; uint8_t buffer[2240]; int frame_per_packet=2; int size_of_pcm=320; mblk_t *m; if (dt->ptime>=10) { frame_per_packet = dt->ptime/10; } if (frame_per_packet<=0) frame_per_packet=1; if (frame_per_packet>14) /* 7*20 == 140 ms max */ frame_per_packet=14; size_of_pcm = 160*frame_per_packet; /* ex: for 20ms -> 160*2==320 */ while((m=ms_queue_get(obj->inputs[0]))!=NULL){ ms_bufferizer_put(bz,m); } while (ms_bufferizer_read(bz,buffer,size_of_pcm)==size_of_pcm){ mblk_t *o=allocb(size_of_pcm/2,0); int i; for (i=0;i<size_of_pcm/2;i++){ *o->b_wptr=Snack_Lin2Alaw(((int16_t*)buffer)[i]); o->b_wptr++; } ms_bufferizer_fill_current_metas(bz, o); mblk_set_timestamp_info(o,dt->ts); dt->ts+=size_of_pcm/2; ms_queue_put(obj->outputs[0],o); } }
static void ms_opus_enc_process(MSFilter *f) { OpusEncData *d = (OpusEncData *)f->data; OpusRepacketizer *repacketizer = NULL; mblk_t *om = NULL; int packet_size, pcm_buffer_size; int max_frame_byte_size, ptime = 20; int frame_count = 0, frame_size = 0; opus_int32 total_length = 0; uint8_t *repacketizer_frame_buffer[MAX_INPUT_FRAMES]; int i; ms_filter_lock(f); ptime = d->ptime; packet_size = d->samplerate * ptime / 1000; /* in samples */ ms_filter_unlock(f); switch (ptime) { case 10: frame_size = d->samplerate * 10 / 1000; frame_count = 1; break; case 20: frame_size = d->samplerate * 20 / 1000; frame_count = 1; break; case 40: frame_size = d->samplerate * 40 / 1000; frame_count = 1; break; case 60: frame_size = d->samplerate * 60 / 1000; frame_count = 1; break; case 80: frame_size = d->samplerate * 40 / 1000; frame_count = 2; break; case 100: frame_size = d->samplerate * 20 / 1000; frame_count = 5; break; case 120: frame_size = d->samplerate * 60 / 1000; frame_count = 2; break; default: frame_size = d->samplerate * 20 / 1000; frame_count = 1; } max_frame_byte_size = MAX_BYTES_PER_MS * ptime/frame_count; pcm_buffer_size = d->channels * frame_size * SIGNAL_SAMPLE_SIZE; if (pcm_buffer_size > d->pcmbufsize){ if (d->pcmbuffer) ms_free(d->pcmbuffer); d->pcmbuffer = ms_malloc(pcm_buffer_size); d->pcmbufsize = pcm_buffer_size; } for (i=0; i<MAX_INPUT_FRAMES; i++) { repacketizer_frame_buffer[i]=NULL; } ms_bufferizer_put_from_queue(d->bufferizer, f->inputs[0]); while (ms_bufferizer_get_avail(d->bufferizer) >= (d->channels * packet_size * SIGNAL_SAMPLE_SIZE)) { opus_int32 ret = 0; if (frame_count == 1) { /* One Opus frame, not using the repacketizer */ om = allocb(max_frame_byte_size, 0); ms_bufferizer_read(d->bufferizer, d->pcmbuffer, frame_size * SIGNAL_SAMPLE_SIZE * d->channels); ret = opus_encode(d->state, (opus_int16 *)d->pcmbuffer, frame_size, om->b_wptr, max_frame_byte_size); if (ret < 0) { freemsg(om); om=NULL; ms_error("Opus encoder error: %s", opus_strerror(ret)); break; } else { total_length = ret; om->b_wptr += total_length; } } else if(frame_count > 1) { /* We have multiple Opus frames we will use the opus repacketizer */ repacketizer = opus_repacketizer_create(); opus_repacketizer_init(repacketizer); /* Do not include FEC/LBRR in any frame after the first one since it will be sent with the previous one */ ret = opus_encoder_ctl(d->state, OPUS_SET_INBAND_FEC(0)); if (ret != OPUS_OK) { ms_error("could not set inband FEC to opus encoder: %s", opus_strerror(ret)); } for (i=0; i<frame_count; i++) { if(frame_count == i+1){ /* if configured, reactivate FEC on the last frame to tell the encoder he should restart saving LBRR frames */ ret = opus_encoder_ctl(d->state, OPUS_SET_INBAND_FEC(d->useinbandfec)); if (ret != OPUS_OK) { ms_error("could not set inband FEC to opus encoder: %s", opus_strerror(ret)); } } if (!repacketizer_frame_buffer[i]) repacketizer_frame_buffer[i] = ms_malloc(max_frame_byte_size); /* the repacketizer need the pointer to packet to remain valid, so we shall have a buffer for each coded frame */ ms_bufferizer_read(d->bufferizer, d->pcmbuffer, frame_size * SIGNAL_SAMPLE_SIZE * d->channels); ret = opus_encode(d->state, (opus_int16 *)d->pcmbuffer, frame_size, repacketizer_frame_buffer[i], max_frame_byte_size); if (ret < 0) { ms_error("Opus encoder error: %s", opus_strerror(ret)); break; } else if (ret > 0) { int err = opus_repacketizer_cat(repacketizer, repacketizer_frame_buffer[i], ret); /* add the encoded frame into the current packet */ if (err != OPUS_OK) { ms_error("Opus repacketizer error: %s", opus_strerror(err)); break; } total_length += ret; } } om = allocb(total_length + frame_count + 1, 0); /* opus repacketizer API: allocate at least number of frame + size of all data added before */ ret = opus_repacketizer_out(repacketizer, om->b_wptr, total_length+frame_count); if(ret < 0){ freemsg(om); om=NULL; ms_error("Opus repacketizer out error: %s", opus_strerror(ret)); } else { om->b_wptr += ret; } opus_repacketizer_destroy(repacketizer); for (i=0; i<frame_count; i++) { if (repacketizer_frame_buffer[i] != NULL) { ms_free(repacketizer_frame_buffer[i]); } } } if(om) { /* we have an encoded output message */ mblk_set_timestamp_info(om, d->ts); ms_bufferizer_fill_current_metas(d->bufferizer, om); ms_queue_put(f->outputs[0], om); d->ts += packet_size*48000/d->samplerate; /* RFC payload RTP opus 03 - section 4: RTP timestamp multiplier : WARNING works only with sr at 48000 */ total_length = 0; } } }
static void ms_opus_enc_process(MSFilter *f) { OpusEncData *d = (OpusEncData *)f->data; mblk_t *im; mblk_t *om = NULL; int i; int frameNumber, packet_size; uint8_t *signalFrameBuffer = NULL; uint8_t *codedFrameBuffer[MAX_INPUT_FRAMES]; OpusRepacketizer *rp = opus_repacketizer_create(); opus_int32 ret = 0; opus_int32 totalLength = 0; int frame_size = d->samplerate * FRAME_LENGTH / 1000; /* in samples */ // lock the access while getting ptime ms_filter_lock(f); frameNumber = d->ptime/FRAME_LENGTH; /* encode 20ms frames, ptime is a multiple of 20ms */ packet_size = d->samplerate * d->ptime / 1000; /* in samples */ ms_filter_unlock(f); while ((im = ms_queue_get(f->inputs[0])) != NULL) { ms_bufferizer_put(d->bufferizer, im); } for (i=0; i<MAX_INPUT_FRAMES; i++) { codedFrameBuffer[i]=NULL; } while (ms_bufferizer_get_avail(d->bufferizer) >= (d->channels * packet_size * SIGNAL_SAMPLE_SIZE)) { totalLength = 0; opus_repacketizer_init(rp); for (i=0; i<frameNumber; i++) { /* encode 20ms by 20ms and repacketize all of them together */ if (!codedFrameBuffer[i]) codedFrameBuffer[i] = ms_malloc(MAX_BYTES_PER_FRAME); /* the repacketizer need the pointer to packet to remain valid, so we shall have a buffer for each coded frame */ if (!signalFrameBuffer) signalFrameBuffer = ms_malloc(frame_size * SIGNAL_SAMPLE_SIZE * d->channels); ms_bufferizer_read(d->bufferizer, signalFrameBuffer, frame_size * SIGNAL_SAMPLE_SIZE * d->channels); ret = opus_encode(d->state, (opus_int16 *)signalFrameBuffer, frame_size, codedFrameBuffer[i], MAX_BYTES_PER_FRAME); if (ret < 0) { ms_error("Opus encoder error: %s", opus_strerror(ret)); break; } if (ret > 0) { int err = opus_repacketizer_cat(rp, codedFrameBuffer[i], ret); /* add the encoded frame into the current packet */ if (err != OPUS_OK) { ms_error("Opus repacketizer error: %s", opus_strerror(err)); break; } totalLength += ret; } } if (ret > 0) { om = allocb(totalLength+frameNumber + 1, 0); /* opus repacktizer API: allocate at leat number of frame + size of all data added before */ ret = opus_repacketizer_out(rp, om->b_wptr, totalLength+frameNumber); om->b_wptr += ret; mblk_set_timestamp_info(om, d->ts); ms_bufferizer_fill_current_metas(d->bufferizer, om); ms_queue_put(f->outputs[0], om); d->ts += packet_size*48000/d->samplerate; /* RFC payload RTP opus 03 - section 4: RTP timestamp multiplier : WARNING works only with sr at 48000 */ ret = 0; } } opus_repacketizer_destroy(rp); if (signalFrameBuffer != NULL) { ms_free(signalFrameBuffer); } for (i=0; i<frameNumber; i++) { if (codedFrameBuffer[i] != NULL) { ms_free(codedFrameBuffer[i]); } } }