mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 11:55:39 +00:00
Merge branch 'master' into 0.11
This commit is contained in:
commit
0894ed2053
11 changed files with 206 additions and 36 deletions
|
@ -5,22 +5,22 @@ This document describes the design and use cases for the progress reporting
|
|||
messages.
|
||||
|
||||
PROGRESS messages are posted on the bus to inform the application about the
|
||||
progress of asynchonous operations in the pipeline. This should not be confused
|
||||
progress of asynchronous operations in the pipeline. This should not be confused
|
||||
with asynchronous state changes.
|
||||
|
||||
We accomodate for the following requirements:
|
||||
We accommodate for the following requirements:
|
||||
|
||||
- Application is informed when an async operation starts and completes.
|
||||
- It should be possible for the application to generically detect common
|
||||
operations and incorporate their progress into the GUI.
|
||||
- Applications can cancel pending operations by doing regular state changes.
|
||||
- Applications should be abe able to wait for completion of async operations.
|
||||
- Applications should be able to wait for completion of async operations.
|
||||
|
||||
We allow for the following scenarios:
|
||||
|
||||
- Elements want to inform the application about asynchronous DNS lookups and
|
||||
pending network requests. This includes starting and completing the lookup.
|
||||
- Elements opening devices and resources assynchronously.
|
||||
- Elements opening devices and resources asynchronously.
|
||||
- Applications having more freedom to implement timeout and cancelation of
|
||||
operations that currently block the state changes or happen invisibly behind
|
||||
the scenes.
|
||||
|
@ -29,9 +29,9 @@ We allow for the following scenarios:
|
|||
Rationale
|
||||
~~~~~~~~~
|
||||
|
||||
The main reason for adding these extra progress notifications is twofold:
|
||||
The main reason for adding these extra progress notifications is twofold:
|
||||
|
||||
1) to give the application more information of what is going on
|
||||
1) to give the application more information of what is going on
|
||||
|
||||
When there are well defined progress information codes, applications
|
||||
can let the user know about the status of the progress. We anticipate to
|
||||
|
@ -48,7 +48,7 @@ The main reason for adding these extra progress notifications is twofold:
|
|||
We would like to make the state change function, instead, start a separate
|
||||
thread that performs the blocking operations in a cancelable way. When going
|
||||
back to the NULL state, all pending operations would be canceled immediately.
|
||||
|
||||
|
||||
For downward state changes, we want to let the application implement its own
|
||||
timeout mechanism. For example: when stopping an RTSP stream, the clients
|
||||
needs to send a TEARDOWN request to the server. This can however take an
|
||||
|
@ -66,7 +66,7 @@ Async state changes
|
|||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
GStreamer currently has a GST_STATE_CHANGE_ASYNC return value to note to the
|
||||
application that a state change is happening assynchronously.
|
||||
application that a state change is happening asynchronously.
|
||||
|
||||
The main purpose of this return value is to make the pipeline wait for preroll
|
||||
and delay a future (upwards) state changes until the sinks are prerolled.
|
||||
|
@ -74,34 +74,35 @@ and delay a future (upwards) state changes until the sinks are prerolled.
|
|||
In the case of async operations on source, this will automatically force sinks
|
||||
to stay async because they will not preroll before the source can produce data.
|
||||
|
||||
The fact that other asynchonous operations happen behind the scnes is irrelevant
|
||||
for the prerolling process so it is not implemented with the ASYNC state change
|
||||
return value in order to not complicate the state changes and mix concepts.
|
||||
The fact that other asynchronous operations happen behind the scenes is
|
||||
irrelevant for the prerolling process so it is not implemented with the ASYNC
|
||||
state change return value in order to not complicate the state changes and mix
|
||||
concepts.
|
||||
|
||||
|
||||
Use cases
|
||||
~~~~~~~~~
|
||||
|
||||
|
||||
* RTSP client (but also HTTP, MMS, ...)
|
||||
|
||||
When the client goes from the READY to the PAUSED state, it opens a socket,
|
||||
performs a DNS lookup, retieves the SDP and negotiates the streams. All these
|
||||
operations currently block the state change function for an undefinite amount
|
||||
performs a DNS lookup, retrieves the SDP and negotiates the streams. All these
|
||||
operations currently block the state change function for an indefinite amount
|
||||
of time and while they are blocking cannot be canceled.
|
||||
|
||||
Instead, a thread would be started to perform these operations assynchronously
|
||||
Instead, a thread would be started to perform these operations asynchronously
|
||||
and the state change would complete with the usual NO_PREROLL return value.
|
||||
Before starting the thread a PROGRESS message would be posted to mark the
|
||||
start of the async operation.
|
||||
|
||||
As the DNS lookup completes and the connection is established, PROGRESS messages
|
||||
are posted on the bus to inform the application of the progress. When
|
||||
As the DNS lookup completes and the connection is established, PROGRESS
|
||||
messages are posted on the bus to inform the application of the progress. When
|
||||
something fails, an error is posted and a PROGRESS CANCELED message is posted.
|
||||
The application can then stop the pipeline.
|
||||
|
||||
If there are no errors and the setup of the streams completed successfully, a
|
||||
PROGRESS COMPLETED is posted on the bus. The thread then goes to sleep and the
|
||||
assynchronous operation completed.
|
||||
asynchronous operation completed.
|
||||
|
||||
The RTSP protocol requires to send a TEARDOWN request to the server
|
||||
before closing the connection and destroying the socket. A state change to the
|
||||
|
@ -117,7 +118,7 @@ Use cases
|
|||
|
||||
DNS lookup and connection times can be measured by calculating the elapsed
|
||||
time between the various PROGRESS messages.
|
||||
|
||||
|
||||
|
||||
|
||||
Messages
|
||||
|
@ -212,7 +213,7 @@ Categories
|
|||
~~~~~~~~~~
|
||||
|
||||
We want to propose some standard codes here:
|
||||
|
||||
|
||||
"open" : A resource is being opened
|
||||
"close" : A resource is being closed
|
||||
|
||||
|
|
|
@ -171,6 +171,8 @@ gst_atomic_queue_new (guint initial_size)
|
|||
* @queue: a #GstAtomicQueue
|
||||
*
|
||||
* Increase the refcount of @queue.
|
||||
*
|
||||
* Since: 0.10.33
|
||||
*/
|
||||
void
|
||||
gst_atomic_queue_ref (GstAtomicQueue * queue)
|
||||
|
@ -195,6 +197,8 @@ gst_atomic_queue_free (GstAtomicQueue * queue)
|
|||
* @queue: a #GstAtomicQueue
|
||||
*
|
||||
* Unref @queue and free the memory when the refcount reaches 0.
|
||||
*
|
||||
* Since: 0.10.33
|
||||
*/
|
||||
void
|
||||
gst_atomic_queue_unref (GstAtomicQueue * queue)
|
||||
|
@ -212,6 +216,8 @@ gst_atomic_queue_unref (GstAtomicQueue * queue)
|
|||
* Peek the head element of the queue without removing it from the queue.
|
||||
*
|
||||
* Returns: the head element of @queue or NULL when the queue is empty.
|
||||
*
|
||||
* Since: 0.10.33
|
||||
*/
|
||||
gpointer
|
||||
gst_atomic_queue_peek (GstAtomicQueue * queue)
|
||||
|
@ -261,6 +267,8 @@ gst_atomic_queue_peek (GstAtomicQueue * queue)
|
|||
* Get the head element of the queue.
|
||||
*
|
||||
* Returns: the head element of @queue or NULL when the queue is empty.
|
||||
*
|
||||
* Since: 0.10.33
|
||||
*/
|
||||
gpointer
|
||||
gst_atomic_queue_pop (GstAtomicQueue * queue)
|
||||
|
@ -326,6 +334,8 @@ gst_atomic_queue_pop (GstAtomicQueue * queue)
|
|||
* @data: the data
|
||||
*
|
||||
* Append @data to the tail of the queue.
|
||||
*
|
||||
* Since: 0.10.33
|
||||
*/
|
||||
void
|
||||
gst_atomic_queue_push (GstAtomicQueue * queue, gpointer data)
|
||||
|
@ -378,6 +388,8 @@ gst_atomic_queue_push (GstAtomicQueue * queue, gpointer data)
|
|||
* Get the amount of items in the queue.
|
||||
*
|
||||
* Returns: the number of elements in the queue.
|
||||
*
|
||||
* Since: 0.10.33
|
||||
*/
|
||||
guint
|
||||
gst_atomic_queue_length (GstAtomicQueue * queue)
|
||||
|
|
|
@ -32,6 +32,8 @@ G_BEGIN_DECLS
|
|||
* Opaque atomic data queue.
|
||||
*
|
||||
* Use the acessor functions to get the stored values.
|
||||
*
|
||||
* Since: 0.10.33
|
||||
*/
|
||||
typedef struct _GstAtomicQueue GstAtomicQueue;
|
||||
|
||||
|
|
|
@ -217,12 +217,14 @@ typedef struct _GstBufferClass GstBufferClass;
|
|||
* @GST_BUFFER_FLAG_MEDIA1: a flag whose use is specific to the caps of the buffer. Since: 0.10.23.
|
||||
* @GST_BUFFER_FLAG_MEDIA2: a flag whose use is specific to the caps of the buffer. Since: 0.10.23.
|
||||
* @GST_BUFFER_FLAG_MEDIA3: a flag whose use is specific to the caps of the buffer. Since: 0.10.23.
|
||||
* @GST_BUFFER_FLAG_MEDIA4: a flag whose use is specific to the caps of the buffer. Since: 0.10.33.
|
||||
* @GST_BUFFER_FLAG_LAST: additional flags can be added starting from this flag.
|
||||
*
|
||||
* A set of buffer flags used to describe properties of a #GstBuffer.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_BUFFER_FLAG_READONLY = GST_MINI_OBJECT_FLAG_READONLY,
|
||||
GST_BUFFER_FLAG_MEDIA4 = GST_MINI_OBJECT_FLAG_RESERVED1,
|
||||
GST_BUFFER_FLAG_PREROLL = (GST_MINI_OBJECT_FLAG_LAST << 0),
|
||||
GST_BUFFER_FLAG_DISCONT = (GST_MINI_OBJECT_FLAG_LAST << 1),
|
||||
GST_BUFFER_FLAG_IN_CAPS = (GST_MINI_OBJECT_FLAG_LAST << 2),
|
||||
|
|
|
@ -27,9 +27,33 @@
|
|||
*
|
||||
* GstIndex is used to generate a stream index of one or more elements
|
||||
* in a pipeline.
|
||||
*
|
||||
* Elements will overload the set_index and get_index virtual methods in
|
||||
* #GstElement. When streaming data, the element will add index entries if it
|
||||
* has an index set.
|
||||
*
|
||||
* Each element that adds to the index will do that using a writer_id. The
|
||||
* writer_id is obtained from gst_index_get_writer_id().
|
||||
*
|
||||
* The application that wants to index the stream will create a new index object
|
||||
* using gst_index_new() or gst_index_factory_make(). The index is assigned to a
|
||||
* specific element, a bin or the whole pipeline. This will cause indexable
|
||||
* elements to add entires to the index while playing.
|
||||
*/
|
||||
|
||||
/* FIXME: complete gobject annotations */
|
||||
/* FIXME-0.11: cleanup API
|
||||
* - no one seems to use GstIndexGroup, GstIndexCertainty
|
||||
*
|
||||
* - the API for application to use the index is mostly missing
|
||||
* - apps need to get a list of writers
|
||||
* - apps need to be able to iterate over each writers index entry collection
|
||||
* - gst_index_get_assoc_entry() should pass ownership
|
||||
* - the GstIndexEntry structure is large and contains repetitive information
|
||||
* - we want to allow Indexers to implement a saner storage and create
|
||||
* GstIndexEntries on demand (the app has to free them), might even make
|
||||
* sense to ask the app to provide a ptr and fill it.
|
||||
*/
|
||||
|
||||
#include "gst_private.h"
|
||||
|
||||
|
@ -281,7 +305,9 @@ gst_index_group_free (GstIndexGroup * group)
|
|||
/**
|
||||
* gst_index_new:
|
||||
*
|
||||
* Create a new tileindex object
|
||||
* Create a new dummy index object. Use gst_element_set_index() to assign that
|
||||
* to an element or pipeline. This index is not storing anything, but will
|
||||
* still emit e.g. the #GstIndex::entry-added signal.
|
||||
*
|
||||
* Returns: (transfer full): a new index object
|
||||
*/
|
||||
|
@ -633,20 +659,23 @@ gst_index_gtype_resolver (GstIndex * index, GstObject * writer,
|
|||
g_return_val_if_fail (writer != NULL, FALSE);
|
||||
|
||||
if (GST_IS_PAD (writer)) {
|
||||
GstElement *element =
|
||||
(GstElement *) gst_object_get_parent (GST_OBJECT (writer));
|
||||
GstObject *element = gst_object_get_parent (GST_OBJECT (writer));
|
||||
gchar *name;
|
||||
|
||||
name = gst_object_get_name (writer);
|
||||
*writer_string = g_strdup_printf ("%s.%s",
|
||||
g_type_name (G_OBJECT_TYPE (element)), name);
|
||||
if (element) {
|
||||
*writer_string = g_strdup_printf ("%s.%s",
|
||||
G_OBJECT_TYPE_NAME (element), name);
|
||||
gst_object_unref (element);
|
||||
} else {
|
||||
*writer_string = name;
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
gst_object_unref (element);
|
||||
g_free (name);
|
||||
|
||||
} else {
|
||||
*writer_string =
|
||||
g_strdup_printf ("%s", g_type_name (G_OBJECT_TYPE (writer)));
|
||||
*writer_string = g_strdup (G_OBJECT_TYPE_NAME (writer));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -105,14 +105,17 @@ typedef void (*GstMiniObjectFinalizeFunction) (GstMiniObject *obj);
|
|||
/**
|
||||
* GstMiniObjectFlags:
|
||||
* @GST_MINI_OBJECT_FLAG_READONLY: is the miniobject readonly or writable
|
||||
* @GST_MINI_OBJECT_FLAG_RESERVED1: a flag reserved for internal use e.g. as
|
||||
* GST_BUFFER_FLAG_MEDIA4. Since: 0.10.33.
|
||||
* @GST_MINI_OBJECT_FLAG_LAST: first flag that can be used by subclasses.
|
||||
*
|
||||
* Flags for the padtemplate
|
||||
* Flags for the mini object
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_MINI_OBJECT_FLAG_READONLY = (1<<0),
|
||||
GST_MINI_OBJECT_FLAG_RESERVED1 = (1<<1),
|
||||
/* padding */
|
||||
GST_MINI_OBJECT_FLAG_LAST = (1<<4)
|
||||
} GstMiniObjectFlags;
|
||||
|
|
|
@ -2017,6 +2017,12 @@ CREATE_USERIALIZATION (uint, UINT);
|
|||
CREATE_USERIALIZATION (uint64, UINT64);
|
||||
CREATE_USERIALIZATION (ulong, ULONG);
|
||||
|
||||
/* FIXME 0.11: remove this again, plugins shouldn't have uchar properties */
|
||||
#ifndef G_MAXUCHAR
|
||||
#define G_MAXUCHAR 255
|
||||
#endif
|
||||
CREATE_USERIALIZATION (uchar, UCHAR);
|
||||
|
||||
/**********
|
||||
* double *
|
||||
**********/
|
||||
|
@ -4931,6 +4937,8 @@ _gst_value_initialize (void)
|
|||
REGISTER_SERIALIZATION (G_TYPE_UINT64, uint64);
|
||||
REGISTER_SERIALIZATION (G_TYPE_ULONG, ulong);
|
||||
|
||||
REGISTER_SERIALIZATION (G_TYPE_UCHAR, uchar);
|
||||
|
||||
g_value_register_transform_func (GST_TYPE_FOURCC, G_TYPE_STRING,
|
||||
gst_value_transform_fourcc_string);
|
||||
g_value_register_transform_func (GST_TYPE_INT_RANGE, G_TYPE_STRING,
|
||||
|
|
|
@ -248,6 +248,27 @@ struct _GstBaseTransformPrivate
|
|||
gboolean proxy_alloc;
|
||||
GstCaps *sink_alloc;
|
||||
GstCaps *src_alloc;
|
||||
|
||||
/*
|
||||
* This flag controls if basetransform should explicitly
|
||||
* do a pad alloc when it receives a buffer even if it operates on
|
||||
* passthrough, this is needed to check for downstream caps suggestions
|
||||
* and this newly alloc'ed buffer is discarded.
|
||||
*
|
||||
* Without this flag basetransform would try a pad alloc whenever it
|
||||
* gets a new buffer and pipelines like:
|
||||
* "src ! basetrans1 ! basetrans2 ! basetrans3 ! sink"
|
||||
* Would have a 3 pad allocs for each buffer pushed downstream from the src.
|
||||
*
|
||||
* This flag is set to TRUE on start up, on setcaps and when a buffer is
|
||||
* pushed downstream. It is set to FALSE after a pad alloc has been requested
|
||||
* downstream.
|
||||
* The rationale is that when a pad alloc flows through the pipeline, all
|
||||
* basetransform elements on passthrough will avoid pad alloc'ing when they
|
||||
* get the buffer.
|
||||
*/
|
||||
gboolean force_alloc;
|
||||
|
||||
/* upstream caps and size suggestions */
|
||||
GstCaps *sink_suggest;
|
||||
guint size_suggest;
|
||||
|
@ -456,6 +477,7 @@ gst_base_transform_init (GstBaseTransform * trans,
|
|||
|
||||
trans->priv->processed = 0;
|
||||
trans->priv->dropped = 0;
|
||||
trans->priv->force_alloc = TRUE;
|
||||
}
|
||||
|
||||
/* given @caps on the src or sink pad (given by @direction)
|
||||
|
@ -1167,6 +1189,8 @@ gst_base_transform_setcaps (GstPad * pad, GstCaps * caps)
|
|||
}
|
||||
|
||||
done:
|
||||
/* new caps, force alloc on next buffer on the chain */
|
||||
trans->priv->force_alloc = TRUE;
|
||||
if (otherpeer)
|
||||
gst_object_unref (otherpeer);
|
||||
if (othercaps)
|
||||
|
@ -1383,12 +1407,18 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
|
|||
goto alloc_failed;
|
||||
|
||||
if (*out_buf == NULL) {
|
||||
GST_DEBUG_OBJECT (trans, "doing alloc with caps %" GST_PTR_FORMAT, oldcaps);
|
||||
if (trans->passthrough && !trans->priv->force_alloc) {
|
||||
GST_DEBUG_OBJECT (trans, "Avoiding pad alloc");
|
||||
*out_buf = gst_buffer_ref (in_buf);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (trans, "doing alloc with caps %" GST_PTR_FORMAT,
|
||||
oldcaps);
|
||||
|
||||
ret = gst_pad_alloc_buffer (trans->srcpad,
|
||||
GST_BUFFER_OFFSET (in_buf), outsize, oldcaps, out_buf);
|
||||
if (ret != GST_FLOW_OK)
|
||||
goto alloc_failed;
|
||||
ret = gst_pad_alloc_buffer (trans->srcpad,
|
||||
GST_BUFFER_OFFSET (in_buf), outsize, oldcaps, out_buf);
|
||||
if (ret != GST_FLOW_OK)
|
||||
goto alloc_failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* must always have a buffer by now */
|
||||
|
@ -1928,6 +1958,13 @@ gst_base_transform_buffer_alloc (GstPad * pad, guint64 offset, guint size,
|
|||
if (sink_suggest)
|
||||
gst_caps_unref (sink_suggest);
|
||||
|
||||
if (res == GST_FLOW_OK) {
|
||||
/* just alloc'ed a buffer, so we only want to do this again if we
|
||||
* received a buffer */
|
||||
GST_DEBUG_OBJECT (trans, "Cleaning force alloc");
|
||||
trans->priv->force_alloc = FALSE;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
/* ERRORS */
|
||||
|
@ -2256,6 +2293,9 @@ skip:
|
|||
if (*outbuf != inbuf)
|
||||
gst_buffer_unref (inbuf);
|
||||
|
||||
/* pushed a buffer, we can now try an alloc */
|
||||
GST_DEBUG_OBJECT (trans, "Pushed a buffer, setting force alloc to true");
|
||||
trans->priv->force_alloc = TRUE;
|
||||
return ret;
|
||||
|
||||
/* ERRORS */
|
||||
|
@ -2476,6 +2516,7 @@ gst_base_transform_activate (GstBaseTransform * trans, gboolean active)
|
|||
gst_caps_replace (&trans->priv->sink_suggest, NULL);
|
||||
trans->priv->processed = 0;
|
||||
trans->priv->dropped = 0;
|
||||
trans->priv->force_alloc = TRUE;
|
||||
|
||||
GST_OBJECT_UNLOCK (trans);
|
||||
} else {
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "gstfakesink.h"
|
||||
#include <gst/gstmarshal.h>
|
||||
#include <string.h>
|
||||
|
||||
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
|
@ -480,6 +481,7 @@ gst_fake_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
|
||||
if (!sink->silent) {
|
||||
gchar ts_str[64], dur_str[64];
|
||||
gchar flag_str[100];
|
||||
|
||||
GST_OBJECT_LOCK (sink);
|
||||
g_free (sink->last_message);
|
||||
|
@ -498,12 +500,32 @@ gst_fake_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
g_strlcpy (dur_str, "none", sizeof (dur_str));
|
||||
}
|
||||
|
||||
{
|
||||
const char *flag_list[12] = {
|
||||
"ro", "media4", "", "",
|
||||
"preroll", "discont", "incaps", "gap",
|
||||
"delta_unit", "media1", "media2", "media3"
|
||||
};
|
||||
int i;
|
||||
char *end = flag_str;
|
||||
end[0] = '\0';
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (GST_MINI_OBJECT_CAST (buf)->flags & (1 << i)) {
|
||||
strcpy (end, flag_list[i]);
|
||||
end += strlen (end);
|
||||
end[0] = ' ';
|
||||
end[1] = '\0';
|
||||
end++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sink->last_message =
|
||||
g_strdup_printf ("chain ******* < (%5d bytes, timestamp: %s"
|
||||
", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %"
|
||||
G_GINT64_FORMAT ", flags: %d) %p", GST_BUFFER_SIZE (buf), ts_str,
|
||||
G_GINT64_FORMAT ", flags: %d %s) %p", GST_BUFFER_SIZE (buf), ts_str,
|
||||
dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
|
||||
GST_MINI_OBJECT_CAST (buf)->flags, buf);
|
||||
GST_MINI_OBJECT_CAST (buf)->flags, flag_str, buf);
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
|
||||
gst_fake_sink_notify_last_message (sink);
|
||||
|
|
|
@ -245,6 +245,51 @@ GST_START_TEST (test_deserialize_guint64)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_deserialize_guchar)
|
||||
{
|
||||
GValue value = { 0 };
|
||||
const char *strings[] = {
|
||||
"0xff",
|
||||
"255",
|
||||
"-1",
|
||||
"1",
|
||||
"-0",
|
||||
};
|
||||
guchar results[] = {
|
||||
0xff,
|
||||
255,
|
||||
(guchar) - 1,
|
||||
1,
|
||||
0,
|
||||
};
|
||||
int i;
|
||||
|
||||
g_value_init (&value, G_TYPE_UCHAR);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
|
||||
fail_unless (gst_value_deserialize (&value, strings[i]),
|
||||
"could not deserialize %s (%d)", strings[i], i);
|
||||
fail_unless (g_value_get_uchar (&value) == results[i],
|
||||
"resulting value is %u not %u, for string %s (%d)",
|
||||
g_value_get_uchar (&value), results[i], strings[i], i);
|
||||
}
|
||||
|
||||
/* test serialisation as well while we're at it */
|
||||
{
|
||||
gchar *str;
|
||||
GValue value = { 0 };
|
||||
g_value_init (&value, G_TYPE_UCHAR);
|
||||
|
||||
g_value_set_uchar (&value, 255);
|
||||
str = gst_value_serialize (&value);
|
||||
|
||||
fail_unless_equals_string (str, "255");
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_deserialize_gstfraction)
|
||||
{
|
||||
GValue value = { 0 };
|
||||
|
@ -2565,6 +2610,7 @@ gst_value_suite (void)
|
|||
tcase_add_test (tc_chain, test_deserialize_guint_failures);
|
||||
tcase_add_test (tc_chain, test_deserialize_gint64);
|
||||
tcase_add_test (tc_chain, test_deserialize_guint64);
|
||||
tcase_add_test (tc_chain, test_deserialize_guchar);
|
||||
tcase_add_test (tc_chain, test_deserialize_gstfraction);
|
||||
tcase_add_test (tc_chain, test_serialize_flags);
|
||||
tcase_add_test (tc_chain, test_deserialize_flags);
|
||||
|
|
|
@ -1191,6 +1191,10 @@ GST_START_TEST (basetransform_chain_ct3)
|
|||
fail_unless (res == GST_FLOW_OK);
|
||||
fail_if (buffer == NULL);
|
||||
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
|
||||
/* if we don't push here, basetransform will think it doesn't need do a
|
||||
* pad alloc for downstream caps suggestions */
|
||||
res = gst_test_trans_push (trans, buffer);
|
||||
buffer = gst_test_trans_pop (trans);
|
||||
gst_buffer_unref (buffer);
|
||||
/* FIXME should not call the pad-alloc function but it currently does */
|
||||
fail_unless (buffer_alloc_ct2_called == FALSE);
|
||||
|
|
Loading…
Reference in a new issue