diff options
Diffstat (limited to 'gst/rtpmanager')
-rw-r--r-- | gst/rtpmanager/Makefile.in | 140 | ||||
-rw-r--r-- | gst/rtpmanager/gstrtpbin.c | 257 | ||||
-rw-r--r-- | gst/rtpmanager/gstrtpbin.h | 2 | ||||
-rw-r--r-- | gst/rtpmanager/gstrtpjitterbuffer.c | 36 | ||||
-rw-r--r-- | gst/rtpmanager/gstrtpptdemux.c | 16 | ||||
-rw-r--r-- | gst/rtpmanager/gstrtpsession.c | 66 | ||||
-rw-r--r-- | gst/rtpmanager/gstrtpssrcdemux.c | 143 | ||||
-rw-r--r-- | gst/rtpmanager/gstrtpssrcdemux.h | 2 | ||||
-rw-r--r-- | gst/rtpmanager/rtpjitterbuffer.c | 24 | ||||
-rw-r--r-- | gst/rtpmanager/rtpsession.c | 318 | ||||
-rw-r--r-- | gst/rtpmanager/rtpsession.h | 11 | ||||
-rw-r--r-- | gst/rtpmanager/rtpsource.c | 3 | ||||
-rw-r--r-- | gst/rtpmanager/rtpsource.h | 5 |
13 files changed, 766 insertions, 257 deletions
diff --git a/gst/rtpmanager/Makefile.in b/gst/rtpmanager/Makefile.in index 85d915d..212952f 100644 --- a/gst/rtpmanager/Makefile.in +++ b/gst/rtpmanager/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -75,8 +75,7 @@ am__aclocal_m4_deps = $(top_srcdir)/common/m4/as-ac-expand.m4 \ $(top_srcdir)/common/m4/orc.m4 $(top_srcdir)/common/m4/pkg.m4 \ $(top_srcdir)/m4/aalib.m4 $(top_srcdir)/m4/esd.m4 \ $(top_srcdir)/m4/gconf-2.m4 $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/gst-fionread.m4 \ - $(top_srcdir)/m4/gst-shout2.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/gst-fionread.m4 $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ @@ -111,6 +110,12 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(plugin_LTLIBRARIES) am__DEPENDENCIES_1 = @@ -130,8 +135,8 @@ am__objects_1 = libgstrtpmanager_la-gstrtpbin-marshal.lo nodist_libgstrtpmanager_la_OBJECTS = $(am__objects_1) libgstrtpmanager_la_OBJECTS = $(am_libgstrtpmanager_la_OBJECTS) \ $(nodist_libgstrtpmanager_la_OBJECTS) -AM_V_lt = $(am__v_lt_$(V)) -am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent libgstrtpmanager_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ @@ -147,21 +152,21 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_$(V)) -am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_$(V)) -am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libgstrtpmanager_la_SOURCES) \ $(nodist_libgstrtpmanager_la_SOURCES) @@ -245,7 +250,10 @@ GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@ GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_EXTRA_CFLAGS = @GLIB_EXTRA_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GLIB_PREFIX = @GLIB_PREFIX@ GLIB_REQ = @GLIB_REQ@ @@ -320,7 +328,6 @@ JPEG_LIBS = @JPEG_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBCACA_CFLAGS = @LIBCACA_CFLAGS@ -LIBCACA_CONFIG = @LIBCACA_CONFIG@ LIBCACA_LIBS = @LIBCACA_LIBS@ LIBDV_CFLAGS = @LIBDV_CFLAGS@ LIBDV_LIBS = @LIBDV_LIBS@ @@ -344,6 +351,7 @@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ @@ -378,18 +386,10 @@ PKG_CONFIG = @PKG_CONFIG@ PLUGINDIR = @PLUGINDIR@ POSUB = @POSUB@ PROFILE_CFLAGS = @PROFILE_CFLAGS@ -PULSE_0_9_11_CFLAGS = @PULSE_0_9_11_CFLAGS@ -PULSE_0_9_11_LIBS = @PULSE_0_9_11_LIBS@ -PULSE_0_9_12_CFLAGS = @PULSE_0_9_12_CFLAGS@ -PULSE_0_9_12_LIBS = @PULSE_0_9_12_LIBS@ -PULSE_0_9_13_CFLAGS = @PULSE_0_9_13_CFLAGS@ -PULSE_0_9_13_LIBS = @PULSE_0_9_13_LIBS@ -PULSE_0_9_15_CFLAGS = @PULSE_0_9_15_CFLAGS@ -PULSE_0_9_15_LIBS = @PULSE_0_9_15_LIBS@ -PULSE_0_9_16_CFLAGS = @PULSE_0_9_16_CFLAGS@ -PULSE_0_9_16_LIBS = @PULSE_0_9_16_LIBS@ PULSE_0_9_20_CFLAGS = @PULSE_0_9_20_CFLAGS@ PULSE_0_9_20_LIBS = @PULSE_0_9_20_LIBS@ +PULSE_1_0_CFLAGS = @PULSE_1_0_CFLAGS@ +PULSE_1_0_LIBS = @PULSE_1_0_LIBS@ PULSE_CFLAGS = @PULSE_CFLAGS@ PULSE_LIBS = @PULSE_LIBS@ PYTHON = @PYTHON@ @@ -442,6 +442,7 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ @@ -476,7 +477,6 @@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ -lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ @@ -566,6 +566,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; +$(top_srcdir)/common/gst-glib-gen.mak: $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh @@ -606,7 +607,7 @@ clean-pluginLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libgstrtpmanager.la: $(libgstrtpmanager_la_OBJECTS) $(libgstrtpmanager_la_DEPENDENCIES) +libgstrtpmanager.la: $(libgstrtpmanager_la_OBJECTS) $(libgstrtpmanager_la_DEPENDENCIES) $(EXTRA_libgstrtpmanager_la_DEPENDENCIES) $(AM_V_CCLD)$(libgstrtpmanager_la_LINK) -rpath $(plugindir) $(libgstrtpmanager_la_OBJECTS) $(libgstrtpmanager_la_LIBADD) $(LIBS) mostlyclean-compile: @@ -630,114 +631,100 @@ distclean-compile: .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libgstrtpmanager_la-gstrtpmanager.lo: gstrtpmanager.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -MT libgstrtpmanager_la-gstrtpmanager.lo -MD -MP -MF $(DEPDIR)/libgstrtpmanager_la-gstrtpmanager.Tpo -c -o libgstrtpmanager_la-gstrtpmanager.lo `test -f 'gstrtpmanager.c' || echo '$(srcdir)/'`gstrtpmanager.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstrtpmanager_la-gstrtpmanager.Tpo $(DEPDIR)/libgstrtpmanager_la-gstrtpmanager.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstrtpmanager.c' object='libgstrtpmanager_la-gstrtpmanager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstrtpmanager.c' object='libgstrtpmanager_la-gstrtpmanager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpmanager.lo `test -f 'gstrtpmanager.c' || echo '$(srcdir)/'`gstrtpmanager.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpmanager.lo `test -f 'gstrtpmanager.c' || echo '$(srcdir)/'`gstrtpmanager.c libgstrtpmanager_la-gstrtpbin.lo: gstrtpbin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -MT libgstrtpmanager_la-gstrtpbin.lo -MD -MP -MF $(DEPDIR)/libgstrtpmanager_la-gstrtpbin.Tpo -c -o libgstrtpmanager_la-gstrtpbin.lo `test -f 'gstrtpbin.c' || echo '$(srcdir)/'`gstrtpbin.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstrtpmanager_la-gstrtpbin.Tpo $(DEPDIR)/libgstrtpmanager_la-gstrtpbin.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstrtpbin.c' object='libgstrtpmanager_la-gstrtpbin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstrtpbin.c' object='libgstrtpmanager_la-gstrtpbin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpbin.lo `test -f 'gstrtpbin.c' || echo '$(srcdir)/'`gstrtpbin.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpbin.lo `test -f 'gstrtpbin.c' || echo '$(srcdir)/'`gstrtpbin.c libgstrtpmanager_la-gstrtpjitterbuffer.lo: gstrtpjitterbuffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -MT libgstrtpmanager_la-gstrtpjitterbuffer.lo -MD -MP -MF $(DEPDIR)/libgstrtpmanager_la-gstrtpjitterbuffer.Tpo -c -o libgstrtpmanager_la-gstrtpjitterbuffer.lo `test -f 'gstrtpjitterbuffer.c' || echo '$(srcdir)/'`gstrtpjitterbuffer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstrtpmanager_la-gstrtpjitterbuffer.Tpo $(DEPDIR)/libgstrtpmanager_la-gstrtpjitterbuffer.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstrtpjitterbuffer.c' object='libgstrtpmanager_la-gstrtpjitterbuffer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstrtpjitterbuffer.c' object='libgstrtpmanager_la-gstrtpjitterbuffer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpjitterbuffer.lo `test -f 'gstrtpjitterbuffer.c' || echo '$(srcdir)/'`gstrtpjitterbuffer.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpjitterbuffer.lo `test -f 'gstrtpjitterbuffer.c' || echo '$(srcdir)/'`gstrtpjitterbuffer.c libgstrtpmanager_la-gstrtpptdemux.lo: gstrtpptdemux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -MT libgstrtpmanager_la-gstrtpptdemux.lo -MD -MP -MF $(DEPDIR)/libgstrtpmanager_la-gstrtpptdemux.Tpo -c -o libgstrtpmanager_la-gstrtpptdemux.lo `test -f 'gstrtpptdemux.c' || echo '$(srcdir)/'`gstrtpptdemux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstrtpmanager_la-gstrtpptdemux.Tpo $(DEPDIR)/libgstrtpmanager_la-gstrtpptdemux.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstrtpptdemux.c' object='libgstrtpmanager_la-gstrtpptdemux.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstrtpptdemux.c' object='libgstrtpmanager_la-gstrtpptdemux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpptdemux.lo `test -f 'gstrtpptdemux.c' || echo '$(srcdir)/'`gstrtpptdemux.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpptdemux.lo `test -f 'gstrtpptdemux.c' || echo '$(srcdir)/'`gstrtpptdemux.c libgstrtpmanager_la-gstrtpssrcdemux.lo: gstrtpssrcdemux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -MT libgstrtpmanager_la-gstrtpssrcdemux.lo -MD -MP -MF $(DEPDIR)/libgstrtpmanager_la-gstrtpssrcdemux.Tpo -c -o libgstrtpmanager_la-gstrtpssrcdemux.lo `test -f 'gstrtpssrcdemux.c' || echo '$(srcdir)/'`gstrtpssrcdemux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstrtpmanager_la-gstrtpssrcdemux.Tpo $(DEPDIR)/libgstrtpmanager_la-gstrtpssrcdemux.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstrtpssrcdemux.c' object='libgstrtpmanager_la-gstrtpssrcdemux.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstrtpssrcdemux.c' object='libgstrtpmanager_la-gstrtpssrcdemux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpssrcdemux.lo `test -f 'gstrtpssrcdemux.c' || echo '$(srcdir)/'`gstrtpssrcdemux.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpssrcdemux.lo `test -f 'gstrtpssrcdemux.c' || echo '$(srcdir)/'`gstrtpssrcdemux.c libgstrtpmanager_la-rtpjitterbuffer.lo: rtpjitterbuffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -MT libgstrtpmanager_la-rtpjitterbuffer.lo -MD -MP -MF $(DEPDIR)/libgstrtpmanager_la-rtpjitterbuffer.Tpo -c -o libgstrtpmanager_la-rtpjitterbuffer.lo `test -f 'rtpjitterbuffer.c' || echo '$(srcdir)/'`rtpjitterbuffer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstrtpmanager_la-rtpjitterbuffer.Tpo $(DEPDIR)/libgstrtpmanager_la-rtpjitterbuffer.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rtpjitterbuffer.c' object='libgstrtpmanager_la-rtpjitterbuffer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtpjitterbuffer.c' object='libgstrtpmanager_la-rtpjitterbuffer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-rtpjitterbuffer.lo `test -f 'rtpjitterbuffer.c' || echo '$(srcdir)/'`rtpjitterbuffer.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-rtpjitterbuffer.lo `test -f 'rtpjitterbuffer.c' || echo '$(srcdir)/'`rtpjitterbuffer.c libgstrtpmanager_la-rtpsession.lo: rtpsession.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -MT libgstrtpmanager_la-rtpsession.lo -MD -MP -MF $(DEPDIR)/libgstrtpmanager_la-rtpsession.Tpo -c -o libgstrtpmanager_la-rtpsession.lo `test -f 'rtpsession.c' || echo '$(srcdir)/'`rtpsession.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstrtpmanager_la-rtpsession.Tpo $(DEPDIR)/libgstrtpmanager_la-rtpsession.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rtpsession.c' object='libgstrtpmanager_la-rtpsession.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtpsession.c' object='libgstrtpmanager_la-rtpsession.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-rtpsession.lo `test -f 'rtpsession.c' || echo '$(srcdir)/'`rtpsession.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-rtpsession.lo `test -f 'rtpsession.c' || echo '$(srcdir)/'`rtpsession.c libgstrtpmanager_la-rtpsource.lo: rtpsource.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -MT libgstrtpmanager_la-rtpsource.lo -MD -MP -MF $(DEPDIR)/libgstrtpmanager_la-rtpsource.Tpo -c -o libgstrtpmanager_la-rtpsource.lo `test -f 'rtpsource.c' || echo '$(srcdir)/'`rtpsource.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstrtpmanager_la-rtpsource.Tpo $(DEPDIR)/libgstrtpmanager_la-rtpsource.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rtpsource.c' object='libgstrtpmanager_la-rtpsource.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtpsource.c' object='libgstrtpmanager_la-rtpsource.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-rtpsource.lo `test -f 'rtpsource.c' || echo '$(srcdir)/'`rtpsource.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-rtpsource.lo `test -f 'rtpsource.c' || echo '$(srcdir)/'`rtpsource.c libgstrtpmanager_la-rtpstats.lo: rtpstats.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -MT libgstrtpmanager_la-rtpstats.lo -MD -MP -MF $(DEPDIR)/libgstrtpmanager_la-rtpstats.Tpo -c -o libgstrtpmanager_la-rtpstats.lo `test -f 'rtpstats.c' || echo '$(srcdir)/'`rtpstats.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstrtpmanager_la-rtpstats.Tpo $(DEPDIR)/libgstrtpmanager_la-rtpstats.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rtpstats.c' object='libgstrtpmanager_la-rtpstats.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtpstats.c' object='libgstrtpmanager_la-rtpstats.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-rtpstats.lo `test -f 'rtpstats.c' || echo '$(srcdir)/'`rtpstats.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-rtpstats.lo `test -f 'rtpstats.c' || echo '$(srcdir)/'`rtpstats.c libgstrtpmanager_la-gstrtpsession.lo: gstrtpsession.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -MT libgstrtpmanager_la-gstrtpsession.lo -MD -MP -MF $(DEPDIR)/libgstrtpmanager_la-gstrtpsession.Tpo -c -o libgstrtpmanager_la-gstrtpsession.lo `test -f 'gstrtpsession.c' || echo '$(srcdir)/'`gstrtpsession.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstrtpmanager_la-gstrtpsession.Tpo $(DEPDIR)/libgstrtpmanager_la-gstrtpsession.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstrtpsession.c' object='libgstrtpmanager_la-gstrtpsession.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstrtpsession.c' object='libgstrtpmanager_la-gstrtpsession.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpsession.lo `test -f 'gstrtpsession.c' || echo '$(srcdir)/'`gstrtpsession.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpsession.lo `test -f 'gstrtpsession.c' || echo '$(srcdir)/'`gstrtpsession.c libgstrtpmanager_la-gstrtpbin-marshal.lo: gstrtpbin-marshal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -MT libgstrtpmanager_la-gstrtpbin-marshal.lo -MD -MP -MF $(DEPDIR)/libgstrtpmanager_la-gstrtpbin-marshal.Tpo -c -o libgstrtpmanager_la-gstrtpbin-marshal.lo `test -f 'gstrtpbin-marshal.c' || echo '$(srcdir)/'`gstrtpbin-marshal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstrtpmanager_la-gstrtpbin-marshal.Tpo $(DEPDIR)/libgstrtpmanager_la-gstrtpbin-marshal.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstrtpbin-marshal.c' object='libgstrtpmanager_la-gstrtpbin-marshal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstrtpbin-marshal.c' object='libgstrtpmanager_la-gstrtpbin-marshal.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpbin-marshal.lo `test -f 'gstrtpbin-marshal.c' || echo '$(srcdir)/'`gstrtpbin-marshal.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstrtpmanager_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstrtpmanager_la_CFLAGS) $(CFLAGS) -c -o libgstrtpmanager_la-gstrtpbin-marshal.lo `test -f 'gstrtpbin-marshal.c' || echo '$(srcdir)/'`gstrtpbin-marshal.c mostlyclean-libtool: -rm -f *.lo @@ -846,10 +833,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c index e8d659f..f843ed2 100644 --- a/gst/rtpmanager/gstrtpbin.c +++ b/gst/rtpmanager/gstrtpbin.c @@ -129,6 +129,8 @@ #include "gstrtpsession.h" #include "gstrtpjitterbuffer.h" +#include <gst/glib-compat-private.h> + GST_DEBUG_CATEGORY_STATIC (gst_rtp_bin_debug); #define GST_CAT_DEFAULT gst_rtp_bin_debug @@ -213,6 +215,9 @@ struct _GstRtpBinPrivate gint shutdown; gboolean autoremove; + + /* UNIX (ntp) time of last SR sync used */ + guint64 last_unix; }; /* signals and args */ @@ -245,6 +250,8 @@ enum #define DEFAULT_AUTOREMOVE FALSE #define DEFAULT_BUFFER_MODE RTP_JITTER_BUFFER_MODE_SLAVE #define DEFAULT_USE_PIPELINE_CLOCK FALSE +#define DEFAULT_RTCP_SYNC GST_RTP_BIN_RTCP_SYNC_ALWAYS +#define DEFAULT_RTCP_SYNC_INTERVAL 0 enum { @@ -254,12 +261,39 @@ enum PROP_DO_LOST, PROP_IGNORE_PT, PROP_NTP_SYNC, + PROP_RTCP_SYNC, + PROP_RTCP_SYNC_INTERVAL, PROP_AUTOREMOVE, PROP_BUFFER_MODE, PROP_USE_PIPELINE_CLOCK, PROP_LAST }; +enum +{ + GST_RTP_BIN_RTCP_SYNC_ALWAYS, + GST_RTP_BIN_RTCP_SYNC_INITIAL, + GST_RTP_BIN_RTCP_SYNC_RTP +}; + +#define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type()) +static GType +gst_rtp_bin_rtcp_sync_get_type (void) +{ + static GType rtcp_sync_type = 0; + static const GEnumValue rtcp_sync_types[] = { + {GST_RTP_BIN_RTCP_SYNC_ALWAYS, "always", "always"}, + {GST_RTP_BIN_RTCP_SYNC_INITIAL, "initial", "initial"}, + {GST_RTP_BIN_RTCP_SYNC_RTP, "rtp-info", "rtp-info"}, + {0, NULL, NULL}, + }; + + if (!rtcp_sync_type) { + rtcp_sync_type = g_enum_register_static ("GstRTCPSync", rtcp_sync_types); + } + return rtcp_sync_type; +} + /* helper objects */ typedef struct _GstRtpBinSession GstRtpBinSession; typedef struct _GstRtpBinStream GstRtpBinStream; @@ -310,6 +344,9 @@ struct _GstRtpBinStream gboolean have_sync; /* mapping to local RTP and NTP time */ gint64 rt_delta; + gint64 rtp_delta; + /* base rtptime in gst time */ + gint64 clock_base; }; #define GST_RTP_SESSION_LOCK(sess) g_mutex_lock ((sess)->lock) @@ -775,6 +812,8 @@ gst_rtp_bin_reset_sync (GstRtpBin * rtpbin) * lip-sync */ stream->have_sync = FALSE; stream->rt_delta = 0; + stream->rtp_delta = 0; + stream->clock_base = -100 * GST_SECOND; } } GST_RTP_BIN_UNLOCK (rtpbin); @@ -979,7 +1018,8 @@ stream_set_ts_offset (GstRtpBin * bin, GstRtpBinStream * stream, static void gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len, guint8 * data, guint64 ntptime, guint64 last_extrtptime, - guint64 base_rtptime, guint64 base_time, guint clock_rate) + guint64 base_rtptime, guint64 base_time, guint clock_rate, + gint64 rtp_clock_base) { GstRtpBinClient *client; gboolean created; @@ -1014,6 +1054,19 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len, stream->ssrc, client, client->cname); } + if (!GST_CLOCK_TIME_IS_VALID (last_extrtptime)) { + GST_DEBUG_OBJECT (bin, "invalidated sync data"); + if (bin->rtcp_sync == GST_RTP_BIN_RTCP_SYNC_RTP) { + /* we don't need that data, so carry on, + * but make some values look saner */ + last_extrtptime = base_rtptime; + } else { + /* nothing we can do with this data in this case */ + GST_DEBUG_OBJECT (bin, "bailing out"); + return; + } + } + /* Take the extended rtptime we found in the SR packet and map it to the * local rtptime. The local rtp time is used to construct timestamps on the * buffers so we will calculate what running_time corresponds to the RTP @@ -1022,8 +1075,9 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len, GST_DEBUG_OBJECT (bin, "base %" G_GUINT64_FORMAT ", extrtptime %" G_GUINT64_FORMAT - ", local RTP %" G_GUINT64_FORMAT ", clock-rate %d", base_rtptime, - last_extrtptime, local_rtp, clock_rate); + ", local RTP %" G_GUINT64_FORMAT ", clock-rate %d, " + "clock-base %" G_GINT64_FORMAT, base_rtptime, + last_extrtptime, local_rtp, clock_rate, rtp_clock_base); /* calculate local RTP time in gstreamer timestamp, we essentially perform the * same conversion that a jitterbuffer would use to convert an rtp timestamp @@ -1070,8 +1124,10 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len, stream->rt_delta = rtdiff - ntpdiff; stream_set_ts_offset (bin, stream, stream->rt_delta); - } else if (client->nstreams > 1) { - gint64 min; + } else { + gint64 min, rtp_min, clock_base = stream->clock_base; + gboolean all_sync, use_rtp; + gboolean rtcp_sync = g_atomic_int_get (&bin->rtcp_sync); /* calculate delta between server and receiver. last_unix is created by * converting the ntptime in the last SR packet to a gstreamer timestamp. This @@ -1089,19 +1145,114 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len, * latencies). * The stream that has the smallest diff is selected as the reference stream, * all other streams will have a positive offset to this difference. */ - min = G_MAXINT64; + + /* some alternative setting allow ignoring RTCP as much as possible, + * for servers generating bogus ntp timeline */ + min = rtp_min = G_MAXINT64; + use_rtp = FALSE; + if (rtcp_sync == GST_RTP_BIN_RTCP_SYNC_RTP) { + guint64 ext_base; + + use_rtp = TRUE; + /* signed version for convienience */ + clock_base = base_rtptime; + /* deal with possible wrap-around */ + ext_base = base_rtptime; + rtp_clock_base = gst_rtp_buffer_ext_timestamp (&ext_base, rtp_clock_base); + /* sanity check; base rtp and provided clock_base should be close */ + if (rtp_clock_base >= clock_base) { + if (rtp_clock_base - clock_base < 10 * clock_rate) { + rtp_clock_base = base_time + + gst_util_uint64_scale_int (rtp_clock_base - clock_base, + GST_SECOND, clock_rate); + } else { + use_rtp = FALSE; + } + } else { + if (clock_base - rtp_clock_base < 10 * clock_rate) { + rtp_clock_base = base_time - + gst_util_uint64_scale_int (clock_base - rtp_clock_base, + GST_SECOND, clock_rate); + } else { + use_rtp = FALSE; + } + } + /* warn and bail for clarity out if no sane values */ + if (!use_rtp) { + GST_WARNING_OBJECT (bin, "unable to sync to provided rtptime"); + return; + } + /* store to track changes */ + clock_base = rtp_clock_base; + /* generate a fake as before, + * now equating rtptime obtained from RTP-Info, + * where the large time represent the otherwise irrelevant npt/ntp time */ + stream->rtp_delta = (GST_SECOND << 28) - rtp_clock_base; + } + for (walk = client->streams; walk; walk = g_slist_next (walk)) { GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data; - if (!ostream->have_sync) + if (!ostream->have_sync) { + all_sync = FALSE; continue; + } + + /* change in current stream's base from previously init'ed value + * leads to reset of all stream's base */ + if (stream != ostream && stream->clock_base >= 0 && + (stream->clock_base != clock_base)) { + GST_DEBUG_OBJECT (bin, "reset upon clock base change"); + ostream->clock_base = -100 * GST_SECOND; + ostream->rtp_delta = 0; + } if (ostream->rt_delta < min) min = ostream->rt_delta; + if (ostream->rtp_delta < rtp_min) + rtp_min = ostream->rtp_delta; } - GST_DEBUG_OBJECT (bin, "client %p min delta %" G_GINT64_FORMAT, client, - min); + /* arrange to re-sync for each stream upon significant change, + * e.g. post-seek */ + all_sync = (stream->clock_base == clock_base); + stream->clock_base = clock_base; + + /* may need init performed above later on, but nothing more to do now */ + if (client->nstreams <= 1) + return; + + GST_DEBUG_OBJECT (bin, "client %p min delta %" G_GINT64_FORMAT + " all sync %d", client, min, all_sync); + GST_DEBUG_OBJECT (bin, "rtcp sync mode %d, use_rtp %d", rtcp_sync, use_rtp); + + switch (rtcp_sync) { + case GST_RTP_BIN_RTCP_SYNC_RTP: + if (!use_rtp) + break; + GST_DEBUG_OBJECT (bin, "using rtp generated reports; " + "client %p min rtp delta %" G_GINT64_FORMAT, client, rtp_min); + /* fall-through */ + case GST_RTP_BIN_RTCP_SYNC_INITIAL: + /* if all have been synced already, do not bother further */ + if (all_sync) { + GST_DEBUG_OBJECT (bin, "all streams already synced; done"); + return; + } + break; + default: + break; + } + + /* bail out if we adjusted recently enough */ + if (all_sync && (last_unix - bin->priv->last_unix) < + bin->rtcp_sync_interval * GST_MSECOND) { + GST_DEBUG_OBJECT (bin, "discarding RTCP sender packet for sync; " + "previous sender info too recent " + "(previous UNIX %" G_GUINT64_FORMAT ")", bin->priv->last_unix); + return; + } + bin->priv->last_unix = last_unix; /* calculate offsets for each stream */ for (walk = client->streams; walk; walk = g_slist_next (walk)) { @@ -1116,7 +1267,10 @@ gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len, /* calculate offset to our reference stream, this should always give a * positive number. */ - ts_offset = ostream->rt_delta - min; + if (use_rtp) + ts_offset = ostream->rtp_delta - rtp_min; + else + ts_offset = ostream->rt_delta - min; stream_set_ts_offset (bin, ostream, ts_offset); } @@ -1149,6 +1303,7 @@ gst_rtp_bin_handle_sync (GstElement * jitterbuffer, GstStructure * s, guint64 base_rtptime; guint64 base_time; guint clock_rate; + guint64 clock_base; guint64 extrtptime; GstBuffer *buffer; @@ -1164,6 +1319,7 @@ gst_rtp_bin_handle_sync (GstElement * jitterbuffer, GstStructure * s, g_value_get_uint64 (gst_structure_get_value (s, "base-rtptime")); base_time = g_value_get_uint64 (gst_structure_get_value (s, "base-time")); clock_rate = g_value_get_uint (gst_structure_get_value (s, "clock-rate")); + clock_base = g_value_get_uint64 (gst_structure_get_value (s, "clock-base")); extrtptime = g_value_get_uint64 (gst_structure_get_value (s, "sr-ext-rtptime")); buffer = gst_value_get_buffer (gst_structure_get_value (s, "sr-buffer")); @@ -1216,7 +1372,8 @@ gst_rtp_bin_handle_sync (GstElement * jitterbuffer, GstStructure * s, GST_RTP_BIN_LOCK (bin); /* associate the stream to CNAME */ gst_rtp_bin_associate (bin, stream, len, data, - ntptime, extrtptime, base_rtptime, base_time, clock_rate); + ntptime, extrtptime, base_rtptime, base_time, clock_rate, + clock_base); GST_RTP_BIN_UNLOCK (bin); } } @@ -1260,7 +1417,9 @@ create_stream (GstRtpBinSession * session, guint32 ssrc) stream->have_sync = FALSE; stream->rt_delta = 0; + stream->rtp_delta = 0; stream->percent = 100; + stream->clock_base = -100 * GST_SECOND; session->streams = g_slist_prepend (session->streams, stream); /* provide clock_rate to the jitterbuffer when needed */ @@ -1380,20 +1539,20 @@ gst_rtp_bin_base_init (gpointer klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); /* sink pads */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_recv_rtp_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_recv_rtcp_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_send_rtp_sink_template)); + gst_element_class_add_static_pad_template (element_class, + &rtpbin_recv_rtp_sink_template); + gst_element_class_add_static_pad_template (element_class, + &rtpbin_recv_rtcp_sink_template); + gst_element_class_add_static_pad_template (element_class, + &rtpbin_send_rtp_sink_template); /* src pads */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_recv_rtp_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_send_rtcp_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_send_rtp_src_template)); + gst_element_class_add_static_pad_template (element_class, + &rtpbin_recv_rtp_src_template); + gst_element_class_add_static_pad_template (element_class, + &rtpbin_send_rtcp_src_template); + gst_element_class_add_static_pad_template (element_class, + &rtpbin_send_rtp_src_template); gst_element_class_set_details_simple (element_class, "RTP Bin", "Filter/Network/RTP", @@ -1677,6 +1836,32 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass) "Synchronize received streams to the NTP clock", DEFAULT_NTP_SYNC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstRtpBin::rtcp-sync: + * + * If not synchronizing (directly) to the NTP clock, determines how to sync + * the various streams. + * + * Since: 0.10.31 + */ + g_object_class_install_property (gobject_class, PROP_RTCP_SYNC, + g_param_spec_enum ("rtcp-sync", "RTCP Sync", + "Use of RTCP SR in synchronization", GST_RTP_BIN_RTCP_SYNC_TYPE, + DEFAULT_RTCP_SYNC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstRtpBin::rtcp-sync-interval: + * + * Determines how often to sync streams using RTCP data. + * + * Since: 0.10.31 + */ + g_object_class_install_property (gobject_class, PROP_RTCP_SYNC_INTERVAL, + g_param_spec_uint ("rtcp-sync-interval", "RTCP Sync Interval", + "RTCP SR interval synchronization (ms) (0 = always)", + 0, G_MAXUINT, DEFAULT_RTCP_SYNC_INTERVAL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state); gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad); @@ -1695,7 +1880,7 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass) static void gst_rtp_bin_init (GstRtpBin * rtpbin, GstRtpBinClass * klass) { - gchar *str; + gchar *cname; rtpbin->priv = GST_RTP_BIN_GET_PRIVATE (rtpbin); rtpbin->priv->bin_lock = g_mutex_new (); @@ -1706,17 +1891,17 @@ gst_rtp_bin_init (GstRtpBin * rtpbin, GstRtpBinClass * klass) rtpbin->do_lost = DEFAULT_DO_LOST; rtpbin->ignore_pt = DEFAULT_IGNORE_PT; rtpbin->ntp_sync = DEFAULT_NTP_SYNC; + rtpbin->rtcp_sync = DEFAULT_RTCP_SYNC; + rtpbin->rtcp_sync_interval = DEFAULT_RTCP_SYNC_INTERVAL; rtpbin->priv->autoremove = DEFAULT_AUTOREMOVE; rtpbin->buffer_mode = DEFAULT_BUFFER_MODE; rtpbin->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK; /* some default SDES entries */ - str = g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ()); + cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ()); rtpbin->sdes = gst_structure_new ("application/x-rtp-source-sdes", - "cname", G_TYPE_STRING, str, - "name", G_TYPE_STRING, g_get_real_name (), - "tool", G_TYPE_STRING, "GStreamer", NULL); - g_free (str); + "cname", G_TYPE_STRING, cname, "tool", G_TYPE_STRING, "GStreamer", NULL); + g_free (cname); } static void @@ -1821,6 +2006,12 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id, case PROP_NTP_SYNC: rtpbin->ntp_sync = g_value_get_boolean (value); break; + case PROP_RTCP_SYNC: + g_atomic_int_set (&rtpbin->rtcp_sync, g_value_get_enum (value)); + break; + case PROP_RTCP_SYNC_INTERVAL: + rtpbin->rtcp_sync_interval = g_value_get_uint (value); + break; case PROP_IGNORE_PT: rtpbin->ignore_pt = g_value_get_boolean (value); break; @@ -1883,6 +2074,12 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id, case PROP_NTP_SYNC: g_value_set_boolean (value, rtpbin->ntp_sync); break; + case PROP_RTCP_SYNC: + g_value_set_enum (value, g_atomic_int_get (&rtpbin->rtcp_sync)); + break; + case PROP_RTCP_SYNC_INTERVAL: + g_value_set_uint (value, rtpbin->rtcp_sync_interval); + break; case PROP_AUTOREMOVE: g_value_set_boolean (value, rtpbin->priv->autoremove); break; @@ -2020,6 +2217,7 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message) now = gst_clock_get_time (clock); base_time = gst_element_get_base_time (GST_ELEMENT_CAST (bin)); running_time = now - base_time; + gst_object_unref (clock); } GST_DEBUG_OBJECT (bin, "running time now %" GST_TIME_FORMAT, @@ -2108,6 +2306,7 @@ gst_rtp_bin_change_state (GstElement * element, GstStateChange transition) case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: + priv->last_unix = 0; GST_LOG_OBJECT (rtpbin, "clearing shutdown flag"); g_atomic_int_set (&priv->shutdown, 0); break; diff --git a/gst/rtpmanager/gstrtpbin.h b/gst/rtpmanager/gstrtpbin.h index 74aaac2..a915787 100644 --- a/gst/rtpmanager/gstrtpbin.h +++ b/gst/rtpmanager/gstrtpbin.h @@ -50,6 +50,8 @@ struct _GstRtpBin { gboolean do_lost; gboolean ignore_pt; gboolean ntp_sync; + gint rtcp_sync; + guint rtcp_sync_interval; RTPJitterBufferMode buffer_mode; gboolean buffering; gboolean use_pipeline_clock; diff --git a/gst/rtpmanager/gstrtpjitterbuffer.c b/gst/rtpmanager/gstrtpjitterbuffer.c index e118699..4c72fb6 100644 --- a/gst/rtpmanager/gstrtpjitterbuffer.c +++ b/gst/rtpmanager/gstrtpjitterbuffer.c @@ -67,6 +67,8 @@ #include "rtpjitterbuffer.h" #include "rtpstats.h" +#include <gst/glib-compat-private.h> + GST_DEBUG_CATEGORY (rtpjitterbuffer_debug); #define GST_CAT_DEFAULT (rtpjitterbuffer_debug) @@ -272,12 +274,12 @@ gst_rtp_jitter_buffer_base_init (gpointer klass) { GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_rtp_jitter_buffer_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_rtp_jitter_buffer_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_rtp_jitter_buffer_sink_rtcp_template)); + gst_element_class_add_static_pad_template (element_class, + &gst_rtp_jitter_buffer_src_template); + gst_element_class_add_static_pad_template (element_class, + &gst_rtp_jitter_buffer_sink_template); + gst_element_class_add_static_pad_template (element_class, + &gst_rtp_jitter_buffer_sink_rtcp_template); gst_element_class_set_details_simple (element_class, "RTP packet jitter-buffer", "Filter/Network/RTP", @@ -671,6 +673,11 @@ gst_rtp_jitter_buffer_clear_pt_map (GstRtpJitterBuffer * jitterbuffer) JBUF_LOCK (priv); priv->clock_rate = -1; + /* do not clear current content, but refresh state for new arrival */ + GST_DEBUG_OBJECT (jitterbuffer, "reset jitterbuffer"); + rtp_jitter_buffer_reset_skew (priv->jbuf); + priv->last_popped_seqnum = -1; + priv->next_seqnum = -1; JBUF_UNLOCK (priv); } @@ -1970,6 +1977,7 @@ gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, GstBuffer * buffer) guint64 ext_rtptime, diff; guint32 rtptime; gboolean drop = FALSE; + guint64 clock_base; jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); @@ -2003,9 +2011,12 @@ gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, GstBuffer * buffer) rtp_jitter_buffer_get_sync (priv->jbuf, &base_rtptime, &base_time, &clock_rate, &last_rtptime); + clock_base = priv->clock_base; + GST_DEBUG_OBJECT (jitterbuffer, "ext SR %" G_GUINT64_FORMAT ", base %" - G_GUINT64_FORMAT ", clock-rate %" G_GUINT32_FORMAT, - ext_rtptime, base_rtptime, clock_rate); + G_GUINT64_FORMAT ", clock-rate %" G_GUINT32_FORMAT + ", clock-base %" G_GUINT64_FORMAT, + ext_rtptime, base_rtptime, clock_rate, clock_base); if (base_rtptime == -1 || clock_rate == -1 || base_time == -1) { GST_DEBUG_OBJECT (jitterbuffer, "dropping, no RTP values"); @@ -2023,8 +2034,12 @@ gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, GstBuffer * buffer) diff = ext_rtptime - last_rtptime; /* if bigger than 1 second, we drop it */ if (diff > clock_rate) { - GST_DEBUG_OBJECT (jitterbuffer, "dropping, too far ahead"); - drop = TRUE; + GST_DEBUG_OBJECT (jitterbuffer, "too far ahead"); + /* should drop this, but some RTSP servers end up with bogus + * way too ahead RTCP packet when repeated PAUSE/PLAY, + * so still trigger rptbin sync but invalidate RTCP data + * (sync might use other methods) */ + ext_rtptime = -1; } GST_DEBUG_OBJECT (jitterbuffer, "ext last %" G_GUINT64_FORMAT ", diff %" G_GUINT64_FORMAT, last_rtptime, diff); @@ -2040,6 +2055,7 @@ gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, GstBuffer * buffer) "base-rtptime", G_TYPE_UINT64, base_rtptime, "base-time", G_TYPE_UINT64, base_time, "clock-rate", G_TYPE_UINT, clock_rate, + "clock-base", G_TYPE_UINT64, clock_base, "sr-ext-rtptime", G_TYPE_UINT64, ext_rtptime, "sr-buffer", GST_TYPE_BUFFER, buffer, NULL); diff --git a/gst/rtpmanager/gstrtpptdemux.c b/gst/rtpmanager/gstrtpptdemux.c index 3c0004d..630212f 100644 --- a/gst/rtpmanager/gstrtpptdemux.c +++ b/gst/rtpmanager/gstrtpptdemux.c @@ -142,10 +142,10 @@ gst_rtp_pt_demux_base_init (gpointer g_class) { GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (g_class); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_pt_demux_sink_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_pt_demux_src_template)); + gst_element_class_add_static_pad_template (gstelement_klass, + &rtp_pt_demux_sink_template); + gst_element_class_add_static_pad_template (gstelement_klass, + &rtp_pt_demux_src_template); gst_element_class_set_details_simple (gstelement_klass, "RTP Demux", "Demux/Network/RTP", @@ -326,6 +326,10 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf) GstPadTemplate *templ; gchar *padname; + caps = gst_rtp_pt_demux_get_caps (rtpdemux, pt); + if (!caps) + goto no_caps; + klass = GST_ELEMENT_GET_CLASS (rtpdemux); templ = gst_element_class_get_pad_template (klass, "src_%d"); padname = g_strdup_printf ("src_%d", pt); @@ -334,10 +338,6 @@ gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf) 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) - goto no_caps; - caps = gst_caps_make_writable (caps); gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL); gst_pad_set_caps (srcpad, caps); diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index ebeb3fd..cf263e3 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -114,6 +114,8 @@ #include <gst/rtp/gstrtpbuffer.h> +#include <gst/glib-compat-private.h> + #include "gstrtpbin-marshal.h" #include "gstrtpsession.h" #include "rtpsession.h" @@ -373,22 +375,22 @@ gst_rtp_session_base_init (gpointer klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); /* sink pads */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_recv_rtp_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_recv_rtcp_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_send_rtp_sink_template)); + gst_element_class_add_static_pad_template (element_class, + &rtpsession_recv_rtp_sink_template); + gst_element_class_add_static_pad_template (element_class, + &rtpsession_recv_rtcp_sink_template); + gst_element_class_add_static_pad_template (element_class, + &rtpsession_send_rtp_sink_template); /* src pads */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_recv_rtp_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_sync_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_send_rtp_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_send_rtcp_src_template)); + gst_element_class_add_static_pad_template (element_class, + &rtpsession_recv_rtp_src_template); + gst_element_class_add_static_pad_template (element_class, + &rtpsession_sync_src_template); + gst_element_class_add_static_pad_template (element_class, + &rtpsession_send_rtp_src_template); + gst_element_class_add_static_pad_template (element_class, + &rtpsession_send_rtcp_src_template); gst_element_class_set_details_simple (element_class, "RTP Session", "Filter/Network/RTP", @@ -837,6 +839,10 @@ rtcp_thread (GstRtpSession * rtpsession) session = rtpsession->priv->session; + GST_DEBUG_OBJECT (rtpsession, "starting at %" GST_TIME_FORMAT, + GST_TIME_ARGS (current_time)); + session->start_time = current_time; + while (!rtpsession->priv->stop_thread) { GstClockReturn res; @@ -904,8 +910,13 @@ start_rtcp_thread (GstRtpSession * rtpsession) g_thread_join (rtpsession->priv->thread); /* only create a new thread if the old one was stopped. Otherwise we can * just reuse the currently running one. */ +#if !GLIB_CHECK_VERSION (2, 31, 0) rtpsession->priv->thread = g_thread_create ((GThreadFunc) rtcp_thread, rtpsession, TRUE, &error); +#else + rtpsession->priv->thread = g_thread_try_new ("rtpsession-rtcp-thread", + (GThreadFunc) rtcp_thread, rtpsession, &error); +#endif rtpsession->priv->thread_stopped = FALSE; } GST_RTP_SESSION_UNLOCK (rtpsession); @@ -1382,30 +1393,34 @@ 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) + guint32 ssrc, guint payload, gboolean all_headers, gint count) { GstCaps *caps; - gboolean requested = FALSE; caps = gst_rtp_session_get_caps_for_pt (rtpsession, payload); if (caps) { const GstStructure *s = gst_caps_get_structure (caps, 0); gboolean pli; + gboolean fir; pli = gst_structure_has_field (s, "rtcp-fb-nack-pli"); + fir = gst_structure_has_field (s, "rtcp-fb-ccm-fir") && all_headers; + + /* Google Talk uses FIR for repair, so send it even if we just want a + * regular PLI */ + if (!pli && + gst_structure_has_field (s, "rtcp-fb-x-gstreamer-fir-as-repair")) + fir = TRUE; gst_caps_unref (caps); - if (pli) { - rtp_session_request_key_unit (rtpsession->priv->session, ssrc); - rtp_session_request_early_rtcp (rtpsession->priv->session, - gst_clock_get_time (rtpsession->priv->sysclock), 200 * GST_MSECOND); - requested = TRUE; - } + if (pli || fir) + return rtp_session_request_key_unit (rtpsession->priv->session, ssrc, + gst_clock_get_time (rtpsession->priv->sysclock), fir, count); } - return requested; + return FALSE; } static gboolean @@ -1431,10 +1446,13 @@ gst_rtp_session_event_recv_rtp_src (GstPad * pad, GstEvent * event) gst_structure_get_uint (s, "ssrc", &ssrc) && gst_structure_get_uint (s, "payload", &pt)) { gboolean all_headers = FALSE; + gint count = -1; gst_structure_get_boolean (s, "all-headers", &all_headers); + if (gst_structure_get_int (s, "count", &count) && count < 0) + count += G_MAXINT; /* Make sure count is positive if present */ if (gst_rtp_session_request_remote_key_unit (rtpsession, ssrc, pt, - all_headers)) + all_headers, count)) forward = FALSE; } break; diff --git a/gst/rtpmanager/gstrtpssrcdemux.c b/gst/rtpmanager/gstrtpssrcdemux.c index 2688775..523f9c5 100644 --- a/gst/rtpmanager/gstrtpssrcdemux.c +++ b/gst/rtpmanager/gstrtpssrcdemux.c @@ -44,6 +44,10 @@ #include "config.h" #endif +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include <string.h> #include <gst/rtp/gstrtpbuffer.h> #include <gst/rtp/gstrtcpbuffer.h> @@ -83,8 +87,8 @@ GST_STATIC_PAD_TEMPLATE ("rtcp_src_%d", GST_STATIC_CAPS ("application/x-rtcp") ); -#define GST_PAD_LOCK(obj) (g_mutex_lock ((obj)->padlock)) -#define GST_PAD_UNLOCK(obj) (g_mutex_unlock ((obj)->padlock)) +#define GST_PAD_LOCK(obj) (g_static_rec_mutex_lock (&(obj)->padlock)) +#define GST_PAD_UNLOCK(obj) (g_static_rec_mutex_unlock (&(obj)->padlock)) /* signals */ enum @@ -118,10 +122,13 @@ static GstFlowReturn gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstBuffer * buf); static gboolean gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad, GstEvent * event); +static GstIterator *gst_rtp_ssrc_demux_iterate_internal_links_sink (GstPad * + pad); /* srcpad stuff */ static gboolean gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event); -static GstIterator *gst_rtp_ssrc_demux_iterate_internal_links (GstPad * pad); +static GstIterator *gst_rtp_ssrc_demux_iterate_internal_links_src (GstPad * + pad); static gboolean gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query); static guint gst_rtp_ssrc_demux_signals[LAST_SIGNAL] = { 0 }; @@ -155,8 +162,7 @@ find_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc) /* with PAD_LOCK */ static GstRtpSsrcDemuxPad * -create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc, - GstClockTime timestamp) +find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc) { GstPad *rtp_pad, *rtcp_pad; GstElementClass *klass; @@ -166,6 +172,11 @@ create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc, GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc); + demuxpad = find_demux_pad_for_ssrc (demux, ssrc); + if (demuxpad != NULL) { + return demuxpad; + } + klass = GST_ELEMENT_GET_CLASS (demux); templ = gst_element_class_get_pad_template (klass, "src_%d"); padname = g_strdup_printf ("src_%d", ssrc); @@ -177,20 +188,12 @@ create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc, rtcp_pad = gst_pad_new_from_template (templ, padname); g_free (padname); - /* we use the first timestamp received to calculate the difference between - * timestamps on all streams */ - GST_DEBUG_OBJECT (demux, "SSRC %08x, first timestamp %" GST_TIME_FORMAT, - ssrc, GST_TIME_ARGS (timestamp)); - /* wrap in structure and add to list */ demuxpad = g_new0 (GstRtpSsrcDemuxPad, 1); demuxpad->ssrc = ssrc; demuxpad->rtp_pad = rtp_pad; demuxpad->rtcp_pad = rtcp_pad; - GST_DEBUG_OBJECT (demux, "first timestamp %" GST_TIME_FORMAT, - GST_TIME_ARGS (timestamp)); - gst_pad_set_element_private (rtp_pad, demuxpad); gst_pad_set_element_private (rtcp_pad, demuxpad); @@ -205,12 +208,12 @@ create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc, gst_pad_set_event_function (rtp_pad, gst_rtp_ssrc_demux_src_event); gst_pad_set_query_function (rtp_pad, gst_rtp_ssrc_demux_src_query); gst_pad_set_iterate_internal_links_function (rtp_pad, - gst_rtp_ssrc_demux_iterate_internal_links); + gst_rtp_ssrc_demux_iterate_internal_links_src); 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_rtp_ssrc_demux_iterate_internal_links_src); gst_pad_set_active (rtcp_pad, TRUE); gst_element_add_pad (GST_ELEMENT_CAST (demux), rtp_pad); @@ -227,14 +230,14 @@ gst_rtp_ssrc_demux_base_init (gpointer g_class) { GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (g_class); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_sink_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_rtcp_sink_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_src_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_rtcp_src_template)); + gst_element_class_add_static_pad_template (gstelement_klass, + &rtp_ssrc_demux_sink_template); + gst_element_class_add_static_pad_template (gstelement_klass, + &rtp_ssrc_demux_rtcp_sink_template); + gst_element_class_add_static_pad_template (gstelement_klass, + &rtp_ssrc_demux_src_template); + gst_element_class_add_static_pad_template (gstelement_klass, + &rtp_ssrc_demux_rtcp_src_template); gst_element_class_set_details_simple (gstelement_klass, "RTP SSRC Demux", "Demux/Network/RTP", @@ -319,6 +322,8 @@ gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux, "sink"), "sink"); gst_pad_set_chain_function (demux->rtp_sink, gst_rtp_ssrc_demux_chain); gst_pad_set_event_function (demux->rtp_sink, gst_rtp_ssrc_demux_sink_event); + gst_pad_set_iterate_internal_links_function (demux->rtp_sink, + gst_rtp_ssrc_demux_iterate_internal_links_sink); gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtp_sink); demux->rtcp_sink = @@ -327,9 +332,11 @@ gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux, gst_pad_set_chain_function (demux->rtcp_sink, gst_rtp_ssrc_demux_rtcp_chain); gst_pad_set_event_function (demux->rtcp_sink, gst_rtp_ssrc_demux_rtcp_sink_event); + gst_pad_set_iterate_internal_links_function (demux->rtcp_sink, + gst_rtp_ssrc_demux_iterate_internal_links_sink); gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtcp_sink); - demux->padlock = g_mutex_new (); + g_static_rec_mutex_init (&demux->padlock); gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED); } @@ -371,7 +378,7 @@ gst_rtp_ssrc_demux_finalize (GObject * object) GstRtpSsrcDemux *demux; demux = GST_RTP_SSRC_DEMUX (object); - g_mutex_free (demux->padlock); + g_static_rec_mutex_free (&demux->padlock); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -511,6 +518,7 @@ gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf) GstRtpSsrcDemux *demux; guint32 ssrc; GstRtpSsrcDemuxPad *dpad; + GstPad *srcpad; demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad)); @@ -522,17 +530,18 @@ gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf) GST_DEBUG_OBJECT (demux, "received buffer of SSRC %08x", ssrc); GST_PAD_LOCK (demux); - dpad = find_demux_pad_for_ssrc (demux, ssrc); + dpad = find_or_create_demux_pad_for_ssrc (demux, ssrc); if (dpad == NULL) { - if (!(dpad = - create_demux_pad_for_ssrc (demux, ssrc, - GST_BUFFER_TIMESTAMP (buf)))) - goto create_failed; + GST_PAD_UNLOCK (demux); + goto create_failed; } + srcpad = gst_object_ref (dpad->rtp_pad); GST_PAD_UNLOCK (demux); /* push to srcpad */ - ret = gst_pad_push (dpad->rtp_pad, buf); + ret = gst_pad_push (srcpad, buf); + + gst_object_unref (srcpad); return ret; @@ -549,7 +558,6 @@ create_failed: { GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL), ("Could not create new pad")); - GST_PAD_UNLOCK (demux); gst_buffer_unref (buf); return GST_FLOW_ERROR; } @@ -563,6 +571,7 @@ gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstBuffer * buf) guint32 ssrc; GstRtpSsrcDemuxPad *dpad; GstRTCPPacket packet; + GstPad *srcpad; demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad)); @@ -586,16 +595,18 @@ gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstBuffer * buf) GST_DEBUG_OBJECT (demux, "received RTCP of SSRC %08x", ssrc); GST_PAD_LOCK (demux); - dpad = find_demux_pad_for_ssrc (demux, ssrc); + dpad = find_or_create_demux_pad_for_ssrc (demux, ssrc); if (dpad == NULL) { - GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc); - if (!(dpad = create_demux_pad_for_ssrc (demux, ssrc, -1))) - goto create_failed; + GST_PAD_UNLOCK (demux); + goto create_failed; } + srcpad = gst_object_ref (dpad->rtcp_pad); GST_PAD_UNLOCK (demux); /* push to srcpad */ - ret = gst_pad_push (dpad->rtcp_pad, buf); + ret = gst_pad_push (srcpad, buf); + + gst_object_unref (srcpad); return ret; @@ -618,7 +629,6 @@ create_failed: { GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL), ("Could not create new pad")); - GST_PAD_UNLOCK (demux); gst_buffer_unref (buf); return GST_FLOW_ERROR; } @@ -664,25 +674,23 @@ gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event) } static GstIterator * -gst_rtp_ssrc_demux_iterate_internal_links (GstPad * pad) +gst_rtp_ssrc_demux_iterate_internal_links_src (GstPad * pad) { GstRtpSsrcDemux *demux; GstPad *otherpad = NULL; - GstIterator *it; + GstIterator *it = NULL; GSList *current; demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad)); + if (!demux) + return NULL; + GST_PAD_LOCK (demux); for (current = demux->srcpads; current; current = g_slist_next (current)) { GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) current->data; - if (pad == demux->rtp_sink) { - otherpad = dpad->rtp_pad; - break; - } else if (pad == demux->rtcp_sink) { - otherpad = dpad->rtcp_pad; - } else if (pad == dpad->rtp_pad) { + if (pad == dpad->rtp_pad) { otherpad = demux->rtp_sink; break; } else if (pad == dpad->rtcp_pad) { @@ -698,6 +706,49 @@ gst_rtp_ssrc_demux_iterate_internal_links (GstPad * pad) return it; } +/* Should return 0 for elements to be included */ +static gint +src_pad_compare_func (gconstpointer a, gconstpointer b) +{ + GstPad *pad = GST_PAD (a); + const gchar *prefix = b; + gint res = 1; + + GST_OBJECT_LOCK (pad); + res = !GST_PAD_NAME (pad) || g_str_has_prefix (GST_PAD_NAME (pad), prefix); + GST_OBJECT_UNLOCK (pad); + + return res; +} + +static GstIterator * +gst_rtp_ssrc_demux_iterate_internal_links_sink (GstPad * pad) +{ + GstRtpSsrcDemux *demux; + GstIterator *it = NULL; + const gchar *prefix = NULL; + + demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad)); + + if (!demux) + return NULL; + + if (pad == demux->rtp_sink) + prefix = "src_"; + else if (pad == demux->rtcp_sink) + prefix = "rtcp_src_"; + else + g_assert_not_reached (); + + it = gst_element_iterate_src_pads (GST_ELEMENT (demux)); + + it = gst_iterator_filter (it, src_pad_compare_func, (gpointer) prefix); + + gst_object_unref (demux); + return it; +} + + static gboolean gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query) { diff --git a/gst/rtpmanager/gstrtpssrcdemux.h b/gst/rtpmanager/gstrtpssrcdemux.h index d5a13ca..6f792d9 100644 --- a/gst/rtpmanager/gstrtpssrcdemux.h +++ b/gst/rtpmanager/gstrtpssrcdemux.h @@ -41,7 +41,7 @@ struct _GstRtpSsrcDemux GstPad *rtp_sink; GstPad *rtcp_sink; - GMutex *padlock; + GStaticRecMutex padlock; GSList *srcpads; }; diff --git a/gst/rtpmanager/rtpjitterbuffer.c b/gst/rtpmanager/rtpjitterbuffer.c index 341388b..5db5da4 100644 --- a/gst/rtpmanager/rtpjitterbuffer.c +++ b/gst/rtpmanager/rtpjitterbuffer.c @@ -634,6 +634,26 @@ rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf, } rtptime = gst_rtp_buffer_get_timestamp (buf); + /* rtp time jumps are checked for during skew calculation, but bypassed + * in other mode, so mind those here and reset jb if needed. + * Only reset if valid input time, which is likely for UDP input + * where we expect this might happen due to async thread effects + * (in seek and state change cycles), but not so much for TCP input */ + if (GST_CLOCK_TIME_IS_VALID (time) && + jbuf->mode != RTP_JITTER_BUFFER_MODE_SLAVE && + jbuf->base_time != -1 && jbuf->last_rtptime != -1) { + GstClockTime ext_rtptime = jbuf->ext_rtptime; + + ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime); + if (ext_rtptime > jbuf->last_rtptime + 3 * clock_rate || + ext_rtptime + 3 * clock_rate < jbuf->last_rtptime) { + /* reset even if we don't have valid incoming time; + * still better than producing possibly very bogus output timestamp */ + GST_WARNING ("rtp delta too big, reset skew"); + rtp_jitter_buffer_reset_skew (jbuf); + } + } + switch (jbuf->mode) { case RTP_JITTER_BUFFER_MODE_NONE: case RTP_JITTER_BUFFER_MODE_BUFFER: @@ -699,7 +719,7 @@ rtp_jitter_buffer_pop (RTPJitterBuffer * jbuf, gint * percent) { GstBuffer *buf; - g_return_val_if_fail (jbuf != NULL, FALSE); + g_return_val_if_fail (jbuf != NULL, NULL); buf = g_queue_pop_tail (jbuf->packets); @@ -727,7 +747,7 @@ rtp_jitter_buffer_peek (RTPJitterBuffer * jbuf) { GstBuffer *buf; - g_return_val_if_fail (jbuf != NULL, FALSE); + g_return_val_if_fail (jbuf != NULL, NULL); buf = g_queue_peek_tail (jbuf->packets); diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index 4852bdb..9f15bd6 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -23,6 +23,8 @@ #include <gst/rtp/gstrtcpbuffer.h> #include <gst/netbuffer/gstnetbuffer.h> +#include <gst/glib-compat-private.h> + #include "gstrtpbin-marshal.h" #include "rtpsession.h" @@ -60,6 +62,7 @@ enum #define DEFAULT_SOURCES NULL #define DEFAULT_RTCP_MIN_INTERVAL (RTP_STATS_MIN_INTERVAL * GST_SECOND) #define DEFAULT_RTCP_FEEDBACK_RETENTION_WINDOW (2 * GST_SECOND) +#define DEFAULT_RTCP_IMMEDIATE_FEEDBACK_THRESHOLD (3) enum { @@ -78,6 +81,7 @@ enum PROP_FAVOR_NEW, PROP_RTCP_MIN_INTERVAL, PROP_RTCP_FEEDBACK_RETENTION_WINDOW, + PROP_RTCP_IMMEDIATE_FEEDBACK_THRESHOLD, PROP_LAST }; @@ -368,7 +372,7 @@ rtp_session_class_init (RTPSessionClass * klass) 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_MINIOBJECT, - G_TYPE_NONE, 4, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, + G_TYPE_NONE, 5, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, GST_TYPE_BUFFER); /** @@ -492,6 +496,14 @@ rtp_session_class_init (RTPSessionClass * klass) 0, G_MAXUINT64, DEFAULT_RTCP_FEEDBACK_RETENTION_WINDOW, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_RTCP_IMMEDIATE_FEEDBACK_THRESHOLD, + g_param_spec_uint ("rtcp-immediate-feedback-threshold", + "RTCP Immediate Feedback threshold", + "The maximum number of members of a RTP session for which immediate" + " feedback is used", + 0, G_MAXUINT, DEFAULT_RTCP_IMMEDIATE_FEEDBACK_THRESHOLD, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); klass->get_source_by_ssrc = GST_DEBUG_FUNCPTR (rtp_session_get_source_by_ssrc); @@ -533,25 +545,39 @@ rtp_session_init (RTPSession * sess) sess->source->internal = TRUE; sess->stats.active_sources++; INIT_AVG (sess->stats.avg_rtcp_packet_size, 100); + sess->source->stats.prev_rtcptime = 0; + sess->source->stats.last_rtcptime = 1; + + rtp_stats_set_min_interval (&sess->stats, + (gdouble) DEFAULT_RTCP_MIN_INTERVAL / GST_SECOND); /* default UDP header length */ sess->header_len = 28; sess->mtu = DEFAULT_RTCP_MTU; /* some default SDES entries */ - str = g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ()); + + /* we do not want to leak details like the username or hostname here */ + str = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ()); rtp_source_set_sdes_string (sess->source, GST_RTCP_SDES_CNAME, str); g_free (str); - rtp_source_set_sdes_string (sess->source, GST_RTCP_SDES_NAME, - g_get_real_name ()); +#if 0 + /* we do not want to leak the user's real name here */ + str = g_strdup_printf ("Anon%u", g_random_int ()); + rtp_source_set_sdes_string (sess->source, GST_RTCP_SDES_NAME, str); + g_free (str); +#endif + rtp_source_set_sdes_string (sess->source, GST_RTCP_SDES_TOOL, "GStreamer"); sess->first_rtcp = TRUE; sess->allow_early = TRUE; sess->rtcp_feedback_retention_window = DEFAULT_RTCP_FEEDBACK_RETENTION_WINDOW; + sess->rtcp_immediate_feedback_threshold = + DEFAULT_RTCP_IMMEDIATE_FEEDBACK_THRESHOLD; - sess->rtcp_pli_requests = g_array_new (FALSE, FALSE, sizeof (guint32)); + sess->last_keyframe_request = GST_CLOCK_TIME_NONE; GST_DEBUG ("%p: session using SSRC: %08x", sess, sess->source->ssrc); } @@ -573,8 +599,6 @@ 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); } @@ -648,6 +672,15 @@ rtp_session_set_property (GObject * object, guint prop_id, case PROP_RTCP_MIN_INTERVAL: rtp_stats_set_min_interval (&sess->stats, (gdouble) g_value_get_uint64 (value) / GST_SECOND); + /* trigger reconsideration */ + RTP_SESSION_LOCK (sess); + sess->next_rtcp_check_time = 0; + RTP_SESSION_UNLOCK (sess); + if (sess->callbacks.reconsider) + sess->callbacks.reconsider (sess, sess->reconsider_user_data); + break; + case PROP_RTCP_IMMEDIATE_FEEDBACK_THRESHOLD: + sess->rtcp_immediate_feedback_threshold = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -703,6 +736,9 @@ rtp_session_get_property (GObject * object, guint prop_id, case PROP_RTCP_MIN_INTERVAL: g_value_set_uint64 (value, sess->stats.min_interval * GST_SECOND); break; + case PROP_RTCP_IMMEDIATE_FEEDBACK_THRESHOLD: + g_value_set_uint (value, sess->rtcp_immediate_feedback_threshold); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2128,45 +2164,112 @@ rtp_session_process_app (RTPSession * sess, GstRTCPPacket * packet, GST_DEBUG ("received APP"); } +static gboolean +rtp_session_request_local_key_unit (RTPSession * sess, RTPSource * src, + gboolean fir, GstClockTime current_time) +{ + guint32 round_trip = 0; + + rtp_source_get_last_rb (src, NULL, NULL, NULL, NULL, NULL, NULL, &round_trip); + + if (sess->last_keyframe_request != GST_CLOCK_TIME_NONE && 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 < 2 * round_trip_in_ns) { + GST_DEBUG ("Ignoring %s request because one was send without one " + "RTT (%" GST_TIME_FORMAT " < %" GST_TIME_FORMAT ")", + fir ? "FIR" : "PLI", + GST_TIME_ARGS (current_time - sess->last_keyframe_request), + GST_TIME_ARGS (round_trip_in_ns));; + return FALSE; + } + } + + sess->last_keyframe_request = current_time; + + GST_LOG ("received %s request from %X %p(%p)", fir ? "FIR" : "PLI", + rtp_source_get_ssrc (src), sess->callbacks.process_rtp, + sess->callbacks.request_key_unit); + + RTP_SESSION_UNLOCK (sess); + sess->callbacks.request_key_unit (sess, fir, + sess->request_key_unit_user_data); + RTP_SESSION_LOCK (sess); + + return TRUE; +} + 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); + rtp_session_request_local_key_unit (sess, src, FALSE, current_time); +} - 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));; +static void +rtp_session_process_fir (RTPSession * sess, guint32 sender_ssrc, + guint8 * fci_data, guint fci_length, GstClockTime current_time) +{ + RTPSource *src; + guint32 ssrc; + guint position = 0; + gboolean our_request = FALSE; + + if (!sess->callbacks.request_key_unit) + return; + + if (fci_length < 8) + return; + + src = g_hash_table_lookup (sess->ssrcs[sess->mask_idx], + GINT_TO_POINTER (sender_ssrc)); + + /* Hack because Google fails to set the sender_ssrc correctly */ + if (!src && sender_ssrc == 1) { + GHashTableIter iter; + + if (sess->stats.sender_sources > + RTP_SOURCE_IS_SENDER (sess->source) ? 2 : 1) return; + + g_hash_table_iter_init (&iter, sess->ssrcs[sess->mask_idx]); + + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) & src)) { + if (src != sess->source && rtp_source_is_sender (src)) + break; + src = NULL; } } - sess->last_keyframe_request = current_time; + if (!src) + return; - GST_LOG ("received PLI from %X %p(%p)", sender_ssrc, - sess->callbacks.process_rtp, sess->callbacks.request_key_unit); + for (position = 0; position < fci_length; position += 8) { + guint8 *data = fci_data + position; - sess->callbacks.request_key_unit (sess, FALSE, - sess->request_key_unit_user_data); + ssrc = GST_READ_UINT32_BE (data); + + if (ssrc == rtp_source_get_ssrc (sess->source)) { + our_request = TRUE; + break; + } + } + if (!our_request) + return; + + rtp_session_request_local_key_unit (sess, src, TRUE, current_time); } static void @@ -2210,7 +2313,9 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet, rtp_source_retain_rtcp_packet (src, packet, arrival->running_time); } - if (rtp_source_get_ssrc (sess->source) == media_ssrc) { + if (rtp_source_get_ssrc (sess->source) == media_ssrc || + /* PSFB FIR puts the media ssrc inside the FCI */ + (type == GST_RTCP_TYPE_PSFB && fbtype == GST_RTCP_PSFB_TYPE_FIR)) { switch (type) { case GST_RTCP_TYPE_PSFB: switch (fbtype) { @@ -2218,6 +2323,10 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet, rtp_session_process_pli (sess, sender_ssrc, media_ssrc, current_time); break; + case GST_RTCP_PSFB_TYPE_FIR: + rtp_session_process_fir (sess, sender_ssrc, fci_data, fci_length, + current_time); + break; default: break; } @@ -2444,7 +2553,7 @@ calculate_rtcp_interval (RTPSession * sess, gboolean deterministic, g_hash_table_foreach (sess->cnames, (GHFunc) add_bitrates, &bandwidth); bandwidth /= 8.0; } - if (bandwidth == 0) + if (bandwidth < 8000) bandwidth = RTP_STATS_BANDWIDTH; rtp_stats_set_bandwidths (&sess->stats, bandwidth, @@ -2719,11 +2828,35 @@ session_cleanup (const gchar * key, RTPSource * source, ReportData * data) gboolean sendertimeout = FALSE; gboolean is_sender, is_active; RTPSession *sess = data->sess; - GstClockTime interval; + GstClockTime interval, binterval; + GstClockTime btime; is_sender = RTP_SOURCE_IS_SENDER (source); is_active = RTP_SOURCE_IS_ACTIVE (source); + /* our own rtcp interval may have been forced low by secondary configuration, + * while sender side may still operate with higher interval, + * so do not just take our interval to decide on timing out sender, + * but take (if data->interval <= 5 * GST_SECOND): + * interval = CLAMP (sender_interval, data->interval, 5 * GST_SECOND) + * where sender_interval is difference between last 2 received RTCP reports + */ + if (data->interval >= 5 * GST_SECOND || (source == sess->source)) { + binterval = data->interval; + } else { + GST_LOG ("prev_rtcp %" GST_TIME_FORMAT ", last_rtcp %" GST_TIME_FORMAT, + GST_TIME_ARGS (source->stats.prev_rtcptime), + GST_TIME_ARGS (source->stats.last_rtcptime)); + /* if not received enough yet, fallback to larger default */ + if (source->stats.last_rtcptime > source->stats.prev_rtcptime) + binterval = source->stats.last_rtcptime - source->stats.prev_rtcptime; + else + binterval = 5 * GST_SECOND; + binterval = CLAMP (binterval, data->interval, 5 * GST_SECOND); + } + GST_LOG ("timeout base interval %" GST_TIME_FORMAT, + GST_TIME_ARGS (binterval)); + /* check for our own source, we don't want to delete our own source. */ if (!(source == sess->source)) { if (source->received_bye) { @@ -2738,11 +2871,13 @@ session_cleanup (const gchar * key, RTPSource * source, ReportData * data) } /* sources that were inactive for more than 5 times the deterministic reporting * interval get timed out. the min timeout is 5 seconds. */ - if (data->current_time > source->last_activity) { - interval = MAX (data->interval * 5, 5 * GST_SECOND); - if (data->current_time - source->last_activity > interval) { + /* mind old time that might pre-date last time going to PLAYING */ + btime = MAX (source->last_activity, sess->start_time); + if (data->current_time > btime) { + interval = MAX (binterval * 5, 5 * GST_SECOND); + if (data->current_time - btime > interval) { GST_DEBUG ("removing timeout source %08x, last %" GST_TIME_FORMAT, - source->ssrc, GST_TIME_ARGS (source->last_activity)); + source->ssrc, GST_TIME_ARGS (btime)); remove = TRUE; } } @@ -2751,12 +2886,13 @@ session_cleanup (const gchar * key, RTPSource * source, ReportData * data) /* senders that did not send for a long time become a receiver, this also * holds for our own source. */ if (is_sender) { - if (data->current_time > source->last_rtp_activity) { - interval = MAX (data->interval * 2, 5 * GST_SECOND); - if (data->current_time - source->last_rtp_activity > interval) { + /* mind old time that might pre-date last time going to PLAYING */ + btime = MAX (source->last_rtp_activity, sess->start_time); + if (data->current_time > btime) { + interval = MAX (binterval * 2, 5 * GST_SECOND); + if (data->current_time - btime > interval) { GST_DEBUG ("sender source %08x timed out and became receiver, last %" - GST_TIME_FORMAT, source->ssrc, - GST_TIME_ARGS (source->last_rtp_activity)); + GST_TIME_FORMAT, source->ssrc, GST_TIME_ARGS (btime)); source->is_sender = FALSE; sess->stats.sender_sources--; sendertimeout = TRUE; @@ -3047,7 +3183,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, + /* "a relatively long time" -- RFC 3550 section 8.2 */ + RTP_STATS_MIN_INTERVAL * GST_SECOND * 10, running_time - sess->rtcp_feedback_retention_window); if (sess->change_ssrc) { @@ -3142,8 +3279,13 @@ rtp_session_request_early_rtcp (RTPSession * sess, GstClockTime current_time, if (current_time + T_dither_max > sess->next_rtcp_check_time) goto dont_send; - /* RFC 4585 section 3.5.2 step 4 */ - if (sess->allow_early == FALSE) + /* RFC 4585 section 3.5.2 step 4 + * Don't send if allow_early is FALSE, but not if we are in + * immediate mode, meaning we are part of a group of at most the + * application-specific threshold. + */ + if (sess->total_sources > sess->rtcp_immediate_feedback_threshold && + sess->allow_early == FALSE) goto dont_send; if (T_dither_max) { @@ -3167,19 +3309,32 @@ rtp_session_request_early_rtcp (RTPSession * sess, GstClockTime current_time, dont_send: RTP_SESSION_UNLOCK (sess); - } -void -rtp_session_request_key_unit (RTPSession * sess, guint32 ssrc) +gboolean +rtp_session_request_key_unit (RTPSession * sess, guint32 ssrc, GstClockTime now, + gboolean fir, gint count) { - guint i; + RTPSource *src = g_hash_table_lookup (sess->ssrcs[sess->mask_idx], + GUINT_TO_POINTER (ssrc)); - for (i = 0; i < sess->rtcp_pli_requests->len; i++) - if (ssrc == g_array_index (sess->rtcp_pli_requests, guint32, i)) - return; + if (!src) + return FALSE; + + if (fir) { + src->send_pli = FALSE; + src->send_fir = TRUE; + + if (count == -1 || count != src->last_fir_count) + src->current_send_fir_seqnum++; + src->last_fir_count = count; + } else if (!src->send_fir) { + src->send_pli = TRUE; + } + + rtp_session_request_early_rtcp (sess, now, 200 * GST_MSECOND); - g_array_append_val (sess->rtcp_pli_requests, ssrc); + return TRUE; } static gboolean @@ -3202,22 +3357,66 @@ rtp_session_on_sending_rtcp (RTPSession * sess, GstBuffer * buffer, gboolean early) { gboolean ret = FALSE; + GHashTableIter iter; + gpointer key, value; + gboolean started_fir = FALSE; + GstRTCPPacket fir_rtcppacket; 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)); + g_hash_table_iter_init (&iter, sess->ssrcs[sess->mask_idx]); + while (g_hash_table_iter_next (&iter, &key, &value)) { + guint media_ssrc = GPOINTER_TO_UINT (key); + RTPSource *media_src = value; + guint8 *fci_data; + + if (media_src->send_fir) { + if (!started_fir) { + if (!gst_rtcp_buffer_add_packet (buffer, GST_RTCP_TYPE_PSFB, + &fir_rtcppacket)) + break; + gst_rtcp_packet_fb_set_type (&fir_rtcppacket, GST_RTCP_PSFB_TYPE_FIR); + gst_rtcp_packet_fb_set_sender_ssrc (&fir_rtcppacket, + rtp_source_get_ssrc (sess->source)); + gst_rtcp_packet_fb_set_media_ssrc (&fir_rtcppacket, 0); + + if (!gst_rtcp_packet_fb_set_fci_length (&fir_rtcppacket, 2)) { + gst_rtcp_packet_remove (&fir_rtcppacket); + break; + } + ret = TRUE; + started_fir = TRUE; + } else { + if (!gst_rtcp_packet_fb_set_fci_length (&fir_rtcppacket, + !gst_rtcp_packet_fb_get_fci_length (&fir_rtcppacket) + 2)) + break; + } - if (media_src && !rtp_source_has_retained (media_src, + fci_data = gst_rtcp_packet_fb_get_fci (&fir_rtcppacket) - + ((gst_rtcp_packet_fb_get_fci_length (&fir_rtcppacket) - 2) * 4); + + GST_WRITE_UINT32_BE (fci_data, media_ssrc); + fci_data += 4; + fci_data[0] = media_src->current_send_fir_seqnum; + fci_data[1] = fci_data[2] = fci_data[3] = 0; + media_src->send_fir = FALSE; + } + } + + g_hash_table_iter_init (&iter, sess->ssrcs[sess->mask_idx]); + while (g_hash_table_iter_next (&iter, &key, &value)) { + guint media_ssrc = GPOINTER_TO_UINT (key); + RTPSource *media_src = value; + GstRTCPPacket pli_rtcppacket; + + if (media_src->send_pli && !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, + if (gst_rtcp_buffer_add_packet (buffer, GST_RTCP_TYPE_PSFB, + &pli_rtcppacket)) { + gst_rtcp_packet_fb_set_type (&pli_rtcppacket, GST_RTCP_PSFB_TYPE_PLI); + gst_rtcp_packet_fb_set_sender_ssrc (&pli_rtcppacket, rtp_source_get_ssrc (sess->source)); - gst_rtcp_packet_fb_set_media_ssrc (&rtcppacket, media_ssrc); + gst_rtcp_packet_fb_set_media_ssrc (&pli_rtcppacket, media_ssrc); ret = TRUE; } else { /* Break because the packet is full, will put next request in a @@ -3226,8 +3425,7 @@ rtp_session_on_sending_rtcp (RTPSession * sess, GstBuffer * buffer, break; } } - - g_array_remove_index (sess->rtcp_pli_requests, 0); + media_src->send_pli = FALSE; } RTP_SESSION_UNLOCK (sess); diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index 93fd300..ecc0b98 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -209,6 +209,7 @@ struct _RTPSession { GstClockTime next_rtcp_check_time; GstClockTime last_rtcp_send_time; + GstClockTime start_time; gboolean first_rtcp; gboolean allow_early; @@ -232,9 +233,10 @@ struct _RTPSession { gboolean change_ssrc; gboolean favor_new; GstClockTime rtcp_feedback_retention_window; + guint rtcp_immediate_feedback_threshold; - GArray *rtcp_pli_requests; GstClockTime last_keyframe_request; + gboolean last_keyframe_all_headers; }; /** @@ -347,7 +349,10 @@ void rtp_session_request_early_rtcp (RTPSession * sess, GstClockT GstClockTimeDiff max_delay); /* Notify session of a request for a new key unit */ -void rtp_session_request_key_unit (RTPSession * sess, - guint32 ssrc); +gboolean rtp_session_request_key_unit (RTPSession * sess, + guint32 ssrc, + GstClockTime now, + gboolean fir, + gint count); #endif /* __RTP_SESSION_H__ */ diff --git a/gst/rtpmanager/rtpsource.c b/gst/rtpmanager/rtpsource.c index fb9e039..f1ee4ac 100644 --- a/gst/rtpmanager/rtpsource.c +++ b/gst/rtpmanager/rtpsource.c @@ -1345,6 +1345,9 @@ rtp_source_process_sr (RTPSource * src, GstClockTime time, guint64 ntptime, /* make current */ src->stats.curr_sr = curridx; + + src->stats.prev_rtcptime = src->stats.last_rtcptime; + src->stats.last_rtcptime = time; } /** diff --git a/gst/rtpmanager/rtpsource.h b/gst/rtpmanager/rtpsource.h index 6db0a6a..fc204ae 100644 --- a/gst/rtpmanager/rtpsource.h +++ b/gst/rtpmanager/rtpsource.h @@ -172,6 +172,11 @@ struct _RTPSource { GList *conflicting_addresses; GQueue *retained_feedback; + + gboolean send_pli; + gboolean send_fir; + guint8 current_send_fir_seqnum; + gint last_fir_count; }; struct _RTPSourceClass { |