mpf_jitter_buffer_t* mpf_jitter_buffer_create(mpf_jb_config_t *jb_config, mpf_codec_descriptor_t *descriptor, mpf_codec_t *codec, apr_pool_t *pool) { size_t i; mpf_frame_t *frame; mpf_jitter_buffer_t *jb = apr_palloc(pool,sizeof(mpf_jitter_buffer_t)); if(!jb_config) { /* create default jb config */ jb_config = apr_palloc(pool,sizeof(mpf_jb_config_t)); mpf_jb_config_init(jb_config); } /* validate jb config */ if(jb_config->initial_playout_delay == 0) { /* default configuration */ jb_config->min_playout_delay = 10; /* ms */ jb_config->initial_playout_delay = 50; /* ms */ jb_config->max_playout_delay = 200; /* ms */ } else { if(jb_config->min_playout_delay > jb_config->initial_playout_delay) { jb_config->min_playout_delay = jb_config->initial_playout_delay; } if(jb_config->max_playout_delay < jb_config->initial_playout_delay) { jb_config->max_playout_delay = 2 * jb_config->initial_playout_delay; } } jb->config = jb_config; jb->codec = codec; jb->frame_ts = (apr_uint32_t)mpf_codec_frame_samples_calculate(descriptor); jb->frame_size = mpf_codec_frame_size_calculate(descriptor,codec->attribs); jb->frame_count = jb->config->max_playout_delay / CODEC_FRAME_TIME_BASE; jb->raw_data = apr_palloc(pool,jb->frame_size*jb->frame_count); jb->frames = apr_palloc(pool,sizeof(mpf_frame_t)*jb->frame_count); for(i=0; i<jb->frame_count; i++) { frame = &jb->frames[i]; frame->type = MEDIA_FRAME_TYPE_NONE; frame->marker = MPF_MARKER_NONE; frame->codec_frame.buffer = jb->raw_data + i*jb->frame_size; } if(jb->config->initial_playout_delay % CODEC_FRAME_TIME_BASE != 0) { jb->config->initial_playout_delay += CODEC_FRAME_TIME_BASE - jb->config->initial_playout_delay % CODEC_FRAME_TIME_BASE; } jb->playout_delay_ts = (apr_uint32_t)(jb->config->initial_playout_delay * descriptor->channel_count * descriptor->sampling_rate / 1000); jb->write_sync = 1; jb->write_ts_offset = 0; jb->write_ts = jb->read_ts = 0; jb->event_write_base_ts = 0; memset(&jb->event_write_base,0,sizeof(mpf_named_event_frame_t)); jb->event_write_update = NULL; return jb; }
MPF_DECLARE(apt_bool_t) mpf_rtp_stream_modify(mpf_audio_stream_t *stream, mpf_rtp_stream_descriptor_t *descriptor) { apt_bool_t status = TRUE; mpf_rtp_stream_t *rtp_stream = stream->obj; if(!rtp_stream) { return FALSE; } if(!rtp_stream->local_media) { /* create local media */ status = mpf_rtp_stream_local_media_create(rtp_stream,descriptor->local,descriptor->remote,descriptor->capabilities); } else if(descriptor->local) { /* update local media */ status = mpf_rtp_stream_local_media_update(rtp_stream,descriptor->local,descriptor->capabilities); } if(descriptor->remote && status == TRUE) { /* update remote media */ mpf_rtp_stream_remote_media_update(rtp_stream,descriptor->remote); /* negotiate local and remote media */ mpf_rtp_stream_media_negotiate(rtp_stream); } if((rtp_stream->base->direction & STREAM_DIRECTION_SEND) == STREAM_DIRECTION_SEND) { mpf_codec_list_t *codec_list = &rtp_stream->remote_media->codec_list; rtp_stream->base->tx_descriptor = codec_list->primary_descriptor; if(rtp_stream->base->tx_descriptor) { rtp_stream->transmitter.samples_per_frame = (apr_uint32_t)mpf_codec_frame_samples_calculate(rtp_stream->base->tx_descriptor); } if(codec_list->event_descriptor) { rtp_stream->base->tx_event_descriptor = codec_list->event_descriptor; } } if((rtp_stream->base->direction & STREAM_DIRECTION_RECEIVE) == STREAM_DIRECTION_RECEIVE) { mpf_codec_list_t *codec_list = &rtp_stream->local_media->codec_list; rtp_stream->base->rx_descriptor = codec_list->primary_descriptor; if(codec_list->event_descriptor) { rtp_stream->base->rx_event_descriptor = codec_list->event_descriptor; } } if(!descriptor->local) { descriptor->local = rtp_stream->local_media; } return status; }
mpf_jitter_buffer_t* mpf_jitter_buffer_create(mpf_jb_config_t *jb_config, mpf_codec_t *codec, apr_pool_t *pool) { size_t i; mpf_jitter_buffer_t *jb = apr_palloc(pool,sizeof(mpf_jitter_buffer_t)); if(!jb_config) { /* create default jb config */ jb_config = apr_palloc(pool,sizeof(mpf_jb_config_t)); mpf_jb_config_init(jb_config); } /* validate jb config */ if(jb_config->initial_playout_delay == 0) { /* default configuration */ jb_config->min_playout_delay = 10; /* ms */ jb_config->initial_playout_delay = 50; /* ms */ jb_config->max_playout_delay = 200; /* ms */ } else { if(jb_config->min_playout_delay > jb_config->initial_playout_delay) { jb_config->min_playout_delay = jb_config->initial_playout_delay; } if(jb_config->max_playout_delay < jb_config->initial_playout_delay) { jb_config->max_playout_delay = 2 * jb_config->initial_playout_delay; } } jb->config = jb_config; jb->frame_ts = mpf_codec_frame_samples_calculate(codec->descriptor); jb->frame_size = mpf_codec_frame_size_calculate(codec->descriptor,codec->attribs); jb->frame_count = jb->config->max_playout_delay / CODEC_FRAME_TIME_BASE; jb->raw_data = apr_palloc(pool,jb->frame_size*jb->frame_count); jb->frames = apr_palloc(pool,sizeof(mpf_frame_t)*jb->frame_count); for(i=0; i<jb->frame_count; i++) { jb->frames[i].type = MEDIA_FRAME_TYPE_NONE; jb->frames[i].codec_frame.buffer = jb->raw_data + i*jb->frame_size; } jb->playout_delay_ts = jb->config->initial_playout_delay * codec->descriptor->channel_count * codec->descriptor->sampling_rate / 1000; jb->write_sync = 1; jb->write_ts_offset = 0; jb->write_ts = jb->read_ts = 0; return jb; }