From: <ra...@fr...> - 2004-08-19 22:53:06
|
CVS Root: /cvs/gstreamer Module: gst-sandbox Changes by: ramon Date: Thu Aug 19 2004 15:53:03 PDT Log message: rtp_report.c: implemented some missing functions Modified files: rtpdec : Makefile rtp_report.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/rtpdec/Makefile.diff?r1=1.4&r2=1.5 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/rtpdec/rtp_report.c.diff?r1=1.11&r2=1.12 ====Begin Diffs==== Index: Makefile =================================================================== RCS file: /cvs/gstreamer/gst-sandbox/rtpdec/Makefile,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- Makefile 13 Aug 2004 10:30:53 -0000 1.4 +++ Makefile 19 Aug 2004 22:52:51 -0000 1.5 @@ -1,4 +1,4 @@ -CFLAGS=$(shell pkg-config --cflags gstreamer-0.8) -DGST_PACKAGE='"GStreamer"' -DGST_ORIGIN='"http://gstreamer.net"' -DVERSION='"0.0"' -Werror +CFLAGS=$(shell pkg-config --cflags gstreamer-0.8) -DGST_PACKAGE='"GStreamer"' -DGST_ORIGIN='"http://gstreamer.net"' -DVERSION='"0.0"' -Wall -Werror check: gstrtpdec.o rtpdec.o rtp_report.o socket_fns.o Index: rtp_report.c RCS file: /cvs/gstreamer/gst-sandbox/rtpdec/rtp_report.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- rtp_report.c 13 Aug 2004 10:30:53 -0000 1.11 +++ rtp_report.c 19 Aug 2004 22:52:51 -0000 1.12 @@ -10,13 +10,13 @@ #include <glib/gtypes.h> #include <glib/gmain.h> #include <sys/poll.h> +#include <unistd.h> #include "rtp_report.h" #include "gstrtpdec.h" #include "rtp_packet.h" /* Todo list in this file: - implement send_report implement get_interval_for_bye implement decide_num_recp_blocks take care of races. The main thread removing a sender from the list, @@ -40,15 +40,17 @@ static void update_wait_time (const GstRtpdec * rtpdec, wait_result_t wait_result, GTimeVal * wait_time, - const GTimeVal * elapsed_time, rtp_mode_t rtp_mode); + const GTimeVal * elapsed_time); static char read_report_thread_message (const GstRtpdec * rtpdec); -static void send_report (GstRtpdec * rtpdec); +static void send_report (GstRtpdec * rtpdec, gboolean do_bye); static void wait_and_send_bye (GstRtpdec * rtpdec); -static void send_bye (GstRtpdec * rtpdec); +static void update_bye_wait_time (const GstRtpdec * rtpdec, + guint* num_bye_senders, GTimeVal * wait_time, static float random_between (float a, float b); @@ -76,7 +78,7 @@ static float timeval_to_float(const GTimeVal* a); -static float_to_timeval(float f, GTimeVal* a); +static void float_to_timeval(float f, GTimeVal* a); @@ -88,7 +90,6 @@ { GstRtpdec *rtpdec = (GstRtpdec *) ptr; wait_result_t wait_result; - guint wait_time; while (1) { GTimeVal wait_time; @@ -100,18 +101,17 @@ wait_result = wait (rtpdec, &wait_time, &elapsed_time, RTP_NORMAL_MODE); if (wait_result == CALC_AGAIN_MEMBER_LEFT || wait_result == CALC_AGAIN_MEMBER_NEW) { - update_wait_time (rtpdec, wait_result, &wait_time, &elapsed_time, - RTP_NORMAL_MODE); + update_wait_time (rtpdec, wait_result, &wait_time, &elapsed_time); continue; } break; } switch (wait_result) { case DO_BYE: - send_bye (rtpdec); + send_report (rtpdec, TRUE); return NULL; case SEND_REPORT: - send_report(rtpdec); + wait_and_send_bye(rtpdec); break; default: g_assert_not_reached (); @@ -127,15 +127,14 @@ wait_result - event that causes the change in wait time. wait_time - new value of wait time. elapsed_time - time already spent, must be discounted by this function to - the wait time. - rtp_mode - whether we are leaving the conference (RTP_BYE_MODE) or we are - inside it */ + the wait time. */ + static void update_wait_time (const GstRtpdec * rtpdec, wait_result_t wait_result, - GTimeVal * wait_time, const GTimeVal * elapsed_time, rtp_mode_t rtp_mode) + GTimeVal * wait_time, const GTimeVal * elapsed_time) - sub_gtimeval(wait_time, elapsed_time); float wait_float; + sub_gtimeval(wait_time, elapsed_time); wait_float = timeval_to_float(wait_time); wait_float *= ((float)rtpdec->new_num_members)/rtpdec->num_members; float_to_timeval(wait_float, wait_time); @@ -220,39 +219,40 @@ fds[1].events = POLLIN; wait_time_ms = wait_time->tv_sec * 1000 + wait_time->tv_usec / 1000; g_get_current_time (&time_before); - retval = poll (fds, 1, wait_time_ms); - g_get_current_time (elapsed_time_waiting); - sub_gtimeval (elapsed_time_waiting, &time_before); - if (retval == 0) { - return SEND_REPORT; - } - g_assert (retval == 1); - msg = read_report_thread_message (rtpdec); - switch (msg) { - case NEW_MEMBER: - if (rtp_mode == RTP_NORMAL_MODE) { - return CALC_AGAIN_MEMBER_NEW; - } - break; - case LEFT_MEMBER: - return CALC_AGAIN_MEMBER_LEFT; - } else { - case PATH_MTU_CHANGED: - /* The last packet was not sent because its size was too large. Send one inmediatly */ + while (1) { + retval = poll (fds, 1, wait_time_ms); + g_get_current_time (elapsed_time_waiting); + sub_gtimeval (elapsed_time_waiting, &time_before); + if (retval == 0) { return SEND_REPORT; - case TERMINATE: - g_assert (rtp_mode == RTP_NORMAL_MODE); - return DO_BYE; - default: - g_assert_not_reached (); + } + g_assert (retval == 1); + msg = read_report_thread_message (rtpdec); + switch (msg) { + case NEW_MEMBER: + if (rtp_mode == RTP_NORMAL_MODE) { + return CALC_AGAIN_MEMBER_NEW; + } + break; + case LEFT_MEMBER: + return CALC_AGAIN_MEMBER_LEFT; + } else { + case PATH_MTU_CHANGED: + /* The last packet was not sent because its size was too large. Send one inmediatly */ + return SEND_REPORT; + case TERMINATE: + g_assert (rtp_mode == RTP_NORMAL_MODE); + return DO_BYE; + default: + g_assert_not_reached (); } - } @@ -269,12 +269,43 @@ /* Send a control report with current statistics */ -send_report (GstRtpdec * rtpdec) +send_report (GstRtpdec * rtpdec, gboolean do_bye) - /* FIXME: implement */ + char *buffer; + guint bufsize; + struct rtcp_recv_report *recv; + struct rtcp_sdes *sdes_cname; + guint sdes_size, recv_report_size; + guint num_recp_blocks; + num_recp_blocks = decide_num_recp_blocks (rtpdec); + recv_report_size = size_recv_report (num_recp_blocks); + sdes_size = size_sdes_cname (rtpdec->cname); + bufsize = recv_report_size + sdes_size; + if (do_bye) { + bufsize += sizeof (struct rtcp_bye); + } + buffer = g_malloc (bufsize); + if (!buffer) { + return; + recv = (struct rtcp_recv_report *) recv; + sdes_cname = (struct rtcp_sdes *) (recv + sizeof (struct rtcp_recv_report)); + store_stats_in_rr (rtpdec, recv, num_recp_blocks); + init_rtcp_cname (sdes_cname, rtpdec->myid, rtpdec->cname); + struct rtcp_bye *bye; + bye = (struct rtcp_bye *) (recv + sizeof (struct rtcp_recv_report) + + sdes_size); + init_rtcp_bye (bye, rtpdec->myid); + send_rtcp (rtpdec, buffer, bufsize); /* Send a bye message to leave the conference. But before we should wait some time, otherwise many people leaving at the same time would collapse @@ -287,59 +318,50 @@ get_interval_for_bye (rtpdec, &wait_time); wait_result_t wait_result; + guint num_bye_senders; GTimeVal elapsed_time_waiting; + num_bye_senders = 1; wait_result = - wait (rtpdec, &wait_time, &elapsed_time_waiting, RTP_BYE_MODE); + wait (rtpdec, &wait_time, &elapsed_time_waiting, RTP_BYE_MODE); g_assert (wait_result != CALC_AGAIN_MEMBER_LEFT); if (wait_result == CALC_AGAIN_MEMBER_NEW) { - update_wait_time (rtpdec, wait_result, &wait_time, &elapsed_time_waiting, - RTP_BYE_MODE); + update_bye_wait_time (rtpdec, &num_bye_senders, &wait_time, &elapsed_time_waiting); continue; } else { - send_bye (rtpdec); + send_report(rtpdec, TRUE); /* Evaluate the time that we should wait before sending a BYE message */ get_interval_for_bye (const GstRtpdec * rtpdec, GTimeVal * result) -} -/* Send now a BYE message to leave the RTP conference */ -static void -send_bye (GstRtpdec * rtpdec) -{ - char *buffer; - guint bufsize; - struct rtcp_recv_report *recv; - struct rtcp_sdes *sdes_cname; - struct rtcp_bye *bye; - guint sdes_size, recv_report_size; - guint num_recp_blocks; - num_recp_blocks = decide_num_recp_blocks (rtpdec); - recv_report_size = size_recv_report (num_recp_blocks); - sdes_size = size_sdes_cname (rtpdec->cname); - bufsize = recv_report_size + sdes_size + sizeof (struct rtcp_bye); - buffer = g_malloc (bufsize); - if (!buffer) { + if (!rtpdec->multicast_mode) { + result->tv_sec = 0; + result->tv_usec = 0; return; + } else { + float time; + const float min_interval = 5.0f; + const float factor_compens = 1.21828f; + time = min_interval*random_between(0.5f, 1.5f)*factor_compens; + result->tv_sec = floor(time); + result->tv_usec = time - floor(time) * 1000000; - recv = (struct rtcp_recv_report *) recv; - sdes_cname = (struct rtcp_sdes *) (recv + sizeof (struct rtcp_recv_report)); - bye = (struct rtcp_bye *) (recv + sizeof (struct rtcp_recv_report) + - sdes_size); - store_stats_in_rr (rtpdec, recv, num_recp_blocks); - init_rtcp_cname (sdes_cname, rtpdec->myid, rtpdec->cname); - init_rtcp_bye (bye, rtpdec->myid); - send_rtcp (rtpdec, buffer, bufsize); +static void +update_bye_wait_time(const GstRtpdec* rtpdec, guint* num_bye_senders, + GTimeVal* wait_time, const GTimeVal* elapsed_time_waiting) +{ + float wait_float; + sub_gtimeval(wait_time, elapsed_time_waiting); + wait_float = timeval_to_float(wait_time); + wait_float = wait_float*(*num_bye_senders + 1)/(*num_bye_senders); + *num_bye_senders++; +} /* Code to setup the data structures of a RTCP message */ @@ -495,8 +517,9 @@ return a->tv_sec + ((float) a->tv_usec)/1000000; -static float_to_timeval(float f, GTimeVal* a) +static void float_to_timeval(float f, GTimeVal* a) a->tv_sec = floor(f); a->tv_usec = (f - floor(f))*1000000; |