Commit 2719b541 authored by Simon Morlat's avatar Simon Morlat

factorize analysis of RTCP SR and RR

parent 406505dd
......@@ -98,7 +98,7 @@ typedef struct _MediaStream MediaStream;
/*
* internal cb to process rtcp stream
* */
typedef void (*media_stream_process_rtcp)(MediaStream *stream, mblk_t *m);
typedef void (*media_stream_process_rtcp_callback_t)(MediaStream *stream, mblk_t *m);
struct _MSMediaStreamSessions{
RtpSession *rtp_session;
......@@ -136,6 +136,8 @@ struct _MediaStream {
IceCheckList *ice_check_list;
time_t start_time;
time_t last_iterate_time;
uint64_t last_packet_count;
time_t last_packet_time;
bool_t use_rc;
bool_t owns_sessions;
bool_t pad[1];
......@@ -143,7 +145,7 @@ struct _MediaStream {
* defines encoder target network bit rate, uses #media_stream_set_target_network_bitrate() setter.
* */
int target_bitrate;
media_stream_process_rtcp process_rtcp;
media_stream_process_rtcp_callback_t process_rtcp;
};
......@@ -246,6 +248,11 @@ MS2_PUBLIC void media_stream_reclaim_sessions(MediaStream *stream, MSMediaStream
void media_stream_iterate(MediaStream * stream);
/**
* Returns TRUE if stream was still actively receiving packets (RTP or RTCP) in the last period specified in timeout_seconds.
**/
MS2_PUBLIC bool_t media_stream_alive(MediaStream *stream, int timeout_seconds);
/**
* @returns curret streams tate
* */
......@@ -279,8 +286,6 @@ struct _AudioStream
MSFilter *recorder_mixer;
MSFilter *recorder;
char *recorder_file;
uint64_t last_packet_count;
time_t last_packet_time;
EchoLimiterType el_type; /*use echo limiter: two MSVolume, measured input level controlling local output level*/
uint32_t features;
bool_t play_dtmfs;
......
......@@ -123,7 +123,7 @@ static void audio_stream_configure_resampler(MSFilter *resampler,MSFilter *from,
static void audio_stream_process_rtcp(MediaStream *media_stream, mblk_t *m){
AudioStream *stream=(AudioStream*)media_stream;
stream->last_packet_time=ms_time(NULL);
do{
const report_block_t *rb=NULL;
if (rtcp_is_SR(m)){
......@@ -150,18 +150,7 @@ void audio_stream_iterate(AudioStream *stream){
}
bool_t audio_stream_alive(AudioStream * stream, int timeout){
const rtp_stats_t *stats=rtp_session_get_stats(stream->ms.sessions.rtp_session);
if (stats->recv!=0){
if (stats->recv!=stream->last_packet_count){
stream->last_packet_count=stats->recv;
stream->last_packet_time=ms_time(NULL);
}
}
if (ms_time(NULL)-stream->last_packet_time>timeout){
/* more than timeout seconds of inactivity*/
return FALSE;
}
return TRUE;
return media_stream_alive((MediaStream*)stream,timeout);
}
/*invoked from FEC capable filters*/
......@@ -654,7 +643,7 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
,stream->ms.rtprecv
,NULL);
stream->ms.start_time=stream->last_packet_time=ms_time(NULL);
stream->ms.start_time=stream->ms.last_packet_time=ms_time(NULL);
stream->ms.state=MSStreamStarted;
return 0;
......
......@@ -465,6 +465,32 @@ void mediastream_payload_type_changed(RtpSession *session, unsigned long data) {
media_stream_change_decoder(stream, pt);
}
static void media_stream_process_rtcp(MediaStream *stream, mblk_t *m, time_t curtime){
stream->last_packet_time=curtime;
ms_message("%s stream [%p]: receiving RTCP %s%s",media_stream_type_str(stream),stream,(rtcp_is_SR(m)?"SR":""),(rtcp_is_RR(m)?"RR":""));
do{
const report_block_t *rb=NULL;
if (rtcp_is_SR(m)){
rb=rtcp_SR_get_report_block(m,0);
}else if (rtcp_is_RR(m)){
rb=rtcp_RR_get_report_block(m,0);
}
if (rb){
unsigned int ij;
float rt=rtp_session_get_round_trip_propagation(stream->sessions.rtp_session);
float flost;
ij=report_block_get_interarrival_jitter(rb);
flost=(float)(100.0*report_block_get_fraction_lost(rb)/256.0);
ms_message("media_stream_process_rtcp[stream=%p]: remote statistics available for [%s] stream\n\tremote's interarrival jitter=%u\n"
"\tremote's lost packets percentage since last report=%f\n\tround trip time=%f seconds",stream,media_stream_type_str(stream),ij,flost,rt);
if (stream->rc) ms_bitrate_controller_process_rtcp(stream->rc,m);
if (stream->qi) ms_quality_indicator_update_from_feedback(stream->qi,m);
}
stream->process_rtcp(stream,m);
}while(rtcp_next_packet(m));
}
void media_stream_iterate(MediaStream *stream){
time_t curtime=ms_time(NULL);
......@@ -481,8 +507,7 @@ void media_stream_iterate(MediaStream *stream){
OrtpEventType evt=ortp_event_get_type(ev);
if (evt==ORTP_EVENT_RTCP_PACKET_RECEIVED){
mblk_t *m=ortp_event_get_data(ev)->packet;
ms_message("%s stream [%p]: receiving RTCP %s%s",media_stream_type_str(stream),stream,(rtcp_is_SR(m)?"SR":""),(rtcp_is_RR(m)?"RR":""));
stream->process_rtcp(stream,m);
media_stream_process_rtcp(stream,m,curtime);
}else if (evt==ORTP_EVENT_RTCP_PACKET_EMITTED){
ms_message("%s_stream_iterate[%p]: local statistics available\n\tLocal's current jitter buffer size:%f ms",
media_stream_type_str(stream), stream, rtp_session_get_jitter_stats(stream->sessions.rtp_session)->jitter_buffer_size_ms);
......@@ -498,6 +523,21 @@ void media_stream_iterate(MediaStream *stream){
}
}
bool_t media_stream_alive(MediaStream *ms, int timeout){
const rtp_stats_t *stats=rtp_session_get_stats(ms->sessions.rtp_session);
if (stats->recv!=0){
if (stats->recv!=ms->last_packet_count){
ms->last_packet_count=stats->recv;
ms->last_packet_time=ms_time(NULL);
}
}
if (ms_time(NULL)-ms->last_packet_time>timeout){
/* more than timeout seconds of inactivity*/
return FALSE;
}
return TRUE;
}
float media_stream_get_quality_rating(MediaStream *stream){
if (stream->qi){
return ms_quality_indicator_get_rating(stream->qi);
......
......@@ -95,70 +95,56 @@ static void internal_event_cb(void *ud, MSFilter *f, unsigned int event, void *e
static void video_stream_process_rtcp(MediaStream *media_stream, mblk_t *m){
VideoStream *stream = (VideoStream *)media_stream;
unsigned int i;
do{
if (rtcp_is_SR(m)){
const report_block_t *rb;
rb=rtcp_SR_get_report_block(m,0);
if (rb){
float rt=rtp_session_get_round_trip_propagation(stream->ms.sessions.rtp_session);
float flost;
i=report_block_get_interarrival_jitter(rb);
flost=(float)(100.0*report_block_get_fraction_lost(rb)/256.0);
ms_message("video_stream_process_rtcp[%p]: interarrival jitter=%u , lost packets percentage since last report=%f, round trip time=%f seconds",stream,i,flost,rt);
if (stream->ms.rc)
ms_bitrate_controller_process_rtcp(stream->ms.rc,m);
}
} else if (rtcp_is_PSFB(m)) {
if (rtcp_PSFB_get_type(m) == RTCP_PSFB_FIR) {
/* Special case for FIR where the packet sender ssrc must be equal to 0. */
if ((rtcp_PSFB_get_media_source_ssrc(m) == rtp_session_get_send_ssrc(stream->ms.sessions.rtp_session))
&& (rtcp_PSFB_get_packet_sender_ssrc(m) == 0)) {
for (i = 0; ; i++) {
rtcp_fb_fir_fci_t *fci = rtcp_PSFB_fir_get_fci(m, i);
if (fci == NULL) break;
if (rtcp_fb_fir_fci_get_ssrc(fci) == rtp_session_get_recv_ssrc(stream->ms.sessions.rtp_session)) {
uint8_t seq_nr = rtcp_fb_fir_fci_get_seq_nr(fci);
ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_FIR, &seq_nr);
break;
}
int i;
if (rtcp_is_PSFB(m)) {
if (rtcp_PSFB_get_type(m) == RTCP_PSFB_FIR) {
/* Special case for FIR where the packet sender ssrc must be equal to 0. */
if ((rtcp_PSFB_get_media_source_ssrc(m) == rtp_session_get_send_ssrc(stream->ms.sessions.rtp_session))
&& (rtcp_PSFB_get_packet_sender_ssrc(m) == 0)) {
for (i = 0; ; i++) {
rtcp_fb_fir_fci_t *fci = rtcp_PSFB_fir_get_fci(m, i);
if (fci == NULL) break;
if (rtcp_fb_fir_fci_get_ssrc(fci) == rtp_session_get_recv_ssrc(stream->ms.sessions.rtp_session)) {
uint8_t seq_nr = rtcp_fb_fir_fci_get_seq_nr(fci);
ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_FIR, &seq_nr);
break;
}
}
} else {
if ((rtcp_PSFB_get_media_source_ssrc(m) == rtp_session_get_send_ssrc(stream->ms.sessions.rtp_session))
&& (rtcp_PSFB_get_packet_sender_ssrc(m) == rtp_session_get_recv_ssrc(stream->ms.sessions.rtp_session))) {
switch (rtcp_PSFB_get_type(m)) {
case RTCP_PSFB_PLI:
ms_filter_call_method_noarg(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_PLI);
break;
case RTCP_PSFB_SLI:
for (i = 0; ; i++) {
rtcp_fb_sli_fci_t *fci = rtcp_PSFB_sli_get_fci(m, i);
MSVideoCodecSLI sli;
if (fci == NULL) break;
sli.first = rtcp_fb_sli_fci_get_first(fci);
sli.number = rtcp_fb_sli_fci_get_number(fci);
sli.picture_id = rtcp_fb_sli_fci_get_picture_id(fci);
ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_SLI, &sli);
}
break;
case RTCP_PSFB_RPSI:
{
rtcp_fb_rpsi_fci_t *fci = rtcp_PSFB_rpsi_get_fci(m);
MSVideoCodecRPSI rpsi;
rpsi.bit_string = rtcp_fb_rpsi_fci_get_bit_string(fci);
rpsi.bit_string_len = rtcp_PSFB_rpsi_get_fci_bit_string_len(m);
ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_RPSI, &rpsi);
}
} else {
if ((rtcp_PSFB_get_media_source_ssrc(m) == rtp_session_get_send_ssrc(stream->ms.sessions.rtp_session))
&& (rtcp_PSFB_get_packet_sender_ssrc(m) == rtp_session_get_recv_ssrc(stream->ms.sessions.rtp_session))) {
switch (rtcp_PSFB_get_type(m)) {
case RTCP_PSFB_PLI:
ms_filter_call_method_noarg(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_PLI);
break;
case RTCP_PSFB_SLI:
for (i = 0; ; i++) {
rtcp_fb_sli_fci_t *fci = rtcp_PSFB_sli_get_fci(m, i);
MSVideoCodecSLI sli;
if (fci == NULL) break;
sli.first = rtcp_fb_sli_fci_get_first(fci);
sli.number = rtcp_fb_sli_fci_get_number(fci);
sli.picture_id = rtcp_fb_sli_fci_get_picture_id(fci);
ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_SLI, &sli);
}
break;
default:
break;
break;
case RTCP_PSFB_RPSI:
{
rtcp_fb_rpsi_fci_t *fci = rtcp_PSFB_rpsi_get_fci(m);
MSVideoCodecRPSI rpsi;
rpsi.bit_string = rtcp_fb_rpsi_fci_get_bit_string(fci);
rpsi.bit_string_len = rtcp_PSFB_rpsi_get_fci_bit_string_len(m);
ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_NOTIFY_RPSI, &rpsi);
}
break;
default:
break;
}
}
}
}while(rtcp_next_packet(m));
}
}
static void stop_preload_graph(VideoStream *stream){
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment