You can subscribe to this list here.
2000 |
Jan
(16) |
Feb
(60) |
Mar
(22) |
Apr
(14) |
May
(24) |
Jun
(20) |
Jul
(15) |
Aug
(55) |
Sep
(39) |
Oct
(27) |
Nov
(33) |
Dec
(53) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(186) |
Feb
(87) |
Mar
(153) |
Apr
(186) |
May
(316) |
Jun
(376) |
Jul
(84) |
Aug
(135) |
Sep
(251) |
Oct
(327) |
Nov
(78) |
Dec
(1619) |
2002 |
Jan
(828) |
Feb
(500) |
Mar
(314) |
Apr
(310) |
May
(306) |
Jun
(361) |
Jul
(320) |
Aug
(136) |
Sep
(427) |
Oct
(285) |
Nov
(248) |
Dec
(344) |
2003 |
Jan
(469) |
Feb
(215) |
Mar
(148) |
Apr
(310) |
May
(303) |
Jun
(227) |
Jul
(315) |
Aug
(158) |
Sep
(191) |
Oct
(325) |
Nov
(479) |
Dec
(417) |
2004 |
Jan
(529) |
Feb
(445) |
Mar
(550) |
Apr
(380) |
May
(385) |
Jun
(263) |
Jul
(393) |
Aug
(186) |
Sep
(138) |
Oct
(272) |
Nov
(254) |
Dec
(259) |
2005 |
Jan
(310) |
Feb
(234) |
Mar
(171) |
Apr
(316) |
May
(364) |
Jun
(381) |
Jul
(420) |
Aug
(489) |
Sep
(663) |
Oct
(735) |
Nov
(839) |
Dec
(403) |
2006 |
Jan
(340) |
Feb
(445) |
Mar
(433) |
Apr
(451) |
May
(438) |
Jun
(312) |
Jul
(315) |
Aug
(283) |
Sep
(290) |
Oct
(243) |
Nov
(195) |
Dec
(182) |
2007 |
Jan
(278) |
Feb
(256) |
Mar
(318) |
Apr
(250) |
May
(286) |
Jun
(249) |
Jul
(226) |
Aug
(179) |
Sep
(265) |
Oct
(234) |
Nov
(244) |
Dec
(272) |
2008 |
Jan
(414) |
Feb
(379) |
Mar
(206) |
Apr
(308) |
May
(422) |
Jun
(350) |
Jul
(205) |
Aug
(349) |
Sep
(127) |
Oct
(306) |
Nov
(359) |
Dec
(236) |
2009 |
Jan
(326) |
Feb
(453) |
Mar
(684) |
Apr
(702) |
May
(1106) |
Jun
(774) |
Jul
(441) |
Aug
(561) |
Sep
(603) |
Oct
(824) |
Nov
(539) |
Dec
(347) |
2010 |
Jan
(470) |
Feb
(448) |
Mar
(845) |
Apr
(512) |
May
(428) |
Jun
(893) |
Jul
(347) |
Aug
(350) |
Sep
(689) |
Oct
(456) |
Nov
(254) |
Dec
(860) |
2011 |
Jan
(763) |
Feb
(106) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <mn...@ke...> - 2011-02-02 14:42:32
|
Module: gst-plugins-base Branch: master Commit: 2c017d2a70d49bf3a9cd40ba203b383e4a54fe59 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-base/commit/?id=2c017d2a70d49bf3a9cd40ba203b383e4a54fe59 Author: Mark Nauwelaerts <mar...@co...> Date: Wed Feb 2 15:33:36 2011 +0100 uridecodebin: fix copy-and-paste typo in property docs --- gst/playback/gsturidecodebin.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index a72c8f2..d36fff9 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -407,7 +407,7 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** - * GstQueue2:ring-buffer-max-size + * GstURIDecodeBin::ring-buffer-max-size * * The maximum size of the ring buffer in kilobytes. If set to 0, the ring * buffer is disabled. Default is 0. |
From: <mn...@ke...> - 2011-02-02 14:38:36
|
Module: gstreamer Branch: master Commit: e14c133587343c2298eccf2a88afe5455ae4cb51 URL: http://cgit.freedesktop.org/gstreamer/gstreamer/commit/?id=e14c133587343c2298eccf2a88afe5455ae4cb51 Author: Mark Nauwelaerts <mar...@co...> Date: Wed Feb 2 15:35:45 2011 +0100 queue2: properly identity dequeued event as such ... which avoids terminating with ERROR rather than UNEXPECTED. --- plugins/elements/gstqueue2.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/plugins/elements/gstqueue2.c b/plugins/elements/gstqueue2.c index 5d70f89..956f2b9 100644 --- a/plugins/elements/gstqueue2.c +++ b/plugins/elements/gstqueue2.c @@ -1927,6 +1927,8 @@ gst_queue2_locked_dequeue (GstQueue2 * queue, gboolean * is_buffer) } else if (GST_IS_EVENT (item)) { GstEvent *event = GST_EVENT_CAST (item); + *is_buffer = FALSE; + GST_CAT_LOG_OBJECT (queue_dataflow, queue, "retrieved event %p from queue", event); |
From: <wt...@ke...> - 2011-02-02 14:37:31
|
Module: gst-rtsp-server Branch: master Commit: a924e90c7944ec6b82202b5d3932636780c8d489 URL: http://cgit.freedesktop.org/gstreamer/gst-rtsp-server/commit/?id=a924e90c7944ec6b82202b5d3932636780c8d489 Author: Wim Taymans <wim...@co...> Date: Wed Feb 2 15:37:03 2011 +0100 media: remove more unused code --- gst/rtsp-server/rtsp-media.c | 46 ------------------------------------------ 1 files changed, 0 insertions(+), 46 deletions(-) diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index 38a37d7..357027a 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -160,45 +160,6 @@ gst_rtsp_media_init (GstRTSPMedia * media) media->buffer_size = DEFAULT_BUFFER_SIZE; } -/* FIXME. this should be done in multiudpsink */ -typedef struct -{ - gint count; - gchar *dest; - gint min, max; -} RTSPDestination; - -static gint -dest_compare (RTSPDestination * a, RTSPDestination * b) -{ - if ((a->min == b->min) && (a->max == b->max) - && (strcmp (a->dest, b->dest) == 0)) - return 0; - - return 1; -} - -static RTSPDestination * -create_destination (const gchar * dest, gint min, gint max) -{ - RTSPDestination *res; - - res = g_slice_new (RTSPDestination); - res->count = 1; - res->dest = g_strdup (dest); - res->min = min; - res->max = max; - - return res; -} - -static void -free_destination (RTSPDestination * dest) -{ - g_free (dest->dest); - g_slice_free (RTSPDestination, dest); -} - void gst_rtsp_media_trans_cleanup (GstRTSPMediaTrans * trans) { @@ -1852,9 +1813,6 @@ static void add_udp_destination (GstRTSPMedia * media, GstRTSPMediaStream * stream, gchar * dest, gint min, gint max) { - gboolean do_add = TRUE; - RTSPDestination *ndest; - GST_INFO ("adding %s:%d-%d", dest, min, max); g_signal_emit_by_name (stream->udpsink[0], "add", dest, min, NULL); g_signal_emit_by_name (stream->udpsink[1], "add", dest, max, NULL); @@ -1864,10 +1822,6 @@ static void remove_udp_destination (GstRTSPMedia * media, GstRTSPMediaStream * stream, gchar * dest, gint min, gint max) { - gboolean do_remove = TRUE; - RTSPDestination *ndest = NULL; - GList *find = NULL; - GST_INFO ("removing %s:%d-%d", dest, min, max); g_signal_emit_by_name (stream->udpsink[0], "remove", dest, min, NULL); g_signal_emit_by_name (stream->udpsink[1], "remove", dest, max, NULL); |
From: <wt...@ke...> - 2011-02-02 14:32:40
|
Module: gst-rtsp-server Branch: master Commit: ec2201a3a8adee4463ac2d52194c814f48b28f20 URL: http://cgit.freedesktop.org/gstreamer/gst-rtsp-server/commit/?id=ec2201a3a8adee4463ac2d52194c814f48b28f20 Author: Wim Taymans <wim...@co...> Date: Wed Feb 2 15:30:45 2011 +0100 media: remove duplicate filtering Remove the duplicate filtering code now that we have a released -good version. Give a warning instead. --- gst/rtsp-server/rtsp-media.c | 78 ++++------------------------------------- gst/rtsp-server/rtsp-media.h | 5 --- 2 files changed, 8 insertions(+), 75 deletions(-) diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index d6a7f25..38a37d7 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -234,9 +234,6 @@ gst_rtsp_media_stream_free (GstRTSPMediaStream * stream) g_list_free (stream->transports); - g_list_foreach (stream->destinations, (GFunc) free_destination, NULL); - g_list_free (stream->destinations); - g_free (stream); } @@ -943,10 +940,9 @@ again: "send-duplicates")) { g_object_set (G_OBJECT (udpsink0), "send-duplicates", FALSE, NULL); g_object_set (G_OBJECT (udpsink1), "send-duplicates", FALSE, NULL); - stream->filter_duplicates = FALSE; } else { - GST_WARNING ("multiudpsink version found without send-duplicates property"); - stream->filter_duplicates = TRUE; + g_warning + ("old multiudpsink version found without send-duplicates property"); } if (g_object_class_find_property (G_OBJECT_GET_CLASS (udpsink0), @@ -1859,38 +1855,9 @@ add_udp_destination (GstRTSPMedia * media, GstRTSPMediaStream * stream, gboolean do_add = TRUE; RTSPDestination *ndest; - if (stream->filter_duplicates) { - RTSPDestination fdest; - GList *find; - - fdest.dest = dest; - fdest.min = min; - fdest.max = max; - - /* first see if we already added this destination */ - find = - g_list_find_custom (stream->destinations, &fdest, - (GCompareFunc) dest_compare); - if (find) { - ndest = (RTSPDestination *) find->data; - - GST_INFO ("already streaming to %s:%d-%d with %d clients", dest, min, max, - ndest->count); - ndest->count++; - do_add = FALSE; - } - } - - if (do_add) { - GST_INFO ("adding %s:%d-%d", dest, min, max); - g_signal_emit_by_name (stream->udpsink[0], "add", dest, min, NULL); - g_signal_emit_by_name (stream->udpsink[1], "add", dest, max, NULL); - - if (stream->filter_duplicates) { - ndest = create_destination (dest, min, max); - stream->destinations = g_list_prepend (stream->destinations, ndest); - } - } + GST_INFO ("adding %s:%d-%d", dest, min, max); + g_signal_emit_by_name (stream->udpsink[0], "add", dest, min, NULL); + g_signal_emit_by_name (stream->udpsink[1], "add", dest, max, NULL); } static void @@ -1901,38 +1868,9 @@ remove_udp_destination (GstRTSPMedia * media, GstRTSPMediaStream * stream, RTSPDestination *ndest = NULL; GList *find = NULL; - if (stream->filter_duplicates) { - RTSPDestination fdest; - - fdest.dest = dest; - fdest.min = min; - fdest.max = max; - - /* first see if we already added this destination */ - find = - g_list_find_custom (stream->destinations, &fdest, - (GCompareFunc) dest_compare); - if (!find) - return; - - ndest = (RTSPDestination *) find->data; - if (--ndest->count > 0) { - do_remove = FALSE; - GST_INFO ("still streaming to %s:%d-%d with %d clients", dest, min, max, - ndest->count); - } - } - - if (do_remove) { - GST_INFO ("removing %s:%d-%d", dest, min, max); - g_signal_emit_by_name (stream->udpsink[0], "remove", dest, min, NULL); - g_signal_emit_by_name (stream->udpsink[1], "remove", dest, max, NULL); - - if (stream->filter_duplicates) { - stream->destinations = g_list_delete_link (stream->destinations, find); - free_destination (ndest); - } - } + GST_INFO ("removing %s:%d-%d", dest, min, max); + g_signal_emit_by_name (stream->udpsink[0], "remove", dest, min, NULL); + g_signal_emit_by_name (stream->udpsink[1], "remove", dest, max, NULL); } /** diff --git a/gst/rtsp-server/rtsp-media.h b/gst/rtsp-server/rtsp-media.h index 32c8226..2f103af 100644 --- a/gst/rtsp-server/rtsp-media.h +++ b/gst/rtsp-server/rtsp-media.h @@ -142,11 +142,6 @@ struct _GstRTSPMediaStream { /* transports we stream to */ GList *transports; - - /* to filter out duplicate destinations in case multiudpsink is too old to do - * this for us */ - gboolean filter_duplicates; - GList *destinations; }; /** |
From: <tp...@ke...> - 2011-02-02 09:15:23
|
Module: gstreamer Branch: master Commit: d9a24f585fa9c58f7c37a7c84f7dd0218184b5a3 URL: http://cgit.freedesktop.org/gstreamer/gstreamer/commit/?id=d9a24f585fa9c58f7c37a7c84f7dd0218184b5a3 Author: Peter Collingbourne <pe...@pc...> Date: Wed Feb 2 02:07:58 2011 +0000 gst-uninstalled: use $GST_PREFIX variable This makes it easier to change the prefix by editing the script. https://bugzilla.gnome.org/show_bug.cgi?id=641212 --- scripts/gst-uninstalled | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diff --git a/scripts/gst-uninstalled b/scripts/gst-uninstalled index 54bd5ad..c9aba1a 100755 --- a/scripts/gst-uninstalled +++ b/scripts/gst-uninstalled @@ -40,6 +40,7 @@ VERSION=`echo $0 | sed s/.*gst-//g` # base path under which dirs are installed GST=$MYGST/$VERSION +GST_PREFIX=$GST/prefix if test ! -e $GST; then echo "$GST does not exist !" exit @@ -52,12 +53,12 @@ $GST/gst-plugins-base/tools:\ $GST/gst-player/src:\ $GST/gst-editor/src:\ $GST/gstreamer-sharp/tools:\ -$GST/prefix/bin:\ +$GST_PREFIX/bin:\ $PATH" # /some/path: makes the dynamic linker look in . too, so avoid this -LD_LIBRARY_PATH=$GST/prefix/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} -DYLD_LIBRARY_PATH=$GST/prefix/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH} +LD_LIBRARY_PATH=$GST_PREFIX/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} +DYLD_LIBRARY_PATH=$GST_PREFIX/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH} # GStreamer rtsp server library LD_LIBRARY_PATH=$GST/gst-rtsp-server/gst/rtsp-server/.libs:$LD_LIBRARY_PATH @@ -89,7 +90,7 @@ export LD_LIBRARY_PATH export DYLD_LIBRARY_PATH export PKG_CONFIG_PATH="\ -$GST/prefix/lib/pkgconfig\ +$GST_PREFIX/lib/pkgconfig\ :$GST/gstreamer/pkgconfig\ :$GST/gst-plugins-base/pkgconfig\ :$GST/gst-plugins-good/pkgconfig\ @@ -135,9 +136,9 @@ export GST_PLUGIN_SCANNER=$GST/gstreamer/libs/gst/helpers/gst-plugin-scanner # in the system-configured man paths from man.config # this still doesn't make it work for the uninstalled case, since man goes # look for a man directory "nearby" instead of the directory I'm telling it to -export MANPATH=$GST/gstreamer/tools:$GST/prefix/share/man:$MANPATH +export MANPATH=$GST/gstreamer/tools:$GST_PREFIX/share/man:$MANPATH pythonver=`python -c "import sys; print sys.version[:3]"` -export PYTHONPATH=$GST/gst-python:$GST/prefix/lib/python$pythonver/site-packages${PYTHONPATH:+:$PYTHONPATH} +export PYTHONPATH=$GST/gst-python:$GST_PREFIX/lib/python$pythonver/site-packages${PYTHONPATH:+:$PYTHONPATH} # totem-pl-parser export PKG_CONFIG_PATH=$GST/totem-pl-parser:$PKG_CONFIG_PATH |
From: <mn...@ke...> - 2011-02-01 20:39:51
|
Module: gst-plugins-bad Branch: master Commit: c32a99559d2826668cb891cc7aff83af587e39b0 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/commit/?id=c32a99559d2826668cb891cc7aff83af587e39b0 Author: Mark Nauwelaerts <mar...@co...> Date: Mon Jan 31 17:24:24 2011 +0100 dccp: use socklen_t where appropriate rather than specific type In particular, fixes Cygwin build where socklen_t is defined as int in line with native win32 api definition. --- gst/dccp/gstdccp.c | 6 +----- gst/dccp/gstdccp_common.h | 3 +++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/gst/dccp/gstdccp.c b/gst/dccp/gstdccp.c index 470c217..af652f2 100644 --- a/gst/dccp/gstdccp.c +++ b/gst/dccp/gstdccp.c @@ -241,18 +241,14 @@ gst_dccp_server_wait_connections (GstElement * element, int server_sock_fd) /* new client */ int client_sock_fd; struct sockaddr_in client_address; - unsigned int client_address_len; + socklen_t client_address_len; memset (&client_address, 0, sizeof (client_address)); client_address_len = 0; if ((client_sock_fd = accept (server_sock_fd, (struct sockaddr *) &client_address, -#ifndef G_OS_WIN32 &client_address_len)) == -1) { -#else - (int *) &client_address_len)) == -1) { -#endif GST_ELEMENT_ERROR (element, RESOURCE, OPEN_WRITE, (NULL), ("Could not accept client on server socket %d: %s (%d)", server_sock_fd, g_strerror (errno), errno)); diff --git a/gst/dccp/gstdccp_common.h b/gst/dccp/gstdccp_common.h index 9657806..a2c2ca2 100644 --- a/gst/dccp/gstdccp_common.h +++ b/gst/dccp/gstdccp_common.h @@ -32,6 +32,9 @@ # define WINVER 0x0501 # include <winsock2.h> # include <ws2tcpip.h> +#ifndef socklen_t +#define socklen_t int +#endif #endif #include <sys/types.h> #include <unistd.h> |
From: <tp...@ke...> - 2011-02-01 20:12:16
|
Module: gst-plugins-bad Branch: master Commit: 17c2b30e9ba502a1a7b6b7e14c63ebc6f43ec908 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/commit/?id=17c2b30e9ba502a1a7b6b7e14c63ebc6f43ec908 Author: Tim-Philipp Müller <tim...@co...> Date: Tue Feb 1 20:01:13 2011 +0000 rtpvp8: also link against libgstbase-0.10 for adapter and bit reader API https://bugzilla.gnome.org/show_bug.cgi?id=641178 --- gst/rtpvp8/Makefile.am | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/rtpvp8/Makefile.am b/gst/rtpvp8/Makefile.am index 8a722eb..05bf5d7 100644 --- a/gst/rtpvp8/Makefile.am +++ b/gst/rtpvp8/Makefile.am @@ -7,8 +7,9 @@ libgstrtpvp8_la_SOURCES = gstrtpvp8.c \ noinst_HEADERS = gstrtpvp8depay.h \ gstrtpvp8pay.h -libgstrtpvp8_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) +libgstrtpvp8_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_BASE_CFLAGS) $(GST_CFLAGS) libgstrtpvp8_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-@GST_MAJORMINOR@ \ - $(GST_LIBS) + $(GST_BASE_LIBS) $(GST_LIBS) libgstrtpvp8_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstrtpvp8_la_LIBTOOLFLAGS = --tag=disable-static |
From: <mn...@ke...> - 2011-02-01 19:19:43
|
Module: gst-plugins-good Branch: master Commit: 564976b6095783d73849c51cf11e16b1a03483c4 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=564976b6095783d73849c51cf11e16b1a03483c4 Author: Mark Nauwelaerts <mar...@co...> Date: Tue Feb 1 19:40:58 2011 +0100 directsound: arrange for definition of _swab on Cygwin gstdirectsoundsink.c: In function 'gst_directsound_sink_write': gstdirectsoundsink.c:557: error: implicit declaration of function '_swab' gstdirectsoundsink.c:557: error: nested extern declaration of '_swab' --- sys/directsound/gstdirectsoundsink.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/sys/directsound/gstdirectsoundsink.c b/sys/directsound/gstdirectsoundsink.c index e64c8ac..462c412 100644 --- a/sys/directsound/gstdirectsoundsink.c +++ b/sys/directsound/gstdirectsoundsink.c @@ -56,6 +56,13 @@ #include <math.h> +#ifdef __CYGWIN__ +#include <unistd.h> +#ifndef _swab +#define _swab swab +#endif +#endif + GST_DEBUG_CATEGORY_STATIC (directsoundsink_debug); #define GST_CAT_DEFAULT directsoundsink_debug |
From: <wt...@ke...> - 2011-02-01 18:00:56
|
Module: gst-plugins-good Branch: master Commit: 8a7a327db7dd0e677844599f4a0db76a7d06b512 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=8a7a327db7dd0e677844599f4a0db76a7d06b512 Author: Olivier Crête <oli...@co...> Date: Wed Oct 6 21:17:28 2010 -0400 rtptheoradepay: Request new keyframe on lost packets Theora can only use the last frame (or the keyframe) as a reference, so in practice. If we receive a buffer that references an unknown codebook, request new headers. It probably means that headers were lost. --- gst/rtp/gstrtptheoradepay.c | 52 ++++++++++++++++++++++++++++++++++++++++-- gst/rtp/gstrtptheoradepay.h | 2 + 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/gst/rtp/gstrtptheoradepay.c b/gst/rtp/gstrtptheoradepay.c index dfe6de3..a21cc6c 100644 --- a/gst/rtp/gstrtptheoradepay.c +++ b/gst/rtp/gstrtptheoradepay.c @@ -67,6 +67,8 @@ static gboolean gst_rtp_theora_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps); static GstBuffer *gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf); +static gboolean gst_rtp_theora_depay_packet_lost (GstBaseRTPDepayload * + depayload, GstEvent * event); static void gst_rtp_theora_depay_finalize (GObject * object); @@ -100,6 +102,7 @@ gst_rtp_theora_depay_class_init (GstRtpTheoraDepayClass * klass) gstbasertpdepayload_class->process = gst_rtp_theora_depay_process; gstbasertpdepayload_class->set_caps = gst_rtp_theora_depay_setcaps; + gstbasertpdepayload_class->packet_lost = gst_rtp_theora_depay_packet_lost; GST_DEBUG_CATEGORY_INIT (rtptheoradepay_debug, "rtptheoradepay", 0, "Theora RTP Depayloader"); @@ -308,6 +311,8 @@ gst_rtp_theora_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) rtptheoradepay = GST_RTP_THEORA_DEPAY (depayload); + rtptheoradepay->needs_keyframe = FALSE; + structure = gst_caps_get_structure (caps, 0); /* read and parse configuration string */ @@ -554,6 +559,9 @@ gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) memcpy (GST_BUFFER_DATA (outbuf), payload, length); } + if ((payload[0] & 0xC0) == 0x0) + rtptheoradepay->needs_keyframe = FALSE; + payload += length; payload_len -= length; @@ -573,6 +581,9 @@ gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) g_free (to_free); + if (rtptheoradepay->needs_keyframe) + goto request_keyframe; + return NULL; no_output: @@ -584,13 +595,13 @@ switch_failed: { GST_ELEMENT_WARNING (rtptheoradepay, STREAM, DECODE, (NULL), ("Could not switch codebooks")); - return NULL; + goto request_config; } packet_short: { GST_ELEMENT_WARNING (rtptheoradepay, STREAM, DECODE, (NULL), ("Packet was too short (%d < 4)", payload_len)); - return NULL; + goto request_keyframe; } ignore_reserved: { @@ -601,13 +612,29 @@ length_short: { GST_ELEMENT_WARNING (rtptheoradepay, STREAM, DECODE, (NULL), ("Packet contains invalid data")); - return NULL; + goto request_keyframe; } invalid_configuration: { /* fatal, as we otherwise risk carrying on without output */ GST_ELEMENT_ERROR (rtptheoradepay, STREAM, DECODE, (NULL), ("Packet contains invalid configuration")); + goto request_config; + } +request_config: + { + gst_pad_push_event (GST_BASE_RTP_DEPAYLOAD_SINKPAD (depayload), + gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, + gst_structure_new ("GstForceKeyUnit", + "all-headers", G_TYPE_BOOLEAN, TRUE, NULL))); + return NULL; + } +request_keyframe: + { + rtptheoradepay->needs_keyframe = TRUE; + gst_pad_push_event (GST_BASE_RTP_DEPAYLOAD_SINKPAD (depayload), + gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, + gst_structure_new ("GstForceKeyUnit", NULL))); return NULL; } } @@ -618,3 +645,22 @@ gst_rtp_theora_depay_plugin_init (GstPlugin * plugin) return gst_element_register (plugin, "rtptheoradepay", GST_RANK_SECONDARY, GST_TYPE_RTP_THEORA_DEPAY); } + +static gboolean +gst_rtp_theora_depay_packet_lost (GstBaseRTPDepayload * depayload, + GstEvent * event) +{ + GstRtpTheoraDepay *rtptheoradepay = GST_RTP_THEORA_DEPAY (depayload); + guint seqnum = 0; + + gst_structure_get_uint (event->structure, "seqnum", &seqnum); + GST_LOG_OBJECT (depayload, "Requested keyframe because frame with seqnum %u" + " is missing", seqnum); + rtptheoradepay->needs_keyframe = TRUE; + + gst_pad_push_event (GST_BASE_RTP_DEPAYLOAD_SINKPAD (depayload), + gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, + gst_structure_new ("GstForceKeyUnit", NULL))); + + return TRUE; +} diff --git a/gst/rtp/gstrtptheoradepay.h b/gst/rtp/gstrtptheoradepay.h index 0d1a911..dff261c 100644 --- a/gst/rtp/gstrtptheoradepay.h +++ b/gst/rtp/gstrtptheoradepay.h @@ -54,6 +54,8 @@ struct _GstRtpTheoraDepay GstAdapter *adapter; gboolean assembling; + + gboolean needs_keyframe; }; struct _GstRtpTheoraDepayClass |
From: <wt...@ke...> - 2011-02-01 18:00:53
|
Module: gst-plugins-good Branch: master Commit: cd923223dd24576679ff91deda71cc8f172504c3 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=cd923223dd24576679ff91deda71cc8f172504c3 Author: Olivier Crête <oli...@co...> Date: Fri Aug 27 14:11:53 2010 -0400 rtpsession: Add action signal to request early RTCP --- gst/rtpmanager/gstrtpbin-marshal.list | 1 + gst/rtpmanager/rtpsession.c | 33 +++++++++++++++++++++++++++++++++ gst/rtpmanager/rtpsession.h | 1 + 3 files changed, 35 insertions(+), 0 deletions(-) diff --git a/gst/rtpmanager/gstrtpbin-marshal.list b/gst/rtpmanager/gstrtpbin-marshal.list index 5176b33..7d9821f 100644 --- a/gst/rtpmanager/gstrtpbin-marshal.list +++ b/gst/rtpmanager/gstrtpbin-marshal.list @@ -9,3 +9,4 @@ VOID:OBJECT,OBJECT UINT64:BOOL,UINT64 BOOL:POINTER,BOOL VOID:UINT,UINT,UINT,UINT,POINTER +VOID:UINT64 diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index a60e7c0..49ce69b 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -44,6 +44,7 @@ enum SIGNAL_ON_SENDER_TIMEOUT, SIGNAL_ON_SENDING_RTCP, SIGNAL_ON_FEEDBACK_RTCP, + SIGNAL_SEND_RTCP, LAST_SIGNAL }; @@ -104,6 +105,8 @@ static void rtp_session_get_property (GObject * object, guint prop_id, static gboolean rtp_session_on_sending_rtcp (RTPSession * sess, GstBuffer * buffer, gboolean early); +static void rtp_session_send_rtcp (RTPSession * sess, + GstClockTimeDiff max_delay); static guint rtp_session_signals[LAST_SIGNAL] = { 0 }; @@ -299,6 +302,22 @@ rtp_session_class_init (RTPSessionClass * klass) G_TYPE_NONE, 4, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_POINTER); + /** + * RTPSession::send-rtcp: + * @session: the object which received the signal + * @max_delay: The maximum delay after which the feedback will not be useful + * anymore + * + * Requests that the #RTPSession initiate a new RTCP packet as soon as + * possible within the requested delay. + */ + + rtp_session_signals[SIGNAL_SEND_RTCP] = + g_signal_new ("send-rtcp", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (RTPSessionClass, send_rtcp), NULL, NULL, + gst_rtp_bin_marshal_VOID__UINT64, G_TYPE_NONE, 1, G_TYPE_UINT64); + g_object_class_install_property (gobject_class, PROP_INTERNAL_SSRC, g_param_spec_uint ("internal-ssrc", "Internal SSRC", "The internal SSRC used for the session", @@ -408,6 +427,7 @@ rtp_session_class_init (RTPSessionClass * klass) klass->get_source_by_ssrc = GST_DEBUG_FUNCPTR (rtp_session_get_source_by_ssrc); klass->on_sending_rtcp = GST_DEBUG_FUNCPTR (rtp_session_on_sending_rtcp); + klass->send_rtcp = GST_DEBUG_FUNCPTR (rtp_session_send_rtcp); GST_DEBUG_CATEGORY_INIT (rtp_session_debug, "rtpsession", 0, "RTP Session"); } @@ -3134,3 +3154,16 @@ rtp_session_on_sending_rtcp (RTPSession * sess, GstBuffer * buffer, return ret; } + +static void +rtp_session_send_rtcp (RTPSession * sess, GstClockTimeDiff max_delay) +{ + GstClockTime now; + + if (!sess->callbacks.send_rtcp) + return; + + now = sess->callbacks.request_time (sess, sess->request_time_user_data); + + rtp_session_request_early_rtcp (sess, now, max_delay); +} diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index 3746a9b..3268490 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -264,6 +264,7 @@ struct _RTPSessionClass { gboolean early); void (*on_feedback_rtcp) (RTPSession *sess, guint type, guint fbtype, guint sender_ssrc, guint media_ssrc, GstBuffer *fci); + void (*send_rtcp) (RTPSession *sess, GstClockTimeDiff max_delay); }; GType rtp_session_get_type (void); |
From: <wt...@ke...> - 2011-02-01 18:00:52
|
Module: gst-plugins-good Branch: master Commit: f399b6a641faf8dea373bf39f17b774be51924cf URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=f399b6a641faf8dea373bf39f17b774be51924cf Author: Wim Taymans <wim...@co...> Date: Tue Feb 1 18:17:13 2011 +0100 rtpsession: fix compilation --- gst/rtpmanager/rtpsession.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index 7d806ee..a0ac833 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -2809,12 +2809,11 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time, data.rtcp, data.is_early, &do_not_suppress); if (sess->callbacks.send_rtcp && (do_not_suppress || !data.may_suppress)) { + guint packet_size; + /* close the RTCP packet */ gst_rtcp_buffer_end (data.rtcp); - if (sess->callbacks.send_rtcp) { - guint packet_size; - packet_size = GST_BUFFER_SIZE (data.rtcp) + sess->header_len; UPDATE_AVG (sess->stats.avg_rtcp_packet_size, packet_size); |
From: <wt...@ke...> - 2011-02-01 18:00:52
|
Module: gst-plugins-good Branch: master Commit: 90354ecb49096408ba6e21b9e050f4c61c9ddcb0 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=90354ecb49096408ba6e21b9e050f4c61c9ddcb0 Author: Olivier Crête <oli...@co...> Date: Tue Sep 7 13:35:16 2010 +0300 rtpsession: Make rtcp buffer metadata writable after processing it Functions that process the rtcp buffer could decide to keep a ref on the buffer for further processing. So make the metadata writable only after they are done. --- gst/rtpmanager/rtpsession.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index d4bbf08..5938d55 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -2048,9 +2048,6 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, if (sess->sent_bye) goto ignore; - /* make writable, we might want to change the buffer */ - buffer = gst_buffer_make_metadata_writable (buffer); - /* start processing the compound packet */ more = gst_rtcp_buffer_get_first_packet (buffer, &packet); while (more) { @@ -2111,10 +2108,13 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, RTP_SESSION_UNLOCK (sess); /* notify caller of sr packets in the callback */ - if (do_sync && sess->callbacks.sync_rtcp) + if (do_sync && sess->callbacks.sync_rtcp) { + /* make writable, we might want to change the buffer */ + buffer = gst_buffer_make_metadata_writable (buffer); + result = sess->callbacks.sync_rtcp (sess, sess->source, buffer, sess->sync_rtcp_user_data); - else + } else gst_buffer_unref (buffer); return result; |
From: <wt...@ke...> - 2011-02-01 18:00:52
|
Module: gst-plugins-good Branch: master Commit: a630c68fc312d4ec79ca514f8770802da3c8ce26 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=a630c68fc312d4ec79ca514f8770802da3c8ce26 Author: Olivier Crête <oli...@co...> Date: Tue Oct 19 22:21:54 2010 +0200 rtpsession: Don't relay more than one PLI request per RTT Drop PLI requests if one was relay in the last RTT, the other side may just not have received the keyframe yet. --- gst/rtpmanager/rtpsession.c | 49 ++++++++++++++++++++++++++++++++++++++---- gst/rtpmanager/rtpsession.h | 1 + 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index d3a7a54..cf73043 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -2007,10 +2007,50 @@ rtp_session_process_app (RTPSession * sess, GstRTCPPacket * packet, GST_DEBUG ("received APP"); } +static void +rtp_session_process_pli (RTPSession * sess, guint32 sender_ssrc, + guint32 media_ssrc, GstClockTime current_time) +{ + RTPSource *src; + guint32 round_trip = 0; + + if (!sess->callbacks.request_key_unit) + return; + + src = g_hash_table_lookup (sess->ssrcs[sess->mask_idx], + GINT_TO_POINTER (sender_ssrc)); + + if (!src) + return; + + if (sess->last_keyframe_request != GST_CLOCK_TIME_NONE && + rtp_source_get_last_rb (src, NULL, NULL, NULL, NULL, NULL, NULL, + &round_trip)) { + GstClockTime round_trip_in_ns = gst_util_uint64_scale (round_trip, + GST_SECOND, 65536); + + if (sess->last_keyframe_request != GST_CLOCK_TIME_NONE && + current_time - sess->last_keyframe_request < round_trip_in_ns) { + GST_DEBUG ("Ignoring PLI because one was send without one RTT (%" + GST_TIME_FORMAT " < %" GST_TIME_FORMAT ")", + GST_TIME_ARGS (current_time - sess->last_keyframe_request), + GST_TIME_ARGS (round_trip_in_ns));; + return; + } + } + + sess->last_keyframe_request = current_time; + + GST_LOG ("received PLI from %X %p(%p)", sender_ssrc, + sess->callbacks.process_rtp, sess->callbacks.request_key_unit); + + sess->callbacks.request_key_unit (sess, FALSE, + sess->request_key_unit_user_data); +} static void rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet, - RTPArrivalStats * arrival) + RTPArrivalStats * arrival, GstClockTime current_time) { GstRTCPType type = gst_rtcp_packet_get_type (packet); GstRTCPFBType fbtype = gst_rtcp_packet_fb_get_type (packet); @@ -2052,9 +2092,8 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet, case GST_RTCP_TYPE_PSFB: switch (fbtype) { case GST_RTCP_PSFB_TYPE_PLI: - if (sess->callbacks.request_key_unit) - sess->callbacks.request_key_unit (sess, FALSE, - sess->request_key_unit_user_data); + rtp_session_process_pli (sess, sender_ssrc, media_ssrc, + current_time); break; default: break; @@ -2136,7 +2175,7 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, break; case GST_RTCP_TYPE_RTPFB: case GST_RTCP_TYPE_PSFB: - rtp_session_process_feedback (sess, &packet, &arrival); + rtp_session_process_feedback (sess, &packet, &arrival, current_time); break; default: GST_WARNING ("got unknown RTCP packet"); diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index 0cc1f6b..9510942 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -221,6 +221,7 @@ struct _RTPSession { GstClockTime rtcp_feedback_retention_window; GArray *rtcp_pli_requests; + GstClockTime last_keyframe_request; }; /** |
From: <wt...@ke...> - 2011-02-01 18:00:52
|
Module: gst-plugins-good Branch: master Commit: a61bb9e94b23f6dbed0319d6f018a8d857b2edcb URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=a61bb9e94b23f6dbed0319d6f018a8d857b2edcb Author: Olivier Crête <oli...@co...> Date: Wed Jun 23 16:43:24 2010 -0400 rtpsession: Send GstForceKeyUnit event in response to received RTCP PLI --- gst/rtpmanager/gstrtpsession.c | 18 +++++++++++++++++- gst/rtpmanager/rtpsession.c | 23 +++++++++++++++++++++++ gst/rtpmanager/rtpsession.h | 16 ++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletions(-) diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index cc784c8..994c53b 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -257,6 +257,8 @@ static GstFlowReturn gst_rtp_session_sync_rtcp (RTPSession * sess, static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload, gpointer user_data); static void gst_rtp_session_reconsider (RTPSession * sess, gpointer user_data); +static void gst_rtp_session_request_key_unit (RTPSession * sess, + gboolean all_headers, gpointer user_data); static RTPSessionCallbacks callbacks = { gst_rtp_session_process_rtp, @@ -264,7 +266,8 @@ static RTPSessionCallbacks callbacks = { gst_rtp_session_sync_rtcp, gst_rtp_session_send_rtcp, gst_rtp_session_clock_rate, - gst_rtp_session_reconsider + gst_rtp_session_reconsider, + gst_rtp_session_request_key_unit }; /* GObject vmethods */ @@ -2143,3 +2146,16 @@ wrong_pad: return; } } + +static void +gst_rtp_session_request_key_unit (RTPSession * sess, + gboolean all_headers, gpointer user_data) +{ + GstRtpSession *rtpsession = GST_RTP_SESSION (user_data); + GstEvent *event; + + event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, + gst_structure_new ("GstForceKeyUnit", + "all-headers", G_TYPE_BOOLEAN, all_headers, NULL)); + gst_pad_push_event (rtpsession->send_rtp_sink, event); +} diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index 32973c0..d3a7a54 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -769,6 +769,10 @@ rtp_session_set_callbacks (RTPSession * sess, RTPSessionCallbacks * callbacks, sess->callbacks.reconsider = callbacks->reconsider; sess->reconsider_user_data = user_data; } + if (callbacks->request_key_unit) { + sess->callbacks.request_key_unit = callbacks->request_key_unit; + sess->request_key_unit_user_data = user_data; + } } /** @@ -2042,6 +2046,25 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet, if (src) rtp_source_retain_rtcp_packet (src, packet, arrival->running_time); } + + if (rtp_source_get_ssrc (sess->source) == media_ssrc) { + switch (type) { + case GST_RTCP_TYPE_PSFB: + switch (fbtype) { + case GST_RTCP_PSFB_TYPE_PLI: + if (sess->callbacks.request_key_unit) + sess->callbacks.request_key_unit (sess, FALSE, + sess->request_key_unit_user_data); + break; + default: + break; + } + break; + case GST_RTCP_TYPE_RTPFB: + default: + break; + } + } } /** diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index 3113247..0cc1f6b 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -121,12 +121,26 @@ typedef gint (*RTPSessionClockRate) (RTPSession *sess, guint8 payload, gpointer typedef void (*RTPSessionReconsider) (RTPSession *sess, gpointer user_data); /** + * RTPSessionRequestKeyUnit: + * @sess: an #RTPSession + * @all_headers: %TRUE if "all-headers" property should be set on the key unit + * request + * @user_data: user data specified when registering +* + * Asks the encoder to produce a key unit as soon as possibly within the + * bandwidth constraints + */ +typedef void (*RTPSessionRequestKeyUnit) (RTPSession *sess, + gboolean all_headers, gpointer user_data); + +/** * RTPSessionCallbacks: * @RTPSessionProcessRTP: callback to process RTP packets * @RTPSessionSendRTP: callback for sending RTP packets * @RTPSessionSendRTCP: callback for sending RTCP packets * @RTPSessionSyncRTCP: callback for handling SR packets * @RTPSessionReconsider: callback for reconsidering the timeout + * @RTPSessionRequestKeyUnit: callback for requesting a new key unit * * These callbacks can be installed on the session manager to get notification * when RTP and RTCP packets are ready for further processing. These callbacks @@ -139,6 +153,7 @@ typedef struct { RTPSessionSendRTCP send_rtcp; RTPSessionClockRate clock_rate; RTPSessionReconsider reconsider; + RTPSessionRequestKeyUnit request_key_unit; } RTPSessionCallbacks; /** @@ -197,6 +212,7 @@ struct _RTPSession { gpointer sync_rtcp_user_data; gpointer clock_rate_user_data; gpointer reconsider_user_data; + gpointer request_key_unit_user_data; RTPSessionStats stats; |
From: <wt...@ke...> - 2011-02-01 18:00:52
|
Module: gst-plugins-good Branch: master Commit: 7350d2adfad6d6d3bef63fb793739204048612c5 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=7350d2adfad6d6d3bef63fb793739204048612c5 Author: Sjoerd Simons <sjo...@co...> Date: Wed Nov 24 15:27:46 2010 -0500 gstrtpsession: Fallback for FIR to PLI if PLI isn't available --- gst/rtpmanager/gstrtpsession.c | 25 +++++++++++++++++++------ 1 files changed, 19 insertions(+), 6 deletions(-) diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index 6d36633..cc784c8 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -1383,22 +1383,35 @@ gst_rtp_session_request_remote_key_unit (GstRtpSession * rtpsession, gboolean fir, pli; const GstStructure *s = gst_caps_get_structure (caps, 0); - if (all_headers && - gst_structure_get_boolean (s, "rtcp-fb-nack-fir", &fir) && fir) { - /* 500 ms acceptable delay for FIR request is a guesstimate, it could + if (!gst_structure_get_boolean (s, "rtcp-fb-nack-fir", &fir)) + fir = FALSE; + + if (!gst_structure_get_boolean (s, "rtcp-fb-nack-pli", &pli)) + pli = FALSE; + + gst_caps_unref (caps); + + if (!pli && !fir) + goto out; + + /* When we need all headers, use FIR if possible falling back to PLI if + * it's available */ + if (all_headers) { + /* 500 ms acceptable delay for urgent request is a guesstimate, it could * be made configurable if needed */ + /* If we don't have fir, fall back to pli */ + rtp_session_request_key_unit (rtpsession->priv->session, ssrc, fir); rtp_session_request_early_rtcp (rtpsession->priv->session, gst_clock_get_time (rtpsession->priv->sysclock), 500 * GST_MSECOND); - rtp_session_request_key_unit (rtpsession->priv->session, ssrc, TRUE); requested = TRUE; - } else if (gst_structure_get_boolean (s, "rtcp-fb-nack-pli", &pli) && pli) { + } else if (pli) { rtp_session_request_key_unit (rtpsession->priv->session, ssrc, FALSE); requested = TRUE; } - gst_caps_unref (caps); } +out: return requested; } |
From: <wt...@ke...> - 2011-02-01 18:00:52
|
Module: gst-plugins-good Branch: master Commit: c0996e6b903e1deaf4ef9ee08da9288bc75fac57 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=c0996e6b903e1deaf4ef9ee08da9288bc75fac57 Author: Olivier Crête <oli...@co...> Date: Fri Aug 27 16:11:06 2010 -0400 rtpsession: Add callback to get the current time --- gst/rtpmanager/gstrtpsession.c | 13 ++++++++++++- gst/rtpmanager/rtpsession.c | 22 ++++++++++++++++++++++ gst/rtpmanager/rtpsession.h | 17 +++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletions(-) diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index 994c53b..b1223d6 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -259,6 +259,8 @@ static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload, static void gst_rtp_session_reconsider (RTPSession * sess, gpointer user_data); static void gst_rtp_session_request_key_unit (RTPSession * sess, gboolean all_headers, gpointer user_data); +static GstClockTime gst_rtp_session_request_time (RTPSession * session, + gpointer user_data); static RTPSessionCallbacks callbacks = { gst_rtp_session_process_rtp, @@ -267,7 +269,8 @@ static RTPSessionCallbacks callbacks = { gst_rtp_session_send_rtcp, gst_rtp_session_clock_rate, gst_rtp_session_reconsider, - gst_rtp_session_request_key_unit + gst_rtp_session_request_key_unit, + gst_rtp_session_request_time }; /* GObject vmethods */ @@ -2159,3 +2162,11 @@ gst_rtp_session_request_key_unit (RTPSession * sess, "all-headers", G_TYPE_BOOLEAN, all_headers, NULL)); gst_pad_push_event (rtpsession->send_rtp_sink, event); } + +static GstClockTime +gst_rtp_session_request_time (RTPSession * session, gpointer user_data) +{ + GstRtpSession *rtpsession = GST_RTP_SESSION (user_data); + + return gst_clock_get_time (rtpsession->priv->sysclock); +} diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index cf73043..a60e7c0 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -773,6 +773,10 @@ rtp_session_set_callbacks (RTPSession * sess, RTPSessionCallbacks * callbacks, sess->callbacks.request_key_unit = callbacks->request_key_unit; sess->request_key_unit_user_data = user_data; } + if (callbacks->request_time) { + sess->callbacks.request_time = callbacks->request_time; + sess->request_time_user_data = user_data; + } } /** @@ -884,6 +888,24 @@ rtp_session_set_reconsider_callback (RTPSession * sess, } /** + * rtp_session_set_request_time_callback: + * @sess: an #RTPSession + * @callback: callback to set + * @user_data: user data passed in the callback + * + * Configure only the request_time callback + */ +void +rtp_session_set_request_time_callback (RTPSession * sess, + RTPSessionRequestTime callback, gpointer user_data) +{ + g_return_if_fail (RTP_IS_SESSION (sess)); + + sess->callbacks.request_time = callback; + sess->request_time_user_data = user_data; +} + +/** * rtp_session_set_bandwidth: * @sess: an #RTPSession * @bandwidth: the bandwidth allocated diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index 9510942..3746a9b 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -134,6 +134,17 @@ typedef void (*RTPSessionRequestKeyUnit) (RTPSession *sess, gboolean all_headers, gpointer user_data); /** + * RTPSessionRequestTime: + * @sess: an #RTPSession + * @user_data: user data specified when registering + * + * This callback will be called when @sess needs the current time. The time + * should be returned as a #GstClockTime + */ +typedef GstClockTime (*RTPSessionRequestTime) (RTPSession *sess, + gpointer user_data); + +/** * RTPSessionCallbacks: * @RTPSessionProcessRTP: callback to process RTP packets * @RTPSessionSendRTP: callback for sending RTP packets @@ -154,6 +165,7 @@ typedef struct { RTPSessionClockRate clock_rate; RTPSessionReconsider reconsider; RTPSessionRequestKeyUnit request_key_unit; + RTPSessionRequestTime request_time; } RTPSessionCallbacks; /** @@ -213,6 +225,7 @@ struct _RTPSession { gpointer clock_rate_user_data; gpointer reconsider_user_data; gpointer request_key_unit_user_data; + gpointer request_time_user_data; RTPSessionStats stats; @@ -278,6 +291,10 @@ void rtp_session_set_clock_rate_callback (RTPSession * sess, void rtp_session_set_reconsider_callback (RTPSession * sess, RTPSessionReconsider callback, gpointer user_data); +void rtp_session_set_request_time_callback (RTPSession * sess, + RTPSessionRequestTime callback, + gpointer user_data); + void rtp_session_set_bandwidth (RTPSession *sess, gdouble bandwidth); gdouble rtp_session_get_bandwidth (RTPSession *sess); void rtp_session_set_rtcp_fraction (RTPSession *sess, gdouble fraction); |
From: <wt...@ke...> - 2011-02-01 18:00:51
|
Module: gst-plugins-good Branch: master Commit: 1643f427db8c3de8cb8dd952eb408c076a4223ee URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=1643f427db8c3de8cb8dd952eb408c076a4223ee Author: Olivier Crête <oli...@co...> Date: Thu Jun 17 17:34:19 2010 -0400 rtpsession: Emit signal on incoming RTCP FB packet --- gst/rtpmanager/gstrtpbin-marshal.list | 1 + gst/rtpmanager/rtpsession.c | 57 +++++++++++++++++++++++++++++++++ gst/rtpmanager/rtpsession.h | 2 + 3 files changed, 60 insertions(+), 0 deletions(-) diff --git a/gst/rtpmanager/gstrtpbin-marshal.list b/gst/rtpmanager/gstrtpbin-marshal.list index 0b0d81f..5176b33 100644 --- a/gst/rtpmanager/gstrtpbin-marshal.list +++ b/gst/rtpmanager/gstrtpbin-marshal.list @@ -8,3 +8,4 @@ VOID:UINT,UINT VOID:OBJECT,OBJECT UINT64:BOOL,UINT64 BOOL:POINTER,BOOL +VOID:UINT,UINT,UINT,UINT,POINTER diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index a0ac833..d4bbf08 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -43,6 +43,7 @@ enum SIGNAL_ON_TIMEOUT, SIGNAL_ON_SENDER_TIMEOUT, SIGNAL_ON_SENDING_RTCP, + SIGNAL_ON_FEEDBACK_RTCP, LAST_SIGNAL }; @@ -271,6 +272,27 @@ rtp_session_class_init (RTPSessionClass * klass) accumulate_trues, NULL, gst_rtp_bin_marshal_BOOLEAN__POINTER_BOOLEAN, G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_BOOLEAN); + /** + * RTPSession::on-feedback-rtcp: + * @session: the object which received the signal + * @type: Type of RTCP packet, will be %GST_RTCP_TYPE_RTPFB or + * %GST_RTCP_TYPE_RTPFB + * @fbtype: The type of RTCP FB packet, probably part of #GstRTCPFBType + * @sender_ssrc: The SSRC of the sender + * @media_ssrc: The SSRC of the media this refers to + * @fci: a #GstBuffer with the FCI data from the FB packet or %NULL if + * there was no FCI + * + * Notify that a RTCP feedback packet has been received + */ + + rtp_session_signals[SIGNAL_ON_FEEDBACK_RTCP] = + g_signal_new ("on-feedback-rtcp", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_feedback_rtcp), + NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT_UINT_UINT_POINTER, + G_TYPE_NONE, 4, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, + G_TYPE_POINTER); + g_object_class_install_property (gobject_class, PROP_INTERNAL_SSRC, g_param_spec_uint ("internal-ssrc", "Internal SSRC", "The internal SSRC used for the session", @@ -1960,6 +1982,37 @@ rtp_session_process_app (RTPSession * sess, GstRTCPPacket * packet, GST_DEBUG ("received APP"); } + +static void +rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet, + RTPArrivalStats * arrival) +{ + GstRTCPType type = gst_rtcp_packet_get_type (packet); + GstRTCPFBType fbtype = gst_rtcp_packet_fb_get_type (packet); + guint32 sender_ssrc = gst_rtcp_packet_fb_get_sender_ssrc (packet); + guint32 media_ssrc = gst_rtcp_packet_fb_get_media_ssrc (packet); + guint length = 4 * (gst_rtcp_packet_get_length (packet) - 2); + + GST_DEBUG ("received feedback %d:%d from %08X about %08X" + " with FCI of length %d", type, fbtype, sender_ssrc, media_ssrc, length); + + if (g_signal_has_handler_pending (sess, + rtp_session_signals[SIGNAL_ON_FEEDBACK_RTCP], 0, TRUE)) { + GstBuffer *fci = NULL; + + if (length) { + fci = gst_buffer_create_sub (packet->buffer, packet->offset + 72, length); + GST_BUFFER_TIMESTAMP (fci) = arrival->running_time; + } + + g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_FEEDBACK_RTCP], 0, + type, fbtype, sender_ssrc, media_ssrc, fci); + + if (fci) + gst_buffer_unref (fci); + } +} + /** * rtp_session_process_rtcp: * @sess: and #RTPSession @@ -2030,6 +2083,10 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, case GST_RTCP_TYPE_APP: rtp_session_process_app (sess, &packet, &arrival); break; + case GST_RTCP_TYPE_RTPFB: + case GST_RTCP_TYPE_PSFB: + rtp_session_process_feedback (sess, &packet, &arrival); + break; default: GST_WARNING ("got unknown RTCP packet"); break; diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index a2d5d57..b63bbcc 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -229,6 +229,8 @@ struct _RTPSessionClass { void (*on_sender_timeout) (RTPSession *sess, RTPSource *source); gboolean (*on_sending_rtcp) (RTPSession *sess, GstBuffer *buffer, gboolean early); + void (*on_feedback_rtcp) (RTPSession *sess, guint type, guint fbtype, + guint sender_ssrc, guint media_ssrc, GstBuffer *fci); }; GType rtp_session_get_type (void); |
From: <wt...@ke...> - 2011-02-01 18:00:51
|
Module: gst-plugins-good Branch: master Commit: 52f95fa7ee441e842dc6ef7fb5cd28bfa1178866 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=52f95fa7ee441e842dc6ef7fb5cd28bfa1178866 Author: Olivier Crête <oli...@co...> Date: Tue Jun 22 19:56:50 2010 -0400 rtpsession: Implement sending PLI packets in response to GstForceKeyUnit --- gst/rtpmanager/gstrtpsession.c | 73 +++++++++++++++++++++++++++++++++++++ gst/rtpmanager/rtpsession.c | 77 ++++++++++++++++++++++++++++++++++++++++ gst/rtpmanager/rtpsession.h | 6 +++ 3 files changed, 156 insertions(+), 0 deletions(-) diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index f10ab92..6d36633 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -1370,6 +1370,77 @@ gst_rtp_session_event_recv_rtp_sink (GstPad * pad, GstEvent * event) } +static gboolean +gst_rtp_session_request_remote_key_unit (GstRtpSession * rtpsession, + guint32 ssrc, guint payload, gboolean all_headers) +{ + GstCaps *caps; + gboolean requested = FALSE; + + caps = gst_rtp_session_get_caps_for_pt (rtpsession, payload); + + if (caps) { + gboolean fir, pli; + const GstStructure *s = gst_caps_get_structure (caps, 0); + + if (all_headers && + gst_structure_get_boolean (s, "rtcp-fb-nack-fir", &fir) && fir) { + /* 500 ms acceptable delay for FIR request is a guesstimate, it could + * be made configurable if needed + */ + rtp_session_request_early_rtcp (rtpsession->priv->session, + gst_clock_get_time (rtpsession->priv->sysclock), 500 * GST_MSECOND); + rtp_session_request_key_unit (rtpsession->priv->session, ssrc, TRUE); + requested = TRUE; + } else if (gst_structure_get_boolean (s, "rtcp-fb-nack-pli", &pli) && pli) { + rtp_session_request_key_unit (rtpsession->priv->session, ssrc, FALSE); + requested = TRUE; + } + gst_caps_unref (caps); + } + + return requested; +} + +static gboolean +gst_rtp_session_event_recv_rtp_src (GstPad * pad, GstEvent * event) +{ + GstRtpSession *rtpsession; + gboolean forward = TRUE; + gboolean ret = TRUE; + const GstStructure *s; + guint32 ssrc; + guint pt; + + rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CUSTOM_UPSTREAM: + s = gst_event_get_structure (event); + if (gst_structure_has_name (s, "GstForceKeyUnit") && + gst_structure_get_uint (s, "ssrc", &ssrc) && + gst_structure_get_uint (s, "payload", &pt)) { + gboolean all_headers = FALSE; + + gst_structure_get_boolean (s, "all-headers", &all_headers); + if (gst_rtp_session_request_remote_key_unit (rtpsession, ssrc, pt, + all_headers)) + forward = FALSE; + } + break; + default: + break; + } + + if (forward) + ret = gst_pad_push_event (rtpsession->recv_rtp_sink, event); + + gst_object_unref (rtpsession); + + return ret; +} + + static GstIterator * gst_rtp_session_iterate_internal_links (GstPad * pad) { @@ -1780,6 +1851,8 @@ create_recv_rtp_sink (GstRtpSession * rtpsession) rtpsession->recv_rtp_src = gst_pad_new_from_static_template (&rtpsession_recv_rtp_src_template, "recv_rtp_src"); + gst_pad_set_event_function (rtpsession->recv_rtp_src, + (GstPadEventFunction) gst_rtp_session_event_recv_rtp_src); gst_pad_set_iterate_internal_links_function (rtpsession->recv_rtp_src, gst_rtp_session_iterate_internal_links); gst_pad_use_fixed_caps (rtpsession->recv_rtp_src); diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index ec40115..32973c0 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -102,6 +102,10 @@ static void rtp_session_set_property (GObject * object, guint prop_id, static void rtp_session_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static gboolean rtp_session_on_sending_rtcp (RTPSession * sess, + GstBuffer * buffer, gboolean early); + + static guint rtp_session_signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (RTPSession, rtp_session, G_TYPE_OBJECT); @@ -403,6 +407,7 @@ rtp_session_class_init (RTPSessionClass * klass) klass->get_source_by_ssrc = GST_DEBUG_FUNCPTR (rtp_session_get_source_by_ssrc); + klass->on_sending_rtcp = GST_DEBUG_FUNCPTR (rtp_session_on_sending_rtcp); GST_DEBUG_CATEGORY_INIT (rtp_session_debug, "rtpsession", 0, "RTP Session"); } @@ -457,6 +462,8 @@ rtp_session_init (RTPSession * sess) sess->allow_early = TRUE; sess->rtcp_feedback_retention_window = DEFAULT_RTCP_FEEDBACK_RETENTION_WINDOW; + sess->rtcp_pli_requests = g_array_new (FALSE, FALSE, sizeof (guint32)); + GST_DEBUG ("%p: session using SSRC: %08x", sess, sess->source->ssrc); } @@ -477,6 +484,8 @@ rtp_session_finalize (GObject * object) g_hash_table_destroy (sess->cnames); g_object_unref (sess->source); + g_array_free (sess->rtcp_pli_requests, TRUE); + G_OBJECT_CLASS (rtp_session_parent_class)->finalize (object); } @@ -2973,3 +2982,71 @@ dont_send: RTP_SESSION_UNLOCK (sess); } + +void +rtp_session_request_key_unit (RTPSession * sess, guint32 ssrc, gboolean fir) +{ + guint i; + + if (fir) + return; + + for (i = 0; i < sess->rtcp_pli_requests->len; i++) + if (ssrc == g_array_index (sess->rtcp_pli_requests, guint32, i)) + return; + + g_array_append_val (sess->rtcp_pli_requests, ssrc); +} + +static gboolean +has_pli_compare_func (gconstpointer a, gconstpointer ignored) +{ + GstRTCPPacket packet; + + packet.buffer = (GstBuffer *) a; + packet.offset = 0; + + if (gst_rtcp_packet_get_type (&packet) == GST_RTCP_TYPE_PSFB && + gst_rtcp_packet_fb_get_type (&packet) == GST_RTCP_PSFB_TYPE_PLI) + return TRUE; + else + return FALSE; +} + +static gboolean +rtp_session_on_sending_rtcp (RTPSession * sess, GstBuffer * buffer, + gboolean early) +{ + gboolean ret = FALSE; + + RTP_SESSION_LOCK (sess); + + while (sess->rtcp_pli_requests->len) { + GstRTCPPacket rtcppacket; + guint media_ssrc = g_array_index (sess->rtcp_pli_requests, guint32, 0); + RTPSource *media_src = g_hash_table_lookup (sess->ssrcs[sess->mask_idx], + GUINT_TO_POINTER (media_ssrc)); + + if (media_src && !rtp_source_has_retained (media_src, + has_pli_compare_func, NULL)) { + if (gst_rtcp_buffer_add_packet (buffer, GST_RTCP_TYPE_PSFB, &rtcppacket)) { + gst_rtcp_packet_fb_set_type (&rtcppacket, GST_RTCP_PSFB_TYPE_PLI); + gst_rtcp_packet_fb_set_sender_ssrc (&rtcppacket, + rtp_source_get_ssrc (sess->source)); + gst_rtcp_packet_fb_set_media_ssrc (&rtcppacket, media_ssrc); + ret = TRUE; + } else { + /* Break because the packet is full, will put next request in a + * further packet + */ + break; + } + } + + g_array_remove_index (sess->rtcp_pli_requests, 0); + } + + RTP_SESSION_UNLOCK (sess); + + return ret; +} diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index 6ae318e..3113247 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -203,6 +203,8 @@ struct _RTPSession { gboolean change_ssrc; gboolean favor_new; GstClockTime rtcp_feedback_retention_window; + + GArray *rtcp_pli_requests; }; /** @@ -308,5 +310,9 @@ GstFlowReturn rtp_session_on_timeout (RTPSession *sess, GstClockTi void rtp_session_request_early_rtcp (RTPSession * sess, GstClockTime current_time, GstClockTimeDiff max_delay); +/* Notify session of a request for a new key unit */ +void rtp_session_request_key_unit (RTPSession * sess, + guint32 ssrc, + gboolean fir); #endif /* __RTP_SESSION_H__ */ |
From: <wt...@ke...> - 2011-02-01 18:00:51
|
Module: gst-plugins-good Branch: master Commit: db5150a23a7eb99033a89045be4a3d3f59b201f1 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=db5150a23a7eb99033a89045be4a3d3f59b201f1 Author: Olivier Crête <oli...@co...> Date: Tue Jun 22 13:33:32 2010 -0400 rtpsource: Retain RTCP Feedback packets for a specified amount of time --- gst/rtpmanager/rtpsession.c | 25 +++++++++++++++++++++- gst/rtpmanager/rtpsession.h | 1 + gst/rtpmanager/rtpsource.c | 49 ++++++++++++++++++++++++++++++++++++++++++- gst/rtpmanager/rtpsource.h | 13 ++++++++++- 4 files changed, 85 insertions(+), 3 deletions(-) diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index 5938d55..ec40115 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -58,6 +58,7 @@ enum #define DEFAULT_NUM_ACTIVE_SOURCES 0 #define DEFAULT_SOURCES NULL #define DEFAULT_RTCP_MIN_INTERVAL (RTP_STATS_MIN_INTERVAL * GST_SECOND) +#define DEFAULT_RTCP_FEEDBACK_RETENTION_WINDOW (2 * GST_SECOND) enum { @@ -75,6 +76,7 @@ enum PROP_SOURCES, PROP_FAVOR_NEW, PROP_RTCP_MIN_INTERVAL, + PROP_RTCP_FEEDBACK_RETENTION_WINDOW, PROP_LAST }; @@ -390,6 +392,15 @@ rtp_session_class_init (RTPSessionClass * klass) 0, G_MAXUINT64, DEFAULT_RTCP_MIN_INTERVAL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_RTCP_FEEDBACK_RETENTION_WINDOW, + g_param_spec_uint64 ("rtcp-feedback-retention-window", + "RTCP Feedback retention window", + "Duration during which RTCP Feedback packets are retained (in ns)", + 0, G_MAXUINT64, DEFAULT_RTCP_FEEDBACK_RETENTION_WINDOW, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + klass->get_source_by_ssrc = GST_DEBUG_FUNCPTR (rtp_session_get_source_by_ssrc); @@ -444,6 +455,7 @@ rtp_session_init (RTPSession * sess) sess->first_rtcp = TRUE; sess->allow_early = TRUE; + sess->rtcp_feedback_retention_window = DEFAULT_RTCP_FEEDBACK_RETENTION_WINDOW; GST_DEBUG ("%p: session using SSRC: %08x", sess, sess->source->ssrc); } @@ -2005,12 +2017,22 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet, GST_BUFFER_TIMESTAMP (fci) = arrival->running_time; } + RTP_SESSION_UNLOCK (sess); g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_FEEDBACK_RTCP], 0, type, fbtype, sender_ssrc, media_ssrc, fci); + RTP_SESSION_LOCK (sess); if (fci) gst_buffer_unref (fci); } + + if (sess->rtcp_feedback_retention_window) { + RTPSource *src = g_hash_table_lookup (sess->ssrcs[sess->mask_idx], + GINT_TO_POINTER (media_ssrc)); + + if (src) + rtp_source_retain_rtcp_packet (src, packet, arrival->running_time); + } } /** @@ -2829,7 +2851,8 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time, /* check for outdated collisions */ GST_DEBUG ("Timing out collisions"); rtp_source_timeout (sess->source, current_time, - data.interval * RTCP_INTERVAL_COLLISION_TIMEOUT); + data.interval * RTCP_INTERVAL_COLLISION_TIMEOUT, + running_time - sess->rtcp_feedback_retention_window); if (sess->change_ssrc) { GST_DEBUG ("need to change our SSRC (%08x)", own->ssrc); diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index b63bbcc..6ae318e 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -202,6 +202,7 @@ struct _RTPSession { gboolean change_ssrc; gboolean favor_new; + GstClockTime rtcp_feedback_retention_window; }; /** diff --git a/gst/rtpmanager/rtpsource.c b/gst/rtpmanager/rtpsource.c index 4a3af16..423d2b6 100644 --- a/gst/rtpmanager/rtpsource.c +++ b/gst/rtpmanager/rtpsource.c @@ -238,6 +238,8 @@ rtp_source_init (RTPSource * src) src->seqnum_base = -1; src->last_rtptime = -1; + src->retained_feedback = g_queue_new (); + rtp_source_reset (src); } @@ -262,6 +264,10 @@ rtp_source_finalize (GObject * object) g_list_foreach (src->conflicting_addresses, (GFunc) g_free, NULL); g_list_free (src->conflicting_addresses); + while ((buffer = g_queue_pop_head (src->retained_feedback))) + gst_buffer_unref (buffer); + g_queue_free (src->retained_feedback); + G_OBJECT_CLASS (rtp_source_parent_class)->finalize (object); } @@ -1719,14 +1725,18 @@ rtp_source_add_conflicting_address (RTPSource * src, * @src: The #RTPSource * @current_time: The current time * @collision_timeout: The amount of time after which a collision is timed out + * @feedback_retention_window: The running time before which retained feedback + * packets have to be discarded * * This is processed on each RTCP interval. It times out old collisions. + * It also times out old retained feedback packets */ void rtp_source_timeout (RTPSource * src, GstClockTime current_time, - GstClockTime collision_timeout) + GstClockTime collision_timeout, GstClockTime feedback_retention_window) { GList *item; + GstRTCPPacket *pkt; item = g_list_first (src->conflicting_addresses); while (item) { @@ -1744,4 +1754,41 @@ rtp_source_timeout (RTPSource * src, GstClockTime current_time, } item = next_item; } + + /* Time out AVPF packets that are older than the desired length */ + while ((pkt = g_queue_peek_tail (src->retained_feedback)) && + GST_BUFFER_TIMESTAMP (pkt) < feedback_retention_window) + gst_buffer_unref (g_queue_pop_tail (src->retained_feedback)); +} + +static gint +compare_buffers (gconstpointer a, gconstpointer b, gpointer user_data) +{ + const GstBuffer *bufa = a; + const GstBuffer *bufb = b; + + return GST_BUFFER_TIMESTAMP (bufa) - GST_BUFFER_TIMESTAMP (bufb); +} + +void +rtp_source_retain_rtcp_packet (RTPSource * src, GstRTCPPacket * packet, + GstClockTime running_time) +{ + GstBuffer *buffer; + + buffer = gst_buffer_create_sub (packet->buffer, packet->offset, + (gst_rtcp_packet_get_length (packet) + 1) * 4); + + GST_BUFFER_TIMESTAMP (buffer) = running_time; + + g_queue_insert_sorted (src->retained_feedback, buffer, compare_buffers, NULL); +} + +gboolean +rtp_source_has_retained (RTPSource * src, GCompareFunc func, gconstpointer data) +{ + if (g_queue_find_custom (src->retained_feedback, data, func)) + return TRUE; + else + return FALSE; } diff --git a/gst/rtpmanager/rtpsource.h b/gst/rtpmanager/rtpsource.h index 94c22b3..fadbe30 100644 --- a/gst/rtpmanager/rtpsource.h +++ b/gst/rtpmanager/rtpsource.h @@ -170,6 +170,8 @@ struct _RTPSource { RTPReceiverReport last_rr; GList *conflicting_addresses; + + GQueue *retained_feedback; }; struct _RTPSourceClass { @@ -248,7 +250,16 @@ void rtp_source_add_conflicting_address (RTPSource * src, void rtp_source_timeout (RTPSource * src, GstClockTime current_time, - GstClockTime collision_timeout); + GstClockTime collision_timeout, + GstClockTime feedback_retention_window); + +void rtp_source_retain_rtcp_packet (RTPSource * src, + GstRTCPPacket *pkt, + GstClockTime running_time); + +gboolean rtp_source_has_retained (RTPSource * src, + GCompareFunc func, + gconstpointer data); #endif /* __RTP_SOURCE_H__ */ |
From: <wt...@ke...> - 2011-02-01 18:00:51
|
Module: gst-plugins-good Branch: master Commit: 1bde4272509c30f0818af865c2f8f51014f7ac14 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=1bde4272509c30f0818af865c2f8f51014f7ac14 Author: Olivier Crête <oli...@co...> Date: Tue Jun 15 18:39:47 2010 -0400 rtpsession: Add method to request early RTCP packet Implement the early mode defined in RFC 4585. In this mode, RTCP feedback packets are sent early to notifier. --- gst/rtpmanager/rtpsession.c | 151 ++++++++++++++++++++++++++++++++++++++---- gst/rtpmanager/rtpsession.h | 8 ++ 2 files changed, 144 insertions(+), 15 deletions(-) Diff: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/diff/?id=1bde4272509c30f0818af865c2f8f51014f7ac14 |
From: <wt...@ke...> - 2011-02-01 18:00:46
|
Module: gst-plugins-good Branch: master Commit: c7b1ce7310d903fe265a8b5e7c773b17790334b4 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=c7b1ce7310d903fe265a8b5e7c773b17790334b4 Author: Olivier Crete <oli...@co...> Date: Fri Jun 18 19:12:40 2010 -0400 rtpssrcdemux: Tag upstream custom events with SSRC --- gst/rtpmanager/gstrtpssrcdemux.c | 30 ++++++++++++++++++++++++++---- 1 files changed, 26 insertions(+), 4 deletions(-) diff --git a/gst/rtpmanager/gstrtpssrcdemux.c b/gst/rtpmanager/gstrtpssrcdemux.c index c8348da..65d4475 100644 --- a/gst/rtpmanager/gstrtpssrcdemux.c +++ b/gst/rtpmanager/gstrtpssrcdemux.c @@ -208,6 +208,7 @@ create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc, gst_rtp_ssrc_demux_iterate_internal_links); gst_pad_set_active (rtp_pad, TRUE); + gst_pad_set_event_function (rtcp_pad, gst_rtp_ssrc_demux_src_event); gst_pad_set_iterate_internal_links_function (rtcp_pad, gst_rtp_ssrc_demux_iterate_internal_links); gst_pad_set_active (rtcp_pad, TRUE); @@ -621,18 +622,39 @@ static gboolean gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event) { GstRtpSsrcDemux *demux; - gboolean res = FALSE; + const GstStructure *s; demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad)); switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: + case GST_EVENT_CUSTOM_UPSTREAM: + case GST_EVENT_CUSTOM_BOTH: + case GST_EVENT_CUSTOM_BOTH_OOB: + s = gst_event_get_structure (event); + if (s && !gst_structure_has_field (s, "ssrc")) { + GSList *walk; + + for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) { + GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) walk->data; + + if (dpad->rtp_pad == pad || dpad->rtcp_pad == pad) { + event = + GST_EVENT_CAST (gst_mini_object_make_writable + (GST_MINI_OBJECT_CAST (event))); + gst_structure_set (event->structure, "ssrc", G_TYPE_UINT, + dpad->ssrc, NULL); + break; + } + } + } + break; default: - res = gst_pad_event_default (pad, event); break; } + gst_object_unref (demux); - return res; + + return gst_pad_event_default (pad, event); } static GstIterator * |
From: <wt...@ke...> - 2011-02-01 18:00:46
|
Module: gst-plugins-good Branch: master Commit: 975e1fecb3047212c06ffc4b1ab99c469a17b2e4 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=975e1fecb3047212c06ffc4b1ab99c469a17b2e4 Author: Olivier Crête <oli...@co...> Date: Tue Jun 1 19:28:01 2010 -0400 rtpsession: Add property for minimum interval between Regular RTCP messages This can be changed according to RFC 4585 --- gst/rtpmanager/gstrtpsession.c | 16 ++++++++++++++++ gst/rtpmanager/rtpsession.c | 14 ++++++++++++++ gst/rtpmanager/rtpstats.c | 6 ++++++ gst/rtpmanager/rtpstats.h | 3 +++ 4 files changed, 39 insertions(+), 0 deletions(-) diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index 751b7f8..f10ab92 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -199,6 +199,7 @@ enum #define DEFAULT_NUM_SOURCES 0 #define DEFAULT_NUM_ACTIVE_SOURCES 0 #define DEFAULT_USE_PIPELINE_CLOCK FALSE +#define DEFAULT_RTCP_MIN_INTERVAL (RTP_STATS_MIN_INTERVAL * GST_SECOND) enum { @@ -213,6 +214,7 @@ enum PROP_NUM_ACTIVE_SOURCES, PROP_INTERNAL_SESSION, PROP_USE_PIPELINE_CLOCK, + PROP_RTCP_MIN_INTERVAL, PROP_LAST }; @@ -588,6 +590,12 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass) DEFAULT_USE_PIPELINE_CLOCK, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_RTCP_MIN_INTERVAL, + g_param_spec_uint64 ("rtcp-min-interval", "Minimum RTCP interval", + "Minimum interval between Regular RTCP packet (in ns)", + 0, G_MAXUINT64, DEFAULT_RTCP_MIN_INTERVAL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_session_change_state); gstelement_class->request_new_pad = @@ -693,6 +701,10 @@ gst_rtp_session_set_property (GObject * object, guint prop_id, case PROP_USE_PIPELINE_CLOCK: priv->use_pipeline_clock = g_value_get_boolean (value); break; + case PROP_RTCP_MIN_INTERVAL: + g_object_set_property (G_OBJECT (priv->session), "rtcp-min-interval", + value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -745,6 +757,10 @@ gst_rtp_session_get_property (GObject * object, guint prop_id, case PROP_USE_PIPELINE_CLOCK: g_value_set_boolean (value, priv->use_pipeline_clock); break; + case PROP_RTCP_MIN_INTERVAL: + g_object_get_property (G_OBJECT (priv->session), "rtcp-min-interval", + value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index 4b1513d..43a4e2e 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -56,6 +56,7 @@ enum #define DEFAULT_NUM_SOURCES 0 #define DEFAULT_NUM_ACTIVE_SOURCES 0 #define DEFAULT_SOURCES NULL +#define DEFAULT_RTCP_MIN_INTERVAL (RTP_STATS_MIN_INTERVAL * GST_SECOND) enum { @@ -72,6 +73,7 @@ enum PROP_NUM_ACTIVE_SOURCES, PROP_SOURCES, PROP_FAVOR_NEW, + PROP_RTCP_MIN_INTERVAL, PROP_LAST }; @@ -360,6 +362,11 @@ rtp_session_class_init (RTPSessionClass * klass) "Resolve SSRC conflict in favor of new sources", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_RTCP_MIN_INTERVAL, + g_param_spec_uint64 ("rtcp-min-interval", "Minimum RTCP interval", + "Minimum interval between Regular RTCP packet (in ns)", + 0, G_MAXUINT64, DEFAULT_RTCP_MIN_INTERVAL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); klass->get_source_by_ssrc = GST_DEBUG_FUNCPTR (rtp_session_get_source_by_ssrc); @@ -505,6 +512,10 @@ rtp_session_set_property (GObject * object, guint prop_id, case PROP_FAVOR_NEW: sess->favor_new = g_value_get_boolean (value); break; + case PROP_RTCP_MIN_INTERVAL: + rtp_stats_set_min_interval (&sess->stats, + (gdouble) g_value_get_uint64 (value) / GST_SECOND); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -556,6 +567,9 @@ rtp_session_get_property (GObject * object, guint prop_id, case PROP_FAVOR_NEW: g_value_set_boolean (value, sess->favor_new); break; + case PROP_RTCP_MIN_INTERVAL: + g_value_set_uint64 (value, sess->stats.min_interval * GST_SECOND); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/rtpmanager/rtpstats.c b/gst/rtpmanager/rtpstats.c index a31e7e5..8fe1d1f 100644 --- a/gst/rtpmanager/rtpstats.c +++ b/gst/rtpmanager/rtpstats.c @@ -286,3 +286,9 @@ rtp_stats_get_packets_lost (const RTPSourceStats * stats) return lost; } + +void +rtp_stats_set_min_interval (RTPSessionStats * stats, gdouble min_interval) +{ + stats->min_interval = min_interval; +} diff --git a/gst/rtpmanager/rtpstats.h b/gst/rtpmanager/rtpstats.h index d657cdf..643da00 100644 --- a/gst/rtpmanager/rtpstats.h +++ b/gst/rtpmanager/rtpstats.h @@ -195,4 +195,7 @@ GstClockTime rtp_stats_calculate_rtcp_interval (RTPSessionStats *stats, gbo GstClockTime rtp_stats_add_rtcp_jitter (RTPSessionStats *stats, GstClockTime interval); GstClockTime rtp_stats_calculate_bye_interval (RTPSessionStats *stats); gint64 rtp_stats_get_packets_lost (const RTPSourceStats *stats); + +void rtp_stats_set_min_interval (RTPSessionStats *stats, + gdouble min_interval); #endif /* __RTP_STATS_H__ */ |
From: <wt...@ke...> - 2011-02-01 18:00:45
|
Module: gst-plugins-good Branch: master Commit: 589b254ce594abc0763a731fc1293b63e9fd0b06 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=589b254ce594abc0763a731fc1293b63e9fd0b06 Author: Olivier Crête <oli...@co...> Date: Sat Jun 19 19:11:06 2010 -0400 rtpptdemux: Tag upstream custom events with payload type --- gst/rtpmanager/gstrtpptdemux.c | 45 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 45 insertions(+), 0 deletions(-) diff --git a/gst/rtpmanager/gstrtpptdemux.c b/gst/rtpmanager/gstrtpptdemux.c index 6b49483..78c4956 100644 --- a/gst/rtpmanager/gstrtpptdemux.c +++ b/gst/rtpmanager/gstrtpptdemux.c @@ -132,6 +132,9 @@ static void gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux); static GstRtpPtDemuxPad *find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt); +static gboolean gst_rtp_pt_demux_src_event (GstPad * pad, GstEvent * event); + + static guint gst_rtp_pt_demux_signals[LAST_SIGNAL] = { 0 }; static void @@ -329,6 +332,7 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf) srcpad = gst_pad_new_from_template (templ, padname); gst_pad_use_fixed_caps (srcpad); g_free (padname); + gst_pad_set_event_function (srcpad, gst_rtp_pt_demux_src_event); caps = gst_rtp_pt_demux_get_caps (rtpdemux, pt); if (!caps) @@ -462,6 +466,47 @@ gst_rtp_pt_demux_sink_event (GstPad * pad, GstEvent * event) } +static gboolean +gst_rtp_pt_demux_src_event (GstPad * pad, GstEvent * event) +{ + GstRtpPtDemux *demux; + const GstStructure *s; + + demux = GST_RTP_PT_DEMUX (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CUSTOM_UPSTREAM: + case GST_EVENT_CUSTOM_BOTH: + case GST_EVENT_CUSTOM_BOTH_OOB: + s = gst_event_get_structure (event); + if (s && !gst_structure_has_field (s, "payload")) { + GSList *walk; + + for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) { + GstRtpPtDemuxPad *dpad = (GstRtpPtDemuxPad *) walk->data; + + if (dpad->pad == pad) { + event = + GST_EVENT_CAST (gst_mini_object_make_writable + (GST_MINI_OBJECT_CAST (event))); + gst_structure_set (event->structure, + "payload", G_TYPE_UINT, dpad->pt, NULL); + break; + } + } + } + break; + default: + break; + } + + gst_object_unref (demux); + + return gst_pad_event_default (pad, event); +} + + + /* * Reserves resources for the object. */ |
From: <wt...@ke...> - 2011-02-01 18:00:44
|
Module: gst-plugins-good Branch: master Commit: cdb546574177d88bcc2b2456fa2e87755db98ed6 URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=cdb546574177d88bcc2b2456fa2e87755db98ed6 Author: Olivier Crête <oli...@co...> Date: Mon Jun 14 18:40:33 2010 -0400 rtpsession: Emit signal when sending a compound RTCP packet This allows users to add extra RTCP packets to the compound RTCP packet. --- gst/rtpmanager/gstrtpbin-marshal.list | 1 + gst/rtpmanager/rtpsession.c | 33 +++++++++++++++++++++++++++++++++ gst/rtpmanager/rtpsession.h | 2 ++ 3 files changed, 36 insertions(+), 0 deletions(-) diff --git a/gst/rtpmanager/gstrtpbin-marshal.list b/gst/rtpmanager/gstrtpbin-marshal.list index 01b530b..0b0d81f 100644 --- a/gst/rtpmanager/gstrtpbin-marshal.list +++ b/gst/rtpmanager/gstrtpbin-marshal.list @@ -7,3 +7,4 @@ VOID:UINT VOID:UINT,UINT VOID:OBJECT,OBJECT UINT64:BOOL,UINT64 +BOOL:POINTER,BOOL diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index 176a86f..4b1513d 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -42,6 +42,7 @@ enum SIGNAL_ON_BYE_TIMEOUT, SIGNAL_ON_TIMEOUT, SIGNAL_ON_SENDER_TIMEOUT, + SIGNAL_ON_SENDING_RTCP, LAST_SIGNAL }; @@ -107,6 +108,16 @@ static GstFlowReturn rtp_session_schedule_bye_locked (RTPSession * sess, static GstClockTime calculate_rtcp_interval (RTPSession * sess, gboolean deterministic, gboolean first); +static gboolean +accumulate_trues (GSignalInvocationHint * ihint, GValue * return_accu, + const GValue * handler_return, gpointer data) +{ + if (g_value_get_boolean (handler_return)) + g_value_set_boolean (return_accu, TRUE); + + return TRUE; +} + static void rtp_session_class_init (RTPSessionClass * klass) { @@ -240,6 +251,24 @@ rtp_session_class_init (RTPSessionClass * klass) NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, RTP_TYPE_SOURCE); + /** + * RTPSession::on-sending-rtcp + * @session: the object which received the signal + * @buffer: the #GstBuffer containing the RTCP packet about to be sent + * @early: %TRUE if the packet is early, %FALSE if it is regular + * + * This signal is emitted before sending an RTCP packet, it can be used + * to add extra RTCP Packets. + * + * Returns: %TRUE if the RTCP buffer should NOT be suppressed, %FALSE + * if suppressing it is acceptable + */ + rtp_session_signals[SIGNAL_ON_SENDING_RTCP] = + g_signal_new ("on-sending-rtcp", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_sending_rtcp), + accumulate_trues, NULL, gst_rtp_bin_marshal_BOOLEAN__POINTER_BOOLEAN, + G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_BOOLEAN); + g_object_class_install_property (gobject_class, PROP_INTERNAL_SSRC, g_param_spec_uint ("internal-ssrc", "Internal SSRC", "The internal SSRC used for the session", @@ -2704,6 +2733,10 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time, /* push out the RTCP packet */ if (data.rtcp) { + /* Give the user a change to add its own packet */ + g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_SENDING_RTCP], 0, + data.rtcp, FALSE, NULL); + /* close the RTCP packet */ gst_rtcp_buffer_end (data.rtcp); diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index 3fc9874..0f86856 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -224,6 +224,8 @@ struct _RTPSessionClass { void (*on_bye_timeout) (RTPSession *sess, RTPSource *source); void (*on_timeout) (RTPSession *sess, RTPSource *source); void (*on_sender_timeout) (RTPSession *sess, RTPSource *source); + gboolean (*on_sending_rtcp) (RTPSession *sess, GstBuffer *buffer, + gboolean early); }; GType rtp_session_get_type (void); |
From: <wt...@ke...> - 2011-02-01 18:00:44
|
Module: gst-plugins-good Branch: master Commit: 9f073459e092097aec6f2d98189fbb0e8e72931e URL: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=9f073459e092097aec6f2d98189fbb0e8e72931e Author: Olivier Crête <oli...@co...> Date: Fri Oct 1 17:19:16 2010 -0400 rtpsession: Emit "on-ssrc-validated" when validating by RTCP Emit "on-ssrc-validated" if the SSRC is validated by receiving a RTCP SDES packet. --- gst/rtpmanager/rtpsession.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index 2698f3c..176a86f 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -1749,7 +1749,7 @@ rtp_session_process_sdes (RTPSession * sess, GstRTCPPacket * packet, i = 0; while (more_items) { guint32 ssrc; - gboolean changed, created; + gboolean changed, created, validated; RTPSource *source; GstStructure *sdes; @@ -1802,10 +1802,13 @@ rtp_session_process_sdes (RTPSession * sess, GstRTCPPacket * packet, /* takes ownership of sdes */ changed = rtp_source_set_sdes_struct (source, sdes); + validated = !RTP_SOURCE_IS_ACTIVE (source); source->validated = TRUE; if (created) on_new_ssrc (sess, source); + if (validated) + on_ssrc_validated (sess, source); if (changed) on_ssrc_sdes (sess, source); |