MPF_DECLARE(apt_bool_t) mpf_rtp_stream_remove(mpf_audio_stream_t *stream) { mpf_rtp_stream_t *rtp_stream = stream->obj; if(rtp_stream->state == MPF_MEDIA_ENABLED) { /* disable RTP/RTCP session */ rtp_stream->state = MPF_MEDIA_DISABLED; if(rtp_stream->rtp_l_sockaddr) { apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remove RTP Session %s:%hu", rtp_stream->rtp_l_sockaddr->hostname, rtp_stream->rtp_l_sockaddr->port); } if(rtp_stream->rtcp_tx_timer) { apt_timer_kill(rtp_stream->rtcp_tx_timer); } if(rtp_stream->rtcp_rx_timer) { apt_timer_kill(rtp_stream->rtcp_rx_timer); } if(rtp_stream->settings->rtcp == TRUE && rtp_stream->settings->rtcp_bye_policy != RTCP_BYE_DISABLE) { apt_str_t reason = {RTCP_BYE_SESSION_ENDED, sizeof(RTCP_BYE_SESSION_ENDED)-1}; mpf_rtcp_bye_send(rtp_stream,&reason); } } mpf_rtp_socket_pair_close(rtp_stream); return TRUE; }
static apt_bool_t mpf_rtp_stream_transmit(mpf_audio_stream_t *stream, const mpf_frame_t *frame) { apt_bool_t status = TRUE; mpf_rtp_stream_t *rtp_stream = stream->obj; rtp_transmitter_t *transmitter = &rtp_stream->transmitter; transmitter->timestamp += transmitter->samples_per_frame; if(frame->type == MEDIA_FRAME_TYPE_NONE) { if(!transmitter->inactivity) { if(transmitter->current_frames == 0) { /* set inactivity (ptime alligned) */ transmitter->inactivity = 1; if(rtp_stream->settings->rtcp == TRUE && rtp_stream->settings->rtcp_bye_policy == RTCP_BYE_PER_TALKSPURT) { apt_str_t reason = {RTCP_BYE_TALKSPURT_ENDED, sizeof(RTCP_BYE_TALKSPURT_ENDED)-1}; mpf_rtcp_bye_send(rtp_stream,&reason); } } else { /* ptime allignment */ status = mpf_rtp_data_send(rtp_stream,transmitter,frame); } } return status; } if((frame->type & MEDIA_FRAME_TYPE_EVENT) == MEDIA_FRAME_TYPE_EVENT){ /* transmit event as soon as received */ if(stream->tx_event_descriptor) { if(frame->marker == MPF_MARKER_START_OF_EVENT) { /* store start time (base) of the event */ transmitter->timestamp_base = transmitter->timestamp; } else if(frame->marker == MPF_MARKER_NEW_SEGMENT) { /* update base in case of long-lasting events */ transmitter->timestamp_base = transmitter->timestamp; } status = mpf_rtp_event_send(rtp_stream,transmitter,frame); } } if((frame->type & MEDIA_FRAME_TYPE_AUDIO) == MEDIA_FRAME_TYPE_AUDIO){ if(transmitter->current_frames == 0) { rtp_header_t *header = (rtp_header_t*)transmitter->packet_data; rtp_header_prepare( transmitter, header, stream->tx_descriptor->payload_type, transmitter->inactivity, transmitter->timestamp); transmitter->packet_size = sizeof(rtp_header_t); if(transmitter->inactivity) { transmitter->inactivity = 0; } } status = mpf_rtp_data_send(rtp_stream,transmitter,frame); } return status; }
static apt_bool_t mpf_rtp_stream_media_negotiate(mpf_rtp_stream_t *rtp_stream) { mpf_rtp_media_descriptor_t *local_media = rtp_stream->local_media; mpf_rtp_media_descriptor_t *remote_media = rtp_stream->remote_media; if(!local_media || !remote_media) { return FALSE; } local_media->id = remote_media->id; local_media->mid = remote_media->mid; local_media->ptime = remote_media->ptime; if(rtp_stream->state == MPF_MEDIA_DISABLED && remote_media->state == MPF_MEDIA_ENABLED) { /* enable RTP/RTCP session */ rtp_stream->state = MPF_MEDIA_ENABLED; if(rtp_stream->rtp_l_sockaddr) { apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Enable RTP Session %s:%hu", rtp_stream->rtp_l_sockaddr->hostname, rtp_stream->rtp_l_sockaddr->port); } if(rtp_stream->rtcp_tx_timer) { apt_timer_set(rtp_stream->rtcp_tx_timer,rtp_stream->settings->rtcp_tx_interval); } if(rtp_stream->rtcp_rx_timer) { apt_timer_set(rtp_stream->rtcp_rx_timer,rtp_stream->settings->rtcp_rx_resolution); } } else if(rtp_stream->state == MPF_MEDIA_ENABLED && remote_media->state == MPF_MEDIA_DISABLED) { /* disable RTP/RTCP session */ rtp_stream->state = MPF_MEDIA_DISABLED; if(rtp_stream->rtp_l_sockaddr) { apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Disable RTP Session %s:%hu", rtp_stream->rtp_l_sockaddr->hostname, rtp_stream->rtp_l_sockaddr->port); } if(rtp_stream->rtcp_tx_timer) { apt_timer_kill(rtp_stream->rtcp_tx_timer); } if(rtp_stream->rtcp_rx_timer) { apt_timer_kill(rtp_stream->rtcp_rx_timer); } if(rtp_stream->settings->rtcp == TRUE && rtp_stream->settings->rtcp_bye_policy != RTCP_BYE_DISABLE) { apt_str_t reason = {RTCP_BYE_SESSION_ENDED, sizeof(RTCP_BYE_SESSION_ENDED)-1}; mpf_rtcp_bye_send(rtp_stream,&reason); } } local_media->state = remote_media->state; local_media->direction = mpf_stream_reverse_direction_get(remote_media->direction); if(remote_media->state == MPF_MEDIA_ENABLED) { mpf_codec_list_t *codec_list1 = NULL; mpf_codec_list_t *codec_list2 = NULL; /* intersect local and remote codecs */ if(rtp_stream->settings->own_preferrence == TRUE) { codec_list1 = &local_media->codec_list; codec_list2 = &remote_media->codec_list; } else { codec_list2 = &local_media->codec_list; codec_list1 = &remote_media->codec_list; } if(mpf_codec_lists_intersect(codec_list1,codec_list2) == FALSE) { /* reject RTP/RTCP session */ rtp_stream->state = MPF_MEDIA_DISABLED; local_media->direction = STREAM_DIRECTION_NONE; local_media->state = MPF_MEDIA_DISABLED; if(rtp_stream->rtp_l_sockaddr) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Reject RTP Session %s:%hu no codecs matched", rtp_stream->rtp_l_sockaddr->hostname, rtp_stream->rtp_l_sockaddr->port); } if(rtp_stream->rtcp_tx_timer) { apt_timer_kill(rtp_stream->rtcp_tx_timer); } if(rtp_stream->rtcp_rx_timer) { apt_timer_kill(rtp_stream->rtcp_rx_timer); } } } rtp_stream->base->direction = local_media->direction; return TRUE; }
static apt_bool_t mpf_rtp_stream_media_negotiate(mpf_rtp_stream_t *rtp_stream) { mpf_rtp_media_descriptor_t *local_media = rtp_stream->local_media; mpf_rtp_media_descriptor_t *remote_media = rtp_stream->remote_media; if(!local_media || !remote_media) { return FALSE; } local_media->id = remote_media->id; local_media->mid = remote_media->mid; local_media->ptime = remote_media->ptime; if(rtp_stream->state == MPF_MEDIA_DISABLED && remote_media->state == MPF_MEDIA_ENABLED) { /* enable RTP/RTCP session */ rtp_stream->state = MPF_MEDIA_ENABLED; if(rtp_stream->rtp_l_sockaddr) { apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Enable RTP Session %s:%hu", rtp_stream->rtp_l_sockaddr->hostname, rtp_stream->rtp_l_sockaddr->port); } if(rtp_stream->rtcp_tx_timer) { mpf_timer_set(rtp_stream->rtcp_tx_timer,rtp_stream->config->rtcp_tx_interval); } if(rtp_stream->rtcp_rx_timer) { mpf_timer_set(rtp_stream->rtcp_rx_timer,rtp_stream->config->rtcp_rx_resolution); } } else if(rtp_stream->state == MPF_MEDIA_ENABLED && remote_media->state == MPF_MEDIA_DISABLED) { /* disable RTP/RTCP session */ rtp_stream->state = MPF_MEDIA_DISABLED; if(rtp_stream->rtp_l_sockaddr) { apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Disable RTP Session %s:%hu", rtp_stream->rtp_l_sockaddr->hostname, rtp_stream->rtp_l_sockaddr->port); } if(rtp_stream->rtcp_tx_timer) { mpf_timer_kill(rtp_stream->rtcp_tx_timer); } if(rtp_stream->rtcp_rx_timer) { mpf_timer_kill(rtp_stream->rtcp_rx_timer); } if(rtp_stream->config->rtcp == TRUE && rtp_stream->config->rtcp_bye_policy != RTCP_BYE_DISABLE) { apt_str_t reason = {RTCP_BYE_SESSION_ENDED, sizeof(RTCP_BYE_SESSION_ENDED)-1}; mpf_rtcp_bye_send(rtp_stream,&reason); } } local_media->state = remote_media->state; local_media->direction = mpf_stream_reverse_direction_get(remote_media->direction); rtp_stream->base->direction = local_media->direction; if(remote_media->state == MPF_MEDIA_ENABLED) { if(mpf_codec_list_is_empty(&remote_media->codec_list) == TRUE) { /* no remote codecs available, initialize them according to the local codecs */ mpf_codec_list_copy(&remote_media->codec_list, &local_media->codec_list, rtp_stream->pool); } /* intersect local and remote codecs */ if(rtp_stream->config->own_preferrence == TRUE) { mpf_codec_lists_intersect( &local_media->codec_list, &remote_media->codec_list); } else { mpf_codec_lists_intersect( &remote_media->codec_list, &local_media->codec_list); } } return TRUE; }