Reworked the capsnegotiation function audiosink now uses capsnego to set its parameters mpg123/ac3dec use capsnego in...

Original commit message from CVS:
Reworked the capsnegotiation function
audiosink now uses capsnego to set its parameters
mpg123/ac3dec use capsnego instead of metadata
Added the beginnings of a testsuite for capsnego.
This commit is contained in:
Wim Taymans 2001-03-18 02:42:30 +00:00
parent 93c01d268f
commit 3534e68563
28 changed files with 1539 additions and 723 deletions

View file

@ -791,6 +791,7 @@ tests/Makefile
tests/sched/Makefile
tests/eos/Makefile
testsuite/Makefile
testsuite/capsnego/Makefile
tests/nego/Makefile
examples/Makefile
examples/autoplug/Makefile

File diff suppressed because it is too large Load diff

View file

@ -296,3 +296,51 @@ pad has caps
=====================================
srccaps = GST_PAD_CAPS (srcpad);
srctempl = FALSE;
do {
//no caps, get one
if (!srccaps)
{
if (srcpad->negotiatefunc && !srctempl)
{
srccaps = srcpad->negotiatefunc (srpad, srcaps, counter);
srctempl = FALSE;
}
else
{
srccaps = gst_pad_get_caps (srcpad);
srctempl = TRUE;
}
}
/* check against other pad */
// the other pad doesn't want to negotiate
if (!sinkpad->negotiatefunc)
{
sinkcaps = gst_pad_get_caps (sinkpad);
if (!sinkcaps)
break;
if (gst_caps_check_compatibility (srccaps, sinkcaps))
{
// cool
break;
}
}
else {
switch pads;
}
} while (counter < 100);

View file

@ -51,8 +51,6 @@ int main(int argc,char *argv[])
gst_pad_connect(gst_element_get_pad(decoder,"src"),
gst_element_get_pad(audiosink,"sink"));
/* make it ready */
gst_element_set_state(bin, GST_STATE_READY);
/* start playing */
gst_element_set_state(bin, GST_STATE_PLAYING);

View file

@ -1,16 +1,6 @@
#include <stdlib.h>
#include <gst/gst.h>
gboolean playing;
/* eos will be called when the src element has an end of stream */
void eos(GstElement *element, gpointer data)
{
g_print("have eos, quitting\n");
playing = FALSE;
}
int main(int argc,char *argv[])
{
GstElement *disksrc, *audiosink, *parse, *decode, *queue;
@ -36,8 +26,6 @@ int main(int argc,char *argv[])
disksrc = gst_elementfactory_make("disksrc", "disk_source");
g_assert(disksrc != NULL);
gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
gtk_signal_connect(GTK_OBJECT(disksrc),"eos",
GTK_SIGNAL_FUNC(eos), thread);
parse = gst_elementfactory_make("mp3parse", "parse");
decode = gst_elementfactory_make("mpg123", "decode");
@ -69,16 +57,10 @@ int main(int argc,char *argv[])
gst_pad_connect(gst_element_get_pad(queue,"src"),
gst_element_get_pad(audiosink,"sink"));
/* make it ready */
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_READY);
/* start playing */
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
playing = TRUE;
while (playing) {
gst_bin_iterate(GST_BIN(bin));
}
while (gst_bin_iterate(GST_BIN(bin)));
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL);

View file

@ -35,8 +35,6 @@ int main(int argc,char *argv[])
xml = gst_xml_new ();
//g_print ("%p\n", xml);
gtk_signal_connect (GTK_OBJECT (xml), "object_loaded", xml_loaded, xml);
ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL);
@ -47,8 +45,6 @@ int main(int argc,char *argv[])
gst_element_set_state(bin, GST_STATE_PLAYING);
playing = TRUE;
while (gst_bin_iterate(GST_BIN(bin)));
gst_element_set_state(bin, GST_STATE_NULL);

View file

@ -49,7 +49,9 @@ static void gst_audiosink_init (GstAudioSink *audiosink);
static gboolean gst_audiosink_open_audio (GstAudioSink *sink);
static void gst_audiosink_close_audio (GstAudioSink *sink);
static void gst_audiosink_sync_parms (GstAudioSink *audiosink);
static GstElementStateReturn gst_audiosink_change_state (GstElement *element);
static GstPadNegotiateReturn gst_audiosink_negotiate (GstPad *pad, GstCaps **caps, gint counter);
static void gst_audiosink_set_arg (GtkObject *object, GtkArg *arg, guint id);
static void gst_audiosink_get_arg (GtkObject *object, GtkArg *arg, guint id);
@ -188,6 +190,7 @@ gst_audiosink_init (GstAudioSink *audiosink)
{
audiosink->sinkpad = gst_pad_new_from_template (gst_audiosink_sink_template, "sink");
gst_element_add_pad (GST_ELEMENT (audiosink), audiosink->sinkpad);
gst_pad_set_negotiate_function (audiosink->sinkpad, gst_audiosink_negotiate);
gst_pad_set_chain_function (audiosink->sinkpad, gst_audiosink_chain);
@ -202,6 +205,41 @@ gst_audiosink_init (GstAudioSink *audiosink)
GST_FLAG_SET (audiosink, GST_ELEMENT_THREAD_SUGGESTED);
}
static GstPadNegotiateReturn
gst_audiosink_negotiate (GstPad *pad, GstCaps **caps, gint counter)
{
GstAudioSink *audiosink;
g_return_val_if_fail (pad != NULL, GST_PAD_NEGOTIATE_FAIL);
g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_NEGOTIATE_FAIL);
audiosink = GST_AUDIOSINK (gst_pad_get_parent (pad));
g_print ("audiosink: negotiate\n");
// we decide
if (counter == 0) {
*caps = NULL;
return GST_PAD_NEGOTIATE_TRY;
}
// have we got caps?
else if (*caps) {
if (audiosink->fd == -1) return GST_PAD_NEGOTIATE_FAIL;
audiosink->format = gst_caps_get_int (*caps, "format");
audiosink->channels = gst_caps_get_int (*caps, "channels");
audiosink->frequency = gst_caps_get_int (*caps, "rate");
gst_audiosink_sync_parms (audiosink);
// FIXME check if the qound card was really set to these caps,
// else send out another caps..
return GST_PAD_NEGOTIATE_AGREE;
}
return GST_PAD_NEGOTIATE_FAIL;
}
static void
gst_audiosink_sync_parms (GstAudioSink *audiosink)
{
@ -222,7 +260,7 @@ gst_audiosink_sync_parms (GstAudioSink *audiosink)
ioctl (audiosink->fd, SNDCTL_DSP_GETOSPACE, &ospace);
g_print("audiosink: setting sound card to %dKHz %d bit %s (%d bytes buffer, %d fragment)\n",
g_print("audiosink: setting sound card to %dHz %d bit %s (%d bytes buffer, %d fragment)\n",
audiosink->frequency, audiosink->format,
(audiosink->channels == 2) ? "stereo" : "mono", ospace.bytes, frag);
@ -232,7 +270,6 @@ static void
gst_audiosink_chain (GstPad *pad, GstBuffer *buf)
{
GstAudioSink *audiosink;
MetaAudioRaw *meta;
gboolean in_flush;
audio_buf_info ospace;
@ -252,22 +289,6 @@ gst_audiosink_chain (GstPad *pad, GstBuffer *buf)
ioctl (audiosink->fd, SNDCTL_DSP_RESET, 0);
}
meta = (MetaAudioRaw *)gst_buffer_get_first_meta (buf);
if (meta != NULL) {
if ((meta->format != audiosink->format) ||
(meta->channels != audiosink->channels) ||
(meta->frequency != audiosink->frequency))
{
audiosink->format = meta->format;
audiosink->channels = meta->channels;
audiosink->frequency = meta->frequency;
gst_audiosink_sync_parms (audiosink);
g_print("audiosink: sound device set to format %d, %d channels, %dHz\n",
audiosink->format, audiosink->channels, audiosink->frequency);
}
}
gtk_signal_emit (GTK_OBJECT (audiosink), gst_audiosink_signals[SIGNAL_HANDOFF],
audiosink);
@ -368,10 +389,6 @@ gst_audiosink_open_audio (GstAudioSink *sink)
/* if we have it, set the default parameters and go have fun */
if (sink->fd >= 0) {
/* set card state */
sink->format = AFMT_S16_LE;
sink->channels = 2; /* stereo */
sink->frequency = 44100;
gst_audiosink_sync_parms (sink);
ioctl(sink->fd, SNDCTL_DSP_GETCAPS, &sink->caps);
g_print("audiosink: Capabilities\n");

View file

@ -399,10 +399,21 @@ gst_caps_check_compatibility_func (GstCaps *fromcaps, GstCaps *tocaps)
gboolean
gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
{
if (fromcaps == NULL ||
tocaps == NULL) {
GST_DEBUG (0,"gstcaps: no caps\n");
return TRUE;
if (fromcaps == NULL) {
if (tocaps == NULL) {
GST_DEBUG (0,"gstcaps: no caps\n");
return TRUE;
}
else {
GST_DEBUG (0,"gstcaps: no src but destination caps\n");
return FALSE;
}
}
else {
if (tocaps == NULL) {
GST_DEBUG (0,"gstcaps: src caps and no dest caps\n");
return TRUE;
}
}
while (fromcaps) {

View file

@ -73,6 +73,12 @@ void gst_caps_set_type_id (GstCaps *caps, guint16 type_id);
GstCaps* gst_caps_set_props (GstCaps *caps, GstProps *props);
GstProps* gst_caps_get_props (GstCaps *caps);
#define gst_caps_set(caps, name, args...) gst_props_set ((caps)->properties, name, args)
#define gst_caps_get_int(caps, name) gst_props_get_int ((caps)->properties, name)
#define gst_caps_get_fourcc_int(caps, name) gst_props_get_fourcc_int ((caps)->properties, name)
#define gst_caps_get_boolean(caps, name) gst_props_get_boolean ((caps)->properties, name)
GstCaps* gst_caps_get_by_name (GstCaps *caps, const gchar *name);
GstCaps* gst_caps_append (GstCaps *caps, GstCaps *capstoadd);

View file

@ -260,7 +260,7 @@ gst_pad_new_from_template (GstPadTemplate *templ,
pad = gst_pad_new (name, templ->direction);
GST_PAD_PADTEMPLATE(pad) = templ;
GST_PAD_CAPS (pad) = GST_PADTEMPLATE_CAPS (templ);
//GST_PAD_CAPS (pad) = GST_PADTEMPLATE_CAPS (templ);
return pad;
}
@ -572,9 +572,11 @@ gst_pad_connect (GstPad *srcpad,
if (GST_PAD_CAPS (srcpad)) {
negotiated = gst_pad_renegotiate (srcpad);
}
else {
else if (GST_PAD_CAPS (sinkpad)) {
negotiated = gst_pad_renegotiate (sinkpad);
}
else
negotiated = TRUE;
if (!negotiated) {
gst_pad_disconnect (GST_PAD (realsrc), GST_PAD (realsink));
@ -728,16 +730,16 @@ gst_pad_get_ghost_pad_list (GstPad *pad)
*
* Set the capabilities of this pad.
*/
void
gboolean
gst_pad_set_caps (GstPad *pad,
GstCaps *caps)
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_REAL_PAD (pad)); // NOTE this restriction
g_return_val_if_fail (pad != NULL, FALSE);
g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); // NOTE this restriction
GST_PAD_CAPS(pad) = caps;
gst_pad_renegotiate (pad);
return gst_pad_renegotiate (pad);
}
/**
@ -754,9 +756,27 @@ gst_pad_get_caps (GstPad *pad)
g_return_val_if_fail (pad != NULL, NULL);
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
return GST_PAD_CAPS(pad);
if (GST_PAD_CAPS (pad))
return GST_PAD_CAPS (pad);
else if (GST_PAD_PADTEMPLATE (pad))
return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad));
return NULL;
}
GstCaps*
gst_pad_get_padtemplate_caps (GstPad *pad)
{
g_return_val_if_fail (pad != NULL, NULL);
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
if (GST_PAD_PADTEMPLATE (pad))
return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad));
return NULL;
}
/**
* gst_pad_get_caps_by_name:
* @pad: the pad to get the capabilities from
@ -914,8 +934,8 @@ gst_pad_renegotiate (GstPad *pad)
gint counter = 0;
GstCaps *newcaps = NULL;
GstRealPad *peerpad, *currentpad, *otherpad;
GstCaps *currentcaps;
GstPadDirection currentdirection;
GstPadNegotiateReturn result;
g_return_val_if_fail (pad != NULL, FALSE);
@ -935,84 +955,56 @@ gst_pad_renegotiate (GstPad *pad)
GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad));
newcaps = GST_PAD_CAPS (pad);
g_assert (newcaps != NULL);
currentdirection = GST_PAD_DIRECTION (currentpad);
do {
currentcaps = newcaps;
currentdirection = GST_PAD_DIRECTION (currentpad);
gboolean matchtempl;
/* this pad wants to negotiate */
if (currentpad->negotiatefunc) {
matchtempl = gst_caps_check_compatibility (newcaps, gst_pad_get_padtemplate_caps (GST_PAD (otherpad)));
GST_DEBUG (GST_CAT_ELEMENT_PADS, "calling negotiate function on pad %s:%s, count=%d\n",
GST_DEBUG_PAD_NAME(currentpad), counter);
newcaps = (currentpad->negotiatefunc) (GST_PAD (currentpad), currentcaps, counter);
if (matchtempl) {
if (otherpad->negotiatefunc) {
GstRealPad *temp;
if (newcaps == NULL && currentcaps != NULL) {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s has refused, negotiation failed :(, count=%d\n",
GST_DEBUG_PAD_NAME(currentpad), counter);
return FALSE;
temp = currentpad;
currentpad = otherpad;
otherpad = temp;
}
if (newcaps == currentcaps) {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s aggreed with caps, count=%d\n",
GST_DEBUG_PAD_NAME(currentpad), counter);
break;
}
}
/* this pad doesn't want to negotiate, take its caps and that will be it then */
else {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "getting caps from pad %s:%s, count=%d\n",
GST_DEBUG_PAD_NAME(currentpad), counter);
newcaps = GST_PAD_CAPS (currentpad);
}
/* we have a caps structure now */
/* check if the other pad wants to negotiate */
if (!otherpad->negotiatefunc) {
GstCaps *srccaps = newcaps;
GstCaps *targetcaps = otherpad->caps;
/* the pad doesn't want to negotiate, so we check if the caps
* we got from the current pad are compatible */
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s doesn't want to negotiate, count=%d\n",
GST_DEBUG_PAD_NAME(otherpad), counter);
// the other pad has no caps, all is ok
if (!targetcaps)
break;
// make sure we check src to sink
if (currentdirection == GST_PAD_SINK) {
GstCaps *temp;
GST_DEBUG (GST_CAT_ELEMENT_PADS, "swapping pad caps for comparison, count=%d\n",
counter);
temp = srccaps;
srccaps = targetcaps;
targetcaps = temp;
}
if (gst_caps_check_compatibility (srccaps, targetcaps)) {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s has compatible caps, count=%d\n",
GST_DEBUG_PAD_NAME(otherpad), counter);
/* we're lucky */
else if (gst_caps_check_compatibility (newcaps, GST_PAD_CAPS (otherpad))) {
break;
}
/* else, we let the current pad select another caps */
else {
newcaps = GST_PAD_CAPS (otherpad);
}
}
/* if the other pad wants to negotiate, setup the pointers */
else {
GstRealPad *temp;
GST_DEBUG (GST_CAT_ELEMENT_PADS, "switching pads for next phase\n");
temp = currentpad;
currentpad = otherpad;
otherpad = temp;
newcaps = GST_PAD_CAPS (otherpad);
}
counter++;
} while (counter < 100); // FIXME
if (currentpad->negotiatefunc) {
result = currentpad->negotiatefunc (GST_PAD (currentpad), &newcaps, counter);
switch (result) {
case GST_PAD_NEGOTIATE_FAIL:
return FALSE;
case GST_PAD_NEGOTIATE_AGREE:
goto succeed;
case GST_PAD_NEGOTIATE_TRY:
break;
}
}
else {
return FALSE;
}
} while (counter < 100);
succeed:
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pads aggreed on caps :)\n");
/* here we have some sort of aggreement of the caps */
@ -1022,61 +1014,27 @@ gst_pad_renegotiate (GstPad *pad)
return TRUE;
}
GstCaps*
gst_pad_negotiate_proxy (GstPad *pad, GstCaps *caps, gint counter)
GstPadNegotiateReturn
gst_pad_negotiate_proxy (GstPad *pad, GstCaps **caps, gint counter)
{
GstRealPad *peer;
GstCaps *newcaps = caps;
g_return_val_if_fail (pad != NULL, NULL);
g_return_val_if_fail (pad != NULL, GST_PAD_NEGOTIATE_FAIL);
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad (%s:%s) proxied\n", GST_DEBUG_PAD_NAME (pad));
peer = GST_RPAD_PEER (pad);
GST_PAD_CAPS (pad) = caps;
//GST_PAD_CAPS (pad) = caps;
if (peer) {
if (peer->negotiatefunc) {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "calling negotiate on peer (%s:%s)\n", GST_DEBUG_PAD_NAME (peer));
newcaps = peer->negotiatefunc (pad, caps, counter);
}
else {
GstCaps *srccaps = newcaps;
GstCaps *targetcaps = peer->caps;
if (targetcaps) {
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
GstCaps *temp;
GST_DEBUG (GST_CAT_ELEMENT_PADS, "swapping pad caps for comparison, count=%d\n",
counter);
temp = srccaps;
srccaps = targetcaps;
targetcaps = temp;
}
if (gst_caps_check_compatibility (srccaps, targetcaps)) {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s has compatible caps\n",
GST_DEBUG_PAD_NAME(peer));
}
else {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "target caps but they didn't match %p %p\n", srccaps, targetcaps);
return NULL;
}
}
return peer->negotiatefunc (peer, caps, counter);
}
}
else {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "no peer\n");
}
if (caps == newcaps) {
GST_PAD_CAPS (pad) = newcaps;
if (peer) GST_PAD_CAPS (peer) = newcaps;
}
return newcaps;
return GST_PAD_NEGOTIATE_AGREE;
}
/**

View file

@ -79,6 +79,12 @@ typedef enum {
GST_REGION_TIME_LEN,
} GstRegionType;
typedef enum {
GST_PAD_NEGOTIATE_FAIL,
GST_PAD_NEGOTIATE_AGREE,
GST_PAD_NEGOTIATE_TRY,
} GstPadNegotiateReturn;
/* this defines the functions used to chain buffers
* pad is the sink pad (so the same chain function can be used for N pads)
@ -92,7 +98,7 @@ typedef void (*GstPadPushFunction) (GstPad *pad, GstBuffer *buf);
typedef GstBuffer *(*GstPadPullFunction) (GstPad *pad);
typedef GstBuffer *(*GstPadPullRegionFunction) (GstPad *pad, GstRegionType type, guint64 offset, guint64 len);
typedef gboolean (*GstPadEOSFunction) (GstPad *pad);
typedef GstCaps* (*GstPadNegotiateFunction) (GstPad *pad, GstCaps *caps, gint count);
typedef GstPadNegotiateReturn (*GstPadNegotiateFunction) (GstPad *pad, GstCaps **caps, gint count);
typedef enum {
GST_PAD_UNKNOWN,
@ -276,8 +282,9 @@ void gst_pad_set_qos_function (GstPad *pad, GstPadQoSFunction qos);
void gst_pad_set_eos_function (GstPad *pad, GstPadEOSFunction eos);
void gst_pad_set_negotiate_function (GstPad *pad, GstPadNegotiateFunction nego);
void gst_pad_set_caps (GstPad *pad, GstCaps *caps);
gboolean gst_pad_set_caps (GstPad *pad, GstCaps *caps);
GstCaps* gst_pad_get_caps (GstPad *pad);
GstCaps* gst_pad_get_padtemplate_caps (GstPad *pad);
gboolean gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad);
void gst_pad_set_element_private (GstPad *pad, gpointer priv);
@ -302,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);
GstCaps* gst_pad_negotiate_proxy (GstPad *pad, GstCaps* caps, gint count);
GstPadNegotiateReturn gst_pad_negotiate_proxy (GstPad *pad, GstCaps **caps, gint count);
#if 1
void gst_pad_push (GstPad *pad, GstBuffer *buf);

View file

@ -89,7 +89,7 @@ gst_props_create_entry (GstPropsFactory factory, gint *skipped)
static gint
props_compare_func (gconstpointer a,
gconstpointer b)
gconstpointer b)
{
GstPropsEntry *entry1 = (GstPropsEntry *)a;
GstPropsEntry *entry2 = (GstPropsEntry *)b;
@ -97,6 +97,16 @@ props_compare_func (gconstpointer a,
return (entry1->propid - entry2->propid);
}
static gint
props_find_func (gconstpointer a,
gconstpointer b)
{
GstPropsEntry *entry2 = (GstPropsEntry *)a;
GQuark entry1 = (GQuark) GPOINTER_TO_INT (b);
return (entry1 - entry2->propid);
}
/**
* gst_props_register:
* @factory: the factory to register
@ -272,6 +282,118 @@ gst_props_new (GstPropsFactoryEntry entry, ...)
return props;
}
GstProps*
gst_props_set (GstProps *props, const gchar *name, GstPropsFactoryEntry entry, ...)
{
GQuark quark;
GList *lentry;
va_list var_args;
quark = g_quark_from_string (name);
lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func);
if (lentry) {
GstPropsEntry *thisentry;
GstPropsFactoryEntry value;
thisentry = (GstPropsEntry *)lentry->data;
va_start (var_args, entry);
// property name
value = (GstPropsFactoryEntry) entry;
switch (GPOINTER_TO_INT (value)) {
case GST_PROPS_INT_ID:
thisentry->propstype = GST_PROPS_INT_ID_NUM;
value = va_arg (var_args, GstPropsFactoryEntry);
thisentry->data.int_data = GPOINTER_TO_INT (value);
break;
case GST_PROPS_FOURCC_ID_NUM:
thisentry->propstype = GST_PROPS_FOURCC_ID_NUM;
value = va_arg (var_args, GstPropsFactoryEntry);
thisentry->data.fourcc_data = GPOINTER_TO_INT (value);
break;
case GST_PROPS_BOOL_ID_NUM:
thisentry->propstype = GST_PROPS_BOOL_ID_NUM;
value = va_arg (var_args, GstPropsFactoryEntry);
thisentry->data.bool_data = GPOINTER_TO_INT (value);
break;
default:
g_print("gstprops: type not allowed\n");
break;
}
}
else {
g_print("gstprops: no property '%s' to change\n", name);
}
return props;
}
gint
gst_props_get_int (GstProps *props, const gchar *name)
{
GList *lentry;
GQuark quark;
quark = g_quark_from_string (name);
lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func);
if (lentry) {
GstPropsEntry *thisentry;
thisentry = (GstPropsEntry *)lentry->data;
return thisentry->data.int_data;
}
return 0;
}
gulong
gst_props_get_fourcc_int (GstProps *props, const gchar *name)
{
GList *lentry;
GQuark quark;
quark = g_quark_from_string (name);
lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func);
if (lentry) {
GstPropsEntry *thisentry;
thisentry = (GstPropsEntry *)lentry->data;
return thisentry->data.fourcc_data;
}
return 0;
}
gboolean
gst_props_get_boolean (GstProps *props, const gchar *name)
{
GList *lentry;
GQuark quark;
quark = g_quark_from_string (name);
lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func);
if (lentry) {
GstPropsEntry *thisentry;
thisentry = (GstPropsEntry *)lentry->data;
return thisentry->data.bool_data;
}
return 0;
}
/**
* gst_props_merge:
* @props: the property to merge into

View file

@ -50,20 +50,20 @@ typedef enum {
GST_PROPS_LAST_ID_NUM = GST_PROPS_END_ID_NUM + 16,
} GstPropsId;
#define GST_PROPS_END_ID GINT_TO_POINTER(GST_PROPS_END_ID_NUM)
#define GST_PROPS_LIST_ID GINT_TO_POINTER(GST_PROPS_LIST_ID_NUM)
#define GST_PROPS_INT_ID GINT_TO_POINTER(GST_PROPS_INT_ID_NUM)
#define GST_PROPS_INT_RANGE_ID GINT_TO_POINTER(GST_PROPS_INT_RANGE_ID_NUM)
#define GST_PROPS_FOURCC_ID GINT_TO_POINTER(GST_PROPS_FOURCC_ID_NUM)
#define GST_PROPS_BOOL_ID GINT_TO_POINTER(GST_PROPS_BOOL_ID_NUM)
#define GST_PROPS_LAST_ID GINT_TO_POINTER(GST_PROPS_LAST_ID_NUM)
#define GST_PROPS_END_ID GINT_TO_POINTER(GST_PROPS_END_ID_NUM)
#define GST_PROPS_LIST_ID GINT_TO_POINTER(GST_PROPS_LIST_ID_NUM)
#define GST_PROPS_INT_ID GINT_TO_POINTER(GST_PROPS_INT_ID_NUM)
#define GST_PROPS_INT_RANGE_ID GINT_TO_POINTER(GST_PROPS_INT_RANGE_ID_NUM)
#define GST_PROPS_FOURCC_ID GINT_TO_POINTER(GST_PROPS_FOURCC_ID_NUM)
#define GST_PROPS_BOOL_ID GINT_TO_POINTER(GST_PROPS_BOOL_ID_NUM)
#define GST_PROPS_LAST_ID GINT_TO_POINTER(GST_PROPS_LAST_ID_NUM)
#define GST_PROPS_LIST(a...) GST_PROPS_LIST_ID,##a,NULL
#define GST_PROPS_INT(a) GST_PROPS_INT_ID,(GINT_TO_POINTER(a))
#define GST_PROPS_INT_RANGE(a,b) GST_PROPS_INT_RANGE_ID,(GINT_TO_POINTER(a)),(GINT_TO_POINTER(b))
#define GST_PROPS_FOURCC(a,b,c,d) GST_PROPS_FOURCC_ID,(GINT_TO_POINTER((a)|(b)<<8|(c)<<16|(d)<<24))
#define GST_PROPS_FOURCC_INT(a) GST_PROPS_FOURCC_ID,(GINT_TO_POINTER(a))
#define GST_PROPS_BOOLEAN(a) GST_PROPS_BOOL_ID,(GINT_TO_POINTER(a))
#define GST_PROPS_LIST(a...) GST_PROPS_LIST_ID,##a,NULL
#define GST_PROPS_INT(a) GST_PROPS_INT_ID,(GINT_TO_POINTER(a))
#define GST_PROPS_INT_RANGE(a,b) GST_PROPS_INT_RANGE_ID,(GINT_TO_POINTER(a)),(GINT_TO_POINTER(b))
#define GST_PROPS_FOURCC(a,b,c,d) GST_PROPS_FOURCC_ID,(GINT_TO_POINTER((a)|(b)<<8|(c)<<16|(d)<<24))
#define GST_PROPS_FOURCC_INT(a) GST_PROPS_FOURCC_ID,(GINT_TO_POINTER(a))
#define GST_PROPS_BOOLEAN(a) GST_PROPS_BOOL_ID,(GINT_TO_POINTER(a))
struct _GstProps {
@ -82,6 +82,12 @@ GstProps* gst_props_merge (GstProps *props, GstProps *tomerge);
gboolean gst_props_check_compatibility (GstProps *fromprops, GstProps *toprops);
GstProps* gst_props_set (GstProps *props, const gchar *name, GstPropsFactoryEntry value, ...);
gint gst_props_get_int (GstProps *props, const gchar *name);
gulong gst_props_get_fourcc_int (GstProps *props, const gchar *name);
gboolean gst_props_get_boolean (GstProps *props, const gchar *name);
xmlNodePtr gst_props_save_thyself (GstProps *props, xmlNodePtr parent);
GstProps* gst_props_load_thyself (xmlNodePtr parent);

View file

@ -66,8 +66,8 @@ static void gst_queue_set_arg (GtkObject *object, GtkArg *arg, guint id);
static void gst_queue_get_arg (GtkObject *object, GtkArg *arg, guint id);
static gboolean gst_queue_handle_eos (GstPad *pad);
static GstCaps* gst_queue_handle_negotiate_src (GstPad *pad, GstCaps *caps, gint count);
static GstCaps* gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps *caps, gint count);
static GstPadNegotiateReturn gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gint count);
static GstPadNegotiateReturn gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gint count);
static void gst_queue_chain (GstPad *pad, GstBuffer *buf);
static GstBuffer * gst_queue_get (GstPad *pad);
@ -152,8 +152,8 @@ gst_queue_init (GstQueue *queue)
queue->fullcond = g_cond_new ();
}
static GstCaps*
gst_queue_handle_negotiate_src (GstPad *pad, GstCaps *caps, gint count)
static GstPadNegotiateReturn
gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gint count)
{
GstQueue *queue;
@ -162,8 +162,8 @@ gst_queue_handle_negotiate_src (GstPad *pad, GstCaps *caps, gint count)
return gst_pad_negotiate_proxy (queue->sinkpad, caps, count);
}
static GstCaps*
gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps *caps, gint count)
static GstPadNegotiateReturn
gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gint count)
{
GstQueue *queue;

View file

@ -49,7 +49,9 @@ static void gst_audiosink_init (GstAudioSink *audiosink);
static gboolean gst_audiosink_open_audio (GstAudioSink *sink);
static void gst_audiosink_close_audio (GstAudioSink *sink);
static void gst_audiosink_sync_parms (GstAudioSink *audiosink);
static GstElementStateReturn gst_audiosink_change_state (GstElement *element);
static GstPadNegotiateReturn gst_audiosink_negotiate (GstPad *pad, GstCaps **caps, gint counter);
static void gst_audiosink_set_arg (GtkObject *object, GtkArg *arg, guint id);
static void gst_audiosink_get_arg (GtkObject *object, GtkArg *arg, guint id);
@ -188,6 +190,7 @@ gst_audiosink_init (GstAudioSink *audiosink)
{
audiosink->sinkpad = gst_pad_new_from_template (gst_audiosink_sink_template, "sink");
gst_element_add_pad (GST_ELEMENT (audiosink), audiosink->sinkpad);
gst_pad_set_negotiate_function (audiosink->sinkpad, gst_audiosink_negotiate);
gst_pad_set_chain_function (audiosink->sinkpad, gst_audiosink_chain);
@ -202,6 +205,41 @@ gst_audiosink_init (GstAudioSink *audiosink)
GST_FLAG_SET (audiosink, GST_ELEMENT_THREAD_SUGGESTED);
}
static GstPadNegotiateReturn
gst_audiosink_negotiate (GstPad *pad, GstCaps **caps, gint counter)
{
GstAudioSink *audiosink;
g_return_val_if_fail (pad != NULL, GST_PAD_NEGOTIATE_FAIL);
g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_NEGOTIATE_FAIL);
audiosink = GST_AUDIOSINK (gst_pad_get_parent (pad));
g_print ("audiosink: negotiate\n");
// we decide
if (counter == 0) {
*caps = NULL;
return GST_PAD_NEGOTIATE_TRY;
}
// have we got caps?
else if (*caps) {
if (audiosink->fd == -1) return GST_PAD_NEGOTIATE_FAIL;
audiosink->format = gst_caps_get_int (*caps, "format");
audiosink->channels = gst_caps_get_int (*caps, "channels");
audiosink->frequency = gst_caps_get_int (*caps, "rate");
gst_audiosink_sync_parms (audiosink);
// FIXME check if the qound card was really set to these caps,
// else send out another caps..
return GST_PAD_NEGOTIATE_AGREE;
}
return GST_PAD_NEGOTIATE_FAIL;
}
static void
gst_audiosink_sync_parms (GstAudioSink *audiosink)
{
@ -222,7 +260,7 @@ gst_audiosink_sync_parms (GstAudioSink *audiosink)
ioctl (audiosink->fd, SNDCTL_DSP_GETOSPACE, &ospace);
g_print("audiosink: setting sound card to %dKHz %d bit %s (%d bytes buffer, %d fragment)\n",
g_print("audiosink: setting sound card to %dHz %d bit %s (%d bytes buffer, %d fragment)\n",
audiosink->frequency, audiosink->format,
(audiosink->channels == 2) ? "stereo" : "mono", ospace.bytes, frag);
@ -232,7 +270,6 @@ static void
gst_audiosink_chain (GstPad *pad, GstBuffer *buf)
{
GstAudioSink *audiosink;
MetaAudioRaw *meta;
gboolean in_flush;
audio_buf_info ospace;
@ -252,22 +289,6 @@ gst_audiosink_chain (GstPad *pad, GstBuffer *buf)
ioctl (audiosink->fd, SNDCTL_DSP_RESET, 0);
}
meta = (MetaAudioRaw *)gst_buffer_get_first_meta (buf);
if (meta != NULL) {
if ((meta->format != audiosink->format) ||
(meta->channels != audiosink->channels) ||
(meta->frequency != audiosink->frequency))
{
audiosink->format = meta->format;
audiosink->channels = meta->channels;
audiosink->frequency = meta->frequency;
gst_audiosink_sync_parms (audiosink);
g_print("audiosink: sound device set to format %d, %d channels, %dHz\n",
audiosink->format, audiosink->channels, audiosink->frequency);
}
}
gtk_signal_emit (GTK_OBJECT (audiosink), gst_audiosink_signals[SIGNAL_HANDOFF],
audiosink);
@ -368,10 +389,6 @@ gst_audiosink_open_audio (GstAudioSink *sink)
/* if we have it, set the default parameters and go have fun */
if (sink->fd >= 0) {
/* set card state */
sink->format = AFMT_S16_LE;
sink->channels = 2; /* stereo */
sink->frequency = 44100;
gst_audiosink_sync_parms (sink);
ioctl(sink->fd, SNDCTL_DSP_GETCAPS, &sink->caps);
g_print("audiosink: Capabilities\n");

View file

@ -66,8 +66,8 @@ static void gst_queue_set_arg (GtkObject *object, GtkArg *arg, guint id);
static void gst_queue_get_arg (GtkObject *object, GtkArg *arg, guint id);
static gboolean gst_queue_handle_eos (GstPad *pad);
static GstCaps* gst_queue_handle_negotiate_src (GstPad *pad, GstCaps *caps, gint count);
static GstCaps* gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps *caps, gint count);
static GstPadNegotiateReturn gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gint count);
static GstPadNegotiateReturn gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gint count);
static void gst_queue_chain (GstPad *pad, GstBuffer *buf);
static GstBuffer * gst_queue_get (GstPad *pad);
@ -152,8 +152,8 @@ gst_queue_init (GstQueue *queue)
queue->fullcond = g_cond_new ();
}
static GstCaps*
gst_queue_handle_negotiate_src (GstPad *pad, GstCaps *caps, gint count)
static GstPadNegotiateReturn
gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gint count)
{
GstQueue *queue;
@ -162,8 +162,8 @@ gst_queue_handle_negotiate_src (GstPad *pad, GstCaps *caps, gint count)
return gst_pad_negotiate_proxy (queue->sinkpad, caps, count);
}
static GstCaps*
gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps *caps, gint count)
static GstPadNegotiateReturn
gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gint count)
{
GstQueue *queue;

View file

@ -51,8 +51,6 @@ int main(int argc,char *argv[])
gst_pad_connect(gst_element_get_pad(decoder,"src"),
gst_element_get_pad(audiosink,"sink"));
/* make it ready */
gst_element_set_state(bin, GST_STATE_READY);
/* start playing */
gst_element_set_state(bin, GST_STATE_PLAYING);

View file

@ -1,16 +1,6 @@
#include <stdlib.h>
#include <gst/gst.h>
gboolean playing;
/* eos will be called when the src element has an end of stream */
void eos(GstElement *element, gpointer data)
{
g_print("have eos, quitting\n");
playing = FALSE;
}
int main(int argc,char *argv[])
{
GstElement *disksrc, *audiosink, *parse, *decode, *queue;
@ -36,8 +26,6 @@ int main(int argc,char *argv[])
disksrc = gst_elementfactory_make("disksrc", "disk_source");
g_assert(disksrc != NULL);
gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
gtk_signal_connect(GTK_OBJECT(disksrc),"eos",
GTK_SIGNAL_FUNC(eos), thread);
parse = gst_elementfactory_make("mp3parse", "parse");
decode = gst_elementfactory_make("mpg123", "decode");
@ -69,16 +57,10 @@ int main(int argc,char *argv[])
gst_pad_connect(gst_element_get_pad(queue,"src"),
gst_element_get_pad(audiosink,"sink"));
/* make it ready */
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_READY);
/* start playing */
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
playing = TRUE;
while (playing) {
gst_bin_iterate(GST_BIN(bin));
}
while (gst_bin_iterate(GST_BIN(bin)));
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL);

View file

@ -35,8 +35,6 @@ int main(int argc,char *argv[])
xml = gst_xml_new ();
//g_print ("%p\n", xml);
gtk_signal_connect (GTK_OBJECT (xml), "object_loaded", xml_loaded, xml);
ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL);
@ -47,8 +45,6 @@ int main(int argc,char *argv[])
gst_element_set_state(bin, GST_STATE_PLAYING);
playing = TRUE;
while (gst_bin_iterate(GST_BIN(bin)));
gst_element_set_state(bin, GST_STATE_NULL);

View file

@ -0,0 +1,9 @@
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs
capsnego
converter

View file

@ -0,0 +1,11 @@
SUBDIRS =
testprogs = capsnego converter
TESTS = $(testprogs)
check_PROGRAMS = $(testprogs)
# we have nothing but apps here, we can do this safely
LIBS += $(GST_LIBS)
CFLAGS += $(GST_CFLAGS)

View file

@ -0,0 +1,143 @@
#include <gst/gst.h>
GstPad *srcpad, *sinkpad;
GstPad *srcpadtempl, *sinkpadtempl;
static GstPadFactory src_factory = {
"src",
GST_PAD_FACTORY_SRC,
GST_PAD_FACTORY_ALWAYS,
GST_PAD_FACTORY_CAPS(
"test_src",
"video/raw",
"height", GST_PROPS_INT_RANGE (16, 4096)
),
NULL,
};
static GstPadFactory sink_factory = {
"sink",
GST_PAD_FACTORY_SINK,
GST_PAD_FACTORY_ALWAYS,
GST_PAD_FACTORY_CAPS(
"test_sink",
"video/raw",
"height", GST_PROPS_INT_RANGE (16, 8192)
),
NULL,
};
static GstCapsFactory sink_caps = {
"sink_caps",
"video/raw",
"height", GST_PROPS_INT (3000),
NULL
};
static GstCapsFactory src_caps = {
"src_caps",
"video/raw",
"height", GST_PROPS_INT (3000),
NULL
};
static GstPadTemplate *srctempl, *sinktempl;
static GstCaps *srccaps, *sinkcaps;
static GstPadNegotiateReturn
negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
{
g_print (">");
if (counter == 0) {
*caps = NULL;
return GST_PAD_NEGOTIATE_TRY;
}
if (*caps)
return GST_PAD_NEGOTIATE_AGREE;
return GST_PAD_NEGOTIATE_FAIL;
}
static GstPadNegotiateReturn
negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
{
g_print ("<");
if (counter == 0) {
*caps = NULL;
return GST_PAD_NEGOTIATE_TRY;
}
if (*caps)
return GST_PAD_NEGOTIATE_AGREE;
return GST_PAD_NEGOTIATE_FAIL;
}
static gboolean
perform_check (void)
{
gboolean result, overall = TRUE;
gint i, j;
g_print ("ABC: A=pad caps, B=pad template, C=negotiate function\n");
for (j=0; j<8; j++) {
GstPad *srctest, *sinktest;
for (i=0; i<8; i++) {
(j & 0x2 ? (sinktest = sinkpadtempl) : (sinktest = sinkpad));
(j & 0x4 ? (gst_pad_set_caps (sinktest, sinkcaps)) : (gst_pad_set_caps (sinktest, NULL)));
(j & 0x1 ? (gst_pad_set_negotiate_function (sinktest, negotiate_sink)) :
gst_pad_set_negotiate_function (sinktest, NULL));
(i & 0x2 ? (srctest = srcpadtempl) : (srctest = srcpad));
(i & 0x4 ? (gst_pad_set_caps (srctest, srccaps)) : (gst_pad_set_caps (srctest, NULL)));
(i & 0x1 ? (gst_pad_set_negotiate_function (srctest, negotiate_src)) :
gst_pad_set_negotiate_function (srctest, NULL));
g_print ("%d%d%d -> %d%d%d ..", (i&4)>>2, (i&2)>>1, i&1, (j&4)>>2, (j&2)>>1, j&1);
result = gst_pad_connect (srctest, sinktest);
g_print (".. %s\n", (result? "ok":"fail"));
if (result) gst_pad_disconnect (srctest, sinktest);
overall &= result;
}
}
return overall;
}
int
main (int argc, char *argv[])
{
gboolean overall = TRUE;
gst_init (&argc, &argv);
srcpad = gst_pad_new ("src", GST_PAD_SRC);
sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
srctempl = gst_padtemplate_new (&src_factory);
sinktempl = gst_padtemplate_new (&sink_factory);
srcpadtempl = gst_pad_new_from_template (srctempl, "src");
sinkpadtempl = gst_pad_new_from_template (sinktempl, "sink");
sinkcaps = gst_caps_register (&sink_caps);
srccaps = gst_caps_register (&src_caps);
g_print ("*** compatible caps/templates ***\n");
overall &= perform_check ();
gst_caps_set (srccaps, "height", GST_PROPS_INT (9000));
g_print ("*** incompatible caps ***\n");
overall &= perform_check ();
exit (!overall);
}

View file

@ -0,0 +1,168 @@
#include <gst/gst.h>
GstPad *srcpad, *sinkpad;
GstPad *srcconvpad, *sinkconvpad;
GstPad *srcpadtempl, *sinkpadtempl;
GstPad *srcconvtempl, *sinkconvtempl;
gint converter_in = -1, converter_out = -1;
static GstPadFactory src_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 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 GstPadFactory sink_factory = {
"sink",
GST_PAD_FACTORY_SINK,
GST_PAD_FACTORY_ALWAYS,
GST_PAD_FACTORY_CAPS(
"test_sink",
"audio/raw",
"rate", GST_PROPS_INT_RANGE (16, 20000)
),
NULL,
};
static GstCapsFactory sink_caps = {
"sink_caps",
"audio/raw",
"rate", GST_PROPS_INT (6000),
NULL
};
static GstCapsFactory src_caps = {
"src_caps",
"audio/raw",
"rate", GST_PROPS_INT (3000),
NULL
};
static GstPadTemplate *srctempl, *sinktempl;
static GstCaps *srccaps, *sinkcaps;
static GstPadNegotiateReturn
negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
{
g_print (">");
if (counter == 0) {
*caps = NULL;
return GST_PAD_NEGOTIATE_TRY;
}
if (*caps) {
converter_out = gst_caps_get_int (*caps, "rate");
return GST_PAD_NEGOTIATE_AGREE;
}
return GST_PAD_NEGOTIATE_FAIL;
}
static GstPadNegotiateReturn
negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
{
g_print ("<");
if (counter == 0) {
*caps = NULL;
return GST_PAD_NEGOTIATE_TRY;
}
if (*caps) {
converter_in = gst_caps_get_int (*caps, "rate");
return GST_PAD_NEGOTIATE_AGREE;
}
return GST_PAD_NEGOTIATE_FAIL;
}
int
main (int argc, char *argv[])
{
gboolean overall = TRUE;
gboolean result;
gst_init (&argc, &argv);
srctempl = gst_padtemplate_new (&src_factory);
sinktempl = gst_padtemplate_new (&sink_factory);
srcpad = gst_pad_new_from_template (srctempl, "src");
sinkpad = gst_pad_new_from_template (sinktempl, "sink");
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);
sinkcaps = gst_caps_register (&sink_caps);
srccaps = gst_caps_register (&src_caps);
result = gst_pad_set_caps (srcpad, srccaps);
g_print ("set caps on src: %d\n", result);
g_print ("initial converter status: %d %d\n", converter_in, converter_out);
result = gst_pad_connect (srcpad, sinkconvpad);
g_print ("pad connect 1: %d\n", result);
overall &= (result == TRUE);
result = gst_pad_connect (srcconvpad, sinkpad);
g_print ("pad connect 2: %d\n", result);
overall &= (result == TRUE);
g_print ("after connect, converter status: %d %d\n", converter_in, converter_out);
result = gst_pad_set_caps (srcpad, srccaps);
g_print ("src pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out);
result = gst_pad_set_caps (sinkpad, sinkcaps);
g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out);
gst_caps_set (srccaps, "rate", GST_PROPS_INT (4000));
result = gst_pad_renegotiate (srcpad);
g_print ("sink pad renegotiate caps %d, converter status: %d %d\n", result, converter_in, converter_out);
gst_caps_set (srccaps, "rate", GST_PROPS_INT (40000));
result = gst_pad_set_caps (srcpad, srccaps);
g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out);
gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (40000));
result = gst_pad_set_caps (sinkpad, sinkcaps);
g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out);
gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (9000));
result = gst_pad_set_caps (sinkpad, sinkcaps);
g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out);
exit (!overall);
}

View file

@ -60,6 +60,15 @@ int main(int argc,char *argv[])
parent = xmlNewChild (doc->xmlRootNode, NULL, "Props3", NULL);
gst_props_save_thyself (testprops, parent);
sinkprops = gst_props_set (sinkprops, "mpegtype", GST_PROPS_INT (1));
sinkprops = gst_props_set (sinkprops, "foobar", GST_PROPS_FOURCC_INT (0x56565656));
g_print ("%08lx\n", gst_props_get_fourcc_int (sinkprops, "foobar"));
g_print ("%d\n", gst_props_get_int (sinkprops, "mpegtype"));
parent = xmlNewChild (doc->xmlRootNode, NULL, "Props4", NULL);
gst_props_save_thyself (sinkprops, parent);
xmlDocDump(stdout, doc);
return 0;

9
testsuite/capsnego/.gitignore vendored Normal file
View file

@ -0,0 +1,9 @@
Makefile
Makefile.in
*.o
*.lo
*.la
.deps
.libs
capsnego
converter

View file

@ -0,0 +1,11 @@
SUBDIRS =
testprogs = capsnego converter
TESTS = $(testprogs)
check_PROGRAMS = $(testprogs)
# we have nothing but apps here, we can do this safely
LIBS += $(GST_LIBS)
CFLAGS += $(GST_CFLAGS)

View file

@ -0,0 +1,143 @@
#include <gst/gst.h>
GstPad *srcpad, *sinkpad;
GstPad *srcpadtempl, *sinkpadtempl;
static GstPadFactory src_factory = {
"src",
GST_PAD_FACTORY_SRC,
GST_PAD_FACTORY_ALWAYS,
GST_PAD_FACTORY_CAPS(
"test_src",
"video/raw",
"height", GST_PROPS_INT_RANGE (16, 4096)
),
NULL,
};
static GstPadFactory sink_factory = {
"sink",
GST_PAD_FACTORY_SINK,
GST_PAD_FACTORY_ALWAYS,
GST_PAD_FACTORY_CAPS(
"test_sink",
"video/raw",
"height", GST_PROPS_INT_RANGE (16, 8192)
),
NULL,
};
static GstCapsFactory sink_caps = {
"sink_caps",
"video/raw",
"height", GST_PROPS_INT (3000),
NULL
};
static GstCapsFactory src_caps = {
"src_caps",
"video/raw",
"height", GST_PROPS_INT (3000),
NULL
};
static GstPadTemplate *srctempl, *sinktempl;
static GstCaps *srccaps, *sinkcaps;
static GstPadNegotiateReturn
negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
{
g_print (">");
if (counter == 0) {
*caps = NULL;
return GST_PAD_NEGOTIATE_TRY;
}
if (*caps)
return GST_PAD_NEGOTIATE_AGREE;
return GST_PAD_NEGOTIATE_FAIL;
}
static GstPadNegotiateReturn
negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
{
g_print ("<");
if (counter == 0) {
*caps = NULL;
return GST_PAD_NEGOTIATE_TRY;
}
if (*caps)
return GST_PAD_NEGOTIATE_AGREE;
return GST_PAD_NEGOTIATE_FAIL;
}
static gboolean
perform_check (void)
{
gboolean result, overall = TRUE;
gint i, j;
g_print ("ABC: A=pad caps, B=pad template, C=negotiate function\n");
for (j=0; j<8; j++) {
GstPad *srctest, *sinktest;
for (i=0; i<8; i++) {
(j & 0x2 ? (sinktest = sinkpadtempl) : (sinktest = sinkpad));
(j & 0x4 ? (gst_pad_set_caps (sinktest, sinkcaps)) : (gst_pad_set_caps (sinktest, NULL)));
(j & 0x1 ? (gst_pad_set_negotiate_function (sinktest, negotiate_sink)) :
gst_pad_set_negotiate_function (sinktest, NULL));
(i & 0x2 ? (srctest = srcpadtempl) : (srctest = srcpad));
(i & 0x4 ? (gst_pad_set_caps (srctest, srccaps)) : (gst_pad_set_caps (srctest, NULL)));
(i & 0x1 ? (gst_pad_set_negotiate_function (srctest, negotiate_src)) :
gst_pad_set_negotiate_function (srctest, NULL));
g_print ("%d%d%d -> %d%d%d ..", (i&4)>>2, (i&2)>>1, i&1, (j&4)>>2, (j&2)>>1, j&1);
result = gst_pad_connect (srctest, sinktest);
g_print (".. %s\n", (result? "ok":"fail"));
if (result) gst_pad_disconnect (srctest, sinktest);
overall &= result;
}
}
return overall;
}
int
main (int argc, char *argv[])
{
gboolean overall = TRUE;
gst_init (&argc, &argv);
srcpad = gst_pad_new ("src", GST_PAD_SRC);
sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
srctempl = gst_padtemplate_new (&src_factory);
sinktempl = gst_padtemplate_new (&sink_factory);
srcpadtempl = gst_pad_new_from_template (srctempl, "src");
sinkpadtempl = gst_pad_new_from_template (sinktempl, "sink");
sinkcaps = gst_caps_register (&sink_caps);
srccaps = gst_caps_register (&src_caps);
g_print ("*** compatible caps/templates ***\n");
overall &= perform_check ();
gst_caps_set (srccaps, "height", GST_PROPS_INT (9000));
g_print ("*** incompatible caps ***\n");
overall &= perform_check ();
exit (!overall);
}

View file

@ -0,0 +1,168 @@
#include <gst/gst.h>
GstPad *srcpad, *sinkpad;
GstPad *srcconvpad, *sinkconvpad;
GstPad *srcpadtempl, *sinkpadtempl;
GstPad *srcconvtempl, *sinkconvtempl;
gint converter_in = -1, converter_out = -1;
static GstPadFactory src_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 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 GstPadFactory sink_factory = {
"sink",
GST_PAD_FACTORY_SINK,
GST_PAD_FACTORY_ALWAYS,
GST_PAD_FACTORY_CAPS(
"test_sink",
"audio/raw",
"rate", GST_PROPS_INT_RANGE (16, 20000)
),
NULL,
};
static GstCapsFactory sink_caps = {
"sink_caps",
"audio/raw",
"rate", GST_PROPS_INT (6000),
NULL
};
static GstCapsFactory src_caps = {
"src_caps",
"audio/raw",
"rate", GST_PROPS_INT (3000),
NULL
};
static GstPadTemplate *srctempl, *sinktempl;
static GstCaps *srccaps, *sinkcaps;
static GstPadNegotiateReturn
negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
{
g_print (">");
if (counter == 0) {
*caps = NULL;
return GST_PAD_NEGOTIATE_TRY;
}
if (*caps) {
converter_out = gst_caps_get_int (*caps, "rate");
return GST_PAD_NEGOTIATE_AGREE;
}
return GST_PAD_NEGOTIATE_FAIL;
}
static GstPadNegotiateReturn
negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
{
g_print ("<");
if (counter == 0) {
*caps = NULL;
return GST_PAD_NEGOTIATE_TRY;
}
if (*caps) {
converter_in = gst_caps_get_int (*caps, "rate");
return GST_PAD_NEGOTIATE_AGREE;
}
return GST_PAD_NEGOTIATE_FAIL;
}
int
main (int argc, char *argv[])
{
gboolean overall = TRUE;
gboolean result;
gst_init (&argc, &argv);
srctempl = gst_padtemplate_new (&src_factory);
sinktempl = gst_padtemplate_new (&sink_factory);
srcpad = gst_pad_new_from_template (srctempl, "src");
sinkpad = gst_pad_new_from_template (sinktempl, "sink");
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);
sinkcaps = gst_caps_register (&sink_caps);
srccaps = gst_caps_register (&src_caps);
result = gst_pad_set_caps (srcpad, srccaps);
g_print ("set caps on src: %d\n", result);
g_print ("initial converter status: %d %d\n", converter_in, converter_out);
result = gst_pad_connect (srcpad, sinkconvpad);
g_print ("pad connect 1: %d\n", result);
overall &= (result == TRUE);
result = gst_pad_connect (srcconvpad, sinkpad);
g_print ("pad connect 2: %d\n", result);
overall &= (result == TRUE);
g_print ("after connect, converter status: %d %d\n", converter_in, converter_out);
result = gst_pad_set_caps (srcpad, srccaps);
g_print ("src pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out);
result = gst_pad_set_caps (sinkpad, sinkcaps);
g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out);
gst_caps_set (srccaps, "rate", GST_PROPS_INT (4000));
result = gst_pad_renegotiate (srcpad);
g_print ("sink pad renegotiate caps %d, converter status: %d %d\n", result, converter_in, converter_out);
gst_caps_set (srccaps, "rate", GST_PROPS_INT (40000));
result = gst_pad_set_caps (srcpad, srccaps);
g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out);
gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (40000));
result = gst_pad_set_caps (sinkpad, sinkcaps);
g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out);
gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (9000));
result = gst_pad_set_caps (sinkpad, sinkcaps);
g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out);
exit (!overall);
}