MPF_DECLARE(mpf_audio_stream_t*) mpf_encoder_create(mpf_audio_stream_t *sink, mpf_codec_t *codec, apr_pool_t *pool) { apr_size_t frame_size; mpf_encoder_t *encoder; mpf_stream_capabilities_t *capabilities; if(!sink || !codec) { return NULL; } encoder = apr_palloc(pool,sizeof(mpf_encoder_t)); capabilities = mpf_stream_capabilities_create(STREAM_DIRECTION_SEND,pool); encoder->base = mpf_audio_stream_create(encoder,&vtable,capabilities,pool); if(!encoder->base) { return NULL; } encoder->base->tx_descriptor = mpf_codec_lpcm_descriptor_create( sink->tx_descriptor->sampling_rate, sink->tx_descriptor->channel_count, pool); encoder->base->tx_event_descriptor = sink->tx_event_descriptor; encoder->sink = sink; encoder->codec = codec; frame_size = mpf_codec_frame_size_calculate(sink->tx_descriptor,codec->attribs); encoder->frame_out.codec_frame.size = frame_size; encoder->frame_out.codec_frame.buffer = apr_palloc(pool,frame_size); return encoder->base; }
static mpf_object_t* mpf_null_bridge_create(mpf_audio_stream_t *source, mpf_audio_stream_t *sink, const mpf_codec_manager_t *codec_manager, const char *name, apr_pool_t *pool) { mpf_codec_t *codec; apr_size_t frame_size; mpf_bridge_t *bridge; apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Create Null Audio Bridge %s",name); bridge = mpf_bridge_base_create(source,sink,name,pool); if(!bridge) { return NULL; } bridge->base.process = mpf_null_bridge_process; codec = mpf_codec_manager_codec_get(codec_manager,source->rx_descriptor,pool); if(!codec) { return NULL; } frame_size = mpf_codec_frame_size_calculate(source->rx_descriptor,codec->attribs); bridge->codec = codec; bridge->frame.codec_frame.size = frame_size; bridge->frame.codec_frame.buffer = apr_palloc(pool,frame_size); if(mpf_audio_stream_rx_open(source,codec) == FALSE) { return NULL; } if(mpf_audio_stream_tx_open(sink,codec) == FALSE) { mpf_audio_stream_rx_close(source); return NULL; } return &bridge->base; }
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_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; }
MPF_DECLARE(mpf_audio_stream_t*) mpf_encoder_create(mpf_audio_stream_t *sink, apr_pool_t *pool) { apr_size_t frame_size; mpf_codec_t *codec; mpf_encoder_t *encoder; if(!sink || !sink->tx_codec) { return NULL; } encoder = apr_palloc(pool,sizeof(mpf_encoder_t)); encoder->base = mpf_audio_stream_create(encoder,&vtable,STREAM_MODE_SEND,pool); encoder->sink = sink; codec = sink->tx_codec; frame_size = mpf_codec_frame_size_calculate(codec->descriptor,codec->attribs); encoder->base->tx_codec = codec; encoder->frame_out.codec_frame.size = frame_size; encoder->frame_out.codec_frame.buffer = apr_palloc(pool,frame_size); return encoder->base; }
MPF_DECLARE(mpf_audio_stream_t*) mpf_decoder_create(mpf_audio_stream_t *source, apr_pool_t *pool) { apr_size_t frame_size; mpf_codec_t *codec; mpf_decoder_t *decoder; if(!source || !source->rx_codec) { return NULL; } decoder = apr_palloc(pool,sizeof(mpf_decoder_t)); decoder->base = mpf_audio_stream_create(decoder,&vtable,STREAM_MODE_RECEIVE,pool); decoder->source = source; codec = source->rx_codec; frame_size = mpf_codec_frame_size_calculate(codec->descriptor,codec->attribs); decoder->base->rx_codec = codec; decoder->frame_in.codec_frame.size = frame_size; decoder->frame_in.codec_frame.buffer = apr_palloc(pool,frame_size); return decoder->base; }
static apt_bool_t mpf_rtp_tx_stream_open(mpf_audio_stream_t *stream, mpf_codec_t *codec) { apr_size_t frame_size; mpf_rtp_stream_t *rtp_stream = stream->obj; rtp_transmitter_t *transmitter = &rtp_stream->transmitter; if(!rtp_stream->rtp_socket || !rtp_stream->rtp_l_sockaddr || !rtp_stream->rtp_r_sockaddr) { return FALSE; } if(!codec) { return FALSE; } if(!transmitter->ptime) { if(rtp_stream->settings && rtp_stream->settings->ptime) { transmitter->ptime = rtp_stream->settings->ptime; } else { transmitter->ptime = 20; } } transmitter->packet_frames = transmitter->ptime / CODEC_FRAME_TIME_BASE; transmitter->current_frames = 0; frame_size = mpf_codec_frame_size_calculate( stream->tx_descriptor, codec->attribs); transmitter->packet_data = apr_palloc( rtp_stream->pool, sizeof(rtp_header_t) + transmitter->packet_frames * frame_size); transmitter->inactivity = 1; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Open RTP Transmitter %s:%hu -> %s:%hu", rtp_stream->rtp_l_sockaddr->hostname, rtp_stream->rtp_l_sockaddr->port, rtp_stream->rtp_r_sockaddr->hostname, rtp_stream->rtp_r_sockaddr->port); return TRUE; }