...
 
Commits (89)
This diff is collapsed.
This diff is collapsed.
GStreamer 1.11.x development series
GStreamer 1.12.x stable series
WHAT IT IS
----------
......
This is GStreamer core 1.12.5.
Release notes for GStreamer 1.12.0
The GStreamer team is pleased to announce the fifth bugfix release in the stable
1.12 release series of your favourite cross-platform multimedia framework!
The GStreamer team is pleased to announce the first release in the stable 1.12
release series. The 1.12 release series is adding new features on top of the
1.0, 1.2, 1.4, 1.6, 1.8 and 1.10 series and is part of the API and ABI-stable
1.x release series of the GStreamer multimedia framework.
This release only contains bugfixes and it is safe to update from 1.12.x. For a
full list of bugfixes see Bugzilla and the release notes.
The 1.12 stable series is now superseded by the 1.14 stable series, and 1.12.5
will likely be the last bugfix release in the 1.12 series.
Full release notes can be found here
Full release notes can be found at:
https://gstreamer.freedesktop.org/releases/1.12/#1.12.5
Binaries for Android, iOS, Mac OS X and Windows will be provided in the next days.
Binaries for Android, iOS, Mac OS X and Windows will be provided shortly
after the release.
This module will not be very useful by itself and should be used in conjunction
with other GStreamer modules for a complete multimedia experience.
This module, gstreamer, only contains core functionality.
For actual media playback, you will need other modules.
- gstreamer: provides the core GStreamer libraries and some generic plugins
gst-plugins-base
contains a basic set of well-supported plugins
gst-plugins-good
contains a set of well-supported plugins under our preferred license
gst-plugins-ugly
contains a set of well-supported plugins, but might pose problems for
distributors
gst-plugins-bad
contains a set of less supported plugins that haven't passed the
rigorous quality testing we expect, or are still missing documentation
and/or unit tests
gst-libav
contains a set of codecs plugins based on libav (formerly gst-ffmpeg)
- gst-plugins-base: a basic set of well-supported plugins and additional
media-specific GStreamer helper libraries for audio,
video, rtsp, rtp, tags, OpenGL, etc.
- gst-plugins-good: a set of well-supported plugins under our preferred
license
- gst-plugins-ugly: a set of well-supported plugins which might pose
problems for distributors
- gst-plugins-bad: a set of plugins of varying quality that have not made
their way into one of core/base/good/ugly yet, for one
reason or another. Many of these are are production quality
elements, but may still be missing documentation or unit
tests; others haven't passed the rigorous quality testing
we expect yet.
Bugs fixed in this release
* 782050 : basetransform/adapter: Check if meta transform_func is NULL before using it
- gst-libav: a set of codecs plugins based on the ffmpeg library. This is
where you can find audio and video decoders and encoders
for a wide variety of formats including H.264, AAC, etc.
- gstreamer-vaapi: hardware-accelerated video decoding and encoding using
VA-API on Linux. Primarily for Intel graphics hardware.
- gst-omx: hardware-accelerated video decoding and encoding, primarily for
embedded Linux systems that provide an OpenMax
implementation layer such as the Raspberry Pi.
- gst-rtsp-server: library to serve files or streaming pipelines via RTSP
- gst-editing-services: library an plugins for non-linear editing
==== Download ====
......@@ -44,7 +59,7 @@ You can find source releases of gstreamer in the download
directory: https://gstreamer.freedesktop.org/src/gstreamer/
The git repository and details how to clone it can be found at
http://cgit.freedesktop.org/gstreamer/gstreamer/
https://cgit.freedesktop.org/gstreamer/gstreamer/
==== Homepage ====
......@@ -53,7 +68,7 @@ The project's website is https://gstreamer.freedesktop.org/
==== Support and Bugs ====
We use GNOME's bugzilla for bug reports and feature requests:
http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer
https://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer
Please submit patches via bugzilla as well.
......@@ -69,12 +84,3 @@ from there (see link above).
Interested developers of the core library, plugins, and applications should
subscribe to the gstreamer-devel list.
Contributors to this release
* Frédéric Dalleau
* Nicola Murino
* Sebastian Dröge
* Víctor Manuel Jáquez Leal
 
\ No newline at end of file
common @ dd9d4031
Subproject commit 48a5d85ebf4a0bad1c997c83100f710fe2154fbf
Subproject commit dd9d4031075713cf37c656ce639b6d60d6f9dde3
......@@ -4,7 +4,7 @@ dnl initialize autoconf
dnl when going to/from release please set the nano (fourth number) right !
dnl releases only do Wall, git and prerelease does Werror too
dnl
AC_INIT([GStreamer],[1.12.0],[http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer],[gstreamer])
AC_INIT([GStreamer],[1.12.5],[http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer],[gstreamer])
AG_GST_INIT
dnl initialize automake (we require GNU make)
......@@ -62,7 +62,7 @@ dnl 1.2.5 => 205
dnl 1.10.9 (who knows) => 1009
dnl
dnl sets GST_LT_LDFLAGS
AS_LIBTOOL(GST, 1200, 0, 1200)
AS_LIBTOOL(GST, 1205, 0, 1205)
dnl *** autotools stuff ****
......@@ -821,15 +821,45 @@ fi
AM_CONDITIONAL(HAVE_GTK, test "x$HAVE_GTK" = "xyes")
dnl libunwind is optionally used by the leaks tracer
PKG_CHECK_MODULES(UNWIND, libunwind, HAVE_UNWIND=yes, HAVE_UNWIND=no)
if test "x$HAVE_UNWIND" = "xyes"; then
AC_DEFINE(HAVE_UNWIND, 1, [libunwind available])
AC_ARG_WITH([unwind],[AS_HELP_STRING([--with-unwind=yes|no|auto],[use libunwind])],
[], [with_unwind=auto])
if [ test "x${with_unwind}" != "xno" ]; then
PKG_CHECK_MODULES(UNWIND, [libunwind],
[
HAVE_UNWIND=yes
AC_DEFINE(HAVE_UNWIND, 1, [libunwind available])
UNWIND_REQUIRE=libunwind
AC_SUBST(UNWIND_REQUIRE)
],
[
HAVE_UNWIND=no
if [ test "x${with_unwind}" = "xyes" ]; then
AC_MSG_ERROR([could not find libunwind])
fi
])
else
HAVE_UNWIND=no
fi
dnl libdw is optionally used to add source lines and numbers to backtraces
PKG_CHECK_MODULES(DW, libdw, HAVE_DW=yes, HAVE_DW=no)
if test "x$HAVE_DW" = "xyes"; then
AC_DEFINE(HAVE_DW, 1, [libdw available])
AC_ARG_WITH([dw],[AS_HELP_STRING([--with-dw=yes|no|auto],[use libdw])],
[], [with_dw=auto])
if [ test "x${with_dw}" != "xno" ]; then
PKG_CHECK_MODULES(DW, [libdw],
[
HAVE_DW=yes
AC_DEFINE(HAVE_DW, 1, [libdw available])
DW_REQUIRE=libdw
AC_SUBST(DW_REQUIRE)
],
[
HAVE_DW=no
if [ test "x${with_dw}" = "xyes" ]; then
AC_MSG_ERROR([could not find libdw])
fi
])
else
HAVE_DW=no
fi
dnl Check for backtrace() from libc
......
......@@ -2242,6 +2242,7 @@ gst_parse_bin_from_description
gst_parse_bin_from_description_full
<SUBSECTION>
gst_parse_context_new
gst_parse_context_copy
gst_parse_context_free
gst_parse_context_get_missing_elements
<SUBSECTION Standard>
......
......@@ -109,6 +109,14 @@
<title>Index of deprecated API</title>
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
</index>
<index>
<title>Index of new API in 1.12.1</title>
<xi:include href="xml/api-index-1.12.1.xml"><xi:fallback /></xi:include>
</index>
<index>
<title>Index of new API in 1.12</title>
<xi:include href="xml/api-index-1.12.xml"><xi:fallback /></xi:include>
</index>
<index>
<title>Index of new API in 1.10</title>
<xi:include href="xml/api-index-1.10.xml"><xi:fallback /></xi:include>
......
......@@ -798,6 +798,8 @@ gst_collect_pads_get_type
GstFlowCombiner
gst_flow_combiner_new
gst_flow_combiner_free
gst_flow_combiner_ref
gst_flow_combiner_unref
gst_flow_combiner_update_flow
gst_flow_combiner_add_pad
gst_flow_combiner_remove_pad
......
......@@ -3,7 +3,7 @@
<description>GStreamer core elements</description>
<filename>../../plugins/elements/.libs/libgstcoreelements.so</filename>
<basename>libgstcoreelements.so</basename>
<version>1.12.0</version>
<version>1.12.5</version>
<license>LGPL</license>
<source>gstreamer</source>
<package>GStreamer source release</package>
......
<plugin>
<name>coretracers</name>
<description>GStreamer core tracers</description>
<filename>../../plugins/tracers/.libs/libgstcoretracers.so</filename>
<basename>libgstcoretracers.so</basename>
<version>1.12.5</version>
<license>LGPL</license>
<source>gstreamer</source>
<package>GStreamer source release</package>
<origin>Unknown package origin</origin>
<elements>
</elements>
</plugin>
\ No newline at end of file
......@@ -2313,6 +2313,12 @@ find_element (GstElement * element, GstBinSortIterator * bit)
if (bit->best == NULL || bit->best_deg > degree) {
bit->best = element;
bit->best_deg = degree;
} else if (bit->best_deg == degree
&& GST_OBJECT_FLAG_IS_SET (bit->best, GST_ELEMENT_FLAG_SOURCE)
&& !GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SOURCE)) {
/* If two elements have the same degree, we want to ensure we
* return non-source elements first. */
bit->best = element;
}
}
......
......@@ -2370,12 +2370,16 @@ gst_buffer_foreach_meta (GstBuffer * buffer, GstBufferForeachMetaFunc func,
else
prev->next = next;
prev = next;
/* call free_func if any */
if (info->free_func)
info->free_func (m, buffer);
/* and free the slice */
g_slice_free1 (ITEM_SIZE (info), walk);
} else {
prev = walk;
}
if (!res)
break;
......
......@@ -117,10 +117,16 @@ gst_child_proxy_default_get_child_by_name (GstChildProxy * parent,
GObject *
gst_child_proxy_get_child_by_name (GstChildProxy * parent, const gchar * name)
{
GstChildProxyInterface *iface;
g_return_val_if_fail (GST_IS_CHILD_PROXY (parent), 0);
return (GST_CHILD_PROXY_GET_INTERFACE (parent)->get_child_by_name (parent,
name));
iface = GST_CHILD_PROXY_GET_INTERFACE (parent);
if (iface->get_child_by_name != NULL)
return iface->get_child_by_name (parent, name);
return NULL;
}
/**
......@@ -138,10 +144,16 @@ gst_child_proxy_get_child_by_name (GstChildProxy * parent, const gchar * name)
GObject *
gst_child_proxy_get_child_by_index (GstChildProxy * parent, guint index)
{
GstChildProxyInterface *iface;
g_return_val_if_fail (GST_IS_CHILD_PROXY (parent), NULL);
return (GST_CHILD_PROXY_GET_INTERFACE (parent)->get_child_by_index (parent,
index));
iface = GST_CHILD_PROXY_GET_INTERFACE (parent);
if (iface->get_child_by_index != NULL)
return iface->get_child_by_index (parent, index);
return NULL;
}
/**
......@@ -157,9 +169,16 @@ gst_child_proxy_get_child_by_index (GstChildProxy * parent, guint index)
guint
gst_child_proxy_get_children_count (GstChildProxy * parent)
{
GstChildProxyInterface *iface;
g_return_val_if_fail (GST_IS_CHILD_PROXY (parent), 0);
return (GST_CHILD_PROXY_GET_INTERFACE (parent)->get_children_count (parent));
iface = GST_CHILD_PROXY_GET_INTERFACE (parent);
if (iface->get_children_count != NULL)
return iface->get_children_count (parent);
return 0;
}
/**
......
......@@ -146,10 +146,11 @@
# define GST_EXPORT __declspec(dllimport) extern
# endif
#else
# define GST_PLUGIN_EXPORT
# if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
# define GST_PLUGIN_EXPORT __attribute__ ((visibility ("default")))
# define GST_EXPORT extern __attribute__ ((visibility ("default")))
# else
# define GST_PLUGIN_EXPORT
# define GST_EXPORT extern
# endif
#endif
......
......@@ -774,7 +774,7 @@ debug_dump_header (GstBin * bin, GstDebugGraphDetails details, GString * str)
" pos=\"0,0!\",\n"
" margin=\"0.05,0.05\",\n"
" style=\"filled\",\n"
" label=\"Legend\\lElement-States: [~] void-pending, [0] null, [-] ready, [=] paused, [>] playing\\lPad-Activation: [-] none, [>] push, [<] pull\\lPad-Flags: [b]locked, [f]lushing, [b]locking; upper-case is set\\lPad-Task: [T] has started task, [t] has paused task\\l\",\n"
" label=\"Legend\\lElement-States: [~] void-pending, [0] null, [-] ready, [=] paused, [>] playing\\lPad-Activation: [-] none, [>] push, [<] pull\\lPad-Flags: [b]locked, [f]lushing, [b]locking, [E]OS; upper-case is set\\lPad-Task: [T] has started task, [t] has paused task\\l\",\n"
" ];"
"\n", G_OBJECT_TYPE_NAME (bin), GST_OBJECT_NAME (bin),
(state_name ? state_name : ""), (param_name ? param_name : "")
......@@ -822,7 +822,7 @@ gst_debug_bin_to_dot_data (GstBin * bin, GstDebugGraphDetails details)
/*
* gst_debug_bin_to_dot_file:
* @bin: the top-level pipeline that should be analyzed
* @file_name: output base filename (e.g. "myplayer")
* @file_name: (type filename): output base filename (e.g. "myplayer")
*
* To aid debugging applications one can use this method to write out the whole
* network of gstreamer elements that form the pipeline into an dot file.
......@@ -872,7 +872,7 @@ gst_debug_bin_to_dot_file (GstBin * bin, GstDebugGraphDetails details,
/*
* gst_debug_bin_to_dot_file_with_ts:
* @bin: the top-level pipeline that should be analyzed
* @file_name: output base filename (e.g. "myplayer")
* @file_name: (type filename): output base filename (e.g. "myplayer")
*
* This works like gst_debug_bin_to_dot_file(), but adds the current timestamp
* to the filename, so that it can be used to take multiple snapshots.
......
......@@ -714,7 +714,7 @@ gst_device_provider_unhide_provider (GstDeviceProvider * provider,
gchar *unhidden_name = NULL;
g_return_if_fail (GST_IS_DEVICE_PROVIDER (provider));
g_return_if_fail (unhidden_name != NULL);
g_return_if_fail (name != NULL);
GST_OBJECT_LOCK (provider);
find =
......
......@@ -403,7 +403,7 @@ gst_element_set_clock_func (GstElement * element, GstClock * clock)
/**
* gst_element_set_clock:
* @element: a #GstElement to set the clock for.
* @clock: the #GstClock to set for the element.
* @clock: (transfer none) (allow-none): the #GstClock to set for the element.
*
* Sets the clock for the element. This function increases the
* refcount on the clock. Any previously set clock on the object
......@@ -3145,7 +3145,7 @@ gst_element_set_bus_func (GstElement * element, GstBus * bus)
/**
* gst_element_set_bus:
* @element: a #GstElement to set the bus of.
* @bus: (transfer none): the #GstBus to set.
* @bus: (transfer none) (allow-none): the #GstBus to set.
*
* Sets the bus of the element. Increases the refcount on the bus.
* For internal use only, unless you're testing elements.
......
......@@ -333,9 +333,9 @@ had_parent:
*
* Access the structure of the event.
*
* Returns: The structure of the event. The structure is still
* owned by the event, which means that you should not free it and
* that the pointer becomes invalid when you free the event.
* Returns: (transfer none) (nullable): The structure of the event. The
* structure is still owned by the event, which means that you should not free
* it and that the pointer becomes invalid when you free the event.
*
* MT safe.
*/
......
......@@ -506,13 +506,16 @@ gst_ghost_pad_dispose (GObject * object)
GST_OBJECT_LOCK (pad);
internal = GST_PROXY_PAD_INTERNAL (pad);
if (internal) {
gst_pad_set_activatemode_function (internal, NULL);
gst_pad_set_activatemode_function (internal, NULL);
GST_PROXY_PAD_INTERNAL (pad) = NULL;
GST_PROXY_PAD_INTERNAL (internal) = NULL;
/* disposes of the internal pad, since the ghostpad is the only possible object
* that has a refcount on the internal pad. */
gst_object_unparent (GST_OBJECT_CAST (internal));
GST_PROXY_PAD_INTERNAL (pad) = NULL;
/* disposes of the internal pad, since the ghostpad is the only possible object
* that has a refcount on the internal pad. */
gst_object_unparent (GST_OBJECT_CAST (internal));
}
GST_OBJECT_UNLOCK (pad);
......@@ -832,11 +835,17 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
g_return_val_if_fail (GST_PAD_CAST (gpad) != newtarget, FALSE);
g_return_val_if_fail (newtarget != GST_PROXY_PAD_INTERNAL (gpad), FALSE);
GST_OBJECT_LOCK (gpad);
internal = GST_PROXY_PAD_INTERNAL (gpad);
if (newtarget == internal) {
GST_OBJECT_UNLOCK (gpad);
GST_WARNING_OBJECT (gpad, "Target has already been set to %s:%s",
GST_DEBUG_PAD_NAME (newtarget));
return FALSE;
}
if (newtarget)
GST_DEBUG_OBJECT (gpad, "set target %s:%s", GST_DEBUG_PAD_NAME (newtarget));
else
......
......@@ -240,8 +240,6 @@ dladdr (void *address, Dl_info * dl)
#endif /* __sgi__ */
#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);
......@@ -464,10 +462,9 @@ _priv_gst_debug_init (void)
if (env)
gst_debug_set_color_mode_from_string (env);
_gst_debug_filter = g_getenv ("GST_DEBUG");
if (_gst_debug_filter) {
gst_debug_set_threshold_from_string (_gst_debug_filter, FALSE);
}
env = g_getenv ("GST_DEBUG");
if (env)
gst_debug_set_threshold_from_string (env, FALSE);
}
/* we can't do this further above, because we initialize the GST_CAT_DEFAULT struct */
......@@ -1692,6 +1689,18 @@ gst_debug_unset_threshold_for_name (const gchar * name)
gst_debug_reset_all_thresholds ();
}
static void
gst_debug_apply_patterns_to_category (GstDebugCategory * cat)
{
GSList *l;
g_mutex_lock (&__level_name_mutex);
for (l = __level_name; l != NULL; l = l->next) {
for_each_threshold_by_entry (cat, (LevelNameEntry *) l->data);
}
g_mutex_unlock (&__level_name_mutex);
}
GstDebugCategory *
_gst_debug_category_new (const gchar * name, guint color,
const gchar * description)
......@@ -1725,9 +1734,7 @@ _gst_debug_category_new (const gchar * name, guint color,
g_mutex_unlock (&__cat_mutex);
/* ensure the filter is applied to categories registered after _debug_init */
if (_gst_debug_filter) {
gst_debug_set_threshold_from_string (_gst_debug_filter, FALSE);
}
gst_debug_apply_patterns_to_category (cat);
return cat;
}
......@@ -1983,7 +1990,7 @@ gst_debug_set_threshold_from_string (const gchar * list, gboolean reset)
g_assert (list);
if (reset)
gst_debug_set_default_threshold (0);
gst_debug_set_default_threshold (GST_LEVEL_DEFAULT);
split = g_strsplit (list, ",", 0);
......@@ -2751,6 +2758,8 @@ generate_backtrace_trace (void)
for (j = 0; j < nptrs; j++)
g_string_append_printf (trace, "%s\n", strings[j]);
free (strings);
return g_string_free (trace, FALSE);
}
#else
......
......@@ -179,6 +179,8 @@ typedef enum {
* GstStackTraceFlags:
* @GST_STACK_TRACE_SHOW_FULL: Try to retrieve as much information as
* possible when getting the stack trace
*
* Since: 1.12
*/
typedef enum {
GST_STACK_TRACE_SHOW_FULL = 1 << 0
......
......@@ -1144,9 +1144,9 @@ gst_message_new_request_state (GstObject * src, GstState state)
*
* Access the structure of the message.
*
* Returns: (transfer none): The structure of the message. The structure is
* still owned by the message, which means that you should not free it and
* that the pointer becomes invalid when you free the message.
* Returns: (transfer none) (nullable): The structure of the message. The
* structure is still owned by the message, which means that you should not
* free it and that the pointer becomes invalid when you free the message.
*
* MT safe.
*/
......
......@@ -1330,7 +1330,7 @@ gst_object_get_value (GstObject * object, const gchar * property_name,
}
/**
* gst_object_get_value_array:
* gst_object_get_value_array: (skip)
* @object: the object that has controlled properties
* @property_name: the name of the property to get
* @timestamp: the time that should be processed
......@@ -1381,7 +1381,7 @@ gst_object_get_value_array (GstObject * object, const gchar * property_name,
* @timestamp: the time that should be processed
* @interval: the time spacing between subsequent values
* @n_values: the number of values
* @values: array to put control-values in
* @values: (array length=n_values): array to put control-values in
*
* Gets a number of #GValues for the given controlled property starting at the
* requested time. The array @values need to hold enough space for @n_values of
......
......@@ -149,6 +149,11 @@ struct _GstPadPrivate
* call. Used to block any data flowing in the pad while the idle callback
* Doesn't finish its work */
gint idle_running;
/* conditional and variable used to ensure pads only get (de)activated
* by a single thread at a time. Protected by the object lock */
GCond activation_cond;
gboolean in_activation;
};
typedef struct
......@@ -417,6 +422,8 @@ gst_pad_init (GstPad * pad)
pad->priv->events = g_array_sized_new (FALSE, TRUE, sizeof (PadEvent), 16);
pad->priv->events_cookie = 0;
pad->priv->last_cookie = -1;
g_cond_init (&pad->priv->activation_cond);
pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
}
......@@ -762,6 +769,7 @@ gst_pad_finalize (GObject * object)
g_rec_mutex_clear (&pad->stream_rec_lock);
g_cond_clear (&pad->block_cond);
g_cond_clear (&pad->priv->activation_cond);
g_array_free (pad->priv->events, TRUE);
G_OBJECT_CLASS (parent_class)->finalize (object);
......@@ -959,12 +967,22 @@ gst_pad_mode_get_name (GstPadMode mode)
return "unknown";
}
static void
/* Returns TRUE if pad wasn't already in the new_mode */
static gboolean
pre_activate (GstPad * pad, GstPadMode new_mode)
{
switch (new_mode) {
case GST_PAD_MODE_NONE:
GST_OBJECT_LOCK (pad);
while (G_UNLIKELY (pad->priv->in_activation))
g_cond_wait (&pad->priv->activation_cond, GST_OBJECT_GET_LOCK (pad));
if (new_mode == GST_PAD_MODE (pad)) {
GST_WARNING_OBJECT (pad,
"Pad is already in the process of being deactivated");
GST_OBJECT_UNLOCK (pad);
return FALSE;
}
pad->priv->in_activation = TRUE;
GST_DEBUG_OBJECT (pad, "setting PAD_MODE NONE, set flushing");
GST_PAD_SET_FLUSHING (pad);
pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
......@@ -976,6 +994,15 @@ pre_activate (GstPad * pad, GstPadMode new_mode)
case GST_PAD_MODE_PUSH:
case GST_PAD_MODE_PULL:
GST_OBJECT_LOCK (pad);
while (G_UNLIKELY (pad->priv->in_activation))
g_cond_wait (&pad->priv->activation_cond, GST_OBJECT_GET_LOCK (pad));
if (new_mode == GST_PAD_MODE (pad)) {
GST_WARNING_OBJECT (pad,
"Pad is already in the process of being activated");
GST_OBJECT_UNLOCK (pad);
return FALSE;
}
pad->priv->in_activation = TRUE;
GST_DEBUG_OBJECT (pad, "setting pad into %s mode, unset flushing",
gst_pad_mode_get_name (new_mode));
GST_PAD_UNSET_FLUSHING (pad);
......@@ -1004,6 +1031,7 @@ pre_activate (GstPad * pad, GstPadMode new_mode)
}
break;
}
return TRUE;
}
static void
......@@ -1011,6 +1039,11 @@ post_activate (GstPad * pad, GstPadMode new_mode)
{
switch (new_mode) {
case GST_PAD_MODE_NONE:
GST_OBJECT_LOCK (pad);
pad->priv->in_activation = FALSE;
g_cond_broadcast (&pad->priv->activation_cond);
GST_OBJECT_UNLOCK (pad);
/* ensures that streaming stops */
GST_PAD_STREAM_LOCK (pad);
GST_DEBUG_OBJECT (pad, "stopped streaming");
......@@ -1021,6 +1054,10 @@ post_activate (GstPad * pad, GstPadMode new_mode)
break;
case GST_PAD_MODE_PUSH:
case GST_PAD_MODE_PULL:
GST_OBJECT_LOCK (pad);
pad->priv->in_activation = FALSE;
g_cond_broadcast (&pad->priv->activation_cond);
GST_OBJECT_UNLOCK (pad);
/* NOP */
break;
}
......@@ -1173,17 +1210,21 @@ activate_mode_internal (GstPad * pad, GstObject * parent, GstPadMode mode,
/* Mark pad as needing reconfiguration */
if (active)
GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE);
pre_activate (pad, new);
if (GST_PAD_ACTIVATEMODEFUNC (pad)) {
if (G_UNLIKELY (!GST_PAD_ACTIVATEMODEFUNC (pad) (pad, parent, mode,
active)))
goto failure;
} else {
/* can happen for sinks of passthrough elements */
}
/* pre_activate returns TRUE if we weren't already in the process of
* switching to the 'new' mode */
if (pre_activate (pad, new)) {
post_activate (pad, new);
if (GST_PAD_ACTIVATEMODEFUNC (pad)) {
if (G_UNLIKELY (!GST_PAD_ACTIVATEMODEFUNC (pad) (pad, parent, mode,
active)))
goto failure;
} else {
/* can happen for sinks of passthrough elements */
}
post_activate (pad, new);
}
GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "%s in %s mode",
active ? "activated" : "deactivated", gst_pad_mode_get_name (mode));
......@@ -1238,6 +1279,8 @@ failure:
active ? "activate" : "deactivate", gst_pad_mode_get_name (mode));
GST_PAD_SET_FLUSHING (pad);
GST_PAD_MODE (pad) = old;
pad->priv->in_activation = FALSE;
g_cond_broadcast (&pad->priv->activation_cond);
GST_OBJECT_UNLOCK (pad);
goto exit;
}
......@@ -3425,6 +3468,16 @@ probe_hook_marshal (GHook * hook, ProbeMarshall * data)
if ((flags & GST_PAD_PROBE_TYPE_SCHEDULING & type) == 0)
goto no_match;
if (G_UNLIKELY (data->handled)) {
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"probe previously returned HANDLED, not calling again");
goto no_match;
} else if (G_UNLIKELY (data->dropped)) {
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"probe previously returned DROPPED, not calling again");
goto no_match;
}
if (type & GST_PAD_PROBE_TYPE_PUSH) {
/* one of the data types for non-idle probes */
if ((type & GST_PAD_PROBE_TYPE_IDLE) == 0
......@@ -3806,6 +3859,8 @@ push_sticky (GstPad * pad, PadEvent * ev, gpointer user_data)
} else {
data->ret = gst_pad_push_event_unchecked (pad, gst_event_ref (event),
GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM);
if (data->ret == GST_FLOW_CUSTOM_SUCCESS_1)
data->ret = GST_FLOW_OK;
}
switch (data->ret) {
......@@ -4446,6 +4501,10 @@ gst_pad_push_data (GstPad * pad, GstPadProbeType type, void *data)
/* do post-blocking probes */
PROBE_HANDLE (pad, type, data, probe_stopped, probe_handled);
/* recheck sticky events because the probe might have cause a relink */
if (G_UNLIKELY ((ret = check_sticky (pad, NULL))) != GST_FLOW_OK)
goto events_error;
if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
goto not_linked;
......@@ -5230,6 +5289,17 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
}
PROBE_PUSH (pad, type | GST_PAD_PROBE_TYPE_PUSH |
GST_PAD_PROBE_TYPE_BLOCK, event, probe_stopped);
/* recheck sticky events because the probe might have cause a relink */
if (GST_PAD_HAS_PENDING_EVENTS (pad) && GST_PAD_IS_SRC (pad)
&& (GST_EVENT_IS_SERIALIZED (event)
|| GST_EVENT_IS_STICKY (event))) {
PushStickyData data = { GST_FLOW_OK, FALSE, event };
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_PENDING_EVENTS);
/* Push all sticky events before our current one
* that have changed */
events_foreach (pad, sticky_changed, &data);
}
break;
}
}
......@@ -6052,6 +6122,9 @@ gst_pad_pause_task (GstPad * pad)
if (task == NULL)
goto no_task;
res = gst_task_set_state (task, GST_TASK_PAUSED);
/* unblock activation waits if any */
pad->priv->in_activation = FALSE;
g_cond_broadcast (&pad->priv->activation_cond);
GST_OBJECT_UNLOCK (pad);
/* wait for task function to finish, this lock is recursive so it does nothing
......@@ -6137,6 +6210,9 @@ gst_pad_stop_task (GstPad * pad)
goto no_task;
GST_PAD_TASK (pad) = NULL;
res = gst_task_set_state (task, GST_TASK_STOPPED);
/* unblock activation waits if any */
pad->priv->in_activation = FALSE;
g_cond_broadcast (&pad->priv->activation_cond);
GST_OBJECT_UNLOCK (pad);
GST_PAD_STREAM_LOCK (pad);
......
......@@ -45,26 +45,6 @@
#include "parse/types.h"
#endif
static GstParseContext *
gst_parse_context_copy (const GstParseContext * context)
{
GstParseContext *ret = NULL;
#ifndef GST_DISABLE_PARSE
ret = gst_parse_context_new ();
if (context) {
GQueue missing_copy = G_QUEUE_INIT;
GList *l;
for (l = context->missing_elements; l != NULL; l = l->next)
g_queue_push_tail (&missing_copy, g_strdup ((const gchar *) l->data));
ret->missing_elements = missing_copy.head;
}
#endif
return ret;
}
G_DEFINE_BOXED_TYPE (GstParseContext, gst_parse_context,
(GBoxedCopyFunc) gst_parse_context_copy,
(GBoxedFreeFunc) gst_parse_context_free);
......@@ -113,6 +93,34 @@ gst_parse_context_new (void)
#endif
}
/**
* gst_parse_context_copy:
* @context: a #GstParseContext
*
* Copies the @context.
*
* Returns: (transfer full): A copied #GstParseContext
*/
GstParseContext *
gst_parse_context_copy (const GstParseContext * context)
{
GstParseContext *ret = NULL;
#ifndef GST_DISABLE_PARSE
ret = gst_parse_context_new ();
if (context) {
GQueue missing_copy = G_QUEUE_INIT;
GList *l;
for (l = context->missing_elements; l != NULL; l = l->next)
g_queue_push_tail (&missing_copy, g_strdup ((const gchar *) l->data));
ret->missing_elements = missing_copy.head;
}
#endif
return ret;
}
/**
* gst_parse_context_free:
* @context: (transfer full): a #GstParseContext
......
......@@ -102,6 +102,9 @@ gchar ** gst_parse_context_get_missing_elements (GstParseContext * cont
void gst_parse_context_free (GstParseContext * context);
GST_EXPORT
GstParseContext * gst_parse_context_copy (const GstParseContext * context);
/* parse functions */
......
......@@ -667,7 +667,7 @@ static GMutex gst_plugin_loading_mutex;
/**
* gst_plugin_load_file:
* @filename: the plugin filename to load
* @filename: (type filename): the plugin filename to load
* @error: pointer to a %NULL-valued GError
*
* Loads the given plugin and refs it. Caller needs to unref after use.
......@@ -913,7 +913,7 @@ gst_plugin_get_description (GstPlugin * plugin)
*
* get the filename of the plugin
*
* Returns: the filename of the plugin
* Returns: (type filename): the filename of the plugin
*/
const gchar *
gst_plugin_get_filename (GstPlugin * plugin)
......@@ -1303,7 +1303,7 @@ gst_plugin_load (GstPlugin * plugin)
GstPlugin *newplugin;
if (gst_plugin_is_loaded (plugin)) {
return plugin;
return gst_object_ref (plugin);
}
if (!(newplugin = gst_plugin_load_file (plugin->filename, &error)))
......@@ -1733,15 +1733,15 @@ gst_plugin_ext_dep_equals (GstPluginDep * dep, const gchar ** env_vars,
/**
* gst_plugin_add_dependency:
* @plugin: a #GstPlugin
* @env_vars: (allow-none): %NULL-terminated array of environment variables affecting the
* @env_vars: (allow-none) (array zero-terminated=1): %NULL-terminated array of environment variables affecting the
* feature set of the plugin (e.g. an environment variable containing
* paths where to look for additional modules/plugins of a library),
* or %NULL. Environment variable names may be followed by a path component
* which will be added to the content of the environment variable, e.g.
* "HOME/.mystuff/plugins".
* @paths: (allow-none): %NULL-terminated array of directories/paths where dependent files
* @paths: (allow-none) (array zero-terminated=1): %NULL-terminated array of directories/paths where dependent files
* may be, or %NULL.
* @names: (allow-none): %NULL-terminated array of file names (or file name suffixes,
* @names: (allow-none) (array zero-terminated=1): %NULL-terminated array of file names (or file name suffixes,
* depending on @flags) to be used in combination with the paths from
* @paths and/or the paths extracted from the environment variables in
* @env_vars, or %NULL.
......
......@@ -705,9 +705,9 @@ had_parent:
*
* Get the structure of a query.
*
* Returns: (transfer none): the #GstStructure of the query. The structure is
* still owned by the query and will therefore be freed when the query
* is unreffed.
* Returns: (transfer none) (nullable): the #GstStructure of the query. The
* structure is still owned by the query and will therefore be freed when the
* query is unreffed.
*/
const GstStructure *
gst_query_get_structure (GstQuery * query)
......@@ -731,10 +731,21 @@ gst_query_get_structure (GstQuery * query)
GstStructure *
gst_query_writable_structure (GstQuery * query)
{
GstStructure *structure;
g_return_val_if_fail (GST_IS_QUERY (query), NULL);
g_return_val_if_fail (gst_query_is_writable (query), NULL);
return GST_QUERY_STRUCTURE (query);
structure = GST_QUERY_STRUCTURE (query);
if (structure == NULL) {
structure =
gst_structure_new_id_empty (gst_query_type_to_quark (GST_QUERY_TYPE
(query)));
gst_structure_set_parent_refcount (structure, &query->mini_object.refcount);
GST_QUERY_STRUCTURE (query) = structure;
}
return structure;
}
/**
......
......@@ -1369,7 +1369,7 @@ gst_registry_scan_path_internal (GstRegistryScanContext * context,
/**
* gst_registry_scan_path:
* @registry: the registry to add found plugins to
* @path: the path to scan
* @path: (type filename): the path to scan
*
* Scan the given path for plugins to add to the registry. The syntax of the
* path is specific to the registry.
......
......@@ -709,6 +709,7 @@ gst_registry_chunks_load_feature (GstRegistry * registry, gchar ** in,
} else if (GST_IS_DYNAMIC_TYPE_FACTORY (feature)) {
GstRegistryChunkDynamicTypeFactory *tmp;
align (*in);
unpack_element (*in, tmp, GstRegistryChunkDynamicTypeFactory, end, fail);
pf = (GstRegistryChunkPluginFeature *) tmp;
......@@ -758,6 +759,7 @@ gst_registry_chunks_load_plugin_dep_strv (gchar ** in, gchar * end, guint n)
return arr;
fail:
GST_INFO ("Reading plugin dependency strings failed");
g_strfreev (arr);
return NULL;
}
......
......@@ -190,7 +190,7 @@ gst_segment_init (GstSegment * segment, GstFormat format)
* @start: the seek start value
* @stop_type: the seek method
* @stop: the seek stop value
* @update: boolean holding whether position was updated.
* @update: (out) (allow-none): boolean holding whether position was updated.
*
* Update the segment structure with the field values of a seek event (see
* gst_event_new_seek()).
......@@ -379,7 +379,7 @@ gst_segment_do_seek (GstSegment * segment, gdouble rate,
* @segment: a #GstSegment structure.
* @format: the format of the segment.
* @position: the position in the segment
* @stream_time: result stream-time
* @stream_time: (out): result stream-time
*
* Translate @position to the total stream time using the currently configured
* segment. Compared to gst_segment_to_stream_time() this function can return
......@@ -537,7 +537,7 @@ gst_segment_to_stream_time (const GstSegment * segment, GstFormat format,
* @segment: a #GstSegment structure.
* @format: the format of the segment.
* @stream_time: the stream-time
* @position: the resulting position in the segment
* @position: (out): the resulting position in the segment
*
* Translate @stream_time to the segment position using the currently configured
* segment. Compared to gst_segment_position_from_stream_time() this function can
......@@ -696,7 +696,7 @@ gst_segment_position_from_stream_time (const GstSegment * segment,
* @segment: a #GstSegment structure.
* @format: the format of the segment.
* @position: the position in the segment
* @running_time: result running-time
* @running_time: (out) (allow-none): result running-time
*
* Translate @position to the total running time using the currently configured
* segment. Compared to gst_segment_to_running_time() this function can return
......@@ -971,7 +971,7 @@ gst_segment_position_from_running_time (const GstSegment * segment,
* @segment: a #GstSegment structure.
* @format: the format of the segment.
* @running_time: the running-time
* @position: the resulting position in the segment
* @position: (out): the resulting position in the segment
*
* Translate @running_time to the segment position using the currently configured
* segment. Compared to gst_segment_position_from_running_time() this function can
......
......@@ -51,6 +51,8 @@ G_BEGIN_DECLS
* Note that this is a flag, and therefore users should not assume it
* will be a single value. Do not use the equality operator for checking
* whether a stream is of a certain type.
*
* Since: 1.10
*/
typedef enum {
GST_STREAM_TYPE_UNKNOWN = 1 << 0,
......@@ -81,6 +83,8 @@ typedef struct _GstStreamPrivate GstStreamPrivate;
*
* Elements can subclass a #GstStream for internal usage (to contain information
* pertinent to streams of data).
*
* Since: 1.10
*/
struct _GstStream {
GstObject object;
......
......@@ -293,7 +293,7 @@ gst_system_clock_get_property (GObject * object, guint prop_id, GValue * value,
/**
* gst_system_clock_set_default:
* @new_clock: a #GstClock
* @new_clock: (allow-none): a #GstClock
*
* Sets the default system clock that can be obtained with
* gst_system_clock_obtain().
......
......@@ -249,21 +249,6 @@ escape_string_internal (const gchar * string, UnsafeCharacterSet mask)
return result;
}
/* escape_string:
* @string: string to be escaped
*
* Escapes @string, replacing any and all special characters
* with equivalent escape sequences.
*
* Return value: a newly allocated string equivalent to @string
* but with all special characters escaped
**/
static gchar *
escape_string (const gchar * string)
{
return escape_string_internal (string, UNSAFE_ALL);
}
static int
hex_to_int (gchar c)
{
......@@ -522,7 +507,7 @@ gst_uri_construct (const gchar * protocol, const gchar * location)
g_return_val_if_fail (location != NULL, NULL);
proto_lowercase = g_ascii_strdown (protocol, -1);
escaped = escape_string (location);
escaped = escape_string_internal (location, UNSAFE_PATH);
retval = g_strdup_printf ("%s://%s", proto_lowercase, escaped);
g_free (escaped);
g_free (proto_lowercase);
......
......@@ -4252,6 +4252,8 @@ gst_calculate_linear_regression (const GstClockTime * xy,
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;
}
......@@ -4302,7 +4304,7 @@ gst_calculate_linear_regression (const GstClockTime * xy,
tmp /= 4;
} while (G_MAXINT64 - sxx <= tmp);
break;
} else if (G_UNLIKELY (tmp < 0 && sxx < 0 && (G_MAXINT64 - sxx >= tmp))) {
} else if (G_UNLIKELY (tmp < 0 && sxx < 0 && (G_MININT64 - sxx >= tmp))) {
do {
/* Drop some precision and restart */
pshift++;
......@@ -4321,7 +4323,7 @@ gst_calculate_linear_regression (const GstClockTime * xy,
tmp /= 4;
} while (G_MAXINT64 - syy <= tmp);
break;
} else if (G_UNLIKELY (tmp < 0 && syy < 0 && (G_MAXINT64 - syy >= tmp))) {
} else if (G_UNLIKELY (tmp < 0 && syy < 0 && (G_MININT64 - syy >= tmp))) {
do {
pshift++;
syy /= 4;
......
......@@ -276,7 +276,10 @@ _gst_value_serialize_g_value_array (const GValue * value, const gchar * begin,
GString *s;
GValue *v;
gchar *s_val;
guint alen = array->n_values;
guint alen = 0;
if (array)
alen = array->n_values;
/* estimate minimum string length to minimise re-allocs in GString */
s = g_string_sized_new (2 + (6 * alen) + 2);
......
......@@ -42,7 +42,8 @@ G_BEGIN_DECLS
* ]|
*
*/
#define GST_MAKE_FOURCC(a,b,c,d) ((guint32)((a)|(b)<<8|(c)<<16|(d)<<24))
#define GST_MAKE_FOURCC(a,b,c,d) \
( (guint32)(a) | ((guint32) (b)) << 8 | ((guint32) (c)) << 16 | ((guint32) (d)) << 24 )
/**
* GST_STR_FOURCC:
......
......@@ -36,7 +36,57 @@ hierarchy, and a set of media-agnostic core elements.
<location rdf:resource="git://anongit.freedesktop.org/gstreamer/gstreamer"/>
<browse rdf:resource="http://cgit.freedesktop.org/gstreamer/gstreamer"/>
</GitRepository>
</repository>
</repository>
<release>
<Version>
<revision>1.12.5</revision>
<branch>1.12</branch>
<name></name>
<created>2018-03-28</created>
<file-release rdf:resource="https://gstreamer.freedesktop.org/src/gstreamer/gstreamer-1.12.5.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.12.4</revision>
<branch>1.12</branch>
<name></name>
<created>2017-12-07</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-1.12.4.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.12.3</revision>
<branch>1.12</branch>
<name></name>
<created>2017-09-18</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-1.12.3.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.12.2</revision>
<branch>1.12</branch>
<name></name>
<created>2017-07-14</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-1.12.2.tar.xz" />
</Version>
</release>
<release>
<Version>
<revision>1.12.1</revision>
<branch>1.12</branch>
<name></name>
<created>2017-06-20</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-1.12.1.tar.xz" />
</Version>
</release>
<release>
<Version>
......
......@@ -655,7 +655,7 @@ gst_base_parse_get_property (GObject * object, guint prop_id, GValue * value,
}
}
static GstBaseParseFrame *
GstBaseParseFrame *
gst_base_parse_frame_copy (GstBaseParseFrame * frame)
{
GstBaseParseFrame *copy;
......@@ -1084,7 +1084,8 @@ gst_base_parse_negotiate_default_caps (GstBaseParse * parse)
GST_INFO_OBJECT (parse,
"Chose default caps %" GST_PTR_FORMAT " for initial gap", default_caps);
gst_caps_unref (sinkcaps);
if (sinkcaps)
gst_caps_unref (sinkcaps);
gst_caps_unref (caps);
return default_caps;
......@@ -1822,7 +1823,8 @@ gst_base_parse_update_bitrates (GstBaseParse * parse, GstBaseParseFrame * frame)
if (parse->priv->bitrate) {
parse->priv->avg_bitrate = parse->priv->bitrate;
/* spread this (confirmed) info ASAP */