static APR_INLINE apt_bool_t mpf_rtp_event_send(mpf_rtp_stream_t *rtp_stream, rtp_transmitter_t *transmitter, const mpf_frame_t *frame) { char packet_data[20]; apr_size_t packet_size = sizeof(rtp_header_t) + sizeof(mpf_named_event_frame_t); rtp_header_t *header = (rtp_header_t*) packet_data; mpf_named_event_frame_t *named_event = (mpf_named_event_frame_t*)(header+1); rtp_header_prepare( transmitter, header, rtp_stream->base->tx_event_descriptor->payload_type, (frame->marker == MPF_MARKER_START_OF_EVENT) ? 1 : 0, transmitter->timestamp_base); *named_event = frame->event_frame; named_event->edge = (frame->marker == MPF_MARKER_END_OF_EVENT) ? 1 : 0; header->sequence = htons(++transmitter->last_seq_num); RTP_TRACE("> RTP time=%6lu ssrc=%8lx pt=%3u %cts=%9lu seq=%5u event=%2u dur=%3u %c\n", (apr_uint32_t)apr_time_usec(apr_time_now()), transmitter->sr_stat.ssrc, header->type, (header->marker == 1) ? '*' : ' ', header->timestamp, transmitter->last_seq_num, named_event->event_id, named_event->duration, (named_event->edge == 1) ? '*' : ' '); header->timestamp = htonl(header->timestamp); named_event->duration = htons((apr_uint16_t)named_event->duration); if(apr_socket_sendto( rtp_stream->rtp_socket, rtp_stream->rtp_r_sockaddr, 0, packet_data, &packet_size) != APR_SUCCESS) { return FALSE; } transmitter->sr_stat.sent_packets++; transmitter->sr_stat.sent_octets += sizeof(mpf_named_event_frame_t); 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; }