mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-05 23:18:47 +00:00
More state change fixes.
Original commit message from CVS: More state change fixes. Added/fixed some testcases. Threadsafety fixes.
This commit is contained in:
parent
83156b4a9d
commit
864a9acf69
34 changed files with 1975 additions and 152 deletions
62
ChangeLog
62
ChangeLog
|
@ -1,3 +1,65 @@
|
|||
2005-01-18 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* docs/design/part-states.txt:
|
||||
* gst/elements/gstfakesrc.c: (gst_fakesrc_loop),
|
||||
(gst_fakesrc_activate):
|
||||
* gst/elements/gstfilesrc.c: (gst_filesrc_getrange),
|
||||
(gst_filesrc_open_file), (gst_filesrc_activate),
|
||||
(filesrc_find_peek), (filesrc_find_suggest),
|
||||
(gst_filesrc_type_find):
|
||||
* gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock),
|
||||
(gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func),
|
||||
(gst_bin_iterate_elements), (bin_element_is_sink),
|
||||
(gst_bin_get_state), (gst_bin_change_state),
|
||||
(gst_bin_get_by_name_recurse_up):
|
||||
* gst/gstbus.c: (gst_bus_dispose), (gst_bus_new), (gst_bus_post),
|
||||
(gst_bus_set_sync_handler), (gst_bus_create_watch), (bus_destroy),
|
||||
(gst_bus_add_watch_full):
|
||||
* gst/gstbus.h:
|
||||
* gst/gstclock.c: (gst_clock_id_ref), (gst_clock_id_unref),
|
||||
(gst_clock_id_compare_func), (gst_clock_id_wait),
|
||||
(gst_clock_id_wait_async), (gst_clock_init), (gst_clock_get_time):
|
||||
* gst/gstcpu.c: (_gst_cpu_initialize_i386), (gst_cpu_get_flags):
|
||||
* gst/gstdata.c: (gst_data_is_writable), (gst_data_copy_on_write):
|
||||
* gst/gstelement.c: (gst_element_class_init),
|
||||
(gst_element_add_pad), (gst_element_remove_pad),
|
||||
(gst_element_get_static_pad), (gst_element_is_locked_state),
|
||||
(gst_element_get_state_func), (gst_element_abort_state),
|
||||
(gst_element_set_state), (gst_element_pads_activate),
|
||||
(gst_element_change_state), (gst_element_dispose),
|
||||
(gst_element_finalize), (gst_element_get_scheduler):
|
||||
* gst/gstelement.h:
|
||||
* gst/gstobject.c: (gst_object_class_init), (gst_object_ref),
|
||||
(gst_object_unref), (gst_object_sink), (gst_object_replace),
|
||||
(gst_object_dispose), (gst_object_dispatch_properties_changed),
|
||||
(gst_object_set_name), (gst_object_set_parent),
|
||||
(gst_object_unparent), (gst_object_check_uniqueness),
|
||||
(gst_object_get_path_string):
|
||||
* gst/gstpad.h:
|
||||
* gst/gstpipeline.c: (is_eos), (pipeline_bus_handler),
|
||||
(gst_pipeline_change_state):
|
||||
* gst/gstplugin.c:
|
||||
* gst/gsttypes.h:
|
||||
* gst/gstutils.c: (gst_element_finish_preroll),
|
||||
(gst_element_get_compatible_pad_filtered),
|
||||
(gst_element_state_get_name), (gst_element_link_pads_filtered),
|
||||
(gst_element_unlink):
|
||||
* testsuite/states/.cvsignore:
|
||||
* testsuite/states/Makefile.am:
|
||||
* testsuite/states/locked.c: (message_received), (main):
|
||||
* testsuite/states/parent.c: (main):
|
||||
* testsuite/states/test1.c: (message_received), (set_state),
|
||||
(get_state), (commit_callback), (abort_callback), (main):
|
||||
* testsuite/states/test2.c: (message_received), (set_state),
|
||||
(get_state), (main):
|
||||
* testsuite/states/test3.c: (message_received), (set_state),
|
||||
(get_state), (main):
|
||||
* testsuite/states/test4.c: (message_received), (set_state),
|
||||
(get_state), (commit_callback), (abort_callback), (main):
|
||||
More state change fixes.
|
||||
Added/fixed some testcases.
|
||||
Threadsafety fixes.
|
||||
|
||||
2005-01-12 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock),
|
||||
|
|
|
@ -59,7 +59,7 @@ The _set_state() function can return 3 possible values:
|
|||
|
||||
In the case of an async state change, it is not possible to proceed to the next
|
||||
state until the current state change completed. After receiving an ASYNC return
|
||||
value, you can use _element_get_state() to poll the status of the plugin.
|
||||
value, you can use _element_get_state() to poll the status of the element.
|
||||
|
||||
When setting the state of an element, the PENDING_STATE is set to the required
|
||||
state and the STATE_ERROR flag is cleared. Then the state change function of the
|
||||
|
|
|
@ -180,6 +180,7 @@ static gboolean gst_filesrc_srcpad_query (GstPad * pad, GstQueryType type,
|
|||
static gboolean gst_filesrc_activate (GstPad * pad, GstActivateMode mode);
|
||||
static GstElementStateReturn gst_filesrc_change_state (GstElement * element);
|
||||
|
||||
static GstCaps *gst_filesrc_type_find (GstFileSrc * src);
|
||||
static void gst_filesrc_uri_handler_init (gpointer g_iface,
|
||||
gpointer iface_data);
|
||||
|
||||
|
@ -854,6 +855,22 @@ gst_filesrc_open_file (GstFileSrc * src)
|
|||
src->curoffset = 0;
|
||||
|
||||
GST_FLAG_SET (src, GST_FILESRC_OPEN);
|
||||
|
||||
{
|
||||
GstCaps *caps;
|
||||
guint64 offset;
|
||||
guint length;
|
||||
|
||||
offset = src->curoffset;
|
||||
length = src->block_size;
|
||||
|
||||
caps = gst_filesrc_type_find (src);
|
||||
gst_pad_set_caps (src->srcpad, caps);
|
||||
|
||||
src->curoffset = offset;
|
||||
src->block_size = length;
|
||||
}
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1122,6 +1139,89 @@ error:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GstFileSrc *src;
|
||||
guint best_probability;
|
||||
GstCaps *caps;
|
||||
|
||||
GstBuffer *buffer;
|
||||
}
|
||||
FileSrcTypeFind;
|
||||
|
||||
static guint8 *
|
||||
filesrc_find_peek (gpointer data, gint64 offset, guint size)
|
||||
{
|
||||
FileSrcTypeFind *find;
|
||||
GstBuffer *buffer;
|
||||
GstFileSrc *src;
|
||||
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
|
||||
find = (FileSrcTypeFind *) data;
|
||||
src = find->src;
|
||||
|
||||
if (offset < 0) {
|
||||
offset += src->filelen;
|
||||
}
|
||||
|
||||
buffer = NULL;
|
||||
gst_filesrc_getrange (src->srcpad, offset, size, &buffer);
|
||||
|
||||
if (find->buffer) {
|
||||
gst_buffer_unref (find->buffer);
|
||||
}
|
||||
find->buffer = buffer;
|
||||
|
||||
return GST_BUFFER_DATA (buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
filesrc_find_suggest (gpointer data, guint probability, const GstCaps * caps)
|
||||
{
|
||||
FileSrcTypeFind *find = (FileSrcTypeFind *) data;
|
||||
|
||||
if (probability > find->best_probability) {
|
||||
gst_caps_replace (&find->caps, gst_caps_copy (caps));
|
||||
find->best_probability = probability;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static GstCaps *
|
||||
gst_filesrc_type_find (GstFileSrc * src)
|
||||
{
|
||||
GstTypeFind gst_find;
|
||||
FileSrcTypeFind find;
|
||||
GList *walk, *type_list = NULL;
|
||||
GstCaps *result = NULL;
|
||||
|
||||
walk = type_list = gst_type_find_factory_get_list ();
|
||||
|
||||
find.src = src;
|
||||
find.best_probability = 0;
|
||||
find.caps = NULL;
|
||||
gst_find.data = &find;
|
||||
gst_find.peek = filesrc_find_peek;
|
||||
gst_find.suggest = filesrc_find_suggest;
|
||||
gst_find.get_length = NULL;
|
||||
|
||||
while (walk) {
|
||||
GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
|
||||
|
||||
gst_type_find_factory_call_function (factory, &gst_find);
|
||||
if (find.best_probability >= GST_TYPE_FIND_MAXIMUM)
|
||||
break;
|
||||
walk = g_list_next (walk);
|
||||
}
|
||||
|
||||
if (find.best_probability > 0)
|
||||
result = find.caps;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*** GSTURIHANDLER INTERFACE *************************************************/
|
||||
|
||||
static guint
|
||||
|
|
83
gst/gstbin.c
83
gst/gstbin.c
|
@ -19,6 +19,8 @@
|
|||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
|
||||
#include "gst_private.h"
|
||||
|
@ -581,15 +583,31 @@ bin_element_is_sink (GstElement * child, GstBin * bin)
|
|||
GList *pads;
|
||||
gboolean connected_src = FALSE;
|
||||
|
||||
pads = child->srcpads;
|
||||
while (pads) {
|
||||
GstPad *pad = GST_PAD (pads->data);
|
||||
for (pads = child->srcpads; pads; pads = g_list_next (pads)) {
|
||||
GstPad *peer;
|
||||
|
||||
if (GST_PAD_IS_LINKED (pad)) {
|
||||
connected_src = TRUE;
|
||||
break;
|
||||
peer = gst_pad_get_peer (GST_PAD_CAST (pads->data));
|
||||
if (peer) {
|
||||
GstElement *parent;
|
||||
|
||||
parent = gst_pad_get_parent (peer);
|
||||
if (parent) {
|
||||
GstObject *grandparent;
|
||||
|
||||
grandparent = gst_object_get_parent (GST_OBJECT_CAST (parent));
|
||||
if (grandparent == GST_OBJECT_CAST (bin)) {
|
||||
connected_src = TRUE;
|
||||
}
|
||||
if (grandparent) {
|
||||
gst_object_unref (GST_OBJECT_CAST (grandparent));
|
||||
}
|
||||
gst_object_unref (GST_OBJECT_CAST (parent));
|
||||
}
|
||||
gst_object_unref (GST_OBJECT_CAST (peer));
|
||||
if (connected_src) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pads = g_list_next (pads);
|
||||
}
|
||||
|
||||
if (connected_src) {
|
||||
|
@ -598,7 +616,7 @@ bin_element_is_sink (GstElement * child, GstBin * bin)
|
|||
GST_OBJECT_NAME (child));
|
||||
} else {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
|
||||
"adding child %s as sink since it has unlinked source pads",
|
||||
"adding child %s as sink since it has unlinked source pads in this bin",
|
||||
GST_OBJECT_NAME (child));
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -640,8 +658,8 @@ gst_bin_iterate_sinks (GstBin * bin)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* this functions loops over all children, as soon as one is
|
||||
* still performing the state change, FALSE is returned.
|
||||
/* this functions loops over all children, as soon as one does
|
||||
* not return SUCCESS, we return that value.
|
||||
*
|
||||
* MT safe
|
||||
*/
|
||||
|
@ -718,7 +736,17 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* this function is called with the STATE_LOCK held.
|
||||
/* this function is called with the STATE_LOCK held. It works
|
||||
* as follows:
|
||||
*
|
||||
* 1) put all sink elements on the queue.
|
||||
* 2) change state of elements in queue, put linked elements to queue.
|
||||
* 3) while queue not empty goto 2)
|
||||
*
|
||||
* This will effectively change the state of all elements in the bin
|
||||
* from the sinks to the sources. We have to change the states this
|
||||
* way so that when a source element pushes data, the downstream element
|
||||
* is in the right state to receive the data.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
|
@ -735,6 +763,7 @@ gst_bin_change_state (GstElement * element)
|
|||
|
||||
bin = GST_BIN (element);
|
||||
|
||||
/* we don't need to take the STATE_LOCK, it is already taken */
|
||||
old_state = GST_STATE (element);
|
||||
pending = GST_STATE_PENDING (element);
|
||||
|
||||
|
@ -791,7 +820,7 @@ restart:
|
|||
GST_LOCK (qelement);
|
||||
pads = qelement->sinkpads;
|
||||
while (pads) {
|
||||
GstPad *pad = GST_PAD (pads->data);
|
||||
GstPad *pad = GST_PAD_CAST (pads->data);
|
||||
GstPad *peer;
|
||||
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
|
||||
|
@ -799,20 +828,32 @@ restart:
|
|||
|
||||
peer = gst_pad_get_peer (pad);
|
||||
if (peer) {
|
||||
GstElement *peer_elem;
|
||||
GstObject *peer_elem;
|
||||
|
||||
/* FIXME does not work for bins etc */
|
||||
peer_elem = GST_ELEMENT (gst_object_get_parent (GST_OBJECT (peer)));
|
||||
peer_elem = gst_object_get_parent (GST_OBJECT_CAST (peer));
|
||||
|
||||
if (peer_elem) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
|
||||
"adding element %s to queue", GST_ELEMENT_NAME (peer_elem));
|
||||
GstObject *parent;
|
||||
|
||||
/* was reffed before pushing on the queue by the
|
||||
* gst_object_get_parent() call we used to get the element. */
|
||||
g_queue_push_tail (elem_queue, peer_elem);
|
||||
/* see if this element is in the bin we are currently handling */
|
||||
parent = gst_object_get_parent (GST_OBJECT_CAST (peer_elem));
|
||||
if (parent && parent == GST_OBJECT_CAST (bin)) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
|
||||
"adding element %s to queue", GST_ELEMENT_NAME (peer_elem));
|
||||
|
||||
/* was reffed before pushing on the queue by the
|
||||
* gst_object_get_parent() call we used to get the element. */
|
||||
g_queue_push_tail (elem_queue, peer_elem);
|
||||
} else {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
|
||||
"not adding element %s to queue, it is in another bin",
|
||||
GST_ELEMENT_NAME (peer_elem));
|
||||
}
|
||||
if (parent) {
|
||||
gst_object_unref (GST_OBJECT_CAST (parent));
|
||||
}
|
||||
}
|
||||
gst_object_unref (GST_OBJECT (peer));
|
||||
gst_object_unref (GST_OBJECT_CAST (peer));
|
||||
} else {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
|
||||
"pad %s:%s does not have a peer", GST_DEBUG_PAD_NAME (pad));
|
||||
|
|
44
gst/gstbus.c
44
gst/gstbus.c
|
@ -125,7 +125,10 @@ gst_bus_dispose (GObject * object)
|
|||
close (bus->control_socket[0]);
|
||||
close (bus->control_socket[1]);
|
||||
|
||||
g_async_queue_unref (bus->queue);
|
||||
if (bus->queue) {
|
||||
g_async_queue_unref (bus->queue);
|
||||
bus->queue = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
@ -160,6 +163,16 @@ gst_bus_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
GstBus *
|
||||
gst_bus_new (void)
|
||||
{
|
||||
GstBus *result;
|
||||
|
||||
result = g_object_new (gst_bus_get_type (), NULL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_bus_post:
|
||||
* @bus: a #GstBus to post on
|
||||
|
@ -167,20 +180,29 @@ gst_bus_get_property (GObject * object, guint prop_id,
|
|||
*
|
||||
* Post a message on the given bus.
|
||||
*
|
||||
* Returns: the new #GstBuffer.
|
||||
* Returns: TRUE if the message could be posted.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
gboolean
|
||||
gst_bus_post (GstBus * bus, GstMessage * message)
|
||||
{
|
||||
gchar c;
|
||||
GstBusSyncReply reply = GST_BUS_PASS;
|
||||
GstBusSyncHandler handler;
|
||||
gpointer handler_data;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
|
||||
g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
|
||||
|
||||
GST_LOCK (bus);
|
||||
handler = bus->sync_handler;
|
||||
handler_data = bus->sync_handler_data;
|
||||
GST_UNLOCK (bus);
|
||||
|
||||
/* first call the sync handler if it is installed */
|
||||
if (bus->sync_handler) {
|
||||
reply = bus->sync_handler (bus, message, bus->sync_handler_data);
|
||||
if (handler) {
|
||||
reply = handler (bus, message, handler_data);
|
||||
}
|
||||
|
||||
/* now see what we should do with the message */
|
||||
|
@ -236,6 +258,8 @@ gst_bus_post (GstBus * bus, GstMessage * message)
|
|||
* handled.
|
||||
*
|
||||
* Returns: TRUE if there are messages on the bus to be handled.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
gboolean
|
||||
gst_bus_have_pending (GstBus * bus)
|
||||
|
@ -257,6 +281,8 @@ gst_bus_have_pending (GstBus * bus)
|
|||
*
|
||||
* Returns: The #GstMessage that is on the bus or NULL when there are no
|
||||
* messages available.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
GstMessage *
|
||||
gst_bus_pop (GstBus * bus)
|
||||
|
@ -287,8 +313,10 @@ gst_bus_set_sync_handler (GstBus * bus, GstBusSyncHandler func, gpointer data)
|
|||
{
|
||||
g_return_if_fail (GST_IS_BUS (bus));
|
||||
|
||||
GST_LOCK (bus);
|
||||
bus->sync_handler = func;
|
||||
bus->sync_handler_data = data;
|
||||
GST_UNLOCK (bus);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -306,6 +334,8 @@ gst_bus_create_watch (GstBus * bus)
|
|||
|
||||
g_return_val_if_fail (GST_IS_BUS (bus), NULL);
|
||||
|
||||
/* FIXME, we need to ref the bus and unref it when the source
|
||||
* is destroyed */
|
||||
source = g_io_create_watch (bus->io_channel, G_IO_IN);
|
||||
|
||||
return source;
|
||||
|
@ -342,6 +372,7 @@ bus_destroy (GstBusWatch * watch)
|
|||
if (watch->notify) {
|
||||
watch->notify (watch->user_data);
|
||||
}
|
||||
gst_object_unref (GST_OBJECT_CAST (watch->bus));
|
||||
g_free (watch);
|
||||
}
|
||||
|
||||
|
@ -352,6 +383,8 @@ bus_destroy (GstBusWatch * watch)
|
|||
* Adds the bus to the mainloop with the given priority.
|
||||
*
|
||||
* Returns: The event source id.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
guint
|
||||
gst_bus_add_watch_full (GstBus * bus, gint priority,
|
||||
|
@ -364,6 +397,7 @@ gst_bus_add_watch_full (GstBus * bus, gint priority,
|
|||
|
||||
watch = g_new (GstBusWatch, 1);
|
||||
|
||||
gst_object_ref (GST_OBJECT_CAST (bus));
|
||||
watch->source = gst_bus_create_watch (bus);
|
||||
watch->bus = bus;
|
||||
watch->priority = priority;
|
||||
|
@ -390,6 +424,8 @@ gst_bus_add_watch_full (GstBus * bus, gint priority,
|
|||
* Adds the bus to the mainloop with the default priority.
|
||||
*
|
||||
* Returns: The event source id.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
guint
|
||||
gst_bus_add_watch (GstBus * bus, GstBusHandler handler, gpointer user_data)
|
||||
|
|
|
@ -73,6 +73,8 @@ struct _GstBusClass
|
|||
|
||||
GType gst_bus_get_type (void);
|
||||
|
||||
GstBus* gst_bus_new (void);
|
||||
|
||||
gboolean gst_bus_post (GstBus * bus, GstMessage * message);
|
||||
|
||||
gboolean gst_bus_have_pending (GstBus * bus);
|
||||
|
|
|
@ -490,6 +490,8 @@ gst_clock_set_resolution (GstClock * clock, guint64 resolution)
|
|||
* Get the accuracy of the clock.
|
||||
*
|
||||
* Returns: the resolution of the clock in microseconds.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
guint64
|
||||
gst_clock_get_resolution (GstClock * clock)
|
||||
|
|
17
gst/gstcpu.c
17
gst/gstcpu.c
|
@ -28,6 +28,7 @@
|
|||
#include "gstcpu.h"
|
||||
#include "gstinfo.h"
|
||||
|
||||
static GStaticMutex _cpu_mutex = G_STATIC_MUTEX_INIT;
|
||||
static guint32 _gst_cpu_flags = 0;
|
||||
|
||||
#if defined(HAVE_CPU_I386) && defined(__GNUC__)
|
||||
|
@ -89,7 +90,9 @@ _gst_cpu_initialize_i386 (gulong * flags, GString * featurelist)
|
|||
{
|
||||
gboolean AMD;
|
||||
gulong eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||
gboolean res = FALSE;
|
||||
|
||||
g_static_mutex_lock (&_cpu_mutex);
|
||||
gst_cpuid_i386 (0, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
|
||||
|
@ -124,13 +127,21 @@ _gst_cpu_initialize_i386 (gulong * flags, GString * featurelist)
|
|||
}
|
||||
*flags = eax;
|
||||
if (_gst_cpu_flags)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
res = TRUE;
|
||||
g_static_mutex_unlock (&_cpu_mutex);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
GstCPUFlags
|
||||
gst_cpu_get_flags (void)
|
||||
{
|
||||
return _gst_cpu_flags;
|
||||
GstCPUFlags res;
|
||||
|
||||
g_static_mutex_lock (&_cpu_mutex);
|
||||
res = _gst_cpu_flags;
|
||||
g_static_mutex_unlock (&_cpu_mutex);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -99,6 +99,8 @@ gst_data_dispose (GstData * data)
|
|||
* Returns: a copy of the data or NULL if the data cannot be copied.
|
||||
* The refcount of the original buffer is not changed so you should unref it
|
||||
* when you don't need it anymore.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
GstData *
|
||||
gst_data_copy (const GstData * data)
|
||||
|
@ -119,6 +121,8 @@ gst_data_copy (const GstData * data)
|
|||
*
|
||||
* Returns: FALSE if the given #GstData is potentially shared and needs to
|
||||
* be copied before it can be modified safely.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
gboolean
|
||||
gst_data_is_writable (GstData * data)
|
||||
|
@ -129,12 +133,12 @@ gst_data_is_writable (GstData * data)
|
|||
|
||||
refcount = gst_atomic_int_read (&data->refcount);
|
||||
|
||||
if (refcount > 1)
|
||||
return FALSE;
|
||||
if (GST_DATA_FLAG_IS_SET (data, GST_DATA_READONLY))
|
||||
return FALSE;
|
||||
/* if we have the only ref and the data is not readonly, we can
|
||||
* safely write */
|
||||
if (refcount == 1 && !GST_DATA_FLAG_IS_SET (data, GST_DATA_READONLY))
|
||||
return TRUE;
|
||||
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,6 +154,8 @@ gst_data_is_writable (GstData * data)
|
|||
*
|
||||
* The refcount of the passed @data is decreased when a copy is made, so
|
||||
* you are not supposed to use it anymore after a call to this function.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
GstData *
|
||||
gst_data_copy_on_write (GstData * data)
|
||||
|
@ -160,6 +166,8 @@ gst_data_copy_on_write (GstData * data)
|
|||
|
||||
refcount = gst_atomic_int_read (&data->refcount);
|
||||
|
||||
/* if we have the only ref and the data is not readonly, we can
|
||||
* safely write, so we return the input data */
|
||||
if (refcount == 1 && !GST_DATA_FLAG_IS_SET (data, GST_DATA_READONLY))
|
||||
return GST_DATA (data);
|
||||
|
||||
|
@ -180,6 +188,8 @@ gst_data_copy_on_write (GstData * data)
|
|||
* Increments the reference count of this data.
|
||||
*
|
||||
* Returns: the data
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
GstData *
|
||||
gst_data_ref (GstData * data)
|
||||
|
@ -203,6 +213,8 @@ gst_data_ref (GstData * data)
|
|||
* Increments the reference count of this data by the given number.
|
||||
*
|
||||
* Returns: the data
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
GstData *
|
||||
gst_data_ref_by_count (GstData * data, gint count)
|
||||
|
@ -230,6 +242,8 @@ gst_data_ref_by_count (GstData * data, gint count)
|
|||
* the pipeline takes ownership of the
|
||||
* data. When the data has been consumed by some element, it must unref() it.
|
||||
* Applications usually don't need to unref() @data.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
void
|
||||
gst_data_unref (GstData * data)
|
||||
|
|
144
gst/gstelement.c
144
gst/gstelement.c
|
@ -64,6 +64,7 @@ static void gst_element_base_class_init (gpointer g_class);
|
|||
static void gst_element_base_class_finalize (gpointer g_class);
|
||||
|
||||
static void gst_element_dispose (GObject * object);
|
||||
static void gst_element_finalize (GObject * object);
|
||||
|
||||
static GstElementStateReturn gst_element_change_state (GstElement * element);
|
||||
static GstElementStateReturn gst_element_get_state_func (GstElement * element,
|
||||
|
@ -137,6 +138,7 @@ gst_element_class_init (GstElementClass * klass)
|
|||
NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
|
||||
|
||||
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
|
||||
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_element_finalize);
|
||||
|
||||
#ifndef GST_DISABLE_LOADSAVE
|
||||
gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
|
||||
|
@ -457,6 +459,8 @@ gst_element_add_pad (GstElement * element, GstPad * pad)
|
|||
GST_OBJECT_CAST (element))))
|
||||
goto had_parent;
|
||||
|
||||
g_free (pad_name);
|
||||
|
||||
/* add it to the list */
|
||||
switch (gst_pad_get_direction (pad)) {
|
||||
case GST_PAD_SRC:
|
||||
|
@ -486,10 +490,9 @@ gst_element_add_pad (GstElement * element, GstPad * pad)
|
|||
/* emit the NEW_PAD signal */
|
||||
g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
|
||||
|
||||
g_free (pad_name);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERROR cases */
|
||||
name_exists:
|
||||
{
|
||||
g_critical ("Padname %s is not unique in element %s, not adding",
|
||||
|
@ -575,6 +578,8 @@ gst_element_remove_pad (GstElement * element, GstPad * pad)
|
|||
goto not_our_pad;
|
||||
GST_UNLOCK (pad);
|
||||
|
||||
g_free (pad_name);
|
||||
|
||||
/* FIXME, is this redundant with pad disposal? */
|
||||
if (GST_IS_REAL_PAD (pad)) {
|
||||
GstPad *peer = gst_pad_get_peer (pad);
|
||||
|
@ -619,12 +624,11 @@ gst_element_remove_pad (GstElement * element, GstPad * pad)
|
|||
|
||||
gst_object_unparent (GST_OBJECT (pad));
|
||||
|
||||
g_free (pad_name);
|
||||
|
||||
return TRUE;
|
||||
|
||||
not_our_pad:
|
||||
{
|
||||
/* FIXME, locking order? */
|
||||
GST_LOCK (element);
|
||||
g_critical ("Padname %s:%s does not belong to element %s when removing",
|
||||
GST_ELEMENT_NAME (GST_PAD_PARENT (pad)), GST_PAD_NAME (pad),
|
||||
|
@ -694,8 +698,8 @@ gst_element_get_static_pad (GstElement * element, const gchar * name)
|
|||
find =
|
||||
g_list_find_custom (element->pads, name, (GCompareFunc) pad_compare_name);
|
||||
if (find) {
|
||||
result = GST_PAD (find->data);
|
||||
gst_object_ref (GST_OBJECT (result));
|
||||
result = GST_PAD_CAST (find->data);
|
||||
gst_object_ref (GST_OBJECT_CAST (result));
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
|
@ -1476,8 +1480,7 @@ gst_element_is_locked_state (GstElement * element)
|
|||
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
|
||||
|
||||
GST_LOCK (element);
|
||||
/* be careful with the flag tests */
|
||||
result = !!GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
|
||||
result = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
|
||||
GST_UNLOCK (element);
|
||||
|
||||
return result;
|
||||
|
@ -1569,15 +1572,15 @@ gst_element_get_state_func (GstElement * element,
|
|||
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
|
||||
|
||||
GST_STATE_LOCK (element);
|
||||
/* we got an error, report immediatly */
|
||||
if (GST_STATE_ERROR (element))
|
||||
goto done;
|
||||
|
||||
old_pending = GST_STATE_PENDING (element);
|
||||
if (old_pending != GST_STATE_VOID_PENDING) {
|
||||
/* we have a pending state change, wait for it to complete */
|
||||
if (!GST_STATE_TIMED_WAIT (element, timeout)) {
|
||||
/* timeout triggered */
|
||||
if (state)
|
||||
*state = GST_STATE (element);
|
||||
if (pending)
|
||||
*pending = GST_STATE_PENDING (element);
|
||||
ret = GST_STATE_ASYNC;
|
||||
} else {
|
||||
/* could be success or failure */
|
||||
|
@ -1588,15 +1591,17 @@ gst_element_get_state_func (GstElement * element,
|
|||
}
|
||||
}
|
||||
}
|
||||
/* if nothing is pending anymore we can return TRUE and
|
||||
* set the values of the current and pending state */
|
||||
/* if nothing is pending anymore we can return SUCCESS */
|
||||
if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
|
||||
if (state)
|
||||
*state = GST_STATE (element);
|
||||
if (pending)
|
||||
*pending = GST_STATE_VOID_PENDING;
|
||||
ret = GST_STATE_SUCCESS;
|
||||
}
|
||||
|
||||
done:
|
||||
if (state)
|
||||
*state = GST_STATE (element);
|
||||
if (pending)
|
||||
*pending = GST_STATE_PENDING (element);
|
||||
|
||||
GST_STATE_UNLOCK (element);
|
||||
|
||||
return ret;
|
||||
|
@ -1672,6 +1677,7 @@ gst_element_abort_state (GstElement * element)
|
|||
"aborting state from %s to %s", gst_element_state_get_name (old_state),
|
||||
gst_element_state_get_name (pending));
|
||||
|
||||
/* flag error */
|
||||
GST_STATE_ERROR (element) = TRUE;
|
||||
|
||||
GST_STATE_BROADCAST (element);
|
||||
|
@ -1734,11 +1740,18 @@ gst_element_set_state (GstElement * element, GstElementState state)
|
|||
GstElementState current;
|
||||
GstElementStateReturn return_val = GST_STATE_SUCCESS;
|
||||
|
||||
oclass = GST_ELEMENT_GET_CLASS (element);
|
||||
|
||||
/* get the element state lock */
|
||||
GST_STATE_LOCK (element);
|
||||
|
||||
#if 0
|
||||
/* a state change is pending and we are not in error, the element is busy
|
||||
* with a state change and we cannot proceed.
|
||||
* FIXME, does not work for a bin.*/
|
||||
if (G_UNLIKELY (GST_STATE_PENDING (element) != GST_STATE_VOID_PENDING &&
|
||||
!GST_STATE_ERROR (element)))
|
||||
goto was_busy;
|
||||
#endif
|
||||
|
||||
/* clear the error flag */
|
||||
GST_STATE_ERROR (element) = FALSE;
|
||||
|
||||
|
@ -1748,6 +1761,8 @@ gst_element_set_state (GstElement * element, GstElementState state)
|
|||
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s",
|
||||
gst_element_state_get_name (current), gst_element_state_get_name (state));
|
||||
|
||||
oclass = GST_ELEMENT_GET_CLASS (element);
|
||||
|
||||
/* We always perform at least one state change, even if the
|
||||
* current state is equal to the required state. This is needed
|
||||
* for bins that sync their children. */
|
||||
|
@ -1798,8 +1813,7 @@ gst_element_set_state (GstElement * element, GstElementState state)
|
|||
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "commited state");
|
||||
break;
|
||||
default:
|
||||
/* somebody added a GST_STATE_ and forgot to do stuff here ! */
|
||||
g_assert_not_reached ();
|
||||
goto invalid_return;
|
||||
}
|
||||
/* get the current state of the element and see if we need to do more
|
||||
* state changes */
|
||||
|
@ -1813,15 +1827,35 @@ exit:
|
|||
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "exit state change");
|
||||
|
||||
return return_val;
|
||||
|
||||
/* ERROR */
|
||||
#if 0
|
||||
was_busy:
|
||||
{
|
||||
GST_STATE_UNLOCK (element);
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
|
||||
"was busy with a state change");
|
||||
|
||||
return GST_STATE_BUSY;
|
||||
}
|
||||
#endif
|
||||
invalid_return:
|
||||
{
|
||||
GST_STATE_UNLOCK (element);
|
||||
/* somebody added a GST_STATE_ and forgot to do stuff here ! */
|
||||
g_critical ("unkown return value from a state change function");
|
||||
return GST_STATE_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* is called with STATE_LOCK
|
||||
*
|
||||
* This function activates the pads of a given element.
|
||||
*
|
||||
* TODO: activates pads from src to sinks?
|
||||
*
|
||||
* */
|
||||
* TODO: activate pads from src to sinks?
|
||||
* move pad activate logic to GstPad because we also need this
|
||||
* when pads are added to elements?
|
||||
*/
|
||||
static gboolean
|
||||
gst_element_pads_activate (GstElement * element, gboolean active)
|
||||
{
|
||||
|
@ -1950,16 +1984,17 @@ gst_element_change_state (GstElement * element)
|
|||
GST_LOCK (element);
|
||||
if (GST_ELEMENT_MANAGER (element)) {
|
||||
element->base_time =
|
||||
GST_ELEMENT (GST_ELEMENT_MANAGER (element))->base_time;
|
||||
GST_ELEMENT_CAST (GST_ELEMENT_MANAGER (element))->base_time;
|
||||
}
|
||||
GST_UNLOCK (element);
|
||||
break;
|
||||
case GST_STATE_PLAYING_TO_PAUSED:
|
||||
break;
|
||||
case GST_STATE_PAUSED_TO_READY:
|
||||
element->base_time = 0;
|
||||
if (!gst_element_pads_activate (element, FALSE)) {
|
||||
result = GST_STATE_FAILURE;
|
||||
} else {
|
||||
element->base_time = 0;
|
||||
}
|
||||
break;
|
||||
case GST_STATE_READY_TO_NULL:
|
||||
|
@ -2010,25 +2045,38 @@ gst_element_dispose (GObject * object)
|
|||
while (element->pads) {
|
||||
gst_element_remove_pad (element, GST_PAD (element->pads->data));
|
||||
}
|
||||
|
||||
g_assert (element->pads == 0);
|
||||
if (G_UNLIKELY (element->pads != 0)) {
|
||||
g_critical ("could not remove pads from element %s",
|
||||
GST_STR_NULL (GST_OBJECT_NAME (object)));
|
||||
}
|
||||
|
||||
GST_LOCK (element);
|
||||
gst_object_replace ((GstObject **) & element->manager, NULL);
|
||||
gst_object_replace ((GstObject **) & element->clock, NULL);
|
||||
GST_UNLOCK (element);
|
||||
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose parent");
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_element_finalize (GObject * object)
|
||||
{
|
||||
GstElement *element = GST_ELEMENT (object);
|
||||
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize");
|
||||
|
||||
GST_STATE_LOCK (element);
|
||||
if (element->state_cond)
|
||||
g_cond_free (element->state_cond);
|
||||
element->state_cond = NULL;
|
||||
GST_STATE_UNLOCK (element);
|
||||
|
||||
g_mutex_free (element->state_lock);
|
||||
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose parent");
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize parent");
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
#ifndef GST_DISABLE_LOADSAVE
|
||||
|
@ -2349,35 +2397,3 @@ gst_element_get_scheduler (GstElement * element)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_element_create_task:
|
||||
* @element: a #GstElement to create the task for.
|
||||
* @func: the taskfunction to run
|
||||
* @data: user data passed to the taskfunction.
|
||||
*
|
||||
* Creates a new GstTask. This function uses the current manager of
|
||||
* the element to instantiate a new task.
|
||||
*
|
||||
* Returns: the newly created #GstTask.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
GstTask *
|
||||
gst_element_create_task (GstElement * element, GstTaskFunction func,
|
||||
gpointer data)
|
||||
{
|
||||
GstScheduler *sched;
|
||||
GstTask *result = NULL;
|
||||
|
||||
GST_LOCK (element);
|
||||
sched = GST_ELEMENT_SCHEDULER (element);
|
||||
gst_object_ref (GST_OBJECT (sched));
|
||||
GST_UNLOCK (element);
|
||||
if (sched) {
|
||||
result = gst_scheduler_create_task (sched, func, data);
|
||||
gst_object_unref (GST_OBJECT (sched));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include <gst/gstindex.h>
|
||||
#include <gst/gstiterator.h>
|
||||
#include <gst/gstmessage.h>
|
||||
#include <gst/gsttask.h>
|
||||
#include <gst/gsttag.h>
|
||||
|
||||
G_BEGIN_DECLS typedef struct _GstElementDetails GstElementDetails;
|
||||
|
@ -315,8 +314,6 @@ void gst_element_set_bus (GstElement * element, GstBus * bus);
|
|||
GstBus *gst_element_get_bus (GstElement * element);
|
||||
void gst_element_set_scheduler (GstElement * element, GstScheduler * scheduler);
|
||||
GstScheduler *gst_element_get_scheduler (GstElement * element);
|
||||
GstTask *gst_element_create_task (GstElement * element, GstTaskFunction func,
|
||||
gpointer data);
|
||||
|
||||
/* pad management */
|
||||
gboolean gst_element_add_pad (GstElement * element, GstPad * pad);
|
||||
|
|
|
@ -394,7 +394,7 @@ gst_object_replace (GstObject ** oldobj, GstObject * newobj)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
if (G_UNLIKELY (*oldobj != newobj)) {
|
||||
if (G_LIKELY (*oldobj != newobj)) {
|
||||
if (newobj)
|
||||
gst_object_ref (newobj);
|
||||
if (*oldobj)
|
||||
|
|
|
@ -518,6 +518,11 @@ gboolean gst_pad_push_event (GstPad *pad, GstEvent *event);
|
|||
gboolean gst_pad_send_event (GstPad *pad, GstEvent *event);
|
||||
gboolean gst_pad_event_default (GstPad *pad, GstEvent *event);
|
||||
|
||||
/* pad tasks */
|
||||
gboolean gst_pad_start_task (GstPad *pad);
|
||||
gboolean gst_pad_pause_task (GstPad *pad);
|
||||
gboolean gst_pad_stop_task (GstPad *pad);
|
||||
|
||||
/* convert/query/format functions */
|
||||
void gst_pad_set_formats_function (GstPad *pad,
|
||||
GstPadFormatsFunction formats);
|
||||
|
|
|
@ -168,13 +168,13 @@ is_eos (GstPipeline * pipeline)
|
|||
GstElement *element = GST_ELEMENT (data);
|
||||
GList *eosed;
|
||||
GstElementState state, pending;
|
||||
gboolean complete;
|
||||
GstElementStateReturn complete;
|
||||
gchar *name;
|
||||
|
||||
complete = gst_element_get_state (element, &state, &pending, NULL);
|
||||
name = gst_element_get_name (element);
|
||||
|
||||
if (!complete) {
|
||||
if (complete == GST_STATE_ASYNC) {
|
||||
GST_DEBUG ("element %s still performing state change", name);
|
||||
result = FALSE;
|
||||
done = TRUE;
|
||||
|
@ -332,9 +332,8 @@ gst_pipeline_change_state (GstElement * element)
|
|||
/* we wait for async state changes ourselves */
|
||||
if (result == GST_STATE_ASYNC) {
|
||||
GST_STATE_UNLOCK (pipeline);
|
||||
gst_element_get_state (element, NULL, NULL, NULL);
|
||||
result = gst_element_get_state (element, NULL, NULL, NULL);
|
||||
GST_STATE_LOCK (pipeline);
|
||||
result = GST_STATE_SUCCESS;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -114,7 +114,7 @@ gst_plugin_error_quark (void)
|
|||
* plugin description in a list to initialize it when we open the main
|
||||
* module later on.
|
||||
* When the main module is known, we can register the plugin right away.
|
||||
* */
|
||||
*/
|
||||
void
|
||||
_gst_plugin_register_static (GstPluginDesc * desc)
|
||||
{
|
||||
|
|
|
@ -22,7 +22,9 @@
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS typedef struct _GstObject GstObject;
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstObject GstObject;
|
||||
typedef struct _GstObjectClass GstObjectClass;
|
||||
typedef struct _GstPad GstPad;
|
||||
typedef struct _GstPadClass GstPadClass;
|
||||
|
@ -43,18 +45,19 @@ typedef struct _GstMessage GstMessage;
|
|||
|
||||
typedef enum
|
||||
{
|
||||
GST_STATE_VOID_PENDING = 0,
|
||||
GST_STATE_NULL = (1 << 0),
|
||||
GST_STATE_READY = (1 << 1),
|
||||
GST_STATE_PAUSED = (1 << 2),
|
||||
GST_STATE_PLAYING = (1 << 3)
|
||||
GST_STATE_VOID_PENDING = 0,
|
||||
GST_STATE_NULL = (1 << 0),
|
||||
GST_STATE_READY = (1 << 1),
|
||||
GST_STATE_PAUSED = (1 << 2),
|
||||
GST_STATE_PLAYING = (1 << 3)
|
||||
} GstElementState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_STATE_FAILURE = 0,
|
||||
GST_STATE_SUCCESS = 1,
|
||||
GST_STATE_ASYNC = 2
|
||||
GST_STATE_FAILURE = 0,
|
||||
GST_STATE_SUCCESS = 1,
|
||||
GST_STATE_ASYNC = 2,
|
||||
GST_STATE_BUSY = 3
|
||||
} GstElementStateReturn;
|
||||
|
||||
typedef enum
|
||||
|
@ -66,15 +69,14 @@ typedef enum
|
|||
|
||||
typedef enum
|
||||
{
|
||||
GST_RANK_NONE = 0,
|
||||
GST_RANK_MARGINAL = 64,
|
||||
GST_RANK_SECONDARY = 128,
|
||||
GST_RANK_PRIMARY = 256
|
||||
GST_RANK_NONE = 0,
|
||||
GST_RANK_MARGINAL = 64,
|
||||
GST_RANK_SECONDARY = 128,
|
||||
GST_RANK_PRIMARY = 256
|
||||
} GstRank;
|
||||
|
||||
#define GST_PADDING 4
|
||||
#define GST_PADDING_INIT { 0 }
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GST_TYPES_H__ */
|
||||
|
|
|
@ -773,7 +773,7 @@ gst_element_state_get_name (GstElementState state)
|
|||
return "PAUSED";
|
||||
break;
|
||||
default:
|
||||
return "UNKNOWN!";
|
||||
return g_strdup_printf ("UNKNOWN!(%d)", state);
|
||||
#endif
|
||||
}
|
||||
return "";
|
||||
|
|
|
@ -180,6 +180,7 @@ static gboolean gst_filesrc_srcpad_query (GstPad * pad, GstQueryType type,
|
|||
static gboolean gst_filesrc_activate (GstPad * pad, GstActivateMode mode);
|
||||
static GstElementStateReturn gst_filesrc_change_state (GstElement * element);
|
||||
|
||||
static GstCaps *gst_filesrc_type_find (GstFileSrc * src);
|
||||
static void gst_filesrc_uri_handler_init (gpointer g_iface,
|
||||
gpointer iface_data);
|
||||
|
||||
|
@ -854,6 +855,22 @@ gst_filesrc_open_file (GstFileSrc * src)
|
|||
src->curoffset = 0;
|
||||
|
||||
GST_FLAG_SET (src, GST_FILESRC_OPEN);
|
||||
|
||||
{
|
||||
GstCaps *caps;
|
||||
guint64 offset;
|
||||
guint length;
|
||||
|
||||
offset = src->curoffset;
|
||||
length = src->block_size;
|
||||
|
||||
caps = gst_filesrc_type_find (src);
|
||||
gst_pad_set_caps (src->srcpad, caps);
|
||||
|
||||
src->curoffset = offset;
|
||||
src->block_size = length;
|
||||
}
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1122,6 +1139,89 @@ error:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GstFileSrc *src;
|
||||
guint best_probability;
|
||||
GstCaps *caps;
|
||||
|
||||
GstBuffer *buffer;
|
||||
}
|
||||
FileSrcTypeFind;
|
||||
|
||||
static guint8 *
|
||||
filesrc_find_peek (gpointer data, gint64 offset, guint size)
|
||||
{
|
||||
FileSrcTypeFind *find;
|
||||
GstBuffer *buffer;
|
||||
GstFileSrc *src;
|
||||
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
|
||||
find = (FileSrcTypeFind *) data;
|
||||
src = find->src;
|
||||
|
||||
if (offset < 0) {
|
||||
offset += src->filelen;
|
||||
}
|
||||
|
||||
buffer = NULL;
|
||||
gst_filesrc_getrange (src->srcpad, offset, size, &buffer);
|
||||
|
||||
if (find->buffer) {
|
||||
gst_buffer_unref (find->buffer);
|
||||
}
|
||||
find->buffer = buffer;
|
||||
|
||||
return GST_BUFFER_DATA (buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
filesrc_find_suggest (gpointer data, guint probability, const GstCaps * caps)
|
||||
{
|
||||
FileSrcTypeFind *find = (FileSrcTypeFind *) data;
|
||||
|
||||
if (probability > find->best_probability) {
|
||||
gst_caps_replace (&find->caps, gst_caps_copy (caps));
|
||||
find->best_probability = probability;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static GstCaps *
|
||||
gst_filesrc_type_find (GstFileSrc * src)
|
||||
{
|
||||
GstTypeFind gst_find;
|
||||
FileSrcTypeFind find;
|
||||
GList *walk, *type_list = NULL;
|
||||
GstCaps *result = NULL;
|
||||
|
||||
walk = type_list = gst_type_find_factory_get_list ();
|
||||
|
||||
find.src = src;
|
||||
find.best_probability = 0;
|
||||
find.caps = NULL;
|
||||
gst_find.data = &find;
|
||||
gst_find.peek = filesrc_find_peek;
|
||||
gst_find.suggest = filesrc_find_suggest;
|
||||
gst_find.get_length = NULL;
|
||||
|
||||
while (walk) {
|
||||
GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
|
||||
|
||||
gst_type_find_factory_call_function (factory, &gst_find);
|
||||
if (find.best_probability >= GST_TYPE_FIND_MAXIMUM)
|
||||
break;
|
||||
walk = g_list_next (walk);
|
||||
}
|
||||
|
||||
if (find.best_probability > 0)
|
||||
result = find.caps;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*** GSTURIHANDLER INTERFACE *************************************************/
|
||||
|
||||
static guint
|
||||
|
|
4
tests/old/testsuite/states/.gitignore
vendored
4
tests/old/testsuite/states/.gitignore
vendored
|
@ -6,6 +6,10 @@ Makefile.in
|
|||
.deps
|
||||
.libs
|
||||
|
||||
test1
|
||||
test2
|
||||
test3
|
||||
test4
|
||||
bin
|
||||
locked
|
||||
parent
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
include ../Rules
|
||||
|
||||
tests_pass = locked parent
|
||||
tests_pass = test1 test2 test3 test4 locked parent
|
||||
tests_fail =
|
||||
tests_ignore = bin
|
||||
tests_ignore =
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
|
||||
static GMainLoop *loop;
|
||||
|
||||
static gboolean
|
||||
message_received (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
||||
{
|
||||
|
@ -28,7 +30,8 @@ message_received (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
|||
|
||||
if (message->type == GST_MESSAGE_EOS) {
|
||||
g_print ("EOS!!\n");
|
||||
gst_main_quit ();
|
||||
if (g_main_loop_is_running (loop))
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
gst_message_unref (message);
|
||||
|
||||
|
@ -47,8 +50,10 @@ main (gint argc, gchar * argv[])
|
|||
|
||||
pipeline = gst_pipeline_new ("pipeline");
|
||||
|
||||
bus = GST_PIPELINE (pipeline)->bus;
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
bus = gst_element_get_bus (pipeline);
|
||||
gst_bus_add_watch (bus, (GstBusHandler) message_received, pipeline);
|
||||
gst_object_unref (GST_OBJECT (bus));
|
||||
|
||||
fakesrc1 = gst_element_factory_make ("fakesrc", "fakesrc1");
|
||||
g_object_set (G_OBJECT (fakesrc1), "num_buffers", 5, NULL);
|
||||
|
@ -77,7 +82,7 @@ main (gint argc, gchar * argv[])
|
|||
g_print ("play..\n");
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
|
||||
gst_main ();
|
||||
g_main_loop_run (loop);
|
||||
|
||||
g_object_set (G_OBJECT (fakesrc1), "num_buffers", 5, NULL);
|
||||
|
||||
|
@ -89,7 +94,7 @@ main (gint argc, gchar * argv[])
|
|||
g_print ("play..\n");
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
|
||||
gst_main ();
|
||||
g_main_loop_run (loop);
|
||||
|
||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ main (gint argc, gchar * argv[])
|
|||
|
||||
gst_bin_add (GST_BIN (pipeline), bin2);
|
||||
g_signal_connect (G_OBJECT (pipeline), "deep_notify",
|
||||
G_CALLBACK (gst_element_default_deep_notify), NULL);
|
||||
G_CALLBACK (gst_object_default_deep_notify), NULL);
|
||||
|
||||
/* setting pipeline to READY should bring in all children to READY */
|
||||
gst_element_set_state (pipeline, GST_STATE_READY);
|
||||
|
@ -77,31 +77,35 @@ main (gint argc, gchar * argv[])
|
|||
g_assert (GST_STATE (identity) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_READY);
|
||||
|
||||
/* setting fakesink to PAUSED should set pipeline and bin2 to PAUSED */
|
||||
/* setting fakesink to PAUSED should not affect pipeline and bin2 */
|
||||
gst_element_set_state (fakesink, GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin1) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesrc) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (identity) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_READY);
|
||||
|
||||
/* setting fakesrc to PAUSED should set bin1 and fakesrc to PAUSED */
|
||||
/* setting fakesrc to PAUSED should not affect bin1 */
|
||||
gst_element_set_state (fakesrc, GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin1) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin1) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesrc) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (identity) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_READY);
|
||||
|
||||
/* setting bin1 to PAUSED, even though it is already, should set
|
||||
* identity to PAUSED as well */
|
||||
gst_element_set_state (bin1, GST_STATE_PAUSED);
|
||||
gst_element_get_state (bin2, NULL, NULL, NULL);
|
||||
g_assert (GST_STATE (bin1) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesrc) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (identity) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_PAUSED);
|
||||
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
g_usleep (1000000);
|
||||
|
||||
g_print ("passed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
208
tests/old/testsuite/states/test1.c
Normal file
208
tests/old/testsuite/states/test1.c
Normal file
|
@ -0,0 +1,208 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "unistd.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
static GMainLoop *loop;
|
||||
|
||||
static gboolean
|
||||
message_received (GstBus * bus, GstMessage * message, gpointer ignored)
|
||||
{
|
||||
g_print ("message %p\n", message);
|
||||
|
||||
if (message->type == GST_MESSAGE_EOS) {
|
||||
g_print ("EOS!!\n");
|
||||
if (g_main_loop_is_running (loop))
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
gst_message_unref (message);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_state (GstElement * element, GstElementState state,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
|
||||
g_print ("setting state to %s, expecting %d...",
|
||||
gst_element_state_get_name (state), expected);
|
||||
ret = gst_element_set_state (element, state);
|
||||
res = (ret == expected);
|
||||
g_print ("%s\n", res ? "OK" : "failed");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_state (GstElement * element, GstElementState exp_state,
|
||||
GstElementState exp_pending, GTimeVal * timeval,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
GstElementState state, pending;
|
||||
|
||||
g_print ("getting state: expecting %s, %s, %d...",
|
||||
gst_element_state_get_name (exp_state),
|
||||
gst_element_state_get_name (exp_pending), expected);
|
||||
|
||||
ret = gst_element_get_state (element, &state, &pending, timeval);
|
||||
|
||||
res = (ret == expected);
|
||||
res &= (state == exp_state);
|
||||
res &= (pending == exp_pending);
|
||||
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %s, %s, %d\n",
|
||||
gst_element_state_get_name (state),
|
||||
gst_element_state_get_name (pending), ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
commit_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, GstElement * element)
|
||||
{
|
||||
g_print ("commiting state change..");
|
||||
gst_element_commit_state (element);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
abort_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, GstElement * element)
|
||||
{
|
||||
g_print ("aborting state change..");
|
||||
gst_element_abort_state (element);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstElement *fakesink;
|
||||
GstBus *bus;
|
||||
GTimeVal timeval;
|
||||
GstClock *clock;
|
||||
GstClockID id;
|
||||
GstClockTime base;
|
||||
GstClockReturn result;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
bus = gst_bus_new ();
|
||||
gst_bus_add_watch (bus, (GstBusHandler) message_received, NULL);
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
g_assert (clock != NULL);
|
||||
|
||||
fakesink = gst_element_factory_make ("fakesink", "fakesink");
|
||||
g_assert (fakesink);
|
||||
|
||||
gst_element_set_bus (fakesink, bus);
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
g_get_current_time (&timeval);
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC * 1);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_print ("aborting state change..\n");
|
||||
gst_element_abort_state (fakesink);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_FAILURE));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_print ("commiting state change..\n");
|
||||
gst_element_commit_state (fakesink);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_PAUSED, GST_STATE_VOID_PENDING,
|
||||
&timeval, GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING,
|
||||
&timeval, GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
base = gst_clock_get_time (clock);
|
||||
id = gst_clock_new_single_shot_id (clock, base + 1 * GST_SECOND);
|
||||
g_print ("waiting one second async id %p to abort state\n", id);
|
||||
result =
|
||||
gst_clock_id_wait_async (id, (GstClockCallback) abort_callback, fakesink);
|
||||
gst_clock_id_unref (id);
|
||||
g_assert (result == GST_CLOCK_OK);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, NULL,
|
||||
GST_STATE_FAILURE));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, NULL,
|
||||
GST_STATE_FAILURE));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
id = gst_clock_new_single_shot_id (clock, base + 1 * GST_SECOND);
|
||||
g_print ("waiting one second async id %p to commit state\n", id);
|
||||
result =
|
||||
gst_clock_id_wait_async (id, (GstClockCallback) commit_callback,
|
||||
fakesink);
|
||||
gst_clock_id_unref (id);
|
||||
g_assert (result == GST_CLOCK_OK);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_print ("passed..\n");
|
||||
gst_object_unref (GST_OBJECT (fakesink));
|
||||
|
||||
return 0;
|
||||
}
|
131
tests/old/testsuite/states/test2.c
Normal file
131
tests/old/testsuite/states/test2.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "unistd.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
static GMainLoop *loop;
|
||||
|
||||
static gboolean
|
||||
message_received (GstBus * bus, GstMessage * message, gpointer ignored)
|
||||
{
|
||||
g_print ("message %p\n", message);
|
||||
|
||||
if (message->type == GST_MESSAGE_EOS) {
|
||||
g_print ("EOS!!\n");
|
||||
if (g_main_loop_is_running (loop))
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
gst_message_unref (message);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_state (GstElement * element, GstElementState state,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
|
||||
g_print ("setting state to %s, expecting %d...",
|
||||
gst_element_state_get_name (state), expected);
|
||||
ret = gst_element_set_state (element, state);
|
||||
res = (ret == expected);
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %d\n", ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_state (GstElement * element, GstElementState exp_state,
|
||||
GstElementState exp_pending, GTimeVal * timeval,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
GstElementState state, pending;
|
||||
|
||||
g_print ("getting state: expecting %s, %s, %d...",
|
||||
gst_element_state_get_name (exp_state),
|
||||
gst_element_state_get_name (exp_pending), expected);
|
||||
|
||||
ret = gst_element_get_state (element, &state, &pending, timeval);
|
||||
|
||||
res = (ret == expected);
|
||||
res &= (state == exp_state);
|
||||
res &= (pending == exp_pending);
|
||||
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %s, %s, %d\n",
|
||||
gst_element_state_get_name (state),
|
||||
gst_element_state_get_name (pending), ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstElement *fakesink;
|
||||
GstBus *bus;
|
||||
GTimeVal timeval;
|
||||
GstClock *clock;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
bus = gst_bus_new ();
|
||||
gst_bus_add_watch (bus, (GstBusHandler) message_received, NULL);
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
g_assert (clock != NULL);
|
||||
|
||||
fakesink = gst_element_factory_make ("fakesink", "fakesink");
|
||||
g_assert (fakesink);
|
||||
|
||||
gst_element_set_bus (fakesink, bus);
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PLAYING, GST_STATE_ASYNC));
|
||||
|
||||
g_get_current_time (&timeval);
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC * 1);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_print ("passed..\n");
|
||||
gst_object_unref (GST_OBJECT (fakesink));
|
||||
|
||||
return 0;
|
||||
}
|
136
tests/old/testsuite/states/test3.c
Normal file
136
tests/old/testsuite/states/test3.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "unistd.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
static GMainLoop *loop;
|
||||
|
||||
static gboolean
|
||||
message_received (GstBus * bus, GstMessage * message, gpointer ignored)
|
||||
{
|
||||
g_print ("message %p\n", message);
|
||||
|
||||
if (message->type == GST_MESSAGE_EOS) {
|
||||
g_print ("EOS!!\n");
|
||||
if (g_main_loop_is_running (loop))
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
gst_message_unref (message);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_state (GstElement * element, GstElementState state,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
|
||||
g_print ("setting state to %s, expecting %d...",
|
||||
gst_element_state_get_name (state), expected);
|
||||
ret = gst_element_set_state (element, state);
|
||||
res = (ret == expected);
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %d\n", ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_state (GstElement * element, GstElementState exp_state,
|
||||
GstElementState exp_pending, GTimeVal * timeval,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
GstElementState state, pending;
|
||||
|
||||
g_print ("getting state: expecting %s, %s, %d...",
|
||||
gst_element_state_get_name (exp_state),
|
||||
gst_element_state_get_name (exp_pending), expected);
|
||||
|
||||
ret = gst_element_get_state (element, &state, &pending, timeval);
|
||||
|
||||
res = (ret == expected);
|
||||
res &= (state == exp_state);
|
||||
res &= (pending == exp_pending);
|
||||
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %s, %s, %d\n",
|
||||
gst_element_state_get_name (state),
|
||||
gst_element_state_get_name (pending), ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstElement *bin;
|
||||
GstBus *bus;
|
||||
GstClock *clock;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
bus = gst_bus_new ();
|
||||
gst_bus_add_watch (bus, (GstBusHandler) message_received, NULL);
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
g_assert (clock != NULL);
|
||||
|
||||
bin = gst_element_factory_make ("bin", "bin");
|
||||
g_assert (bin);
|
||||
|
||||
gst_element_set_bus (bin, bus);
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PLAYING, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_PLAYING, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_print ("passed..\n");
|
||||
gst_object_unref (GST_OBJECT (bin));
|
||||
|
||||
return 0;
|
||||
}
|
230
tests/old/testsuite/states/test4.c
Normal file
230
tests/old/testsuite/states/test4.c
Normal file
|
@ -0,0 +1,230 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "unistd.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
static GMainLoop *loop;
|
||||
|
||||
static gboolean
|
||||
message_received (GstBus * bus, GstMessage * message, gpointer ignored)
|
||||
{
|
||||
g_print ("message %p\n", message);
|
||||
|
||||
if (message->type == GST_MESSAGE_EOS) {
|
||||
g_print ("EOS!!\n");
|
||||
if (g_main_loop_is_running (loop))
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
gst_message_unref (message);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_state (GstElement * element, GstElementState state,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
|
||||
g_print ("setting %s state to %s, expecting %d...",
|
||||
gst_element_get_name (element),
|
||||
gst_element_state_get_name (state), expected);
|
||||
ret = gst_element_set_state (element, state);
|
||||
res = (ret == expected);
|
||||
g_print ("%s\n", res ? "OK" : "failed");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_state (GstElement * element, GstElementState exp_state,
|
||||
GstElementState exp_pending, GTimeVal * timeval,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
GstElementState state, pending;
|
||||
|
||||
g_print ("getting state %s: expecting %s, %s, %d...",
|
||||
gst_element_get_name (element),
|
||||
gst_element_state_get_name (exp_state),
|
||||
gst_element_state_get_name (exp_pending), expected);
|
||||
|
||||
ret = gst_element_get_state (element, &state, &pending, timeval);
|
||||
|
||||
res = (ret == expected);
|
||||
res &= (state == exp_state);
|
||||
res &= (pending == exp_pending);
|
||||
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %s, %s, %d\n",
|
||||
gst_element_state_get_name (state),
|
||||
gst_element_state_get_name (pending), ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
commit_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, GstElement * element)
|
||||
{
|
||||
g_print ("commiting state change..");
|
||||
gst_element_commit_state (element);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
abort_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, GstElement * element)
|
||||
{
|
||||
g_print ("aborting state change..");
|
||||
gst_element_abort_state (element);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstElement *fakesink, *bin;
|
||||
GstBus *bus;
|
||||
GTimeVal timeval;
|
||||
GstClock *clock;
|
||||
GstClockID id;
|
||||
GstClockTime base;
|
||||
GstClockReturn result;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
bus = gst_bus_new ();
|
||||
gst_bus_add_watch (bus, (GstBusHandler) message_received, NULL);
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
g_assert (clock != NULL);
|
||||
|
||||
fakesink = gst_element_factory_make ("fakesink", "fakesink");
|
||||
g_assert (fakesink);
|
||||
bin = gst_element_factory_make ("bin", "bin");
|
||||
g_assert (bin);
|
||||
|
||||
gst_bin_add (GST_BIN (bin), fakesink);
|
||||
|
||||
gst_element_set_bus (bin, bus);
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_NULL, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_NULL, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_get_current_time (&timeval);
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC / 2);
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC / 2);
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC / 2);
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC / 2);
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, &timeval,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING,
|
||||
&timeval, GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC / 2);
|
||||
g_assert (get_state (bin, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, &timeval,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, &timeval,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
base = gst_clock_get_time (clock);
|
||||
id = gst_clock_new_single_shot_id (clock, base + 1 * GST_SECOND);
|
||||
g_print ("waiting one second async id %p to abort state\n", id);
|
||||
result =
|
||||
gst_clock_id_wait_async (id, (GstClockCallback) abort_callback, fakesink);
|
||||
gst_clock_id_unref (id);
|
||||
g_assert (result == GST_CLOCK_OK);
|
||||
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_PAUSED, NULL,
|
||||
GST_STATE_FAILURE));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
base = gst_clock_get_time (clock);
|
||||
id = gst_clock_new_single_shot_id (clock, base + 1 * GST_SECOND);
|
||||
g_print ("waiting one second async id %p to commit state\n", id);
|
||||
result =
|
||||
gst_clock_id_wait_async (id, (GstClockCallback) commit_callback,
|
||||
fakesink);
|
||||
gst_clock_id_unref (id);
|
||||
g_assert (result == GST_CLOCK_OK);
|
||||
|
||||
g_assert (get_state (bin, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_print ("passed..\n");
|
||||
gst_object_unref (GST_OBJECT (fakesink));
|
||||
|
||||
return 0;
|
||||
}
|
4
testsuite/states/.gitignore
vendored
4
testsuite/states/.gitignore
vendored
|
@ -6,6 +6,10 @@ Makefile.in
|
|||
.deps
|
||||
.libs
|
||||
|
||||
test1
|
||||
test2
|
||||
test3
|
||||
test4
|
||||
bin
|
||||
locked
|
||||
parent
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
include ../Rules
|
||||
|
||||
tests_pass = locked parent
|
||||
tests_pass = test1 test2 test3 test4 locked parent
|
||||
tests_fail =
|
||||
tests_ignore = bin
|
||||
tests_ignore =
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
|
||||
static GMainLoop *loop;
|
||||
|
||||
static gboolean
|
||||
message_received (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
||||
{
|
||||
|
@ -28,7 +30,8 @@ message_received (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
|||
|
||||
if (message->type == GST_MESSAGE_EOS) {
|
||||
g_print ("EOS!!\n");
|
||||
gst_main_quit ();
|
||||
if (g_main_loop_is_running (loop))
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
gst_message_unref (message);
|
||||
|
||||
|
@ -47,8 +50,10 @@ main (gint argc, gchar * argv[])
|
|||
|
||||
pipeline = gst_pipeline_new ("pipeline");
|
||||
|
||||
bus = GST_PIPELINE (pipeline)->bus;
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
bus = gst_element_get_bus (pipeline);
|
||||
gst_bus_add_watch (bus, (GstBusHandler) message_received, pipeline);
|
||||
gst_object_unref (GST_OBJECT (bus));
|
||||
|
||||
fakesrc1 = gst_element_factory_make ("fakesrc", "fakesrc1");
|
||||
g_object_set (G_OBJECT (fakesrc1), "num_buffers", 5, NULL);
|
||||
|
@ -77,7 +82,7 @@ main (gint argc, gchar * argv[])
|
|||
g_print ("play..\n");
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
|
||||
gst_main ();
|
||||
g_main_loop_run (loop);
|
||||
|
||||
g_object_set (G_OBJECT (fakesrc1), "num_buffers", 5, NULL);
|
||||
|
||||
|
@ -89,7 +94,7 @@ main (gint argc, gchar * argv[])
|
|||
g_print ("play..\n");
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
|
||||
gst_main ();
|
||||
g_main_loop_run (loop);
|
||||
|
||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ main (gint argc, gchar * argv[])
|
|||
|
||||
gst_bin_add (GST_BIN (pipeline), bin2);
|
||||
g_signal_connect (G_OBJECT (pipeline), "deep_notify",
|
||||
G_CALLBACK (gst_element_default_deep_notify), NULL);
|
||||
G_CALLBACK (gst_object_default_deep_notify), NULL);
|
||||
|
||||
/* setting pipeline to READY should bring in all children to READY */
|
||||
gst_element_set_state (pipeline, GST_STATE_READY);
|
||||
|
@ -77,31 +77,35 @@ main (gint argc, gchar * argv[])
|
|||
g_assert (GST_STATE (identity) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_READY);
|
||||
|
||||
/* setting fakesink to PAUSED should set pipeline and bin2 to PAUSED */
|
||||
/* setting fakesink to PAUSED should not affect pipeline and bin2 */
|
||||
gst_element_set_state (fakesink, GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin1) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesrc) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (identity) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_READY);
|
||||
|
||||
/* setting fakesrc to PAUSED should set bin1 and fakesrc to PAUSED */
|
||||
/* setting fakesrc to PAUSED should not affect bin1 */
|
||||
gst_element_set_state (fakesrc, GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin1) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin1) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesrc) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (identity) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_READY);
|
||||
|
||||
/* setting bin1 to PAUSED, even though it is already, should set
|
||||
* identity to PAUSED as well */
|
||||
gst_element_set_state (bin1, GST_STATE_PAUSED);
|
||||
gst_element_get_state (bin2, NULL, NULL, NULL);
|
||||
g_assert (GST_STATE (bin1) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (bin2) == GST_STATE_READY);
|
||||
g_assert (GST_STATE (fakesrc) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (identity) == GST_STATE_PAUSED);
|
||||
g_assert (GST_STATE (fakesink) == GST_STATE_PAUSED);
|
||||
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
g_usleep (1000000);
|
||||
|
||||
g_print ("passed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
208
testsuite/states/test1.c
Normal file
208
testsuite/states/test1.c
Normal file
|
@ -0,0 +1,208 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "unistd.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
static GMainLoop *loop;
|
||||
|
||||
static gboolean
|
||||
message_received (GstBus * bus, GstMessage * message, gpointer ignored)
|
||||
{
|
||||
g_print ("message %p\n", message);
|
||||
|
||||
if (message->type == GST_MESSAGE_EOS) {
|
||||
g_print ("EOS!!\n");
|
||||
if (g_main_loop_is_running (loop))
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
gst_message_unref (message);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_state (GstElement * element, GstElementState state,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
|
||||
g_print ("setting state to %s, expecting %d...",
|
||||
gst_element_state_get_name (state), expected);
|
||||
ret = gst_element_set_state (element, state);
|
||||
res = (ret == expected);
|
||||
g_print ("%s\n", res ? "OK" : "failed");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_state (GstElement * element, GstElementState exp_state,
|
||||
GstElementState exp_pending, GTimeVal * timeval,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
GstElementState state, pending;
|
||||
|
||||
g_print ("getting state: expecting %s, %s, %d...",
|
||||
gst_element_state_get_name (exp_state),
|
||||
gst_element_state_get_name (exp_pending), expected);
|
||||
|
||||
ret = gst_element_get_state (element, &state, &pending, timeval);
|
||||
|
||||
res = (ret == expected);
|
||||
res &= (state == exp_state);
|
||||
res &= (pending == exp_pending);
|
||||
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %s, %s, %d\n",
|
||||
gst_element_state_get_name (state),
|
||||
gst_element_state_get_name (pending), ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
commit_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, GstElement * element)
|
||||
{
|
||||
g_print ("commiting state change..");
|
||||
gst_element_commit_state (element);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
abort_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, GstElement * element)
|
||||
{
|
||||
g_print ("aborting state change..");
|
||||
gst_element_abort_state (element);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstElement *fakesink;
|
||||
GstBus *bus;
|
||||
GTimeVal timeval;
|
||||
GstClock *clock;
|
||||
GstClockID id;
|
||||
GstClockTime base;
|
||||
GstClockReturn result;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
bus = gst_bus_new ();
|
||||
gst_bus_add_watch (bus, (GstBusHandler) message_received, NULL);
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
g_assert (clock != NULL);
|
||||
|
||||
fakesink = gst_element_factory_make ("fakesink", "fakesink");
|
||||
g_assert (fakesink);
|
||||
|
||||
gst_element_set_bus (fakesink, bus);
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
g_get_current_time (&timeval);
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC * 1);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_print ("aborting state change..\n");
|
||||
gst_element_abort_state (fakesink);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_FAILURE));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_print ("commiting state change..\n");
|
||||
gst_element_commit_state (fakesink);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_PAUSED, GST_STATE_VOID_PENDING,
|
||||
&timeval, GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING,
|
||||
&timeval, GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
base = gst_clock_get_time (clock);
|
||||
id = gst_clock_new_single_shot_id (clock, base + 1 * GST_SECOND);
|
||||
g_print ("waiting one second async id %p to abort state\n", id);
|
||||
result =
|
||||
gst_clock_id_wait_async (id, (GstClockCallback) abort_callback, fakesink);
|
||||
gst_clock_id_unref (id);
|
||||
g_assert (result == GST_CLOCK_OK);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, NULL,
|
||||
GST_STATE_FAILURE));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, NULL,
|
||||
GST_STATE_FAILURE));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
id = gst_clock_new_single_shot_id (clock, base + 1 * GST_SECOND);
|
||||
g_print ("waiting one second async id %p to commit state\n", id);
|
||||
result =
|
||||
gst_clock_id_wait_async (id, (GstClockCallback) commit_callback,
|
||||
fakesink);
|
||||
gst_clock_id_unref (id);
|
||||
g_assert (result == GST_CLOCK_OK);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_print ("passed..\n");
|
||||
gst_object_unref (GST_OBJECT (fakesink));
|
||||
|
||||
return 0;
|
||||
}
|
131
testsuite/states/test2.c
Normal file
131
testsuite/states/test2.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "unistd.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
static GMainLoop *loop;
|
||||
|
||||
static gboolean
|
||||
message_received (GstBus * bus, GstMessage * message, gpointer ignored)
|
||||
{
|
||||
g_print ("message %p\n", message);
|
||||
|
||||
if (message->type == GST_MESSAGE_EOS) {
|
||||
g_print ("EOS!!\n");
|
||||
if (g_main_loop_is_running (loop))
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
gst_message_unref (message);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_state (GstElement * element, GstElementState state,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
|
||||
g_print ("setting state to %s, expecting %d...",
|
||||
gst_element_state_get_name (state), expected);
|
||||
ret = gst_element_set_state (element, state);
|
||||
res = (ret == expected);
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %d\n", ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_state (GstElement * element, GstElementState exp_state,
|
||||
GstElementState exp_pending, GTimeVal * timeval,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
GstElementState state, pending;
|
||||
|
||||
g_print ("getting state: expecting %s, %s, %d...",
|
||||
gst_element_state_get_name (exp_state),
|
||||
gst_element_state_get_name (exp_pending), expected);
|
||||
|
||||
ret = gst_element_get_state (element, &state, &pending, timeval);
|
||||
|
||||
res = (ret == expected);
|
||||
res &= (state == exp_state);
|
||||
res &= (pending == exp_pending);
|
||||
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %s, %s, %d\n",
|
||||
gst_element_state_get_name (state),
|
||||
gst_element_state_get_name (pending), ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstElement *fakesink;
|
||||
GstBus *bus;
|
||||
GTimeVal timeval;
|
||||
GstClock *clock;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
bus = gst_bus_new ();
|
||||
gst_bus_add_watch (bus, (GstBusHandler) message_received, NULL);
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
g_assert (clock != NULL);
|
||||
|
||||
fakesink = gst_element_factory_make ("fakesink", "fakesink");
|
||||
g_assert (fakesink);
|
||||
|
||||
gst_element_set_bus (fakesink, bus);
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PLAYING, GST_STATE_ASYNC));
|
||||
|
||||
g_get_current_time (&timeval);
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC * 1);
|
||||
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_print ("passed..\n");
|
||||
gst_object_unref (GST_OBJECT (fakesink));
|
||||
|
||||
return 0;
|
||||
}
|
136
testsuite/states/test3.c
Normal file
136
testsuite/states/test3.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "unistd.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
static GMainLoop *loop;
|
||||
|
||||
static gboolean
|
||||
message_received (GstBus * bus, GstMessage * message, gpointer ignored)
|
||||
{
|
||||
g_print ("message %p\n", message);
|
||||
|
||||
if (message->type == GST_MESSAGE_EOS) {
|
||||
g_print ("EOS!!\n");
|
||||
if (g_main_loop_is_running (loop))
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
gst_message_unref (message);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_state (GstElement * element, GstElementState state,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
|
||||
g_print ("setting state to %s, expecting %d...",
|
||||
gst_element_state_get_name (state), expected);
|
||||
ret = gst_element_set_state (element, state);
|
||||
res = (ret == expected);
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %d\n", ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_state (GstElement * element, GstElementState exp_state,
|
||||
GstElementState exp_pending, GTimeVal * timeval,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
GstElementState state, pending;
|
||||
|
||||
g_print ("getting state: expecting %s, %s, %d...",
|
||||
gst_element_state_get_name (exp_state),
|
||||
gst_element_state_get_name (exp_pending), expected);
|
||||
|
||||
ret = gst_element_get_state (element, &state, &pending, timeval);
|
||||
|
||||
res = (ret == expected);
|
||||
res &= (state == exp_state);
|
||||
res &= (pending == exp_pending);
|
||||
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %s, %s, %d\n",
|
||||
gst_element_state_get_name (state),
|
||||
gst_element_state_get_name (pending), ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstElement *bin;
|
||||
GstBus *bus;
|
||||
GstClock *clock;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
bus = gst_bus_new ();
|
||||
gst_bus_add_watch (bus, (GstBusHandler) message_received, NULL);
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
g_assert (clock != NULL);
|
||||
|
||||
bin = gst_element_factory_make ("bin", "bin");
|
||||
g_assert (bin);
|
||||
|
||||
gst_element_set_bus (bin, bus);
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PLAYING, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_PLAYING, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_print ("passed..\n");
|
||||
gst_object_unref (GST_OBJECT (bin));
|
||||
|
||||
return 0;
|
||||
}
|
230
testsuite/states/test4.c
Normal file
230
testsuite/states/test4.c
Normal file
|
@ -0,0 +1,230 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "unistd.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
static GMainLoop *loop;
|
||||
|
||||
static gboolean
|
||||
message_received (GstBus * bus, GstMessage * message, gpointer ignored)
|
||||
{
|
||||
g_print ("message %p\n", message);
|
||||
|
||||
if (message->type == GST_MESSAGE_EOS) {
|
||||
g_print ("EOS!!\n");
|
||||
if (g_main_loop_is_running (loop))
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
gst_message_unref (message);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_state (GstElement * element, GstElementState state,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
|
||||
g_print ("setting %s state to %s, expecting %d...",
|
||||
gst_element_get_name (element),
|
||||
gst_element_state_get_name (state), expected);
|
||||
ret = gst_element_set_state (element, state);
|
||||
res = (ret == expected);
|
||||
g_print ("%s\n", res ? "OK" : "failed");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_state (GstElement * element, GstElementState exp_state,
|
||||
GstElementState exp_pending, GTimeVal * timeval,
|
||||
GstElementStateReturn expected)
|
||||
{
|
||||
GstElementStateReturn ret;
|
||||
gboolean res;
|
||||
GstElementState state, pending;
|
||||
|
||||
g_print ("getting state %s: expecting %s, %s, %d...",
|
||||
gst_element_get_name (element),
|
||||
gst_element_state_get_name (exp_state),
|
||||
gst_element_state_get_name (exp_pending), expected);
|
||||
|
||||
ret = gst_element_get_state (element, &state, &pending, timeval);
|
||||
|
||||
res = (ret == expected);
|
||||
res &= (state == exp_state);
|
||||
res &= (pending == exp_pending);
|
||||
|
||||
if (res) {
|
||||
g_print ("OK\n");
|
||||
} else {
|
||||
g_print ("failed, got %s, %s, %d\n",
|
||||
gst_element_state_get_name (state),
|
||||
gst_element_state_get_name (pending), ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
commit_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, GstElement * element)
|
||||
{
|
||||
g_print ("commiting state change..");
|
||||
gst_element_commit_state (element);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
abort_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, GstElement * element)
|
||||
{
|
||||
g_print ("aborting state change..");
|
||||
gst_element_abort_state (element);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstElement *fakesink, *bin;
|
||||
GstBus *bus;
|
||||
GTimeVal timeval;
|
||||
GstClock *clock;
|
||||
GstClockID id;
|
||||
GstClockTime base;
|
||||
GstClockReturn result;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
bus = gst_bus_new ();
|
||||
gst_bus_add_watch (bus, (GstBusHandler) message_received, NULL);
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
g_assert (clock != NULL);
|
||||
|
||||
fakesink = gst_element_factory_make ("fakesink", "fakesink");
|
||||
g_assert (fakesink);
|
||||
bin = gst_element_factory_make ("bin", "bin");
|
||||
g_assert (bin);
|
||||
|
||||
gst_bin_add (GST_BIN (bin), fakesink);
|
||||
|
||||
gst_element_set_bus (bin, bus);
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_NULL, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_NULL, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_get_current_time (&timeval);
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC / 2);
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC / 2);
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC / 2);
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC / 2);
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_PAUSED, &timeval,
|
||||
GST_STATE_ASYNC));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, &timeval,
|
||||
GST_STATE_SUCCESS));
|
||||
g_assert (get_state (fakesink, GST_STATE_READY, GST_STATE_VOID_PENDING,
|
||||
&timeval, GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
g_assert (set_state (fakesink, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_time_val_add (&timeval, G_USEC_PER_SEC / 2);
|
||||
g_assert (get_state (bin, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, &timeval,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_READY, GST_STATE_SUCCESS));
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_VOID_PENDING, &timeval,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
base = gst_clock_get_time (clock);
|
||||
id = gst_clock_new_single_shot_id (clock, base + 1 * GST_SECOND);
|
||||
g_print ("waiting one second async id %p to abort state\n", id);
|
||||
result =
|
||||
gst_clock_id_wait_async (id, (GstClockCallback) abort_callback, fakesink);
|
||||
gst_clock_id_unref (id);
|
||||
g_assert (result == GST_CLOCK_OK);
|
||||
|
||||
g_assert (get_state (bin, GST_STATE_READY, GST_STATE_PAUSED, NULL,
|
||||
GST_STATE_FAILURE));
|
||||
|
||||
g_assert (set_state (bin, GST_STATE_PAUSED, GST_STATE_ASYNC));
|
||||
|
||||
base = gst_clock_get_time (clock);
|
||||
id = gst_clock_new_single_shot_id (clock, base + 1 * GST_SECOND);
|
||||
g_print ("waiting one second async id %p to commit state\n", id);
|
||||
result =
|
||||
gst_clock_id_wait_async (id, (GstClockCallback) commit_callback,
|
||||
fakesink);
|
||||
gst_clock_id_unref (id);
|
||||
g_assert (result == GST_CLOCK_OK);
|
||||
|
||||
g_assert (get_state (bin, GST_STATE_PAUSED, GST_STATE_VOID_PENDING, NULL,
|
||||
GST_STATE_SUCCESS));
|
||||
|
||||
g_print ("passed..\n");
|
||||
gst_object_unref (GST_OBJECT (fakesink));
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue