Merge the tizen patch based on 1.12.2 26/158526/2
authorEunhae Choi <eunhae1.choi@samsung.com>
Wed, 1 Nov 2017 12:22:50 +0000 (21:22 +0900)
committereunhae choi <eunhae1.choi@samsung.com>
Wed, 1 Nov 2017 12:42:47 +0000 (12:42 +0000)
Change-Id: I726dcc9cd0c177974dacef2a4243362b9951dd6f

37 files changed:
1  2 
.gbs.conf
configure.ac
gst/Makefile.am
gst/gstbin.c
gst/gstelement.c
gst/gstelementfactory.c
gst/gstelementfactory.h
gst/gstinfo.c
gst/gstobject.c
gst/gstobject.h
gst/gstpad.c
gst/gstquark.c
gst/gstquark.h
gst/gstquery.c
gst/gstquery.h
gst/gsttaglist.c
gst/gsttaglist.h
gst/gstutils.c
gst/gstutils.h
libs/gst/base/gstbaseparse.c
libs/gst/base/gstbaseparse.h
libs/gst/base/gstbasesrc.c
libs/gst/base/gstbasesrc.h
libs/gst/helpers/Makefile.am
packaging/common.tar.gz
packaging/gstreamer.spec
pkgconfig/gstreamer.pc.in
plugins/elements/gstfilesink.c
plugins/elements/gstmultiqueue.c
plugins/elements/gstmultiqueue.h
plugins/elements/gstqueue.c
plugins/elements/gstqueue.h
plugins/elements/gstqueue2.c
plugins/elements/gstqueue2.h
plugins/elements/gsttypefindelement.c
tests/check/gst/gstsegment.c
tools/Makefile.am

diff --cc .gbs.conf
index 0000000,7302e56..3033b86
mode 000000,100644..100644
--- /dev/null
+++ b/.gbs.conf
@@@ -1,0 -1,3 +1,3 @@@
 -upstream_branch = upstream/1.6
+ [general]
++upstream_branch = upstream/1.12
+ upstream_tag = ${upstreamversion}
diff --cc configure.ac
@@@ -882,17 -818,45 +882,46 @@@ dnl Check for -Bsymbolic-functions link
  dnl intra-library PLT jumps, if available.
  AC_ARG_ENABLE(Bsymbolic,
                [AS_HELP_STRING([--disable-Bsymbolic],[avoid linking with -Bsymbolic])],,
 -              [SAVED_LDFLAGS="${LDFLAGS}"
 +              [SAVED_LDFLAGS="${LDFLAGS}" SAVED_LIBS="${LIBS}"
                 AC_MSG_CHECKING([for -Bsymbolic-functions linker flag])
                 LDFLAGS=-Wl,-Bsymbolic-functions
 -               AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int main (void) { return 0; }]])],[
 +               LIBS=
 +               AC_TRY_LINK([], [return 0],
                             AC_MSG_RESULT(yes)
 -                           enable_Bsymbolic=yes],[
 +                           enable_Bsymbolic=yes,
                             AC_MSG_RESULT(no)
 -                           enable_Bsymbolic=no])
 -               LDFLAGS="${SAVED_LDFLAGS}"])
 +                           enable_Bsymbolic=no)
 +               LDFLAGS="${SAVED_LDFLAGS}" LIBS="${SAVED_LIBS}"])
  
+ dnl Check for dlog
+ AC_ARG_ENABLE(dlog, AC_HELP_STRING([--enable-dlog], [using dlog]),
+ [
+  case "${enableval}" in
+          yes) USE_DLOG=yes ;;
+          no)  USE_DLOG=no ;;
+          *)   AC_MSG_ERROR(bad value ${enableval} for --enable-dlog) ;;
+  esac
+ ],[USE_DLOG=no])
+ if test "x$USE_DLOG" = "xyes"; then
+         PKG_CHECK_MODULES(DLOG, dlog)
+         AC_SUBST(DLOG_CFLAGS)
+         AC_SUBST(DLOG_LIBS)
+ fi
+ AM_CONDITIONAL(USE_DLOG, test "x$USE_DLOG" = "xyes")
+ dnl end
+ dnl Check for tv-profile
+ AC_ARG_ENABLE(tv-profile, AC_HELP_STRING([--enable-tv-profile], [using tv-profile]),
+ [
+  case "${enableval}" in
+          yes) HAVE_TV_PROFILE="-DTIZEN_PROFILE_TV -DTIZEN_FEATURE_TRUSTZONE -DRVU_LIVESTREAMING_OPTIMIZATION" ;;
+          no)  HAVE_TV_PROFILE= ;;
+          *)   AC_MSG_ERROR(bad value ${enableval} for --enable-tv-profile) ;;
+  esac
+ ],[HAVE_TV_PROFILE=])
+ AC_SUBST(HAVE_TV_PROFILE)
+ dnl end
  
  dnl *** set variables based on configure arguments
  
diff --cc gst/Makefile.am
@@@ -150,9 -152,13 +150,15 @@@ libgstreamer_@GST_API_VERSION@_la_LIBAD
        $(GST_ALL_LIBS)                                 \
        $(WIN32_LIBS)                                   \
        $(SOCKET_LIBS)                                  \
 +      $(UNWIND_LIBS)                                  \
 +      $(DW_LIBS)                                      \
        $(LIBM)
+ if USE_DLOG
+ libgstreamer_@GST_API_VERSION@_la_CFLAGS += $(DLOG_CFLAGS)
+ libgstreamer_@GST_API_VERSION@_la_LIBADD += $(DLOG_LIBS)
+ libgstreamer_@GST_API_VERSION@_la_CFLAGS += -DUSE_DLOG
+ endif
  
  libgstreamer_@GST_API_VERSION@_la_LDFLAGS =           \
        $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
diff --cc gst/gstbin.c
@@@ -1525,10 -1301,17 +1526,19 @@@ gst_bin_add (GstBin * bin, GstElement 
    GST_CAT_DEBUG (GST_CAT_PARENTAGE, "adding element %s to bin %s",
        GST_STR_NULL (GST_ELEMENT_NAME (element)),
        GST_STR_NULL (GST_ELEMENT_NAME (bin)));
+ #else
+   gst_set_family_id_to_child (element, (GST_OBJECT_CAST (bin)->family_id));
+   GST_CAT_DEBUG (GST_CAT_PARENTAGE,
+       "adding element %s (id %d) to bin %s (id %d)",
+       GST_STR_NULL (GST_ELEMENT_NAME (element)),
+       GST_OBJECT_CAST (element)->family_id,
+       GST_STR_NULL (GST_ELEMENT_NAME (bin)), GST_OBJECT_CAST (bin)->family_id);
+ #endif
  
 +  GST_TRACER_BIN_ADD_PRE (bin, element);
    result = bclass->add_element (bin, element);
 +  GST_TRACER_BIN_ADD_POST (bin, element, result);
  
    return result;
  
Simple merge
Simple merge
Simple merge
diff --cc gst/gstinfo.c
@@@ -240,8 -221,10 +240,12 @@@ dladdr (void *address, Dl_info * dl
  #endif /* __sgi__ */
  #endif
  
+ #if defined(USE_DLOG)
+ #include <dlog.h>
+ #endif
 +static const gchar *_gst_debug_filter = NULL;
 +
  static void gst_debug_reset_threshold (gpointer category, gpointer unused);
  static void gst_debug_reset_all_thresholds (void);
  
diff --cc gst/gstobject.c
@@@ -206,8 -228,14 +214,10 @@@ gst_object_init (GstObject * object
    object->name = NULL;
    GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p new", object);
  
 -#ifndef GST_DISABLE_TRACE
 -  _gst_alloc_trace_new (_gst_object_trace, object);
 -#endif
 -
    object->flags = 0;
+ #ifdef TIZEN_PROFILE_TV
+   object->family_id = 0;
+ #endif
    object->control_rate = 100 * GST_MSECOND;
    object->last_sync = GST_CLOCK_TIME_NONE;
  }
diff --cc gst/gstobject.h
Simple merge
diff --cc gst/gstpad.c
Simple merge
diff --cc gst/gstquark.c
@@@ -70,12 -70,10 +70,15 @@@ static const gchar *_quark_strings[] = 
    "GstMessageNeedContext", "GstMessageHaveContext", "context", "context-type",
    "GstMessageStreamStart", "group-id", "uri-redirection",
    "GstMessageDeviceAdded", "GstMessageDeviceRemoved", "device",
 -  "uri-redirection-permanent"
 +  "uri-redirection-permanent", "GstMessagePropertyNotify", "property-name",
 +  "property-value", "streams", "GstEventSelectStreams",
 +  "GstMessageStreamCollection", "collection", "stream", "stream-collection",
 +  "GstMessageStreamsSelected", "GstMessageRedirect", "redirect-entry-locations",
 +  "redirect-entry-taglists", "redirect-entry-structures",
 +  "GstEventStreamGroupDone"
+ #ifdef TIZEN_PROFILE_TV
+   ,"GstQuarkQueryResource"
+ #endif
  };
  
  GQuark _priv_gst_quark_table[GST_QUARK_MAX];
diff --cc gst/gstquark.h
@@@ -202,22 -202,12 +202,27 @@@ typedef enum _GstQuarkI
    GST_QUARK_MESSAGE_DEVICE_REMOVED = 171,
    GST_QUARK_DEVICE = 172,
    GST_QUARK_URI_REDIRECTION_PERMANENT = 173,
 -  GST_QUARK_MAX = 174
 +  GST_QUARK_MESSAGE_PROPERTY_NOTIFY = 174,
 +  GST_QUARK_PROPERTY_NAME = 175,
 +  GST_QUARK_PROPERTY_VALUE = 176,
 +  GST_QUARK_STREAMS = 177,
 +  GST_QUARK_EVENT_SELECT_STREAMS = 178,
 +  GST_QUARK_MESSAGE_STREAM_COLLECTION = 179,
 +  GST_QUARK_COLLECTION = 180,
 +  GST_QUARK_STREAM = 181,
 +  GST_QUARK_EVENT_STREAM_COLLECTION = 182,
 +  GST_QUARK_MESSAGE_STREAMS_SELECTED = 183,
 +  GST_QUARK_MESSAGE_REDIRECT = 184,
 +  GST_QUARK_REDIRECT_ENTRY_LOCATIONS = 185,
 +  GST_QUARK_REDIRECT_ENTRY_TAGLISTS = 186,
 +  GST_QUARK_REDIRECT_ENTRY_STRUCTURES = 187,
 +  GST_QUARK_EVENT_STREAM_GROUP_DONE = 188,
+ #ifndef TIZEN_PROFILE_TV
 -  GST_QUARK_QUERY_RESOURCE = 174,
 -  GST_QUARK_MAX = 175
 +  GST_QUARK_MAX = 189
+ #else
++  GST_QUARK_QUERY_RESOURCE = 189,
++  GST_QUARK_MAX = 190
+ #endif
  } GstQuarkId;
  
  extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
diff --cc gst/gstquery.c
Simple merge
diff --cc gst/gstquery.h
Simple merge
Simple merge
Simple merge
diff --cc gst/gstutils.c
@@@ -4123,265 -3955,105 +4126,368 @@@ gst_util_group_id_next (void
    return g_atomic_int_add (&counter, 1);
  }
  
 +/* Compute log2 of the passed 64-bit number by finding the highest set bit */
 +static guint
 +gst_log2 (GstClockTime in)
 +{
 +  const guint64 b[] =
 +      { 0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000, 0xFFFFFFFF00000000LL };
 +  const guint64 S[] = { 1, 2, 4, 8, 16, 32 };
 +  int i;
 +
 +  guint count = 0;
 +  for (i = 5; i >= 0; i--) {
 +    if (in & b[i]) {
 +      in >>= S[i];
 +      count |= S[i];
 +    }
 +  }
 +
 +  return count;
 +}
 +
 +/**
 + * gst_calculate_linear_regression:
 + * @xy: Pairs of (x,y) values
 + * @temp: Temporary scratch space used by the function
 + * @n: number of (x,y) pairs
 + * @m_num: (out): numerator of calculated slope
 + * @m_denom: (out): denominator of calculated slope
 + * @b: (out): Offset at Y-axis
 + * @xbase: (out): Offset at X-axis
 + * @r_squared: (out): R-squared
 + *
 + * Calculates the linear regression of the values @xy and places the
 + * result in @m_num, @m_denom, @b and @xbase, representing the function
 + *   y(x) = m_num/m_denom * (x - xbase) + b
 + * that has the least-square distance from all points @x and @y.
 + *
 + * @r_squared will contain the remaining error.
 + *
 + * If @temp is not %NULL, it will be used as temporary space for the function,
 + * in which case the function works without any allocation at all. If @temp is
 + * %NULL, an allocation will take place. @temp should have at least the same
 + * amount of memory allocated as @xy, i.e. 2*n*sizeof(GstClockTime).
 + *
 + * > This function assumes (x,y) values with reasonable large differences
 + * > between them. It will not calculate the exact results if the differences
 + * > between neighbouring values are too small due to not being able to
 + * > represent sub-integer values during the calculations.
 + *
 + * Returns: %TRUE if the linear regression was successfully calculated
 + *
 + * Since: 1.12
 + */
 +/* http://mathworld.wolfram.com/LeastSquaresFitting.html
 + * with SLAVE_LOCK
 + */
 +gboolean
 +gst_calculate_linear_regression (const GstClockTime * xy,
 +    GstClockTime * temp, guint n,
 +    GstClockTime * m_num, GstClockTime * m_denom,
 +    GstClockTime * b, GstClockTime * xbase, gdouble * r_squared)
 +{
 +  const GstClockTime *x, *y;
 +  GstClockTime *newx, *newy;
 +  GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
 +  GstClockTime xmax, ymax;
 +  GstClockTimeDiff sxx, sxy, syy;
 +  gint i, j;
 +  gint pshift = 0;
 +  gint max_bits;
 +
 +  g_return_val_if_fail (xy != NULL, FALSE);
 +  g_return_val_if_fail (m_num != NULL, FALSE);
 +  g_return_val_if_fail (m_denom != NULL, FALSE);
 +  g_return_val_if_fail (b != NULL, FALSE);
 +  g_return_val_if_fail (xbase != NULL, FALSE);
 +  g_return_val_if_fail (r_squared != NULL, FALSE);
 +
 +  x = xy;
 +  y = xy + 1;
 +
 +  xbar = ybar = sxx = syy = sxy = 0;
 +
 +  xmin = ymin = G_MAXUINT64;
 +  xmax = ymax = 0;
 +  for (i = j = 0; i < n; i++, j += 2) {
 +    xmin = MIN (xmin, x[j]);
 +    ymin = MIN (ymin, y[j]);
 +
 +    xmax = MAX (xmax, x[j]);
 +    ymax = MAX (ymax, y[j]);
 +  }
 +
 +  if (temp == NULL) {
 +    /* Allocate up to 1kb on the stack, otherwise heap */
 +    newx = n > 64 ? g_new (GstClockTime, 2 * n) : g_newa (GstClockTime, 2 * n);
 +    newy = newx + 1;
 +  } else {
 +    newx = temp;
 +    newy = temp + 1;
 +  }
 +
 +  /* strip off unnecessary bits of precision */
 +  for (i = j = 0; i < n; i++, j += 2) {
 +    newx[j] = x[j] - xmin;
 +    newy[j] = y[j] - ymin;
 +  }
 +
 +#ifdef DEBUGGING_ENABLED
 +  GST_CAT_DEBUG (GST_CAT_CLOCK, "reduced numbers:");
 +  for (i = j = 0; i < n; i++, j += 2)
 +    GST_CAT_DEBUG (GST_CAT_CLOCK,
 +        "  %" G_GUINT64_FORMAT "  %" G_GUINT64_FORMAT, newx[j], newy[j]);
 +#endif
 +
 +  /* have to do this precisely otherwise the results are pretty much useless.
 +   * should guarantee that none of these accumulators can overflow */
 +
 +  /* quantities on the order of 1e10 to 1e13 -> 30-35 bits;
 +   * window size a max of 2^10, so
 +   this addition could end up around 2^45 or so -- ample headroom */
 +  for (i = j = 0; i < n; i++, j += 2) {
 +    /* Just in case assumptions about headroom prove false, let's check */
 +    if ((newx[j] > 0 && G_MAXUINT64 - xbar <= newx[j]) ||
 +        (newy[j] > 0 && G_MAXUINT64 - ybar <= newy[j])) {
 +      GST_CAT_WARNING (GST_CAT_CLOCK,
 +          "Regression overflowed in clock slaving! xbar %"
 +          G_GUINT64_FORMAT " newx[j] %" G_GUINT64_FORMAT " ybar %"
 +          G_GUINT64_FORMAT " newy[j] %" G_GUINT64_FORMAT, xbar, newx[j], ybar,
 +          newy[j]);
 +      if (temp == NULL && n > 64)
 +        g_free (newx);
 +      return FALSE;
 +    }
 +
 +    xbar += newx[j];
 +    ybar += newy[j];
 +  }
 +  xbar /= n;
 +  ybar /= n;
 +
 +  /* multiplying directly would give quantities on the order of 1e20-1e26 ->
 +   * 60 bits to 70 bits times the window size that's 80 which is too much.
 +   * Instead we (1) subtract off the xbar*ybar in the loop instead of after,
 +   * to avoid accumulation; (2) shift off some estimated number of bits from
 +   * each multiplicand to limit the expected ceiling. For strange
 +   * distributions of input values, things can still overflow, in which
 +   * case we drop precision and retry - at most a few times, in practice rarely
 +   */
 +
 +  /* Guess how many bits we might need for the usual distribution of input,
 +   * with a fallback loop that drops precision if things go pear-shaped */
 +  max_bits = gst_log2 (MAX (xmax - xmin, ymax - ymin)) * 7 / 8 + gst_log2 (n);
 +  if (max_bits > 64)
 +    pshift = max_bits - 64;
 +
 +  i = 0;
 +  do {
 +#ifdef DEBUGGING_ENABLED
 +    GST_CAT_DEBUG (GST_CAT_CLOCK,
 +        "Restarting regression with precision shift %u", pshift);
 +#endif
 +
 +    xbar4 = xbar >> pshift;
 +    ybar4 = ybar >> pshift;
 +    sxx = syy = sxy = 0;
 +    for (i = j = 0; i < n; i++, j += 2) {
 +      GstClockTime newx4, newy4;
 +      GstClockTimeDiff tmp;
 +
 +      newx4 = newx[j] >> pshift;
 +      newy4 = newy[j] >> pshift;
 +
 +      tmp = (newx4 + xbar4) * (newx4 - xbar4);
 +      if (G_UNLIKELY (tmp > 0 && sxx > 0 && (G_MAXINT64 - sxx <= tmp))) {
 +        do {
 +          /* Drop some precision and restart */
 +          pshift++;
 +          sxx /= 4;
 +          tmp /= 4;
 +        } while (G_MAXINT64 - sxx <= tmp);
 +        break;
 +      } else if (G_UNLIKELY (tmp < 0 && sxx < 0 && (G_MAXINT64 - sxx >= tmp))) {
 +        do {
 +          /* Drop some precision and restart */
 +          pshift++;
 +          sxx /= 4;
 +          tmp /= 4;
 +        } while (G_MININT64 - sxx >= tmp);
 +        break;
 +      }
 +      sxx += tmp;
 +
 +      tmp = newy4 * newy4 - ybar4 * ybar4;
 +      if (G_UNLIKELY (tmp > 0 && syy > 0 && (G_MAXINT64 - syy <= tmp))) {
 +        do {
 +          pshift++;
 +          syy /= 4;
 +          tmp /= 4;
 +        } while (G_MAXINT64 - syy <= tmp);
 +        break;
 +      } else if (G_UNLIKELY (tmp < 0 && syy < 0 && (G_MAXINT64 - syy >= tmp))) {
 +        do {
 +          pshift++;
 +          syy /= 4;
 +          tmp /= 4;
 +        } while (G_MININT64 - syy >= tmp);
 +        break;
 +      }
 +      syy += tmp;
 +
 +      tmp = newx4 * newy4 - xbar4 * ybar4;
 +      if (G_UNLIKELY (tmp > 0 && sxy > 0 && (G_MAXINT64 - sxy <= tmp))) {
 +        do {
 +          pshift++;
 +          sxy /= 4;
 +          tmp /= 4;
 +        } while (G_MAXINT64 - sxy <= tmp);
 +        break;
 +      } else if (G_UNLIKELY (tmp < 0 && sxy < 0 && (G_MININT64 - sxy >= tmp))) {
 +        do {
 +          pshift++;
 +          sxy /= 4;
 +          tmp /= 4;
 +        } while (G_MININT64 - sxy >= tmp);
 +        break;
 +      }
 +      sxy += tmp;
 +    }
 +  } while (i < n);
 +
 +  if (G_UNLIKELY (sxx == 0))
 +    goto invalid;
 +
 +  *m_num = sxy;
 +  *m_denom = sxx;
 +  *b = (ymin + ybar) - gst_util_uint64_scale_round (xbar, *m_num, *m_denom);
 +  /* Report base starting from the most recent observation */
 +  *xbase = xmax;
 +  *b += gst_util_uint64_scale_round (xmax - xmin, *m_num, *m_denom);
 +
 +  *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
 +
 +#ifdef DEBUGGING_ENABLED
 +  GST_CAT_DEBUG (GST_CAT_CLOCK, "  m      = %g", ((double) *m_num) / *m_denom);
 +  GST_CAT_DEBUG (GST_CAT_CLOCK, "  b      = %" G_GUINT64_FORMAT, *b);
 +  GST_CAT_DEBUG (GST_CAT_CLOCK, "  xbase  = %" G_GUINT64_FORMAT, *xbase);
 +  GST_CAT_DEBUG (GST_CAT_CLOCK, "  r2     = %g", *r_squared);
 +#endif
 +
 +  if (temp == NULL && n > 64)
 +    g_free (newx);
 +
 +  return TRUE;
 +
 +invalid:
 +  {
 +    GST_CAT_DEBUG (GST_CAT_CLOCK, "sxx == 0, regression failed");
 +    if (temp == NULL && n > 64)
 +      g_free (newx);
 +    return FALSE;
 +  }
 +}
++
+ #ifdef TIZEN_PROFILE_TV
+ /**
+  * gst_element_query_resource
+  * @element: (in) a #GstElement to invoke the resource query on.
+  * @resources: (out): a pointer to the list of resources asked for.
+  * Returns: TRUE if the query could be performed.
+  */
+ gboolean
+ gst_element_query_resource (GstElement * element, GList ** resource_list)
+ {
+   GstQuery *query;
+   gboolean ret;
+   char resources[250];
+   char *element_resource;
+   guint count = 0, i = 0;
+   GstObject *object;
+   int resource_num;
+   if (resource_list == NULL) {
+     return FALSE;
+   }
+   query = gst_query_new_resource (resources);
+   if (GST_IS_BIN (element)) {
+     count = gst_child_proxy_get_children_count ((GstChildProxy *)element);
+     for (i = 0; i < count; i++) {
+       if (!(object = gst_child_proxy_get_child_by_index ((GstChildProxy *)element, i)))
+         continue;
+       if (GST_IS_BIN (object)) {
+         ret = gst_element_query_resource ((GstElement *)object, resource_list);
+         gst_object_unref (object);
+         continue;
+       }
+       ret = gst_element_query ((GstElement *) object, query);
+       if (ret) {
+         element_resource = gst_query_parse_resource (query);
+         resource_num = (int) atoi (element_resource);
+         GST_DEBUG_OBJECT (element,
+             "\n resource ID received after query is :%d\n", resource_num);
+         if (NULL == (g_list_find (*resource_list, (gconstpointer)resource_num))) {
+           *resource_list =
+               g_list_append (*resource_list, GINT_TO_POINTER (resource_num));
+         }
+       }
+       gst_object_unref (object);
+     }
+   } else {
+     ret = gst_element_query ((GstElement *) element, query);
+     if (ret) {
+       element_resource = gst_query_parse_resource (query);
+       resource_num = (int) atoi (element_resource);
+       GST_DEBUG_OBJECT (element, "\n resource ID received after query is :%d\n",
+           resource_num);
+       if (NULL == (g_list_find (*resource_list, (gconstpointer)resource_num))) {
+         *resource_list =
+             g_list_append (*resource_list, GINT_TO_POINTER (resource_num));
+       }
+     }
+   }
+   gst_query_unref (query);
+   return TRUE;
+ }
+ static void
+ set_family_id (const GValue * item, gpointer user_data)
+ {
+   gpointer object = g_value_get_object (item);
+   if (GST_IS_PAD (object)) {
+     GstPad *pad = GST_PAD_CAST (object);
+     g_object_set (G_OBJECT (pad), "family-id", (int) user_data, NULL);
+   } else if (GST_IS_ELEMENT (object)) {
+     gst_set_family_id_to_child (GST_ELEMENT_CAST (object), (int) user_data);
+   }
+   return;
+ }
+ void
+ gst_set_family_id_to_child (GstElement * child, int id)
+ {
+   GstIterator *it;
+   if (!GST_IS_ELEMENT (child))
+     return;
+   g_object_set (G_OBJECT (child), "family-id", id, NULL);
+   it = gst_element_iterate_pads (child);
+   gst_iterator_foreach (it, (GstIteratorForeachFunction) set_family_id,
+       (gpointer) id);
+   gst_iterator_free (it);
+   it = NULL;
+   if (!GST_IS_BIN (child))
+     return;
+   it = gst_bin_iterate_recurse (GST_BIN (child));
+   gst_iterator_foreach (it, (GstIteratorForeachFunction) set_family_id,
+       (gpointer) id);
+   gst_iterator_free (it);
+   it = NULL;
+   return;
+ }
+ #endif
diff --cc gst/gstutils.h
@@@ -1059,13 -1034,9 +1063,16 @@@ gboolean      gst_util_fraction_ad
                                                   gint *res_n, gint *res_d);
  gint          gst_util_fraction_compare         (gint a_n, gint a_d, gint b_n, gint b_d);
  
 +gboolean      gst_calculate_linear_regression   (const GstClockTime * xy,
 +                                                 GstClockTime * temp, guint n,
 +                                                 GstClockTime * m_num, GstClockTime * m_denom,
 +                                                 GstClockTime * b, GstClockTime * xbase,
 +                                                 gdouble * r_squared);
 +
 +
+ #ifdef TIZEN_PROFILE_TV
+ void          gst_set_family_id_to_child        (GstElement* child, int id);
+ #endif
  G_END_DECLS
  
  #endif /* __GST_UTILS_H__ */
Simple merge
@@@ -351,15 -348,22 +351,31 @@@ void            gst_base_parse_set_ts_a
  void            gst_base_parse_merge_tags       (GstBaseParse  * parse,
                                                   GstTagList    * tags,
                                                   GstTagMergeMode mode);
+ #ifdef TIZEN_FEATURE_BASEPARSE_MODIFICATION
+ void            gst_base_parse_get_upstream_size (GstBaseParse * parse,
+                                                   gint64 * upstream_size);
+ void            gst_base_parse_get_index_last_offset (GstBaseParse * parse,
+                                                       gint64 * index_last_offset);
+ void            gst_base_parse_get_index_last_ts (GstBaseParse * parse,
+                                                   GstClockTime * index_last_ts);
+ void            gst_base_parse_get_pad_mode (GstBaseParse * parse,
+                                              GstPadMode * pad_mode);
+ void            gst_base_parse_set_seek_mode (GstBaseParse * parse,
+                                               gboolean       seek_mode);
+ #endif
 +
 +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
 +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstBaseParseFrame, gst_base_parse_frame_free)
 +#endif
 +
 +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
 +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstBaseParse, gst_object_unref)
 +#endif
 +
  G_END_DECLS
  
  #endif /* __GST_BASE_PARSE_H__ */
Simple merge
@@@ -271,11 -277,10 +277,14 @@@ void            gst_base_src_get_alloca
                                                 GstAllocator **allocator,
                                                 GstAllocationParams *params);
  
+ #ifdef TIZEN_PROFILE_TV
+ void            gst_base_src_update_segment   (GstBaseSrc * src, gint64 timestamp);
+ #endif
  
 +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
 +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstBaseSrc, gst_object_unref)
 +#endif
 +
  G_END_DECLS
  
  #endif /* __GST_BASE_SRC_H__ */
@@@ -2,24 -13,19 +2,26 @@@ helpers_PROGRAMS = gst-plugin-scanne
  helpersdir=$(libexecdir)/gstreamer-$(GST_API_VERSION)
  
  gst_plugin_scanner_SOURCES = gst-plugin-scanner.c
- gst_plugin_scanner_CFLAGS = $(GST_OBJ_CFLAGS)
+ gst_plugin_scanner_CFLAGS = $(GST_OBJ_CFLAGS) -fPIE
  gst_plugin_scanner_LDADD = $(GST_OBJ_LIBS)
+ gst_plugin_scanner_LDFLAGS = -pie
  
 +if ENABLE_BASH_COMPLETION
 +helpers_PROGRAMS += gst-completion-helper
 +gst_completion_helper_SOURCES = gst-completion-helper.c
 +gst_completion_helper_CFLAGS = $(GST_OBJ_CFLAGS)
 +gst_completion_helper_LDADD = $(GST_OBJ_LIBS)
 +endif
 +
  if HAVE_PTP
  helpers_PROGRAMS += gst-ptp-helper
  gst_ptp_helper_SOURCES = gst-ptp-helper.c
- gst_ptp_helper_CFLAGS = $(GST_OBJ_CFLAGS) $(GIO_CFLAGS)
+ gst_ptp_helper_CFLAGS = $(GST_OBJ_CFLAGS) $(GIO_CFLAGS) -fPIE
  gst_ptp_helper_LDADD = $(GST_OBJ_LIBS) $(GIO_LIBS) $(CAP_LIBS)
+ gst_ptp_helper_LDFLAGS = -pie
  endif
  
 -install-exec-hook: install-helpersPROGRAMS
 +install-data-hook:
  if HAVE_PTP
  if HAVE_PTP_HELPER_SETUID
        - chown root $(DESTDIR)$(helpersdir)/gst-ptp-helper
index 0000000,d9ed1aa..c3aef17
mode 000000,100644..100644
Binary files differ
index 0000000,8329a00..7a56073
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,150 +1,150 @@@
 -Version:        1.6.1
 -Release:        9
+ %define gst_branch 1.0
+ Name:           gstreamer
 -rm -rf %{buildroot}%{_libdir}/girepository-1.0/*.typelib
++Version:        1.12.2
++Release:        0
+ Summary:        Streaming-Media Framework Runtime
+ License:        LGPL-2.0+
+ Group:          Multimedia/Framework
+ Url:            http://gstreamer.freedesktop.org/
+ Source0:        http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-%{version}.tar.xz
+ Source100:      common.tar.gz
+ BuildRequires:  bison
+ BuildRequires:  gettext-tools
+ BuildRequires:  check-devel
+ BuildRequires:  fdupes
+ BuildRequires:  flex
+ BuildRequires:  pkgconfig(glib-2.0) >= 2.32.0
+ BuildRequires:  libtool
+ BuildRequires:  pkgconfig(libxml-2.0)
+ BuildRequires:  pkgconfig(gobject-introspection-1.0) >= 1.31.1
+ BuildRequires:  pkgconfig(dlog)
+ %description
+ GStreamer is a streaming-media framework, based on graphs of filters
+ which operate on media data. Applications using this library can do
+ anything from real-time sound processing to playing videos, and just
+ about anything else media-related.  Its plug-in-based architecture
+ means that new data types or processing capabilities can be added by
+ installing new plug-ins.
+ %package utils
+ Summary:        Streaming-Media Framework Runtime
+ Group:          Multimedia/Framework
+ Provides:       gstreamer:%{_bindir}/gst-launch-%{gst_branch} = %{version}
+ # Symbol for unversioned wrappers:
+ Provides:       gstreamer-utils_versioned = %{version}
+ %description utils
+ GStreamer is a streaming-media framework, based on graphs of filters
+ which operate on media data. Applications using this library can do
+ anything from real-time sound processing to playing videos, and just
+ about anything else media-related.  Its plug-in-based architecture
+ means that new data types or processing capabilities can be added by
+ installing new plug-ins.
+ %package devel
+ Summary:        Include Files and Libraries mandatory for Development
+ Group:          Development/Libraries
+ # gstreamer-utils is required for the gstreamer-provides rpm magic.
+ Requires:       gstreamer-utils = %{version}
+ Requires:       %{name} = %{version}
+ %description devel
+ This package contains all necessary include files and libraries needed
+ to develop applications that require these.
+ %lang_package
+ %prep
+ %setup -q -n gstreamer-%{version}
+ %setup -q -T -D -a 100
+ %build
+ # FIXME: GTKDOC_CFLAGS, GST_OBJ_CFLAGS:
+ # Silently ignored compilation of uninstalled gtk-doc scanners without RPM_OPT_FLAGS.
+ export V=1
+ NOCONFIGURE=1 ./autogen.sh
+ export CFLAGS="%{optflags} \
+       -DTIZEN_FEATURE_QUEUE2_MODIFICATION\
+       -DTIZEN_FEATURE_FILESINK_MODIFICATION\
+       -DTIZEN_FEATURE_MQ_MODIFICATION\
+       -DTIZEN_FEATURE_BASEPARSE_MODIFICATION\
+       -DTIZEN_FEATURE_QUEUE_MODIFICATION\
+ %if "%{TIZEN_PRODUCT_TV}" == "1"
+       -DTIZEN_PROFILE_TV\
+       -DRVU_LIVESTREAMING_OPTIMIZATION\
+       -DTIZEN_FEATURE_TRUSTZONE\
+ %endif
+       -DTIZEN_FEATURE_RTSPSRC_MODIFICATION\
+       -fno-strict-aliasing"
+ %configure\
+ %if %{with introspection}
+         --enable-introspection\
+ %endif
+         --disable-static\
+         --disable-docbook\
+         --disable-gtk-doc\
+         --enable-dlog\
+ %if "%{TIZEN_PRODUCT_TV}" == "1"
+         --enable-tv-profile\
+ %endif
+         --disable-examples\
+         --disable-tests
+ make %{?_smp_mflags}
+ %install
+ %make_install
+ mkdir -p %{buildroot}%{_datadir}/gstreamer-%{gst_branch}/presets
+ mkdir -p %{buildroot}%{_docdir}/%{name}
+ %find_lang %{name}-%{gst_branch}
+ mv %{name}-%{gst_branch}.lang %{name}.lang
+ rm -rf %{buildroot}%{_datadir}/gtk-doc
+ rm -rf %{buildroot}%{_docdir}/%{name}/manual
+ rm -rf %{buildroot}%{_docdir}/%{name}/pwg
 -%{_libdir}/gstreamer-%{gst_branch}/include/gst/gstconfig.h
++rm -rf %{buildroot}%{_libdir}/girepository-%{gst_branch}/*.typelib
+ mkdir -p %{buildroot}%{_datadir}/gstreamer-%{gst_branch}/presets
+ %fdupes %{buildroot}
+ %post -p /sbin/ldconfig
+ %postun -p /sbin/ldconfig
+ %files
+ %manifest %{name}.manifest
+ %defattr(-, root, root)
+ %license COPYING
+ %dir %{_datadir}/gstreamer-%{gst_branch}
+ %dir %{_datadir}/gstreamer-%{gst_branch}/presets
+ %dir %{_libdir}/gstreamer-%{gst_branch}
+ %{_libdir}/gstreamer-%{gst_branch}/*.so
+ %dir %{_libexecdir}/gstreamer-%{gst_branch}
++#%{_libdir}/include/gstreamer-%{gst_branch}/gst/gstconfig.h
+ %{_libexecdir}/gstreamer-%{gst_branch}/gst-plugin-scanner
+ %{_libexecdir}/gstreamer-%{gst_branch}/gst-ptp-helper
+ %{_libdir}/*.so.*
+ #%{_libdir}/girepository-1.0/Gst-1.0.typelib
+ #%{_libdir}/girepository-1.0/GstBase-1.0.typelib
+ #%{_libdir}/girepository-1.0/GstCheck-1.0.typelib
+ #%{_libdir}/girepository-1.0/GstController-1.0.typelib
+ #%{_libdir}/girepository-1.0/GstNet-1.0.typelib
+ %files utils
+ %manifest %{name}.manifest
+ %defattr(-, root, root)
+ %license COPYING
+ %{_bindir}/*-%{gst_branch}
+ %doc %{_mandir}/man?/*-%{gst_branch}.*
+ %files devel
+ %manifest %{name}.manifest
+ %defattr(-, root, root)
+ %{_datadir}/aclocal/*.m4
+ %{_includedir}/*
+ %{_libdir}/*.so
+ %{_libdir}/pkgconfig/*.pc
+ %{_datadir}/gir-1.0/*.gir
+ %changelog
Simple merge
Simple merge
@@@ -166,9 -182,11 +176,15 @@@ struct _GstSingleQueu
    GCond query_handled;
    gboolean last_query;
    GstQuery *last_handled_query;
 +
 +  /* For interleave calculation */
 +  GThread *thread;
++
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+ /*RVU patch : update buffering percent*/
+   gint sq_stream_type;
+   GstClockTime cur_time_of_begin_buffering;
+ #endif
  };
  
  
@@@ -203,8 -224,13 +223,15 @@@ static void recheck_buffering_status (G
  
  static void gst_single_queue_flush_queue (GstSingleQueue * sq, gboolean full);
  
 +static void calculate_interleave (GstMultiQueue * mq);
 +
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+ /*RVU patch : work for get stream type to set single queue buffering params*/
+ static void single_queue_set_stream_type (GstSingleQueue * squeue,
+     GstBuffer * buffer);
+ static void early_exit_buffering (GstMultiQueue * mq);
+ #endif
  static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink_%u",
      GST_PAD_SINK,
      GST_PAD_REQUEST,
@@@ -242,16 -268,16 +269,20 @@@ enu
   * aditional extra size. */
  #define DEFAULT_EXTRA_SIZE_BYTES 10 * 1024 * 1024       /* 10 MB */
  #define DEFAULT_EXTRA_SIZE_BUFFERS 5
+ #ifdef TIZEN_FEATURE_MQ_MODIFICATION
+ #define DEFAULT_EXTRA_SIZE_TIME 10 * GST_SECOND
+ #else
  #define DEFAULT_EXTRA_SIZE_TIME 3 * GST_SECOND
+ #endif
  
  #define DEFAULT_USE_BUFFERING FALSE
 -#define DEFAULT_LOW_PERCENT   10
 -#define DEFAULT_HIGH_PERCENT  99
 +#define DEFAULT_LOW_WATERMARK  0.01
 +#define DEFAULT_HIGH_WATERMARK 0.99
  #define DEFAULT_SYNC_BY_RUNNING_TIME FALSE
 +#define DEFAULT_USE_INTERLEAVE FALSE
 +#define DEFAULT_UNLINKED_CACHE_TIME 250 * GST_MSECOND
 +
 +#define DEFAULT_MINIMUM_INTERLEAVE (250 * GST_MSECOND)
  
  enum
  {
    PROP_USE_BUFFERING,
    PROP_LOW_PERCENT,
    PROP_HIGH_PERCENT,
 +  PROP_LOW_WATERMARK,
 +  PROP_HIGH_WATERMARK,
    PROP_SYNC_BY_RUNNING_TIME,
 +  PROP_USE_INTERLEAVE,
 +  PROP_UNLINKED_CACHE_TIME,
 +  PROP_MINIMUM_INTERLEAVE,
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+ /*RVU patch : buffering params*/
+   PROP_MAX_AUDIO_SIZE_BYTES,
+   PROP_MAX_AUDIO_SIZE_BUFFERS,
+   PROP_MAX_AUDIO_SIZE_TIME,
+   PROP_MAX_VIDEO_SIZE_BYTES,
+   PROP_MAX_VIDEO_SIZE_BUFFERS,
+   PROP_MAX_VIDEO_SIZE_TIME,
+   PROP_ENABLE_BUFFERING_OPT,
+ /*RVU patch : rvu reset, disable audio buffering and adaptive buffering property*/
+   PROP_RESET_FLAG,
+   PROP_DISABLE_AUDIO_BUFFERING,
+   PROP_BUFFERING_ENHANCEMENT,
+ #endif
    PROP_LAST
  };
  
@@@ -603,26 -479,60 +656,79 @@@ gst_multi_queue_class_init (GstMultiQue
            "Synchronize deactivated or not-linked streams by running time",
            DEFAULT_SYNC_BY_RUNNING_TIME,
            G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+ /*RVU patch : buffering params property*/
+   g_object_class_install_property (gobject_class, PROP_MAX_AUDIO_SIZE_BYTES,
+       g_param_spec_uint ("max-size-audio-bytes", "Max. size (kB)",
+           "Max. amount of data in the audio queue (bytes, 0=disable)", 0,
+           G_MAXUINT, DEFAULT_MAX_SIZE_BYTES,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_MAX_AUDIO_SIZE_BUFFERS,
+       g_param_spec_uint ("max-size-audio-buffers", "Max. size (buffers)",
+           "Max. number of buffers in the audio queue (0=disable)", 0, G_MAXUINT,
+           DEFAULT_MAX_SIZE_BUFFERS,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_MAX_AUDIO_SIZE_TIME,
+       g_param_spec_uint64 ("max-size-audio-time", "Max. size (ns)",
+           "Max. amount of data in the audio queue (in ns, 0=disable)", 0,
+           G_MAXUINT64, DEFAULT_MAX_SIZE_TIME,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_SIZE_BYTES,
+       g_param_spec_uint ("max-size-video-bytes", "Max. size (kB)",
+           "Max. amount of data in the video queue (bytes, 0=disable)",
+           0, G_MAXUINT, DEFAULT_MAX_SIZE_BYTES,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_SIZE_BUFFERS,
+       g_param_spec_uint ("max-size-video-buffers", "Max. size (buffers)",
+           "Max. number of buffers in the video queue (0=disable)", 0, G_MAXUINT,
+           DEFAULT_MAX_SIZE_BUFFERS,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_SIZE_TIME,
+       g_param_spec_uint64 ("max-size-video-time", "Max. size (ns)",
+           "Max. amount of data in the video queue (in ns, 0=disable)", 0,
+           G_MAXUINT64, DEFAULT_MAX_SIZE_TIME,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_ENABLE_BUFFERING_OPT,
+       g_param_spec_boolean ("enable-buffering-opt",
+           "make buffering optimize enable",
+           "enable to control the buffering queue size and time.", FALSE,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /*RVU patch : rvu reset, disable audio buffering and adaptive buffering property*/
+   g_object_class_install_property (gobject_class, PROP_RESET_FLAG,
+       g_param_spec_int ("buffering-reset-flag", "reset flag",
+           "reset buffering flag", 0, 1, 0,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_DISABLE_AUDIO_BUFFERING,
+       g_param_spec_boolean ("disable-audio-buffering",
+           "disable audio stream buffering", "disable audio buffering solution",
+           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+   g_object_class_install_property (gobject_class, PROP_BUFFERING_ENHANCEMENT,
+       g_param_spec_boolean ("enhancement-buffering", "enhancement buffering solution",
+           "enhancement buffering solution",
+           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ #endif
  
 +  g_object_class_install_property (gobject_class, PROP_USE_INTERLEAVE,
 +      g_param_spec_boolean ("use-interleave", "Use interleave",
 +          "Adjust time limits based on input interleave",
 +          DEFAULT_USE_INTERLEAVE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 +
 +  g_object_class_install_property (gobject_class, PROP_UNLINKED_CACHE_TIME,
 +      g_param_spec_uint64 ("unlinked-cache-time", "Unlinked cache time (ns)",
 +          "Extra buffering in time for unlinked streams (if 'sync-by-running-time')",
 +          0, G_MAXUINT64, DEFAULT_UNLINKED_CACHE_TIME,
 +          G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
 +          G_PARAM_STATIC_STRINGS));
 +
 +  g_object_class_install_property (gobject_class, PROP_MINIMUM_INTERLEAVE,
 +      g_param_spec_uint64 ("min-interleave-time", "Minimum interleave time",
 +          "Minimum extra buffering for deinterleaving (size of the queues) when use-interleave=true",
 +          0, G_MAXUINT64, DEFAULT_MINIMUM_INTERLEAVE,
 +          G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
 +          G_PARAM_STATIC_STRINGS));
 +
    gobject_class->finalize = gst_multi_queue_finalize;
  
    gst_element_class_set_static_metadata (gstelement_class,
@@@ -664,7 -573,22 +770,22 @@@ gst_multi_queue_init (GstMultiQueue * m
  
    mqueue->counter = 1;
    mqueue->highid = -1;
 -  mqueue->high_time = GST_CLOCK_TIME_NONE;
 +  mqueue->high_time = GST_CLOCK_STIME_NONE;
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+ /*RVU patch : buffering params init*/
+   mqueue->audio_max_size.bytes = DEFAULT_MAX_SIZE_BYTES;
+   mqueue->audio_max_size.visible = DEFAULT_MAX_SIZE_BUFFERS;
+   mqueue->audio_max_size.time = DEFAULT_MAX_SIZE_TIME;
+   mqueue->video_max_size.bytes = DEFAULT_MAX_SIZE_BYTES;
+   mqueue->video_max_size.visible = DEFAULT_MAX_SIZE_BUFFERS;
+   mqueue->video_max_size.time = DEFAULT_MAX_SIZE_TIME;
+   mqueue->buffering_start_time = 0;
+   mqueue->stream_duration = 0;
+ /*RVU patch : rvu reset flag, disable audio buffering flag and adaptive buffering flag*/
+   mqueue->buffering_reset = FALSE;
+   mqueue->disable_audio_buffering = FALSE;
+   mqueue->enhancement_buffering = FALSE;
+ #endif
  
    g_mutex_init (&mqueue->qlock);
    g_mutex_init (&mqueue->buffering_post_lock);
@@@ -793,22 -772,29 +953,46 @@@ gst_multi_queue_set_property (GObject 
      case PROP_SYNC_BY_RUNNING_TIME:
        mq->sync_by_running_time = g_value_get_boolean (value);
        break;
 +    case PROP_USE_INTERLEAVE:
 +      mq->use_interleave = g_value_get_boolean (value);
 +      break;
 +    case PROP_UNLINKED_CACHE_TIME:
 +      GST_MULTI_QUEUE_MUTEX_LOCK (mq);
 +      mq->unlinked_cache_time = g_value_get_uint64 (value);
 +      GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
 +      gst_multi_queue_post_buffering (mq);
 +      break;
 +    case PROP_MINIMUM_INTERLEAVE:
 +      GST_MULTI_QUEUE_MUTEX_LOCK (mq);
 +      mq->min_interleave_time = g_value_get_uint64 (value);
 +      if (mq->use_interleave)
 +        calculate_interleave (mq);
 +      GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
 +      break;
++
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+ /*RVU patch : rvu reset buffering, disable audio buffering and adaptive buffering property*/
+     case PROP_RESET_FLAG:
+       mq->buffering = FALSE;
+       mq->percent = 0;
+       mq->buffering_reset = TRUE;
+       GST_DEBUG_OBJECT (mq, "MQ RESET FLAG!\n");
+       break;
+     case PROP_DISABLE_AUDIO_BUFFERING:
+     {
+       mq->disable_audio_buffering = g_value_get_boolean (value);
+       GST_LOG_OBJECT (mq, "disable-audio-buffering %d\n",
+           mq->disable_audio_buffering);
+     }
+       break;
+     case PROP_BUFFERING_ENHANCEMENT:
+     {
+       mq->enhancement_buffering = g_value_get_boolean (value);
+       GST_LOG_OBJECT (mq, "mq->enhancement_buffering %d\n",
+           mq->enhancement_buffering);
+     }
+       break;
+ #endif
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        break;
@@@ -862,15 -874,15 +1080,24 @@@ gst_multi_queue_get_property (GObject 
      case PROP_SYNC_BY_RUNNING_TIME:
        g_value_set_boolean (value, mq->sync_by_running_time);
        break;
 +    case PROP_USE_INTERLEAVE:
 +      g_value_set_boolean (value, mq->use_interleave);
 +      break;
 +    case PROP_UNLINKED_CACHE_TIME:
 +      g_value_set_uint64 (value, mq->unlinked_cache_time);
 +      break;
 +    case PROP_MINIMUM_INTERLEAVE:
 +      g_value_set_uint64 (value, mq->min_interleave_time);
 +      break;
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+ /*RVU patch : rvu disable audio buffering and adaptive buffering property*/
+     case PROP_DISABLE_AUDIO_BUFFERING:
+       g_value_set_boolean (value, mq->disable_audio_buffering);
+       break;
+     case PROP_BUFFERING_ENHANCEMENT:
+       g_value_set_boolean (value, mq->enhancement_buffering);
+       break;
+ #endif
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        break;
@@@ -1124,55 -1129,136 +1351,149 @@@ get_buffering_level (GstSingleQueue * s
        G_GUINT64_FORMAT, sq->id, size.visible, sq->max_size.visible,
        size.bytes, sq->max_size.bytes, sq->cur_time, sq->max_size.time);
  
 -  /* get bytes and time percentages and take the max */
 -  if (sq->is_eos || sq->srcresult == GST_FLOW_NOT_LINKED) {
 -    percent = 100;
 +  /* get bytes and time buffer levels and take the max */
 +  if (sq->is_eos || sq->srcresult == GST_FLOW_NOT_LINKED || sq->is_sparse) {
 +    buffering_level = MAX_BUFFERING_LEVEL;
    } else {
 -    percent = 0;
 +    buffering_level = 0;
      if (sq->max_size.time > 0) {
 -      tmp = (sq->cur_time * 100) / sq->max_size.time;
 -      percent = MAX (percent, tmp);
 +      tmp =
 +          gst_util_uint64_scale (sq->cur_time,
 +          MAX_BUFFERING_LEVEL, sq->max_size.time);
 +      buffering_level = MAX (buffering_level, tmp);
      }
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+     /*RVU patch : rvu adaptive buffering */
+     if (sq->mqueue->enhancement_buffering == TRUE)
+       GST_LOG_OBJECT (sq->mqueue,
+           "MULTIQUEUE ENHANCEMENT BUFFERING SOLUTION ENABLE!\n");
+     if (sq->mqueue->enhancement_buffering == FALSE) {
+       if (sq->max_size.bytes > 0) {
+         tmp = (size.bytes * 100) / sq->max_size.bytes;
+         percent = MAX (percent, tmp);
+       }
+     } else {
+       GST_LOG_OBJECT (sq->mqueue, "disable bytes buffering profile!\n");
+     }
+ #else
      if (sq->max_size.bytes > 0) {
 -      tmp = (size.bytes * 100) / sq->max_size.bytes;
 -      percent = MAX (percent, tmp);
 +      tmp =
 +          gst_util_uint64_scale_int (size.bytes,
 +          MAX_BUFFERING_LEVEL, sq->max_size.bytes);
 +      buffering_level = MAX (buffering_level, tmp);
      }
+ #endif
    }
  
 -  return percent;
 +  return buffering_level;
  }
  
  /* WITH LOCK TAKEN */
  static void
  update_buffering (GstMultiQueue * mq, GstSingleQueue * sq)
  {
 -  gint percent;
 +  gint buffering_level, percent;
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+   /*RVU patch : disable mq audio buffering solution */
+   GstPad *audio_pad = NULL;
+   GstCaps *audio_caps = NULL;
+   GstStructure *audio_caps_str = NULL;
+   const char *audio_mime = NULL;
+   const char *audio_stream_type = NULL;
+ #endif
    /* nothing to dowhen we are not in buffering mode */
    if (!mq->use_buffering)
      return;
 -  percent = get_percentage (sq);
 +
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+   /*RVU patch : disable mq audio buffering solution */
+   if ((sq != NULL) && (mq->disable_audio_buffering == TRUE)) {
+     GST_LOG_OBJECT (mq, "disable audio buffering solution start!\n");
+     audio_pad = GST_PAD_PEER (sq->sinkpad);
+     audio_caps = gst_pad_get_current_caps (audio_pad);
+     if (NULL == audio_caps) {
+       GST_LOG_OBJECT (mq, "audio caps is null!\n");
+       goto NEXT_STEP;
+     }
+     audio_caps_str = gst_caps_get_structure (audio_caps, 0);
+     if (NULL == audio_caps_str) {
+       GST_LOG_OBJECT (mq, "audio caps string is NULL!\n");
+       goto NEXT_STEP;
+     }
+     audio_mime = gst_structure_get_name (audio_caps_str);
+     if (NULL == audio_mime) {
+       GST_LOG_OBJECT (mq, "audio caps string mime is NULL!\n");
+       goto NEXT_STEP;
+     }
+     GST_LOG_OBJECT (mq, "audio_mime:[%s]\n", audio_mime);
+     if (g_strrstr (audio_mime, "audio")) {
+       GST_LOG_OBJECT (mq,
+           "non-drm audio single queue!, skip audio buffering\n");
+       goto LAST_POS;
+     } else if (g_strrstr (audio_mime, "drm")) {
+       audio_stream_type =
+           gst_structure_get_string (audio_caps_str, "stream-type");
+       if (NULL == audio_stream_type) {
+         GST_LOG_OBJECT (mq, "drm audio single queue can not get stream-type\n");
+         goto NEXT_STEP;
+       }
+       if (g_strrstr (audio_stream_type, "audio")) {
+         GST_LOG_OBJECT (mq, "drm audio single queue!, skip audio buffering!\n");
+         goto LAST_POS;
+       }
+     }
+     GST_LOG_OBJECT (mq, "disable audio buffering solution end!\n");
+   }
+ NEXT_STEP:
+   if (audio_caps != NULL) {
+     GST_LOG_OBJECT (mq,
+         "audio caps release for disable audio buffering solution!\n");
+     gst_caps_unref (audio_caps);
+     audio_caps = NULL;
+   }
+ #endif
++
 +  buffering_level = get_buffering_level (sq);
 +
 +  /* scale so that if buffering_level equals the high watermark,
 +   * the percentage is 100% */
 +  percent = gst_util_uint64_scale (buffering_level, 100, mq->high_watermark);
 +  /* clip */
 +  if (percent > 100)
 +    percent = 100;
  
    if (mq->buffering) {
 -    if (percent >= mq->high_percent) {
 +    if (buffering_level >= mq->high_watermark) {
        mq->buffering = FALSE;
      }
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+ /*RVU patch : rvu reset buffering */
+     if (mq->buffering_reset) {
+       if (percent < mq->low_percent) {
+         mq->buffering = TRUE;
+         mq->percent = percent;
+         mq->percent_changed = TRUE;
+       }
+     }
+ #endif
      /* make sure it increases */
 -    percent = MAX (mq->percent, percent);
 +    percent = MAX (mq->buffering_percent, percent);
  
      SET_PERCENT (mq, percent);
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+ /*RVU patch : adaptive buffering solution*/
+     if (mq->enhancement_buffering == TRUE) {
+       if (percent >= mq->high_percent) {
+         mq->percent_changed = TRUE;
+         GST_LOG_OBJECT (mq, "MULTIQUEUE ENHANCEMENT BUFFERING!\n");
+       }
+     }
+ #endif
    } else {
      GList *iter;
      gboolean is_buffering = TRUE;
@@@ -2822,20 -2795,11 +3330,24 @@@ single_queue_check_full (GstDataQueue 
      return TRUE;
  
    /* check time or bytes */
 -  res = IS_FILLED (sq, time, sq->cur_time) || IS_FILLED (sq, bytes, bytes);
+ #ifdef TIZEN_FEATURE_MQ_MODIFICATION
+   res = IS_FILLED_EXTRA (sq, time, sq->cur_time) || IS_FILLED (sq, bytes, bytes);
+ #else
 +  res = IS_FILLED (sq, bytes, bytes);
 +  /* We only care about limits in time if we're not a sparse stream or
 +   * we're not syncing by running time */
 +  if (!sq->is_sparse || !mq->sync_by_running_time) {
 +    /* If unlinked, take into account the extra unlinked cache time */
 +    if (mq->sync_by_running_time && sq->srcresult == GST_FLOW_NOT_LINKED) {
 +      if (sq->cur_time > mq->unlinked_cache_time)
 +        res |= IS_FILLED (sq, time, sq->cur_time - mq->unlinked_cache_time);
 +      else
 +        res = FALSE;
 +    } else
 +      res |= IS_FILLED (sq, time, sq->cur_time);
 +  }
 +
+ #endif
    return res;
  }
  
@@@ -2971,16 -2927,13 +3483,19 @@@ gst_single_queue_new (GstMultiQueue * m
    sq->sink_tainted = TRUE;
    sq->src_tainted = TRUE;
  
+ #ifdef TIZEN_FEATURE_TRUSTZONE
+   sq->sq_stream_type = -1;
+ #endif
    name = g_strdup_printf ("sink_%u", sq->id);
 -  sq->sinkpad = gst_pad_new_from_static_template (&sinktemplate, name);
 +  templ = gst_static_pad_template_get (&sinktemplate);
 +  sq->sinkpad = g_object_new (GST_TYPE_MULTIQUEUE_PAD, "name", name,
 +      "direction", templ->direction, "template", templ, NULL);
 +  gst_object_unref (templ);
    g_free (name);
  
 +  mqpad = (GstMultiQueuePad *) sq->sinkpad;
 +  mqpad->sq = sq;
 +
    gst_pad_set_chain_function (sq->sinkpad,
        GST_DEBUG_FUNCPTR (gst_multi_queue_chain));
    gst_pad_set_activatemode_function (sq->sinkpad,
@@@ -80,13 -75,18 +80,24 @@@ struct _GstMultiQueue 
  
    gint numwaiting;    /* number of not-linked pads waiting */
  
 -  gboolean percent_changed;
 +  gboolean buffering_percent_changed;
    GMutex buffering_post_lock; /* assures only one posted at a time */
 +
 +  GstClockTime interleave;    /* Input interleave */
 +  GstClockTimeDiff last_interleave_update;
 +
 +  GstClockTime unlinked_cache_time;
++
+ #ifdef RVU_LIVESTREAMING_OPTIMIZATION
+   /*RVU patch - reset functionality & buffering optimization*/
+   gboolean enable_buffering_opt;
+   guint64 buffering_start_time;
+   guint64 stream_duration;
+   GstDataQueueSize video_max_size, audio_max_size;
+   gboolean buffering_reset;
+   gboolean disable_audio_buffering;
+   gboolean enhancement_buffering;
+ #endif
  };
  
  struct _GstMultiQueueClass {
Simple merge
Simple merge
@@@ -143,7 -128,9 +143,10 @@@ enu
    PROP_TEMP_LOCATION,
    PROP_TEMP_REMOVE,
    PROP_RING_BUFFER_MAX_SIZE,
 +  PROP_AVG_IN_RATE,
+ #ifdef TIZEN_FEATURE_RTSPSRC_MODIFICATION
+   PROP_BUFFER_MODE,
+ #endif
    PROP_LAST
  };
  
@@@ -305,9 -266,11 +308,12 @@@ static gboolean gst_queue2_is_empty (Gs
  static gboolean gst_queue2_is_filled (GstQueue2 * queue);
  
  static void update_cur_level (GstQueue2 * queue, GstQueue2Range * range);
 -static void update_in_rates (GstQueue2 * queue);
 +static void update_in_rates (GstQueue2 * queue, gboolean force);
 +static GstMessage *gst_queue2_get_buffering_message (GstQueue2 * queue);
  static void gst_queue2_post_buffering (GstQueue2 * queue);
+ #ifdef TIZEN_FEATURE_QUEUE2_MODIFICATION
+ static gboolean change_current_range(GstQueue2 * queue, GstQueue2Range *req_range, guint64 offset, guint length);
+ #endif
  
  typedef enum
  {
@@@ -441,16 -386,19 +447,28 @@@ gst_queue2_class_init (GstQueue2Class 
            0, G_MAXUINT64, DEFAULT_RING_BUFFER_MAX_SIZE,
            G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  
 -
 +  /**
 +   * GstQueue2:avg-in-rate
 +   *
 +   * The average input data rate.
 +   */
 +  g_object_class_install_property (gobject_class, PROP_AVG_IN_RATE,
 +      g_param_spec_int64 ("avg-in-rate", "Input data rate (bytes/s)",
 +          "Average input data rate (bytes/s)",
 +          0, G_MAXINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 +
+ #ifdef TIZEN_FEATURE_RTSPSRC_MODIFICATION
+   /**
+    * GstQueue2:buffer-mode:
+    *
+    * Control the buffering mode used by the queue2.
+    */
+   g_object_class_install_property (gobject_class, PROP_BUFFER_MODE,
+       g_param_spec_enum ("buffer-mode", "Buffer Mode",
+           "Control the buffering algorithm in use",
+           GST_TYPE_BUFFERING_MODE, GST_BUFFERING_STREAM,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ #endif
    /* set several parent class virtual functions */
    gobject_class->finalize = gst_queue2_finalize;
  
@@@ -1097,18 -990,29 +1145,31 @@@ gst_queue2_post_buffering (GstQueue2 * 
  static void
  update_buffering (GstQueue2 * queue)
  {
 -  gint percent;
 +  gint buffering_level, percent;
+ #ifdef TIZEN_FEATURE_QUEUE2_MODIFICATION
+   GstQueue2Range *range;
+   if (queue->read)
+     range = queue->read;
+   else
+     range = queue->current;
+ #endif
  
    /* Ensure the variables used to calculate buffering state are up-to-date. */
+ #ifdef TIZEN_FEATURE_QUEUE2_MODIFICATION
+   if (range)
+     update_cur_level (queue, range);
+ #else
    if (queue->current)
      update_cur_level (queue, queue->current);
 -  update_in_rates (queue);
+ #endif
 +  update_in_rates (queue, FALSE);
  
 -  if (!get_buffering_percent (queue, NULL, &percent))
 +  if (!get_buffering_level (queue, NULL, &buffering_level))
      return;
  
 +  percent = convert_to_buffering_percent (queue, buffering_level);
 +
    if (queue->is_buffering) {
      /* if we were buffering see if we reached the high watermark */
      if (percent >= 100)
@@@ -3864,19 -3794,11 +4067,24 @@@ gst_queue2_get_property (GObject * obje
      case PROP_RING_BUFFER_MAX_SIZE:
        g_value_set_uint64 (value, queue->ring_buffer_max_size);
        break;
 +    case PROP_AVG_IN_RATE:
 +    {
 +      gdouble in_rate = queue->byte_in_rate;
 +
 +      /* During the first RATE_INTERVAL, byte_in_rate will not have been
 +       * calculated, so calculate it here. */
 +      if (in_rate == 0.0 && queue->bytes_in
 +          && queue->last_update_in_rates_elapsed > 0.0)
 +        in_rate = queue->bytes_in / queue->last_update_in_rates_elapsed;
 +
 +      g_value_set_int64 (value, (gint64) in_rate);
 +      break;
 +    }
+ #ifdef TIZEN_FEATURE_RTSPSRC_MODIFICATION
+     case PROP_BUFFER_MODE:
+       g_value_set_enum (value, queue->mode);
+       break;
+ #endif
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        break;
Simple merge
Simple merge
@@@ -859,133 -788,40 +859,213 @@@ GST_START_TEST (segment_full
            50, &rt) == -1);
    GST_DEBUG ("%" G_GUINT64_FORMAT, rt);
    fail_unless (rt == 50);
 +
 +  segment.start = 50;
 +  segment.stop = 300;
 +  segment.position = 150;
 +  segment.time = 0;
 +  segment.offset = 0;
 +  gst_segment_set_running_time (&segment, GST_FORMAT_TIME, 100);
 +  fail_unless_equals_int (segment.base, 100);
 +  fail_unless (gst_segment_position_from_running_time_full (&segment,
 +          GST_FORMAT_TIME, 70, &pos) == -1);
 +  fail_unless (gst_segment_position_from_running_time_full (&segment,
 +          GST_FORMAT_TIME, 140, &pos) == 1);
 +  fail_unless_equals_int (pos, 190);
 +}
 +
 +GST_END_TEST;
 +
 +GST_START_TEST (segment_stream_time_full)
 +{
 +  GstSegment segment;
 +  guint64 st, pos;
 +
 +  gst_segment_init (&segment, GST_FORMAT_TIME);
 +
 +  segment.start = 50;
 +  segment.stop = 200;
 +  segment.time = 30;
 +  segment.position = 0;
 +
 +  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
 +          0, &st) == -1);
 +  fail_unless_equals_int (st, 20);
 +  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
 +          20, &st) == 1);
 +  fail_unless_equals_int (st, 0);
 +  fail_unless (gst_segment_position_from_stream_time_full (&segment,
 +          GST_FORMAT_TIME, 0, &pos) == 1);
 +  fail_unless_equals_int (pos, 20);
 +  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
 +          10, &st) == -1);
 +  fail_unless_equals_int (st, 10);
 +  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
 +          40, &st) == 1);
 +  fail_unless_equals_int (st, 20);
 +  fail_unless (gst_segment_position_from_stream_time_full (&segment,
 +          GST_FORMAT_TIME, st, &pos) == 1);
 +  fail_unless_equals_int (pos, 40);
 +  segment.time = 100;
 +  fail_unless (gst_segment_position_from_stream_time_full (&segment,
 +          GST_FORMAT_TIME, 40, &pos) == -1);
 +  fail_unless_equals_int (pos, 10);
 +  fail_unless (gst_segment_position_from_stream_time_full (&segment,
 +          GST_FORMAT_TIME, 60, &pos) == 1);
 +  fail_unless_equals_int (pos, 10);
 +
 +  segment.start = 50;
 +  segment.position = 150;
 +  segment.stop = 200;
 +  segment.time = 0;
 +  segment.applied_rate = -1;
 +  segment.rate = -1;
 +
 +  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
 +          0, &st) == 1);
 +  fail_unless_equals_int (st, 200);
 +  fail_unless (gst_segment_position_from_stream_time_full (&segment,
 +          GST_FORMAT_TIME, 200, &pos) == 1);
 +  fail_unless_equals_int (pos, 0);
 +  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
 +          250, &st) == -1);
 +  fail_unless_equals_int (st, 50);
 +  fail_unless (gst_segment_position_from_stream_time_full (&segment,
 +          GST_FORMAT_TIME, 200, &pos) == 1);
 +  fail_unless_equals_int (pos, 0);
 +  fail_unless (gst_segment_position_from_stream_time_full (&segment,
 +          GST_FORMAT_TIME, 250, &pos) == -1);
 +  fail_unless_equals_int (pos, 50);
 +
 +  segment.time = 70;
 +  fail_unless (gst_segment_to_stream_time_full (&segment, GST_FORMAT_TIME,
 +          250, &st) == 1);
 +  fail_unless_equals_int (st, 20);
 +  fail_unless (gst_segment_position_from_stream_time_full (&segment,
 +          GST_FORMAT_TIME, 50, &pos) == 1);
 +  fail_unless_equals_int (pos, 220);
 +  fail_unless (gst_segment_position_from_stream_time_full (&segment,
 +          GST_FORMAT_TIME, 90, &pos) == 1);
 +  fail_unless_equals_int (pos, 180);
 +
 +  segment.stop = 60;
 +  fail_unless (gst_segment_position_from_stream_time_full (&segment,
 +          GST_FORMAT_TIME, 5, &pos) == 1);
 +  fail_unless_equals_int (pos, 125);
 +}
 +
 +GST_END_TEST;
 +
 +GST_START_TEST (segment_negative_rate)
 +{
 +  GstSegment segment;
 +
 +  gst_segment_init (&segment, GST_FORMAT_TIME);
 +
 +  segment.start = 50;
 +  segment.position = 150;
 +  segment.stop = 200;
 +  segment.time = 0;
 +  segment.applied_rate = -1;
 +  segment.rate = -1;
 +
 +  /* somewhere in the middle */
 +  check_times (&segment, 100, 100, 100);
 +  /* after stop */
 +  check_times (&segment, 220, -1, -1);
 +  /* before start */
 +  check_times (&segment, 10, -1, -1);
 +  /* at segment start */
 +  check_times (&segment, 50, 150, 150);
 +  /* another place in the middle */
 +  check_times (&segment, 150, 50, 50);
 +  /* at segment stop */
 +  check_times (&segment, 200, 0, 0);
 +
 +  segment.time = 100;
 +  segment.base = 100;
 +  /* somewhere in the middle */
 +  check_times (&segment, 100, 200, 200);
++  /* at segment start */
++  check_times (&segment, 50, 250, 250);
++  /* another place in the middle */
++  check_times (&segment, 150, 150, 150);
++  /* at segment stop */
++  check_times (&segment, 200, 100, 100);
++}
++
++GST_END_TEST;
++
++GST_START_TEST (segment_negative_applied_rate)
++{
++  GstSegment segment;
++
++  gst_segment_init (&segment, GST_FORMAT_TIME);
++
++  segment.start = 50;
++  segment.position = 150;
++  segment.stop = 200;
++  segment.time = 0;
++  segment.applied_rate = -1;
++  segment.rate = 1;
++
++  /* somewhere in the middle */
++  check_times (&segment, 100, 100, 50);
++  /* after stop */
++  check_times (&segment, 220, -1, -1);
++  /* before start */
++  check_times (&segment, 10, -1, -1);
++  /* at segment start */
++  check_times (&segment, 50, 150, 0);
++  /* another place in the middle */
++  check_times (&segment, 150, 50, 100);
++  /* at segment stop */
++  check_times (&segment, 200, 0, 150);
++
++  segment.time = 100;
++  segment.base = 100;
++  /* somewhere in the middle */
++  check_times (&segment, 100, 200, 150);
++  /* at segment start */
++  check_times (&segment, 50, 250, 100);
++  /* another place in the middle */
++  check_times (&segment, 150, 150, 200);
++  /* at segment stop */
++  check_times (&segment, 200, 100, 250);
+ }
+ GST_END_TEST;
+ GST_START_TEST (segment_negative_rate)
+ {
+   GstSegment segment;
+   gst_segment_init (&segment, GST_FORMAT_TIME);
+   segment.start = 50;
+   segment.position = 150;
+   segment.stop = 200;
+   segment.time = 0;
+   segment.applied_rate = -1;
+   segment.rate = -1;
+   /* somewhere in the middle */
+   check_times (&segment, 100, 100, 100);
+   /* after stop */
+   check_times (&segment, 220, -1, -1);
+   /* before start */
+   check_times (&segment, 10, -1, -1);
+   /* at segment start */
+   check_times (&segment, 50, 150, 150);
+   /* another place in the middle */
+   check_times (&segment, 150, 50, 50);
+   /* at segment stop */
+   check_times (&segment, 200, 0, 0);
+   segment.time = 100;
+   segment.base = 100;
+   /* somewhere in the middle */
+   check_times (&segment, 100, 200, 200);
    /* at segment start */
    check_times (&segment, 50, 250, 250);
    /* another place in the middle */
@@@ -5,16 -4,14 +5,18 @@@ bin_PROGRAMS = 
        gst-typefind-@GST_API_VERSION@
  
  gst_inspect_@GST_API_VERSION@_SOURCES = gst-inspect.c tools.h
- gst_inspect_@GST_API_VERSION@_CFLAGS = $(GST_OBJ_CFLAGS)
+ gst_inspect_@GST_API_VERSION@_CFLAGS = $(GST_OBJ_CFLAGS) -fPIE
  gst_inspect_@GST_API_VERSION@_LDADD = $(GST_OBJ_LIBS)
+ gst_inspect_@GST_API_VERSION@_LDFLAGS = -pie
  
 +gst_stats_@GST_API_VERSION@_SOURCES = gst-stats.c tools.h
 +gst_stats_@GST_API_VERSION@_CFLAGS = $(GST_OBJ_CFLAGS)
 +gst_stats_@GST_API_VERSION@_LDADD = $(GST_OBJ_LIBS)
 +
  gst_typefind_@GST_API_VERSION@_SOURCES = gst-typefind.c tools.h
- gst_typefind_@GST_API_VERSION@_CFLAGS = $(GST_OBJ_CFLAGS)
+ gst_typefind_@GST_API_VERSION@_CFLAGS = $(GST_OBJ_CFLAGS) -fPIE
  gst_typefind_@GST_API_VERSION@_LDADD = $(GST_OBJ_LIBS)
+ gst_typefind_@GST_API_VERSION@_LDFLAGS = -pie
  
  if !GST_DISABLE_PARSE
  bin_PROGRAMS += gst-launch-@GST_API_VERSION@