--- /dev/null
-upstream_branch = upstream/1.6
+ [general]
++upstream_branch = upstream/1.12
+ upstream_tag = ${upstreamversion}
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
$(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)
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;
#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);
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;
}
"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];
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];
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
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__ */
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__ */
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__ */
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
--- /dev/null
-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
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
};
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,
* 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
};
"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,
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);
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;
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;
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;
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;
}
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,
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 {
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
};
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
{
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;
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)
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;
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 */
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@