mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 11:10:37 +00:00
More work on capsnego proxying. It should be OK now.
Original commit message from CVS: More work on capsnego proxying. It should be OK now. Added another testcase enum that shows various capsnego algorithms. Warn about pads that try to set a capability incompatible with their padtemplate. Implemented refcounting and copy_on_write for caps/props.
This commit is contained in:
parent
29cb713b21
commit
0267b92c93
17 changed files with 792 additions and 79 deletions
|
@ -71,6 +71,8 @@ gst_init (int *argc, char **argv[])
|
|||
|
||||
_gst_cpu_initialize ();
|
||||
_gst_type_initialize ();
|
||||
_gst_props_initialize ();
|
||||
_gst_caps_initialize ();
|
||||
_gst_plugin_initialize ();
|
||||
_gst_buffer_initialize ();
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
#include "gstbuffer.h"
|
||||
|
||||
|
||||
GMemChunk *_gst_buffer_chunk;
|
||||
GMutex *chunck_lock;
|
||||
static GMemChunk *_gst_buffer_chunk;
|
||||
static GMutex *_gst_buffer_chunk_lock;
|
||||
|
||||
void
|
||||
_gst_buffer_initialize (void)
|
||||
|
@ -36,7 +36,7 @@ _gst_buffer_initialize (void)
|
|||
_gst_buffer_chunk = g_mem_chunk_new ("GstBuffer", sizeof(GstBuffer),
|
||||
sizeof(GstBuffer) * 16, G_ALLOC_AND_FREE);
|
||||
|
||||
chunck_lock = g_mutex_new ();
|
||||
_gst_buffer_chunk_lock = g_mutex_new ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,9 +51,9 @@ gst_buffer_new(void)
|
|||
{
|
||||
GstBuffer *buffer;
|
||||
|
||||
g_mutex_lock (chunck_lock);
|
||||
g_mutex_lock (_gst_buffer_chunk_lock);
|
||||
buffer = g_mem_chunk_alloc (_gst_buffer_chunk);
|
||||
g_mutex_unlock (chunck_lock);
|
||||
g_mutex_unlock (_gst_buffer_chunk_lock);
|
||||
GST_INFO (GST_CAT_BUFFER,"creating new buffer %p",buffer);
|
||||
|
||||
// g_print("allocating new mutex\n");
|
||||
|
@ -112,9 +112,9 @@ gst_buffer_create_sub (GstBuffer *parent,
|
|||
g_return_val_if_fail (size > 0, NULL);
|
||||
g_return_val_if_fail ((offset+size) <= parent->size, NULL);
|
||||
|
||||
g_mutex_lock (chunck_lock);
|
||||
g_mutex_lock (_gst_buffer_chunk_lock);
|
||||
buffer = g_mem_chunk_alloc (_gst_buffer_chunk);
|
||||
g_mutex_unlock (chunck_lock);
|
||||
g_mutex_unlock (_gst_buffer_chunk_lock);
|
||||
GST_INFO (GST_CAT_BUFFER,"creating new subbuffer %p from parent %p", buffer, parent);
|
||||
|
||||
buffer->lock = g_mutex_new ();
|
||||
|
@ -235,9 +235,9 @@ void gst_buffer_destroy (GstBuffer *buffer)
|
|||
//g_print("freed mutex\n");
|
||||
|
||||
// remove it entirely from memory
|
||||
g_mutex_lock (chunck_lock);
|
||||
g_mutex_lock (_gst_buffer_chunk_lock);
|
||||
g_mem_chunk_free (_gst_buffer_chunk,buffer);
|
||||
g_mutex_unlock (chunck_lock);
|
||||
g_mutex_unlock (_gst_buffer_chunk_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
127
gst/gstcaps.c
127
gst/gstcaps.c
|
@ -28,10 +28,16 @@
|
|||
|
||||
#include "gstpropsprivate.h"
|
||||
|
||||
static GMemChunk *_gst_caps_chunk;
|
||||
static GMutex *_gst_caps_chunk_lock;
|
||||
|
||||
void
|
||||
_gst_caps_initialize (void)
|
||||
{
|
||||
_gst_caps_chunk = g_mem_chunk_new ("GstCaps",
|
||||
sizeof (GstCaps), sizeof (GstCaps) * 256,
|
||||
G_ALLOC_AND_FREE);
|
||||
_gst_caps_chunk_lock = g_mutex_new ();
|
||||
}
|
||||
|
||||
static guint16
|
||||
|
@ -68,11 +74,15 @@ gst_caps_new (const gchar *name, const gchar *mime)
|
|||
|
||||
g_return_val_if_fail (mime != NULL, NULL);
|
||||
|
||||
caps = g_new0 (GstCaps, 1);
|
||||
g_mutex_lock (_gst_caps_chunk_lock);
|
||||
caps = g_mem_chunk_alloc (_gst_caps_chunk);
|
||||
g_mutex_unlock (_gst_caps_chunk_lock);
|
||||
|
||||
caps->name = g_strdup (name);
|
||||
caps->id = get_type_for_mime (mime);
|
||||
caps->properties = NULL;
|
||||
caps->next = NULL;
|
||||
caps->refcount = 1;
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
@ -128,7 +138,6 @@ gst_caps_register_count (GstCapsFactory *factory, guint *counter)
|
|||
{
|
||||
GstCapsFactoryEntry tag;
|
||||
gint i = 0;
|
||||
guint16 typeid;
|
||||
gchar *name;
|
||||
GstCaps *caps;
|
||||
|
||||
|
@ -142,20 +151,110 @@ gst_caps_register_count (GstCapsFactory *factory, guint *counter)
|
|||
tag = (*factory)[i++];
|
||||
g_return_val_if_fail (tag != NULL, NULL);
|
||||
|
||||
typeid = get_type_for_mime ((gchar *)tag);
|
||||
|
||||
caps = g_new0 (GstCaps, 1);
|
||||
g_return_val_if_fail (caps != NULL, NULL);
|
||||
|
||||
caps->name = g_strdup (name);
|
||||
caps->id = typeid;
|
||||
caps->properties = gst_props_register_count (&(*factory)[i], counter);
|
||||
caps = gst_caps_new_with_props (name, (gchar *)tag,
|
||||
gst_props_register_count (&(*factory)[i], counter));
|
||||
|
||||
*counter += 2;
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_caps_destroy:
|
||||
* @caps: the caps to destroy
|
||||
*
|
||||
* Frees the memory used by this caps structure and all
|
||||
* the chained caps and properties.
|
||||
*/
|
||||
void
|
||||
gst_caps_destroy (GstCaps *caps)
|
||||
{
|
||||
g_return_if_fail (caps != NULL);
|
||||
|
||||
if (caps->next)
|
||||
gst_caps_unref (caps->next);
|
||||
|
||||
g_free (caps->name);
|
||||
g_free (caps);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_caps_unref:
|
||||
* @caps: the caps to unref
|
||||
*
|
||||
* Decrease the refcount of this caps structure,
|
||||
* destroying it when the refcount is 0
|
||||
*/
|
||||
void
|
||||
gst_caps_unref (GstCaps *caps)
|
||||
{
|
||||
g_return_if_fail (caps != NULL);
|
||||
|
||||
caps->refcount--;
|
||||
|
||||
if (caps->next)
|
||||
gst_caps_unref (caps->next);
|
||||
|
||||
if (caps->refcount == 0)
|
||||
gst_caps_destroy (caps);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_caps_ref:
|
||||
* @caps: the caps to ref
|
||||
*
|
||||
* Increase the refcount of this caps structure
|
||||
*/
|
||||
void
|
||||
gst_caps_ref (GstCaps *caps)
|
||||
{
|
||||
g_return_if_fail (caps != NULL);
|
||||
|
||||
caps->refcount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_caps_copy_on_write:
|
||||
* @caps: the caps to copy
|
||||
*
|
||||
* Copies the caps if the refcount is greater than 1
|
||||
*/
|
||||
GstCaps*
|
||||
gst_caps_copy (GstCaps *caps)
|
||||
{
|
||||
GstCaps *new = caps;;
|
||||
|
||||
g_return_val_if_fail (caps != NULL, NULL);
|
||||
|
||||
new = gst_caps_new_with_props (
|
||||
caps->name,
|
||||
(gst_type_find_by_id (caps->id))->mime,
|
||||
gst_props_copy (caps->properties));
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_caps_copy_on_write:
|
||||
* @caps: the caps to copy
|
||||
*
|
||||
* Copies the caps if the refcount is greater than 1
|
||||
*/
|
||||
GstCaps*
|
||||
gst_caps_copy_on_write (GstCaps *caps)
|
||||
{
|
||||
GstCaps *new = caps;;
|
||||
|
||||
g_return_val_if_fail (caps != NULL, NULL);
|
||||
|
||||
if (caps->refcount > 1) {
|
||||
new = gst_caps_copy (caps);
|
||||
gst_caps_unref (caps);
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_caps_get_name:
|
||||
* @caps: the caps to get the name from
|
||||
|
@ -479,9 +578,15 @@ gst_caps_load_thyself (xmlNodePtr parent)
|
|||
while (field) {
|
||||
if (!strcmp (field->name, "capscomp")) {
|
||||
xmlNodePtr subfield = field->xmlChildrenNode;
|
||||
GstCaps *caps = g_new0 (GstCaps, 1);
|
||||
GstCaps *caps;
|
||||
gchar *content;
|
||||
|
||||
g_mutex_lock (_gst_caps_chunk_lock);
|
||||
caps = g_mem_chunk_alloc0 (_gst_caps_chunk);
|
||||
g_mutex_unlock (_gst_caps_chunk_lock);
|
||||
|
||||
caps->refcount = 1;
|
||||
|
||||
while (subfield) {
|
||||
if (!strcmp (subfield->name, "name")) {
|
||||
caps->name = xmlNodeGetContent (subfield);
|
||||
|
|
|
@ -45,9 +45,10 @@ typedef GstCapsFactoryEntry GstCapsFactory[];
|
|||
|
||||
struct _GstCaps {
|
||||
gchar *name; /* the name of this caps */
|
||||
|
||||
guint16 id; /* type id (major type) */
|
||||
|
||||
guint refcount;
|
||||
|
||||
GstProps *properties; /* properties for this capability */
|
||||
|
||||
GstCaps *next;
|
||||
|
@ -61,6 +62,13 @@ GstCaps* gst_caps_new_with_props (const gchar *name, const gchar *mime, GstPro
|
|||
GstCaps* gst_caps_register (GstCapsFactory *factory);
|
||||
GstCaps* gst_caps_register_count (GstCapsFactory *factory, guint *counter);
|
||||
|
||||
void gst_caps_unref (GstCaps *caps);
|
||||
void gst_caps_ref (GstCaps *caps);
|
||||
void gst_caps_destroy (GstCaps *caps);
|
||||
|
||||
GstCaps* gst_caps_copy (GstCaps *caps);
|
||||
GstCaps* gst_caps_copy_on_write (GstCaps *caps);
|
||||
|
||||
const gchar* gst_caps_get_name (GstCaps *caps);
|
||||
void gst_caps_set_name (GstCaps *caps, const gchar *name);
|
||||
|
||||
|
|
42
gst/gstpad.c
42
gst/gstpad.c
|
@ -740,9 +740,13 @@ gst_pad_set_caps (GstPad *pad,
|
|||
if (!gst_caps_check_compatibility (caps, gst_pad_get_padtemplate_caps (pad))) {
|
||||
g_warning ("pad %s:%s tried to set caps incompatible with its padtemplate\n",
|
||||
GST_DEBUG_PAD_NAME (pad));
|
||||
return FALSE;
|
||||
//return FALSE;
|
||||
}
|
||||
|
||||
if (GST_PAD_CAPS (pad))
|
||||
gst_caps_unref (GST_PAD_CAPS (pad));
|
||||
|
||||
gst_caps_ref (caps);
|
||||
GST_PAD_CAPS(pad) = caps;
|
||||
|
||||
return gst_pad_renegotiate (pad);
|
||||
|
@ -945,7 +949,7 @@ gst_pad_renegotiate_func (GstPad *pad, GstPad *peerpad, GstCaps **newcaps, gint
|
|||
|
||||
matchtempl = gst_caps_check_compatibility (*newcaps, gst_pad_get_padtemplate_caps (GST_PAD (otherpad)));
|
||||
|
||||
GST_DEBUG (GST_CAT_ELEMENT_PADS, "caps compatibility check %d\n", matchtempl);
|
||||
GST_DEBUG (GST_CAT_ELEMENT_PADS, "caps compatibility check %s\n", (matchtempl?"ok":"fail"));
|
||||
|
||||
if (matchtempl) {
|
||||
if (otherpad->negotiatefunc) {
|
||||
|
@ -963,17 +967,19 @@ gst_pad_renegotiate_func (GstPad *pad, GstPad *peerpad, GstCaps **newcaps, gint
|
|||
}
|
||||
else {
|
||||
*newcaps = GST_PAD_CAPS (otherpad);
|
||||
gst_caps_ref(*newcaps);
|
||||
}
|
||||
}
|
||||
else {
|
||||
*newcaps = GST_PAD_CAPS (otherpad);
|
||||
gst_caps_ref(*newcaps);
|
||||
}
|
||||
|
||||
(*counter)++;
|
||||
|
||||
if (currentpad->negotiatefunc) {
|
||||
GST_DEBUG (GST_CAT_ELEMENT_PADS, "calling negotiate function on pad %s:%s\n",
|
||||
GST_DEBUG_PAD_NAME (currentpad));
|
||||
GST_DEBUG (GST_CAT_ELEMENT_PADS, "calling negotiate function on pad %s:%s counter: %d\n",
|
||||
GST_DEBUG_PAD_NAME (currentpad), *counter);
|
||||
result = currentpad->negotiatefunc (GST_PAD (currentpad), newcaps, *counter);
|
||||
|
||||
switch (result) {
|
||||
|
@ -995,6 +1001,9 @@ gst_pad_renegotiate_func (GstPad *pad, GstPad *peerpad, GstCaps **newcaps, gint
|
|||
|
||||
} while (*counter < 100);
|
||||
|
||||
g_warning ("negotiation between (%s:%s) and (%s:%s) failed: too many attempts (%d)\n",
|
||||
GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad), *counter);
|
||||
|
||||
GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiation failed, too many attempts\n");
|
||||
|
||||
return FALSE;
|
||||
|
@ -1051,28 +1060,31 @@ gst_pad_renegotiate (GstPad *pad)
|
|||
|
||||
|
||||
GstPadNegotiateReturn
|
||||
gst_pad_negotiate_proxy (GstPad *pad, GstCaps **caps, gint counter)
|
||||
gst_pad_negotiate_proxy (GstPad *srcpad, GstPad *destpad, GstCaps **caps, gint counter)
|
||||
{
|
||||
GstRealPad *peer;
|
||||
GstRealPad *srcpeer;
|
||||
GstRealPad *destpeer;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (pad != NULL, GST_PAD_NEGOTIATE_FAIL);
|
||||
g_return_val_if_fail (srcpad != NULL, GST_PAD_NEGOTIATE_FAIL);
|
||||
g_return_val_if_fail (destpad != NULL, GST_PAD_NEGOTIATE_FAIL);
|
||||
|
||||
GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiation proxied to pad (%s:%s)\n", GST_DEBUG_PAD_NAME (pad));
|
||||
GST_DEBUG (GST_CAT_ELEMENT_PADS, "negotiation proxied from pad (%s:%s) to pad (%s:%s)\n",
|
||||
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
|
||||
|
||||
peer = GST_RPAD_PEER (pad);
|
||||
srcpeer = GST_RPAD_PEER (srcpad);
|
||||
destpeer = GST_RPAD_PEER (destpad);
|
||||
|
||||
//GST_PAD_CAPS (pad) = caps;
|
||||
|
||||
if (peer) {
|
||||
result = gst_pad_renegotiate_func (pad, GST_PAD (peer), caps, &counter);
|
||||
if (srcpeer && destpeer) {
|
||||
counter--;
|
||||
result = gst_pad_renegotiate_func (GST_PAD (srcpeer), GST_PAD (destpeer), caps, &counter);
|
||||
|
||||
if (result) {
|
||||
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pads aggreed on caps :)\n");
|
||||
|
||||
/* here we have some sort of aggreement of the caps */
|
||||
GST_PAD_CAPS (pad) = *caps;
|
||||
GST_PAD_CAPS (peer) = *caps;
|
||||
GST_PAD_CAPS (srcpad) = *caps;
|
||||
GST_PAD_CAPS (destpad) = *caps;
|
||||
}
|
||||
else {
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
|
|
|
@ -309,7 +309,7 @@ gboolean gst_pad_connect (GstPad *srcpad, GstPad *sinkpad);
|
|||
void gst_pad_disconnect (GstPad *srcpad, GstPad *sinkpad);
|
||||
|
||||
gboolean gst_pad_renegotiate (GstPad *pad);
|
||||
GstPadNegotiateReturn gst_pad_negotiate_proxy (GstPad *pad, GstCaps **caps, gint count);
|
||||
GstPadNegotiateReturn gst_pad_negotiate_proxy (GstPad *srcpad, GstPad *destpad, GstCaps **caps, gint count);
|
||||
|
||||
#if 1
|
||||
void gst_pad_push (GstPad *pad, GstBuffer *buf);
|
||||
|
|
|
@ -227,7 +227,7 @@ gst_plugin_load_all(void)
|
|||
|
||||
path = _gst_plugin_paths;
|
||||
while (path != NULL) {
|
||||
GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugins from %s\n",(gchar *)path->data);
|
||||
GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugins from %s",(gchar *)path->data);
|
||||
gst_plugin_load_recurse(path->data,NULL);
|
||||
path = g_list_next(path);
|
||||
}
|
||||
|
|
153
gst/gstprops.c
153
gst/gstprops.c
|
@ -26,6 +26,11 @@
|
|||
#include "gstprops.h"
|
||||
#include "gstpropsprivate.h"
|
||||
|
||||
static GMemChunk *_gst_props_entries_chunk;
|
||||
static GMutex *_gst_props_entries_chunk_lock;
|
||||
|
||||
static GMemChunk *_gst_props_chunk;
|
||||
static GMutex *_gst_props_chunk_lock;
|
||||
|
||||
static gboolean gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry2);
|
||||
|
||||
|
@ -41,6 +46,15 @@ static guint _arg_len[] = {
|
|||
void
|
||||
_gst_props_initialize (void)
|
||||
{
|
||||
_gst_props_entries_chunk = g_mem_chunk_new ("GstPropsEntries",
|
||||
sizeof (GstPropsEntry), sizeof (GstPropsEntry) * 256,
|
||||
G_ALLOC_AND_FREE);
|
||||
_gst_props_entries_chunk_lock = g_mutex_new ();
|
||||
|
||||
_gst_props_chunk = g_mem_chunk_new ("GstProps",
|
||||
sizeof (GstProps), sizeof (GstProps) * 256,
|
||||
G_ALLOC_AND_FREE);
|
||||
_gst_props_chunk_lock = g_mutex_new ();
|
||||
}
|
||||
|
||||
static GstPropsEntry*
|
||||
|
@ -50,7 +64,9 @@ gst_props_create_entry (GstPropsFactory factory, gint *skipped)
|
|||
GstPropsEntry *entry;
|
||||
guint i=0;
|
||||
|
||||
entry = g_new0 (GstPropsEntry, 1);
|
||||
g_mutex_lock (_gst_props_entries_chunk_lock);
|
||||
entry = g_mem_chunk_alloc (_gst_props_entries_chunk);
|
||||
g_mutex_unlock (_gst_props_entries_chunk_lock);
|
||||
|
||||
tag = factory[i++];
|
||||
switch (GPOINTER_TO_INT (tag)) {
|
||||
|
@ -68,15 +84,17 @@ gst_props_create_entry (GstPropsFactory factory, gint *skipped)
|
|||
entry->data.fourcc_data = GPOINTER_TO_INT (factory[i++]);
|
||||
break;
|
||||
case GST_PROPS_LIST_ID_NUM:
|
||||
g_print("gstprops: list not allowed in list\n");
|
||||
g_warning ("gstprops: list not allowed in list\n");
|
||||
break;
|
||||
case GST_PROPS_BOOL_ID_NUM:
|
||||
entry->propstype = GST_PROPS_BOOL_ID_NUM;
|
||||
entry->data.bool_data = GPOINTER_TO_INT (factory[i++]);
|
||||
break;
|
||||
default:
|
||||
g_print("gstprops: unknown props id found\n");
|
||||
g_free (entry);
|
||||
g_warning ("gstprops: unknown props id found\n");
|
||||
g_mutex_lock (_gst_props_entries_chunk_lock);
|
||||
g_mem_chunk_free (_gst_props_entries_chunk, entry);
|
||||
g_mutex_unlock (_gst_props_entries_chunk_lock);
|
||||
entry = NULL;
|
||||
break;
|
||||
}
|
||||
|
@ -146,10 +164,14 @@ gst_props_register_count (GstPropsFactory factory, guint *counter)
|
|||
|
||||
if (!tag) goto end;
|
||||
|
||||
props = g_new0 (GstProps, 1);
|
||||
g_mutex_lock (_gst_props_chunk_lock);
|
||||
props = g_mem_chunk_alloc (_gst_props_chunk);
|
||||
g_mutex_unlock (_gst_props_chunk_lock);
|
||||
|
||||
g_return_val_if_fail (props != NULL, NULL);
|
||||
|
||||
props->properties = NULL;
|
||||
props->refcount = 1;
|
||||
|
||||
while (tag) {
|
||||
GQuark quark;
|
||||
|
@ -168,7 +190,10 @@ gst_props_register_count (GstPropsFactory factory, guint *counter)
|
|||
{
|
||||
GstPropsEntry *list_entry;
|
||||
|
||||
entry = g_new0 (GstPropsEntry, 1);
|
||||
g_mutex_lock (_gst_props_entries_chunk_lock);
|
||||
entry = g_mem_chunk_alloc (_gst_props_entries_chunk);
|
||||
g_mutex_unlock (_gst_props_entries_chunk_lock);
|
||||
|
||||
entry->propid = quark;
|
||||
entry->propstype = GST_PROPS_LIST_ID_NUM;
|
||||
entry->data.list_data.entries = NULL;
|
||||
|
@ -331,6 +356,99 @@ gst_props_set (GstProps *props, const gchar *name, GstPropsFactoryEntry entry, .
|
|||
return props;
|
||||
}
|
||||
|
||||
void
|
||||
gst_props_unref (GstProps *props)
|
||||
{
|
||||
g_return_if_fail (props != NULL);
|
||||
|
||||
props->refcount--;
|
||||
|
||||
if (props->refcount == 0)
|
||||
gst_props_destroy (props);
|
||||
}
|
||||
|
||||
void
|
||||
gst_props_ref (GstProps *props)
|
||||
{
|
||||
g_return_if_fail (props != NULL);
|
||||
|
||||
props->refcount++;
|
||||
}
|
||||
|
||||
void
|
||||
gst_props_destroy (GstProps *props)
|
||||
{
|
||||
GList *entries;
|
||||
|
||||
g_return_if_fail (props != NULL);
|
||||
|
||||
entries = props->properties;
|
||||
|
||||
while (entries) {
|
||||
GstPropsEntry *entry = (GstPropsEntry *)entries->data;
|
||||
|
||||
// FIXME also free the lists
|
||||
g_mutex_lock (_gst_props_entries_chunk_lock);
|
||||
g_mem_chunk_free (_gst_props_entries_chunk, entry);
|
||||
g_mutex_unlock (_gst_props_entries_chunk_lock);
|
||||
|
||||
entries = g_list_next (entries);
|
||||
}
|
||||
|
||||
g_list_free (props->properties);
|
||||
}
|
||||
|
||||
GstProps*
|
||||
gst_props_copy (GstProps *props)
|
||||
{
|
||||
GstProps *new;
|
||||
GList *properties;
|
||||
|
||||
g_return_val_if_fail (props != NULL, NULL);
|
||||
|
||||
g_mutex_lock (_gst_props_chunk_lock);
|
||||
new = g_mem_chunk_alloc (_gst_props_chunk);
|
||||
g_mutex_unlock (_gst_props_chunk_lock);
|
||||
|
||||
new->properties = NULL;
|
||||
|
||||
properties = props->properties;
|
||||
|
||||
while (properties) {
|
||||
GstPropsEntry *entry = (GstPropsEntry *)properties->data;
|
||||
GstPropsEntry *newentry;
|
||||
|
||||
g_mutex_lock (_gst_props_entries_chunk_lock);
|
||||
newentry = g_mem_chunk_alloc (_gst_props_entries_chunk);
|
||||
g_mutex_unlock (_gst_props_entries_chunk_lock);
|
||||
|
||||
// FIXME copy lists too
|
||||
memcpy (newentry, entry, sizeof (GstPropsEntry));
|
||||
|
||||
new->properties = g_list_prepend (new->properties, newentry);
|
||||
|
||||
properties = g_list_next (properties);
|
||||
}
|
||||
new->properties = g_list_reverse (new->properties);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
GstProps*
|
||||
gst_props_copy_on_write (GstProps *props)
|
||||
{
|
||||
GstProps *new = props;;
|
||||
|
||||
g_return_val_if_fail (props != NULL, NULL);
|
||||
|
||||
if (props->refcount > 1) {
|
||||
new = gst_props_copy (props);
|
||||
gst_props_unref (props);
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
gint
|
||||
gst_props_get_int (GstProps *props, const gchar *name)
|
||||
{
|
||||
|
@ -681,7 +799,9 @@ gst_props_load_thyself_func (xmlNodePtr field)
|
|||
GstPropsEntry *entry;
|
||||
gchar *prop;
|
||||
|
||||
entry = g_new0 (GstPropsEntry, 1);
|
||||
g_mutex_lock (_gst_props_entries_chunk_lock);
|
||||
entry = g_mem_chunk_alloc (_gst_props_entries_chunk);
|
||||
g_mutex_unlock (_gst_props_entries_chunk_lock);
|
||||
|
||||
if (!strcmp(field->name, "int")) {
|
||||
entry->propstype = GST_PROPS_INT_ID_NUM;
|
||||
|
@ -724,7 +844,9 @@ gst_props_load_thyself_func (xmlNodePtr field)
|
|||
g_free (prop);
|
||||
}
|
||||
else {
|
||||
g_free (entry);
|
||||
g_mutex_lock (_gst_props_entries_chunk_lock);
|
||||
g_mem_chunk_free (_gst_props_entries_chunk, entry);
|
||||
g_mutex_unlock (_gst_props_entries_chunk_lock);
|
||||
entry = NULL;
|
||||
}
|
||||
|
||||
|
@ -742,17 +864,28 @@ gst_props_load_thyself_func (xmlNodePtr field)
|
|||
GstProps*
|
||||
gst_props_load_thyself (xmlNodePtr parent)
|
||||
{
|
||||
GstProps *props = g_new0 (GstProps, 1);
|
||||
GstProps *props;
|
||||
xmlNodePtr field = parent->xmlChildrenNode;
|
||||
gchar *prop;
|
||||
|
||||
g_mutex_lock (_gst_props_chunk_lock);
|
||||
props = g_mem_chunk_alloc (_gst_props_chunk);
|
||||
g_mutex_unlock (_gst_props_chunk_lock);
|
||||
|
||||
props->properties = NULL;
|
||||
props->refcount = 1;
|
||||
|
||||
while (field) {
|
||||
if (!strcmp (field->name, "list")) {
|
||||
GstPropsEntry *entry;
|
||||
xmlNodePtr subfield = field->xmlChildrenNode;
|
||||
|
||||
entry = g_new0 (GstPropsEntry, 1);
|
||||
g_mutex_lock (_gst_props_entries_chunk_lock);
|
||||
entry = g_mem_chunk_alloc (_gst_props_entries_chunk);
|
||||
g_mutex_unlock (_gst_props_entries_chunk_lock);
|
||||
|
||||
entry->propstype = GST_PROPS_LIST_ID_NUM;
|
||||
entry->data.list_data.entries = NULL;
|
||||
prop = xmlGetProp (field, "name");
|
||||
entry->propid = g_quark_from_string (prop);
|
||||
g_free (prop);
|
||||
|
|
|
@ -67,6 +67,8 @@ typedef enum {
|
|||
|
||||
|
||||
struct _GstProps {
|
||||
gint refcount;
|
||||
|
||||
GList *properties; /* real properties for this property */
|
||||
};
|
||||
|
||||
|
@ -78,6 +80,13 @@ GstProps* gst_props_register_count (GstPropsFactory factory, guint *counter);
|
|||
|
||||
GstProps* gst_props_new (GstPropsFactoryEntry entry, ...);
|
||||
|
||||
void gst_props_unref (GstProps *props);
|
||||
void gst_props_ref (GstProps *props);
|
||||
void gst_props_destroy (GstProps *props);
|
||||
|
||||
GstProps* gst_props_copy (GstProps *props);
|
||||
GstProps* gst_props_copy_on_write (GstProps *props);
|
||||
|
||||
GstProps* gst_props_merge (GstProps *props, GstProps *tomerge);
|
||||
|
||||
gboolean gst_props_check_compatibility (GstProps *fromprops, GstProps *toprops);
|
||||
|
|
|
@ -159,17 +159,10 @@ gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
|
|||
|
||||
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
|
||||
|
||||
if (counter == 0) {
|
||||
*caps = NULL;
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
if (*caps) {
|
||||
if (counter == 1) {
|
||||
return gst_pad_negotiate_proxy (queue->sinkpad, caps, counter);
|
||||
}
|
||||
}
|
||||
return gst_pad_negotiate_proxy (pad, queue->sinkpad, caps, counter);
|
||||
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
|
||||
//return GST_PAD_NEGOTIATE_FAIL;
|
||||
}
|
||||
|
||||
static GstPadNegotiateReturn
|
||||
|
@ -179,17 +172,19 @@ gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
|
|||
|
||||
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
|
||||
|
||||
/*
|
||||
if (counter == 0) {
|
||||
*caps = NULL;
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
if (*caps) {
|
||||
if (counter == 1) {
|
||||
return gst_pad_negotiate_proxy (queue->srcpad, caps, counter);
|
||||
}
|
||||
*/
|
||||
return gst_pad_negotiate_proxy (pad, queue->srcpad, caps, counter);
|
||||
/*
|
||||
}
|
||||
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
*/
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
@ -159,17 +159,10 @@ gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
|
|||
|
||||
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
|
||||
|
||||
if (counter == 0) {
|
||||
*caps = NULL;
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
if (*caps) {
|
||||
if (counter == 1) {
|
||||
return gst_pad_negotiate_proxy (queue->sinkpad, caps, counter);
|
||||
}
|
||||
}
|
||||
return gst_pad_negotiate_proxy (pad, queue->sinkpad, caps, counter);
|
||||
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
|
||||
//return GST_PAD_NEGOTIATE_FAIL;
|
||||
}
|
||||
|
||||
static GstPadNegotiateReturn
|
||||
|
@ -179,17 +172,19 @@ gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
|
|||
|
||||
queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
|
||||
|
||||
/*
|
||||
if (counter == 0) {
|
||||
*caps = NULL;
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
if (*caps) {
|
||||
if (counter == 1) {
|
||||
return gst_pad_negotiate_proxy (queue->srcpad, caps, counter);
|
||||
}
|
||||
*/
|
||||
return gst_pad_negotiate_proxy (pad, queue->srcpad, caps, counter);
|
||||
/*
|
||||
}
|
||||
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
*/
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
SUBDIRS =
|
||||
|
||||
testprogs = capsnego converter converter2
|
||||
testprogs = capsnego converter converter2 enum
|
||||
|
||||
TESTS = $(testprogs)
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ converter_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
|
|||
|
||||
if (counter == 1) {
|
||||
converter_out = gst_caps_get_int (*caps, "rate");
|
||||
return gst_pad_negotiate_proxy (srcconvpad, caps, counter);
|
||||
return gst_pad_negotiate_proxy (pad, srcconvpad, caps, counter);
|
||||
}
|
||||
return GST_PAD_NEGOTIATE_AGREE;
|
||||
}
|
||||
|
|
227
tests/old/testsuite/capsnego/enum.c
Normal file
227
tests/old/testsuite/capsnego/enum.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
|
||||
GstPad *srcconvpad, *sinkconvpad;
|
||||
GstPadTemplate *srcconvtempl, *sinkconvtempl;
|
||||
|
||||
static GstPadFactory src_conv_factory = {
|
||||
"src",
|
||||
GST_PAD_FACTORY_SRC,
|
||||
GST_PAD_FACTORY_ALWAYS,
|
||||
GST_PAD_FACTORY_CAPS(
|
||||
"test_src",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT_RANGE (16, 20000)
|
||||
),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static GstPadFactory sink_conv_factory = {
|
||||
"src",
|
||||
GST_PAD_FACTORY_SINK,
|
||||
GST_PAD_FACTORY_ALWAYS,
|
||||
GST_PAD_FACTORY_CAPS(
|
||||
"test_src",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT_RANGE (16, 20000)
|
||||
),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static GstCapsFactory src_caps = {
|
||||
"src_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (3000),
|
||||
NULL
|
||||
};
|
||||
|
||||
static GstCaps *srccaps, *sinkcaps;
|
||||
|
||||
static gint src_rate = 140;
|
||||
static gint sink_rate = 100;
|
||||
|
||||
static GstPadNegotiateReturn
|
||||
negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
|
||||
{
|
||||
g_print (">(%d:%d)", src_rate, (*caps)->refcount);
|
||||
src_rate++;
|
||||
|
||||
if (counter == 0 || caps == NULL) {
|
||||
g_print ("*");
|
||||
*caps = gst_caps_new_with_props (
|
||||
"src_caps",
|
||||
"audio/raw",
|
||||
gst_props_new (
|
||||
"rate", GST_PROPS_INT (src_rate),
|
||||
NULL)
|
||||
);
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
if (*caps) {
|
||||
gint in_rate = gst_caps_get_int (*caps, "rate");
|
||||
g_print ("(%d)", in_rate);
|
||||
|
||||
if (in_rate > 140 && in_rate < 300) {
|
||||
g_print ("A");
|
||||
return GST_PAD_NEGOTIATE_AGREE;
|
||||
}
|
||||
|
||||
*caps = gst_caps_copy_on_write (*caps);
|
||||
gst_caps_set (*caps, "rate", GST_PROPS_INT (src_rate));
|
||||
g_print ("T");
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
|
||||
g_print ("F");
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
}
|
||||
|
||||
static GstPadNegotiateReturn
|
||||
negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
|
||||
{
|
||||
|
||||
g_print ("<(%d:%d:%p)", sink_rate, (*caps)->refcount, *caps);
|
||||
sink_rate++;
|
||||
|
||||
if (counter == 0 || *caps == NULL) {
|
||||
g_print ("*");
|
||||
*caps = gst_caps_new_with_props (
|
||||
"sink_caps",
|
||||
"audio/raw",
|
||||
gst_props_new (
|
||||
"rate", GST_PROPS_INT (sink_rate),
|
||||
NULL)
|
||||
);
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
if (*caps) {
|
||||
gint in_rate = gst_caps_get_int (*caps, "rate");
|
||||
g_print ("(%d)", in_rate);
|
||||
|
||||
if (in_rate >= 100 && in_rate < 140) {
|
||||
g_print ("A");
|
||||
return GST_PAD_NEGOTIATE_AGREE;
|
||||
}
|
||||
|
||||
*caps = gst_caps_copy_on_write (*caps);
|
||||
g_print ("%p", *caps);
|
||||
gst_caps_set (*caps, "rate", GST_PROPS_INT (sink_rate));
|
||||
|
||||
g_print ("T");
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
|
||||
g_print ("F");
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
gboolean overall = TRUE;
|
||||
gboolean result;
|
||||
GstElement *queue;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
g_mem_chunk_info();
|
||||
|
||||
srcconvtempl = gst_padtemplate_new (&src_conv_factory);
|
||||
sinkconvtempl = gst_padtemplate_new (&sink_conv_factory);
|
||||
srcconvpad = gst_pad_new_from_template (srcconvtempl, "src");
|
||||
sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "sink");
|
||||
|
||||
gst_pad_set_negotiate_function (srcconvpad, negotiate_src);
|
||||
gst_pad_set_negotiate_function (sinkconvpad, negotiate_sink);
|
||||
|
||||
srccaps = gst_caps_register (&src_caps);
|
||||
sinkcaps = gst_caps_copy (srccaps);
|
||||
|
||||
g_print ("The wild goose chase...\n");
|
||||
|
||||
result = gst_pad_connect (srcconvpad, sinkconvpad);
|
||||
g_print ("pad connect 1: %d\n", result);
|
||||
overall &= (result == TRUE);
|
||||
|
||||
result = gst_pad_set_caps (srcconvpad, srccaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
g_print ("with the src negotiate function disabled...\n");
|
||||
|
||||
GST_PAD_CAPS (srcconvpad) = NULL;
|
||||
GST_PAD_CAPS (sinkconvpad) = NULL;
|
||||
src_rate = 140;
|
||||
sink_rate = 100;
|
||||
|
||||
gst_pad_set_negotiate_function (srcconvpad, NULL);
|
||||
|
||||
gst_caps_set (srccaps, "rate", GST_PROPS_INT (120));
|
||||
result = gst_pad_set_caps (srcconvpad, srccaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
|
||||
g_print ("with the sink negotiate function disabled...\n");
|
||||
|
||||
GST_PAD_CAPS (srcconvpad) = NULL;
|
||||
GST_PAD_CAPS (sinkconvpad) = NULL;
|
||||
src_rate = 140;
|
||||
sink_rate = 100;
|
||||
|
||||
gst_pad_set_negotiate_function (srcconvpad, negotiate_src);
|
||||
gst_pad_set_negotiate_function (sinkconvpad, NULL);
|
||||
|
||||
gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (170));
|
||||
result = gst_pad_set_caps (sinkconvpad, sinkcaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
g_print ("without negotiate functions...\n");
|
||||
|
||||
GST_PAD_CAPS (srcconvpad) = NULL;
|
||||
GST_PAD_CAPS (sinkconvpad) = NULL;
|
||||
src_rate = 140;
|
||||
sink_rate = 100;
|
||||
|
||||
gst_pad_set_negotiate_function (srcconvpad, NULL);
|
||||
gst_pad_set_negotiate_function (sinkconvpad, NULL);
|
||||
|
||||
sinkcaps = gst_caps_copy (sinkcaps);
|
||||
gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (150));
|
||||
result = gst_pad_set_caps (sinkconvpad, sinkcaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
|
||||
sinkcaps = gst_caps_copy (sinkcaps);
|
||||
gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (160));
|
||||
result = gst_pad_set_caps (sinkconvpad, sinkcaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
g_print ("with a proxy element in between...\n");
|
||||
|
||||
gst_pad_disconnect (srcconvpad, sinkconvpad);
|
||||
|
||||
queue = gst_elementfactory_make ("queue", "queue");
|
||||
|
||||
GST_PAD_CAPS (srcconvpad) = NULL;
|
||||
GST_PAD_CAPS (sinkconvpad) = NULL;
|
||||
src_rate = 140;
|
||||
sink_rate = 100;
|
||||
|
||||
gst_pad_set_negotiate_function (srcconvpad, negotiate_src);
|
||||
gst_pad_set_negotiate_function (sinkconvpad, negotiate_sink);
|
||||
|
||||
gst_pad_connect (srcconvpad, gst_element_get_pad (queue, "sink"));
|
||||
gst_pad_connect (gst_element_get_pad (queue, "src"), sinkconvpad);
|
||||
|
||||
gst_caps_set (srccaps, "rate", GST_PROPS_INT (50));
|
||||
result = gst_pad_set_caps (srcconvpad, srccaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
|
||||
exit (!overall);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
SUBDIRS =
|
||||
|
||||
testprogs = capsnego converter converter2
|
||||
testprogs = capsnego converter converter2 enum
|
||||
|
||||
TESTS = $(testprogs)
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ converter_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
|
|||
|
||||
if (counter == 1) {
|
||||
converter_out = gst_caps_get_int (*caps, "rate");
|
||||
return gst_pad_negotiate_proxy (srcconvpad, caps, counter);
|
||||
return gst_pad_negotiate_proxy (pad, srcconvpad, caps, counter);
|
||||
}
|
||||
return GST_PAD_NEGOTIATE_AGREE;
|
||||
}
|
||||
|
|
227
testsuite/capsnego/enum.c
Normal file
227
testsuite/capsnego/enum.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
|
||||
GstPad *srcconvpad, *sinkconvpad;
|
||||
GstPadTemplate *srcconvtempl, *sinkconvtempl;
|
||||
|
||||
static GstPadFactory src_conv_factory = {
|
||||
"src",
|
||||
GST_PAD_FACTORY_SRC,
|
||||
GST_PAD_FACTORY_ALWAYS,
|
||||
GST_PAD_FACTORY_CAPS(
|
||||
"test_src",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT_RANGE (16, 20000)
|
||||
),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static GstPadFactory sink_conv_factory = {
|
||||
"src",
|
||||
GST_PAD_FACTORY_SINK,
|
||||
GST_PAD_FACTORY_ALWAYS,
|
||||
GST_PAD_FACTORY_CAPS(
|
||||
"test_src",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT_RANGE (16, 20000)
|
||||
),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static GstCapsFactory src_caps = {
|
||||
"src_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (3000),
|
||||
NULL
|
||||
};
|
||||
|
||||
static GstCaps *srccaps, *sinkcaps;
|
||||
|
||||
static gint src_rate = 140;
|
||||
static gint sink_rate = 100;
|
||||
|
||||
static GstPadNegotiateReturn
|
||||
negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
|
||||
{
|
||||
g_print (">(%d:%d)", src_rate, (*caps)->refcount);
|
||||
src_rate++;
|
||||
|
||||
if (counter == 0 || caps == NULL) {
|
||||
g_print ("*");
|
||||
*caps = gst_caps_new_with_props (
|
||||
"src_caps",
|
||||
"audio/raw",
|
||||
gst_props_new (
|
||||
"rate", GST_PROPS_INT (src_rate),
|
||||
NULL)
|
||||
);
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
if (*caps) {
|
||||
gint in_rate = gst_caps_get_int (*caps, "rate");
|
||||
g_print ("(%d)", in_rate);
|
||||
|
||||
if (in_rate > 140 && in_rate < 300) {
|
||||
g_print ("A");
|
||||
return GST_PAD_NEGOTIATE_AGREE;
|
||||
}
|
||||
|
||||
*caps = gst_caps_copy_on_write (*caps);
|
||||
gst_caps_set (*caps, "rate", GST_PROPS_INT (src_rate));
|
||||
g_print ("T");
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
|
||||
g_print ("F");
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
}
|
||||
|
||||
static GstPadNegotiateReturn
|
||||
negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
|
||||
{
|
||||
|
||||
g_print ("<(%d:%d:%p)", sink_rate, (*caps)->refcount, *caps);
|
||||
sink_rate++;
|
||||
|
||||
if (counter == 0 || *caps == NULL) {
|
||||
g_print ("*");
|
||||
*caps = gst_caps_new_with_props (
|
||||
"sink_caps",
|
||||
"audio/raw",
|
||||
gst_props_new (
|
||||
"rate", GST_PROPS_INT (sink_rate),
|
||||
NULL)
|
||||
);
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
if (*caps) {
|
||||
gint in_rate = gst_caps_get_int (*caps, "rate");
|
||||
g_print ("(%d)", in_rate);
|
||||
|
||||
if (in_rate >= 100 && in_rate < 140) {
|
||||
g_print ("A");
|
||||
return GST_PAD_NEGOTIATE_AGREE;
|
||||
}
|
||||
|
||||
*caps = gst_caps_copy_on_write (*caps);
|
||||
g_print ("%p", *caps);
|
||||
gst_caps_set (*caps, "rate", GST_PROPS_INT (sink_rate));
|
||||
|
||||
g_print ("T");
|
||||
return GST_PAD_NEGOTIATE_TRY;
|
||||
}
|
||||
|
||||
g_print ("F");
|
||||
return GST_PAD_NEGOTIATE_FAIL;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
gboolean overall = TRUE;
|
||||
gboolean result;
|
||||
GstElement *queue;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
g_mem_chunk_info();
|
||||
|
||||
srcconvtempl = gst_padtemplate_new (&src_conv_factory);
|
||||
sinkconvtempl = gst_padtemplate_new (&sink_conv_factory);
|
||||
srcconvpad = gst_pad_new_from_template (srcconvtempl, "src");
|
||||
sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "sink");
|
||||
|
||||
gst_pad_set_negotiate_function (srcconvpad, negotiate_src);
|
||||
gst_pad_set_negotiate_function (sinkconvpad, negotiate_sink);
|
||||
|
||||
srccaps = gst_caps_register (&src_caps);
|
||||
sinkcaps = gst_caps_copy (srccaps);
|
||||
|
||||
g_print ("The wild goose chase...\n");
|
||||
|
||||
result = gst_pad_connect (srcconvpad, sinkconvpad);
|
||||
g_print ("pad connect 1: %d\n", result);
|
||||
overall &= (result == TRUE);
|
||||
|
||||
result = gst_pad_set_caps (srcconvpad, srccaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
g_print ("with the src negotiate function disabled...\n");
|
||||
|
||||
GST_PAD_CAPS (srcconvpad) = NULL;
|
||||
GST_PAD_CAPS (sinkconvpad) = NULL;
|
||||
src_rate = 140;
|
||||
sink_rate = 100;
|
||||
|
||||
gst_pad_set_negotiate_function (srcconvpad, NULL);
|
||||
|
||||
gst_caps_set (srccaps, "rate", GST_PROPS_INT (120));
|
||||
result = gst_pad_set_caps (srcconvpad, srccaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
|
||||
g_print ("with the sink negotiate function disabled...\n");
|
||||
|
||||
GST_PAD_CAPS (srcconvpad) = NULL;
|
||||
GST_PAD_CAPS (sinkconvpad) = NULL;
|
||||
src_rate = 140;
|
||||
sink_rate = 100;
|
||||
|
||||
gst_pad_set_negotiate_function (srcconvpad, negotiate_src);
|
||||
gst_pad_set_negotiate_function (sinkconvpad, NULL);
|
||||
|
||||
gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (170));
|
||||
result = gst_pad_set_caps (sinkconvpad, sinkcaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
g_print ("without negotiate functions...\n");
|
||||
|
||||
GST_PAD_CAPS (srcconvpad) = NULL;
|
||||
GST_PAD_CAPS (sinkconvpad) = NULL;
|
||||
src_rate = 140;
|
||||
sink_rate = 100;
|
||||
|
||||
gst_pad_set_negotiate_function (srcconvpad, NULL);
|
||||
gst_pad_set_negotiate_function (sinkconvpad, NULL);
|
||||
|
||||
sinkcaps = gst_caps_copy (sinkcaps);
|
||||
gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (150));
|
||||
result = gst_pad_set_caps (sinkconvpad, sinkcaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
|
||||
sinkcaps = gst_caps_copy (sinkcaps);
|
||||
gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (160));
|
||||
result = gst_pad_set_caps (sinkconvpad, sinkcaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
g_print ("with a proxy element in between...\n");
|
||||
|
||||
gst_pad_disconnect (srcconvpad, sinkconvpad);
|
||||
|
||||
queue = gst_elementfactory_make ("queue", "queue");
|
||||
|
||||
GST_PAD_CAPS (srcconvpad) = NULL;
|
||||
GST_PAD_CAPS (sinkconvpad) = NULL;
|
||||
src_rate = 140;
|
||||
sink_rate = 100;
|
||||
|
||||
gst_pad_set_negotiate_function (srcconvpad, negotiate_src);
|
||||
gst_pad_set_negotiate_function (sinkconvpad, negotiate_sink);
|
||||
|
||||
gst_pad_connect (srcconvpad, gst_element_get_pad (queue, "sink"));
|
||||
gst_pad_connect (gst_element_get_pad (queue, "src"), sinkconvpad);
|
||||
|
||||
gst_caps_set (srccaps, "rate", GST_PROPS_INT (50));
|
||||
result = gst_pad_set_caps (srcconvpad, srccaps);
|
||||
g_print ("\nset caps on src: %d, final rate: %d\n", result,
|
||||
gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate"));
|
||||
|
||||
|
||||
exit (!overall);
|
||||
}
|
Loading…
Reference in a new issue