summaryrefslogtreecommitdiff
path: root/gst/rtpmanager
diff options
context:
space:
mode:
Diffstat (limited to 'gst/rtpmanager')
-rw-r--r--gst/rtpmanager/Makefile.in140
-rw-r--r--gst/rtpmanager/gstrtpbin.c257
-rw-r--r--gst/rtpmanager/gstrtpbin.h2
-rw-r--r--gst/rtpmanager/gstrtpjitterbuffer.c36
-rw-r--r--gst/rtpmanager/gstrtpptdemux.c16
-rw-r--r--gst/rtpmanager/gstrtpsession.c66
-rw-r--r--gst/rtpmanager/gstrtpssrcdemux.c143
-rw-r--r--gst/rtpmanager/gstrtpssrcdemux.h2
-rw-r--r--gst/rtpmanager/rtpjitterbuffer.c24
-rw-r--r--gst/rtpmanager/rtpsession.c318
-rw-r--r--gst/rtpmanager/rtpsession.h11
-rw-r--r--gst/rtpmanager/rtpsource.c3
-rw-r--r--gst/rtpmanager/rtpsource.h5
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 {