Merge CAPS branch

Original commit message from CVS:
Merge CAPS branch
This commit is contained in:
David Schleef 2003-12-22 01:47:09 +00:00
parent 6bb536ed65
commit 3b60021408
61 changed files with 2481 additions and 2715 deletions

View file

@ -12,78 +12,27 @@ struct probe_context {
gint total_ls; gint total_ls;
GstCaps *metadata; GstCaps *metadata;
GstCaps *streaminfo; GstCaps *streaminfo;
GstCaps *caps; GstCaps *caps;
}; };
static void static void
print_caps (GstCaps *caps) print_caps (GstCaps *caps)
{ {
if (caps == NULL) return; char *s;
if (!strcmp (gst_caps_get_mime (caps), "application/x-gst-metadata") || s = gst_caps_to_string (caps);
!strcmp (gst_caps_get_mime (caps), "application/x-gst-streaminfo")) g_print(" %s\n", s);
{ g_free (s);
GstProps *props = caps->properties;
GList *walk;
/* ugly hack, but ok for now. If needed, fix by individual strcmp */
g_print (" %s:\n", gst_caps_get_mime (caps) + 18);
if (props == NULL) {
g_print (" none\n");
return;
}
walk = props->properties;
while (walk) {
GstPropsEntry *entry = (GstPropsEntry *) walk->data;
const gchar *name;
const gchar *str_val;
gint int_val;
GstPropsType type;
name = gst_props_entry_get_name (entry);
type = gst_props_entry_get_props_type (entry);
switch (type) {
case GST_PROPS_STRING_TYPE:
gst_props_entry_get_string (entry, &str_val);
g_print (" %s='%s'\n", name, str_val);
break;
case GST_PROPS_INT_TYPE:
gst_props_entry_get_int (entry, &int_val);
g_print (" %s=%d\n", name, int_val);
break;
default:
break;
}
walk = g_list_next (walk);
}
}
else {
g_print (" unkown caps type\n");
}
} }
static void static void
print_format (GstCaps *caps) print_format (GstCaps *caps)
{ {
g_print (" format:\n"); char *s;
if (!caps || caps->properties == NULL) { s = gst_caps_to_string (caps);
g_print (" unkown\n"); g_print(" format: %s\n", s);
return; g_free (s);
}
if (!strcmp (gst_caps_get_mime (caps), "audio/raw")) {
gint channels;
gint rate;
gst_caps_get_int (caps, "channels", &channels);
gst_caps_get_int (caps, "rate", &rate);
g_print (" channels: %d\n", channels);
g_print (" rate: %d\n", rate);
}
else {
g_print (" unkown format\n");
}
} }
static void static void

View file

@ -344,7 +344,7 @@ found_track:
/* gets the matching alsa format or NULL if none matches */ /* gets the matching alsa format or NULL if none matches */
static GstAlsaFormat * static GstAlsaFormat *
gst_alsa_get_format (GstCaps *caps) gst_alsa_get_format (const GstStructure *structure)
{ {
const gchar *mimetype; const gchar *mimetype;
GstAlsaFormat *ret; GstAlsaFormat *ret;
@ -353,19 +353,21 @@ gst_alsa_get_format (GstCaps *caps)
return NULL; return NULL;
/* we have to differentiate between int and float formats */ /* we have to differentiate between int and float formats */
mimetype = gst_caps_get_mime (caps); mimetype = gst_structure_get_name (structure);
if (! strncmp (mimetype, "audio/x-raw-int", 15)) { if (! strncmp (mimetype, "audio/x-raw-int", 15)) {
gboolean sign; gboolean sign;
gint width, depth, endianness; gint width, depth, endianness;
/* extract the needed information from the caps */ /* extract the needed information from the cap */
if (! gst_caps_get (caps, "width", &width, "depth", &depth, "signed", &sign, NULL)) if (!(gst_structure_get_int (structure, "width", &width) &&
goto error; gst_structure_get_int (structure, "depth", &depth) &&
gst_structure_get_boolean (structure, "signed", &sign)))
goto error;
/* extract endianness if needed */ /* extract endianness if needed */
if (width > 8) { if (width > 8) {
if (! gst_caps_get (caps, "endianness", &endianness, NULL)) if (!gst_structure_get_int (structure, "endianness", &endianness))
goto error; goto error;
} else { } else {
endianness = G_BYTE_ORDER; endianness = G_BYTE_ORDER;
@ -377,7 +379,7 @@ gst_alsa_get_format (GstCaps *caps)
gint width; gint width;
/* get layout */ /* get layout */
if (! gst_caps_get (caps, "width", &width, NULL)) if (!gst_structure_get_int (structure, "width", &width))
goto error; goto error;
/* match layout to format wrt to endianness */ /* match layout to format wrt to endianness */
@ -407,7 +409,8 @@ gst_alsa_get_format (GstCaps *caps)
} }
/* get rate and channels */ /* get rate and channels */
if (!gst_caps_get (caps, "rate", &ret->rate, "channels", &ret->channels, NULL)) if (!(gst_structure_get_int (structure, "rate", &ret->rate) &&
gst_structure_get_int (structure, "channels", &ret->channels)))
goto error; goto error;
return ret; return ret;
@ -431,73 +434,69 @@ gst_alsa_formats_match (GstAlsaFormat *one, GstAlsaFormat *two)
static GstCaps * static GstCaps *
gst_alsa_get_caps_internal (snd_pcm_format_t format) gst_alsa_get_caps_internal (snd_pcm_format_t format)
{ {
const gchar *name = snd_pcm_format_name (format);
if (format == SND_PCM_FORMAT_A_LAW) { if (format == SND_PCM_FORMAT_A_LAW) {
return GST_CAPS_NEW (name, "audio/x-alaw", return gst_caps_new_simple ("audio/x-alaw", NULL);
"law", GST_PROPS_INT(2),
"width", GST_PROPS_INT(8),
"depth", GST_PROPS_INT(8),
"signed", GST_PROPS_BOOLEAN (FALSE),
NULL);
} else if (format == SND_PCM_FORMAT_MU_LAW) { } else if (format == SND_PCM_FORMAT_MU_LAW) {
return GST_CAPS_NEW (name, "audio/x-mulaw", return gst_caps_new_simple ("audio/x-mulaw", NULL);
"law", GST_PROPS_INT(1),
"width", GST_PROPS_INT(8),
"depth", GST_PROPS_INT(8),
"signed", GST_PROPS_BOOLEAN (FALSE),
NULL);
} else if (snd_pcm_format_linear (format)) { } else if (snd_pcm_format_linear (format)) {
/* int */ /* int */
GstProps *props = GstStructure *structure = gst_structure_new ("audio/x-raw-int",
gst_props_new ("width", GST_PROPS_INT(snd_pcm_format_physical_width (format)), "width", G_TYPE_INT, (gint) snd_pcm_format_physical_width (format),
"depth", GST_PROPS_INT(snd_pcm_format_width (format)), "depth", G_TYPE_INT, (gint) snd_pcm_format_width (format),
"law", GST_PROPS_INT(0), "signed", G_TYPE_BOOLEAN, snd_pcm_format_signed (format) == 1 ? TRUE : FALSE,
"signed", GST_PROPS_BOOLEAN (snd_pcm_format_signed (format) == 1 ? TRUE : FALSE), NULL);
NULL);
/* endianness */ /* endianness */
if (snd_pcm_format_physical_width (format) > 8) { if (snd_pcm_format_physical_width (format) > 8) {
switch (snd_pcm_format_little_endian (format)) { switch (snd_pcm_format_little_endian (format)) {
case 0: case 0:
gst_props_add_entry (props, gst_props_entry_new ("endianness", GST_PROPS_INT (G_BIG_ENDIAN))); gst_structure_set (structure, "endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL);
break; break;
case 1: case 1:
gst_props_add_entry (props, gst_props_entry_new ("endianness", GST_PROPS_INT (G_LITTLE_ENDIAN))); gst_structure_set (structure, "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, NULL);
break; break;
default: default:
GST_WARNING ("Unknown byte order in sound driver. Continuing by assuming system byte order."); GST_WARNING ("Unknown byte order in sound driver. Continuing by assuming system byte order.");
gst_props_add_entry (props, gst_props_entry_new ("endianness", GST_PROPS_INT (G_BYTE_ORDER))); gst_structure_set (structure, "endianness", G_TYPE_INT, G_BYTE_ORDER, NULL);
break; break;
} }
} }
return gst_caps_new (name, "audio/x-raw-int", props); return gst_caps_new_full (structure, NULL);
} else if (snd_pcm_format_float (format)) { } else if (snd_pcm_format_float (format)) {
/* no float with non-platform endianness */ /* no float with non-platform endianness */
if (!snd_pcm_format_cpu_endian (format)) if (!snd_pcm_format_cpu_endian (format))
return NULL; return NULL;
return GST_CAPS_NEW (name, "audio/x-raw-float", return gst_caps_new_simple ("audio/x-raw-float",
"width", GST_PROPS_INT (snd_pcm_format_width (format)), "width", G_TYPE_INT, (gint) snd_pcm_format_width (format),
"endianness", GST_PROPS_INT (G_BYTE_ORDER)); "endianness", G_TYPE_INT, G_BYTE_ORDER,
NULL);
} }
return NULL; return NULL;
} }
static inline void static inline void
add_channels (GstProps *props, gint min_rate, gint max_rate, gint min_channels, gint max_channels) { add_channels (GstStructure *structure, gint min_rate, gint max_rate,
gint min_channels, gint max_channels)
{
if (min_rate < 0) { if (min_rate < 0) {
gst_props_add_entry (props, gst_props_entry_new ("rate", GST_PROPS_INT_RANGE (GST_ALSA_MIN_RATE, GST_ALSA_MAX_RATE))); min_rate = GST_ALSA_MIN_RATE;
} else if (max_rate < 0) { max_rate = GST_ALSA_MAX_RATE;
gst_props_add_entry (props, gst_props_entry_new ("rate", GST_PROPS_INT (min_rate))); }
if (max_rate < 0) {
gst_structure_set (structure, "rate", G_TYPE_INT, min_rate, NULL);
} else { } else {
gst_props_add_entry (props, gst_props_entry_new ("rate", GST_PROPS_INT_RANGE (min_rate, max_rate))); gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, min_rate,
max_rate, NULL);
} }
if (min_channels < 0) { if (min_channels < 0) {
gst_props_add_entry (props, gst_props_entry_new ("channels", GST_PROPS_INT_RANGE (1, GST_ALSA_MAX_CHANNELS))); min_channels = 1;
} else if (max_channels < 0) { max_channels = GST_ALSA_MAX_CHANNELS;
gst_props_add_entry (props, gst_props_entry_new ("channels", GST_PROPS_INT (min_channels))); }
if (max_channels < 0) {
gst_structure_set (structure, "channels", G_TYPE_INT, min_channels, NULL);
} else { } else {
gst_props_add_entry (props, gst_props_entry_new ("channels", GST_PROPS_INT_RANGE (min_channels, max_channels))); gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE,
min_channels, max_channels, NULL);
} }
} }
@ -510,7 +509,7 @@ add_channels (GstProps *props, gint min_rate, gint max_rate, gint min_channels,
GstCaps * GstCaps *
gst_alsa_caps (snd_pcm_format_t format, gint rate, gint channels) gst_alsa_caps (snd_pcm_format_t format, gint rate, gint channels)
{ {
GstCaps *ret_caps = NULL; GstCaps *ret_caps;
if (format != SND_PCM_FORMAT_UNKNOWN) { if (format != SND_PCM_FORMAT_UNKNOWN) {
/* there are some caps set already */ /* there are some caps set already */
@ -518,20 +517,22 @@ gst_alsa_caps (snd_pcm_format_t format, gint rate, gint channels)
/* we can never use a format we can't set caps for */ /* we can never use a format we can't set caps for */
g_assert (ret_caps != NULL); g_assert (ret_caps != NULL);
g_assert (ret_caps->properties != NULL); g_assert (gst_caps_get_size (ret_caps) == 1);
add_channels (ret_caps->properties, rate, -1, channels, -1); add_channels (gst_caps_get_structure (ret_caps, 0), rate, -1, channels, -1);
} else { } else {
int i; int i;
GstCaps *temp; GstCaps *temp;
ret_caps = gst_caps_new_empty ();
for (i = 0; i <= SND_PCM_FORMAT_LAST; i++) { for (i = 0; i <= SND_PCM_FORMAT_LAST; i++) {
temp = gst_alsa_get_caps_internal (i); temp = gst_alsa_get_caps_internal (i);
/* can be NULL, because not all alsa formats can be specified as caps */ /* can be NULL, because not all alsa formats can be specified as caps */
if (temp != NULL && temp->properties != NULL) { if (temp != NULL) {
add_channels (temp->properties, rate, -1, channels, -1); g_assert (gst_caps_get_size (temp) == 1);
ret_caps = gst_caps_append (ret_caps, temp); add_channels (gst_caps_get_structure (temp, 0), rate, -1, channels, -1);
gst_caps_append (ret_caps, temp);
} }
} }
} }
@ -541,7 +542,7 @@ gst_alsa_caps (snd_pcm_format_t format, gint rate, gint channels)
/* Return better caps when device is open */ /* Return better caps when device is open */
GstCaps * GstCaps *
gst_alsa_get_caps (GstPad *pad, GstCaps *caps) gst_alsa_get_caps (GstPad *pad)
{ {
GstAlsa *this; GstAlsa *this;
snd_pcm_hw_params_t *hw_params; snd_pcm_hw_params_t *hw_params;
@ -556,8 +557,8 @@ gst_alsa_get_caps (GstPad *pad, GstCaps *caps)
this = GST_ALSA (gst_pad_get_parent (pad)); this = GST_ALSA (gst_pad_get_parent (pad));
if (!GST_FLAG_IS_SET (this, GST_ALSA_OPEN)) if (!GST_FLAG_IS_SET (this, GST_ALSA_OPEN))
return gst_pad_get_pad_template_caps (pad); return NULL;
snd_pcm_hw_params_alloca (&hw_params); snd_pcm_hw_params_alloca (&hw_params);
ERROR_CHECK (snd_pcm_hw_params_any (this->handle, hw_params), ERROR_CHECK (snd_pcm_hw_params_any (this->handle, hw_params),
"Broken configuration for this PCM: %s"); "Broken configuration for this PCM: %s");
@ -587,9 +588,10 @@ gst_alsa_get_caps (GstPad *pad, GstCaps *caps)
if (snd_pcm_format_mask_test (mask, i)) { if (snd_pcm_format_mask_test (mask, i)) {
GstCaps *caps = gst_alsa_get_caps_internal (i); GstCaps *caps = gst_alsa_get_caps_internal (i);
/* we can never use a format we can't set caps for */ /* we can never use a format we can't set caps for */
if (caps != NULL && caps->properties != NULL) { if (caps != NULL) {
add_channels (caps->properties, min_rate, max_rate, min_channels, max_channels); g_assert (gst_caps_get_size (caps) == 1);
ret = gst_caps_append (ret, caps); add_channels (gst_caps_get_structure (caps, 0), min_rate, max_rate, min_channels, max_channels);
gst_caps_append (ret, caps);
} }
} }
} }
@ -599,7 +601,7 @@ gst_alsa_get_caps (GstPad *pad, GstCaps *caps)
/* Negotiates the caps */ /* Negotiates the caps */
GstPadLinkReturn GstPadLinkReturn
gst_alsa_link (GstPad *pad, GstCaps *caps) gst_alsa_link (GstPad *pad, const GstCaps *caps)
{ {
GstAlsa *this; GstAlsa *this;
GstAlsaFormat *format; GstAlsaFormat *format;
@ -610,50 +612,48 @@ gst_alsa_link (GstPad *pad, GstCaps *caps)
this = GST_ALSA (gst_pad_get_parent (pad)); this = GST_ALSA (gst_pad_get_parent (pad));
if (GST_CAPS_IS_FIXED (caps)) { if (this->handle == NULL)
if (this->handle == NULL && ! gst_alsa_open_audio (this)) if (!gst_alsa_open_audio (this))
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
format = gst_alsa_get_format (caps); format = gst_alsa_get_format (gst_caps_get_structure (caps, 0));
if (format == NULL) if (format == NULL)
return GST_PAD_LINK_DELAYED; return GST_PAD_LINK_REFUSED;
GST_DEBUG ("found format %s", snd_pcm_format_name (format->format));
if (!GST_FLAG_IS_SET (this, GST_ALSA_CAPS_NEGO)) {
gint i;
GST_DEBUG ("found format %s", snd_pcm_format_name (format->format)); GST_FLAG_SET (this, GST_ALSA_CAPS_NEGO);
if (! GST_FLAG_IS_SET (this, GST_ALSA_CAPS_NEGO)) { if (gst_alsa_formats_match (this->format, format)) {
gint i; ret = GST_PAD_LINK_OK;
goto out;
}
GST_FLAG_SET (this, GST_ALSA_CAPS_NEGO); if (!gst_alsa_probe_hw_params (this, format)) {
ret = GST_PAD_LINK_REFUSED;
goto out;
}
if (gst_alsa_formats_match (this->format, format)) { for (i = 0; i < ((GstElement *) this)->numpads; i++) {
ret = GST_PAD_LINK_OK; g_assert (this->pad[i] != NULL);
goto out; if (this->pad[i] == pad)
} continue;
if (gst_pad_try_set_caps (this->pad[i], caps) == GST_PAD_LINK_REFUSED) {
if (! gst_alsa_probe_hw_params (this, format)) { if (this->format) {
ret = GST_PAD_LINK_REFUSED; GstCaps *old = gst_alsa_caps (this->format->format, this->format->rate, this->format->channels);
goto out; for (--i; i >= 0; i--) {
} if (gst_pad_try_set_caps (this->pad[i], old) == GST_PAD_LINK_REFUSED) {
gst_element_error (GST_ELEMENT (this), "error resetting caps to sane value");
for (i = 0; i < ((GstElement *) this)->numpads; i++) { gst_caps_free (old);
g_assert (this->pad[i] != NULL); break;
} else {
if (this->pad[i] == pad) continue; /* FIXME: unset caps on pads somehow */
if (gst_pad_try_set_caps (this->pad[i], gst_caps_ref (caps)) == GST_PAD_LINK_REFUSED) {
if (this->format) {
GstCaps *old = gst_alsa_caps (this->format->format, this->format->rate, this->format->channels);
for (--i; i >= 0; i--) {
if (gst_pad_try_set_caps (this->pad[i], gst_caps_ref (old)) == GST_PAD_LINK_REFUSED) {
gst_element_error (GST_ELEMENT (this), "error resetting caps to sane value");
gst_caps_unref (old);
break;
}
} }
gst_caps_unref (old);
} else {
/* FIXME: unset caps on pads somehow */
} }
gst_caps_free (old);
ret = GST_PAD_LINK_REFUSED; ret = GST_PAD_LINK_REFUSED;
goto out; goto out;
} }

View file

@ -171,9 +171,8 @@ GType gst_alsa_get_type (void);
void gst_alsa_set_eos (GstAlsa * this); void gst_alsa_set_eos (GstAlsa * this);
GstPadLinkReturn gst_alsa_link (GstPad * pad, GstPadLinkReturn gst_alsa_link (GstPad * pad,
GstCaps * caps); const GstCaps * caps);
GstCaps * gst_alsa_get_caps (GstPad * pad, GstCaps * gst_alsa_get_caps (GstPad * pad);
GstCaps *caps);
GstCaps * gst_alsa_caps (snd_pcm_format_t format, GstCaps * gst_alsa_caps (snd_pcm_format_t format,
gint rate, gint rate,
gint channels); gint channels);

View file

@ -65,8 +65,7 @@ gst_alsa_sink_pad_factory (void)
if (!template) if (!template)
template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, -1), gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, -1));
NULL);
return template; return template;
} }
@ -78,8 +77,7 @@ gst_alsa_sink_request_pad_factory (void)
if (!template) if (!template)
template = template =
gst_pad_template_new ("sink%d", GST_PAD_SINK, GST_PAD_REQUEST, gst_pad_template_new ("sink%d", GST_PAD_SINK, GST_PAD_REQUEST,
gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, 1), gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, 1));
NULL);
return template; return template;
} }

View file

@ -61,8 +61,7 @@ gst_alsa_src_pad_factory (void)
if (!template) if (!template)
template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, -1), gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, -1));
NULL);
return template; return template;
} }
@ -73,8 +72,7 @@ gst_alsa_src_request_pad_factory (void)
if (!template) if (!template)
template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, 1), gst_alsa_caps (SND_PCM_FORMAT_UNKNOWN, -1, 1));
NULL);
return template; return template;
} }
@ -241,14 +239,15 @@ gst_alsa_src_adjust_rate (gint rate, gboolean aggressive)
static gboolean static gboolean
gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive) gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive)
{ {
GstCaps *all_caps, *caps, *walk; GstCaps *all_caps, *caps;
GstStructure *structure, *walk;
gint channels, min_channels, max_channels; gint channels, min_channels, max_channels;
gint rate, min_rate, max_rate; gint rate, min_rate, max_rate;
gint i, endian, width, depth; gint i, endian, width, depth;
gboolean sign; gboolean sign;
GstAlsa *this = GST_ALSA (src); GstAlsa *this = GST_ALSA (src);
all_caps = gst_alsa_get_caps (this->pad[0], NULL); all_caps = gst_alsa_get_caps (this->pad[0]);
if (all_caps == NULL) return FALSE; if (all_caps == NULL) return FALSE;
/* now intersect this with all caps of the peers... */ /* now intersect this with all caps of the peers... */
for (i = 0; i < GST_ELEMENT (src)->numpads; i++) { for (i = 0; i < GST_ELEMENT (src)->numpads; i++) {
@ -260,38 +259,40 @@ gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive)
} }
/* construct caps */ /* construct caps */
caps = GST_CAPS_NEW ("alsasrc caps", "audio/x-raw-int", caps = gst_caps_new_simple ("audio/x-raw-int",
"endianness", GST_PROPS_INT (G_BYTE_ORDER), NULL);
"signed", GST_PROPS_BOOLEAN (TRUE), g_assert (gst_caps_get_size (caps) == 1);
"width", GST_PROPS_INT (16), structure = gst_caps_get_structure (caps, 0);
"depth", GST_PROPS_INT (16),
"rate", GST_PROPS_INT (44100),
"channels", GST_PROPS_INT (1));
gst_caps_ref (caps);
gst_caps_sink (caps);
/* now try to find the best match */ /* now try to find the best match */
walk = all_caps; for (i = 0; i < gst_caps_get_size (all_caps); i++) {
while (walk) { walk = gst_caps_get_structure (all_caps, i);
gst_caps_get (walk, "signed", &sign, "width", &width, "depth", &depth, NULL); if (!(gst_structure_get_int (walk, "signed", &sign) &&
if (gst_caps_has_property (walk, "endianness")) { gst_structure_get_int (walk, "width", &width) &&
gst_caps_get_int (walk, "endianness", &endian); gst_structure_get_int (walk, "depth", &depth))) {
} else { GST_ERROR_OBJECT (src, "couldn't parse my own format. Huh?");
continue;
}
if (!gst_structure_get_int (walk, "endianness", &endian)) {
endian = G_BYTE_ORDER; endian = G_BYTE_ORDER;
} }
gst_caps_set (caps, "endianness", GST_PROPS_INT (endian)); gst_structure_set (structure,
gst_caps_set (caps, "width", GST_PROPS_INT (width)); "endianness", G_TYPE_INT, endian,
gst_caps_set (caps, "depth", GST_PROPS_INT (depth)); "width", G_TYPE_INT, width,
gst_caps_set (caps, "signed", GST_PROPS_BOOLEAN (sign)); "depth", G_TYPE_INT, depth,
"signed", G_TYPE_BOOLEAN, sign,
NULL);
gst_props_entry_get_int_range (gst_props_get_entry (GST_CAPS_PROPERTIES (walk), "rate"), &min_rate, &max_rate); min_rate = gst_value_get_int_range_min (gst_structure_get_value (walk, "rate"));
gst_props_entry_get_int_range (gst_props_get_entry (GST_CAPS_PROPERTIES (walk), "channels"), &min_channels, &max_channels); max_rate = gst_value_get_int_range_max (gst_structure_get_value (walk, "rate"));
min_channels = gst_value_get_int_range_min (gst_structure_get_value (walk, "channels"));
max_channels = gst_value_get_int_range_max (gst_structure_get_value (walk, "channels"));
for (rate = max_rate;; rate--) { for (rate = max_rate;; rate--) {
if ((rate = gst_alsa_src_adjust_rate (rate, aggressive)) < min_rate) if ((rate = gst_alsa_src_adjust_rate (rate, aggressive)) < min_rate)
break; break;
gst_caps_set (caps, "rate", GST_PROPS_INT (rate)); gst_structure_set (structure, "rate", G_TYPE_INT, rate, NULL);
for (channels = aggressive ? max_channels : MIN (max_channels, 2); channels >= min_channels; channels--) { for (channels = aggressive ? max_channels : MIN (max_channels, 2); channels >= min_channels; channels--) {
gst_caps_set (caps, "channels", GST_PROPS_INT (channels)); gst_structure_set (structure, "channels", G_TYPE_INT, channels, NULL);
GST_DEBUG ("trying new caps: %ssigned, endianness: %d, width %d, depth %d, channels %d, rate %d", GST_DEBUG ("trying new caps: %ssigned, endianness: %d, width %d, depth %d, channels %d, rate %d",
sign ? "" : "un", endian, width, depth, channels, rate); sign ? "" : "un", endian, width, depth, channels, rate);
if (gst_pad_try_set_caps (this->pad[0], caps) != GST_PAD_LINK_REFUSED) if (gst_pad_try_set_caps (this->pad[0], caps) != GST_PAD_LINK_REFUSED)
@ -303,7 +304,6 @@ gst_alsa_src_set_caps (GstAlsaSrc *src, gboolean aggressive)
} }
} }
} }
walk = GST_CAPS_NEXT (walk);
} }
if (!aggressive) if (!aggressive)
@ -326,11 +326,6 @@ gst_alsa_src_loop (GstElement *element)
gst_element_error (element, "Could not set caps"); gst_element_error (element, "Could not set caps");
return; return;
} }
/* get the bufferpool going */
if (src->pool)
gst_buffer_pool_unref (src->pool);
src->pool = gst_buffer_pool_get_default (gst_alsa_samples_to_bytes (this, this->period_size),
2 * element->numpads);
} }
while ((avail = gst_alsa_update_avail (this)) < this->period_size) { while ((avail = gst_alsa_update_avail (this)) < this->period_size) {
@ -349,7 +344,7 @@ gst_alsa_src_loop (GstElement *element)
/* make sure every pad has a buffer */ /* make sure every pad has a buffer */
for (i = 0; i < element->numpads; i++) { for (i = 0; i < element->numpads; i++) {
if (!src->buf[i]) { if (!src->buf[i]) {
src->buf[i] = gst_buffer_new_from_pool (src->pool, 0, 0); src->buf[i] = gst_buffer_new_and_alloc (4096);
} }
} }
/* fill buffer with data */ /* fill buffer with data */
@ -380,10 +375,6 @@ gst_alsa_src_flush (GstAlsaSrc *src)
src->buf[i] = NULL; src->buf[i] = NULL;
} }
} }
if (src->pool) {
gst_buffer_pool_unref (src->pool);
src->pool = NULL;
}
} }
static GstElementStateReturn static GstElementStateReturn
gst_alsa_src_change_state (GstElement *element) gst_alsa_src_change_state (GstElement *element)

View file

@ -38,7 +38,6 @@ typedef struct _GstAlsaSrcClass GstAlsaSrcClass;
struct _GstAlsaSrc { struct _GstAlsaSrc {
GstAlsa parent; GstAlsa parent;
GstBuffer *buf[GST_ALSA_MAX_TRACKS]; GstBuffer *buf[GST_ALSA_MAX_TRACKS];
GstBufferPool *pool;
}; };
struct _GstAlsaSrcClass { struct _GstAlsaSrcClass {

View file

@ -51,21 +51,21 @@ static GstElementDetails cdparanoia_details = {
"Erik Walthinsen <omega@cse.ogi.edu>", "Erik Walthinsen <omega@cse.ogi.edu>",
}; };
GST_PAD_TEMPLATE_FACTORY (cdparanoia_src_factory, static GstStaticPadTemplate cdparanoia_src_template =
"src", GST_STATIC_PAD_TEMPLATE (
GST_PAD_SRC, "src",
GST_PAD_ALWAYS, GST_PAD_SRC,
GST_CAPS_NEW ( GST_PAD_ALWAYS,
"cdparanoia_src", GST_STATIC_CAPS (
"audio/x-raw-int", "audio/x-raw-int, "
"endianness", GST_PROPS_INT (G_BYTE_ORDER), "endianness = (int) BYTE_ORDER, "
"signed", GST_PROPS_BOOLEAN (TRUE), "signed = (boolean) true, "
"width", GST_PROPS_INT (16), "width = (int) 16, "
"depth", GST_PROPS_INT (16), "depth = (int) 16, "
"rate", GST_PROPS_INT (44100), "rate = (int) 44100, "
"channels", GST_PROPS_INT (2), "channels = (int) 2, "
"chunksize", GST_PROPS_INT (CD_FRAMESIZE_RAW) "chunksize = (int) " G_STRINGIFY(CD_FRAMESIZE_RAW)
) )
); );
@ -202,7 +202,8 @@ cdparanoia_base_init (gpointer g_class)
{ {
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (element_class, GST_PAD_TEMPLATE_GET (cdparanoia_src_factory)); gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&cdparanoia_src_template));
gst_element_class_set_details (element_class, &cdparanoia_details); gst_element_class_set_details (element_class, &cdparanoia_details);
} }
@ -289,7 +290,8 @@ static void
cdparanoia_init (CDParanoia *cdparanoia) cdparanoia_init (CDParanoia *cdparanoia)
{ {
cdparanoia->srcpad = cdparanoia->srcpad =
gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (cdparanoia_src_factory), "src"); gst_pad_new_from_template (
gst_static_pad_template_get (&cdparanoia_src_template), "src");
gst_pad_set_get_function (cdparanoia->srcpad, cdparanoia_get); gst_pad_set_get_function (cdparanoia->srcpad, cdparanoia_get);
gst_pad_set_event_function (cdparanoia->srcpad, cdparanoia_event); gst_pad_set_event_function (cdparanoia->srcpad, cdparanoia_event);
gst_pad_set_event_mask_function (cdparanoia->srcpad, cdparanoia_get_event_mask); gst_pad_set_event_mask_function (cdparanoia->srcpad, cdparanoia_get_event_mask);

View file

@ -82,22 +82,21 @@ enum {
/* FILL ME */ /* FILL ME */
}; };
GST_PAD_TEMPLATE_FACTORY (ogg_demux_src_template_factory, static GstStaticPadTemplate ogg_demux_src_template_factory =
GST_STATIC_PAD_TEMPLATE (
"src", "src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_SOMETIMES, GST_PAD_SOMETIMES,
NULL GST_STATIC_CAPS_ANY
) );
GST_PAD_TEMPLATE_FACTORY (ogg_demux_sink_template_factory,
static GstStaticPadTemplate ogg_demux_sink_template_factory =
GST_STATIC_PAD_TEMPLATE (
"sink", "sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_CAPS_NEW ( GST_STATIC_CAPS ("application/ogg")
"ogg_demux_sink", );
"application/ogg",
NULL
)
)
static void gst_ogg_demux_base_init (gpointer g_class); static void gst_ogg_demux_base_init (gpointer g_class);
@ -170,9 +169,9 @@ gst_ogg_demux_base_init (gpointer g_class)
gst_element_class_set_details (element_class, &gst_ogg_demux_details); gst_element_class_set_details (element_class, &gst_ogg_demux_details);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_GET (ogg_demux_sink_template_factory)); gst_static_pad_template_get (&ogg_demux_sink_template_factory));
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_GET (ogg_demux_src_template_factory)); gst_static_pad_template_get (&ogg_demux_src_template_factory));
} }
static void static void
gst_ogg_demux_class_init (gpointer g_class, gpointer class_data) gst_ogg_demux_class_init (gpointer g_class, gpointer class_data)
@ -193,7 +192,7 @@ gst_ogg_demux_init (GTypeInstance *instance, gpointer g_class)
/* create the sink pad */ /* create the sink pad */
ogg->sinkpad = gst_pad_new_from_template( ogg->sinkpad = gst_pad_new_from_template(
GST_PAD_TEMPLATE_GET (ogg_demux_sink_template_factory), "sink"); gst_static_pad_template_get (&ogg_demux_sink_template_factory), "sink");
gst_element_add_pad (GST_ELEMENT (ogg), ogg->sinkpad); gst_element_add_pad (GST_ELEMENT (ogg), ogg->sinkpad);
gst_pad_set_chain_function (ogg->sinkpad, GST_DEBUG_FUNCPTR (gst_ogg_demux_chain)); gst_pad_set_chain_function (ogg->sinkpad, GST_DEBUG_FUNCPTR (gst_ogg_demux_chain));
@ -438,7 +437,9 @@ gst_ogg_pad_push (GstOggDemux *ogg, GstOggPad *pad)
GstCaps *caps = gst_ogg_type_find (&packet); GstCaps *caps = gst_ogg_type_find (&packet);
gchar *name = g_strdup_printf ("serial %d", pad->serial); gchar *name = g_strdup_printf ("serial %d", pad->serial);
pad->pad = gst_pad_new_from_template (ogg_demux_src_template_factory(), name); pad->pad = gst_pad_new_from_template (
gst_static_pad_template_get (&ogg_demux_src_template_factory),
name);
g_free (name); g_free (name);
gst_pad_set_event_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_src_event)); gst_pad_set_event_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_src_event));
gst_pad_set_event_mask_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_get_event_masks)); gst_pad_set_event_mask_function (pad->pad, GST_DEBUG_FUNCPTR (gst_ogg_demux_get_event_masks));
@ -527,12 +528,12 @@ ogg_find_peek (gpointer data, gint64 offset, guint size)
} }
} }
static void static void
ogg_find_suggest (gpointer data, guint probability, GstCaps *caps) ogg_find_suggest (gpointer data, guint probability, const GstCaps *caps)
{ {
OggTypeFind *find = (OggTypeFind *) data; OggTypeFind *find = (OggTypeFind *) data;
if (probability > find->best_probability) { if (probability > find->best_probability) {
gst_caps_replace_sink (&find->caps, caps); gst_caps_replace (&find->caps, gst_caps_copy (caps));
find->best_probability = probability; find->best_probability = probability;
} }
} }

View file

@ -28,46 +28,35 @@ enum {
}; };
GST_PAD_TEMPLATE_FACTORY(textoverlay_src_template_factory, static GstStaticPadTemplate textoverlay_src_template_factory =
"src", GST_STATIC_PAD_TEMPLATE (
GST_PAD_SRC, "src",
GST_PAD_ALWAYS, GST_PAD_SRC,
GST_CAPS_NEW( GST_PAD_ALWAYS,
"textoverlay_src", GST_STATIC_CAPS ("video/x-raw-yuv, "
"video/x-raw-yuv", "format = (fourcc) I420, "
"format", GST_PROPS_LIST( "width = (int) [ 1, MAX ], "
GST_PROPS_FOURCC(GST_STR_FOURCC("I420")) "height = (int) [ 1, MAX ]")
), );
"width", GST_PROPS_INT_RANGE(0, G_MAXINT),
"height", GST_PROPS_INT_RANGE(0, G_MAXINT)
)
)
GST_PAD_TEMPLATE_FACTORY(video_sink_template_factory, static GstStaticPadTemplate video_sink_template_factory =
"video_sink", GST_STATIC_PAD_TEMPLATE (
GST_PAD_SINK, "video_sink",
GST_PAD_ALWAYS, GST_PAD_SINK,
GST_CAPS_NEW( GST_PAD_ALWAYS,
"video_sink", GST_STATIC_CAPS ("video/x-raw-yuv, "
"video/x-raw-yuv", "format = (fourcc) I420, "
"format", GST_PROPS_LIST( "width = (int) [ 1, MAX ], "
GST_PROPS_FOURCC(GST_STR_FOURCC("I420")) "height = (int) [ 1, MAX ]")
), );
"width", GST_PROPS_INT_RANGE(0, G_MAXINT),
"height", GST_PROPS_INT_RANGE(0, G_MAXINT)
)
)
GST_PAD_TEMPLATE_FACTORY(text_sink_template_factory, static GstStaticPadTemplate text_sink_template_factory =
"text_sink", GST_STATIC_PAD_TEMPLATE (
GST_PAD_SINK, "text_sink",
GST_PAD_ALWAYS, GST_PAD_SINK,
GST_CAPS_NEW( GST_PAD_ALWAYS,
"text_sink", GST_STATIC_CAPS ("text/x-pango-markup; text/plain")
"text/x-pango-markup", );
NULL
)
)
static void gst_textoverlay_base_init (gpointer g_class); static void gst_textoverlay_base_init (gpointer g_class);
static void gst_textoverlay_class_init(GstTextOverlayClass *klass); static void gst_textoverlay_class_init(GstTextOverlayClass *klass);
@ -116,9 +105,12 @@ gst_textoverlay_base_init (gpointer g_class)
{ {
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (element_class, GST_PAD_TEMPLATE_GET (textoverlay_src_template_factory)); gst_element_class_add_pad_template (element_class,
gst_element_class_add_pad_template (element_class, GST_PAD_TEMPLATE_GET (video_sink_template_factory)); gst_static_pad_template_get (&textoverlay_src_template_factory));
gst_element_class_add_pad_template (element_class, GST_PAD_TEMPLATE_GET (text_sink_template_factory)); gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&video_sink_template_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&text_sink_template_factory));
gst_element_class_set_details (element_class, &textoverlay_details); gst_element_class_set_details (element_class, &textoverlay_details);
} }
@ -228,18 +220,17 @@ render_text(GstTextOverlay *overlay)
static GstPadLinkReturn static GstPadLinkReturn
gst_textoverlay_video_sinkconnect(GstPad *pad, GstCaps *caps) gst_textoverlay_video_sinkconnect(GstPad *pad, const GstCaps *caps)
{ {
GstTextOverlay *overlay; GstTextOverlay *overlay;
GstStructure *structure;
overlay = GST_TEXTOVERLAY(gst_pad_get_parent(pad)); overlay = GST_TEXTOVERLAY(gst_pad_get_parent(pad));
if (!GST_CAPS_IS_FIXED(caps)) structure = gst_caps_get_structure (caps, 0);
return GST_PAD_LINK_DELAYED;
overlay->width = overlay->height = 0; overlay->width = overlay->height = 0;
gst_caps_get_int(caps, "width", &overlay->width); gst_structure_get_int (structure, "width", &overlay->width);
gst_caps_get_int(caps, "height", &overlay->height); gst_structure_get_int (structure, "height", &overlay->height);
return gst_pad_try_set_caps(overlay->srcpad, caps); return gst_pad_try_set_caps(overlay->srcpad, caps);
} }
@ -514,20 +505,20 @@ gst_textoverlay_init(GstTextOverlay *overlay)
{ {
/* video sink */ /* video sink */
overlay->video_sinkpad = gst_pad_new_from_template( overlay->video_sinkpad = gst_pad_new_from_template(
GST_PAD_TEMPLATE_GET(video_sink_template_factory), "video_sink"); gst_static_pad_template_get (&video_sink_template_factory), "video_sink");
/* gst_pad_set_chain_function(overlay->video_sinkpad, gst_textoverlay_video_chain); */ /* gst_pad_set_chain_function(overlay->video_sinkpad, gst_textoverlay_video_chain); */
gst_pad_set_link_function(overlay->video_sinkpad, gst_textoverlay_video_sinkconnect); gst_pad_set_link_function(overlay->video_sinkpad, gst_textoverlay_video_sinkconnect);
gst_element_add_pad(GST_ELEMENT(overlay), overlay->video_sinkpad); gst_element_add_pad(GST_ELEMENT(overlay), overlay->video_sinkpad);
/* text sink */ /* text sink */
overlay->text_sinkpad = gst_pad_new_from_template( overlay->text_sinkpad = gst_pad_new_from_template(
GST_PAD_TEMPLATE_GET(text_sink_template_factory), "text_sink"); gst_static_pad_template_get (&text_sink_template_factory), "text_sink");
/* gst_pad_set_link_function(overlay->text_sinkpad, gst_textoverlay_text_sinkconnect); */ /* gst_pad_set_link_function(overlay->text_sinkpad, gst_textoverlay_text_sinkconnect); */
gst_element_add_pad(GST_ELEMENT(overlay), overlay->text_sinkpad); gst_element_add_pad(GST_ELEMENT(overlay), overlay->text_sinkpad);
/* (video) source */ /* (video) source */
overlay->srcpad = gst_pad_new_from_template( overlay->srcpad = gst_pad_new_from_template(
GST_PAD_TEMPLATE_GET(textoverlay_src_template_factory), "src"); gst_static_pad_template_get (&textoverlay_src_template_factory), "src");
gst_element_add_pad(GST_ELEMENT(overlay), overlay->srcpad); gst_element_add_pad(GST_ELEMENT(overlay), overlay->srcpad);
overlay->layout = pango_layout_new(GST_TEXTOVERLAY_GET_CLASS(overlay)->pango_context); overlay->layout = pango_layout_new(GST_TEXTOVERLAY_GET_CLASS(overlay)->pango_context);

View file

@ -132,28 +132,21 @@ vorbisenc_get_type (void)
static GstCaps* static GstCaps*
vorbis_caps_factory (void) vorbis_caps_factory (void)
{ {
return return gst_caps_new_simple ("application/ogg", NULL);
gst_caps_new (
"vorbis_vorbis",
"application/ogg",
NULL);
} }
static GstCaps* static GstCaps*
raw_caps_factory (void) raw_caps_factory (void)
{ {
return return
gst_caps_new ( gst_caps_new_simple ("audio/x-raw-int",
"vorbis_raw", "endianness", G_TYPE_INT, G_BYTE_ORDER,
"audio/x-raw-int", "signed", G_TYPE_BOOLEAN, TRUE,
gst_props_new ( "width", G_TYPE_INT, 16,
"endianness", GST_PROPS_INT (G_BYTE_ORDER), "depth", G_TYPE_INT, 16,
"signed", GST_PROPS_BOOLEAN (TRUE), "rate", GST_TYPE_INT_RANGE, 11025, 48000,
"width", GST_PROPS_INT (16), "channels", GST_TYPE_INT_RANGE, 1, 2,
"depth", GST_PROPS_INT (16), NULL);
"rate", GST_PROPS_INT_RANGE (11025, 48000),
"channels", GST_PROPS_INT_RANGE (1, 2),
NULL));
} }
static void static void
@ -167,10 +160,10 @@ gst_vorbisenc_base_init (gpointer g_class)
gst_vorbisenc_sink_template = gst_pad_template_new ("sink", GST_PAD_SINK, gst_vorbisenc_sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
raw_caps, NULL); raw_caps);
gst_vorbisenc_src_template = gst_pad_template_new ("src", GST_PAD_SRC, gst_vorbisenc_src_template = gst_pad_template_new ("src", GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
vorbis_caps, NULL); vorbis_caps);
gst_element_class_add_pad_template (element_class, gst_vorbisenc_sink_template); gst_element_class_add_pad_template (element_class, gst_vorbisenc_sink_template);
gst_element_class_add_pad_template (element_class, gst_vorbisenc_src_template); gst_element_class_add_pad_template (element_class, gst_vorbisenc_src_template);
gst_element_class_set_details (element_class, &vorbisenc_details); gst_element_class_set_details (element_class, &vorbisenc_details);
@ -220,17 +213,16 @@ gst_vorbisenc_class_init (VorbisEncClass * klass)
} }
static GstPadLinkReturn static GstPadLinkReturn
gst_vorbisenc_sinkconnect (GstPad * pad, GstCaps * caps) gst_vorbisenc_sinkconnect (GstPad * pad, const GstCaps * caps)
{ {
VorbisEnc *vorbisenc; VorbisEnc *vorbisenc;
GstStructure *structure;
vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad)); vorbisenc = GST_VORBISENC (gst_pad_get_parent (pad));
if (!GST_CAPS_IS_FIXED (caps)) structure = gst_caps_get_structure (caps, 0);
return GST_PAD_LINK_DELAYED; gst_structure_get_int (structure, "channels", &vorbisenc->channels);
gst_structure_get_int (structure, "rate", &vorbisenc->frequency);
gst_caps_get_int (caps, "channels", &vorbisenc->channels);
gst_caps_get_int (caps, "rate", &vorbisenc->frequency);
gst_vorbisenc_setup (vorbisenc); gst_vorbisenc_setup (vorbisenc);

View file

@ -101,8 +101,6 @@ enum
{ {
ARG_0, ARG_0,
ARG_BLOCKSIZE, ARG_BLOCKSIZE,
ARG_METADATA,
ARG_STREAMINFO
}; };
static void gst_vorbisfile_base_init (gpointer g_class); static void gst_vorbisfile_base_init (gpointer g_class);
@ -180,44 +178,32 @@ vorbisfile_get_type (void)
static GstCaps* static GstCaps*
vorbis_caps_factory (void) vorbis_caps_factory (void)
{ {
return return gst_caps_new_simple ("application/ogg", NULL);
gst_caps_new (
"vorbis_vorbis",
"application/ogg",
NULL);
} }
static GstCaps* static GstCaps*
raw_caps_factory (void) raw_caps_factory (void)
{ {
return return gst_caps_new_simple ("audio/x-raw-int",
gst_caps_new ( "endianness", G_TYPE_INT, G_BYTE_ORDER,
"vorbis_raw", "signed", G_TYPE_BOOLEAN, TRUE,
"audio/x-raw-int", "width", G_TYPE_INT, 16,
gst_props_new ( "depth", G_TYPE_INT, 16,
"endianness", GST_PROPS_INT (G_BYTE_ORDER), "rate", GST_TYPE_INT_RANGE, 11025, 48000,
"signed", GST_PROPS_BOOLEAN (TRUE), "channels", GST_TYPE_INT_RANGE, 1, 2,
"width", GST_PROPS_INT (16), NULL);
"depth", GST_PROPS_INT (16),
"rate", GST_PROPS_INT_RANGE (11025, 48000),
"channels", GST_PROPS_INT_RANGE (1, 2),
NULL));
} }
static GstCaps* static GstCaps*
raw_caps2_factory (void) raw_caps2_factory (void)
{ {
return return gst_caps_new_simple ("audio/x-raw-float",
gst_caps_new ( "width", G_TYPE_INT, 32,
"vorbis_raw_float", "endianness", G_TYPE_INT, G_BYTE_ORDER,
"audio/x-raw-float", "rate", GST_TYPE_INT_RANGE, 11025, 48000,
gst_props_new ( "channels", GST_TYPE_INT_RANGE, 1, 2,
"width", GST_PROPS_INT (32), "buffer-frames", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"endianness", GST_PROPS_INT (G_BYTE_ORDER), NULL);
"rate", GST_PROPS_INT_RANGE (11025, 48000),
"channels", GST_PROPS_INT_RANGE (1, 2),
"buffer-frames", GST_PROPS_INT_RANGE (1, G_MAXINT),
NULL));
} }
static void static void
@ -232,11 +218,11 @@ gst_vorbisfile_base_init (gpointer g_class)
gst_vorbisdec_sink_template = gst_pad_template_new ("sink", GST_PAD_SINK, gst_vorbisdec_sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
vorbis_caps, NULL); vorbis_caps);
raw_caps = gst_caps_prepend (raw_caps, raw_caps2); gst_caps_append (raw_caps2, raw_caps);
gst_vorbisdec_src_template = gst_pad_template_new ("src", GST_PAD_SRC, gst_vorbisdec_src_template = gst_pad_template_new ("src", GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
raw_caps, NULL); raw_caps2);
gst_element_class_add_pad_template (element_class, gst_vorbisdec_sink_template); gst_element_class_add_pad_template (element_class, gst_vorbisdec_sink_template);
gst_element_class_add_pad_template (element_class, gst_vorbisdec_src_template); gst_element_class_add_pad_template (element_class, gst_vorbisdec_src_template);
gst_element_class_set_details (element_class, &vorbisfile_details); gst_element_class_set_details (element_class, &vorbisfile_details);
@ -256,12 +242,6 @@ gst_vorbisfile_class_init (VorbisFileClass * klass)
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BLOCKSIZE, g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BLOCKSIZE,
g_param_spec_ulong ("blocksize", "Block size", "Size in bytes to read per buffer", g_param_spec_ulong ("blocksize", "Block size", "Size in bytes to read per buffer",
1, G_MAXULONG, DEFAULT_BLOCKSIZE, G_PARAM_READWRITE)); 1, G_MAXULONG, DEFAULT_BLOCKSIZE, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, ARG_METADATA,
g_param_spec_boxed ("metadata", "Metadata", "(logical) Stream metadata",
GST_TYPE_CAPS, G_PARAM_READABLE));
g_object_class_install_property (gobject_class, ARG_STREAMINFO,
g_param_spec_boxed ("streaminfo", "stream", "(logical) Stream information",
GST_TYPE_CAPS, G_PARAM_READABLE));
gobject_class->get_property = gst_vorbisfile_get_property; gobject_class->get_property = gst_vorbisfile_get_property;
gobject_class->set_property = gst_vorbisfile_set_property; gobject_class->set_property = gst_vorbisfile_set_property;
@ -295,7 +275,6 @@ gst_vorbisfile_init (VorbisFile * vorbisfile)
vorbisfile->offset = 0; vorbisfile->offset = 0;
vorbisfile->seek_pending = 0; vorbisfile->seek_pending = 0;
vorbisfile->need_discont = FALSE; vorbisfile->need_discont = FALSE;
vorbisfile->metadata = NULL;
vorbisfile->streaminfo = NULL; vorbisfile->streaminfo = NULL;
vorbisfile->current_link = -1; vorbisfile->current_link = -1;
vorbisfile->blocksize = DEFAULT_BLOCKSIZE; vorbisfile->blocksize = DEFAULT_BLOCKSIZE;
@ -435,6 +414,7 @@ ov_callbacks vorbisfile_ov_callbacks =
gst_vorbisfile_tell, gst_vorbisfile_tell,
}; };
#if 0
/* retrieve the comment field (or tags) and put in metadata GstCaps /* retrieve the comment field (or tags) and put in metadata GstCaps
* returns TRUE if caps could be set, * returns TRUE if caps could be set,
* FALSE if they couldn't be read somehow */ * FALSE if they couldn't be read somehow */
@ -463,7 +443,7 @@ gst_vorbisfile_update_metadata (VorbisFile *vorbisfile, gint link)
value = strstr (*ptr, "="); value = strstr (*ptr, "=");
if (value) { if (value) {
name = g_strndup (*ptr, value-*ptr); name = g_strndup (*ptr, value-*ptr);
entry = gst_props_entry_new (name, GST_PROPS_STRING_TYPE, value+1); entry = gst_props_entry_new (name, G_TYPE_STRING_TYPE, value+1);
gst_props_add_entry (props, (GstPropsEntry *) entry); gst_props_add_entry (props, (GstPropsEntry *) entry);
} }
ptr++; ptr++;
@ -498,21 +478,21 @@ gst_vorbisfile_update_streaminfo (VorbisFile *vorbisfile, gint link)
props = gst_props_empty_new (); props = gst_props_empty_new ();
vi = ov_info (vf, link); vi = ov_info (vf, link);
entry = gst_props_entry_new ("version", GST_PROPS_INT_TYPE, vi->version); entry = gst_props_entry_new ("version", G_TYPE_INT_TYPE, vi->version);
gst_props_add_entry (props, (GstPropsEntry *) entry); gst_props_add_entry (props, (GstPropsEntry *) entry);
entry = gst_props_entry_new ("bitrate_upper", GST_PROPS_INT_TYPE, entry = gst_props_entry_new ("bitrate_upper", G_TYPE_INT_TYPE,
vi->bitrate_upper); vi->bitrate_upper);
gst_props_add_entry (props, (GstPropsEntry *) entry); gst_props_add_entry (props, (GstPropsEntry *) entry);
entry = gst_props_entry_new ("bitrate_nominal", GST_PROPS_INT_TYPE, entry = gst_props_entry_new ("bitrate_nominal", G_TYPE_INT_TYPE,
vi->bitrate_nominal); vi->bitrate_nominal);
gst_props_add_entry (props, (GstPropsEntry *) entry); gst_props_add_entry (props, (GstPropsEntry *) entry);
entry = gst_props_entry_new ("bitrate_lower", GST_PROPS_INT_TYPE, entry = gst_props_entry_new ("bitrate_lower", G_TYPE_INT_TYPE,
vi->bitrate_lower); vi->bitrate_lower);
gst_props_add_entry (props, (GstPropsEntry *) entry); gst_props_add_entry (props, (GstPropsEntry *) entry);
entry = gst_props_entry_new ("serial", GST_PROPS_INT_TYPE, entry = gst_props_entry_new ("serial", G_TYPE_INT_TYPE,
ov_serialnumber (vf, link)); ov_serialnumber (vf, link));
gst_props_add_entry (props, (GstPropsEntry *) entry); gst_props_add_entry (props, (GstPropsEntry *) entry);
entry = gst_props_entry_new ("bitrate", GST_PROPS_INT_TYPE, entry = gst_props_entry_new ("bitrate", G_TYPE_INT_TYPE,
ov_bitrate (vf, link)); ov_bitrate (vf, link));
gst_props_add_entry (props, (GstPropsEntry *) entry); gst_props_add_entry (props, (GstPropsEntry *) entry);
@ -524,6 +504,7 @@ gst_vorbisfile_update_streaminfo (VorbisFile *vorbisfile, gint link)
return TRUE; return TRUE;
} }
#endif
static gboolean static gboolean
gst_vorbisfile_new_link (VorbisFile *vorbisfile, gint link) gst_vorbisfile_new_link (VorbisFile *vorbisfile, gint link)
@ -535,25 +516,19 @@ gst_vorbisfile_new_link (VorbisFile *vorbisfile, gint link)
/* new logical bitstream */ /* new logical bitstream */
vorbisfile->current_link = link; vorbisfile->current_link = link;
gst_vorbisfile_update_metadata (vorbisfile, link); caps = gst_caps_new_simple ("audio/x-raw-int",
gst_vorbisfile_update_streaminfo (vorbisfile, link); "endianness", G_TYPE_INT, G_BYTE_ORDER,
"signed", G_TYPE_BOOLEAN, TRUE,
caps = GST_CAPS_NEW ("vorbisdec_src", "width", G_TYPE_INT, 16,
"audio/x-raw-int", "depth", G_TYPE_INT, 16,
"endianness", GST_PROPS_INT (G_BYTE_ORDER), "rate", G_TYPE_INT, vi->rate,
"signed", GST_PROPS_BOOLEAN (TRUE), "channels", G_TYPE_INT, vi->channels,
"width", GST_PROPS_INT (16), NULL);
"depth", GST_PROPS_INT (16),
"rate", GST_PROPS_INT (vi->rate),
"channels", GST_PROPS_INT (vi->channels));
gst_caps_ref (caps);
if (gst_pad_try_set_caps (vorbisfile->srcpad, caps) <= 0) { if (gst_pad_try_set_caps (vorbisfile->srcpad, caps) <= 0) {
if (!gst_pad_recover_caps_error (vorbisfile->srcpad, caps)) res = FALSE;
res = FALSE;
} }
gst_caps_free (caps);
gst_caps_unref (caps);
return res; return res;
} }
@ -1156,12 +1131,6 @@ gst_vorbisfile_get_property (GObject *object, guint prop_id,
case ARG_BLOCKSIZE: case ARG_BLOCKSIZE:
g_value_set_ulong (value, vorbisfile->blocksize); g_value_set_ulong (value, vorbisfile->blocksize);
break; break;
case ARG_METADATA:
g_value_set_boxed (value, vorbisfile->metadata);
break;
case ARG_STREAMINFO:
g_value_set_boxed (value, vorbisfile->streaminfo);
break;
default: default:
g_warning ("Unknown property id\n"); g_warning ("Unknown property id\n");
} }

View file

@ -1,12 +1,21 @@
librarydir = $(libdir)/gstreamer-@GST_MAJORMINOR@ librarydir = $(libdir)/gstreamer-@GST_MAJORMINOR@
library_LTLIBRARIES = libgstaudio.la library_LTLIBRARIES = libgstaudio.la libgstaudiofilter.la libgstaudiofilterexample.la
libgstaudio_la_SOURCES = audio.c audioclock.c libgstaudio_la_SOURCES = audio.c audioclock.c
libgstaudioincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/audio libgstaudioincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/audio
libgstaudioinclude_HEADERS = audio.h audioclock.h libgstaudioinclude_HEADERS = audio.h audioclock.h gstaudiofilter.h
libgstaudio_la_LIBADD = libgstaudio_la_LIBADD =
libgstaudio_la_CFLAGS = $(GST_CFLAGS) libgstaudio_la_CFLAGS = $(GST_CFLAGS)
libgstaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstaudiofilter_la_SOURCES = gstaudiofilter.c gstaudiofilter.h
libgstaudiofilter_la_CFLAGS = $(GST_CFLAGS)
libgstaudiofilter_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstaudiofilterexample_la_SOURCES = gstaudiofilterexample.c
libgstaudiofilterexample_la_CFLAGS = $(GST_CFLAGS)
libgstaudiofilterexample_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)

View file

@ -35,22 +35,23 @@ gst_audio_frame_byte_size (GstPad* pad)
int width = 0; int width = 0;
int channels = 0; int channels = 0;
GstCaps *caps;
GstCaps *caps = NULL; GstStructure *structure;
/* get caps of pad */ /* get caps of pad */
caps = GST_PAD_CAPS (pad); caps = GST_PAD_CAPS (pad);
if (caps == NULL) if (caps == NULL) {
{
/* ERROR: could not get caps of pad */ /* ERROR: could not get caps of pad */
g_warning ("gstaudio: could not get caps of pad %s:%s\n", g_warning ("gstaudio: could not get caps of pad %s:%s\n",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad)); GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
return 0; return 0;
} }
gst_caps_get_int (caps, "width", &width); structure = gst_caps_get_structure (caps, 0);
gst_caps_get_int (caps, "channels", &channels);
gst_structure_get_int (structure, "width", &width);
gst_structure_get_int (structure, "channels", &channels);
return (width / 8) * channels; return (width / 8) * channels;
} }
@ -83,6 +84,7 @@ gst_audio_frame_rate (GstPad *pad)
{ {
GstCaps *caps = NULL; GstCaps *caps = NULL;
gint rate; gint rate;
GstStructure *structure;
/* get caps of pad */ /* get caps of pad */
caps = GST_PAD_CAPS (pad); caps = GST_PAD_CAPS (pad);
@ -94,7 +96,8 @@ gst_audio_frame_rate (GstPad *pad)
return 0; return 0;
} }
else { else {
gst_caps_get_int (caps, "rate", &rate); structure = gst_caps_get_structure (caps, 0);
gst_structure_get_int (structure, "rate", &rate);
return rate; return rate;
} }
} }
@ -115,6 +118,7 @@ gst_audio_length (GstPad* pad, GstBuffer* buf)
double length; double length;
GstCaps *caps = NULL; GstCaps *caps = NULL;
GstStructure *structure;
g_assert (GST_IS_BUFFER (buf)); g_assert (GST_IS_BUFFER (buf));
/* get caps of pad */ /* get caps of pad */
@ -128,10 +132,11 @@ gst_audio_length (GstPad* pad, GstBuffer* buf)
} }
else else
{ {
structure = gst_caps_get_structure (caps, 0);
bytes = GST_BUFFER_SIZE (buf); bytes = GST_BUFFER_SIZE (buf);
gst_caps_get_int (caps, "width", &width); gst_structure_get_int (structure, "width", &width);
gst_caps_get_int (caps, "channels", &channels); gst_structure_get_int (structure, "channels", &channels);
gst_caps_get_int (caps, "rate", &rate); gst_structure_get_int (structure, "rate", &rate);
g_assert (bytes != 0); g_assert (bytes != 0);
g_assert (width != 0); g_assert (width != 0);
@ -152,6 +157,7 @@ gst_audio_highest_sample_value (GstPad* pad)
gboolean is_signed = FALSE; gboolean is_signed = FALSE;
gint width = 0; gint width = 0;
GstCaps *caps = NULL; GstCaps *caps = NULL;
GstStructure *structure;
caps = GST_PAD_CAPS (pad); caps = GST_PAD_CAPS (pad);
if (caps == NULL) if (caps == NULL)
@ -160,8 +166,9 @@ gst_audio_highest_sample_value (GstPad* pad)
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad)); GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_PAD_NAME (pad));
} }
gst_caps_get_int (caps, "width", &width); structure = gst_caps_get_structure (caps, 0);
gst_caps_get_boolean (caps, "signed", &is_signed); gst_structure_get_int (structure, "width", &width);
gst_structure_get_boolean (structure, "signed", &is_signed);
if (is_signed) --width; if (is_signed) --width;
/* example : 16 bit, signed : samples between -32768 and 32767 */ /* example : 16 bit, signed : samples between -32768 and 32767 */

View file

@ -50,66 +50,43 @@ G_BEGIN_DECLS
#define GST_AUDIO_DEF_RATE 44100 #define GST_AUDIO_DEF_RATE 44100
#define GST_AUDIO_INT_PAD_TEMPLATE_PROPS \ #define GST_AUDIO_INT_PAD_TEMPLATE_CAPS \
gst_props_new (\ "audio/x-raw-int, " \
"rate", GST_PROPS_INT_RANGE (1, G_MAXINT),\ "rate = (int) [ 1, MAX ], " \
"channels", GST_PROPS_INT_RANGE (1, G_MAXINT),\ "channels = (int) [ 1, MAX ], " \
"endianness", GST_PROPS_LIST (\ "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
GST_PROPS_INT (G_LITTLE_ENDIAN),\ "width = (int) { 8, 16, 32 }, " \
GST_PROPS_INT (G_BIG_ENDIAN)\ "depth = (int) [ 1, 32 ], " \
),\ "signed = (boolean) { true, false }, " \
"width", GST_PROPS_LIST (\ "buffer-frames = (int) [ 1, MAX ]"
GST_PROPS_INT (8),\
GST_PROPS_INT (16),\
GST_PROPS_INT (32)\
),\
"depth", GST_PROPS_INT_RANGE (1, 32),\
"signed", GST_PROPS_LIST (\
GST_PROPS_BOOLEAN (TRUE),\
GST_PROPS_BOOLEAN (FALSE)\
),\
"buffer-frames", GST_PROPS_INT_RANGE (1, G_MAXINT),\
NULL)
/* "standard" int audio is native order, 16 bit stereo. */ /* "standard" int audio is native order, 16 bit stereo. */
#define GST_AUDIO_INT_STANDARD_PAD_TEMPLATE_PROPS \ #define GST_AUDIO_INT_STANDARD_PAD_TEMPLATE_CAPS \
gst_props_new (\ "audio/x-raw-int, " \
"rate", GST_PROPS_INT_RANGE (1, G_MAXINT),\ "rate = (int) [ 1, MAX ], " \
"channels", GST_PROPS_INT (2),\ "channels = (int) 2, " \
"endianness", GST_PROPS_INT (G_BYTE_ORDER),\ "endianness = (int) BYTE_ORDER, " \
"width", GST_PROPS_INT (16),\ "width = (int) 16, " \
"depth", GST_PROPS_INT (16),\ "depth = (int) 16, " \
"signed", GST_PROPS_LIST (\ "signed = (boolean) true, " \
GST_PROPS_BOOLEAN (TRUE),\ "buffer-frames = (int) [ 1, MAX]"
GST_PROPS_BOOLEAN (FALSE)\
),\
"buffer-frames", GST_PROPS_INT_RANGE (1, G_MAXINT),\
NULL)
#define GST_AUDIO_FLOAT_PAD_TEMPLATE_PROPS \ #define GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS \
gst_props_new (\ "audio/x-raw-float, " \
"rate", GST_PROPS_INT_RANGE (1, G_MAXINT),\ "rate = (int) [ 1, MAX ], " \
"channels", GST_PROPS_INT_RANGE (1, G_MAXINT),\ "channels = (int) [ 1, MAX ], " \
"endianness", GST_PROPS_LIST (\ "endianness = (int) { LITTLE_ENDIAN , BIG_ENDIAN }, " \
GST_PROPS_INT (G_LITTLE_ENDIAN),\ "width = (int) { 32, 64 }, " \
GST_PROPS_INT (G_BIG_ENDIAN)\ "buffer-frames = (int) [ 1, MAX]"
),\
"width", GST_PROPS_LIST (\
GST_PROPS_INT (32),\
GST_PROPS_INT (64)\
),\
"buffer-frames", GST_PROPS_INT_RANGE (1, G_MAXINT),\
NULL)
/* "standard" float audio is native order, 32 bit mono. */ /* "standard" float audio is native order, 32 bit mono. */
#define GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_PROPS \ #define GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS \
gst_props_new (\ "audio/x-raw-float, " \
"rate", GST_PROPS_INT_RANGE (1, G_MAXINT),\ "rate = (int) [ 1, MAX ], " \
"channels", GST_PROPS_INT (1),\ "channels = (int) 1, " \
"endianness", GST_PROPS_INT (G_BYTE_ORDER),\ "endianness = (int) BYTE_ORDER, " \
"width", GST_PROPS_INT (32),\ "buffer-frames = (int) [ 1, MAX]"
"buffer-frames", GST_PROPS_INT_RANGE (1, G_MAXINT),\
NULL)
/* /*
* this library defines and implements some helper functions for audio * this library defines and implements some helper functions for audio

View file

@ -0,0 +1,322 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) <2003> David Schleef <ds@schleef.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/*#define DEBUG_ENABLED */
#include <gstaudiofilter.h>
#include <string.h>
/* GstAudiofilter signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_METHOD,
/* FILL ME */
};
static void gst_audiofilter_base_init (gpointer g_class);
static void gst_audiofilter_class_init (gpointer g_class, gpointer class_data);
static void gst_audiofilter_init (GTypeInstance *instance, gpointer g_class);
static void gst_audiofilter_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_audiofilter_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_audiofilter_chain (GstPad *pad, GstData *_data);
GstCaps * gst_audiofilter_class_get_capslist(GstAudiofilterClass *klass);
static GstElementClass *parent_class = NULL;
GType
gst_audiofilter_get_type (void)
{
static GType audiofilter_type = 0;
if (!audiofilter_type) {
static const GTypeInfo audiofilter_info = {
sizeof(GstAudiofilterClass),
gst_audiofilter_base_init,
NULL,
gst_audiofilter_class_init,
NULL,
NULL,
sizeof(GstAudiofilter),
0,
gst_audiofilter_init,
};
audiofilter_type = g_type_register_static(GST_TYPE_ELEMENT,
"GstAudiofilter", &audiofilter_info, G_TYPE_FLAG_ABSTRACT);
}
return audiofilter_type;
}
static void gst_audiofilter_base_init (gpointer g_class)
{
static GstElementDetails audiofilter_details = {
"Audio filter base class",
"Filter/Effect/Audio",
"Filters audio",
"David Schleef <ds@schleef.org>"
};
GstAudiofilterClass *klass = (GstAudiofilterClass *) g_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_set_details (element_class, &audiofilter_details);
}
static void gst_audiofilter_class_init (gpointer g_class, gpointer class_data)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstAudiofilterClass *klass;
klass = (GstAudiofilterClass *)g_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
gobject_class->set_property = gst_audiofilter_set_property;
gobject_class->get_property = gst_audiofilter_get_property;
}
static GstCaps *
gst_audiofilter_getcaps (GstPad *pad)
{
GstAudiofilter *audiofilter;
GstCaps *othercaps;
GstAudiofilterClass *audiofilter_class;
GST_DEBUG("gst_audiofilter_sink_getcaps");
audiofilter = GST_AUDIOFILTER (gst_pad_get_parent (pad));
audiofilter_class = GST_AUDIOFILTER_CLASS (
G_OBJECT_GET_CLASS (audiofilter));
if (pad == audiofilter->srcpad) {
othercaps = gst_pad_get_allowed_caps (audiofilter->sinkpad);
} else {
othercaps = gst_pad_get_allowed_caps (audiofilter->srcpad);
}
return gst_caps_intersect (othercaps, audiofilter_class->caps);
}
static GstPadLinkReturn
gst_audiofilter_link (GstPad *pad, const GstCaps *caps)
{
GstAudiofilter *audiofilter;
GstPadLinkReturn ret;
GstPadLinkReturn link_ret;
GstStructure *structure;
GstAudiofilterClass *audiofilter_class;
GST_DEBUG("gst_audiofilter_link");
audiofilter = GST_AUDIOFILTER (gst_pad_get_parent (pad));
audiofilter_class = GST_AUDIOFILTER_CLASS (
G_OBJECT_GET_CLASS (audiofilter));
if (pad == audiofilter->srcpad) {
link_ret = gst_pad_try_set_caps (audiofilter->sinkpad, caps);
} else {
link_ret = gst_pad_try_set_caps (audiofilter->srcpad, caps);
}
if (link_ret != GST_PAD_LINK_OK) return link_ret;
structure = gst_caps_get_structure (caps, 0);
if (strcmp (gst_structure_get_name (structure), "audio/x-raw-int") == 0) {
ret = gst_structure_get_int (structure, "depth", &audiofilter->depth);
ret &= gst_structure_get_int (structure, "width", &audiofilter->width);
ret &= gst_structure_get_int (structure, "channels", &audiofilter->channels);
} else if (strcmp (gst_structure_get_name (structure), "audio/x-raw-float")
== 0) {
} else {
g_assert_not_reached();
}
ret &= gst_structure_get_int (structure, "rate", &audiofilter->rate);
if (audiofilter_class->setup) (audiofilter_class->setup) (audiofilter);
return GST_PAD_LINK_OK;
}
static void
gst_audiofilter_init (GTypeInstance *instance, gpointer g_class)
{
GstAudiofilter *audiofilter = GST_AUDIOFILTER (instance);
GstPadTemplate *pad_template;
GST_DEBUG("gst_audiofilter_init");
pad_template = gst_element_class_get_pad_template(GST_ELEMENT_CLASS(g_class),
"sink");
g_return_if_fail(pad_template != NULL);
audiofilter->sinkpad = gst_pad_new_from_template(pad_template, "sink");
gst_element_add_pad(GST_ELEMENT(audiofilter),audiofilter->sinkpad);
gst_pad_set_chain_function(audiofilter->sinkpad,gst_audiofilter_chain);
gst_pad_set_link_function(audiofilter->sinkpad,gst_audiofilter_link);
gst_pad_set_getcaps_function(audiofilter->sinkpad,gst_audiofilter_getcaps);
pad_template = gst_element_class_get_pad_template(GST_ELEMENT_CLASS(g_class),
"src");
g_return_if_fail(pad_template != NULL);
audiofilter->srcpad = gst_pad_new_from_template(pad_template, "src");
gst_element_add_pad(GST_ELEMENT(audiofilter),audiofilter->srcpad);
gst_pad_set_link_function(audiofilter->srcpad,gst_audiofilter_link);
gst_pad_set_getcaps_function(audiofilter->srcpad,gst_audiofilter_getcaps);
audiofilter->inited = FALSE;
}
static void
gst_audiofilter_chain (GstPad *pad, GstData *data)
{
GstBuffer *inbuf = GST_BUFFER (data);
GstAudiofilter *audiofilter;
GstBuffer *outbuf;
GstAudiofilterClass *audiofilter_class;
GST_DEBUG ("gst_audiofilter_chain");
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (inbuf != NULL);
audiofilter = GST_AUDIOFILTER (gst_pad_get_parent (pad));
//g_return_if_fail (audiofilter->inited);
audiofilter_class = GST_AUDIOFILTER_CLASS (
G_OBJECT_GET_CLASS (audiofilter));
GST_DEBUG ("gst_audiofilter_chain: got buffer of %d bytes in '%s'",
GST_BUFFER_SIZE(inbuf), GST_OBJECT_NAME (audiofilter));
if(audiofilter->passthru){
gst_pad_push(audiofilter->srcpad, data);
return;
}
if (gst_data_is_writable(data)) {
if (audiofilter_class->filter_inplace) {
(audiofilter_class->filter_inplace) (audiofilter, inbuf);
outbuf = inbuf;
} else {
outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE(inbuf));
GST_BUFFER_DURATION(outbuf) = GST_BUFFER_DURATION(inbuf);
GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(inbuf);
(audiofilter_class->filter) (audiofilter, outbuf, inbuf);
gst_buffer_unref(inbuf);
}
} else {
outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE(inbuf));
GST_BUFFER_DURATION(outbuf) = GST_BUFFER_DURATION(inbuf);
GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(inbuf);
if (audiofilter_class->filter) {
(audiofilter_class->filter) (audiofilter, outbuf, inbuf);
} else {
memcpy(GST_BUFFER_DATA(outbuf), GST_BUFFER_DATA(inbuf),
GST_BUFFER_SIZE(inbuf));
(audiofilter_class->filter_inplace) (audiofilter, outbuf);
}
gst_buffer_unref(inbuf);
}
gst_pad_push(audiofilter->srcpad, GST_DATA (outbuf));
}
static void
gst_audiofilter_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
GstAudiofilter *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_AUDIOFILTER(object));
src = GST_AUDIOFILTER(object);
GST_DEBUG("gst_audiofilter_set_property");
switch (prop_id) {
default:
break;
}
}
static void
gst_audiofilter_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
GstAudiofilter *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_AUDIOFILTER(object));
src = GST_AUDIOFILTER(object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
void gst_audiofilter_class_add_pad_templates (
GstAudiofilterClass *audiofilter_class, const GstCaps *caps)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (audiofilter_class);
audiofilter_class->caps = gst_caps_copy(caps);
gst_element_class_add_pad_template (element_class,
gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS,
gst_caps_copy(caps)));
gst_element_class_add_pad_template (element_class,
gst_pad_template_new("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
gst_caps_copy(caps)));
}
static gboolean
plugin_init (GstPlugin *plugin)
{
return TRUE;
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstaudiofilter",
"Audio filter parent class",
plugin_init,
VERSION,
"LGPL",
GST_PACKAGE,
GST_ORIGIN
)

View file

@ -0,0 +1,84 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_AUDIOFILTER_H__
#define __GST_AUDIOFILTER_H__
#include <gst/gst.h>
G_BEGIN_DECLS
typedef struct _GstAudiofilter GstAudiofilter;
typedef struct _GstAudiofilterClass GstAudiofilterClass;
typedef void (*GstAudiofilterFilterFunc)(GstAudiofilter *filter,
GstBuffer *outbuf, GstBuffer *inbuf);
typedef void (*GstAudiofilterInplaceFilterFunc)(GstAudiofilter *filter,
GstBuffer *buffer);
typedef void (*GstAudiofilterSetupFunc) (GstAudiofilter *filter);
#define GST_TYPE_AUDIOFILTER \
(gst_audiofilter_get_type())
#define GST_AUDIOFILTER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIOFILTER,GstAudiofilter))
#define GST_AUDIOFILTER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOFILTER,GstAudiofilterClass))
#define GST_IS_AUDIOFILTER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIOFILTER))
#define GST_IS_AUDIOFILTER_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOFILTER))
struct _GstAudiofilter {
GstElement element;
GstPad *sinkpad,*srcpad;
/* audio state */
gboolean inited;
int rate;
int width;
int channels;
int depth;
gboolean passthru;
};
struct _GstAudiofilterClass {
GstElementClass parent_class;
GstCaps *caps;
GstAudiofilterSetupFunc setup;
GstAudiofilterInplaceFilterFunc filter_inplace;
GstAudiofilterFilterFunc filter;
};
GType gst_audiofilter_get_type(void);
void gst_audiofilter_class_add_pad_templates (GstAudiofilterClass *audiofilterclass, const GstCaps *caps);
G_END_DECLS
#endif /* __GST_AUDIOFILTER_H__ */

View file

@ -0,0 +1,170 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) <2003> David Schleef <ds@schleef.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/audio/gstaudiofilter.h>
typedef struct _GstAudiofilterExample GstAudiofilterExample;
typedef struct _GstAudiofilterExampleClass GstAudiofilterExampleClass;
#define GST_TYPE_AUDIOFILTER_EXAMPLE \
(gst_audiofilter_example_get_type())
#define GST_AUDIOFILTER_EXAMPLE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIOFILTER_EXAMPLE,GstAudiofilterExample))
#define GST_AUDIOFILTER_EXAMPLE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOFILTER_EXAMPLE,GstAudiofilterExampleClass))
#define GST_IS_AUDIOFILTER_EXAMPLE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIOFILTER_EXAMPLE))
#define GST_IS_AUDIOFILTER_EXAMPLE_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOFILTER_EXAMPLE))
struct _GstAudiofilterExample {
GstAudiofilter audiofilter;
};
struct _GstAudiofilterExampleClass {
GstAudiofilterClass parent_class;
};
/* GstAudiofilterExample signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_METHOD,
/* FILL ME */
};
static void gst_audiofilter_example_base_init (gpointer g_class);
static void gst_audiofilter_example_class_init (gpointer g_class, gpointer class_data);
static void gst_audiofilter_example_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_audiofilter_example_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
GType
gst_audiofilter_example_get_type (void)
{
static GType audiofilter_example_type = 0;
if (!audiofilter_example_type) {
static const GTypeInfo audiofilter_example_info = {
sizeof(GstAudiofilterExampleClass),
gst_audiofilter_example_base_init,
NULL,
gst_audiofilter_example_class_init,
NULL,
NULL,
sizeof(GstAudiofilterExample),
0,
NULL,
};
audiofilter_example_type = g_type_register_static(GST_TYPE_AUDIOFILTER,
"GstAudiofilterExample", &audiofilter_example_info, 0);
}
return audiofilter_example_type;
}
static void gst_audiofilter_example_base_init (gpointer g_class)
{
static GstElementDetails audiofilter_example_details = {
"Audio filter example",
"Filter/Effect/Audio",
"Filters audio",
"David Schleef <ds@schleef.org>"
};
GstAudiofilterExampleClass *klass = (GstAudiofilterExampleClass *) g_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_set_details (element_class, &audiofilter_example_details);
}
static void gst_audiofilter_example_class_init (gpointer g_class, gpointer class_data)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstAudiofilterExampleClass *klass;
klass = (GstAudiofilterExampleClass *)g_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
gobject_class->set_property = gst_audiofilter_example_set_property;
gobject_class->get_property = gst_audiofilter_example_get_property;
}
static void
gst_audiofilter_example_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
GstAudiofilterExample *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_AUDIOFILTER_EXAMPLE(object));
src = GST_AUDIOFILTER_EXAMPLE(object);
GST_DEBUG("gst_audiofilter_example_set_property");
switch (prop_id) {
default:
break;
}
}
static void
gst_audiofilter_example_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
GstAudiofilterExample *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_AUDIOFILTER_EXAMPLE(object));
src = GST_AUDIOFILTER_EXAMPLE(object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
plugin_init (GstPlugin *plugin)
{
return TRUE;
}
GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstaudiofilter_example",
"Audio filter example",
plugin_init,
VERSION,
"LGPL",
GST_PACKAGE,
GST_ORIGIN
)

View file

@ -136,13 +136,13 @@ gmi_reset (GstMediaInfo *info)
if (priv->format) if (priv->format)
{ {
GMI_DEBUG ("unreffing priv->format, error before this ?\n"); GMI_DEBUG ("unreffing priv->format, error before this ?\n");
gst_caps_unref (priv->format); gst_caps_free (priv->format);
priv->format = NULL; priv->format = NULL;
} }
if (priv->metadata) if (priv->metadata)
{ {
GMI_DEBUG ("unreffing priv->metadata, error before this ?\n"); GMI_DEBUG ("unreffing priv->metadata, error before this ?\n");
gst_caps_unref (priv->metadata); gst_caps_free (priv->metadata);
priv->metadata = NULL; priv->metadata = NULL;
} }
if (priv->stream) if (priv->stream)
@ -193,12 +193,12 @@ gmi_seek_to_track (GstMediaInfo *info, long track)
/* clear structs because of the seek */ /* clear structs because of the seek */
if (priv->metadata) if (priv->metadata)
{ {
gst_caps_unref (priv->metadata); gst_caps_free (priv->metadata);
priv->metadata = NULL; priv->metadata = NULL;
} }
if (priv->streaminfo) if (priv->streaminfo)
{ {
gst_caps_unref (priv->streaminfo); gst_caps_free (priv->streaminfo);
priv->streaminfo = NULL; priv->streaminfo = NULL;
} }
return TRUE; return TRUE;
@ -304,7 +304,7 @@ gmip_find_type_pre (GstMediaInfoPriv *priv)
if (priv->type) if (priv->type)
{ {
/* we don't need to unref, this is done inside gsttypefind.c /* we don't need to unref, this is done inside gsttypefind.c
gst_caps_unref (priv->type); gst_caps_free (priv->type);
*/ */
priv->type = NULL; priv->type = NULL;
} }
@ -573,14 +573,13 @@ gmip_find_track_streaminfo_post (GstMediaInfoPriv *priv)
&format, &value_end); &format, &value_end);
if (res) if (res)
{ {
GstPropsEntry *length;
/* substract to get the length */ /* substract to get the length */
GMI_DEBUG("DEBUG: start %lld, end %lld\n", value_start, value_end); GMI_DEBUG("DEBUG: start %lld, end %lld\n", value_start, value_end);
value_end -= value_start; value_end -= value_start;
/* FIXME: check units; this is in seconds */ /* FIXME: check units; this is in seconds */
length = gst_props_entry_new ("length",
GST_PROPS_INT ((int) (value_end / 1E6))); gst_caps_set_simple (priv->streaminfo,
gst_props_add_entry (gst_caps_get_props (priv->streaminfo), length); "length", G_TYPE_INT, (int) (value_end / 1E6), NULL);
} }
} }
} }

View file

@ -4,56 +4,6 @@
#include <string.h> #include <string.h>
#include "media-info.h" #include "media-info.h"
static void
caps_print (GstCaps *caps)
{
if (caps == NULL) return;
/*
if (!strcmp (gst_caps_get_mime (caps), "application/x-gst-metadata") ||
!strcmp (gst_caps_get_mime (caps), "application/x-gst-streaminfo"))
*/
if (TRUE)
{
GstProps *props = caps->properties;
GList *walk;
if (props == NULL)
{
g_print (" none\n");
return;
}
walk = props->properties;
while (walk) {
GstPropsEntry *entry = (GstPropsEntry *) walk->data;
const gchar *name;
const gchar *str_val;
gint int_val;
GstPropsType type;
name = gst_props_entry_get_name (entry);
type = gst_props_entry_get_props_type (entry);
switch (type) {
case GST_PROPS_STRING_TYPE:
gst_props_entry_get_string (entry, &str_val);
g_print (" %s='%s'\n", name, str_val);
break;
case GST_PROPS_INT_TYPE:
gst_props_entry_get_int (entry, &int_val);
g_print (" %s=%d\n", name, int_val);
break;
default:
break;
}
walk = g_list_next (walk);
}
}
else {
g_print (" unkown caps type\n");
}
}
static void static void
info_print (GstMediaInfoStream *stream) info_print (GstMediaInfoStream *stream)
{ {
@ -77,11 +27,11 @@ info_print (GstMediaInfoStream *stream)
g_print ("- track %d\n", i); g_print ("- track %d\n", i);
track = (GstMediaInfoTrack *) p->data; track = (GstMediaInfoTrack *) p->data;
g_print (" - metadata:\n"); g_print (" - metadata:\n");
caps_print (track->metadata); g_print ("%s\n", gst_caps_to_string (track->metadata));
g_print (" - streaminfo:\n"); g_print (" - streaminfo:\n");
caps_print (track->streaminfo); g_print ("%s\n", gst_caps_to_string (track->streaminfo));
g_print (" - format:\n"); g_print (" - format:\n");
caps_print (track->format); g_print ("%s\n", gst_caps_to_string (track->format));
p = p->next; p = p->next;
} }
} }

View file

@ -294,7 +294,8 @@ gst_media_info_read_idler (GstMediaInfo *info, GstMediaInfoStream **streamp)
GMI_DEBUG("doing find_type_post\n"); GMI_DEBUG("doing find_type_post\n");
gmip_find_type_post (priv); gmip_find_type_post (priv);
GMI_DEBUG("finding out mime type\n"); GMI_DEBUG("finding out mime type\n");
mime = g_strdup (gst_caps_get_mime (priv->type)); mime = g_strdup (gst_structure_get_name (
gst_caps_get_structure(priv->type, 0)));
GMI_DEBUG("found out mime type: %s\n", mime); GMI_DEBUG("found out mime type: %s\n", mime);
decoder = gmi_get_decoder (info, mime); decoder = gmi_get_decoder (info, mime);
if (decoder == NULL) if (decoder == NULL)
@ -443,7 +444,8 @@ gst_media_info_read (GstMediaInfo *info, const char *location, guint16 flags)
if (!gmip_find_type (priv)) return NULL; if (!gmip_find_type (priv)) return NULL;
mime = g_strdup (gst_caps_get_mime (priv->type)); mime = g_strdup (gst_structure_get_name (
gst_caps_get_structure(priv->type, 0)));
GMI_DEBUG("mime type: %s\n", mime); GMI_DEBUG("mime type: %s\n", mime);
/* c) figure out decoder */ /* c) figure out decoder */

View file

@ -20,6 +20,7 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
#include <string.h>
#include "gstplay.h" #include "gstplay.h"
@ -919,40 +920,41 @@ gst_play_get_sink_element (GstPlay *play,
} }
else { else {
/* If not a src pad checking caps */ /* If not a src pad checking caps */
GstCaps *caps; const GstCaps *caps;
caps = gst_pad_get_caps (GST_PAD (pads->data)); GstStructure *structure;
while (caps) { gboolean has_video_cap = FALSE;
gboolean has_video_cap = FALSE, has_audio_cap = FALSE; gboolean has_audio_cap = FALSE;
if (g_ascii_strcasecmp (gst_caps_get_mime (caps),
"audio/x-raw-int") == 0) {
has_audio_cap = TRUE;
}
if ((g_ascii_strcasecmp (gst_caps_get_mime (caps),
"video/x-raw-yuv") == 0) ||
(g_ascii_strcasecmp (gst_caps_get_mime (caps),
"video/x-raw-rgb") == 0)) {
has_video_cap = TRUE;
}
switch (sink_type) { caps = gst_pad_get_caps (GST_PAD (pads->data));
case GST_PLAY_SINK_TYPE_AUDIO: structure = gst_caps_get_structure (caps, 0);
if (has_audio_cap)
has_correct_type = TRUE; if (strcmp (gst_structure_get_name (structure),
break;; "audio/x-raw-int") == 0) {
case GST_PLAY_SINK_TYPE_VIDEO: has_audio_cap = TRUE;
if (has_video_cap) }
has_correct_type = TRUE;
break;; if (strcmp (gst_structure_get_name (structure),
case GST_PLAY_SINK_TYPE_ANY: "video/x-raw-yuv") == 0 ||
if ((has_video_cap) || (has_audio_cap)) strcmp (gst_structure_get_name (structure),
has_correct_type = TRUE; "video/x-raw-rgb") == 0) {
break;; has_video_cap = TRUE;
default: }
has_correct_type = FALSE;
} switch (sink_type) {
case GST_PLAY_SINK_TYPE_AUDIO:
caps = caps->next; if (has_audio_cap)
has_correct_type = TRUE;
break;;
case GST_PLAY_SINK_TYPE_VIDEO:
if (has_video_cap)
has_correct_type = TRUE;
break;;
case GST_PLAY_SINK_TYPE_ANY:
if ((has_video_cap) || (has_audio_cap))
has_correct_type = TRUE;
break;;
default:
has_correct_type = FALSE;
} }
} }

View file

@ -20,6 +20,7 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
#include <string.h>
#include "gstplay.h" #include "gstplay.h"
@ -919,40 +920,41 @@ gst_play_get_sink_element (GstPlay *play,
} }
else { else {
/* If not a src pad checking caps */ /* If not a src pad checking caps */
GstCaps *caps; const GstCaps *caps;
caps = gst_pad_get_caps (GST_PAD (pads->data)); GstStructure *structure;
while (caps) { gboolean has_video_cap = FALSE;
gboolean has_video_cap = FALSE, has_audio_cap = FALSE; gboolean has_audio_cap = FALSE;
if (g_ascii_strcasecmp (gst_caps_get_mime (caps),
"audio/x-raw-int") == 0) {
has_audio_cap = TRUE;
}
if ((g_ascii_strcasecmp (gst_caps_get_mime (caps),
"video/x-raw-yuv") == 0) ||
(g_ascii_strcasecmp (gst_caps_get_mime (caps),
"video/x-raw-rgb") == 0)) {
has_video_cap = TRUE;
}
switch (sink_type) { caps = gst_pad_get_caps (GST_PAD (pads->data));
case GST_PLAY_SINK_TYPE_AUDIO: structure = gst_caps_get_structure (caps, 0);
if (has_audio_cap)
has_correct_type = TRUE; if (strcmp (gst_structure_get_name (structure),
break;; "audio/x-raw-int") == 0) {
case GST_PLAY_SINK_TYPE_VIDEO: has_audio_cap = TRUE;
if (has_video_cap) }
has_correct_type = TRUE;
break;; if (strcmp (gst_structure_get_name (structure),
case GST_PLAY_SINK_TYPE_ANY: "video/x-raw-yuv") == 0 ||
if ((has_video_cap) || (has_audio_cap)) strcmp (gst_structure_get_name (structure),
has_correct_type = TRUE; "video/x-raw-rgb") == 0) {
break;; has_video_cap = TRUE;
default: }
has_correct_type = FALSE;
} switch (sink_type) {
case GST_PLAY_SINK_TYPE_AUDIO:
caps = caps->next; if (has_audio_cap)
has_correct_type = TRUE;
break;;
case GST_PLAY_SINK_TYPE_VIDEO:
if (has_video_cap)
has_correct_type = TRUE;
break;;
case GST_PLAY_SINK_TYPE_ANY:
if ((has_video_cap) || (has_audio_cap))
has_correct_type = TRUE;
break;;
default:
has_correct_type = FALSE;
} }
} }

View file

@ -26,6 +26,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include <string.h>
#include "play.h" #include "play.h"
enum enum
@ -906,43 +907,38 @@ gst_play_get_sink_element (GstPlay * play,
else else
{ {
/* If not a src pad checking caps */ /* If not a src pad checking caps */
GstCaps *caps; gboolean has_video_cap = FALSE, has_audio_cap = FALSE;
caps = gst_pad_get_caps (GST_PAD (pads->data)); const char *media_type;
while (caps)
{
gboolean has_video_cap = FALSE, has_audio_cap = FALSE;
if (g_ascii_strcasecmp (gst_caps_get_mime (caps),
"audio/x-raw-int") == 0)
{
has_audio_cap = TRUE;
}
if ((g_ascii_strcasecmp (gst_caps_get_mime (caps),
"video/x-raw-yuv") == 0) ||
(g_ascii_strcasecmp (gst_caps_get_mime (caps),
"video/x-raw-rgb") == 0))
{
has_video_cap = TRUE;
}
switch (sink_type) media_type = gst_structure_get_name (gst_caps_get_structure (
{ gst_pad_get_caps (GST_PAD (pads->data)), 0));
case GST_PLAY_SINK_TYPE_AUDIO: if (strcmp (media_type, "audio/x-raw-int") == 0)
if (has_audio_cap) {
has_correct_type = TRUE; has_audio_cap = TRUE;
break;; }
case GST_PLAY_SINK_TYPE_VIDEO: if ((strcmp (media_type, "video/x-raw-yuv") == 0) ||
if (has_video_cap) (strcmp (media_type, "video/x-raw-rgb") == 0))
has_correct_type = TRUE;
break;; {
case GST_PLAY_SINK_TYPE_ANY: has_video_cap = TRUE;
if ((has_video_cap) || (has_audio_cap)) }
has_correct_type = TRUE;
break;; switch (sink_type)
default: {
has_correct_type = FALSE; case GST_PLAY_SINK_TYPE_AUDIO:
} if (has_audio_cap)
caps = caps->next; has_correct_type = TRUE;
break;;
case GST_PLAY_SINK_TYPE_VIDEO:
if (has_video_cap)
has_correct_type = TRUE;
break;;
case GST_PLAY_SINK_TYPE_ANY:
if ((has_video_cap) || (has_audio_cap))
has_correct_type = TRUE;
break;;
default:
has_correct_type = FALSE;
} }
} }
pads = g_list_next (pads); pads = g_list_next (pads);

View file

@ -36,40 +36,28 @@ gst_riff_create_video_caps (guint32 codec_fcc,
switch (codec_fcc) { switch (codec_fcc) {
case GST_MAKE_FOURCC('I','4','2','0'): case GST_MAKE_FOURCC('I','4','2','0'):
case GST_MAKE_FOURCC('Y','U','Y','2'): case GST_MAKE_FOURCC('Y','U','Y','2'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-raw-yuv",
"riff_video_raw", "format", GST_TYPE_FOURCC, codec_fcc,
"video/x-raw-yuv", NULL);
"format", GST_PROPS_FOURCC (codec_fcc)
);
break; break;
case GST_MAKE_FOURCC('M','J','P','G'): /* YUY2 MJPEG */ case GST_MAKE_FOURCC('M','J','P','G'): /* YUY2 MJPEG */
case GST_MAKE_FOURCC('J','P','E','G'): /* generic (mostly RGB) MJPEG */ case GST_MAKE_FOURCC('J','P','E','G'): /* generic (mostly RGB) MJPEG */
case GST_MAKE_FOURCC('P','I','X','L'): /* Miro/Pinnacle fourccs */ case GST_MAKE_FOURCC('P','I','X','L'): /* Miro/Pinnacle fourccs */
case GST_MAKE_FOURCC('V','I','X','L'): /* Miro/Pinnacle fourccs */ case GST_MAKE_FOURCC('V','I','X','L'): /* Miro/Pinnacle fourccs */
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-jpeg", NULL);
"riff_video_jpeg",
"video/x-jpeg",
NULL
);
break; break;
case GST_MAKE_FOURCC('H','F','Y','U'): case GST_MAKE_FOURCC('H','F','Y','U'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ( "video/x-huffyuv", NULL);
"riff_video_hfyu",
"video/x-huffyuv",
NULL
);
break; break;
case GST_MAKE_FOURCC('M','P','E','G'): case GST_MAKE_FOURCC('M','P','E','G'):
case GST_MAKE_FOURCC('M','P','G','I'): case GST_MAKE_FOURCC('M','P','G','I'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/mpeg",
"riff_video_mpeg1", "systemstream", G_TYPE_BOOLEAN, FALSE,
"video/mpeg", "mpegversion", G_TYPE_BOOLEAN, 1,
"systemstream", GST_PROPS_BOOLEAN (FALSE), NULL);
"mpegversion", GST_PROPS_BOOLEAN (1)
);
break; break;
case GST_MAKE_FOURCC('H','2','6','3'): case GST_MAKE_FOURCC('H','2','6','3'):
@ -79,138 +67,98 @@ gst_riff_create_video_caps (guint32 codec_fcc,
case GST_MAKE_FOURCC('V','D','O','W'): case GST_MAKE_FOURCC('V','D','O','W'):
case GST_MAKE_FOURCC('V','I','V','O'): case GST_MAKE_FOURCC('V','I','V','O'):
case GST_MAKE_FOURCC('x','2','6','3'): case GST_MAKE_FOURCC('x','2','6','3'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-h263", NULL);
"riff_video_h263",
"video/x-h263",
NULL
);
break; break;
case GST_MAKE_FOURCC('D','I','V','3'): case GST_MAKE_FOURCC('D','I','V','3'):
case GST_MAKE_FOURCC('D','I','V','4'): case GST_MAKE_FOURCC('D','I','V','4'):
case GST_MAKE_FOURCC('D','I','V','5'): case GST_MAKE_FOURCC('D','I','V','5'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-divx",
"riff_video_divx3", "divxversion", G_TYPE_INT, 3,
"video/x-divx", NULL);
"divxversion", GST_PROPS_INT(3)
);
break; break;
case GST_MAKE_FOURCC('d','i','v','x'): case GST_MAKE_FOURCC('d','i','v','x'):
case GST_MAKE_FOURCC('D','I','V','X'): case GST_MAKE_FOURCC('D','I','V','X'):
case GST_MAKE_FOURCC('D','X','5','0'): case GST_MAKE_FOURCC('D','X','5','0'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-divx",
"riff_video_divx45", "divxversion", G_TYPE_INT, 5,
"video/x-divx", NULL);
"divxversion", GST_PROPS_INT(5)
);
break; break;
case GST_MAKE_FOURCC('X','V','I','D'): case GST_MAKE_FOURCC('X','V','I','D'):
case GST_MAKE_FOURCC('x','v','i','d'): case GST_MAKE_FOURCC('x','v','i','d'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-xvid", NULL);
"riff_video_xvid",
"video/x-xvid",
NULL
);
break; break;
case GST_MAKE_FOURCC('M','P','G','4'): case GST_MAKE_FOURCC('M','P','G','4'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-msmpeg",
"riff_video_msmpeg41", "msmpegversion", G_TYPE_INT, 41,
"video/x-msmpeg", NULL);
"msmpegversion", GST_PROPS_INT (41)
);
break; break;
case GST_MAKE_FOURCC('M','P','4','2'): case GST_MAKE_FOURCC('M','P','4','2'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-msmpeg",
"riff_video_msmpeg42", "msmpegversion", G_TYPE_INT, 42,
"video/x-msmpeg", NULL);
"msmpegversion", GST_PROPS_INT (42)
);
break; break;
case GST_MAKE_FOURCC('M','P','4','3'): case GST_MAKE_FOURCC('M','P','4','3'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-msmpeg",
"riff_video_msmpeg43", "msmpegversion", G_TYPE_INT, 43,
"video/x-msmpeg", NULL);
"msmpegversion", GST_PROPS_INT (43)
);
break; break;
case GST_MAKE_FOURCC('3','I','V','1'): case GST_MAKE_FOURCC('3','I','V','1'):
case GST_MAKE_FOURCC('3','I','V','2'): case GST_MAKE_FOURCC('3','I','V','2'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ( "video/x-3ivx", NULL);
"riff_video_3ivx",
"video/x-3ivx",
NULL
);
break; break;
case GST_MAKE_FOURCC('D','V','S','D'): case GST_MAKE_FOURCC('D','V','S','D'):
case GST_MAKE_FOURCC('d','v','s','d'): case GST_MAKE_FOURCC('d','v','s','d'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-dv",
"riff_video_dv", "systemstream", G_TYPE_BOOLEAN, FALSE,
"video/x-dv", NULL);
"systemstream", GST_PROPS_BOOLEAN (FALSE)
);
break; break;
case GST_MAKE_FOURCC('W','M','V','1'): case GST_MAKE_FOURCC('W','M','V','1'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-wmv",
"riff_video_wmv1", "wmvversion", G_TYPE_INT, 1,
"video/x-wmv", NULL);
"wmvversion", GST_PROPS_INT (1)
);
break; break;
case GST_MAKE_FOURCC('W','M','V','2'): case GST_MAKE_FOURCC('W','M','V','2'):
caps = GST_CAPS_NEW ( caps = gst_caps_new_simple ("video/x-wmv",
"riff_video_wmv2", "wmvversion", G_TYPE_INT, 2,
"video/x-wmv", NULL);
"wmvversion", GST_PROPS_INT (2)
);
break; break;
default: default:
GST_WARNING ("Unkown video fourcc " GST_FOURCC_FORMAT, GST_WARNING ("Unkown video fourcc " GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (codec_fcc)); GST_FOURCC_ARGS (codec_fcc));
break; return NULL;
} }
/* add general properties */ if (strh != NULL) {
if (caps != NULL) { gfloat fps = 1. * strh->rate / strh->scale;
GstPropsEntry *framerate, *width, *height;
if (strh != NULL) { gst_caps_set_simple (caps, "framerate", G_TYPE_DOUBLE, fps, NULL);
gfloat fps = 1. * strh->rate / strh->scale; } else {
gst_caps_set_simple (caps,
"framerate", GST_TYPE_DOUBLE_RANGE, 0., G_MAXDOUBLE,
NULL);
}
framerate = gst_props_entry_new ("framerate", if (strf != NULL) {
GST_PROPS_FLOAT (fps)); gst_caps_set_simple (caps,
} else { "width", G_TYPE_INT, strf->width,
framerate = gst_props_entry_new ("framerate", "height", G_TYPE_INT, strf->height,
GST_PROPS_FLOAT_RANGE (0., G_MAXFLOAT)); NULL);
} } else {
gst_caps_set_simple (caps,
if (strf != NULL) { "width", GST_TYPE_INT_RANGE, 16, 4096,
width = gst_props_entry_new ("width", "height", GST_TYPE_INT_RANGE, 16, 4096,
GST_PROPS_INT (strf->width)); NULL);
height = gst_props_entry_new ("height",
GST_PROPS_INT (strf->height));
} else {
width = gst_props_entry_new ("width",
GST_PROPS_INT_RANGE (16, 4096));
height = gst_props_entry_new ("height",
GST_PROPS_INT_RANGE (16, 4096));
}
if (!caps->properties)
caps->properties = gst_props_empty_new ();
gst_props_add_entry (caps->properties, width);
gst_props_add_entry (caps->properties, height);
gst_props_add_entry (caps->properties, framerate);
} }
return caps; return caps;
@ -225,57 +173,38 @@ gst_riff_create_audio_caps (guint16 codec_id,
switch (codec_id) { switch (codec_id) {
case GST_RIFF_WAVE_FORMAT_MPEGL3: /* mp3 */ case GST_RIFF_WAVE_FORMAT_MPEGL3: /* mp3 */
caps = GST_CAPS_NEW ("riff_audio_mp1l3", caps = gst_caps_new_simple ("audio/mpeg",
"audio/mpeg", "mpegversion", G_TYPE_INT, 1,
"mpegversion", GST_PROPS_INT (1), "layer", G_TYPE_INT, 3,
"layer", GST_PROPS_INT (3)); NULL);
break; break;
case GST_RIFF_WAVE_FORMAT_MPEGL12: /* mp1 or mp2 */ case GST_RIFF_WAVE_FORMAT_MPEGL12: /* mp1 or mp2 */
caps = GST_CAPS_NEW ("riff_audio_mp1l12", caps = gst_caps_new_simple ("audio/mpeg",
"audio/mpeg", "mpegversion", G_TYPE_INT, 1,
"mpegversion", GST_PROPS_INT (1), "layer", G_TYPE_INT, 2,
"layer", GST_PROPS_INT (2)); NULL);
break; break;
case GST_RIFF_WAVE_FORMAT_PCM: /* PCM/wav */ { case GST_RIFF_WAVE_FORMAT_PCM: /* PCM/wav */
GstPropsEntry *width = NULL, *depth = NULL, *signedness = NULL;
if (strf != NULL) { if (strf != NULL) {
gint ba = GUINT16_FROM_LE (strf->blockalign); gint ba = GUINT16_FROM_LE (strf->blockalign);
gint ch = GUINT16_FROM_LE (strf->channels); gint ch = GUINT16_FROM_LE (strf->channels);
gint ws = GUINT16_FROM_LE (strf->size); gint ws = GUINT16_FROM_LE (strf->size);
width = gst_props_entry_new ("width", caps = gst_caps_new_simple ("audio/x-raw-int",
GST_PROPS_INT (ba * 8 / ch)); "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
depth = gst_props_entry_new ("depth", "width", G_TYPE_INT, (int)(ba * 8 / ch),
GST_PROPS_INT (ws)); "depth", G_TYPE_INT, ws,
signedness = gst_props_entry_new ("signed", "signed", G_TYPE_BOOLEAN, ws != 8,
GST_PROPS_BOOLEAN (ws != 8)); NULL);
} else { } else {
signedness = gst_props_entry_new ("signed", caps = gst_caps_from_string ("audio/x-raw-int, "
GST_PROPS_LIST ( "endianness = (int) LITTLE_ENDIAN, "
GST_PROPS_BOOLEAN (TRUE), "signed = (boolean) { true, false }, "
GST_PROPS_BOOLEAN (FALSE))); "width = (int) { 8, 16 }, "
width = gst_props_entry_new ("width", "height = (int) { 8, 16 }");
GST_PROPS_LIST (
GST_PROPS_INT (8),
GST_PROPS_INT (16)));
depth = gst_props_entry_new ("depth",
GST_PROPS_LIST (
GST_PROPS_INT (8),
GST_PROPS_INT (16)));
} }
caps = GST_CAPS_NEW ("riff_audio_pcm",
"audio/x-raw-int",
"endianness",
GST_PROPS_INT (G_LITTLE_ENDIAN));
gst_props_add_entry (caps->properties, width);
gst_props_add_entry (caps->properties, depth);
gst_props_add_entry (caps->properties, signedness);
}
break; break;
case GST_RIFF_WAVE_FORMAT_MULAW: case GST_RIFF_WAVE_FORMAT_MULAW:
@ -283,9 +212,7 @@ gst_riff_create_audio_caps (guint16 codec_id,
GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.", GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.",
strf->size); strf->size);
} }
caps = GST_CAPS_NEW ("riff_audio_mulaw", caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
"audio/x-mulaw",
NULL);
break; break;
case GST_RIFF_WAVE_FORMAT_ALAW: case GST_RIFF_WAVE_FORMAT_ALAW:
@ -293,9 +220,7 @@ gst_riff_create_audio_caps (guint16 codec_id,
GST_WARNING ("invalid depth (%d) of alaw audio, overwriting.", GST_WARNING ("invalid depth (%d) of alaw audio, overwriting.",
strf->size); strf->size);
} }
caps = GST_CAPS_NEW ("riff_audio_alaw", caps = gst_caps_new_simple ("audio/x-alaw", NULL);
"audio/x-alaw",
NULL);
break; break;
case GST_RIFF_WAVE_FORMAT_VORBIS1: /* ogg/vorbis mode 1 */ case GST_RIFF_WAVE_FORMAT_VORBIS1: /* ogg/vorbis mode 1 */
@ -304,15 +229,11 @@ gst_riff_create_audio_caps (guint16 codec_id,
case GST_RIFF_WAVE_FORMAT_VORBIS1PLUS: /* ogg/vorbis mode 1+ */ case GST_RIFF_WAVE_FORMAT_VORBIS1PLUS: /* ogg/vorbis mode 1+ */
case GST_RIFF_WAVE_FORMAT_VORBIS2PLUS: /* ogg/vorbis mode 2+ */ case GST_RIFF_WAVE_FORMAT_VORBIS2PLUS: /* ogg/vorbis mode 2+ */
case GST_RIFF_WAVE_FORMAT_VORBIS3PLUS: /* ogg/vorbis mode 3+ */ case GST_RIFF_WAVE_FORMAT_VORBIS3PLUS: /* ogg/vorbis mode 3+ */
caps = GST_CAPS_NEW ("riff_audio_vorbis", caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
"audio/x-vorbis",
NULL);
break; break;
case GST_RIFF_WAVE_FORMAT_A52: case GST_RIFF_WAVE_FORMAT_A52:
caps = GST_CAPS_NEW ("riff_audio_ac3", caps = gst_caps_new_simple ("audio/x-ac3", NULL);
"audio/x-ac3",
NULL);
break; break;
default: default:
@ -321,26 +242,16 @@ gst_riff_create_audio_caps (guint16 codec_id,
break; break;
} }
if (caps != NULL) { if (strf != NULL) {
GstPropsEntry *samplerate, *channels; gst_caps_set_simple (caps,
"rate", G_TYPE_INT, strf->rate,
if (strf != NULL) { "channels", G_TYPE_INT, strf->channels,
samplerate = gst_props_entry_new ("rate", NULL);
GST_PROPS_INT (strf->rate)); } else {
channels = gst_props_entry_new ("channels", gst_caps_set_simple (caps,
GST_PROPS_INT (strf->channels)); "rate", GST_TYPE_INT_RANGE, 8000, 96000,
} else { "channels", GST_TYPE_INT_RANGE, 1, 2,
samplerate = gst_props_entry_new ("rate", NULL);
GST_PROPS_INT_RANGE (8000, 96000));
channels = gst_props_entry_new ("channels",
GST_PROPS_INT_RANGE (1, 2));
}
if (!caps->properties)
caps->properties = gst_props_empty_new ();
gst_props_add_entry (caps->properties, samplerate);
gst_props_add_entry (caps->properties, channels);
} }
return caps; return caps;
@ -357,14 +268,13 @@ gst_riff_create_iavs_caps (guint32 codec_fcc,
/* is this correct? */ /* is this correct? */
case GST_MAKE_FOURCC ('D','V','S','D'): case GST_MAKE_FOURCC ('D','V','S','D'):
case GST_MAKE_FOURCC ('d','v','s','d'): case GST_MAKE_FOURCC ('d','v','s','d'):
caps = GST_CAPS_NEW ("riff_iavs_dv", caps = gst_caps_new_simple ("video/x-dv",
"video/x-dv", "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
"systemstream", GST_PROPS_BOOLEAN (TRUE));
default: default:
GST_WARNING ("Unkown IAVS fourcc " GST_FOURCC_FORMAT, GST_WARNING ("Unkown IAVS fourcc " GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (codec_fcc)); GST_FOURCC_ARGS (codec_fcc));
break; return NULL;
} }
return caps; return caps;
@ -398,12 +308,13 @@ gst_riff_create_video_template_caps (void)
0 0
}; };
guint i; guint i;
GstCaps *caps = NULL, *one; GstCaps *caps, *one;
caps = gst_caps_new_empty ();
for (i = 0; tags[i] != 0; i++) { for (i = 0; tags[i] != 0; i++) {
one = gst_riff_create_video_caps (tags[i], NULL, NULL); one = gst_riff_create_video_caps (tags[i], NULL, NULL);
if (one) if (one)
caps = gst_caps_append (caps, one); gst_caps_append (caps, one);
} }
return caps; return caps;
@ -424,12 +335,13 @@ gst_riff_create_audio_template_caps (void)
0 0
}; };
guint i; guint i;
GstCaps *caps = NULL, *one; GstCaps *caps, *one;
caps = gst_caps_new_empty ();
for (i = 0; tags[i] != 0; i++) { for (i = 0; tags[i] != 0; i++) {
one = gst_riff_create_audio_caps (tags[i], NULL, NULL); one = gst_riff_create_audio_caps (tags[i], NULL, NULL);
if (one) if (one)
caps = gst_caps_append (caps, one); gst_caps_append (caps, one);
} }
return caps; return caps;
@ -444,13 +356,15 @@ gst_riff_create_iavs_template_caps (void)
0 0
}; };
guint i; guint i;
GstCaps *caps = NULL, *one; GstCaps *caps, *one;
caps = gst_caps_new_empty ();
for (i = 0; tags[i] != 0; i++) { for (i = 0; tags[i] != 0; i++) {
one = gst_riff_create_iavs_caps (tags[i], NULL, NULL); one = gst_riff_create_iavs_caps (tags[i], NULL, NULL);
if (one) if (one)
caps = gst_caps_append (caps, one); gst_caps_append (caps, one);
} }
return caps; return caps;
} }

View file

@ -714,7 +714,7 @@ gst_riff_read_info (GstRiffRead *riff)
GstRiffLevel *level; GstRiffLevel *level;
GList *last; GList *last;
gchar *name, *type; gchar *name, *type;
GstProps *props; GstCaps *caps;
/* What we're doing here is ugly (oh no!); we look /* What we're doing here is ugly (oh no!); we look
* at our LIST tag size and assure that we do not * at our LIST tag size and assure that we do not
@ -726,11 +726,10 @@ gst_riff_read_info (GstRiffRead *riff)
end = level->start + level->length; end = level->start + level->length;
g_free (level); g_free (level);
props = gst_props_empty_new (); caps = gst_caps_new_simple ("application/x-gst-metadata", NULL);
while (gst_bytestream_tell (riff->bs) < end) { while (gst_bytestream_tell (riff->bs) < end) {
if (!gst_riff_peek_head (riff, &tag, NULL, NULL)) { if (!gst_riff_peek_head (riff, &tag, NULL, NULL)) {
gst_props_unref (props);
return FALSE; return FALSE;
} }
@ -813,26 +812,18 @@ gst_riff_read_info (GstRiffRead *riff)
} }
if (type) { if (type) {
GstPropsEntry *entry;
if (!gst_riff_read_ascii (riff, &tag, &name)) { if (!gst_riff_read_ascii (riff, &tag, &name)) {
gst_props_unref (props);
return FALSE; return FALSE;
} }
entry = gst_props_entry_new (type, GST_PROPS_STRING (name)); gst_caps_set_simple (caps, type, G_TYPE_STRING, name, NULL);
gst_props_add_entry (props, entry);
} else { } else {
gst_riff_read_skip (riff); gst_riff_read_skip (riff);
} }
} }
/* let the world know about this wonderful thing */ /* let the world know about this wonderful thing */
gst_props_debug (props); gst_caps_replace (&riff->metadata, caps);
gst_caps_replace_sink (&riff->metadata,
gst_caps_new ("riff_metadata",
"application/x-gst-metadata",
props));
g_object_notify (G_OBJECT (riff), "metadata"); g_object_notify (G_OBJECT (riff), "metadata");
return TRUE; return TRUE;

View file

@ -107,10 +107,10 @@ static void gst_videofilter_class_init (gpointer g_class, gpointer class_data)
gobject_class->get_property = gst_videofilter_get_property; gobject_class->get_property = gst_videofilter_get_property;
} }
static GstCaps *gst_videofilter_format_get_caps(GstVideofilterFormat *format) static GstStructure *gst_videofilter_format_get_structure(GstVideofilterFormat *format)
{ {
unsigned int fourcc; unsigned int fourcc;
GstCaps *caps; GstStructure *structure;
if(format->filter_func==NULL) if(format->filter_func==NULL)
return NULL; return NULL;
@ -118,79 +118,48 @@ static GstCaps *gst_videofilter_format_get_caps(GstVideofilterFormat *format)
fourcc = GST_MAKE_FOURCC(format->fourcc[0],format->fourcc[1],format->fourcc[2],format->fourcc[3]); fourcc = GST_MAKE_FOURCC(format->fourcc[0],format->fourcc[1],format->fourcc[2],format->fourcc[3]);
if(format->bpp){ if(format->bpp){
caps = GST_CAPS_NEW ("videofilter", "video/x-raw-rgb", structure = gst_structure_new ("video/x-raw-rgb",
"depth", GST_PROPS_INT(format->bpp), "depth", G_TYPE_INT, format->bpp,
"bpp", GST_PROPS_INT(format->depth), "bpp", G_TYPE_INT, format->depth,
"endianness", GST_PROPS_INT(format->endianness), "endianness", G_TYPE_INT, format->endianness,
"red_mask", GST_PROPS_INT(format->red_mask), "red_mask", G_TYPE_INT, format->red_mask,
"green_mask", GST_PROPS_INT(format->green_mask), "green_mask", G_TYPE_INT, format->green_mask,
"blue_mask", GST_PROPS_INT(format->blue_mask)); "blue_mask", G_TYPE_INT, format->blue_mask, NULL);
}else{ }else{
caps = GST_CAPS_NEW ("videoflip", "video/x-raw-yuv", structure = gst_structure_new ("video/x-raw-yuv",
"format", GST_PROPS_FOURCC (fourcc), "format", GST_TYPE_FOURCC, fourcc, NULL);
"height", GST_PROPS_INT_RANGE (1,G_MAXINT), }
"width", GST_PROPS_INT_RANGE (1,G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0,G_MAXFLOAT) gst_structure_set(structure,
); "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE,
NULL);
return structure;
}
GstCaps * gst_videofilter_class_get_capslist(GstVideofilterClass *klass)
{
GstCaps *caps;
GstStructure *structure;
int i;
caps = gst_caps_new_empty();
for(i=0;i<klass->formats->len;i++){
structure = gst_videofilter_format_get_structure(g_ptr_array_index(klass->formats,i));
gst_caps_append_structure (caps, structure);
} }
return caps; return caps;
} }
GstCaps * gst_videofilter_class_get_capslist(GstVideofilterClass *klass)
{
static GstCaps *capslist = NULL;
GstCaps *caps;
int i;
if (capslist){
gst_caps_ref(capslist);
return capslist;
}
for(i=0;i<klass->formats->len;i++){
caps = gst_videofilter_format_get_caps(g_ptr_array_index(klass->formats,i));
capslist = gst_caps_append(capslist, caps);
}
gst_caps_ref(capslist);
return capslist;
}
static GstCaps* gst_videofilter_caps_add_variable_part (GstCaps *caps)
{
GstCaps *yuv, *rgb;
if (caps == NULL)
return NULL;
yuv = GST_CAPS_NEW("videofilter_size","video/x-raw-yuv",
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT));
rgb = GST_CAPS_NEW("videofilter_size","video/x-raw-rgb",
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT));
yuv = gst_caps_intersect (yuv, caps);
rgb = gst_caps_intersect (rgb, caps);
if (yuv) {
gst_caps_append (yuv, rgb);
} else {
g_assert (rgb);
yuv = rgb;
}
gst_caps_unref (caps);
return yuv;
}
static GstCaps * static GstCaps *
gst_videofilter_sink_getcaps (GstPad *pad, GstCaps *caps) gst_videofilter_sink_getcaps (GstPad *pad)
{ {
GstVideofilter *videofilter; GstVideofilter *videofilter;
GstVideofilterClass *klass; GstVideofilterClass *klass;
GstCaps *capslist = NULL; GstCaps *caps;
GstCaps *peercaps; GstCaps *peercaps;
int i; int i;
@ -207,115 +176,81 @@ gst_videofilter_sink_getcaps (GstPad *pad, GstCaps *caps)
/* Look through our list of caps and find those that match with /* Look through our list of caps and find those that match with
* the peer's formats. Create a list of them. */ * the peer's formats. Create a list of them. */
/* FIXME optimize if peercaps == NULL */ /* FIXME optimize if peercaps == NULL */
caps = gst_caps_new_empty ();
for(i=0;i<klass->formats->len;i++){ for(i=0;i<klass->formats->len;i++){
GstCaps *icaps; GstCaps *icaps;
GstCaps *fromcaps = gst_videofilter_format_get_caps(g_ptr_array_index( GstCaps *fromcaps;
klass->formats,i));
fromcaps = gst_caps_new_full (gst_videofilter_format_get_structure (
g_ptr_array_index (klass->formats,i)));
icaps = gst_caps_intersect(fromcaps, peercaps); icaps = gst_caps_intersect (fromcaps, peercaps);
//if(gst_caps_is_always_compatible(fromcaps, peercaps)){
if(icaps != NULL){ if(icaps != NULL){
capslist = gst_caps_append(capslist, fromcaps); gst_caps_append (caps, fromcaps);
} else {
gst_caps_free (fromcaps);
} }
//gst_caps_unref (fromcaps); if(icaps) gst_caps_free (icaps);
if(icaps) gst_caps_unref (icaps);
} }
gst_caps_unref (peercaps); gst_caps_free (peercaps);
capslist = gst_videofilter_caps_add_variable_part (capslist); return caps;
return capslist;
} }
static GstPadLinkReturn static GstPadLinkReturn
gst_videofilter_src_link (GstPad *pad, GstCaps *caps) gst_videofilter_src_link (GstPad *pad, const GstCaps *caps)
{ {
GstVideofilter *videofilter; GstVideofilter *videofilter;
GstPadLinkReturn ret; GstStructure *structure;
GstCaps *peercaps; gboolean ret;
GST_DEBUG("gst_videofilter_src_link"); GST_DEBUG("gst_videofilter_src_link");
videofilter = GST_VIDEOFILTER (gst_pad_get_parent (pad)); videofilter = GST_VIDEOFILTER (gst_pad_get_parent (pad));
if (!GST_CAPS_IS_FIXED (caps)) { structure = gst_caps_get_structure (caps, 0);
return GST_PAD_LINK_DELAYED;
}
gst_caps_debug(caps,"ack");
videofilter->format = gst_videofilter_find_format_by_caps (videofilter,caps); videofilter->format = gst_videofilter_find_format_by_caps (videofilter,caps);
g_return_val_if_fail(videofilter->format, GST_PAD_LINK_REFUSED); g_return_val_if_fail(videofilter->format, GST_PAD_LINK_REFUSED);
gst_caps_get_int (caps, "width", &videofilter->to_width); ret = gst_structure_get_int (structure, "width", &videofilter->to_width);
gst_caps_get_int (caps, "height", &videofilter->to_height); ret &= gst_structure_get_int (structure, "height", &videofilter->to_height);
ret &= gst_structure_get_double (structure, "framerate", &videofilter->framerate);
if (!ret) return GST_PAD_LINK_REFUSED;
GST_DEBUG("width %d height %d",videofilter->to_width,videofilter->to_height); GST_DEBUG("width %d height %d",videofilter->to_width,videofilter->to_height);
peercaps = gst_caps_copy(caps); gst_videofilter_setup(videofilter);
gst_caps_set(peercaps, "width", GST_PROPS_INT_RANGE (0, G_MAXINT)); return GST_PAD_LINK_OK;
gst_caps_set(peercaps, "height", GST_PROPS_INT_RANGE (0, G_MAXINT));
ret = gst_pad_try_set_caps (videofilter->srcpad, peercaps);
gst_caps_unref(peercaps);
if(ret==GST_PAD_LINK_OK){
caps = gst_pad_get_caps (videofilter->srcpad);
gst_caps_get_int (caps, "width", &videofilter->from_width);
gst_caps_get_int (caps, "height", &videofilter->from_height);
//gst_videofilter_setup(videofilter);
}
return ret;
} }
static GstPadLinkReturn static GstPadLinkReturn
gst_videofilter_sink_link (GstPad *pad, GstCaps *caps) gst_videofilter_sink_link (GstPad *pad, const GstCaps *caps)
{ {
GstVideofilter *videofilter; GstVideofilter *videofilter;
GstPadLinkReturn ret; GstPadLinkReturn ret;
GstCaps *peercaps; GstStructure *structure;
GST_DEBUG("gst_videofilter_sink_link"); GST_DEBUG("gst_videofilter_sink_link");
videofilter = GST_VIDEOFILTER (gst_pad_get_parent (pad)); videofilter = GST_VIDEOFILTER (gst_pad_get_parent (pad));
if (!GST_CAPS_IS_FIXED (caps)) { structure = gst_caps_get_structure (caps, 0);
return GST_PAD_LINK_DELAYED;
}
videofilter->format = gst_videofilter_find_format_by_caps (videofilter,caps); videofilter->format = gst_videofilter_find_format_by_caps (videofilter,caps);
GST_DEBUG("sink_link: %s\n",gst_caps_to_string(caps));
g_return_val_if_fail(videofilter->format, GST_PAD_LINK_REFUSED); g_return_val_if_fail(videofilter->format, GST_PAD_LINK_REFUSED);
gst_caps_get_int (caps, "width", &videofilter->from_width); ret = gst_structure_get_int (structure, "width", &videofilter->from_width);
gst_caps_get_int (caps, "height", &videofilter->from_height); ret &= gst_structure_get_int (structure, "height", &videofilter->from_height);
gst_caps_get_float (caps, "framerate", &videofilter->framerate); ret &= gst_structure_get_double (structure, "framerate", &videofilter->framerate);
if (!ret) return GST_PAD_LINK_REFUSED;
GST_DEBUG("width %d height %d",videofilter->from_width,videofilter->from_height);
gst_videofilter_setup(videofilter); gst_videofilter_setup(videofilter);
peercaps = gst_caps_copy(caps); return GST_PAD_LINK_OK;
gst_caps_set(peercaps, "width", GST_PROPS_INT (videofilter->to_width));
gst_caps_set(peercaps, "height", GST_PROPS_INT (videofilter->to_height));
gst_caps_set(peercaps, "framerate", GST_PROPS_FLOAT (videofilter->framerate));
GST_DEBUG("setting %s\n",gst_caps_to_string(peercaps));
ret = gst_pad_try_set_caps (videofilter->srcpad, peercaps);
//gst_caps_unref(peercaps);
if(ret==GST_PAD_LINK_OK || ret==GST_PAD_LINK_DONE){
caps = gst_pad_get_caps (videofilter->srcpad);
//gst_caps_get_int (caps, "width", &videofilter->to_width);
//gst_caps_get_int (caps, "height", &videofilter->to_height);
//gst_videofilter_setup(videofilter);
}
return ret;
} }
static void static void
@ -457,6 +392,7 @@ void gst_videofilter_set_output_size(GstVideofilter *videofilter,
{ {
int ret; int ret;
GstCaps *srccaps; GstCaps *srccaps;
GstStructure *structure;
g_return_if_fail(GST_IS_VIDEOFILTER(videofilter)); g_return_if_fail(GST_IS_VIDEOFILTER(videofilter));
@ -467,18 +403,16 @@ void gst_videofilter_set_output_size(GstVideofilter *videofilter,
* videofilter->format->depth)/8; * videofilter->format->depth)/8;
srccaps = gst_caps_copy(gst_pad_get_caps(videofilter->srcpad)); srccaps = gst_caps_copy(gst_pad_get_caps(videofilter->srcpad));
structure = gst_caps_get_structure (srccaps, 0);
if(!GST_CAPS_IS_FIXED(srccaps)){ gst_structure_set (structure, "width", G_TYPE_INT, width,
gst_caps_unref (srccaps); "height", G_TYPE_INT, height, NULL);
return;
}
gst_caps_set(srccaps, "width", GST_PROPS_INT (videofilter->to_width));
gst_caps_set(srccaps, "height", GST_PROPS_INT (videofilter->to_height));
ret = gst_pad_try_set_caps (videofilter->srcpad, srccaps); ret = gst_pad_try_set_caps (videofilter->srcpad, srccaps);
g_return_if_fail(ret<0); if (ret < 0) {
g_critical ("could not set output size");
}
} }
static void gst_videofilter_setup(GstVideofilter *videofilter) static void gst_videofilter_setup(GstVideofilter *videofilter)
@ -513,12 +447,13 @@ static void gst_videofilter_setup(GstVideofilter *videofilter)
} }
GstVideofilterFormat *gst_videofilter_find_format_by_caps(GstVideofilter *videofilter, GstVideofilterFormat *gst_videofilter_find_format_by_caps(GstVideofilter *videofilter,
GstCaps *caps) const GstCaps *caps)
{ {
int i; int i;
GstCaps *c;
GstVideofilterClass *klass; GstVideofilterClass *klass;
GstVideofilterFormat *format; GstVideofilterFormat *format;
gboolean ret;
GstStructure *structure;
klass = GST_VIDEOFILTER_CLASS(G_OBJECT_GET_CLASS(videofilter)); klass = GST_VIDEOFILTER_CLASS(G_OBJECT_GET_CLASS(videofilter));
@ -526,15 +461,16 @@ GstVideofilterFormat *gst_videofilter_find_format_by_caps(GstVideofilter *videof
for(i=0;i<klass->formats->len;i++){ for(i=0;i<klass->formats->len;i++){
format = g_ptr_array_index(klass->formats,i); format = g_ptr_array_index(klass->formats,i);
c = gst_videofilter_format_get_caps(format); structure = gst_videofilter_format_get_structure(format);
if(c){ if(structure){
if(gst_caps_is_always_compatible(caps, c)){ GstCaps *format_caps;
gst_caps_unref(c); format_caps = gst_caps_new_full (structure, NULL);
return format; ret = gst_caps_is_always_compatible (caps, format_caps);
} gst_caps_free (format_caps);
if (ret) return format;
} }
gst_caps_unref(c);
} }
return NULL; return NULL;
@ -548,17 +484,15 @@ void gst_videofilter_class_add_format(GstVideofilterClass *videofilterclass,
void gst_videofilter_class_add_pad_templates (GstVideofilterClass *videofilter_class) void gst_videofilter_class_add_pad_templates (GstVideofilterClass *videofilter_class)
{ {
GstCaps *caps;
GstElementClass *element_class = GST_ELEMENT_CLASS (videofilter_class); GstElementClass *element_class = GST_ELEMENT_CLASS (videofilter_class);
caps = gst_videofilter_class_get_capslist (videofilter_class);
caps = gst_videofilter_caps_add_variable_part (caps);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_NEW("src", GST_PAD_SRC, GST_PAD_ALWAYS, gst_caps_copy (caps))); gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS,
gst_videofilter_class_get_capslist (videofilter_class)));
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_NEW("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps)); gst_pad_template_new("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
gst_videofilter_class_get_capslist (videofilter_class)));
} }
static gboolean static gboolean

View file

@ -75,7 +75,7 @@ struct _GstVideofilter {
/* private */ /* private */
gint from_buf_size; gint from_buf_size;
gint to_buf_size; gint to_buf_size;
gfloat framerate; gdouble framerate;
GstBuffer *in_buf; GstBuffer *in_buf;
GstBuffer *out_buf; GstBuffer *out_buf;
@ -95,7 +95,7 @@ int gst_videofilter_get_input_height(GstVideofilter *videofilter);
void gst_videofilter_set_output_size(GstVideofilter *videofilter, void gst_videofilter_set_output_size(GstVideofilter *videofilter,
int width, int height); int width, int height);
GstVideofilterFormat *gst_videofilter_find_format_by_caps(GstVideofilter *filter, GstVideofilterFormat *gst_videofilter_find_format_by_caps(GstVideofilter *filter,
GstCaps *caps); const GstCaps *caps);
GstCaps *gst_videofilter_class_get_capslist(GstVideofilterClass *videofilterclass); GstCaps *gst_videofilter_class_get_capslist(GstVideofilterClass *videofilterclass);
void gst_videofilter_class_add_format(GstVideofilterClass *videofilterclass, void gst_videofilter_class_add_format(GstVideofilterClass *videofilterclass,

View file

@ -26,11 +26,12 @@
/* This is simply a convenience function, nothing more or less */ /* This is simply a convenience function, nothing more or less */
gfloat gdouble
gst_video_frame_rate (GstPad *pad) gst_video_frame_rate (GstPad *pad)
{ {
gfloat fps = 0.; gdouble fps = 0.;
GstCaps *caps; GstCaps *caps;
GstStructure *structure;
/* get pad caps */ /* get pad caps */
caps = GST_PAD_CAPS (pad); caps = GST_PAD_CAPS (pad);
@ -41,16 +42,14 @@ gst_video_frame_rate (GstPad *pad)
return 0.; return 0.;
} }
if (!gst_caps_has_property_typed (caps, "framerate", structure = gst_caps_get_structure (caps, 0);
GST_PROPS_FLOAT_TYPE)) { if (!gst_structure_get_double (structure, "framerate", &fps)){
g_warning ("gstvideo: failed to get framerate property of pad %s:%s", g_warning ("gstvideo: failed to get framerate property of pad %s:%s",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_ELEMENT_NAME (gst_pad_get_parent (pad)),
GST_PAD_NAME (pad)); GST_PAD_NAME (pad));
return 0.; return 0.;
} }
gst_caps_get_float (caps, "framerate", &fps);
GST_DEBUG ("Framerate request on pad %s:%s: %f", GST_DEBUG ("Framerate request on pad %s:%s: %f",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_ELEMENT_NAME (gst_pad_get_parent (pad)),
GST_PAD_NAME(pad), fps); GST_PAD_NAME(pad), fps);
@ -64,8 +63,12 @@ gst_video_get_size (GstPad *pad,
gint *height) gint *height)
{ {
GstCaps *caps; GstCaps *caps;
GstStructure *structure;
gboolean ret;
g_return_val_if_fail (pad != NULL, FALSE); g_return_val_if_fail (pad != NULL, FALSE);
g_return_val_if_fail (width != NULL, FALSE);
g_return_val_if_fail (height != NULL, FALSE);
caps = GST_PAD_CAPS (pad); caps = GST_PAD_CAPS (pad);
@ -76,21 +79,17 @@ gst_video_get_size (GstPad *pad,
return FALSE; return FALSE;
} }
if (!gst_caps_has_property_typed (caps, "width", structure = gst_caps_get_structure (caps, 0);
GST_PROPS_INT_TYPE) || ret = gst_structure_get_int (structure, "width", width);
!gst_caps_has_property_typed (caps, "height", ret &= gst_structure_get_int (structure, "height", height);
GST_PROPS_FLOAT_TYPE)) {
if (!ret) {
g_warning ("gstvideo: failed to get size properties on pad %s:%s", g_warning ("gstvideo: failed to get size properties on pad %s:%s",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_ELEMENT_NAME (gst_pad_get_parent (pad)),
GST_PAD_NAME(pad)); GST_PAD_NAME(pad));
return FALSE; return FALSE;
} }
if (width)
gst_caps_get_int (caps, "width", width);
if (height)
gst_caps_get_int (caps, "height", height);
GST_DEBUG ("size request on pad %s:%s: %dx%d", GST_DEBUG ("size request on pad %s:%s: %dx%d",
GST_ELEMENT_NAME (gst_pad_get_parent (pad)), GST_ELEMENT_NAME (gst_pad_get_parent (pad)),
GST_PAD_NAME (pad), GST_PAD_NAME (pad),

View file

@ -23,203 +23,175 @@
#include <gst/gst.h> #include <gst/gst.h>
#define R_MASK_32 0xff000000 #define R_MASK_32 "0xff000000"
#define G_MASK_32 0x00ff0000 #define G_MASK_32 "0x00ff0000"
#define B_MASK_32 0x0000ff00 #define B_MASK_32 "0x0000ff00"
#define R_MASK_32_REVERSE 0x000000ff #define R_MASK_32_REVERSE "0x000000ff"
#define G_MASK_32_REVERSE 0x0000ff00 #define G_MASK_32_REVERSE "0x0000ff00"
#define B_MASK_32_REVERSE 0x00ff0000 #define B_MASK_32_REVERSE "0x00ff0000"
#define R_MASK_24 0xff0000 #define R_MASK_24 "0xff0000"
#define G_MASK_24 0x00ff00 #define G_MASK_24 "0x00ff00"
#define B_MASK_24 0x0000ff #define B_MASK_24 "0x0000ff"
#define R_MASK_24_REVERSE 0x0000ff #define R_MASK_24_REVERSE "0x0000ff"
#define G_MASK_24_REVERSE 0x00ff00 #define G_MASK_24_REVERSE "0x00ff00"
#define B_MASK_24_REVERSE 0xff0000 #define B_MASK_24_REVERSE "0xff0000"
#define R_MASK_16 0xf800 #define R_MASK_16 "0xf800"
#define G_MASK_16 0x07e0 #define G_MASK_16 "0x07e0"
#define B_MASK_16 0x001f #define B_MASK_16 "0x001f"
#define R_MASK_15 0x8c00 #define R_MASK_15 "0x7c00"
#define G_MASK_15 0x03e0 #define G_MASK_15 "0x03e0"
#define B_MASK_15 0x001f #define B_MASK_15 "0x001f"
#define SIZE_RANGE GST_PROPS_INT_RANGE (16, 4096) #define R_MASK_32_INT 0xff000000
#define FPS_RANGE GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) #define G_MASK_32_INT 0x00ff0000
#define B_MASK_32_INT 0x0000ff00
#define R_MASK_32_REVERSE_INT 0x000000ff
#define G_MASK_32_REVERSE_INT 0x0000ff00
#define B_MASK_32_REVERSE_INT 0x00ff0000
#define R_MASK_24_INT 0xff0000
#define G_MASK_24_INT 0x00ff00
#define B_MASK_24_INT 0x0000ff
#define R_MASK_24_REVERSE_INT 0x0000ff
#define G_MASK_24_REVERSE_INT 0x00ff00
#define B_MASK_24_REVERSE_INT 0xff0000
#define R_MASK_16_INT 0xf800
#define G_MASK_16_INT 0x07e0
#define B_MASK_16_INT 0x001f
#define R_MASK_15_INT 0x7c00
#define G_MASK_15_INT 0x03e0
#define B_MASK_15_INT 0x001f
#define SIZE_RANGE "(int) [ 16, 4096 ]"
#define FPS_RANGE "(double) [ 0, max ]"
/* properties for pad templates */ /* properties for pad templates */
#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_32 \ #define GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24_32 \
gst_props_new ( \ "video/x-raw-rgb, " \
"bpp", GST_PROPS_LIST ( \ "bpp = (int) { 24, 32 }, " \
GST_PROPS_INT (24), \ "depth = (int) { 24, 32 }, " \
GST_PROPS_INT (32) \ "endianness = (int) BIG_ENDIAN, " \
), \ "red_mask = (int) { " R_MASK_32 ", " R_MASK_24 " }, " \
"depth", GST_PROPS_LIST ( \ "green_mask = (int) { " G_MASK_32 ", " G_MASK_24 " }, " \
GST_PROPS_INT (24), \ "blue_mask = (int) { " B_MASK_32 ", " B_MASK_24 " }, " \
GST_PROPS_INT (32) \ "width = " SIZE_RANGE ", " \
), \ "height = " SIZE_RANGE ", " \
"endianness", GST_PROPS_INT (G_BIG_ENDIAN), \ "framerate = " FPS_RANGE
"red_mask", GST_PROPS_LIST ( \
GST_PROPS_INT (R_MASK_32), \
GST_PROPS_INT (R_MASK_24) \
), \
"green_mask", GST_PROPS_LIST ( \
GST_PROPS_INT (G_MASK_32), \
GST_PROPS_INT (G_MASK_24) \
), \
"blue_mask", GST_PROPS_LIST ( \
GST_PROPS_INT (B_MASK_32), \
GST_PROPS_INT (B_MASK_24) \
), \
"width", SIZE_RANGE, \
"height", SIZE_RANGE, \
"framerate", FPS_RANGE, \
NULL)
#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_32_REVERSE \ #define GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24_32_REVERSE \
gst_props_new ( \ "video/x-raw-rgb, " \
"bpp", GST_PROPS_LIST ( \ "bpp = (int) { 24, 32 }, " \
GST_PROPS_INT (24), \ "depth = (int) { 24, 32 }, " \
GST_PROPS_INT (32) \ "endianness = (int) BIG_ENDIAN, " \
), \ "red_mask = (int) { " R_MASK_32_REVERSE ", " R_MASK_24_REVERSE "}, " \
"depth", GST_PROPS_LIST ( \ "green_mask = (int) { " G_MASK_32_REVERSE ", " G_MASK_24_REVERSE "}, " \
GST_PROPS_INT (24), \ "blue_mask = (int) { " B_MASK_32_REVERSE ", " B_MASK_24_REVERSE "}, " \
GST_PROPS_INT (32) \ "width = " SIZE_RANGE ", " \
), \ "height = " SIZE_RANGE ", " \
"endianness", GST_PROPS_INT (G_BIG_ENDIAN), \ "framerate = " FPS_RANGE
"red_mask", GST_PROPS_LIST ( \
GST_PROPS_INT (R_MASK_32_REVERSE), \
GST_PROPS_INT (R_MASK_24_REVERSE) \
), \
"green_mask", GST_PROPS_LIST ( \
GST_PROPS_INT (G_MASK_32_REVERSE), \
GST_PROPS_INT (G_MASK_24_REVERSE) \
), \
"blue_mask", GST_PROPS_LIST ( \
GST_PROPS_INT (B_MASK_32_REVERSE), \
GST_PROPS_INT (B_MASK_24_REVERSE) \
), \
"width", SIZE_RANGE, \
"height", SIZE_RANGE, \
"framerate", FPS_RANGE, \
NULL)
#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_32 \ #define GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_32 \
gst_props_new ( \ "video/x-raw-rgb, " \
"bpp", GST_PROPS_INT (32), \ "bpp = (int) 32, " \
"depth", GST_PROPS_INT (32), \ "depth = (int) 32, " \
"endianness", GST_PROPS_INT (G_BIG_ENDIAN), \ "endianness = (int) BIG_ENDIAN, " \
"red_mask", GST_PROPS_INT (R_MASK_32), \ "red_mask = (int) " R_MASK_32 ", " \
"green_mask", GST_PROPS_INT (G_MASK_32), \ "green_mask = (int) " G_MASK_32 ", " \
"blue_mask", GST_PROPS_INT (B_MASK_32), \ "blue_mask = (int) " B_MASK_32 ", " \
"width", SIZE_RANGE, \ "width = " SIZE_RANGE ", " \
"height", SIZE_RANGE, \ "height = " SIZE_RANGE ", " \
"framerate", FPS_RANGE, \ "framerate = " FPS_RANGE
NULL)
#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24 \ #define GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24 \
gst_props_new ( \ "video/x-raw-rgb, " \
"bpp", GST_PROPS_INT (24), \ "bpp = (int) 24, " \
"depth", GST_PROPS_INT (24), \ "depth = (int) 24, " \
"endianness", GST_PROPS_INT (G_BIG_ENDIAN), \ "endianness = (int) BIG_ENDIAN, " \
"red_mask", GST_PROPS_INT (R_MASK_24), \ "red_mask = (int) " R_MASK_24 ", " \
"green_mask", GST_PROPS_INT (G_MASK_24), \ "green_mask = (int) " G_MASK_24 ", " \
"blue_mask", GST_PROPS_INT (B_MASK_24), \ "blue_mask = (int) " B_MASK_24 ", " \
"width", SIZE_RANGE, \ "width = " SIZE_RANGE ", " \
"height", SIZE_RANGE, \ "height = " SIZE_RANGE ", " \
"framerate", FPS_RANGE, \ "framerate = " FPS_RANGE
NULL)
#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_32_REVERSE \ #define GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_32_REVERSE \
gst_props_new ( \ "video/x-raw-rgb, " \
"bpp", GST_PROPS_INT (32), \ "bpp = (int) 32, " \
"depth", GST_PROPS_INT (32), \ "depth = (int) 32, " \
"endianness", GST_PROPS_INT (G_BIG_ENDIAN), \ "endianness = (int) BIG_ENDIAN, " \
"red_mask", GST_PROPS_INT (R_MASK_32_REVERSE), \ "red_mask = (int) " R_MASK_32_REVERSE ", " \
"green_mask", GST_PROPS_INT (G_MASK_32_REVERSE), \ "green_mask = (int) " G_MASK_32_REVERSE ", " \
"blue_mask", GST_PROPS_INT (B_MASK_32_REVERSE), \ "blue_mask = (int) " B_MASK_32_REVERSE ", " \
"width", SIZE_RANGE, \ "width = " SIZE_RANGE ", " \
"height", SIZE_RANGE, \ "height = " SIZE_RANGE ", " \
"framerate", FPS_RANGE, \ "framerate = " FPS_RANGE
NULL)
#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_REVERSE \ #define GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24_REVERSE \
gst_props_new ( \ "video/x-raw-rgb, " \
"bpp", GST_PROPS_INT (24), \ "bpp = (int) 24, " \
"depth", GST_PROPS_INT (24), \ "depth = (int) 24, " \
"endianness", GST_PROPS_INT (G_BIG_ENDIAN), \ "endianness = (int) BIG_ENDIAN, " \
"red_mask", GST_PROPS_INT (R_MASK_24_REVERSE), \ "red_mask = (int) " R_MASK_24_REVERSE ", " \
"green_mask", GST_PROPS_INT (G_MASK_24_REVERSE), \ "green_mask = (int) " G_MASK_24_REVERSE ", " \
"blue_mask", GST_PROPS_INT (B_MASK_24_REVERSE), \ "blue_mask = (int) " B_MASK_24_REVERSE ", " \
"width", SIZE_RANGE, \ "width = " SIZE_RANGE ", " \
"height", SIZE_RANGE, \ "height = " SIZE_RANGE ", " \
"framerate", FPS_RANGE, \ "framerate = " FPS_RANGE
NULL)
#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15_16 \ #define GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_15_16 \
gst_props_new ( \ "video/x-raw-rgb, " \
"bpp", GST_PROPS_INT (16), \ "bpp = (int) 16, " \
"depth", GST_PROPS_LIST ( \ "depth = (int) { 15, 16 }, " \
GST_PROPS_INT (15), \ "endianness = (int) BYTE_ORDER, " \
GST_PROPS_INT (16) \ "red_mask = (int) { " R_MASK_15 ", " R_MASK_16 " }, " \
), \ "green_mask = (int) { " G_MASK_15 ", " G_MASK_16 " }, " \
"endianness", GST_PROPS_INT (G_BYTE_ORDER), \ "blue_mask = (int) { " B_MASK_15 ", " B_MASK_16 " }, " \
"red_mask", GST_PROPS_LIST ( \ "width = " SIZE_RANGE ", " \
GST_PROPS_INT (R_MASK_15), \ "height = " SIZE_RANGE ", " \
GST_PROPS_INT (R_MASK_16) \ "framerate = " FPS_RANGE
), \
"green_mask", GST_PROPS_LIST ( \
GST_PROPS_INT (G_MASK_15), \
GST_PROPS_INT (G_MASK_16) \
), \
"blue_mask", GST_PROPS_LIST ( \
GST_PROPS_INT (B_MASK_15), \
GST_PROPS_INT (B_MASK_16) \
), \
"width", SIZE_RANGE, \
"height", SIZE_RANGE, \
"framerate", FPS_RANGE, \
NULL)
#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_16 \ #define GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_16 \
gst_props_new ( \ "video/x-raw-rgb, " \
"bpp", GST_PROPS_INT (16), \ "bpp = (int) 16, " \
"depth", GST_PROPS_INT (16), \ "depth = (int) 16, " \
"endianness", GST_PROPS_INT (G_BYTE_ORDER), \ "endianness = (int) BYTE_ORDER, " \
"red_mask", GST_PROPS_INT (R_MASK_16), \ "red_mask = (int) " R_MASK_16 ", " \
"green_mask", GST_PROPS_INT (G_MASK_16), \ "green_mask = (int) " G_MASK_16 ", " \
"blue_mask", GST_PROPS_INT (B_MASK_16), \ "blue_mask = (int) " B_MASK_16 ", " \
"width", SIZE_RANGE, \ "width = " SIZE_RANGE ", " \
"height", SIZE_RANGE, \ "height = " SIZE_RANGE ", " \
"framerate", FPS_RANGE, \ "framerate = " FPS_RANGE
NULL)
#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15 \ #define GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_15 \
gst_props_new ( \ "video/x-raw-rgb, " \
"bpp", GST_PROPS_INT (15), \ "bpp = (int) 16, " \
"depth", GST_PROPS_INT (15), \ "depth = (int) 15, " \
"endianness", GST_PROPS_INT (G_BYTE_ORDER), \ "endianness = (int) BYTE_ORDER, " \
"red_mask", GST_PROPS_INT (R_MASK_15), \ "red_mask = (int) " R_MASK_15 ", " \
"green_mask", GST_PROPS_INT (G_MASK_15), \ "green_mask = (int) " G_MASK_15 ", " \
"blue_mask", GST_PROPS_INT (B_MASK_15), \ "blue_mask = (int) " B_MASK_15 ", " \
"width", SIZE_RANGE, \ "width = " SIZE_RANGE ", " \
"height", SIZE_RANGE, \ "height = " SIZE_RANGE ", " \
"framerate", FPS_RANGE, \ "framerate = " FPS_RANGE
NULL)
#define GST_VIDEO_YUV_PAD_TEMPLATE_PROPS(fourcc) \ #define GST_VIDEO_YUV_PAD_TEMPLATE_CAPS(fourcc) \
gst_props_new (\ "video/x-raw-yuv, " \
"format", fourcc, \ "format = (fourcc) " fourcc ", " \
"width", SIZE_RANGE, \ "width = " SIZE_RANGE ", " \
"height", SIZE_RANGE, \ "height = " SIZE_RANGE ", " \
"framerate", FPS_RANGE, \ "framerate = " FPS_RANGE
NULL)
/* functions */ /* functions */
gfloat gst_video_frame_rate (GstPad *pad); gdouble gst_video_frame_rate (GstPad *pad);
gboolean gst_video_get_size (GstPad *pad, gboolean gst_video_get_size (GstPad *pad,
gint *width, gint *width,
gint *height); gint *height);

View file

@ -51,24 +51,26 @@ enum {
/* FILL ME */ /* FILL ME */
}; };
GST_PAD_TEMPLATE_FACTORY (gst_adder_src_template_factory, static GstStaticPadTemplate gst_adder_src_template =
GST_STATIC_PAD_TEMPLATE (
"src", "src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
gst_caps_new ("int_src", "audio/x-raw-int", GST_STATIC_CAPS(
GST_AUDIO_INT_PAD_TEMPLATE_PROPS), GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
gst_caps_new ("float_src", "audio/x-raw-float", GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS
GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_PROPS) )
); );
GST_PAD_TEMPLATE_FACTORY (gst_adder_sink_template_factory, static GstStaticPadTemplate gst_adder_sink_template =
GST_STATIC_PAD_TEMPLATE (
"sink%d", "sink%d",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_REQUEST, GST_PAD_REQUEST,
gst_caps_new ("int_sink", "audio/x-raw-int", GST_STATIC_CAPS(
GST_AUDIO_INT_PAD_TEMPLATE_PROPS), GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
gst_caps_new ("float_sink", "audio/x-raw-float", GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS
GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_PROPS) )
); );
static void gst_adder_class_init (GstAdderClass *klass); static void gst_adder_class_init (GstAdderClass *klass);
@ -106,12 +108,12 @@ gst_adder_get_type (void) {
} }
static gboolean static gboolean
gst_adder_parse_caps (GstAdder *adder, GstCaps *caps) gst_adder_parse_caps (GstAdder *adder, GstStructure *structure)
{ {
const gchar *mimetype; const gchar *mimetype;
GstElement *el = GST_ELEMENT (adder); GstElement *el = GST_ELEMENT (adder);
mimetype = gst_caps_get_mime (caps); mimetype = gst_structure_get_name (structure);
if (adder->format == GST_ADDER_FORMAT_UNSET) { if (adder->format == GST_ADDER_FORMAT_UNSET) {
/* the caps haven't been set yet at all, so we need to go ahead and set all /* the caps haven't been set yet at all, so we need to go ahead and set all
@ -119,18 +121,18 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
if (strcmp (mimetype, "audio/x-raw-int") == 0) { if (strcmp (mimetype, "audio/x-raw-int") == 0) {
GST_DEBUG ("parse_caps sets adder to format int"); GST_DEBUG ("parse_caps sets adder to format int");
adder->format = GST_ADDER_FORMAT_INT; adder->format = GST_ADDER_FORMAT_INT;
gst_caps_get_int (caps, "width", &adder->width); gst_structure_get_int (structure, "width", &adder->width);
gst_caps_get_int (caps, "depth", &adder->depth); gst_structure_get_int (structure, "depth", &adder->depth);
gst_caps_get_int (caps, "endianness", &adder->endianness); gst_structure_get_int (structure, "endianness", &adder->endianness);
gst_caps_get_boolean (caps, "signed", &adder->is_signed); gst_structure_get_boolean (structure, "signed", &adder->is_signed);
gst_caps_get_int (caps, "channels", &adder->channels); gst_structure_get_int (structure, "channels", &adder->channels);
gst_caps_get_int (caps, "rate", &adder->rate); gst_structure_get_int (structure, "rate", &adder->rate);
} else if (strcmp (mimetype, "audio/x-raw-float") == 0) { } else if (strcmp (mimetype, "audio/x-raw-float") == 0) {
GST_DEBUG ("parse_caps sets adder to format float"); GST_DEBUG ("parse_caps sets adder to format float");
adder->format = GST_ADDER_FORMAT_FLOAT; adder->format = GST_ADDER_FORMAT_FLOAT;
gst_caps_get_int (caps, "width", &adder->width); gst_structure_get_int (structure, "width", &adder->width);
gst_caps_get_int (caps, "channels", &adder->channels); gst_structure_get_int (structure, "channels", &adder->channels);
gst_caps_get_int (caps, "rate", &adder->rate); gst_structure_get_int (structure, "rate", &adder->rate);
} }
} else { } else {
/* otherwise, a previously-linked pad has set all the values. we should barf /* otherwise, a previously-linked pad has set all the values. we should barf
@ -139,10 +141,10 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
gint width, channels, rate; gint width, channels, rate;
gboolean is_signed; gboolean is_signed;
gst_caps_get_int (caps, "width", &width); gst_structure_get_int (structure, "width", &width);
gst_caps_get_int (caps, "channels", &channels); gst_structure_get_int (structure, "channels", &channels);
gst_caps_get_boolean (caps, "signed", &is_signed); gst_structure_get_boolean (structure, "signed", &is_signed);
gst_caps_get_int (caps, "rate", &rate); gst_structure_get_int (structure, "rate", &rate);
/* provide an error message if we can't link */ /* provide an error message if we can't link */
if (adder->format != GST_ADDER_FORMAT_INT) { if (adder->format != GST_ADDER_FORMAT_INT) {
@ -174,9 +176,9 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
} else if (strcmp (mimetype, "audio/x-raw-float") == 0) { } else if (strcmp (mimetype, "audio/x-raw-float") == 0) {
gint channels, rate, width; gint channels, rate, width;
gst_caps_get_int (caps, "width", &width); gst_structure_get_int (structure, "width", &width);
gst_caps_get_int (caps, "channels", &channels); gst_structure_get_int (structure, "channels", &channels);
gst_caps_get_int (caps, "rate", &rate); gst_structure_get_int (structure, "rate", &rate);
if (adder->format != GST_ADDER_FORMAT_FLOAT) { if (adder->format != GST_ADDER_FORMAT_FLOAT) {
gst_element_error (el, "can't link a non-float pad to a float adder"); gst_element_error (el, "can't link a non-float pad to a float adder");
@ -204,7 +206,7 @@ gst_adder_parse_caps (GstAdder *adder, GstCaps *caps)
} }
static GstPadLinkReturn static GstPadLinkReturn
gst_adder_link (GstPad *pad, GstCaps *caps) gst_adder_link (GstPad *pad, const GstCaps *caps)
{ {
GstAdder *adder; GstAdder *adder;
const GList *sinkpads; const GList *sinkpads;
@ -217,25 +219,22 @@ gst_adder_link (GstPad *pad, GstCaps *caps)
adder = GST_ADDER (GST_PAD_PARENT (pad)); adder = GST_ADDER (GST_PAD_PARENT (pad));
if (GST_CAPS_IS_FIXED (caps)) { if (!gst_adder_parse_caps (adder, gst_caps_get_structure (caps, 0)))
if (!gst_adder_parse_caps (adder, caps)) return GST_PAD_LINK_REFUSED;
return GST_PAD_LINK_REFUSED;
if (pad == adder->srcpad || gst_pad_try_set_caps (adder->srcpad, caps) > 0) { if (pad == adder->srcpad || gst_pad_try_set_caps (adder->srcpad, caps) > 0) {
sinkpads = gst_element_get_pad_list ((GstElement *) adder); sinkpads = gst_element_get_pad_list ((GstElement *) adder);
while (sinkpads) { while (sinkpads) {
p = (GstPad *) sinkpads->data; p = (GstPad *) sinkpads->data;
if (p != pad && p != adder->srcpad) { if (p != pad && p != adder->srcpad) {
if (gst_pad_try_set_caps (p, caps) <= 0) { if (gst_pad_try_set_caps (p, caps) <= 0) {
GST_DEBUG ("caps mismatch; unlinking and removing pad %s:%s " GST_DEBUG ("caps mismatch; unlinking and removing pad %s:%s "
"(peer %s:%s)", "(peer %s:%s)",
GST_DEBUG_PAD_NAME (p), GST_DEBUG_PAD_NAME (p),
GST_DEBUG_PAD_NAME (GST_PAD_PEER (p))); GST_DEBUG_PAD_NAME (GST_PAD_PEER (p)));
gst_pad_unlink (GST_PAD (GST_PAD_PEER (p)), p); gst_pad_unlink (GST_PAD (GST_PAD_PEER (p)), p);
remove = g_list_prepend (remove, p); remove = g_list_prepend (remove, p);
} }
}
sinkpads = g_list_next (sinkpads);
} }
while (remove) { while (remove) {
gst_element_remove_pad (GST_ELEMENT (adder), gst_element_remove_pad (GST_ELEMENT (adder),
@ -256,12 +255,11 @@ gst_adder_link (GstPad *pad, GstCaps *caps)
} }
remove = g_list_next (remove); remove = g_list_next (remove);
} }
return GST_PAD_LINK_OK; remove = g_list_next (remove);
} else {
return GST_PAD_LINK_REFUSED;
} }
return GST_PAD_LINK_OK;
} else { } else {
return GST_PAD_LINK_DELAYED; return GST_PAD_LINK_REFUSED;
} }
} }
@ -275,9 +273,9 @@ gst_adder_class_init (GstAdderClass *klass)
gstelement_class = (GstElementClass *) klass; gstelement_class = (GstElementClass *) klass;
gst_element_class_add_pad_template (gstelement_class, gst_element_class_add_pad_template (gstelement_class,
GST_PAD_TEMPLATE_GET (gst_adder_src_template_factory)); gst_static_pad_template_get (&gst_adder_src_template));
gst_element_class_add_pad_template (gstelement_class, gst_element_class_add_pad_template (gstelement_class,
GST_PAD_TEMPLATE_GET (gst_adder_sink_template_factory)); gst_static_pad_template_get (&gst_adder_sink_template));
gst_element_class_set_details (gstelement_class, &adder_details); gst_element_class_set_details (gstelement_class, &adder_details);
parent_class = g_type_class_ref (GST_TYPE_ELEMENT); parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
@ -295,8 +293,8 @@ gst_adder_class_init (GstAdderClass *klass)
static void static void
gst_adder_init (GstAdder *adder) gst_adder_init (GstAdder *adder)
{ {
adder->srcpad = gst_pad_new_from_template (gst_adder_src_template_factory (), adder->srcpad = gst_pad_new_from_template (
"src"); gst_static_pad_template_get (&gst_adder_src_template), "src");
gst_element_add_pad (GST_ELEMENT (adder), adder->srcpad); gst_element_add_pad (GST_ELEMENT (adder), adder->srcpad);
gst_element_set_loop_function (GST_ELEMENT (adder), gst_adder_loop); gst_element_set_loop_function (GST_ELEMENT (adder), gst_adder_loop);
gst_pad_set_link_function (adder->srcpad, gst_adder_link); gst_pad_set_link_function (adder->srcpad, gst_adder_link);
@ -305,7 +303,6 @@ gst_adder_init (GstAdder *adder)
/* keep track of the sinkpads requested */ /* keep track of the sinkpads requested */
adder->bufpool = NULL;
adder->numsinkpads = 0; adder->numsinkpads = 0;
adder->input_channels = NULL; adder->input_channels = NULL;
} }
@ -398,16 +395,9 @@ gst_adder_loop (GstElement *element)
adder = GST_ADDER (element); adder = GST_ADDER (element);
if (adder->bufpool == NULL) {
adder->bufpool = gst_pad_get_bufferpool (adder->srcpad);
if (adder->bufpool == NULL) {
adder->bufpool = gst_buffer_pool_get_default (GST_ADDER_BUFFER_SIZE,
GST_ADDER_NUM_BUFFERS);
}
}
/* get new output buffer */ /* get new output buffer */
buf_out = gst_buffer_new_from_pool (adder->bufpool, 0, 0); /* FIXME the 1024 is arbitrary */
buf_out = gst_buffer_new_and_alloc (1024);
if (buf_out == NULL) { if (buf_out == NULL) {
gst_element_error (GST_ELEMENT (adder), "could not get new output buffer"); gst_element_error (GST_ELEMENT (adder), "could not get new output buffer");
@ -534,10 +524,7 @@ gst_adder_loop (GstElement *element)
} }
if (adder->format == GST_ADDER_FORMAT_UNSET) { if (adder->format == GST_ADDER_FORMAT_UNSET) {
GstCaps *caps = GstCaps *caps = gst_caps_from_string (GST_AUDIO_INT_PAD_TEMPLATE_CAPS);
gst_caps_new ("default_adder_caps",
"audio/x-raw-int",
GST_AUDIO_INT_PAD_TEMPLATE_PROPS);
if (gst_pad_try_set_caps (adder->srcpad, caps) < 0) { if (gst_pad_try_set_caps (adder->srcpad, caps) < 0) {
gst_element_error (GST_ELEMENT (adder), gst_element_error (GST_ELEMENT (adder),
@ -546,7 +533,7 @@ gst_adder_loop (GstElement *element)
return; return;
} }
gst_adder_parse_caps (adder, caps); gst_adder_parse_caps (adder, gst_caps_get_structure(caps, 0));
} }
GST_BUFFER_TIMESTAMP (buf_out) = adder->timestamp; GST_BUFFER_TIMESTAMP (buf_out) = adder->timestamp;
@ -580,10 +567,6 @@ gst_adder_change_state (GstElement *element)
case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PAUSED_TO_PLAYING:
break; break;
case GST_STATE_PLAYING_TO_PAUSED: case GST_STATE_PLAYING_TO_PAUSED:
if (adder->bufpool) {
gst_buffer_pool_unref (adder->bufpool);
adder->bufpool = NULL;
}
break; break;
case GST_STATE_PAUSED_TO_READY: case GST_STATE_PAUSED_TO_READY:
break; break;

View file

@ -63,7 +63,6 @@ struct _GstAdder {
GstElement element; GstElement element;
GstPad *srcpad; GstPad *srcpad;
GstBufferPool *bufpool;
/* keep track of the sinkpads */ /* keep track of the sinkpads */
guint numsinkpads; guint numsinkpads;

View file

@ -121,7 +121,7 @@ static void gst_audio_convert_get_property (GObject *object, guint prop_id, GVa
/* gstreamer functions */ /* gstreamer functions */
static void gst_audio_convert_chain (GstPad *pad, GstData *_data); static void gst_audio_convert_chain (GstPad *pad, GstData *_data);
static GstPadLinkReturn gst_audio_convert_link (GstPad *pad, GstCaps *caps); static GstPadLinkReturn gst_audio_convert_link (GstPad *pad, const GstCaps *caps);
static GstElementStateReturn gst_audio_convert_change_state (GstElement *element); static GstElementStateReturn gst_audio_convert_change_state (GstElement *element);
/* actual work */ /* actual work */
@ -151,37 +151,27 @@ static GstElementClass *parent_class = NULL;
/*** GSTREAMER PROTOTYPES *****************************************************/ /*** GSTREAMER PROTOTYPES *****************************************************/
GST_PAD_TEMPLATE_FACTORY (audio_convert_src_template_factory, static GstStaticPadTemplate gst_audio_convert_src_template =
GST_STATIC_PAD_TEMPLATE (
"src", "src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
gst_caps_append ( GST_STATIC_CAPS (
gst_caps_new ( GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
"audio_convert_src_int", GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS
"audio/x-raw-int",
GST_AUDIO_INT_PAD_TEMPLATE_PROPS),
gst_caps_new (
"audio_convert_src_float",
"audio/x-raw-float",
GST_AUDIO_FLOAT_PAD_TEMPLATE_PROPS)
) )
) );
GST_PAD_TEMPLATE_FACTORY (audio_convert_sink_template_factory, static GstStaticPadTemplate gst_audio_convert_sink_template =
GST_STATIC_PAD_TEMPLATE (
"sink", "sink",
GST_PAD_SINK, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
gst_caps_append ( GST_STATIC_CAPS (
gst_caps_new ( GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
"audio_convert_sink_int", GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS
"audio/x-raw-int",
GST_AUDIO_INT_PAD_TEMPLATE_PROPS),
gst_caps_new (
"audio_convert_sink_float",
"audio/x-raw-float",
GST_AUDIO_FLOAT_PAD_TEMPLATE_PROPS)
) )
) );
/*** TYPE FUNCTIONS ***********************************************************/ /*** TYPE FUNCTIONS ***********************************************************/
@ -214,9 +204,9 @@ gst_audio_convert_base_init (gpointer g_class)
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_GET (audio_convert_src_template_factory)); gst_static_pad_template_get (&gst_audio_convert_src_template));
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_GET (audio_convert_sink_template_factory)); gst_static_pad_template_get (&gst_audio_convert_sink_template));
gst_element_class_set_details (element_class, &audio_convert_details); gst_element_class_set_details (element_class, &audio_convert_details);
} }
@ -261,14 +251,14 @@ static void
gst_audio_convert_init (GstAudioConvert *this) gst_audio_convert_init (GstAudioConvert *this)
{ {
/* sinkpad */ /* sinkpad */
this->sink = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET ( this->sink = gst_pad_new_from_template (
audio_convert_sink_template_factory), "sink"); gst_static_pad_template_get (&gst_audio_convert_sink_template), "sink");
gst_pad_set_link_function (this->sink, gst_audio_convert_link); gst_pad_set_link_function (this->sink, gst_audio_convert_link);
gst_element_add_pad (GST_ELEMENT(this), this->sink); gst_element_add_pad (GST_ELEMENT(this), this->sink);
/* srcpad */ /* srcpad */
this->src = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET ( this->src = gst_pad_new_from_template (
audio_convert_src_template_factory), "src"); gst_static_pad_template_get (&gst_audio_convert_src_template), "src");
gst_pad_set_link_function (this->src, gst_audio_convert_link); gst_pad_set_link_function (this->src, gst_audio_convert_link);
gst_element_add_pad (GST_ELEMENT(this), this->src); gst_element_add_pad (GST_ELEMENT(this), this->src);
@ -383,38 +373,36 @@ gst_audio_convert_chain (GstPad *pad, GstData *_data)
} }
static GstPadLinkReturn static GstPadLinkReturn
gst_audio_convert_link (GstPad *pad, GstCaps *caps) gst_audio_convert_link (GstPad *pad, const GstCaps *caps)
{ {
GstAudioConvert *this; GstAudioConvert *this;
gint nr = 0; gint nr = 0;
gint rate, endianness, depth, width, channels; gint rate, endianness, depth, width, channels;
gboolean sign; gboolean sign;
GstStructure *structure;
gboolean ret;
g_return_val_if_fail(GST_IS_PAD(pad), GST_PAD_LINK_REFUSED); g_return_val_if_fail(GST_IS_PAD(pad), GST_PAD_LINK_REFUSED);
g_return_val_if_fail(GST_IS_AUDIO_CONVERT(GST_OBJECT_PARENT (pad)), GST_PAD_LINK_REFUSED); g_return_val_if_fail(GST_IS_AUDIO_CONVERT(GST_OBJECT_PARENT (pad)), GST_PAD_LINK_REFUSED);
this = GST_AUDIO_CONVERT(GST_OBJECT_PARENT (pad)); this = GST_AUDIO_CONVERT(GST_OBJECT_PARENT (pad));
/* could we do better? */
if (!GST_CAPS_IS_FIXED (caps)) return GST_PAD_LINK_DELAYED;
nr = (pad == this->sink) ? 0 : (pad == this->src) ? 1 : -1; nr = (pad == this->sink) ? 0 : (pad == this->src) ? 1 : -1;
g_assert (nr > -1); g_assert (nr > -1);
if (! gst_caps_get (caps, structure = gst_caps_get_structure (caps, 0);
"channels", &channels,
"signed", &sign,
"depth", &depth,
"width", &width,
"rate", &rate, NULL))
return GST_PAD_LINK_DELAYED;
if (!gst_caps_get_int (caps, "endianness", &endianness)) { ret = gst_structure_get_int (structure, "channels", &channels);
if (width == 1) { ret &= gst_structure_get_boolean (structure, "signed", &sign);
endianness = G_BYTE_ORDER; ret &= gst_structure_get_int (structure, "depth", &depth);
} else { ret &= gst_structure_get_int (structure, "width", &width);
return GST_PAD_LINK_DELAYED; ret &= gst_structure_get_int (structure, "rate", &rate);
} endianness = G_BYTE_ORDER;
if (width != 8) {
ret &= gst_structure_get_int (structure, "endianness", &endianness);
} }
if (!ret) return GST_PAD_LINK_REFUSED;
/* we can't convert rate changes yet */ /* we can't convert rate changes yet */
if ((this->caps_set[1 - nr]) && if ((this->caps_set[1 - nr]) &&
(rate != this->rate[1 - nr])) (rate != this->rate[1 - nr]))
@ -454,32 +442,26 @@ gst_audio_convert_change_state (GstElement *element)
/*** ACTUAL WORK **************************************************************/ /*** ACTUAL WORK **************************************************************/
static GstCaps* static GstCaps *
make_caps (gint endianness, gboolean sign, gint depth, gint width, gint rate, gint channels) make_caps (gint endianness, gboolean sign, gint depth, gint width, gint rate, gint channels)
{ {
if (width == 1) { GstCaps *caps;
return GST_CAPS_NEW (
"audio_convert_caps", caps = gst_caps_new_simple ("audio/x-raw-int",
"audio/x-raw-int", "signed", G_TYPE_BOOLEAN, sign,
"signed", GST_PROPS_BOOLEAN (sign), "depth", G_TYPE_INT, depth,
"depth", GST_PROPS_INT (depth), "width", G_TYPE_INT, width * 8,
"width", GST_PROPS_INT (width * 8), "rate", G_TYPE_INT, rate,
"rate", GST_PROPS_INT (rate), "channels", G_TYPE_INT, channels, NULL);
"channels", GST_PROPS_INT (channels)
); if (width != 1) {
} else { gst_caps_set_simple (caps,
return GST_CAPS_NEW ( "endianness", G_TYPE_INT, endianness, NULL);
"audio_convert_caps",
"audio/x-raw-int",
"endianness", GST_PROPS_INT (endianness),
"signed", GST_PROPS_BOOLEAN (sign),
"depth", GST_PROPS_INT (depth),
"width", GST_PROPS_INT (width * 8),
"rate", GST_PROPS_INT (rate),
"channels", GST_PROPS_INT (channels)
);
} }
return caps;
} }
static gboolean static gboolean
gst_audio_convert_set_caps (GstPad *pad) gst_audio_convert_set_caps (GstPad *pad)
{ {

View file

@ -50,22 +50,20 @@ enum {
/* FILL ME */ /* FILL ME */
}; };
GST_PAD_TEMPLATE_FACTORY (sink_factory, static GstStaticPadTemplate gst_audioscale_sink_template =
GST_STATIC_PAD_TEMPLATE (
"sink", "sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
gst_caps_new ("audioscale_sink", GST_STATIC_CAPS ( GST_AUDIO_INT_PAD_TEMPLATE_CAPS)
"audio/x-raw-int",
GST_AUDIO_INT_PAD_TEMPLATE_PROPS)
); );
GST_PAD_TEMPLATE_FACTORY (src_factory, static GstStaticPadTemplate gst_audioscale_src_template =
GST_STATIC_PAD_TEMPLATE (
"src", "src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
gst_caps_new ("audioscale_src", GST_STATIC_CAPS ( GST_AUDIO_INT_PAD_TEMPLATE_CAPS)
"audio/x-raw-int",
GST_AUDIO_INT_PAD_TEMPLATE_PROPS)
); );
#define GST_TYPE_AUDIOSCALE_METHOD (gst_audioscale_method_get_type()) #define GST_TYPE_AUDIOSCALE_METHOD (gst_audioscale_method_get_type())
@ -129,9 +127,9 @@ gst_audioscale_base_init (gpointer g_class)
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (gstelement_class, gst_element_class_add_pad_template (gstelement_class,
GST_PAD_TEMPLATE_GET (src_factory)); gst_static_pad_template_get (&gst_audioscale_src_template));
gst_element_class_add_pad_template (gstelement_class, gst_element_class_add_pad_template (gstelement_class,
GST_PAD_TEMPLATE_GET (sink_factory)); gst_static_pad_template_get (&gst_audioscale_sink_template));
gst_element_class_set_details (gstelement_class, &gst_audioscale_details); gst_element_class_set_details (gstelement_class, &gst_audioscale_details);
} }
@ -160,10 +158,13 @@ gst_audioscale_class_init (AudioscaleClass *klass)
} }
static GstCaps * static GstCaps *
gst_audioscale_getcaps (GstPad *pad, GstCaps *caps) gst_audioscale_getcaps (GstPad *pad)
{ {
Audioscale *audioscale; Audioscale *audioscale;
GstCaps *peercaps; GstCaps *peercaps;
GstCaps *caps;
int i;
int n;
audioscale = GST_AUDIOSCALE (gst_pad_get_parent (pad)); audioscale = GST_AUDIOSCALE (gst_pad_get_parent (pad));
@ -173,105 +174,75 @@ gst_audioscale_getcaps (GstPad *pad, GstCaps *caps)
peercaps = gst_pad_get_allowed_caps (audioscale->srcpad); peercaps = gst_pad_get_allowed_caps (audioscale->srcpad);
} }
if(peercaps == GST_CAPS_NONE){ caps = gst_caps_intersect (peercaps, gst_static_caps_get (
return GST_CAPS_NONE; &gst_audioscale_sink_template.static_caps));
} if (gst_caps_is_empty(caps)) return caps;
caps = gst_caps_copy (peercaps);
#if 1
/* we do this hack, because the audioscale lib doesn't handle /* we do this hack, because the audioscale lib doesn't handle
* rate conversions larger than a factor of 2 */ * rate conversions larger than a factor of 2 */
if(gst_caps_has_property_typed(caps, "rate", GST_PROPS_INT_RANGE_TYPE)){ n = gst_caps_get_size (caps);
for (i=0;i<n;i++){
int rate_min, rate_max; int rate_min, rate_max;
GstStructure *structure = gst_caps_get_structure (caps, i);
const GValue *value;
gst_props_entry_get_int_range (gst_props_get_entry(caps->properties, "rate"), value = gst_structure_get_value (structure, "rate");
&rate_min, &rate_max); if (value == NULL) return NULL;
gst_caps_set (caps, "rate", GST_PROPS_INT_RANGE((rate_min+1)/2,
rate_max*2));
}else{
int rate;
gst_caps_get_int (caps, "rate", &rate); if (G_VALUE_TYPE (value) == G_TYPE_INT) {
gst_caps_set (caps, "rate", GST_PROPS_INT_RANGE((rate+1)/2,rate*2)); rate_min = g_value_get_int (value);
rate_max = rate_min;
} else if (G_VALUE_TYPE (value) == GST_TYPE_INT_RANGE) {
rate_min = gst_value_get_int_range_min (value);
rate_max = gst_value_get_int_range_max (value);
} else {
return NULL;
}
gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, rate_min/2,
rate_max*2, NULL);
} }
#else
gst_caps_set (caps, "rate", GST_PROPS_INT_RANGE(4000,96000));
#endif
return caps; return caps;
} }
static GstPadLinkReturn static GstPadLinkReturn
gst_audioscale_sink_link (GstPad * pad, GstCaps * caps) gst_audioscale_link (GstPad * pad, const GstCaps * caps)
{ {
Audioscale *audioscale; Audioscale *audioscale;
resample_t *r; resample_t *r;
GstCaps *caps1; GstStructure *structure;
GstCaps *caps2; int rate;
GstCaps *peercaps; int channels;
gint rate;
int ret; int ret;
GstPadLinkReturn link_ret;
audioscale = GST_AUDIOSCALE (gst_pad_get_parent (pad)); audioscale = GST_AUDIOSCALE (gst_pad_get_parent (pad));
r = audioscale->resample; r = audioscale->resample;
if (!GST_CAPS_IS_FIXED (caps)){ link_ret = gst_pad_try_set_caps ((pad == audioscale->srcpad)
return GST_PAD_LINK_DELAYED; ? audioscale->sinkpad : audioscale->srcpad, caps);
} if(link_ret == GST_PAD_LINK_OK){
ret = gst_pad_try_set_caps (audioscale->srcpad, caps);
if(ret == GST_PAD_LINK_OK || ret == GST_PAD_LINK_DONE){
audioscale->passthru = TRUE; audioscale->passthru = TRUE;
return ret; return link_ret;
} }
audioscale->passthru = FALSE; audioscale->passthru = FALSE;
gst_caps_get_int (caps, "rate", &rate); structure = gst_caps_get_structure (caps, 0);
gst_caps_get_int (caps, "channels", &r->channels);
r->i_rate = rate; ret = gst_structure_get_int (structure, "rate", &rate);
ret &= gst_structure_get_int (structure, "channels", &channels);
r->channels = channels;
if (pad == audioscale->srcpad) {
r->i_rate = rate;
} else {
r->o_rate = rate;
}
resample_reinit(r); resample_reinit(r);
peercaps = gst_pad_get_allowed_caps (audioscale->srcpad); return GST_PAD_LINK_OK;
caps1 = gst_caps_copy (caps);
#if 1
/* we do this hack, because the audioscale lib doesn't handle
* rate conversions larger than a factor of 2 */
if(gst_caps_has_property_typed(caps1, "rate", GST_PROPS_INT_RANGE_TYPE)){
int rate_min, rate_max;
gst_props_entry_get_int_range (gst_props_get_entry(caps1->properties, "rate"),
&rate_min, &rate_max);
gst_caps_set (caps1, "rate", GST_PROPS_INT_RANGE((rate_min+1)/2,
rate_max*2));
}else{
gst_caps_get_int (caps1, "rate", &rate);
gst_caps_set (caps1, "rate", GST_PROPS_INT_RANGE((rate+1)/2,rate*2));
}
#else
gst_caps_set (caps1, "rate", GST_PROPS_INT_RANGE(4000,96000));
#endif
caps2 = gst_caps_intersect(caps1, peercaps);
gst_caps_unref(caps1);
if(caps2 == GST_CAPS_NONE){
return GST_PAD_LINK_REFUSED;
}
if (GST_CAPS_IS_FIXED (caps2)) {
ret = gst_pad_try_set_caps (audioscale->srcpad, caps2);
gst_caps_get_int (caps, "rate", &rate);
r->o_rate = rate;
audioscale->targetfrequency = rate;
resample_reinit(r);
return ret;
}
gst_caps_unref (caps2);
return GST_PAD_LINK_DELAYED;
} }
static void * static void *
@ -294,16 +265,17 @@ gst_audioscale_init (Audioscale *audioscale)
resample_t *r; resample_t *r;
audioscale->sinkpad = gst_pad_new_from_template ( audioscale->sinkpad = gst_pad_new_from_template (
GST_PAD_TEMPLATE_GET (sink_factory), "sink"); gst_static_pad_template_get (&gst_audioscale_sink_template), "sink");
gst_element_add_pad(GST_ELEMENT(audioscale),audioscale->sinkpad); gst_element_add_pad(GST_ELEMENT(audioscale),audioscale->sinkpad);
gst_pad_set_chain_function(audioscale->sinkpad,gst_audioscale_chain); gst_pad_set_chain_function(audioscale->sinkpad,gst_audioscale_chain);
gst_pad_set_link_function (audioscale->sinkpad, gst_audioscale_sink_link); gst_pad_set_link_function (audioscale->sinkpad, gst_audioscale_link);
gst_pad_set_getcaps_function (audioscale->sinkpad, gst_audioscale_getcaps); gst_pad_set_getcaps_function (audioscale->sinkpad, gst_audioscale_getcaps);
audioscale->srcpad = gst_pad_new_from_template ( audioscale->srcpad = gst_pad_new_from_template (
GST_PAD_TEMPLATE_GET (src_factory), "src"); gst_static_pad_template_get (&gst_audioscale_src_template), "src");
gst_element_add_pad(GST_ELEMENT(audioscale),audioscale->srcpad); gst_element_add_pad(GST_ELEMENT(audioscale),audioscale->srcpad);
gst_pad_set_link_function (audioscale->srcpad, gst_audioscale_link);
gst_pad_set_getcaps_function (audioscale->srcpad, gst_audioscale_getcaps); gst_pad_set_getcaps_function (audioscale->srcpad, gst_audioscale_getcaps);
r = g_new0(resample_t,1); r = g_new0(resample_t,1);

View file

@ -54,19 +54,18 @@ enum {
ARG_VOLUME, ARG_VOLUME,
}; };
GST_PAD_TEMPLATE_FACTORY (sinesrc_src_factory, static GstStaticPadTemplate gst_sinesrc_src_template =
GST_STATIC_PAD_TEMPLATE (
"src", "src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_CAPS_NEW ( GST_STATIC_CAPS ("audio/x-raw-int, "
"sinesrc_src", "endianness = (int) BYTE_ORDER, "
"audio/x-raw-int", "signed = (boolean) true, "
"endianness", GST_PROPS_INT (G_BYTE_ORDER), "width = (int) 16, "
"signed", GST_PROPS_BOOLEAN (TRUE), "depth = (int) 16, "
"width", GST_PROPS_INT (16), "rate = (int) [ 8000, 48000 ], "
"depth", GST_PROPS_INT (16), "channels = (int) 1"
"rate", GST_PROPS_INT_RANGE (8000, 48000),
"channels", GST_PROPS_INT (1)
) )
); );
@ -83,7 +82,7 @@ static void gst_sinesrc_get_property (GObject *object,
GParamSpec *pspec); GParamSpec *pspec);
static GstPadLinkReturn static GstPadLinkReturn
gst_sinesrc_link (GstPad *pad, gst_sinesrc_link (GstPad *pad,
GstCaps *caps); const GstCaps *caps);
static GstElementStateReturn static GstElementStateReturn
gst_sinesrc_change_state (GstElement *element); gst_sinesrc_change_state (GstElement *element);
@ -100,6 +99,7 @@ static gboolean gst_sinesrc_src_query (GstPad *pad,
gint64 *value); gint64 *value);
static GstData* gst_sinesrc_get (GstPad *pad); static GstData* gst_sinesrc_get (GstPad *pad);
static GstCaps * gst_sinesrc_src_fixate (GstPad *pad, const GstCaps *caps, gpointer user_data);
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
/*static guint gst_sinesrc_signals[LAST_SIGNAL] = { 0 }; */ /*static guint gst_sinesrc_signals[LAST_SIGNAL] = { 0 }; */
@ -128,8 +128,8 @@ gst_sinesrc_base_init (GstSineSrcClass *klass)
{ {
GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_GET (sinesrc_src_factory)); gst_static_pad_template_get (&gst_sinesrc_src_template));
gst_element_class_set_details (element_class, &gst_sinesrc_details); gst_element_class_set_details (element_class, &gst_sinesrc_details);
} }
@ -153,10 +153,10 @@ gst_sinesrc_class_init (GstSineSrcClass *klass)
"Number of samples in each outgoing buffer", "Number of samples in each outgoing buffer",
1, G_MAXINT, 1024, G_PARAM_READWRITE)); 1, G_MAXINT, 1024, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREQ, g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREQ,
g_param_spec_float ("freq", "Frequency", "Frequency of sine source", g_param_spec_double ("freq", "Frequency", "Frequency of sine source",
0.0, 20000.0, 440.0, G_PARAM_READWRITE)); 0.0, 20000.0, 440.0, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VOLUME, g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VOLUME,
g_param_spec_float ("volume", "Volume", "Volume", g_param_spec_double ("volume", "Volume", "Volume",
0.0, 1.0, 0.8, G_PARAM_READWRITE)); 0.0, 1.0, 0.8, G_PARAM_READWRITE));
gobject_class->set_property = gst_sinesrc_set_property; gobject_class->set_property = gst_sinesrc_set_property;
@ -169,7 +169,9 @@ static void
gst_sinesrc_init (GstSineSrc *src) gst_sinesrc_init (GstSineSrc *src)
{ {
src->srcpad = gst_pad_new_from_template ( src->srcpad = gst_pad_new_from_template (
GST_PAD_TEMPLATE_GET (sinesrc_src_factory), "src"); gst_static_pad_template_get (&gst_sinesrc_src_template), "src");
gst_pad_set_link_function (src->srcpad, gst_sinesrc_link);
gst_pad_set_fixate_function (src->srcpad, gst_sinesrc_src_fixate);
gst_element_add_pad (GST_ELEMENT(src), src->srcpad); gst_element_add_pad (GST_ELEMENT(src), src->srcpad);
gst_pad_set_get_function (src->srcpad, gst_sinesrc_get); gst_pad_set_get_function (src->srcpad, gst_sinesrc_get);
@ -186,7 +188,6 @@ gst_sinesrc_init (GstSineSrc *src)
src->samples_per_buffer=1024; src->samples_per_buffer=1024;
src->timestamp=0LLU; src->timestamp=0LLU;
src->offset=0LLU; src->offset=0LLU;
src->bufpool=NULL;
src->seq = 0; src->seq = 0;
@ -194,7 +195,7 @@ gst_sinesrc_init (GstSineSrc *src)
gst_dpman_add_required_dparam_callback ( gst_dpman_add_required_dparam_callback (
src->dpman, src->dpman,
g_param_spec_float("freq","Frequency (Hz)","Frequency of the tone", g_param_spec_double("freq","Frequency (Hz)","Frequency of the tone",
10.0, 10000.0, 350.0, G_PARAM_READWRITE), 10.0, 10000.0, 350.0, G_PARAM_READWRITE),
"hertz", "hertz",
gst_sinesrc_update_freq, gst_sinesrc_update_freq,
@ -203,7 +204,7 @@ gst_sinesrc_init (GstSineSrc *src)
gst_dpman_add_required_dparam_direct ( gst_dpman_add_required_dparam_direct (
src->dpman, src->dpman,
g_param_spec_float("volume","Volume","Volume of the tone", g_param_spec_double("volume","Volume","Volume of the tone",
0.0, 1.0, 0.8, G_PARAM_READWRITE), 0.0, 1.0, 0.8, G_PARAM_READWRITE),
"scalar", "scalar",
&(src->volume) &(src->volume)
@ -216,55 +217,41 @@ gst_sinesrc_init (GstSineSrc *src)
} }
#define gst_caps_get_int_range(caps, name, min, max) \ static GstCaps *
gst_props_entry_get_int_range(gst_props_get_entry((caps)->properties, \ gst_sinesrc_src_fixate (GstPad *pad, const GstCaps *caps,
name), \ gpointer user_data)
min, max)
static GstPadLinkReturn
gst_sinesrc_link (GstPad *pad,
GstCaps *caps)
{ {
GstSineSrc *src = GST_SINESRC (gst_pad_get_parent (pad)); GstStructure *structure;
gint samplerate = 0, m; GstCaps *newcaps;
for (; caps != NULL; caps = caps->next) { structure = gst_structure_copy (gst_caps_get_structure (caps, 0));
GstCaps *newcaps; newcaps = gst_caps_new_full (structure, NULL);
if (gst_caps_has_fixed_property (caps, "rate")) if (gst_caps_structure_fixate_field_nearest_int (structure, "rate", 44100)) {
gst_caps_get_int (caps, "rate", &samplerate); return newcaps;
else /* max. */
gst_caps_get_int_range (caps, "rate", &m, &samplerate);
src->samplerate = samplerate;
gst_dpman_set_rate (src->dpman, src->samplerate);
gst_sinesrc_update_table_inc (src);
newcaps = GST_CAPS_NEW ("sinesrc_src_caps",
"audio/x-raw-int",
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"signed", GST_PROPS_BOOLEAN (TRUE),
"width", GST_PROPS_INT (16),
"depth", GST_PROPS_INT (16),
"rate", GST_PROPS_INT (samplerate),
"channels", GST_PROPS_INT (1));
switch (gst_pad_try_set_caps (src->srcpad, newcaps)) {
case GST_PAD_LINK_OK:
case GST_PAD_LINK_DONE:
return GST_PAD_LINK_DONE;
case GST_PAD_LINK_DELAYED:
/* don't try further */
return GST_PAD_LINK_DELAYED;
default:
break;
}
} }
/* nothing good found */ gst_caps_free (newcaps);
return GST_PAD_LINK_REFUSED; return NULL;
}
static GstPadLinkReturn
gst_sinesrc_link (GstPad *pad, const GstCaps *caps)
{
GstSineSrc *sinesrc;
const GstStructure *structure;
gboolean ret;
GST_DEBUG ("gst_sinesrc_src_link");
sinesrc = GST_SINESRC (gst_pad_get_parent (pad));
structure = gst_caps_get_structure (caps, 0);
ret = gst_structure_get_int (structure, "rate", &sinesrc->samplerate);
if (!ret) return GST_PAD_LINK_REFUSED;
return GST_PAD_LINK_OK;
} }
static const GstQueryType * static const GstQueryType *
@ -328,13 +315,11 @@ gst_sinesrc_get (GstPad *pad)
g_return_val_if_fail (pad != NULL, NULL); g_return_val_if_fail (pad != NULL, NULL);
src = GST_SINESRC (gst_pad_get_parent (pad)); src = GST_SINESRC (gst_pad_get_parent (pad));
if (src->bufpool == NULL) {
src->bufpool = gst_buffer_pool_get_default (2 * src->samples_per_buffer, 8);
}
tdiff = src->samples_per_buffer * GST_SECOND / src->samplerate; tdiff = src->samples_per_buffer * GST_SECOND / src->samplerate;
buf = (GstBuffer *) gst_buffer_new_from_pool (src->bufpool, 0, 0); /* FIXME the 1024 is arbitrary */
buf = gst_buffer_new_and_alloc (1024);
GST_BUFFER_TIMESTAMP(buf) = src->timestamp; GST_BUFFER_TIMESTAMP(buf) = src->timestamp;
GST_BUFFER_OFFSET (buf) = src->offset; GST_BUFFER_OFFSET (buf) = src->offset;
GST_BUFFER_DURATION (buf) = tdiff; GST_BUFFER_DURATION (buf) = tdiff;
@ -419,7 +404,7 @@ gst_sinesrc_set_property (GObject *object, guint prop_id,
break; break;
case ARG_VOLUME: case ARG_VOLUME:
gst_dpman_bypass_dparam (src->dpman, "volume"); gst_dpman_bypass_dparam (src->dpman, "volume");
src->volume = g_value_get_float (value); src->volume = g_value_get_double (value);
break; break;
default: default:
break; break;
@ -444,10 +429,10 @@ gst_sinesrc_get_property (GObject *object, guint prop_id,
g_value_set_int (value, src->samples_per_buffer); g_value_set_int (value, src->samples_per_buffer);
break; break;
case ARG_FREQ: case ARG_FREQ:
g_value_set_float (value, src->freq); g_value_set_double (value, src->freq);
break; break;
case ARG_VOLUME: case ARG_VOLUME:
g_value_set_float (value, src->volume); g_value_set_double (value, src->volume);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -480,10 +465,10 @@ gst_sinesrc_populate_sinetable (GstSineSrc *src)
{ {
gint i; gint i;
gdouble pi2scaled = M_PI * 2 / src->table_size; gdouble pi2scaled = M_PI * 2 / src->table_size;
gfloat *table = g_new (gfloat, src->table_size); gdouble *table = g_new (gdouble, src->table_size);
for(i=0 ; i < src->table_size ; i++){ for(i=0 ; i < src->table_size ; i++){
table[i] = (gfloat) sin(i * pi2scaled); table[i] = (gdouble) sin(i * pi2scaled);
} }
g_free (src->table_data); g_free (src->table_data);
@ -496,7 +481,7 @@ gst_sinesrc_update_freq (const GValue *value, gpointer data)
GstSineSrc *src = (GstSineSrc *) data; GstSineSrc *src = (GstSineSrc *) data;
g_return_if_fail (GST_IS_SINESRC (src)); g_return_if_fail (GST_IS_SINESRC (src));
src->freq = g_value_get_float (value); src->freq = g_value_get_double (value);
src->table_inc = src->table_size * src->freq / src->samplerate; src->table_inc = src->table_size * src->freq / src->samplerate;
/*GST_DEBUG ("freq %f", src->freq); */ /*GST_DEBUG ("freq %f", src->freq); */
@ -508,6 +493,36 @@ gst_sinesrc_update_table_inc (GstSineSrc *src)
src->table_inc = src->table_size * src->freq / src->samplerate; src->table_inc = src->table_size * src->freq / src->samplerate;
} }
#if 0
static gboolean
gst_sinesrc_force_caps (GstSineSrc *src)
{
static GstStaticCaps static_caps = GST_STATIC_CAPS ("audio/x-raw-int, "
"endianness = (int) BYTE_ORDER, "
"signed = (boolean) true, "
"width = (int) 16, "
"depth = (int) 16, "
"rate = (int) [ 8000, 48000 ], "
"channels = (int) 1"
);
GstCaps *caps;
GstStructure *structure;
if (!src->newcaps)
return TRUE;
caps = gst_caps_copy (gst_static_caps_get (&static_caps));
structure = gst_caps_get_structure (caps, 0);
gst_structure_set (structure, "rate", G_TYPE_INT, src->samplerate, NULL);
src->newcaps = gst_pad_try_set_caps (src->srcpad, caps) < GST_PAD_LINK_OK;
return !src->newcaps;
}
#endif
static gboolean static gboolean
plugin_init (GstPlugin *plugin) plugin_init (GstPlugin *plugin)
{ {

View file

@ -55,11 +55,11 @@ struct _GstSineSrc {
GstDParamManager *dpman; GstDParamManager *dpman;
/* parameters */ /* parameters */
gfloat volume; gdouble volume;
gfloat freq; gdouble freq;
/* lookup table data */ /* lookup table data */
gfloat *table_data; gdouble *table_data;
gdouble table_pos; gdouble table_pos;
gdouble table_inc; gdouble table_inc;
gint table_size; gint table_size;
@ -75,7 +75,6 @@ struct _GstSineSrc {
guint64 timestamp; guint64 timestamp;
guint64 offset; guint64 offset;
GstBufferPool *bufpool;
gdouble accumulator; gdouble accumulator;
}; };

View file

@ -74,32 +74,21 @@ enum {
LAST_SIGNAL LAST_SIGNAL
}; };
GST_PAD_TEMPLATE_FACTORY (vorbis_tag_src_template_factory, static GstStaticPadTemplate gst_vorbis_tag_src_template =
GST_STATIC_PAD_TEMPLATE (
"src", "src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_CAPS_NEW ( GST_STATIC_CAPS ("audio/x-vorbis; application/x-gst-tags")
"vorbis_tag_data_src", );
"audio/x-vorbis",
NULL
),
GST_CAPS_NEW (
"vorbis_tag_tag_src",
"application/x-gst-tags",
NULL
)
)
GST_PAD_TEMPLATE_FACTORY (vorbis_tag_sink_template_factory, static GstStaticPadTemplate gst_vorbis_tag_sink_template =
GST_STATIC_PAD_TEMPLATE (
"sink", "sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_CAPS_NEW ( GST_STATIC_CAPS ( "audio/x-vorbis" )
"vorbis_tag_data_sink", );
"audio/x-vorbis",
NULL
)
)
static void gst_vorbis_tag_base_init (gpointer g_class); static void gst_vorbis_tag_base_init (gpointer g_class);
@ -155,9 +144,9 @@ gst_vorbis_tag_base_init (gpointer g_class)
gst_element_class_set_details (element_class, &gst_vorbis_tag_details); gst_element_class_set_details (element_class, &gst_vorbis_tag_details);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_GET (vorbis_tag_sink_template_factory)); gst_static_pad_template_get (&gst_vorbis_tag_sink_template));
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_GET (vorbis_tag_src_template_factory)); gst_static_pad_template_get (&gst_vorbis_tag_src_template));
} }
static void static void
gst_vorbis_tag_class_init (gpointer g_class, gpointer class_data) gst_vorbis_tag_class_init (gpointer g_class, gpointer class_data)
@ -175,12 +164,12 @@ gst_vorbis_tag_init (GTypeInstance *instance, gpointer g_class)
/* create the sink and src pads */ /* create the sink and src pads */
tag->sinkpad = gst_pad_new_from_template( tag->sinkpad = gst_pad_new_from_template(
GST_PAD_TEMPLATE_GET (vorbis_tag_sink_template_factory), "sink"); gst_static_pad_template_get (&gst_vorbis_tag_sink_template), "sink");
gst_element_add_pad (GST_ELEMENT (tag), tag->sinkpad); gst_element_add_pad (GST_ELEMENT (tag), tag->sinkpad);
gst_pad_set_chain_function (tag->sinkpad, GST_DEBUG_FUNCPTR (gst_vorbis_tag_chain)); gst_pad_set_chain_function (tag->sinkpad, GST_DEBUG_FUNCPTR (gst_vorbis_tag_chain));
tag->srcpad = gst_pad_new_from_template( tag->srcpad = gst_pad_new_from_template(
GST_PAD_TEMPLATE_GET (vorbis_tag_src_template_factory), "src"); gst_static_pad_template_get (&gst_vorbis_tag_src_template), "src");
gst_element_add_pad (GST_ELEMENT (tag), tag->srcpad); gst_element_add_pad (GST_ELEMENT (tag), tag->srcpad);
} }
static GstTagEntryMatch tag_matches[] = { static GstTagEntryMatch tag_matches[] = {
@ -520,12 +509,15 @@ gst_vorbis_tag_chain (GstPad *pad, GstData *data)
if (tag->output == OUTPUT_UNKNOWN) { if (tag->output == OUTPUT_UNKNOWN) {
/* caps nego */ /* caps nego */
do { do {
if (gst_pad_try_set_caps (tag->srcpad, GST_CAPS_NEW ("vorbis_tag_data_src", "audio/x-vorbis", NULL)) >= 0) { if (gst_pad_try_set_caps (tag->srcpad, gst_caps_new_simple (
"audio/x-vorbis", NULL)) >= 0) {
tag->output = OUTPUT_DATA; tag->output = OUTPUT_DATA;
} else if (gst_pad_try_set_caps (tag->srcpad, GST_CAPS_NEW ("vorbis_tag_tag_src", "application/x-gst-tags", NULL)) >= 0) { } else if (gst_pad_try_set_caps (tag->srcpad, gst_caps_new_simple (
"application/x-gst-tags", NULL)) >= 0) {
tag->output = OUTPUT_TAGS; tag->output = OUTPUT_TAGS;
} else { } else {
GstCaps *caps = gst_pad_template_get_caps (GST_PAD_TEMPLATE_GET (vorbis_tag_src_template_factory)); const GstCaps *caps = gst_static_caps_get (
&gst_vorbis_tag_src_template.static_caps);
if (gst_pad_recover_caps_error (tag->srcpad, caps)) if (gst_pad_recover_caps_error (tag->srcpad, caps))
continue; continue;
return; return;

View file

@ -146,7 +146,7 @@ gst_tcpsink_class_init (GstTCPSink *klass)
static GstPadLinkReturn static GstPadLinkReturn
gst_tcpsink_sinkconnect (GstPad *pad, GstCaps *caps) gst_tcpsink_sink_link (GstPad *pad, const GstCaps *caps)
{ {
GstTCPSink *tcpsink; GstTCPSink *tcpsink;
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
@ -240,7 +240,7 @@ gst_tcpsink_init (GstTCPSink *tcpsink)
tcpsink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); tcpsink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
gst_element_add_pad (GST_ELEMENT (tcpsink), tcpsink->sinkpad); gst_element_add_pad (GST_ELEMENT (tcpsink), tcpsink->sinkpad);
gst_pad_set_chain_function (tcpsink->sinkpad, gst_tcpsink_chain); gst_pad_set_chain_function (tcpsink->sinkpad, gst_tcpsink_chain);
gst_pad_set_link_function (tcpsink->sinkpad, gst_tcpsink_sinkconnect); gst_pad_set_link_function (tcpsink->sinkpad, gst_tcpsink_sink_link);
tcpsink->host = g_strdup (TCP_DEFAULT_HOST); tcpsink->host = g_strdup (TCP_DEFAULT_HOST);
tcpsink->port = TCP_DEFAULT_PORT; tcpsink->port = TCP_DEFAULT_PORT;

View file

@ -38,7 +38,8 @@ GST_DEBUG_CATEGORY_STATIC (type_find_debug);
/*** text/plain ****************************************************************/ /*** text/plain ****************************************************************/
#define UTF8_CAPS GST_CAPS_NEW ("cdxa_type_find", "text/plain", NULL) static GstStaticCaps utf8_caps = GST_STATIC_CAPS ("text/plain");
#define UTF8_CAPS gst_caps_copy(gst_static_caps_get(&utf8_caps))
static void static void
utf8_type_find (GstTypeFind *tf, gpointer unused) utf8_type_find (GstTypeFind *tf, gpointer unused)
{ {
@ -67,7 +68,8 @@ utf8_type_find (GstTypeFind *tf, gpointer unused)
/*** text/uri-list ************************************************************/ /*** text/uri-list ************************************************************/
#define URI_CAPS GST_CAPS_NEW ("uri_type_find", "text/uri-list", NULL) static GstStaticCaps uri_caps = GST_STATIC_CAPS ("text/uri-list");
#define URI_CAPS gst_caps_copy(gst_static_caps_get(&uri_caps))
#define BUFFER_SIZE 16 /* If the string is < 16 bytes we're screwed */ #define BUFFER_SIZE 16 /* If the string is < 16 bytes we're screwed */
#define INC_BUFFER { \ #define INC_BUFFER { \
pos++; \ pos++; \
@ -128,7 +130,8 @@ uri_type_find (GstTypeFind *tf, gpointer unused)
/*** video/x-fli **************************************************************/ /*** video/x-fli **************************************************************/
#define FLX_CAPS GST_CAPS_NEW ("flx_type_find", "video/x-fli", NULL) static GstStaticCaps flx_caps = GST_STATIC_CAPS ("video/x-fli");
#define FLX_CAPS gst_caps_copy(gst_static_caps_get(&flx_caps))
static void static void
flx_type_find (GstTypeFind *tf, gpointer unused) flx_type_find (GstTypeFind *tf, gpointer unused)
{ {
@ -158,7 +161,8 @@ flx_type_find (GstTypeFind *tf, gpointer unused)
/*** application/x-id3 **************************************************************/ /*** application/x-id3 **************************************************************/
#define ID3_CAPS GST_CAPS_NEW ("id3_type_find", "application/x-id3", NULL) static GstStaticCaps id3_caps = GST_STATIC_CAPS ("application/x-id3");
#define ID3_CAPS gst_caps_copy(gst_static_caps_get(&id3_caps))
static void static void
id3_type_find (GstTypeFind *tf, gpointer unused) id3_type_find (GstTypeFind *tf, gpointer unused)
{ {
@ -296,13 +300,9 @@ mp3_type_frame_length_from_header (guint32 header, guint *put_layer,
} }
#define MP3_CAPS(layer) (layer == 0 ? \ static GstStaticCaps mp3_caps = GST_STATIC_CAPS ("audio/mpeg, "
GST_CAPS_NEW ("mp3_type_find", "audio/mpeg", \ "mpegversion = (int) 1, layer = (int) [ 1, 3 ]");
"mpegversion", GST_PROPS_INT (1), \ #define MP3_CAPS gst_caps_copy(gst_static_caps_get(&mp3_caps))
"layer", GST_PROPS_INT_RANGE (1, 3)) : \
GST_CAPS_NEW ("mp3_type_find", "audio/mpeg", \
"mpegversion", GST_PROPS_INT (1), \
"layer", GST_PROPS_INT (layer)))
/* /*
* random values for typefinding * random values for typefinding
* if no more data is available, we will return a probability of * if no more data is available, we will return a probability of
@ -387,8 +387,12 @@ mp3_type_find (GstTypeFind *tf, gpointer unused)
} }
g_assert (probability <= GST_TYPE_FIND_MAXIMUM); g_assert (probability <= GST_TYPE_FIND_MAXIMUM);
if (probability > 0) { if (probability > 0) {
GstCaps *caps;
g_assert (layer > 0); g_assert (layer > 0);
gst_type_find_suggest (tf, probability, MP3_CAPS (layer)); caps = MP3_CAPS;
gst_structure_set (gst_caps_get_structure (caps, 0), "layer",
G_TYPE_INT, layer, 0);
gst_type_find_suggest (tf, probability, caps);
} }
return; return;
} }
@ -401,13 +405,9 @@ mp3_type_find (GstTypeFind *tf, gpointer unused)
/*** video/mpeg systemstream **************************************************/ /*** video/mpeg systemstream **************************************************/
#define MPEG_SYS_CAPS(version) (version == 0 ? \ static GstStaticCaps mpeg_sys_caps = GST_STATIC_CAPS ("video/mpeg, "
GST_CAPS_NEW ("mpeg_type_find", "video/mpeg", \ "systemstream = (boolean) true, mpegversion = (int) [ 1, 2 ]");
"systemstream", GST_PROPS_BOOLEAN (TRUE), \ #define MPEG_SYS_CAPS gst_caps_copy(gst_static_caps_get(&mpeg_sys_caps))
"mpegversion", GST_PROPS_INT_RANGE (1, 2)) : \
GST_CAPS_NEW ("mpeg_type_find", "video/mpeg", \
"systemstream", GST_PROPS_BOOLEAN (TRUE), \
"mpegversion", GST_PROPS_INT (version)))
#define IS_MPEG_HEADER(data) ((((guint8 *)data)[0] == 0x00) && \ #define IS_MPEG_HEADER(data) ((((guint8 *)data)[0] == 0x00) && \
(((guint8 *)data)[1] == 0x00) && \ (((guint8 *)data)[1] == 0x00) && \
(((guint8 *)data)[2] == 0x01) && \ (((guint8 *)data)[2] == 0x01) && \
@ -428,7 +428,11 @@ mpeg2_sys_type_find (GstTypeFind *tf, gpointer unused)
if (data && IS_MPEG_HEADER (data)) { if (data && IS_MPEG_HEADER (data)) {
if ((data[4] & 0xC0) == 0x40) { if ((data[4] & 0xC0) == 0x40) {
/* type 2 */ /* type 2 */
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MPEG_SYS_CAPS (2)); GstCaps *caps;
caps = MPEG_SYS_CAPS;
gst_structure_set (gst_caps_get_structure (caps, 0), "mpegversion",
G_TYPE_INT, 2, 0);
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, caps);
} }
} }
}; };
@ -515,6 +519,7 @@ mpeg1_sys_type_find (GstTypeFind *tf, gpointer unused)
guint8 *data = NULL; guint8 *data = NULL;
guint size = 0; guint size = 0;
guint64 skipped = 0; guint64 skipped = 0;
GstCaps *caps;
while (skipped < GST_MPEG_TYPEFIND_TRY_SYNC) { while (skipped < GST_MPEG_TYPEFIND_TRY_SYNC) {
if (size < 4) { if (size < 4) {
@ -546,7 +551,10 @@ mpeg1_sys_type_find (GstTypeFind *tf, gpointer unused)
if (probability < GST_TYPE_FIND_MINIMUM) if (probability < GST_TYPE_FIND_MINIMUM)
probability = GST_TYPE_FIND_MINIMUM; probability = GST_TYPE_FIND_MINIMUM;
g_assert (probability <= GST_TYPE_FIND_MAXIMUM); g_assert (probability <= GST_TYPE_FIND_MAXIMUM);
gst_type_find_suggest (tf, probability, MPEG_SYS_CAPS (1)); caps = MPEG_SYS_CAPS;
gst_structure_set (gst_caps_get_structure (caps, 0), "mpegversion",
G_TYPE_INT, 1, 0);
gst_type_find_suggest (tf, probability, caps);
return; return;
} }
} }
@ -558,9 +566,9 @@ mpeg1_sys_type_find (GstTypeFind *tf, gpointer unused)
/*** video/mpeg video stream **************************************************/ /*** video/mpeg video stream **************************************************/
#define MPEG_VIDEO_CAPS \ static GstStaticCaps mpeg_video_caps = GST_STATIC_CAPS ("video/mpeg, "
GST_CAPS_NEW ("mpeg_type_find", "video/mpeg", \ "systemstream = (boolean) false");
"systemstream", GST_PROPS_BOOLEAN (FALSE)) #define MPEG_VIDEO_CAPS gst_caps_copy(gst_static_caps_get(&mpeg_video_caps))
static void static void
mpeg_video_type_find (GstTypeFind *tf, gpointer unused) mpeg_video_type_find (GstTypeFind *tf, gpointer unused)
{ {
@ -576,7 +584,8 @@ mpeg_video_type_find (GstTypeFind *tf, gpointer unused)
/*** video/quicktime***********************************************************/ /*** video/quicktime***********************************************************/
#define QT_CAPS gst_caps_new ("qt_typefind", "video/quicktime", NULL) static GstStaticCaps qt_caps = GST_STATIC_CAPS ("video/quicktime");
#define QT_CAPS gst_caps_copy(gst_static_caps_get(&qt_caps))
static void static void
qt_type_find (GstTypeFind *tf, gpointer unused) qt_type_find (GstTypeFind *tf, gpointer unused)
{ {
@ -609,7 +618,8 @@ qt_type_find (GstTypeFind *tf, gpointer unused)
/*** audio/x-aiff *********************************************/ /*** audio/x-aiff *********************************************/
#define AIFF_CAPS GST_CAPS_NEW ("aiff_type_find", "audio/x-aiff", NULL) static GstStaticCaps aiff_caps = GST_STATIC_CAPS ("audio/x-aiff");
#define AIFF_CAPS gst_caps_copy(gst_static_caps_get(&aiff_caps))
static void static void
aiff_type_find (GstTypeFind *tf, gpointer unused) aiff_type_find (GstTypeFind *tf, gpointer unused)
{ {
@ -624,7 +634,8 @@ aiff_type_find (GstTypeFind *tf, gpointer unused)
/*** audio/x-shorten ****************************************/ /*** audio/x-shorten ****************************************/
#define SHN_CAPS GST_CAPS_NEW ("shn_type_find", "audio/x-shorten", NULL) static GstStaticCaps shn_caps = GST_STATIC_CAPS ("audio/x-shorten");
#define SHN_CAPS gst_caps_copy(gst_static_caps_get(&shn_caps))
static void static void
shn_type_find (GstTypeFind *tf, gpointer unused) shn_type_find (GstTypeFind *tf, gpointer unused)
{ {
@ -640,7 +651,8 @@ shn_type_find (GstTypeFind *tf, gpointer unused)
/*** audio/x-m4a *********************************************/ /*** audio/x-m4a *********************************************/
#define AAC_CAPS GST_CAPS_NEW ("m4a_type_find", "audio/x-m4a", NULL) static GstStaticCaps aac_caps = GST_STATIC_CAPS ("audio/x-m4a");
#define AAC_CAPS gst_caps_copy(gst_static_caps_get(&aac_caps))
static void static void
m4a_type_find (GstTypeFind *tf, gpointer unused) m4a_type_find (GstTypeFind *tf, gpointer unused)
{ {
@ -652,7 +664,8 @@ m4a_type_find (GstTypeFind *tf, gpointer unused)
/*** audio/x-mod *********************************************/ /*** audio/x-mod *********************************************/
#define MOD_CAPS gst_caps_new ("mod_type_find", "audio/x-mod", NULL) static GstStaticCaps mod_caps = GST_STATIC_CAPS ("audio/x-mod");
#define MOD_CAPS gst_caps_copy(gst_static_caps_get(&mod_caps))
/* FIXME: M15 CheckType to do */ /* FIXME: M15 CheckType to do */
static void static void
mod_type_find (GstTypeFind *tf, gpointer unused) mod_type_find (GstTypeFind *tf, gpointer unused)
@ -769,7 +782,8 @@ mod_type_find (GstTypeFind *tf, gpointer unused)
/*** application/x-shockwave-flash ********************************************/ /*** application/x-shockwave-flash ********************************************/
#define SWF_CAPS gst_caps_new ("swf_type_find", "application/x-shockwave-flash", NULL) static GstStaticCaps swf_caps = GST_STATIC_CAPS ("audio/x-shockwave-flash");
#define SWF_CAPS gst_caps_copy(gst_static_caps_get(&swf_caps))
static void static void
swf_type_find (GstTypeFind *tf, gpointer unused) swf_type_find (GstTypeFind *tf, gpointer unused)
{ {
@ -783,7 +797,8 @@ swf_type_find (GstTypeFind *tf, gpointer unused)
/*** image/jpeg ***************************************************************/ /*** image/jpeg ***************************************************************/
#define JPEG_CAPS gst_caps_new ("jpeg_type_find", "image/jpeg", NULL) static GstStaticCaps jpeg_caps = GST_STATIC_CAPS ("image/jpeg");
#define JPEG_CAPS gst_caps_copy(gst_static_caps_get(&jpeg_caps))
static void static void
jpeg_type_find (GstTypeFind *tf, gpointer unused) jpeg_type_find (GstTypeFind *tf, gpointer unused)
{ {
@ -802,7 +817,9 @@ jpeg_type_find (GstTypeFind *tf, gpointer unused)
} }
/*** image/bmp *********************/ /*** image/bmp *********************/
#define BMP_CAPS gst_caps_new ("bmp_type_find", "image/bmp", NULL)
static GstStaticCaps bmp_caps = GST_STATIC_CAPS ("image/bmp");
#define BMP_CAPS gst_caps_copy(gst_static_caps_get(&bmp_caps))
static void static void
bmp_type_find (GstTypeFind *tf, gpointer unused) bmp_type_find (GstTypeFind *tf, gpointer unused)
{ {
@ -821,12 +838,15 @@ bmp_type_find (GstTypeFind *tf, gpointer unused)
} }
/*** image/tiff ********************/ /*** image/tiff ********************/
#define TIFF_CAPS(endian) (endian == 0 ? \ static GstStaticCaps tiff_caps = GST_STATIC_CAPS ("image/tiff, "
GST_CAPS_NEW ("tiff_type_find", "image/tiff", \ "endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }" );
"endianness", GST_PROPS_LIST (GST_PROPS_INT ( \ #define TIFF_CAPS gst_caps_copy(gst_static_caps_get(&tiff_caps))
G_LITTLE_ENDIAN), GST_PROPS_INT (G_BIG_ENDIAN))) : \ static GstStaticCaps tiff_be_caps = GST_STATIC_CAPS ("image/tiff, "
GST_CAPS_NEW ("tiff_type_find", "image/tiff", \ "endianness = (int) BIG_ENDIAN");
"endianness", GST_PROPS_INT (endian))) #define TIFF_BE_CAPS gst_caps_copy(gst_static_caps_get(&tiff_be_caps))
static GstStaticCaps tiff_le_caps = GST_STATIC_CAPS ("image/tiff, "
"endianness = (int) LITTLE_ENDIAN");
#define TIFF_LE_CAPS gst_caps_copy(gst_static_caps_get(&tiff_le_caps))
static void static void
tiff_type_find (GstTypeFind *tf, gpointer ununsed) tiff_type_find (GstTypeFind *tf, gpointer ununsed)
{ {
@ -836,20 +856,18 @@ tiff_type_find (GstTypeFind *tf, gpointer ununsed)
if (data) { if (data) {
if (memcmp (data, le_header, 4) == 0) { if (memcmp (data, le_header, 4) == 0) {
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, TIFF_CAPS (G_LITTLE_ENDIAN)); gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, TIFF_LE_CAPS);
} else if (memcmp (data, be_header, 4) == 0) { } else if (memcmp (data, be_header, 4) == 0) {
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, TIFF_CAPS (G_BIG_ENDIAN)); gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, TIFF_BE_CAPS);
} }
} }
} }
/*** video/x-dv ***************************************************************/ /*** video/x-dv ***************************************************************/
#define DV_CAPS GST_CAPS_NEW ("dv_type_find", "video/x-dv", \ static GstStaticCaps dv_caps = GST_STATIC_CAPS ("video/x-dv, "
"systemstream", GST_PROPS_BOOLEAN (TRUE)) "systemstream = (boolean) true");
#define DV_CAPS_FORMAT(format) GST_CAPS_NEW ("dv_type_find", "video/x-dv", \ #define DV_CAPS gst_caps_copy(gst_static_caps_get(&dv_caps))
"systemstream", GST_PROPS_BOOLEAN (TRUE), \
"format", GST_PROPS_STRING(format))
static void static void
dv_type_find (GstTypeFind *tf, gpointer private) dv_type_find (GstTypeFind *tf, gpointer private)
{ {
@ -861,20 +879,24 @@ dv_type_find (GstTypeFind *tf, gpointer private)
if (data && (data[0] == 0x1f) && (data[1] == 0x07) && (data[2] == 0x00) && if (data && (data[0] == 0x1f) && (data[1] == 0x07) && (data[2] == 0x00) &&
((data[4]&0x01) == 0)){ ((data[4]&0x01) == 0)){
gchar *format; gchar *format;
GstCaps *caps = DV_CAPS;
if (data[3] & 0x80) { if (data[3] & 0x80) {
format = "PAL"; format = "PAL";
} else { } else {
format = "NTSC"; format = "NTSC";
} }
gst_structure_set (gst_caps_get_structure (caps, 0), "format",
G_TYPE_STRING, format, NULL);
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, DV_CAPS_FORMAT(format)); gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, caps);
} }
} }
/*** application/x-vorbis *****************************************************/ /*** application/x-vorbis *****************************************************/
#define VORBIS_CAPS GST_CAPS_NEW ("vorbis_type_find", "audio/x-vorbis", NULL) static GstStaticCaps vorbis_caps = GST_STATIC_CAPS ("audio/x-vorbis");
#define VORBIS_CAPS gst_caps_copy(gst_static_caps_get(&vorbis_caps))
static void static void
vorbis_type_find (GstTypeFind *tf, gpointer private) vorbis_type_find (GstTypeFind *tf, gpointer private)
{ {
@ -922,7 +944,8 @@ start_with_type_find (GstTypeFind *tf, gpointer private)
guint8 *data; guint8 *data;
GST_LOG ("trying to find mime type %s with the first %u bytes of data", GST_LOG ("trying to find mime type %s with the first %u bytes of data",
gst_caps_get_mime (start_with->caps), start_with->size); gst_structure_get_name (gst_caps_get_structure(start_with->caps, 0)),
start_with->size);
data = gst_type_find_peek (tf, 0, start_with->size); data = gst_type_find_peek (tf, 0, start_with->size);
if (data && memcmp (data, start_with->data, start_with->size)==0) { if (data && memcmp (data, start_with->data, start_with->size)==0) {
gst_type_find_suggest (tf, start_with->probability, start_with->caps); gst_type_find_suggest (tf, start_with->probability, start_with->caps);
@ -934,7 +957,7 @@ G_BEGIN_DECLS{ \
sw_data->data = _data; \ sw_data->data = _data; \
sw_data->size = _size; \ sw_data->size = _size; \
sw_data->probability = _probability; \ sw_data->probability = _probability; \
sw_data->caps = gst_caps_new ("start_with_caps", name, NULL); \ sw_data->caps = gst_caps_new_simple (name, NULL); \
TYPE_FIND_REGISTER (plugin, name, rank, start_with_type_find, \ TYPE_FIND_REGISTER (plugin, name, rank, start_with_type_find, \
ext, sw_data->caps, sw_data); \ ext, sw_data->caps, sw_data); \
}G_END_DECLS }G_END_DECLS
@ -959,7 +982,7 @@ G_BEGIN_DECLS{ \
sw_data->data = _data; \ sw_data->data = _data; \
sw_data->size = 4; \ sw_data->size = 4; \
sw_data->probability = GST_TYPE_FIND_MAXIMUM; \ sw_data->probability = GST_TYPE_FIND_MAXIMUM; \
sw_data->caps = gst_caps_new ("riff_caps", name, NULL); \ sw_data->caps = gst_caps_new_simple (name, NULL); \
TYPE_FIND_REGISTER (plugin, name, rank, riff_type_find, \ TYPE_FIND_REGISTER (plugin, name, rank, riff_type_find, \
ext, sw_data->caps, sw_data); \ ext, sw_data->caps, sw_data); \
}G_END_DECLS }G_END_DECLS
@ -1036,11 +1059,11 @@ plugin_init (GstPlugin *plugin)
TYPE_FIND_REGISTER (plugin, "audio/x-mod", GST_RANK_SECONDARY, TYPE_FIND_REGISTER (plugin, "audio/x-mod", GST_RANK_SECONDARY,
mod_type_find, mod_exts, MOD_CAPS, NULL); mod_type_find, mod_exts, MOD_CAPS, NULL);
TYPE_FIND_REGISTER (plugin, "audio/mpeg", GST_RANK_PRIMARY, TYPE_FIND_REGISTER (plugin, "audio/mpeg", GST_RANK_PRIMARY,
mp3_type_find, mp3_exts, MP3_CAPS (0), NULL); mp3_type_find, mp3_exts, MP3_CAPS, NULL);
TYPE_FIND_REGISTER (plugin, "video/mpeg1", GST_RANK_PRIMARY, TYPE_FIND_REGISTER (plugin, "video/mpeg1", GST_RANK_PRIMARY,
mpeg1_sys_type_find, mpeg_sys_exts, MPEG_SYS_CAPS (1), NULL); mpeg1_sys_type_find, mpeg_sys_exts, MPEG_SYS_CAPS, NULL);
TYPE_FIND_REGISTER (plugin, "video/mpeg2", GST_RANK_SECONDARY, TYPE_FIND_REGISTER (plugin, "video/mpeg2", GST_RANK_SECONDARY,
mpeg2_sys_type_find, mpeg_sys_exts, MPEG_SYS_CAPS (2), NULL); mpeg2_sys_type_find, mpeg_sys_exts, MPEG_SYS_CAPS, NULL);
TYPE_FIND_REGISTER_START_WITH (plugin, "application/ogg", GST_RANK_PRIMARY, TYPE_FIND_REGISTER_START_WITH (plugin, "application/ogg", GST_RANK_PRIMARY,
ogg_exts, "OggS", 4, GST_TYPE_FIND_MAXIMUM); ogg_exts, "OggS", 4, GST_TYPE_FIND_MAXIMUM);
TYPE_FIND_REGISTER (plugin, "video/mpeg", GST_RANK_SECONDARY, TYPE_FIND_REGISTER (plugin, "video/mpeg", GST_RANK_SECONDARY,
@ -1069,7 +1092,7 @@ plugin_init (GstPlugin *plugin)
TYPE_FIND_REGISTER (plugin, "image/bmp", GST_RANK_PRIMARY, TYPE_FIND_REGISTER (plugin, "image/bmp", GST_RANK_PRIMARY,
bmp_type_find, bmp_exts, BMP_CAPS, NULL); bmp_type_find, bmp_exts, BMP_CAPS, NULL);
TYPE_FIND_REGISTER (plugin, "image/tiff", GST_RANK_PRIMARY, TYPE_FIND_REGISTER (plugin, "image/tiff", GST_RANK_PRIMARY,
tiff_type_find, tiff_exts, TIFF_CAPS(0), NULL); tiff_type_find, tiff_exts, TIFF_CAPS, NULL);
TYPE_FIND_REGISTER_START_WITH (plugin, "video/x-matroska", GST_RANK_SECONDARY, TYPE_FIND_REGISTER_START_WITH (plugin, "video/x-matroska", GST_RANK_SECONDARY,
matroska_exts, "\032\105\337\243\223\102\202\210matroska", 16, GST_TYPE_FIND_MAXIMUM); matroska_exts, "\032\105\337\243\223\102\202\210matroska", 16, GST_TYPE_FIND_MAXIMUM);
TYPE_FIND_REGISTER (plugin, "video/x-dv", GST_RANK_SECONDARY, TYPE_FIND_REGISTER (plugin, "video/x-dv", GST_RANK_SECONDARY,

View file

@ -68,80 +68,30 @@ gst_videoscale_method_get_type (void)
static GstCaps * static GstCaps *
gst_videoscale_get_capslist(void) gst_videoscale_get_capslist(void)
{ {
static GstCaps *capslist = NULL;
GstCaps *caps; GstCaps *caps;
int i; int i;
if (capslist){ caps = gst_caps_new_empty();
gst_caps_ref(capslist);
return capslist;
}
for(i=0;i<videoscale_n_formats;i++){ for(i=0;i<videoscale_n_formats;i++){
caps = videoscale_get_caps(videoscale_formats + i); gst_caps_append_structure (caps,
capslist = gst_caps_append(capslist, caps); videoscale_get_structure (videoscale_formats + i));
} }
gst_caps_ref(capslist); return caps;
return capslist;
} }
static GstPadTemplate * static GstPadTemplate *
gst_videoscale_src_template_factory(void) gst_videoscale_src_template_factory(void)
{ {
static GstPadTemplate *templ = NULL; return gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
gst_videoscale_get_capslist());
if(!templ){
GstCaps *caps;
GstCaps *caps1 = GST_CAPS_NEW("src","video/x-raw-yuv",
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT));
GstCaps *caps2 = GST_CAPS_NEW("src","video/x-raw-rgb",
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT));
caps = gst_caps_intersect(caps1, gst_videoscale_get_capslist ());
gst_caps_unref (caps1);
caps1 = caps;
caps = gst_caps_intersect(caps2, gst_videoscale_get_capslist ());
gst_caps_unref (caps2);
caps2 = caps;
caps = gst_caps_append(caps1, caps2);
templ = GST_PAD_TEMPLATE_NEW("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps);
}
return templ;
} }
static GstPadTemplate * static GstPadTemplate *
gst_videoscale_sink_template_factory(void) gst_videoscale_sink_template_factory(void)
{ {
static GstPadTemplate *templ = NULL; return gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
gst_videoscale_get_capslist());
if(!templ){
GstCaps *caps;
GstCaps *caps1 = GST_CAPS_NEW("src","video/x-raw-yuv",
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT));
GstCaps *caps2 = GST_CAPS_NEW("src","video/x-raw-rgb",
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT));
caps = gst_caps_intersect(caps1, gst_videoscale_get_capslist ());
gst_caps_unref (caps1);
caps1 = caps;
caps = gst_caps_intersect(caps2, gst_videoscale_get_capslist ());
gst_caps_unref (caps2);
caps2 = caps;
caps = gst_caps_append(caps1, caps2);
templ = GST_PAD_TEMPLATE_NEW("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps);
}
return templ;
} }
static void gst_videoscale_base_init (gpointer g_class); static void gst_videoscale_base_init (gpointer g_class);
@ -186,8 +136,8 @@ gst_videoscale_base_init (gpointer g_class)
gst_element_class_set_details (element_class, &videoscale_details); gst_element_class_set_details (element_class, &videoscale_details);
gst_element_class_add_pad_template (element_class, GST_PAD_TEMPLATE_GET (gst_videoscale_sink_template_factory)); gst_element_class_add_pad_template (element_class, gst_videoscale_sink_template_factory());
gst_element_class_add_pad_template (element_class, GST_PAD_TEMPLATE_GET (gst_videoscale_src_template_factory)); gst_element_class_add_pad_template (element_class, gst_videoscale_src_template_factory());
} }
static void static void
gst_videoscale_class_init (GstVideoscaleClass *klass) gst_videoscale_class_init (GstVideoscaleClass *klass)
@ -210,16 +160,13 @@ gst_videoscale_class_init (GstVideoscaleClass *klass)
} }
static GstCaps * static GstCaps *
gst_videoscale_getcaps (GstPad *pad, GstCaps *caps) gst_videoscale_getcaps (GstPad *pad)
{ {
GstVideoscale *videoscale; GstVideoscale *videoscale;
//GstCaps *capslist = NULL;
GstCaps *peercaps; GstCaps *peercaps;
//GstCaps *sizecaps1, *sizecaps2; GstCaps *caps;
//GstCaps *sizecaps;
GstCaps *handled_caps;
GstCaps *icaps;
GstPad *otherpad; GstPad *otherpad;
int i;
GST_DEBUG ("gst_videoscale_getcaps"); GST_DEBUG ("gst_videoscale_getcaps");
videoscale = GST_VIDEOSCALE (gst_pad_get_parent (pad)); videoscale = GST_VIDEOSCALE (gst_pad_get_parent (pad));
@ -238,139 +185,64 @@ gst_videoscale_getcaps (GstPad *pad, GstCaps *caps)
} }
peercaps = gst_pad_get_allowed_caps (GST_PAD_PEER(otherpad)); peercaps = gst_pad_get_allowed_caps (GST_PAD_PEER(otherpad));
GST_DEBUG("othercaps are %s", gst_caps_to_string(peercaps)); GST_DEBUG_CAPS("othercaps are", peercaps);
{ caps = gst_caps_copy (peercaps);
GstCaps *caps1 = GST_CAPS_NEW("src","video/x-raw-yuv", for(i=0;i<gst_caps_get_size(caps);i++) {
"width", GST_PROPS_INT_RANGE (0, G_MAXINT), GstStructure *structure = gst_caps_get_structure (caps, i);
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT));
GstCaps *caps2 = GST_CAPS_NEW("src","video/x-raw-rgb",
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT));
caps = gst_caps_intersect(caps1, gst_videoscale_get_capslist ()); gst_structure_set (structure,
gst_caps_unref (caps1); "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
caps1 = caps; "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
caps = gst_caps_intersect(caps2, gst_videoscale_get_capslist ()); NULL);
gst_caps_unref (caps2);
caps2 = caps;
handled_caps = gst_caps_append(caps1, caps2);
} }
icaps = gst_caps_intersect (handled_caps, gst_caps_copy(peercaps)); GST_DEBUG_CAPS ("returning caps", caps);
GST_DEBUG("returning caps %s", gst_caps_to_string (icaps)); return caps;
return icaps;
} }
static GstPadLinkReturn static GstPadLinkReturn
gst_videoscale_link (GstPad *pad, GstCaps *caps) gst_videoscale_link (GstPad *pad, const GstCaps *caps)
{ {
GstVideoscale *videoscale; GstVideoscale *videoscale;
GstPadLinkReturn ret; GstPadLinkReturn ret;
GstCaps *othercaps; GstCaps *othercaps;
GstPad *otherpad; GstPad *otherpad;
GstCaps *icaps; GstStructure *structure;
GST_DEBUG ("gst_videoscale_link"); GST_DEBUG ("gst_videoscale_link");
videoscale = GST_VIDEOSCALE (gst_pad_get_parent (pad)); videoscale = GST_VIDEOSCALE (gst_pad_get_parent (pad));
if (!GST_CAPS_IS_FIXED (caps)) {
return GST_PAD_LINK_DELAYED;
}
if (pad == videoscale->srcpad) { if (pad == videoscale->srcpad) {
otherpad = videoscale->sinkpad; otherpad = videoscale->sinkpad;
} else { } else {
otherpad = videoscale->srcpad; otherpad = videoscale->srcpad;
} }
if (otherpad == NULL) {
return GST_PAD_LINK_DELAYED; ret = gst_pad_try_set_caps (otherpad, caps);
if (ret == GST_PAD_LINK_OK) {
/* cool, we can use passthru */
videoscale->passthru = TRUE;
return GST_PAD_LINK_OK;
} }
othercaps = GST_PAD_CAPS (otherpad); othercaps = GST_PAD_CAPS (otherpad);
if (othercaps) { structure = gst_caps_get_structure (caps, 0);
GstCaps *othercaps_wh;
GST_DEBUG ("otherpad caps are already set");
GST_DEBUG ("otherpad caps are %s", gst_caps_to_string(othercaps));
othercaps_wh = gst_caps_copy (othercaps);
gst_caps_set(othercaps_wh, "width", GST_PROPS_INT_RANGE (1, G_MAXINT),
"height", GST_PROPS_INT_RANGE (1, G_MAXINT), NULL);
#if 1
icaps = othercaps;
#else
/* FIXME this is disabled because videotestsrc ! videoscale ! ximagesink
* doesn't negotiate caps correctly the first time, so we pretend it's
* still ok here. */
icaps = gst_caps_intersect (othercaps_wh, caps);
GST_DEBUG ("intersected caps are %s", gst_caps_to_string(icaps));
if (icaps == NULL) {
/* the new caps are not compatible with the existing, set caps */
/* currently, we don't force renegotiation */
return GST_PAD_LINK_REFUSED;
}
#endif
if (!GST_CAPS_IS_FIXED (icaps)) {
return GST_PAD_LINK_REFUSED;
}
/* ok, we have a candidate caps */
} else {
GstCaps *othercaps_wh;
GST_DEBUG ("otherpad caps are unset");
othercaps = gst_pad_get_allowed_caps (pad);
othercaps_wh = gst_caps_copy (othercaps);
gst_caps_set(othercaps_wh, "width", GST_PROPS_INT_RANGE (1, G_MAXINT),
"height", GST_PROPS_INT_RANGE (1, G_MAXINT), NULL);
icaps = gst_caps_intersect (othercaps_wh, caps);
GST_DEBUG ("intersected caps are %s", gst_caps_to_string(icaps));
if (icaps == NULL) {
/* the new caps are not compatible with the existing, set caps */
/* currently, we don't force renegotiation */
return GST_PAD_LINK_REFUSED;
}
if (!GST_CAPS_IS_FIXED (icaps)) {
return GST_PAD_LINK_REFUSED;
}
/* ok, we have a candidate caps */
ret = gst_pad_try_set_caps (otherpad, gst_caps_copy(icaps));
if (ret == GST_PAD_LINK_DELAYED || ret == GST_PAD_LINK_REFUSED) {
return ret;
}
}
if (pad == videoscale->srcpad) { if (pad == videoscale->srcpad) {
gst_caps_get_int (icaps, "width", &videoscale->from_width); ret = gst_structure_get_int (structure, "width", &videoscale->to_width);
gst_caps_get_int (icaps, "height", &videoscale->from_height); ret &= gst_structure_get_int (structure, "height", &videoscale->to_height);
gst_caps_get_int (caps, "width", &videoscale->to_width);
gst_caps_get_int (caps, "height", &videoscale->to_height);
} else { } else {
gst_caps_get_int (icaps, "width", &videoscale->to_width); ret = gst_structure_get_int (structure, "width", &videoscale->from_width);
gst_caps_get_int (icaps, "height", &videoscale->to_height); ret &= gst_structure_get_int (structure, "height", &videoscale->from_height);
gst_caps_get_int (caps, "width", &videoscale->from_width);
gst_caps_get_int (caps, "height", &videoscale->from_height);
} }
videoscale->format = videoscale_find_by_caps (caps); if(!ret) return GST_PAD_LINK_REFUSED;
videoscale->format = videoscale_find_by_structure (structure);
gst_videoscale_setup(videoscale); gst_videoscale_setup(videoscale);
return GST_PAD_LINK_OK; return GST_PAD_LINK_OK;
@ -381,7 +253,7 @@ gst_videoscale_init (GstVideoscale *videoscale)
{ {
GST_DEBUG ("gst_videoscale_init"); GST_DEBUG ("gst_videoscale_init");
videoscale->sinkpad = gst_pad_new_from_template ( videoscale->sinkpad = gst_pad_new_from_template (
GST_PAD_TEMPLATE_GET (gst_videoscale_sink_template_factory), gst_videoscale_sink_template_factory(),
"sink"); "sink");
gst_element_add_pad(GST_ELEMENT(videoscale),videoscale->sinkpad); gst_element_add_pad(GST_ELEMENT(videoscale),videoscale->sinkpad);
gst_pad_set_chain_function(videoscale->sinkpad,gst_videoscale_chain); gst_pad_set_chain_function(videoscale->sinkpad,gst_videoscale_chain);
@ -389,7 +261,7 @@ gst_videoscale_init (GstVideoscale *videoscale)
gst_pad_set_getcaps_function(videoscale->sinkpad,gst_videoscale_getcaps); gst_pad_set_getcaps_function(videoscale->sinkpad,gst_videoscale_getcaps);
videoscale->srcpad = gst_pad_new_from_template ( videoscale->srcpad = gst_pad_new_from_template (
GST_PAD_TEMPLATE_GET (gst_videoscale_src_template_factory), gst_videoscale_src_template_factory(),
"src"); "src");
gst_element_add_pad(GST_ELEMENT(videoscale),videoscale->srcpad); gst_element_add_pad(GST_ELEMENT(videoscale),videoscale->srcpad);
gst_pad_set_link_function(videoscale->srcpad,gst_videoscale_link); gst_pad_set_link_function(videoscale->srcpad,gst_videoscale_link);
@ -448,7 +320,7 @@ gst_videoscale_chain (GstPad *pad, GstData *_data)
GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(buf); GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(buf);
g_return_if_fail(videoscale->format); g_return_if_fail(videoscale->format);
GST_DEBUG ("format %s",videoscale->format->fourcc); GST_DEBUG ("format " GST_FOURCC_FORMAT,GST_FOURCC_ARGS(videoscale->format->fourcc));
g_return_if_fail(videoscale->format->scale); g_return_if_fail(videoscale->format->scale);
videoscale->format->scale(videoscale, GST_BUFFER_DATA(outbuf), data); videoscale->format->scale(videoscale, GST_BUFFER_DATA(outbuf), data);

View file

@ -67,76 +67,115 @@ static void gst_videoscale_scale_nearest_24bit (GstVideoscale *scale,
static void gst_videoscale_scale_nearest_16bit (GstVideoscale *scale, static void gst_videoscale_scale_nearest_16bit (GstVideoscale *scale,
unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh); unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh);
#define fourcc_YUY2 GST_MAKE_FOURCC('Y','U','Y','2')
#define fourcc_UYVY GST_MAKE_FOURCC('U','Y','V','Y')
#define fourcc_Y422 GST_MAKE_FOURCC('Y','4','2','2')
#define fourcc_UYNV GST_MAKE_FOURCC('U','Y','N','V')
#define fourcc_YVYU GST_MAKE_FOURCC('Y','V','Y','U')
#define fourcc_YV12 GST_MAKE_FOURCC('Y','V','1','2')
#define fourcc_I420 GST_MAKE_FOURCC('I','4','2','0')
#define fourcc_Y800 GST_MAKE_FOURCC('Y','8','0','0')
#define fourcc_RGB_ GST_MAKE_FOURCC('R','G','B',' ')
struct videoscale_format_struct videoscale_formats[] = { struct videoscale_format_struct videoscale_formats[] = {
/* packed */ /* packed */
{ "YUY2", 16, gst_videoscale_packed422, }, { fourcc_YUY2, 16, gst_videoscale_packed422, },
{ "UYVY", 16, gst_videoscale_packed422rev, }, { fourcc_UYVY, 16, gst_videoscale_packed422rev, },
{ "Y422", 16, gst_videoscale_packed422rev, }, { fourcc_Y422, 16, gst_videoscale_packed422rev, },
{ "UYNV", 16, gst_videoscale_packed422rev, }, { fourcc_UYNV, 16, gst_videoscale_packed422rev, },
{ "YVYU", 16, gst_videoscale_packed422, }, { fourcc_YVYU, 16, gst_videoscale_packed422, },
/* planar */ /* planar */
{ "YV12", 12, gst_videoscale_planar411, }, { fourcc_YV12, 12, gst_videoscale_planar411, },
{ "I420", 12, gst_videoscale_planar411, }, { fourcc_I420, 12, gst_videoscale_planar411, },
{ "Y800", 8, gst_videoscale_planar400, }, { fourcc_Y800, 8, gst_videoscale_planar400, },
/* RGB */ /* RGB */
{ "RGB ", 32, gst_videoscale_32bit, 24, G_BIG_ENDIAN, 0x00ff0000, 0x0000ff00, 0x000000ff }, { fourcc_RGB_, 32, gst_videoscale_32bit, 24, G_BIG_ENDIAN, 0x00ff0000, 0x0000ff00, 0x000000ff },
{ "RGB ", 32, gst_videoscale_32bit, 24, G_BIG_ENDIAN, 0x000000ff, 0x0000ff00, 0x00ff0000 }, { fourcc_RGB_, 32, gst_videoscale_32bit, 24, G_BIG_ENDIAN, 0x000000ff, 0x0000ff00, 0x00ff0000 },
{ "RGB ", 32, gst_videoscale_32bit, 24, G_BIG_ENDIAN, 0xff000000, 0x00ff0000, 0x0000ff00 }, { fourcc_RGB_, 32, gst_videoscale_32bit, 24, G_BIG_ENDIAN, 0xff000000, 0x00ff0000, 0x0000ff00 },
{ "RGB ", 32, gst_videoscale_32bit, 24, G_BIG_ENDIAN, 0x0000ff00, 0x00ff0000, 0xff000000 }, { fourcc_RGB_, 32, gst_videoscale_32bit, 24, G_BIG_ENDIAN, 0x0000ff00, 0x00ff0000, 0xff000000 },
{ "RGB ", 24, gst_videoscale_24bit, 24, G_BIG_ENDIAN, 0xff0000, 0x00ff00, 0x0000ff }, { fourcc_RGB_, 24, gst_videoscale_24bit, 24, G_BIG_ENDIAN, 0xff0000, 0x00ff00, 0x0000ff },
{ "RGB ", 24, gst_videoscale_24bit, 24, G_BIG_ENDIAN, 0x0000ff, 0x00ff00, 0xff0000 }, { fourcc_RGB_, 24, gst_videoscale_24bit, 24, G_BIG_ENDIAN, 0x0000ff, 0x00ff00, 0xff0000 },
{ "RGB ", 16, gst_videoscale_16bit, 16, G_BYTE_ORDER, 0xf800, 0x07e0, 0x001f }, { fourcc_RGB_, 16, gst_videoscale_16bit, 16, G_BYTE_ORDER, 0xf800, 0x07e0, 0x001f },
{ "RGB ", 16, gst_videoscale_16bit, 15, G_BYTE_ORDER, 0x7c00, 0x03e0, 0x001f }, { fourcc_RGB_, 16, gst_videoscale_16bit, 15, G_BYTE_ORDER, 0x7c00, 0x03e0, 0x001f },
}; };
int videoscale_n_formats = sizeof(videoscale_formats)/sizeof(videoscale_formats[0]); int videoscale_n_formats = sizeof(videoscale_formats)/sizeof(videoscale_formats[0]);
GstCaps * GstStructure *
videoscale_get_caps(struct videoscale_format_struct *format) videoscale_get_structure (struct videoscale_format_struct *format)
{ {
unsigned int fourcc; GstStructure *structure;
GstCaps *caps;
if(format->scale==NULL) if(format->scale==NULL)
return NULL; return NULL;
fourcc = GST_MAKE_FOURCC(format->fourcc[0],format->fourcc[1],format->fourcc[2],format->fourcc[3]);
if(format->bpp){ if(format->bpp){
caps = GST_CAPS_NEW ("videoscale", "video/x-raw-rgb", structure = gst_structure_new ("video/x-raw-rgb",
"depth", GST_PROPS_INT(format->bpp), "depth", G_TYPE_INT, format->bpp,
"bpp", GST_PROPS_INT(format->depth), "bpp", G_TYPE_INT, format->depth,
"endianness", GST_PROPS_INT(format->endianness), "endianness", G_TYPE_INT, format->endianness,
"red_mask", GST_PROPS_INT(format->red_mask), "red_mask", G_TYPE_INT, format->red_mask,
"green_mask", GST_PROPS_INT(format->green_mask), "green_mask", G_TYPE_INT, format->green_mask,
"blue_mask", GST_PROPS_INT(format->blue_mask)); "blue_mask", G_TYPE_INT, format->blue_mask,
NULL);
}else{ }else{
caps = GST_CAPS_NEW ("videoscale", "video/x-raw-yuv", structure = gst_structure_new ("video/x-raw-yuv",
"format", GST_PROPS_FOURCC (fourcc)); "fourcc", GST_TYPE_FOURCC, format->fourcc, NULL);
} }
return caps; gst_structure_set(structure,
"width", GST_TYPE_INT_RANGE, 0, G_MAXINT,
"height", GST_TYPE_INT_RANGE, 0, G_MAXINT,
"framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE,
NULL);
return structure;
} }
struct videoscale_format_struct * struct videoscale_format_struct *
videoscale_find_by_caps(GstCaps *caps) videoscale_find_by_structure(GstStructure *structure)
{ {
int i; int i;
gboolean ret;
struct videoscale_format_struct *format;
GST_DEBUG ("finding %p",caps); GST_DEBUG ("finding %p",structure);
g_return_val_if_fail(caps != NULL, NULL); g_return_val_if_fail(structure != NULL, NULL);
for (i = 0; i < videoscale_n_formats; i++){ if(strcmp(gst_structure_get_name(structure),"video/x-raw-yuv")==0){
GstCaps *c; unsigned int fourcc;
c = videoscale_get_caps(videoscale_formats + i); ret = gst_structure_get_fourcc (structure, "format", &fourcc);
if(c){ if(!ret) return NULL;
if(gst_caps_is_always_compatible(caps, c)){ for (i = 0; i < videoscale_n_formats; i++){
gst_caps_unref(c); format = videoscale_formats + i;
return videoscale_formats + i; if(format->bpp==0 && format->fourcc == fourcc){
return format;
}
}
}else{
int bpp;
int depth;
int endianness;
int red_mask;
int green_mask;
int blue_mask;
ret = gst_structure_get_int (structure, "bpp", &bpp);
ret &= gst_structure_get_int (structure, "depth", &depth);
ret &= gst_structure_get_int (structure, "endianness", &endianness);
ret &= gst_structure_get_int (structure, "red_mask", &red_mask);
ret &= gst_structure_get_int (structure, "green_mask", &green_mask);
ret &= gst_structure_get_int (structure, "blue_mask", &blue_mask);
if(!ret) return NULL;
for (i = 0; i < videoscale_n_formats; i++){
format = videoscale_formats + i;
if(format->bpp == bpp && format->depth == depth &&
format->endianness == endianness && format->red_mask == red_mask &&
format->green_mask == green_mask && format->blue_mask == blue_mask) {
return format;
} }
gst_caps_unref(c);
} }
} }
@ -149,8 +188,8 @@ gst_videoscale_setup (GstVideoscale *videoscale)
g_return_if_fail (GST_IS_VIDEOSCALE (videoscale)); g_return_if_fail (GST_IS_VIDEOSCALE (videoscale));
g_return_if_fail (videoscale->format != NULL); g_return_if_fail (videoscale->format != NULL);
GST_DEBUG ("format=%p \"%s\" from %dx%d to %dx%d", GST_DEBUG ("format=%p " GST_FOURCC_FORMAT " from %dx%d to %dx%d",
videoscale->format, videoscale->format->fourcc, videoscale->format, GST_FOURCC_ARGS(videoscale->format->fourcc),
videoscale->from_width, videoscale->from_height, videoscale->from_width, videoscale->from_height,
videoscale->to_width, videoscale->to_height); videoscale->to_width, videoscale->to_height);

View file

@ -24,7 +24,7 @@
#include "gstvideoscale.h" #include "gstvideoscale.h"
struct videoscale_format_struct { struct videoscale_format_struct {
char *fourcc; unsigned int fourcc;
int depth; int depth;
void (*scale)(GstVideoscale *,unsigned char *dest, unsigned char *src); void (*scale)(GstVideoscale *,unsigned char *dest, unsigned char *src);
int bpp; int bpp;
@ -37,9 +37,9 @@ struct videoscale_format_struct {
extern struct videoscale_format_struct videoscale_formats[]; extern struct videoscale_format_struct videoscale_formats[];
extern int videoscale_n_formats; extern int videoscale_n_formats;
GstCaps *videoscale_get_caps(struct videoscale_format_struct *format); GstStructure *videoscale_get_structure(struct videoscale_format_struct *format);
struct videoscale_format_struct *videoscale_find_by_caps(GstCaps *caps); struct videoscale_format_struct *videoscale_find_by_structure (GstStructure *structure);
#endif #endif

View file

@ -81,22 +81,16 @@ static gboolean gst_videotestsrc_src_query (GstPad *pad,
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
static GstCaps * gst_videotestsrc_get_capslist (void); static GstCaps * gst_videotestsrc_get_capslist (void);
static GstCaps * gst_videotestsrc_get_capslist_size (int width, int height, float rate); #if 0
static GstCaps * gst_videotestsrc_get_capslist_size (int width, int height, double rate);
#endif
static GstPadTemplate * static GstPadTemplate *
videotestsrc_src_template_factory(void) gst_videotestsrc_src_template_factory(void)
{ {
static GstPadTemplate *templ = NULL; return gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
gst_videotestsrc_get_capslist());
if(!templ){
GstCaps *caps;
caps = gst_videotestsrc_get_capslist_size(0,0,0.0);
templ = GST_PAD_TEMPLATE_NEW("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps);
}
return templ;
} }
GType GType
@ -150,7 +144,7 @@ gst_videotestsrc_base_init (gpointer g_class)
gst_element_class_set_details (element_class, &videotestsrc_details); gst_element_class_set_details (element_class, &videotestsrc_details);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_GET (videotestsrc_src_template_factory)); gst_videotestsrc_src_template_factory());
} }
static void static void
gst_videotestsrc_class_init (GstVideotestsrcClass * klass) gst_videotestsrc_class_init (GstVideotestsrcClass * klass)
@ -171,8 +165,8 @@ gst_videotestsrc_class_init (GstVideotestsrcClass * klass)
g_param_spec_string ("fourcc", "fourcc", "fourcc", g_param_spec_string ("fourcc", "fourcc", "fourcc",
NULL, G_PARAM_READWRITE)); NULL, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_RATE, g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_RATE,
g_param_spec_float ("fps", "FPS", "Default frame rate", g_param_spec_double ("fps", "FPS", "Default frame rate",
0., G_MAXFLOAT, 30., G_PARAM_READWRITE)); 0., G_MAXDOUBLE, 30., G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TYPE, g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TYPE,
g_param_spec_enum ("pattern", "Pattern", "Type of test pattern to generate", g_param_spec_enum ("pattern", "Pattern", "Type of test pattern to generate",
GST_TYPE_VIDEOTESTSRC_PATTERN, 1, G_PARAM_READWRITE)); GST_TYPE_VIDEOTESTSRC_PATTERN, 1, G_PARAM_READWRITE));
@ -199,73 +193,68 @@ gst_videotestsrc_set_clock (GstElement *element, GstClock *clock)
gst_object_replace ((GstObject **)&v->clock, (GstObject *)clock); gst_object_replace ((GstObject **)&v->clock, (GstObject *)clock);
} }
static GstCaps *
gst_videotestsrc_src_fixate (GstPad * pad, const GstCaps * caps,
gpointer user_data)
{
GstStructure *structure;
GstCaps *newcaps;
/* FIXME this function isn't very intelligent in choosing "good" caps */
structure = gst_structure_copy(gst_caps_get_structure (caps, 0));
newcaps = gst_caps_new_full (structure, NULL);
if (gst_caps_get_size (caps) > 1) {
return newcaps;
}
if (gst_caps_structure_fixate_field_nearest_int (structure, "width", 320)) {
return newcaps;
}
if (gst_caps_structure_fixate_field_nearest_int (structure, "height", 240)) {
return newcaps;
}
if (gst_caps_structure_fixate_field_nearest_double (structure, "framerate",
30.0)) {
return newcaps;
}
/* failed to fixate */
gst_caps_free (newcaps);
return NULL;
}
static GstPadLinkReturn static GstPadLinkReturn
gst_videotestsrc_src_link (GstPad * pad, GstCaps * caps) gst_videotestsrc_src_link (GstPad * pad, const GstCaps * caps)
{ {
GstVideotestsrc *videotestsrc; GstVideotestsrc *videotestsrc;
GstCaps *caps1 = NULL; const GstStructure *structure;
GstPadLinkReturn ret;
GST_DEBUG ("gst_videotestsrc_src_link"); GST_DEBUG ("gst_videotestsrc_src_link");
videotestsrc = GST_VIDEOTESTSRC (gst_pad_get_parent (pad)); videotestsrc = GST_VIDEOTESTSRC (gst_pad_get_parent (pad));
for ( ; caps != NULL; caps = caps->next) { structure = gst_caps_get_structure (caps, 0);
GstPadLinkReturn ret;
caps1 = gst_caps_copy_1(caps); videotestsrc->fourcc = paintinfo_find_by_structure(structure);
if (!videotestsrc->fourcc) {
if(!gst_caps_has_fixed_property(caps1, "framerate")){ g_critical ("videotestsrc format not found\n");
gst_caps_set(caps1, "framerate", GST_PROPS_FLOAT(videotestsrc->default_rate));
}
if(!gst_caps_has_fixed_property(caps1, "width")){
gst_caps_set(caps1, "width", GST_PROPS_INT(videotestsrc->default_width));
}
if(!gst_caps_has_fixed_property(caps1, "height")){
gst_caps_set(caps1, "height", GST_PROPS_INT(videotestsrc->default_height));
}
gst_caps_ref(caps1);
gst_caps_sink(caps1);
ret = gst_pad_try_set_caps(pad, caps1);
if (ret != GST_PAD_LINK_OK &&
ret != GST_PAD_LINK_DONE) {
gst_caps_unref(caps1);
continue;
}
videotestsrc->fourcc = paintinfo_find_by_caps(caps1);
if (!videotestsrc->fourcc) {
gst_caps_unref(caps1);
continue;
}
/* if we get here, it's OK */
//gst_caps_unref(caps1);
break;
}
if (caps == NULL) {
GST_DEBUG ("videotestsrc: no suitable opposite-side caps found");
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
} }
g_return_val_if_fail(videotestsrc->fourcc, GST_PAD_LINK_REFUSED); ret = gst_structure_get_int (structure, "width", &videotestsrc->width);
ret &= gst_structure_get_int (structure, "height", &videotestsrc->height);
ret &= gst_structure_get_double (structure, "framerate",
&videotestsrc->rate);
//g_print ("videotestsrc: using fourcc element %p %s\n", if (!ret) return GST_PAD_LINK_REFUSED;
// videotestsrc->fourcc, videotestsrc->fourcc->name);
gst_caps_get_int (caps1, "width", &videotestsrc->width);
gst_caps_get_int (caps1, "height", &videotestsrc->height);
gst_caps_get_float (caps1, "framerate", &videotestsrc->rate);
videotestsrc->bpp = videotestsrc->fourcc->bitspp; videotestsrc->bpp = videotestsrc->fourcc->bitspp;
GST_DEBUG ("size %d x %d", videotestsrc->width, videotestsrc->height); GST_DEBUG ("size %d x %d", videotestsrc->width, videotestsrc->height);
videotestsrc->pool = gst_pad_get_bufferpool (videotestsrc->srcpad); return GST_PAD_LINK_OK;
return GST_PAD_LINK_DONE;
} }
static void static void
@ -274,10 +263,6 @@ gst_videotestsrc_src_unlink (GstPad * pad)
GstVideotestsrc *videotestsrc; GstVideotestsrc *videotestsrc;
videotestsrc = GST_VIDEOTESTSRC (gst_pad_get_parent (pad)); videotestsrc = GST_VIDEOTESTSRC (gst_pad_get_parent (pad));
if (videotestsrc->pool) {
gst_buffer_pool_unref (videotestsrc->pool);
}
} }
static GstElementStateReturn static GstElementStateReturn
@ -310,92 +295,53 @@ gst_videotestsrc_change_state (GstElement * element)
static GstCaps * static GstCaps *
gst_videotestsrc_get_capslist (void) gst_videotestsrc_get_capslist (void)
{ {
static GstCaps *capslist = NULL;
GstCaps *caps; GstCaps *caps;
GstStructure *structure;
int i; int i;
if(!capslist){ caps = gst_caps_new_empty();
for(i=0;i<n_fourccs;i++){ for(i=0;i<n_fourccs;i++){
caps = paint_get_caps(fourcc_list + i); structure = paint_get_structure (fourcc_list + i);
capslist = gst_caps_append(capslist, caps); gst_structure_set(structure,
} "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
"framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, NULL);
gst_caps_append_structure (caps, structure);
} }
g_return_val_if_fail(capslist->refcount > 0, NULL);
return gst_caps_ref(capslist);
}
static GstCaps *
gst_videotestsrc_get_capslist_size (int width, int height, float rate)
{
GstCaps *capslist;
GstCaps *caps;
GstCaps *caps_yuv_mask;
GstCaps *caps_rgb_mask;
GstCaps *caps_yuv;
GstCaps *caps_rgb;
caps_rgb_mask = GST_CAPS_NEW("src","video/x-raw-rgb",
"width", GST_PROPS_INT_RANGE (1, G_MAXINT),
"height", GST_PROPS_INT_RANGE (1, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT));
caps_yuv_mask = GST_CAPS_NEW("src","video/x-raw-yuv",
"width", GST_PROPS_INT_RANGE (1, G_MAXINT),
"height", GST_PROPS_INT_RANGE (1, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT));
if(height){
gst_caps_set(caps_rgb_mask, "height", GST_PROPS_INT(height));
gst_caps_set(caps_yuv_mask, "height", GST_PROPS_INT(height));
}
if(width){
gst_caps_set(caps_rgb_mask, "width", GST_PROPS_INT(width));
gst_caps_set(caps_yuv_mask, "width", GST_PROPS_INT(width));
}
if(rate > 0){
gst_caps_set(caps_rgb_mask, "framerate", GST_PROPS_FLOAT(rate));
gst_caps_set(caps_yuv_mask, "framerate", GST_PROPS_FLOAT(rate));
}
capslist = gst_videotestsrc_get_capslist ();
g_return_val_if_fail(capslist->refcount > 0, NULL);
caps_yuv = gst_caps_intersect(caps_yuv_mask, capslist);
caps_rgb = gst_caps_intersect(caps_rgb_mask, capslist);
caps = gst_caps_append(caps_yuv, caps_rgb);
//gst_caps_unref (capslist);
//gst_caps_unref (caps_yuv_mask);
//gst_caps_unref (caps_rgb_mask);
g_return_val_if_fail(caps->refcount > 0, NULL);
return caps; return caps;
} }
#if 0
static GstCaps * static GstCaps *
gst_videotestsrc_getcaps (GstPad * pad, GstCaps * caps) gst_videotestsrc_get_capslist_size (int width, int height, double rate)
{
GstCaps *caps;
GstStructure *structure;
int i;
caps = gst_caps_new_empty();
for(i=0;i<n_fourccs;i++){
structure = paint_get_structure (fourcc_list + i);
gst_structure_set(structure,
"width", G_TYPE_INT, width,
"height", G_TYPE_INT, height,
"framerate", G_TYPE_INT, rate, NULL);
gst_caps_append_structure (caps, structure);
}
return caps;
}
#endif
static GstCaps *
gst_videotestsrc_getcaps (GstPad * pad)
{ {
GstVideotestsrc *vts; GstVideotestsrc *vts;
vts = GST_VIDEOTESTSRC (gst_pad_get_parent (pad)); vts = GST_VIDEOTESTSRC (gst_pad_get_parent (pad));
#if 0 return gst_videotestsrc_get_capslist ();
if (vts->forced_format != NULL) {
struct fourcc_list_struct *fourcc;
fourcc = paintrect_find_name (vts->forced_format);
if (fourcc) {
caps1 = paint_get_caps(fourcc);
}
}
#endif
caps = gst_videotestsrc_get_capslist_size (vts->width, vts->height, vts->rate);
g_return_val_if_fail(caps->refcount > 0, NULL);
return caps;
} }
static void static void
@ -403,9 +349,10 @@ gst_videotestsrc_init (GstVideotestsrc * videotestsrc)
{ {
GST_DEBUG ("gst_videotestsrc_init"); GST_DEBUG ("gst_videotestsrc_init");
videotestsrc->srcpad = videotestsrc->srcpad = gst_pad_new_from_template (
gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (videotestsrc_src_template_factory), "src"); gst_videotestsrc_src_template_factory(), "src");
gst_pad_set_getcaps_function (videotestsrc->srcpad, gst_videotestsrc_getcaps); gst_pad_set_getcaps_function (videotestsrc->srcpad, gst_videotestsrc_getcaps);
gst_pad_set_fixate_function (videotestsrc->srcpad, gst_videotestsrc_src_fixate);
gst_element_add_pad (GST_ELEMENT (videotestsrc), videotestsrc->srcpad); gst_element_add_pad (GST_ELEMENT (videotestsrc), videotestsrc->srcpad);
gst_pad_set_get_function (videotestsrc->srcpad, gst_videotestsrc_get); gst_pad_set_get_function (videotestsrc->srcpad, gst_videotestsrc_get);
gst_pad_set_link_function (videotestsrc->srcpad, gst_videotestsrc_src_link); gst_pad_set_link_function (videotestsrc->srcpad, gst_videotestsrc_src_link);
@ -414,7 +361,6 @@ gst_videotestsrc_init (GstVideotestsrc * videotestsrc)
gst_pad_set_query_type_function (videotestsrc->srcpad, gst_pad_set_query_type_function (videotestsrc->srcpad,
gst_videotestsrc_get_query_types); gst_videotestsrc_get_query_types);
videotestsrc->pool = NULL;
gst_videotestsrc_set_pattern(videotestsrc, GST_VIDEOTESTSRC_SMPTE); gst_videotestsrc_set_pattern(videotestsrc, GST_VIDEOTESTSRC_SMPTE);
videotestsrc->sync = TRUE; videotestsrc->sync = TRUE;
@ -482,7 +428,7 @@ gst_videotestsrc_get (GstPad * pad)
videotestsrc = GST_VIDEOTESTSRC (gst_pad_get_parent (pad)); videotestsrc = GST_VIDEOTESTSRC (gst_pad_get_parent (pad));
if (!videotestsrc->fourcc) { if (videotestsrc->fourcc == NULL) {
gst_element_error (GST_ELEMENT (videotestsrc), gst_element_error (GST_ELEMENT (videotestsrc),
"No color format set - aborting"); "No color format set - aborting");
return NULL; return NULL;
@ -493,18 +439,7 @@ gst_videotestsrc_get (GstPad * pad)
GST_DEBUG ("size=%ld %dx%d", newsize, videotestsrc->width, videotestsrc->height); GST_DEBUG ("size=%ld %dx%d", newsize, videotestsrc->width, videotestsrc->height);
buf = NULL; buf = gst_buffer_new_and_alloc (newsize);
if (videotestsrc->pool) {
buf = gst_buffer_new_from_pool (videotestsrc->pool, 0, 0);
/* if the buffer we get is too small, make our own */
if (buf && GST_BUFFER_SIZE (buf) < newsize){
gst_buffer_unref (buf);
buf = NULL;
}
}
if (!buf) {
buf = gst_buffer_new_and_alloc (newsize);
}
g_return_val_if_fail (GST_BUFFER_DATA (buf) != NULL, NULL); g_return_val_if_fail (GST_BUFFER_DATA (buf) != NULL, NULL);
videotestsrc->make_image (videotestsrc, (void *) GST_BUFFER_DATA (buf), videotestsrc->make_image (videotestsrc, (void *) GST_BUFFER_DATA (buf),
@ -586,7 +521,7 @@ gst_videotestsrc_set_property (GObject * object, guint prop_id, const GValue * v
} }
break; break;
case ARG_RATE: case ARG_RATE:
src->default_rate = g_value_get_float (value); src->default_rate = g_value_get_double (value);
break; break;
case ARG_TYPE: case ARG_TYPE:
gst_videotestsrc_set_pattern (src, g_value_get_enum (value)); gst_videotestsrc_set_pattern (src, g_value_get_enum (value));
@ -619,7 +554,7 @@ gst_videotestsrc_get_property (GObject * object, guint prop_id, GValue * value,
g_value_set_string (value, src->forced_format); g_value_set_string (value, src->forced_format);
break; break;
case ARG_RATE: case ARG_RATE:
g_value_set_float (value, src->default_rate); g_value_set_double (value, src->default_rate);
break; break;
case ARG_TYPE: case ARG_TYPE:
g_value_set_enum (value, src->type); g_value_set_enum (value, src->type);

View file

@ -56,7 +56,7 @@ struct _GstVideotestsrc {
gint default_width; gint default_width;
gint default_height; gint default_height;
gboolean sync; gboolean sync;
gfloat default_rate; double default_rate;
/* video state */ /* video state */
char *format_name; char *format_name;
@ -69,12 +69,10 @@ struct _GstVideotestsrc {
gint64 timestamp_offset; gint64 timestamp_offset;
gint64 n_frames; gint64 n_frames;
gint bpp; gint bpp;
gfloat rate; gdouble rate;
int type; int type;
GstClock *clock; GstClock *clock;
GstBufferPool *pool;
void (*make_image)(GstVideotestsrc *v, unsigned char *dest, int w, int h); void (*make_image)(GstVideotestsrc *v, unsigned char *dest, int w, int h);
}; };
@ -82,7 +80,7 @@ struct _GstVideotestsrcClass {
GstElementClass parent_class; GstElementClass parent_class;
}; };
GType gst_videotestsrc_get_type(void); GType gst_videotestsrc_get_type(void) G_GNUC_CONST;
G_END_DECLS G_END_DECLS

View file

@ -385,17 +385,21 @@ struct fourcc_list_struct fourcc_list[] = {
}; };
int n_fourccs = sizeof (fourcc_list) / sizeof (fourcc_list[0]); int n_fourccs = sizeof (fourcc_list) / sizeof (fourcc_list[0]);
struct fourcc_list_struct *paintinfo_find_by_caps(GstCaps *caps) struct fourcc_list_struct *paintinfo_find_by_structure(const GstStructure *structure)
{ {
int i; int i;
const char *mimetype = gst_caps_get_mime(caps); const char *media_type = gst_structure_get_name(structure);
int ret;
if(strcmp(mimetype, "video/x-raw-yuv")==0){ g_return_val_if_fail (structure, NULL);
if(strcmp(media_type, "video/x-raw-yuv")==0){
char *s; char *s;
int fourcc; int fourcc;
guint32 format; guint32 format;
gst_caps_get(caps, "format", &format, NULL); ret = gst_structure_get_fourcc (structure, "format", &format);
if (!ret) return NULL;
for (i = 0; i < n_fourccs; i++) { for (i = 0; i < n_fourccs; i++) {
s = fourcc_list[i].fourcc; s = fourcc_list[i].fourcc;
//g_print("testing " GST_FOURCC_FORMAT " and %s\n", GST_FOURCC_ARGS(format), s); //g_print("testing " GST_FOURCC_FORMAT " and %s\n", GST_FOURCC_ARGS(format), s);
@ -404,19 +408,19 @@ struct fourcc_list_struct *paintinfo_find_by_caps(GstCaps *caps)
return fourcc_list + i; return fourcc_list + i;
} }
} }
}else if(strcmp(mimetype, "video/x-raw-rgb")==0){ }else if(strcmp(media_type, "video/x-raw-rgb")==0){
int red_mask; int red_mask;
int green_mask; int green_mask;
int blue_mask; int blue_mask;
int depth; int depth;
int bpp; int bpp;
gst_caps_get(caps, "red_mask", &red_mask, ret = gst_structure_get_int (structure, "red_mask", &red_mask);
"green_mask", &green_mask, ret &= gst_structure_get_int (structure, "green_mask", &green_mask);
"blue_mask", &blue_mask, ret &= gst_structure_get_int (structure, "blue_mask", &blue_mask);
"depth", &depth, ret &= gst_structure_get_int (structure, "depth", &depth);
"bpp", &bpp, ret &= gst_structure_get_int (structure, "bpp", &bpp);
NULL);
for (i = 0; i < n_fourccs; i++) { for (i = 0; i < n_fourccs; i++) {
if (strcmp(fourcc_list[i].fourcc, "RGB ") == 0 && if (strcmp(fourcc_list[i].fourcc, "RGB ") == 0 &&
fourcc_list[i].red_mask == red_mask && fourcc_list[i].red_mask == red_mask &&
@ -429,12 +433,9 @@ struct fourcc_list_struct *paintinfo_find_by_caps(GstCaps *caps)
} }
} }
return NULL; return NULL;
}else{
g_warning("unknown format");
return NULL;
} }
g_warning("format not found"); g_critical("format not found for media type %s", media_type);
return NULL; return NULL;
} }
@ -474,10 +475,9 @@ struct fourcc_list_struct * paintrect_find_name (const char *name)
} }
GstCaps *paint_get_caps(struct fourcc_list_struct *format) GstStructure *paint_get_structure(struct fourcc_list_struct *format)
{ {
unsigned int fourcc; unsigned int fourcc;
GstCaps *caps;
g_return_val_if_fail(format, NULL); g_return_val_if_fail(format, NULL);
@ -491,21 +491,19 @@ GstCaps *paint_get_caps(struct fourcc_list_struct *format)
}else{ }else{
endianness = G_BIG_ENDIAN; endianness = G_BIG_ENDIAN;
} }
caps = GST_CAPS_NEW ("videotestsrc_filter", return gst_structure_new ("video/x-raw-rgb",
"video/x-raw-rgb", "bpp", G_TYPE_INT, format->bitspp,
"bpp", GST_PROPS_INT(format->bitspp), "endianness", G_TYPE_INT, endianness,
"endianness", GST_PROPS_INT(endianness), "depth", G_TYPE_INT, format->depth,
"depth", GST_PROPS_INT(format->depth), "red_mask", G_TYPE_INT, format->red_mask,
"red_mask", GST_PROPS_INT(format->red_mask), "green_mask", G_TYPE_INT, format->green_mask,
"green_mask", GST_PROPS_INT(format->green_mask), "blue_mask", G_TYPE_INT, format->blue_mask,
"blue_mask", GST_PROPS_INT(format->blue_mask)); NULL);
}else{ }else{
caps = GST_CAPS_NEW ("videotestsrc_filter", return gst_structure_new ("video/x-raw-yuv",
"video/x-raw-yuv", "format", GST_TYPE_FOURCC, fourcc,
"format", GST_PROPS_FOURCC (fourcc)); NULL);
} }
return caps;
} }
void void

View file

@ -53,8 +53,9 @@ struct fourcc_list_struct
struct fourcc_list_struct * paintrect_find_fourcc (int find_fourcc); struct fourcc_list_struct * paintrect_find_fourcc (int find_fourcc);
struct fourcc_list_struct * paintrect_find_name (const char *name); struct fourcc_list_struct * paintrect_find_name (const char *name);
struct fourcc_list_struct *paintinfo_find_by_caps(GstCaps *caps); struct fourcc_list_struct *paintinfo_find_by_structure(
GstCaps *paint_get_caps(struct fourcc_list_struct *format); const GstStructure *structure);
GstStructure *paint_get_structure(struct fourcc_list_struct *format);
void gst_videotestsrc_smpte (GstVideotestsrc * v, unsigned char *dest, int w, int h); void gst_videotestsrc_smpte (GstVideotestsrc * v, unsigned char *dest, int w, int h);
void gst_videotestsrc_snow (GstVideotestsrc * v, unsigned char *dest, int w, int h); void gst_videotestsrc_snow (GstVideotestsrc * v, unsigned char *dest, int w, int h);
void gst_videotestsrc_black (GstVideotestsrc * v, unsigned char *dest, int w, int h); void gst_videotestsrc_black (GstVideotestsrc * v, unsigned char *dest, int w, int h);

View file

@ -1,9 +1,11 @@
plugin_LTLIBRARIES = libgstvolume.la # disabled, since I want to fix this by subclassing audiofilter
libgstvolume_la_SOURCES = gstvolume.c #plugin_LTLIBRARIES = libgstvolume.la
libgstvolume_la_CFLAGS = $(GST_CFLAGS)
libgstvolume_la_LIBADD = $(GST_LIBS) $(GST_CONTROL_LIBS)
libgstvolume_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = gstvolume.h filter.func #libgstvolume_la_SOURCES = gstvolume.c
#libgstvolume_la_CFLAGS = $(GST_CFLAGS)
#libgstvolume_la_LIBADD = $(GST_LIBS) $(GST_CONTROL_LIBS)
#libgstvolume_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
#noinst_HEADERS = gstvolume.h filter.func

View file

@ -50,7 +50,8 @@ enum {
ARG_VOLUME ARG_VOLUME
}; };
GST_PAD_TEMPLATE_FACTORY (volume_sink_factory, static GstStaticPadTemplate volume_sink_factory =
GST_STATIC_PAD_TEMPLATE (
"sink", "sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
@ -59,19 +60,20 @@ GST_PAD_TEMPLATE_FACTORY (volume_sink_factory,
"audio/x-raw-float", "audio/x-raw-float",
GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_PROPS GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_PROPS
), ),
GST_CAPS_NEW ( GST_STATIC_CAPS (
"volume_int_sink", "volume_int_sink",
"audio/x-raw-int", "audio/x-raw-int",
"channels", GST_PROPS_INT_RANGE (1, G_MAXINT), "channels", G_TYPE_INT_RANGE (1, G_MAXINT),
"rate", GST_PROPS_INT_RANGE (1, G_MAXINT), "rate", G_TYPE_INT_RANGE (1, G_MAXINT),
"endianness", GST_PROPS_INT (G_BYTE_ORDER), "endianness", G_TYPE_INT (G_BYTE_ORDER),
"width", GST_PROPS_INT (16), "width", G_TYPE_INT (16),
"depth", GST_PROPS_INT (16), "depth", G_TYPE_INT (16),
"signed", GST_PROPS_BOOLEAN (TRUE) "signed", G_TYPE_BOOLEAN (TRUE)
) )
); );
GST_PAD_TEMPLATE_FACTORY (volume_src_factory, static GstStaticPadTemplate volume_src_factory =
GST_STATIC_PAD_TEMPLATE (
"src", "src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
@ -80,15 +82,15 @@ GST_PAD_TEMPLATE_FACTORY (volume_src_factory,
"audio/x-raw-float", "audio/x-raw-float",
GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_PROPS GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_PROPS
), ),
GST_CAPS_NEW ( GST_STATIC_CAPS (
"volume_int_src", "volume_int_src",
"audio/x-raw-int", "audio/x-raw-int",
"channels", GST_PROPS_INT_RANGE (1, G_MAXINT), "channels", G_TYPE_INT_RANGE (1, G_MAXINT),
"rate", GST_PROPS_INT_RANGE (1, G_MAXINT), "rate", G_TYPE_INT_RANGE (1, G_MAXINT),
"endianness", GST_PROPS_INT (G_BYTE_ORDER), "endianness", G_TYPE_INT (G_BYTE_ORDER),
"width", GST_PROPS_INT (16), "width", G_TYPE_INT (16),
"depth", GST_PROPS_INT (16), "depth", G_TYPE_INT (16),
"signed", GST_PROPS_BOOLEAN (TRUE) "signed", G_TYPE_BOOLEAN (TRUE)
) )
); );
@ -109,16 +111,6 @@ static void volume_chain_int16 (GstPad *pad, GstData *_data);
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
/*static guint gst_filter_signals[LAST_SIGNAL] = { 0 }; */ /*static guint gst_filter_signals[LAST_SIGNAL] = { 0 }; */
static GstBufferPool*
volume_get_bufferpool (GstPad *pad)
{
GstVolume *filter;
filter = GST_VOLUME (gst_pad_get_parent (pad));
return gst_pad_get_bufferpool (filter->srcpad);
}
static GstPadLinkReturn static GstPadLinkReturn
volume_connect (GstPad *pad, GstCaps *caps) volume_connect (GstPad *pad, GstCaps *caps)
{ {
@ -137,7 +129,7 @@ volume_connect (GstPad *pad, GstCaps *caps)
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
if ((set_retval = gst_pad_try_set_caps(otherpad, caps)) > 0) if ((set_retval = gst_pad_try_set_caps(otherpad, caps)) > 0)
if (gst_caps_get_int (caps, "rate", &rate)){ if (gst_structure_get_int (structure, "rate", &rate)){
gst_dpman_set_rate(filter->dpman, rate); gst_dpman_set_rate(filter->dpman, rate);
} }
return set_retval; return set_retval;
@ -154,8 +146,7 @@ volume_parse_caps (GstVolume *filter, GstCaps *caps)
g_return_val_if_fail(filter!=NULL,FALSE); g_return_val_if_fail(filter!=NULL,FALSE);
g_return_val_if_fail(caps!=NULL,FALSE); g_return_val_if_fail(caps!=NULL,FALSE);
mimetype = gst_caps_get_mime (caps); mimetype = gst_structure_get_mime (structure
if (strcmp(mimetype, "audio/x-raw-int")==0) { if (strcmp(mimetype, "audio/x-raw-int")==0) {
gst_pad_set_chain_function(filter->sinkpad,volume_chain_int16); gst_pad_set_chain_function(filter->sinkpad,volume_chain_int16);
return TRUE; return TRUE;
@ -227,7 +218,6 @@ volume_init (GstVolume *filter)
{ {
filter->sinkpad = gst_pad_new_from_template(volume_sink_factory (),"sink"); filter->sinkpad = gst_pad_new_from_template(volume_sink_factory (),"sink");
gst_pad_set_link_function(filter->sinkpad,volume_connect); gst_pad_set_link_function(filter->sinkpad,volume_connect);
gst_pad_set_bufferpool_function(filter->sinkpad,volume_get_bufferpool);
filter->srcpad = gst_pad_new_from_template(volume_src_factory (),"src"); filter->srcpad = gst_pad_new_from_template(volume_src_factory (),"src");
gst_pad_set_link_function(filter->srcpad,volume_connect); gst_pad_set_link_function(filter->srcpad,volume_connect);

View file

@ -56,7 +56,7 @@ static void gst_v4lmjpegsink_init (GstV4lMjpegSink
/* the chain of buffers */ /* the chain of buffers */
static GstPadLinkReturn gst_v4lmjpegsink_sinkconnect (GstPad *pad, static GstPadLinkReturn gst_v4lmjpegsink_sinkconnect (GstPad *pad,
GstCaps *vscapslist); const GstCaps *vscapslist);
static void gst_v4lmjpegsink_chain (GstPad *pad, static void gst_v4lmjpegsink_chain (GstPad *pad,
GstData *_data); GstData *_data);
@ -72,14 +72,7 @@ static void gst_v4lmjpegsink_get_property (GObject
static GstElementStateReturn gst_v4lmjpegsink_change_state (GstElement *element); static GstElementStateReturn gst_v4lmjpegsink_change_state (GstElement *element);
static void gst_v4lmjpegsink_set_clock (GstElement *element, GstClock *clock); static void gst_v4lmjpegsink_set_clock (GstElement *element, GstClock *clock);
/* bufferpool functions */
static GstBuffer* gst_v4lmjpegsink_buffer_new (GstBufferPool *pool,
guint64 offset,
guint size,
gpointer user_data);
static GstCaps *capslist = NULL;
static GstPadTemplate *sink_template; static GstPadTemplate *sink_template;
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
@ -111,28 +104,21 @@ gst_v4lmjpegsink_get_type (void)
static void static void
gst_v4lmjpegsink_base_init (gpointer g_class) gst_v4lmjpegsink_base_init (gpointer g_class)
{ {
GstCaps *caps; static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-jpeg, "
"width = (int) [ 1, MAX ], "
"height = (int) [ 1, MAX ], "
"framerate = (double) [ 0, MAX ]")
);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_v4lmjpegsink_details); gst_element_class_set_details (gstelement_class, &gst_v4lmjpegsink_details);
caps = gst_caps_new ("v4lmjpegsink_caps", gst_element_class_add_pad_template (gstelement_class,
"video/x-jpeg", gst_static_pad_template_get(&sink_template));
gst_props_new (
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT),
NULL )
);
capslist = gst_caps_append(capslist, caps);
sink_template = gst_pad_template_new (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
capslist, NULL);
gst_element_class_add_pad_template (gstelement_class, sink_template);
} }
static void static void
gst_v4lmjpegsink_class_init (GstV4lMjpegSinkClass *klass) gst_v4lmjpegsink_class_init (GstV4lMjpegSinkClass *klass)
@ -200,59 +186,44 @@ gst_v4lmjpegsink_init (GstV4lMjpegSink *v4lmjpegsink)
v4lmjpegsink->bufsize = 256; v4lmjpegsink->bufsize = 256;
GST_FLAG_SET(v4lmjpegsink, GST_ELEMENT_THREAD_SUGGESTED); GST_FLAG_SET(v4lmjpegsink, GST_ELEMENT_THREAD_SUGGESTED);
v4lmjpegsink->bufferpool = gst_buffer_pool_new(
NULL,
NULL,
(GstBufferPoolBufferNewFunction)gst_v4lmjpegsink_buffer_new,
NULL,
NULL,
v4lmjpegsink);
} }
static GstPadLinkReturn static GstPadLinkReturn
gst_v4lmjpegsink_sinkconnect (GstPad *pad, gst_v4lmjpegsink_sinkconnect (GstPad *pad,
GstCaps *vscapslist) const GstCaps *vscapslist)
{ {
GstV4lMjpegSink *v4lmjpegsink; GstV4lMjpegSink *v4lmjpegsink;
GstCaps *caps; GstStructure *structure;
v4lmjpegsink = GST_V4LMJPEGSINK (gst_pad_get_parent (pad)); v4lmjpegsink = GST_V4LMJPEGSINK (gst_pad_get_parent (pad));
/* we are not going to act on variable caps */
if (!GST_CAPS_IS_FIXED (vscapslist) || !GST_V4L_IS_OPEN(GST_V4LELEMENT(v4lmjpegsink)))
return GST_PAD_LINK_DELAYED;
/* in case the buffers are active (which means that we already /* in case the buffers are active (which means that we already
* did capsnego before and didn't clean up), clean up anyways */ * did capsnego before and didn't clean up), clean up anyways */
if (GST_V4L_IS_ACTIVE(GST_V4LELEMENT(v4lmjpegsink))) if (GST_V4L_IS_ACTIVE(GST_V4LELEMENT(v4lmjpegsink)))
if (!gst_v4lmjpegsink_playback_deinit(v4lmjpegsink)) if (!gst_v4lmjpegsink_playback_deinit(v4lmjpegsink))
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
for (caps = vscapslist; caps != NULL; caps = vscapslist = vscapslist->next) structure = gst_caps_get_structure (vscapslist, 0);
{
gst_caps_get_int (caps, "width", &v4lmjpegsink->width);
gst_caps_get_int (caps, "height", &v4lmjpegsink->height);
if (!gst_v4lmjpegsink_set_playback(v4lmjpegsink, gst_structure_get_int (structure, "width", &v4lmjpegsink->width);
v4lmjpegsink->width, v4lmjpegsink->height, gst_structure_get_int (structure, "height", &v4lmjpegsink->height);
v4lmjpegsink->x_offset, v4lmjpegsink->y_offset,
GST_V4LELEMENT(v4lmjpegsink)->vchan.norm, 0)) /* TODO: interlacing */
continue;
/* set buffer info */ if (!gst_v4lmjpegsink_set_playback(v4lmjpegsink,
if (!gst_v4lmjpegsink_set_buffer(v4lmjpegsink, v4lmjpegsink->width, v4lmjpegsink->height,
v4lmjpegsink->numbufs, v4lmjpegsink->bufsize)) v4lmjpegsink->x_offset, v4lmjpegsink->y_offset,
continue; GST_V4LELEMENT(v4lmjpegsink)->vchan.norm, 0)) /* TODO: interlacing */
if (!gst_v4lmjpegsink_playback_init(v4lmjpegsink)) return GST_PAD_LINK_REFUSED;
continue;
return GST_PAD_LINK_OK; /* set buffer info */
} if (!gst_v4lmjpegsink_set_buffer(v4lmjpegsink,
v4lmjpegsink->numbufs, v4lmjpegsink->bufsize))
return GST_PAD_LINK_REFUSED;
if (!gst_v4lmjpegsink_playback_init(v4lmjpegsink))
return GST_PAD_LINK_REFUSED;
return GST_PAD_LINK_OK;
/* if we got here - it's not good */
return GST_PAD_LINK_REFUSED;
} }
@ -295,6 +266,7 @@ gst_v4lmjpegsink_chain (GstPad *pad,
gst_clock_id_free (id); gst_clock_id_free (id);
} }
#if 0
if (GST_BUFFER_POOL(buf) == v4lmjpegsink->bufferpool) if (GST_BUFFER_POOL(buf) == v4lmjpegsink->bufferpool)
{ {
num = GPOINTER_TO_INT(GST_BUFFER_POOL_PRIVATE(buf)); num = GPOINTER_TO_INT(GST_BUFFER_POOL_PRIVATE(buf));
@ -302,6 +274,7 @@ gst_v4lmjpegsink_chain (GstPad *pad,
} }
else else
{ {
#endif
/* check size */ /* check size */
if (GST_BUFFER_SIZE(buf) > v4lmjpegsink->breq.size) if (GST_BUFFER_SIZE(buf) > v4lmjpegsink->breq.size)
{ {
@ -316,7 +289,9 @@ gst_v4lmjpegsink_chain (GstPad *pad,
memcpy(gst_v4lmjpegsink_get_buffer(v4lmjpegsink, num), memcpy(gst_v4lmjpegsink_get_buffer(v4lmjpegsink, num),
GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf)); GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf));
gst_v4lmjpegsink_play_frame(v4lmjpegsink, num); gst_v4lmjpegsink_play_frame(v4lmjpegsink, num);
#if 0
} }
#endif
g_signal_emit(G_OBJECT(v4lmjpegsink),gst_v4lmjpegsink_signals[SIGNAL_FRAME_DISPLAYED],0); g_signal_emit(G_OBJECT(v4lmjpegsink),gst_v4lmjpegsink_signals[SIGNAL_FRAME_DISPLAYED],0);
@ -324,6 +299,7 @@ gst_v4lmjpegsink_chain (GstPad *pad,
} }
#if 0
static GstBuffer * static GstBuffer *
gst_v4lmjpegsink_buffer_new (GstBufferPool *pool, gst_v4lmjpegsink_buffer_new (GstBufferPool *pool,
guint64 offset, guint64 offset,
@ -359,6 +335,7 @@ gst_v4lmjpegsink_buffer_new (GstBufferPool *pool,
return buffer; return buffer;
} }
#endif
static void static void

View file

@ -66,9 +66,6 @@ struct _GstV4lMjpegSink {
GCond **cond_queued_frames; GCond **cond_queued_frames;
gint current_frame; gint current_frame;
/* something to get our buffers from */
GstBufferPool *bufferpool;
/* width/height/norm of the jpeg stream */ /* width/height/norm of the jpeg stream */
gint width; gint width;
gint height; gint height;

View file

@ -81,10 +81,9 @@ static gboolean gst_v4lmjpegsrc_src_query (GstPad *pad,
/* buffer functions */ /* buffer functions */
static GstPadLinkReturn gst_v4lmjpegsrc_srcconnect (GstPad *pad, static GstPadLinkReturn gst_v4lmjpegsrc_srcconnect (GstPad *pad,
GstCaps *caps); const GstCaps *caps);
static GstData* gst_v4lmjpegsrc_get (GstPad *pad); static GstData* gst_v4lmjpegsrc_get (GstPad *pad);
static GstCaps* gst_v4lmjpegsrc_getcaps (GstPad *pad, static GstCaps* gst_v4lmjpegsrc_getcaps (GstPad *pad);
GstCaps *caps);
/* get/set params */ /* get/set params */
static void gst_v4lmjpegsrc_set_property (GObject *object, static void gst_v4lmjpegsrc_set_property (GObject *object,
@ -103,17 +102,7 @@ static void gst_v4lmjpegsrc_set_clock (GstElement *eleme
/* state handling */ /* state handling */
static GstElementStateReturn gst_v4lmjpegsrc_change_state (GstElement *element); static GstElementStateReturn gst_v4lmjpegsrc_change_state (GstElement *element);
/* bufferpool functions */
static GstBuffer* gst_v4lmjpegsrc_buffer_new (GstBufferPool *pool,
guint64 offset,
guint size,
gpointer user_data);
static void gst_v4lmjpegsrc_buffer_free (GstBufferPool *pool,
GstBuffer *buf,
gpointer user_data);
static GstCaps *capslist = NULL;
static GstPadTemplate *src_template; static GstPadTemplate *src_template;
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
@ -147,28 +136,22 @@ gst_v4lmjpegsrc_get_type (void)
static void static void
gst_v4lmjpegsrc_base_init (gpointer g_class) gst_v4lmjpegsrc_base_init (gpointer g_class)
{ {
GstCaps *caps; static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-jpeg, "
"width = (int) [ 0, MAX ], "
"height = (int) [ 0, MAX ], "
"framerate = (double) [ 0, MAX ]"
)
);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (gstelement_class, &gst_v4lmjpegsrc_details); gst_element_class_set_details (gstelement_class, &gst_v4lmjpegsrc_details);
caps = gst_caps_new ("v4lmjpegsrc_caps", gst_element_class_add_pad_template (gstelement_class,
"video/x-jpeg", gst_static_pad_template_get (&src_template));
gst_props_new (
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
"height", GST_PROPS_INT_RANGE (0, G_MAXINT),
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT),
NULL )
);
capslist = gst_caps_append(capslist, caps);
src_template = gst_pad_template_new (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
capslist, NULL);
gst_element_class_add_pad_template (gstelement_class, src_template);
} }
static void static void
gst_v4lmjpegsrc_class_init (GstV4lMjpegSrcClass *klass) gst_v4lmjpegsrc_class_init (GstV4lMjpegSrcClass *klass)
@ -260,14 +243,6 @@ gst_v4lmjpegsrc_init (GstV4lMjpegSrc *v4lmjpegsrc)
gst_pad_set_query_function (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_src_query); gst_pad_set_query_function (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_src_query);
gst_pad_set_query_type_function (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_get_query_types); gst_pad_set_query_type_function (v4lmjpegsrc->srcpad, gst_v4lmjpegsrc_get_query_types);
v4lmjpegsrc->bufferpool = gst_buffer_pool_new(
NULL,
NULL,
(GstBufferPoolBufferNewFunction)gst_v4lmjpegsrc_buffer_new,
NULL,
(GstBufferPoolBufferFreeFunction)gst_v4lmjpegsrc_buffer_free,
v4lmjpegsrc);
#if 0 #if 0
v4lmjpegsrc->frame_width = 0; v4lmjpegsrc->frame_width = 0;
v4lmjpegsrc->frame_height = 0; v4lmjpegsrc->frame_height = 0;
@ -416,7 +391,7 @@ calc_bufsize (int hor_dec,
return result; return result;
} }
#define gst_caps_get_int_range(caps, name, min, max) \ #define gst_structure_get_int_range (structure, name, min, max) \
gst_props_entry_get_int_range(gst_props_get_entry((caps)->properties, \ gst_props_entry_get_int_range(gst_props_get_entry((caps)->properties, \
name), \ name), \
min, max) min, max)
@ -424,16 +399,15 @@ calc_bufsize (int hor_dec,
static GstPadLinkReturn static GstPadLinkReturn
gst_v4lmjpegsrc_srcconnect (GstPad *pad, gst_v4lmjpegsrc_srcconnect (GstPad *pad,
GstCaps *caps) const GstCaps *caps)
{ {
GstPadLinkReturn ret_val;
GstV4lMjpegSrc *v4lmjpegsrc = GST_V4LMJPEGSRC(gst_pad_get_parent(pad)); GstV4lMjpegSrc *v4lmjpegsrc = GST_V4LMJPEGSRC(gst_pad_get_parent(pad));
gint hor_dec, ver_dec; gint hor_dec, ver_dec;
gint w, h; gint w, h;
gint max_w = GST_V4LELEMENT(v4lmjpegsrc)->vcap.maxwidth, gint max_w = GST_V4LELEMENT(v4lmjpegsrc)->vcap.maxwidth,
max_h = GST_V4LELEMENT(v4lmjpegsrc)->vcap.maxheight; max_h = GST_V4LELEMENT(v4lmjpegsrc)->vcap.maxheight;
gulong bufsize; gulong bufsize;
gfloat fps = gst_v4lmjpegsrc_get_fps(v4lmjpegsrc); GstStructure *structure;
/* in case the buffers are active (which means that we already /* in case the buffers are active (which means that we already
* did capsnego before and didn't clean up), clean up anyways */ * did capsnego before and didn't clean up), clean up anyways */
@ -453,22 +427,9 @@ gst_v4lmjpegsrc_srcconnect (GstPad *pad,
* our own mime type back and it'll work. Other properties are to be set * our own mime type back and it'll work. Other properties are to be set
* by the src, not by the opposite caps */ * by the src, not by the opposite caps */
if (gst_caps_has_property(caps, "width")) { structure = gst_caps_get_structure (caps, 0);
if (gst_caps_has_fixed_property(caps, "width")) { gst_structure_get_int (structure, "width", &w);
gst_caps_get_int(caps, "width", &w); gst_structure_get_int (structure, "height", &h);
} else {
int max;
gst_caps_get_int_range(caps, "width", &max, &w);
}
}
if (gst_caps_has_property(caps, "height")) {
if (gst_caps_has_fixed_property(caps, "height")) {
gst_caps_get_int(caps, "height", &h);
} else {
int max;
gst_caps_get_int_range(caps, "height", &max, &h);
}
}
/* figure out decimation */ /* figure out decimation */
if (w >= max_w) { if (w >= max_w) {
@ -530,23 +491,7 @@ gst_v4lmjpegsrc_srcconnect (GstPad *pad,
} }
#endif #endif
/* we now have an actual width/height - *set it* */ return GST_PAD_LINK_OK;
caps = gst_caps_new("v4lmjpegsrc_caps",
"video/x-jpeg",
gst_props_new(
"width", GST_PROPS_INT(v4lmjpegsrc->end_width),
"height", GST_PROPS_INT(v4lmjpegsrc->end_height),
"framerate", GST_PROPS_FLOAT(fps),
NULL ) );
if ((ret_val = gst_pad_try_set_caps(v4lmjpegsrc->srcpad, caps)) == GST_PAD_LINK_REFUSED)
return GST_PAD_LINK_REFUSED;
else if (ret_val == GST_PAD_LINK_DELAYED)
return GST_PAD_LINK_DELAYED;
if (!gst_v4lmjpegsrc_capture_init(v4lmjpegsrc))
return GST_PAD_LINK_REFUSED;
return GST_PAD_LINK_DONE;
} }
@ -566,14 +511,6 @@ gst_v4lmjpegsrc_get (GstPad *pad)
(fps = gst_v4lmjpegsrc_get_fps(v4lmjpegsrc)) == 0) (fps = gst_v4lmjpegsrc_get_fps(v4lmjpegsrc)) == 0)
return NULL; return NULL;
buf = gst_buffer_new_from_pool(v4lmjpegsrc->bufferpool, 0, 0);
if (!buf)
{
gst_element_error(GST_ELEMENT(v4lmjpegsrc),
"Failed to create a new GstBuffer");
return NULL;
}
if (v4lmjpegsrc->need_writes > 0) { if (v4lmjpegsrc->need_writes > 0) {
/* use last frame */ /* use last frame */
num = v4lmjpegsrc->last_frame; num = v4lmjpegsrc->last_frame;
@ -643,8 +580,10 @@ gst_v4lmjpegsrc_get (GstPad *pad)
v4lmjpegsrc->use_num_times[num] = 1; v4lmjpegsrc->use_num_times[num] = 1;
} }
buf = gst_buffer_new ();
GST_BUFFER_DATA(buf) = gst_v4lmjpegsrc_get_buffer(v4lmjpegsrc, num); GST_BUFFER_DATA(buf) = gst_v4lmjpegsrc_get_buffer(v4lmjpegsrc, num);
GST_BUFFER_SIZE(buf) = v4lmjpegsrc->last_size; GST_BUFFER_SIZE(buf) = v4lmjpegsrc->last_size;
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_READONLY);
if (v4lmjpegsrc->use_fixed_fps) if (v4lmjpegsrc->use_fixed_fps)
GST_BUFFER_TIMESTAMP(buf) = v4lmjpegsrc->handled * GST_SECOND / fps; GST_BUFFER_TIMESTAMP(buf) = v4lmjpegsrc->handled * GST_SECOND / fps;
else /* calculate time based on our own clock */ else /* calculate time based on our own clock */
@ -660,27 +599,20 @@ gst_v4lmjpegsrc_get (GstPad *pad)
static GstCaps* static GstCaps*
gst_v4lmjpegsrc_getcaps (GstPad *pad, gst_v4lmjpegsrc_getcaps (GstPad *pad)
GstCaps *_caps)
{ {
GstV4lMjpegSrc *v4lmjpegsrc = GST_V4LMJPEGSRC(gst_pad_get_parent(pad)); GstV4lMjpegSrc *v4lmjpegsrc = GST_V4LMJPEGSRC(gst_pad_get_parent(pad));
struct video_capability *vcap = &GST_V4LELEMENT(v4lmjpegsrc)->vcap; struct video_capability *vcap = &GST_V4LELEMENT(v4lmjpegsrc)->vcap;
GstCaps *caps;
if (!GST_V4L_IS_OPEN(GST_V4LELEMENT(v4lmjpegsrc))) { if (!GST_V4L_IS_OPEN(GST_V4LELEMENT(v4lmjpegsrc))) {
return NULL; return NULL;
} }
caps = GST_CAPS_NEW("v4lmjpegsrc_jpeg_caps", return gst_caps_new_simple ("video/x-jpeg",
"video/x-jpeg", "width", GST_TYPE_INT_RANGE, vcap->maxwidth/4, vcap->maxwidth,
"width", GST_PROPS_INT_RANGE(vcap->maxwidth/4, "height", GST_TYPE_INT_RANGE, vcap->maxheight/4, vcap->maxheight,
vcap->maxwidth), "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE,
"height", GST_PROPS_INT_RANGE(vcap->maxheight/4, NULL);
vcap->maxheight),
"framerate", GST_PROPS_FLOAT_RANGE(0, G_MAXFLOAT),
NULL);
return caps;
} }
@ -834,6 +766,7 @@ gst_v4lmjpegsrc_set_clock (GstElement *element,
} }
#if 0
static GstBuffer* static GstBuffer*
gst_v4lmjpegsrc_buffer_new (GstBufferPool *pool, gst_v4lmjpegsrc_buffer_new (GstBufferPool *pool,
guint64 offset, guint64 offset,
@ -856,8 +789,9 @@ gst_v4lmjpegsrc_buffer_new (GstBufferPool *pool,
return buffer; return buffer;
} }
#endif
#if 0
static void static void
gst_v4lmjpegsrc_buffer_free (GstBufferPool *pool, GstBuffer *buf, gpointer user_data) gst_v4lmjpegsrc_buffer_free (GstBufferPool *pool, GstBuffer *buf, gpointer user_data)
{ {
@ -884,3 +818,4 @@ gst_v4lmjpegsrc_buffer_free (GstBufferPool *pool, GstBuffer *buf, gpointer user_
/* free the buffer struct et all */ /* free the buffer struct et all */
gst_buffer_default_free(buf); gst_buffer_default_free(buf);
} }
#endif

View file

@ -46,9 +46,6 @@ struct _GstV4lMjpegSrc {
/* pads */ /* pads */
GstPad *srcpad; GstPad *srcpad;
/* the bufferpool */
GstBufferPool *bufferpool;
/* buffer/capture info */ /* buffer/capture info */
struct mjpeg_sync bsync; struct mjpeg_sync bsync;
struct mjpeg_requestbuffers breq; struct mjpeg_requestbuffers breq;

View file

@ -74,10 +74,9 @@ static gboolean gst_v4lsrc_src_query (GstPad *pad,
/* buffer functions */ /* buffer functions */
static GstPadLinkReturn gst_v4lsrc_srcconnect (GstPad *pad, static GstPadLinkReturn gst_v4lsrc_srcconnect (GstPad *pad,
GstCaps *caps); const GstCaps *caps);
static GstCaps* gst_v4lsrc_getcaps (GstPad *pad, static GstCaps* gst_v4lsrc_getcaps (GstPad *pad);
GstCaps *caps); static GstData* gst_v4lsrc_get (GstPad *pad);
static GstData* gst_v4lsrc_get (GstPad *pad);
/* get/set params */ /* get/set params */
static void gst_v4lsrc_set_property (GObject *object, static void gst_v4lsrc_set_property (GObject *object,
@ -92,15 +91,6 @@ static void gst_v4lsrc_get_property (GObject *object,
/* state handling */ /* state handling */
static GstElementStateReturn gst_v4lsrc_change_state (GstElement *element); static GstElementStateReturn gst_v4lsrc_change_state (GstElement *element);
/* bufferpool functions */
static GstBuffer* gst_v4lsrc_buffer_new (GstBufferPool *pool,
guint64 offset,
guint size,
gpointer user_data);
static void gst_v4lsrc_buffer_free (GstBufferPool *pool,
GstBuffer *buf,
gpointer user_data);
/* set_clock function for a/V sync */ /* set_clock function for a/V sync */
static void gst_v4lsrc_set_clock (GstElement *element, static void gst_v4lsrc_set_clock (GstElement *element,
GstClock *clock); GstClock *clock);
@ -214,14 +204,6 @@ gst_v4lsrc_init (GstV4lSrc *v4lsrc)
gst_pad_set_query_function (v4lsrc->srcpad, gst_v4lsrc_src_query); gst_pad_set_query_function (v4lsrc->srcpad, gst_v4lsrc_src_query);
gst_pad_set_query_type_function (v4lsrc->srcpad, gst_v4lsrc_get_query_types); gst_pad_set_query_type_function (v4lsrc->srcpad, gst_v4lsrc_get_query_types);
v4lsrc->bufferpool = gst_buffer_pool_new(
NULL,
NULL,
(GstBufferPoolBufferNewFunction)gst_v4lsrc_buffer_new,
NULL,
(GstBufferPoolBufferFreeFunction)gst_v4lsrc_buffer_free,
v4lsrc);
v4lsrc->buffer_size = 0; v4lsrc->buffer_size = 0;
/* no clock */ /* no clock */
@ -341,10 +323,7 @@ gst_v4lsrc_src_query (GstPad *pad,
} }
static GstCaps * static GstCaps *
gst_v4lsrc_palette_to_caps (int palette, gst_v4lsrc_palette_to_caps (int palette)
GstPropsEntry *width,
GstPropsEntry *height,
GstPropsEntry *fps)
{ {
guint32 fourcc; guint32 fourcc;
GstCaps *caps; GstCaps *caps;
@ -374,89 +353,66 @@ gst_v4lsrc_palette_to_caps (int palette,
} }
if (fourcc == GST_MAKE_FOURCC('R','G','B',' ')) { if (fourcc == GST_MAKE_FOURCC('R','G','B',' ')) {
gint depth = 0, endianness = 0;
guint32 r_mask = 0, g_mask = 0, b_mask = 0;
switch (palette) { switch (palette) {
case VIDEO_PALETTE_RGB555: case VIDEO_PALETTE_RGB555:
depth = 15; endianness = G_BYTE_ORDER; caps = gst_caps_from_string ("video/x-raw-rgb, "
r_mask = 0x7c00; g_mask = 0x03e0; b_mask = 0x001f; "bpp = (int) 16, "
"depth = (int) 15, "
"endianness = (int) BYTE_ORDER, "
"red_mask = 0x7c00, "
"green_mask = 0x03e0, "
"blue_mask = 0x001f");
break; break;
case VIDEO_PALETTE_RGB565: case VIDEO_PALETTE_RGB565:
depth = 16; endianness = G_BYTE_ORDER; caps = gst_caps_from_string ("video/x-raw-rgb, "
r_mask = 0xf800; g_mask = 0x07f0; b_mask = 0x001f; "bpp = (int) 16, "
"depth = (int) 16, "
"endianness = (int) BYTE_ORDER, "
"red_mask = 0xf800, "
"green_mask = 0x07f0, "
"blue_mask = 0x001f");
break; break;
case VIDEO_PALETTE_RGB24: case VIDEO_PALETTE_RGB24:
depth = 24; endianness = G_BIG_ENDIAN; caps = gst_caps_from_string ("video/x-raw-rgb, "
r_mask = R_MASK_24; g_mask = G_MASK_24; b_mask = B_MASK_24; "bpp = (int) 24, "
"depth = (int) 24, "
"endianness = (int) BIG_ENDIAN, "
"red_mask = " R_MASK_24 ", "
"green_mask = " G_MASK_24 ", "
"blue_mask = " B_MASK_24);
break; break;
case VIDEO_PALETTE_RGB32: case VIDEO_PALETTE_RGB32:
depth = 32; endianness = G_BIG_ENDIAN; caps = gst_caps_from_string ("video/x-raw-rgb, "
r_mask = R_MASK_32; g_mask = G_MASK_32; b_mask = B_MASK_32; "bpp = (int) 24, "
"depth = (int) 32, "
"endianness = (int) BIG_ENDIAN, "
"red_mask = " R_MASK_32 ", "
"green_mask = " G_MASK_32 ", "
"blue_mask = " B_MASK_32);
break; break;
default: default:
g_assert_not_reached(); g_assert_not_reached();
break; return NULL;
} }
caps = GST_CAPS_NEW("v4lsrc_rgb_caps",
"video/x-raw-rgb",
"bpp", GST_PROPS_INT((depth+1) & ~1),
"depth", GST_PROPS_INT(depth),
"endianness", GST_PROPS_INT(G_BYTE_ORDER),
"red_mask", GST_PROPS_INT(r_mask),
"green_mask", GST_PROPS_INT(g_mask),
"blue_mask", GST_PROPS_INT(b_mask),
NULL);
} else { } else {
caps = GST_CAPS_NEW("v4lsrc_yuv_caps", caps = gst_caps_new_simple ("video/x-raw-yuv",
"video/x-raw-yuv", "format", GST_TYPE_FOURCC, fourcc, NULL);
"format", GST_PROPS_FOURCC(fourcc),
NULL);
} }
gst_props_add_entry(caps->properties, width);
gst_props_add_entry(caps->properties, height);
gst_props_add_entry(caps->properties, fps);
return caps; return caps;
} }
#define gst_v4lsrc_palette_to_caps_fixed(palette, width, height, fps) \
gst_v4lsrc_palette_to_caps(palette, \
gst_props_entry_new("width", \
GST_PROPS_INT(width)), \
gst_props_entry_new("height", \
GST_PROPS_INT(height)), \
gst_props_entry_new("framerate", \
GST_PROPS_FLOAT(fps)) \
)
#define gst_v4lsrc_palette_to_caps_range(palette, min_w, max_w, min_h, max_h) \
gst_v4lsrc_palette_to_caps(palette, \
gst_props_entry_new("width", \
GST_PROPS_INT_RANGE(min_w, \
max_w)), \
gst_props_entry_new("height", \
GST_PROPS_INT_RANGE(min_h, \
max_h)), \
gst_props_entry_new("framerate", \
GST_PROPS_FLOAT_RANGE(0., \
G_MAXFLOAT)) \
)
#define gst_caps_get_int_range(caps, name, min, max) \
gst_props_entry_get_int_range(gst_props_get_entry((caps)->properties, \
name), \
min, max)
static GstPadLinkReturn static GstPadLinkReturn
gst_v4lsrc_srcconnect (GstPad *pad, gst_v4lsrc_srcconnect (GstPad *pad, const GstCaps *vscapslist)
GstCaps *vscapslist)
{ {
GstPadLinkReturn ret_val; GstPadLinkReturn ret_val;
GstV4lSrc *v4lsrc; GstV4lSrc *v4lsrc;
GstCaps *caps, *newcaps; GstCaps *newcaps;
gint palette; gint palette;
guint32 fourcc;
gint depth, w, h;
GstStructure *structure;
v4lsrc = GST_V4LSRC (gst_pad_get_parent (pad)); v4lsrc = GST_V4LSRC (gst_pad_get_parent (pad));
@ -472,120 +428,96 @@ gst_v4lsrc_srcconnect (GstPad *pad,
return GST_PAD_LINK_DELAYED; return GST_PAD_LINK_DELAYED;
} }
/* TODO: caps = gst_caps_normalize(capslist); */ structure = gst_caps_get_structure (vscapslist, 0);
for (caps = vscapslist ; caps != NULL ; caps = vscapslist = vscapslist->next)
if (!strcmp(gst_structure_get_name (structure), "video/x-raw-yuv"))
gst_structure_get_fourcc (structure, "format", &fourcc);
else
fourcc = GST_MAKE_FOURCC('R','G','B',' ');
gst_structure_get_int (structure, "width", &w);
gst_structure_get_int (structure, "height", &h);
switch (fourcc)
{ {
guint32 fourcc; case GST_MAKE_FOURCC('I','4','2','0'):
gint depth, w, h; case GST_MAKE_FOURCC('I','Y','U','V'):
palette = VIDEO_PALETTE_YUV420P;
if (!strcmp(gst_caps_get_mime(caps), "video/x-raw-yuv")) v4lsrc->buffer_size = ((w+1)&~1) * ((h+1)&~1) * 1.5;
gst_caps_get_fourcc_int (caps, "format", &fourcc); break;
else case GST_MAKE_FOURCC('Y','U','Y','2'):
fourcc = GST_MAKE_FOURCC('R','G','B',' '); palette = VIDEO_PALETTE_YUV422;
v4lsrc->buffer_size = ((w+1)&~1) * h * 2;
if (gst_caps_has_property(caps, "width")) { break;
if (gst_caps_has_fixed_property(caps, "width")) { case GST_MAKE_FOURCC('U','Y','V','Y'):
gst_caps_get_int(caps, "width", &w); palette = VIDEO_PALETTE_UYVY;
} else { v4lsrc->buffer_size = ((w+1)&~1) * h * 2;
int min; break;
gst_caps_get_int_range(caps, "width", &min, &w); case GST_MAKE_FOURCC('Y','4','1','P'):
palette = VIDEO_PALETTE_YUV411;
v4lsrc->buffer_size = ((w+3)&~3) * h * 1.5;
break;
case GST_MAKE_FOURCC('R','G','B',' '):
depth = gst_structure_get_int (structure, "depth", &depth);
switch (depth)
{
case 15:
palette = VIDEO_PALETTE_RGB555;
v4lsrc->buffer_size = w * h * 2;
break;
case 16:
palette = VIDEO_PALETTE_RGB565;
v4lsrc->buffer_size = w * h * 2;
break;
case 24:
palette = VIDEO_PALETTE_RGB24;
v4lsrc->buffer_size = w * h * 3;
break;
case 32:
palette = VIDEO_PALETTE_RGB32;
v4lsrc->buffer_size = w * h * 4;
break;
default:
return GST_PAD_LINK_REFUSED;
} }
} default:
if (gst_caps_has_property(caps, "height")) {
if (gst_caps_has_fixed_property(caps, "height")) {
gst_caps_get_int(caps, "height", &h);
} else {
int min;
gst_caps_get_int_range(caps, "height", &min, &h);
}
}
switch (fourcc)
{
case GST_MAKE_FOURCC('I','4','2','0'):
case GST_MAKE_FOURCC('I','Y','U','V'):
palette = VIDEO_PALETTE_YUV420P;
v4lsrc->buffer_size = ((w+1)&~1) * ((h+1)&~1) * 1.5;
goto try_caps;
case GST_MAKE_FOURCC('Y','U','Y','2'):
palette = VIDEO_PALETTE_YUV422;
v4lsrc->buffer_size = ((w+1)&~1) * h * 2;
goto try_caps;
case GST_MAKE_FOURCC('U','Y','V','Y'):
palette = VIDEO_PALETTE_UYVY;
v4lsrc->buffer_size = ((w+1)&~1) * h * 2;
goto try_caps;
case GST_MAKE_FOURCC('Y','4','1','P'):
palette = VIDEO_PALETTE_YUV411;
v4lsrc->buffer_size = ((w+3)&~3) * h * 1.5;
goto try_caps;
case GST_MAKE_FOURCC('R','G','B',' '):
depth = gst_caps_get_int (caps, "depth", &depth);
switch (depth)
{
case 15:
palette = VIDEO_PALETTE_RGB555;
v4lsrc->buffer_size = w * h * 2;
goto try_caps;
case 16:
palette = VIDEO_PALETTE_RGB565;
v4lsrc->buffer_size = w * h * 2;
goto try_caps;
case 24:
palette = VIDEO_PALETTE_RGB24;
v4lsrc->buffer_size = w * h * 3;
goto try_caps;
case 32:
palette = VIDEO_PALETTE_RGB32;
v4lsrc->buffer_size = w * h * 4;
goto try_caps;
default:
goto try_next;
}
default:
goto try_next;
}
/* if this caps wasn't useful, try the next one */
try_next:
continue;
/* if this caps was useful, try it out */
try_caps:
/* try the current 'palette' out on the video device */
if (!gst_v4lsrc_try_palette(v4lsrc, palette))
continue;
/* try to connect the pad/caps with the actual width/height */
newcaps = gst_v4lsrc_palette_to_caps_fixed(palette, w, h,
gst_v4lsrc_get_fps(v4lsrc));
gst_caps_debug (newcaps, "new caps to set on v4lsrc's src pad");
if ((ret_val = gst_pad_try_set_caps(v4lsrc->srcpad, newcaps)) == GST_PAD_LINK_REFUSED)
continue;
else if (ret_val == GST_PAD_LINK_DELAYED)
return GST_PAD_LINK_DELAYED;
if (!gst_v4lsrc_set_capture(v4lsrc, w, h, palette))
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
}
if (!gst_v4lsrc_capture_init(v4lsrc)) /* try the current 'palette' out on the video device */
return GST_PAD_LINK_REFUSED; if (!gst_v4lsrc_try_palette(v4lsrc, palette))
return GST_PAD_LINK_REFUSED;
return GST_PAD_LINK_DONE; /* try to connect the pad/caps with the actual width/height */
} //newcaps = gst_v4lsrc_palette_to_caps_fixed(palette);
newcaps = gst_v4lsrc_palette_to_caps (palette);
gst_caps_set_simple (newcaps,
"width", G_TYPE_INT, w,
"height", G_TYPE_INT, h,
"framerate", G_TYPE_DOUBLE, gst_v4lsrc_get_fps(v4lsrc),
NULL);
/* still nothing - no good caps */ GST_DEBUG_CAPS ("new caps to set on v4lsrc's src pad", newcaps);
return GST_PAD_LINK_REFUSED;
if ((ret_val = gst_pad_try_set_caps(v4lsrc->srcpad, newcaps)) == GST_PAD_LINK_REFUSED)
return GST_PAD_LINK_REFUSED;
else if (ret_val == GST_PAD_LINK_DELAYED)
return GST_PAD_LINK_DELAYED;
if (!gst_v4lsrc_set_capture(v4lsrc, w, h, palette))
return GST_PAD_LINK_REFUSED;
if (!gst_v4lsrc_capture_init(v4lsrc))
return GST_PAD_LINK_REFUSED;
return GST_PAD_LINK_DONE;
} }
static GstCaps * static GstCaps *
gst_v4lsrc_getcaps (GstPad *pad, gst_v4lsrc_getcaps (GstPad *pad)
GstCaps *caps)
{ {
GstCaps *list = NULL; GstCaps *list;
GstV4lSrc *v4lsrc = GST_V4LSRC(gst_pad_get_parent(pad)); GstV4lSrc *v4lsrc = GST_V4LSRC(gst_pad_get_parent(pad));
int palette[] = { int palette[] = {
VIDEO_PALETTE_YUV422, VIDEO_PALETTE_YUV422,
@ -603,12 +535,28 @@ gst_v4lsrc_getcaps (GstPad *pad,
return NULL; return NULL;
} }
list = gst_caps_new_empty();
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
GstCaps *one; GstCaps *one;
one = gst_v4lsrc_palette_to_caps_range(palette[i], #define gst_v4lsrc_palette_to_caps_range(palette, min_w, max_w, min_h, max_h) \
vcap->minwidth, vcap->maxwidth, gst_v4lsrc_palette_to_caps(palette, \
vcap->minheight, vcap->maxheight); gst_props_entry_new("width", \
list = gst_caps_append(list, one); G_TYPE_INT_RANGE(min_w, \
max_w)), \
gst_props_entry_new("height", \
G_TYPE_INT_RANGE(min_h, \
max_h)), \
gst_props_entry_new("framerate", \
G_TYPE_DOUBLE_RANGE(0., \
G_MAXFLOAT)) \
)
one = gst_v4lsrc_palette_to_caps(palette[i]);
gst_caps_set_simple (one,
"width", GST_TYPE_INT_RANGE, vcap->minwidth, vcap->maxwidth,
"height", GST_TYPE_INT_RANGE, vcap->minheight, vcap->maxheight,
NULL);
gst_caps_append(list, one);
} }
return list; return list;
@ -631,14 +579,6 @@ gst_v4lsrc_get (GstPad *pad)
(fps = gst_v4lsrc_get_fps(v4lsrc)) == 0) (fps = gst_v4lsrc_get_fps(v4lsrc)) == 0)
return NULL; return NULL;
buf = gst_buffer_new_from_pool(v4lsrc->bufferpool, 0, 0);
if (!buf)
{
gst_element_error(GST_ELEMENT(v4lsrc),
"Failed to create a new GstBuffer");
return NULL;
}
if (v4lsrc->need_writes > 0) { if (v4lsrc->need_writes > 0) {
/* use last frame */ /* use last frame */
num = v4lsrc->last_frame; num = v4lsrc->last_frame;
@ -696,6 +636,8 @@ gst_v4lsrc_get (GstPad *pad)
v4lsrc->use_num_times[num] = 1; v4lsrc->use_num_times[num] = 1;
} }
buf = gst_buffer_new ();
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_READONLY);
GST_BUFFER_DATA(buf) = gst_v4lsrc_get_buffer(v4lsrc, num); GST_BUFFER_DATA(buf) = gst_v4lsrc_get_buffer(v4lsrc, num);
GST_BUFFER_SIZE(buf) = v4lsrc->buffer_size; GST_BUFFER_SIZE(buf) = v4lsrc->buffer_size;
if (v4lsrc->use_fixed_fps) if (v4lsrc->use_fixed_fps)
@ -822,6 +764,7 @@ gst_v4lsrc_change_state (GstElement *element)
} }
#if 0
static GstBuffer* static GstBuffer*
gst_v4lsrc_buffer_new (GstBufferPool *pool, gst_v4lsrc_buffer_new (GstBufferPool *pool,
guint64 offset, guint64 offset,
@ -845,8 +788,9 @@ gst_v4lsrc_buffer_new (GstBufferPool *pool,
return buffer; return buffer;
} }
#endif
#if 0
static void static void
gst_v4lsrc_buffer_free (GstBufferPool *pool, GstBuffer *buf, gpointer user_data) gst_v4lsrc_buffer_free (GstBufferPool *pool, GstBuffer *buf, gpointer user_data)
{ {
@ -873,6 +817,7 @@ gst_v4lsrc_buffer_free (GstBufferPool *pool, GstBuffer *buf, gpointer user_data)
/* free struct */ /* free struct */
gst_buffer_default_free(buf); gst_buffer_default_free(buf);
} }
#endif
static void static void

View file

@ -44,9 +44,6 @@ struct _GstV4lSrc {
/* pads */ /* pads */
GstPad *srcpad; GstPad *srcpad;
/* bufferpool for the buffers we're gonna use */
GstBufferPool *bufferpool;
/* capture/buffer info */ /* capture/buffer info */
struct video_mmap mmap; struct video_mmap mmap;
struct video_mbuf mbuf; struct video_mbuf mbuf;

View file

@ -38,15 +38,16 @@ static GstElementDetails gst_ximagesink_details = GST_ELEMENT_DETAILS (
/* Default template - initiated with class struct to allow gst-register to work /* Default template - initiated with class struct to allow gst-register to work
without X running */ without X running */
GST_PAD_TEMPLATE_FACTORY (gst_ximagesink_sink_template_factory, static GstStaticPadTemplate gst_ximagesink_sink_template_factory =
GST_STATIC_PAD_TEMPLATE (
"sink", "sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_CAPS_NEW ("ximagesink_rgbsink", "video/x-raw-rgb", GST_STATIC_CAPS ("video/x-raw-rgb, "
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), "framerate = (double) [ 0, MAX ], "
"width", GST_PROPS_INT_RANGE (0, G_MAXINT), "width = (int) [ 0, MAX ], "
"height", GST_PROPS_INT_RANGE (0, G_MAXINT)) "height = (int) [ 0, MAX ]")
) );
static GstVideoSinkClass *parent_class = NULL; static GstVideoSinkClass *parent_class = NULL;
@ -302,16 +303,17 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
ximagesink->xwindow->height = e.xconfigure.height; ximagesink->xwindow->height = e.xconfigure.height;
r = gst_pad_try_set_caps (GST_VIDEOSINK_PAD (ximagesink), r = gst_pad_try_set_caps (GST_VIDEOSINK_PAD (ximagesink),
GST_CAPS_NEW ("ximagesink_ximage_caps", "video/x-raw-rgb", gst_caps_new_simple ("video/x-raw-rgb",
"bpp", GST_PROPS_INT (ximagesink->xcontext->bpp), "bpp", G_TYPE_INT, ximagesink->xcontext->bpp,
"depth", GST_PROPS_INT (ximagesink->xcontext->depth), "depth", G_TYPE_INT, ximagesink->xcontext->depth,
"endianness", GST_PROPS_INT (ximagesink->xcontext->endianness), "endianness", G_TYPE_INT, ximagesink->xcontext->endianness,
"red_mask", GST_PROPS_INT (ximagesink->xcontext->visual->red_mask), "red_mask", G_TYPE_INT, ximagesink->xcontext->visual->red_mask,
"green_mask", GST_PROPS_INT (ximagesink->xcontext->visual->green_mask), "green_mask", G_TYPE_INT, ximagesink->xcontext->visual->green_mask,
"blue_mask", GST_PROPS_INT (ximagesink->xcontext->visual->blue_mask), "blue_mask", G_TYPE_INT, ximagesink->xcontext->visual->blue_mask,
"width", GST_PROPS_INT (e.xconfigure.width), "width", G_TYPE_INT, e.xconfigure.width,
"height", GST_PROPS_INT (e.xconfigure.height), "height", G_TYPE_INT, e.xconfigure.height,
"framerate", GST_PROPS_FLOAT (ximagesink->framerate))); "framerate", G_TYPE_DOUBLE, ximagesink->framerate,
NULL));
if ( (r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE) ) if ( (r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE) )
{ {
@ -458,23 +460,20 @@ gst_ximagesink_xcontext_get (GstXImageSink *ximagesink)
xcontext->visual->blue_mask = GULONG_TO_BE (xcontext->visual->blue_mask); xcontext->visual->blue_mask = GULONG_TO_BE (xcontext->visual->blue_mask);
} }
xcontext->caps = GST_CAPS_NEW ("ximagesink_ximage_caps", "video/x-raw-rgb", xcontext->caps = gst_caps_new_simple ("video/x-raw-rgb",
"bpp", GST_PROPS_INT (xcontext->bpp), "bpp", G_TYPE_INT, xcontext->bpp,
"depth", GST_PROPS_INT (xcontext->depth), "depth", G_TYPE_INT, xcontext->depth,
"endianness", GST_PROPS_INT (xcontext->endianness), "endianness", G_TYPE_INT, xcontext->endianness,
"red_mask", GST_PROPS_INT (xcontext->visual->red_mask), "red_mask", G_TYPE_INT, xcontext->visual->red_mask,
"green_mask", GST_PROPS_INT (xcontext->visual->green_mask), "green_mask", G_TYPE_INT, xcontext->visual->green_mask,
"blue_mask", GST_PROPS_INT (xcontext->visual->blue_mask), "blue_mask", G_TYPE_INT, xcontext->visual->blue_mask,
"width", GST_PROPS_INT_RANGE (0, G_MAXINT), "width", GST_TYPE_INT_RANGE, 0, G_MAXINT,
"height", GST_PROPS_INT_RANGE (0, G_MAXINT), "height", GST_TYPE_INT_RANGE, 0, G_MAXINT,
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT)); "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE,
NULL);
g_mutex_unlock (ximagesink->x_lock); g_mutex_unlock (ximagesink->x_lock);
/* We make this caps non floating. This way we keep it during our whole life */
gst_caps_ref (xcontext->caps);
gst_caps_sink (xcontext->caps);
return xcontext; return xcontext;
} }
@ -486,7 +485,7 @@ gst_ximagesink_xcontext_clear (GstXImageSink *ximagesink)
g_return_if_fail (ximagesink != NULL); g_return_if_fail (ximagesink != NULL);
g_return_if_fail (GST_IS_XIMAGESINK (ximagesink)); g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
gst_caps_unref (ximagesink->xcontext->caps); gst_caps_free (ximagesink->xcontext->caps);
g_mutex_lock (ximagesink->x_lock); g_mutex_lock (ximagesink->x_lock);
@ -500,7 +499,7 @@ gst_ximagesink_xcontext_clear (GstXImageSink *ximagesink)
/* Element stuff */ /* Element stuff */
static GstCaps * static GstCaps *
gst_ximagesink_getcaps (GstPad *pad, GstCaps *caps) gst_ximagesink_getcaps (GstPad *pad)
{ {
GstXImageSink *ximagesink; GstXImageSink *ximagesink;
@ -509,25 +508,22 @@ gst_ximagesink_getcaps (GstPad *pad, GstCaps *caps)
if (ximagesink->xcontext) if (ximagesink->xcontext)
return gst_caps_copy (ximagesink->xcontext->caps); return gst_caps_copy (ximagesink->xcontext->caps);
return GST_CAPS_NEW ("ximagesink_rgbsink", "video/x-raw-rgb", return gst_caps_from_string ("video/x-raw-rgb, "
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), "framerate = (double) [ 0, MAX ], "
"width", GST_PROPS_INT_RANGE (0, G_MAXINT), "width = (int) [ 0, MAX ], "
"height", GST_PROPS_INT_RANGE (0, G_MAXINT)); "height = (int) [ 0, MAX ]");
} }
static GstPadLinkReturn static GstPadLinkReturn
gst_ximagesink_sinkconnect (GstPad *pad, GstCaps *caps) gst_ximagesink_sinkconnect (GstPad *pad, const GstCaps *caps)
{ {
GstXImageSink *ximagesink; GstXImageSink *ximagesink;
char *caps_str1, *caps_str2; char *caps_str1, *caps_str2;
gboolean ret;
GstStructure *structure;
ximagesink = GST_XIMAGESINK (gst_pad_get_parent (pad)); ximagesink = GST_XIMAGESINK (gst_pad_get_parent (pad));
/* we are not going to act on variable caps */
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_LINK_DELAYED;
if (GST_CAPS_IS_CHAINED (caps))
return GST_PAD_LINK_DELAYED;
if (!ximagesink->xcontext) if (!ximagesink->xcontext)
return GST_PAD_LINK_DELAYED; return GST_PAD_LINK_DELAYED;
@ -536,27 +532,25 @@ gst_ximagesink_sinkconnect (GstPad *pad, GstCaps *caps)
GST_DEBUG ("sinkconnect %s with %s", caps_str1, caps_str2); GST_DEBUG ("sinkconnect %s with %s", caps_str1, caps_str2);
if (caps_str1) g_free (caps_str1);
g_free (caps_str1); g_free (caps_str2);
if (caps_str2)
g_free (caps_str2);
if (!gst_caps_get_int (caps, "width", &(GST_VIDEOSINK_WIDTH (ximagesink)))) structure = gst_caps_get_structure (caps, 0);
return GST_PAD_LINK_REFUSED; ret = gst_structure_get_int (structure, "width",
if (!gst_caps_get_int (caps, "height", &(GST_VIDEOSINK_HEIGHT (ximagesink)))) &(GST_VIDEOSINK_WIDTH (ximagesink)));
return GST_PAD_LINK_REFUSED; ret &= gst_structure_get_int (structure, "height",
if (!gst_caps_get_float (caps, "framerate", &ximagesink->framerate)) &(GST_VIDEOSINK_HEIGHT (ximagesink)));
return GST_PAD_LINK_REFUSED; ret &= gst_structure_get_double (structure,
"framerate", &ximagesink->framerate);
if (!ret) return GST_PAD_LINK_REFUSED;
if (gst_caps_has_fixed_property (caps, "pixel_width")) ximagesink->pixel_width = 1;
gst_caps_get_int (caps, "pixel_width", &ximagesink->pixel_width); gst_structure_get_int (structure, "pixel_width",
else &ximagesink->pixel_width);
ximagesink->pixel_width = 1;
if (gst_caps_has_fixed_property (caps, "pixel_height")) ximagesink->pixel_height = 1;
gst_caps_get_int (caps, "pixel_height", &ximagesink->pixel_height); gst_structure_get_int (structure, "pixel_height",
else &ximagesink->pixel_height);
ximagesink->pixel_height = 1;
/* Creating our window and our image */ /* Creating our window and our image */
if (!ximagesink->xwindow) if (!ximagesink->xwindow)
@ -660,12 +654,14 @@ gst_ximagesink_chain (GstPad *pad, GstData *_data)
gst_clock_id_free (id); gst_clock_id_free (id);
} }
#if 0
/* If we have a pool and the image is from this pool, simply put it. */ /* If we have a pool and the image is from this pool, simply put it. */
if ( (ximagesink->bufferpool) && if ( (ximagesink->bufferpool) &&
(GST_BUFFER_BUFFERPOOL (buf) == ximagesink->bufferpool) ) (GST_BUFFER_BUFFERPOOL (buf) == ximagesink->bufferpool) )
gst_ximagesink_ximage_put (ximagesink, GST_BUFFER_POOL_PRIVATE (buf)); gst_ximagesink_ximage_put (ximagesink, GST_BUFFER_POOL_PRIVATE (buf));
else /* Else we have to copy the data into our private image, */ else /* Else we have to copy the data into our private image, */
{ /* if we have one... */ { /* if we have one... */
#endif
if (ximagesink->ximage) if (ximagesink->ximage)
{ {
memcpy (ximagesink->ximage->ximage->data, memcpy (ximagesink->ximage->ximage->data,
@ -679,13 +675,16 @@ gst_ximagesink_chain (GstPad *pad, GstData *_data)
gst_element_error (GST_ELEMENT (ximagesink), "no image to draw"); gst_element_error (GST_ELEMENT (ximagesink), "no image to draw");
return; return;
} }
#if 0
} }
#endif
gst_buffer_unref (buf); gst_buffer_unref (buf);
gst_ximagesink_handle_xevents (ximagesink, pad); gst_ximagesink_handle_xevents (ximagesink, pad);
} }
#if 0
static GstBuffer* static GstBuffer*
gst_ximagesink_buffer_new (GstBufferPool *pool, gst_ximagesink_buffer_new (GstBufferPool *pool,
gint64 location, guint size, gpointer user_data) gint64 location, guint size, gpointer user_data)
@ -767,6 +766,7 @@ gst_ximagesink_buffer_free (GstBufferPool *pool,
gst_buffer_default_free (buffer); gst_buffer_default_free (buffer);
} }
#endif
static void static void
gst_ximagesink_imagepool_clear (GstXImageSink *ximagesink) gst_ximagesink_imagepool_clear (GstXImageSink *ximagesink)
@ -784,30 +784,6 @@ gst_ximagesink_imagepool_clear (GstXImageSink *ximagesink)
g_mutex_unlock(ximagesink->pool_lock); g_mutex_unlock(ximagesink->pool_lock);
} }
static GstBufferPool*
gst_ximagesink_get_bufferpool (GstPad *pad)
{
GstXImageSink *ximagesink;
ximagesink = GST_XIMAGESINK (gst_pad_get_parent (pad));
if (!ximagesink->bufferpool) {
ximagesink->bufferpool = gst_buffer_pool_new (
NULL, /* free */
NULL, /* copy */
(GstBufferPoolBufferNewFunction) gst_ximagesink_buffer_new,
NULL, /* buffer copy, the default is fine */
(GstBufferPoolBufferFreeFunction) gst_ximagesink_buffer_free,
ximagesink);
ximagesink->image_pool = NULL;
}
gst_buffer_pool_ref (ximagesink->bufferpool);
return ximagesink->bufferpool;
}
/* Interfaces stuff */ /* Interfaces stuff */
static gboolean static gboolean
@ -948,9 +924,6 @@ gst_ximagesink_dispose (GObject *object)
g_mutex_free (ximagesink->x_lock); g_mutex_free (ximagesink->x_lock);
g_mutex_free (ximagesink->pool_lock); g_mutex_free (ximagesink->pool_lock);
if (ximagesink->bufferpool)
gst_buffer_pool_free (ximagesink->bufferpool);
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
@ -958,9 +931,8 @@ static void
gst_ximagesink_init (GstXImageSink *ximagesink) gst_ximagesink_init (GstXImageSink *ximagesink)
{ {
GST_VIDEOSINK_PAD (ximagesink) = gst_pad_new_from_template ( GST_VIDEOSINK_PAD (ximagesink) = gst_pad_new_from_template (
GST_PAD_TEMPLATE_GET ( gst_static_pad_template_get (&gst_ximagesink_sink_template_factory),
gst_ximagesink_sink_template_factory), "sink");
"sink");
gst_element_add_pad (GST_ELEMENT (ximagesink), gst_element_add_pad (GST_ELEMENT (ximagesink),
GST_VIDEOSINK_PAD (ximagesink)); GST_VIDEOSINK_PAD (ximagesink));
@ -971,8 +943,6 @@ gst_ximagesink_init (GstXImageSink *ximagesink)
gst_ximagesink_sinkconnect); gst_ximagesink_sinkconnect);
gst_pad_set_getcaps_function (GST_VIDEOSINK_PAD (ximagesink), gst_pad_set_getcaps_function (GST_VIDEOSINK_PAD (ximagesink),
gst_ximagesink_getcaps); gst_ximagesink_getcaps);
gst_pad_set_bufferpool_function (GST_VIDEOSINK_PAD (ximagesink),
gst_ximagesink_get_bufferpool);
ximagesink->xcontext = NULL; ximagesink->xcontext = NULL;
ximagesink->xwindow = NULL; ximagesink->xwindow = NULL;
@ -999,7 +969,7 @@ gst_ximagesink_base_init (gpointer g_class)
gst_element_class_set_details (element_class, &gst_ximagesink_details); gst_element_class_set_details (element_class, &gst_ximagesink_details);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_GET (gst_ximagesink_sink_template_factory)); gst_static_pad_template_get (&gst_ximagesink_sink_template_factory));
} }
static void static void

View file

@ -107,13 +107,12 @@ struct _GstXImageSink {
GstXWindow *xwindow; GstXWindow *xwindow;
GstXImage *ximage; GstXImage *ximage;
gfloat framerate; gdouble framerate;
GMutex *x_lock; GMutex *x_lock;
/* Unused */ /* Unused */
gint pixel_width, pixel_height; gint pixel_width, pixel_height;
GstBufferPool *bufferpool;
GMutex *pool_lock; GMutex *pool_lock;
GSList *image_pool; GSList *image_pool;
}; };

View file

@ -38,19 +38,22 @@ static GstElementDetails gst_xvimagesink_details = GST_ELEMENT_DETAILS (
/* Default template - initiated with class struct to allow gst-register to work /* Default template - initiated with class struct to allow gst-register to work
without X running */ without X running */
GST_PAD_TEMPLATE_FACTORY (gst_xvimagesink_sink_template_factory, static GstStaticPadTemplate gst_xvimagesink_sink_template_factory =
GST_STATIC_PAD_TEMPLATE (
"sink", "sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_CAPS_NEW ("xvimagesink_rgbsink", "video/x-raw-rgb", GST_STATIC_CAPS (
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), "video/x-raw-rgb, "
"width", GST_PROPS_INT_RANGE (0, G_MAXINT), "framerate = (double) [ 0, MAX ], "
"height", GST_PROPS_INT_RANGE (0, G_MAXINT)), "width = (int) [ 0, MAX ], "
GST_CAPS_NEW ("xvimagesink_yuvsink", "video/x-raw-yuv", "height = (int) [ 0, MAX ]; "
"framerate", GST_PROPS_FLOAT_RANGE(0, G_MAXFLOAT), "video/x-raw-yuv, "
"width", GST_PROPS_INT_RANGE(0, G_MAXINT), "framerate = (double) [ 0, MAX ], "
"height", GST_PROPS_INT_RANGE(0, G_MAXINT)) "width = (int) [ 0, MAX ], "
) "height = (int) [ 0, MAX ]"
)
);
static GstVideoSinkClass *parent_class = NULL; static GstVideoSinkClass *parent_class = NULL;
@ -398,11 +401,11 @@ gst_xvimagesink_get_xv_support (GstXContext *xcontext)
gint nb_formats; gint nb_formats;
XvImageFormatValues *formats = NULL; XvImageFormatValues *formats = NULL;
GstCaps *caps = NULL; GstCaps *caps = NULL;
char *caps_str;
/* We get all image formats supported by our port */ /* We get all image formats supported by our port */
formats = XvListImageFormats (xcontext->disp, formats = XvListImageFormats (xcontext->disp,
xcontext->xv_port_id, &nb_formats); xcontext->xv_port_id, &nb_formats);
caps = gst_caps_new_empty ();
for (i = 0; i < nb_formats; i++) for (i = 0; i < nb_formats; i++)
{ {
GstCaps *format_caps = NULL; GstCaps *format_caps = NULL;
@ -411,17 +414,17 @@ gst_xvimagesink_get_xv_support (GstXContext *xcontext)
{ {
case XvRGB: case XvRGB:
{ {
format_caps = GST_CAPS_NEW ("xvimagesink_caps", format_caps = gst_caps_new_simple ("video/x-raw-rgb",
"video/x-raw-rgb", "endianness", G_TYPE_INT, xcontext->endianness,
"endianness", GST_PROPS_INT (xcontext->endianness), "depth", G_TYPE_INT, xcontext->depth,
"depth", GST_PROPS_INT (xcontext->depth), "bpp", G_TYPE_INT, xcontext->bpp,
"bpp", GST_PROPS_INT (xcontext->bpp), "blue_mask", G_TYPE_INT, formats[i].red_mask,
"blue_mask", GST_PROPS_INT (formats[i].red_mask), "green_mask", G_TYPE_INT, formats[i].green_mask,
"green_mask", GST_PROPS_INT (formats[i].green_mask), "red_mask", G_TYPE_INT, formats[i].blue_mask,
"red_mask", GST_PROPS_INT (formats[i].blue_mask), "width", GST_TYPE_INT_RANGE, 0, G_MAXINT,
"width", GST_PROPS_INT_RANGE (0, G_MAXINT), "height", GST_TYPE_INT_RANGE, 0, G_MAXINT,
"height", GST_PROPS_INT_RANGE (0, G_MAXINT), "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE,
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT)); NULL);
/* For RGB caps we store them and the image /* For RGB caps we store them and the image
format so that we can get back the format format so that we can get back the format
@ -442,29 +445,26 @@ gst_xvimagesink_get_xv_support (GstXContext *xcontext)
break; break;
} }
case XvYUV: case XvYUV:
format_caps = GST_CAPS_NEW ("xvimagesink_caps", format_caps = gst_caps_new_simple ("video/x-raw-yuv",
"video/x-raw-yuv", "format", GST_TYPE_FOURCC,formats[i].id,
"format", GST_PROPS_FOURCC (formats[i].id), "width", GST_TYPE_INT_RANGE, 0, G_MAXINT,
"width", GST_PROPS_INT_RANGE (0, G_MAXINT), "height", GST_TYPE_INT_RANGE, 0, G_MAXINT,
"height", GST_PROPS_INT_RANGE (0, G_MAXINT), "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE,
"framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT)); NULL);
break; break;
default:
g_assert_not_reached();
break;
} }
if (format_caps) gst_caps_append (caps, format_caps);
caps = gst_caps_append (caps, format_caps);
} }
if (formats) if (formats)
XFree (formats); XFree (formats);
caps_str = gst_caps_to_string (caps); GST_DEBUG_CAPS ("Generated the following caps", caps);
GST_DEBUG ("Generated the following caps %s", caps_str);
if (caps_str)
g_free (caps_str);
return caps; return caps;
} }
@ -562,10 +562,6 @@ gst_xvimagesink_xcontext_get (GstXvImageSink *xvimagesink)
g_mutex_unlock (xvimagesink->x_lock); g_mutex_unlock (xvimagesink->x_lock);
/* We make this caps non floating. This way we keep it during our whole life */
gst_caps_ref (xcontext->caps);
gst_caps_sink (xcontext->caps);
return xcontext; return xcontext;
} }
@ -584,7 +580,7 @@ gst_xvimagesink_xcontext_clear (GstXvImageSink *xvimagesink)
while (list) while (list)
{ {
GstXvImageFormat *format = list->data; GstXvImageFormat *format = list->data;
gst_caps_unref (format->caps); gst_caps_free (format->caps);
g_free (format); g_free (format);
list = g_list_next (list); list = g_list_next (list);
} }
@ -592,7 +588,7 @@ gst_xvimagesink_xcontext_clear (GstXvImageSink *xvimagesink)
if (xvimagesink->xcontext->formats_list) if (xvimagesink->xcontext->formats_list)
g_list_free (xvimagesink->xcontext->formats_list); g_list_free (xvimagesink->xcontext->formats_list);
gst_caps_unref (xvimagesink->xcontext->caps); gst_caps_free (xvimagesink->xcontext->caps);
g_mutex_lock (xvimagesink->x_lock); g_mutex_lock (xvimagesink->x_lock);
@ -612,7 +608,6 @@ static gint
gst_xvimagesink_get_fourcc_from_caps (GstXvImageSink *xvimagesink, gst_xvimagesink_get_fourcc_from_caps (GstXvImageSink *xvimagesink,
GstCaps *caps) GstCaps *caps)
{ {
gint fourcc = 0;
GList *list = NULL; GList *list = NULL;
g_return_val_if_fail (xvimagesink != NULL, 0); g_return_val_if_fail (xvimagesink != NULL, 0);
@ -628,83 +623,71 @@ gst_xvimagesink_get_fourcc_from_caps (GstXvImageSink *xvimagesink,
{ {
GstCaps *icaps = NULL; GstCaps *icaps = NULL;
icaps = gst_caps_intersect (caps, format->caps); icaps = gst_caps_intersect (caps, format->caps);
if (icaps) if (!gst_caps_is_empty(icaps))
fourcc = format->format; return format->format;
} }
list = g_list_next (list); list = g_list_next (list);
} }
return fourcc; return 0;
} }
static GstCaps * static GstCaps *
gst_xvimagesink_getcaps (GstPad *pad, GstCaps *caps) gst_xvimagesink_getcaps (GstPad *pad)
{ {
GstXvImageSink *xvimagesink; GstXvImageSink *xvimagesink;
xvimagesink = GST_XVIMAGESINK (gst_pad_get_parent (pad)); xvimagesink = GST_XVIMAGESINK (gst_pad_get_parent (pad));
if (xvimagesink->xcontext) if (xvimagesink->xcontext)
return gst_caps_copy (xvimagesink->xcontext->caps); return gst_caps_copy (xvimagesink->xcontext->caps);
return gst_caps_append (GST_CAPS_NEW ("xvimagesink_rgbsink", return gst_caps_from_string(
"video/x-raw-rgb", "video/x-raw-rgb, "
"framerate", GST_PROPS_FLOAT_RANGE(0, G_MAXFLOAT), "framerate = (double) [ 0, MAX ], "
"width", GST_PROPS_INT_RANGE(0, G_MAXINT), "width = (int) [ 0, MAX ], "
"height", GST_PROPS_INT_RANGE(0, G_MAXINT)), "height = (int) [ 0, MAX ]; "
GST_CAPS_NEW ("xvimagesink_yuvsink", "video/x-raw-yuv, "
"video/x-raw-yuv", "framerate = (double) [ 0, MAX ], "
"framerate", GST_PROPS_FLOAT_RANGE(0, G_MAXFLOAT), "width = (int) [ 0, MAX ], "
"width", GST_PROPS_INT_RANGE(0, G_MAXINT), "height = (int) [ 0, MAX ]");
"height", GST_PROPS_INT_RANGE(0, G_MAXINT)));
} }
static GstPadLinkReturn static GstPadLinkReturn
gst_xvimagesink_sinkconnect (GstPad *pad, GstCaps *caps) gst_xvimagesink_sinkconnect (GstPad *pad, const GstCaps *caps)
{ {
GstXvImageSink *xvimagesink; GstXvImageSink *xvimagesink;
char *caps_str1, *caps_str2; char *caps_str1, *caps_str2;
GstStructure *structure;
gboolean ret;
xvimagesink = GST_XVIMAGESINK (gst_pad_get_parent (pad)); xvimagesink = GST_XVIMAGESINK (gst_pad_get_parent (pad));
/* we are not going to act on variable caps */
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_LINK_DELAYED;
if (GST_CAPS_IS_CHAINED (caps))
return GST_PAD_LINK_DELAYED;
caps_str1 = gst_caps_to_string (xvimagesink->xcontext->caps); caps_str1 = gst_caps_to_string (xvimagesink->xcontext->caps);
caps_str2 = gst_caps_to_string (caps); caps_str2 = gst_caps_to_string (caps);
GST_DEBUG ("sinkconnect %s with %s", caps_str1, caps_str2); GST_DEBUG ("sinkconnect %s with %s", caps_str1, caps_str2);
if (caps_str1) g_free (caps_str1);
g_free (caps_str1); g_free (caps_str2);
if (caps_str2)
g_free (caps_str2);
if (!gst_caps_get_int (caps, "width", &(GST_VIDEOSINK_WIDTH (xvimagesink)))) structure = gst_caps_get_structure (caps, 0);
return GST_PAD_LINK_REFUSED; ret = gst_structure_get_int (structure, "width", &(GST_VIDEOSINK_WIDTH (xvimagesink)));
if (!gst_caps_get_int (caps, "height", &(GST_VIDEOSINK_HEIGHT (xvimagesink)))) ret &= gst_structure_get_int (structure, "height", &(GST_VIDEOSINK_HEIGHT (xvimagesink)));
return GST_PAD_LINK_REFUSED; ret &= gst_structure_get_double (structure, "framerate", &xvimagesink->framerate);
if (!gst_caps_get_float (caps, "framerate", &xvimagesink->framerate)) if (!ret) return GST_PAD_LINK_REFUSED;
return GST_PAD_LINK_REFUSED;
if (gst_caps_has_fixed_property (caps, "format")) if (!gst_structure_get_fourcc (structure, "format",
gst_caps_get_fourcc_int (caps, "format", &xvimagesink->xcontext->im_format); &xvimagesink->xcontext->im_format)) {
else
xvimagesink->xcontext->im_format = gst_xvimagesink_get_fourcc_from_caps ( xvimagesink->xcontext->im_format = gst_xvimagesink_get_fourcc_from_caps (
xvimagesink, caps); xvimagesink, gst_caps_copy(caps));
}
if (gst_caps_has_fixed_property (caps, "pixel_width")) xvimagesink->pixel_width = 1;
gst_caps_get_int (caps, "pixel_width", &xvimagesink->pixel_width); gst_structure_get_int (structure, "pixel_width", &xvimagesink->pixel_width);
else
xvimagesink->pixel_width = 1;
if (gst_caps_has_fixed_property (caps, "pixel_height")) xvimagesink->pixel_height = 1;
gst_caps_get_int (caps, "pixel_height", &xvimagesink->pixel_height); gst_structure_get_int (structure, "pixel_height", &xvimagesink->pixel_height);
else
xvimagesink->pixel_height = 1;
/* Creating our window and our image */ /* Creating our window and our image */
if (!xvimagesink->xwindow) if (!xvimagesink->xwindow)
@ -814,12 +797,14 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data)
gst_clock_id_free (id); gst_clock_id_free (id);
} }
#if 0
/* If we have a pool and the image is from this pool, simply put it. */ /* If we have a pool and the image is from this pool, simply put it. */
if ( (xvimagesink->bufferpool) && if ( (xvimagesink->bufferpool) &&
(GST_BUFFER_BUFFERPOOL (buf) == xvimagesink->bufferpool) ) (GST_BUFFER_BUFFERPOOL (buf) == xvimagesink->bufferpool) )
gst_xvimagesink_xvimage_put (xvimagesink, GST_BUFFER_POOL_PRIVATE (buf)); gst_xvimagesink_xvimage_put (xvimagesink, GST_BUFFER_POOL_PRIVATE (buf));
else /* Else we have to copy the data into our private image, */ else /* Else we have to copy the data into our private image, */
{ /* if we have one... */ { /* if we have one... */
#endif
if (xvimagesink->xvimage) if (xvimagesink->xvimage)
{ {
memcpy (xvimagesink->xvimage->xvimage->data, memcpy (xvimagesink->xvimage->xvimage->data,
@ -833,7 +818,9 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data)
gst_element_error (GST_ELEMENT (xvimagesink), "no image to draw"); gst_element_error (GST_ELEMENT (xvimagesink), "no image to draw");
return; return;
} }
#if 0
} }
#endif
/* set correct time for next buffer */ /* set correct time for next buffer */
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) && xvimagesink->framerate > 0) { if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) && xvimagesink->framerate > 0) {
xvimagesink->time += GST_SECOND / xvimagesink->framerate; xvimagesink->time += GST_SECOND / xvimagesink->framerate;
@ -844,6 +831,7 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data)
gst_xvimagesink_handle_xevents (xvimagesink, pad); gst_xvimagesink_handle_xevents (xvimagesink, pad);
} }
#if 0
static GstBuffer* static GstBuffer*
gst_xvimagesink_buffer_new (GstBufferPool *pool, gst_xvimagesink_buffer_new (GstBufferPool *pool,
gint64 location, guint size, gpointer user_data) gint64 location, guint size, gpointer user_data)
@ -926,6 +914,7 @@ gst_xvimagesink_buffer_free (GstBufferPool *pool,
gst_buffer_default_free (buffer); gst_buffer_default_free (buffer);
} }
#endif
static void static void
gst_xvimagesink_imagepool_clear (GstXvImageSink *xvimagesink) gst_xvimagesink_imagepool_clear (GstXvImageSink *xvimagesink)
@ -943,30 +932,6 @@ gst_xvimagesink_imagepool_clear (GstXvImageSink *xvimagesink)
g_mutex_unlock(xvimagesink->pool_lock); g_mutex_unlock(xvimagesink->pool_lock);
} }
static GstBufferPool*
gst_xvimagesink_get_bufferpool (GstPad *pad)
{
GstXvImageSink *xvimagesink;
xvimagesink = GST_XVIMAGESINK (gst_pad_get_parent (pad));
if (!xvimagesink->bufferpool) {
xvimagesink->bufferpool = gst_buffer_pool_new (
NULL, /* free */
NULL, /* copy */
(GstBufferPoolBufferNewFunction) gst_xvimagesink_buffer_new,
NULL, /* buffer copy, the default is fine */
(GstBufferPoolBufferFreeFunction) gst_xvimagesink_buffer_free,
xvimagesink);
xvimagesink->image_pool = NULL;
}
gst_buffer_pool_ref (xvimagesink->bufferpool);
return xvimagesink->bufferpool;
}
/* Interfaces stuff */ /* Interfaces stuff */
static gboolean static gboolean
@ -1100,9 +1065,6 @@ gst_xvimagesink_dispose (GObject *object)
g_mutex_free (xvimagesink->x_lock); g_mutex_free (xvimagesink->x_lock);
g_mutex_free (xvimagesink->pool_lock); g_mutex_free (xvimagesink->pool_lock);
if (xvimagesink->bufferpool)
gst_buffer_pool_free (xvimagesink->bufferpool);
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
@ -1110,9 +1072,8 @@ static void
gst_xvimagesink_init (GstXvImageSink *xvimagesink) gst_xvimagesink_init (GstXvImageSink *xvimagesink)
{ {
GST_VIDEOSINK_PAD (xvimagesink) = gst_pad_new_from_template ( GST_VIDEOSINK_PAD (xvimagesink) = gst_pad_new_from_template (
GST_PAD_TEMPLATE_GET ( gst_static_pad_template_get (&gst_xvimagesink_sink_template_factory),
gst_xvimagesink_sink_template_factory), "sink");
"sink");
gst_element_add_pad (GST_ELEMENT (xvimagesink), gst_element_add_pad (GST_ELEMENT (xvimagesink),
GST_VIDEOSINK_PAD (xvimagesink)); GST_VIDEOSINK_PAD (xvimagesink));
@ -1123,8 +1084,6 @@ gst_xvimagesink_init (GstXvImageSink *xvimagesink)
gst_xvimagesink_sinkconnect); gst_xvimagesink_sinkconnect);
gst_pad_set_getcaps_function (GST_VIDEOSINK_PAD (xvimagesink), gst_pad_set_getcaps_function (GST_VIDEOSINK_PAD (xvimagesink),
gst_xvimagesink_getcaps); gst_xvimagesink_getcaps);
gst_pad_set_bufferpool_function (GST_VIDEOSINK_PAD (xvimagesink),
gst_xvimagesink_get_bufferpool);
xvimagesink->xcontext = NULL; xvimagesink->xcontext = NULL;
xvimagesink->xwindow = NULL; xvimagesink->xwindow = NULL;
@ -1151,7 +1110,7 @@ gst_xvimagesink_base_init (gpointer g_class)
gst_element_class_set_details (element_class, &gst_xvimagesink_details); gst_element_class_set_details (element_class, &gst_xvimagesink_details);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
GST_PAD_TEMPLATE_GET (gst_xvimagesink_sink_template_factory)); gst_static_pad_template_get (&gst_xvimagesink_sink_template_factory));
} }
static void static void

View file

@ -122,7 +122,7 @@ struct _GstXvImageSink {
GstXWindow *xwindow; GstXWindow *xwindow;
GstXvImage *xvimage; GstXvImage *xvimage;
gfloat framerate; gdouble framerate;
GMutex *x_lock; GMutex *x_lock;
/* Unused */ /* Unused */
@ -130,7 +130,6 @@ struct _GstXvImageSink {
GstClockTime time; GstClockTime time;
GstBufferPool *bufferpool;
GMutex *pool_lock; GMutex *pool_lock;
GSList *image_pool; GSList *image_pool;
}; };

View file

@ -12,78 +12,27 @@ struct probe_context {
gint total_ls; gint total_ls;
GstCaps *metadata; GstCaps *metadata;
GstCaps *streaminfo; GstCaps *streaminfo;
GstCaps *caps; GstCaps *caps;
}; };
static void static void
print_caps (GstCaps *caps) print_caps (GstCaps *caps)
{ {
if (caps == NULL) return; char *s;
if (!strcmp (gst_caps_get_mime (caps), "application/x-gst-metadata") || s = gst_caps_to_string (caps);
!strcmp (gst_caps_get_mime (caps), "application/x-gst-streaminfo")) g_print(" %s\n", s);
{ g_free (s);
GstProps *props = caps->properties;
GList *walk;
/* ugly hack, but ok for now. If needed, fix by individual strcmp */
g_print (" %s:\n", gst_caps_get_mime (caps) + 18);
if (props == NULL) {
g_print (" none\n");
return;
}
walk = props->properties;
while (walk) {
GstPropsEntry *entry = (GstPropsEntry *) walk->data;
const gchar *name;
const gchar *str_val;
gint int_val;
GstPropsType type;
name = gst_props_entry_get_name (entry);
type = gst_props_entry_get_props_type (entry);
switch (type) {
case GST_PROPS_STRING_TYPE:
gst_props_entry_get_string (entry, &str_val);
g_print (" %s='%s'\n", name, str_val);
break;
case GST_PROPS_INT_TYPE:
gst_props_entry_get_int (entry, &int_val);
g_print (" %s=%d\n", name, int_val);
break;
default:
break;
}
walk = g_list_next (walk);
}
}
else {
g_print (" unkown caps type\n");
}
} }
static void static void
print_format (GstCaps *caps) print_format (GstCaps *caps)
{ {
g_print (" format:\n"); char *s;
if (!caps || caps->properties == NULL) { s = gst_caps_to_string (caps);
g_print (" unkown\n"); g_print(" format: %s\n", s);
return; g_free (s);
}
if (!strcmp (gst_caps_get_mime (caps), "audio/raw")) {
gint channels;
gint rate;
gst_caps_get_int (caps, "channels", &channels);
gst_caps_get_int (caps, "rate", &rate);
g_print (" channels: %d\n", channels);
g_print (" rate: %d\n", rate);
}
else {
g_print (" unkown format\n");
}
} }
static void static void

View file

@ -12,78 +12,27 @@ struct probe_context {
gint total_ls; gint total_ls;
GstCaps *metadata; GstCaps *metadata;
GstCaps *streaminfo; GstCaps *streaminfo;
GstCaps *caps; GstCaps *caps;
}; };
static void static void
print_caps (GstCaps *caps) print_caps (GstCaps *caps)
{ {
if (caps == NULL) return; char *s;
if (!strcmp (gst_caps_get_mime (caps), "application/x-gst-metadata") || s = gst_caps_to_string (caps);
!strcmp (gst_caps_get_mime (caps), "application/x-gst-streaminfo")) g_print(" %s\n", s);
{ g_free (s);
GstProps *props = caps->properties;
GList *walk;
/* ugly hack, but ok for now. If needed, fix by individual strcmp */
g_print (" %s:\n", gst_caps_get_mime (caps) + 18);
if (props == NULL) {
g_print (" none\n");
return;
}
walk = props->properties;
while (walk) {
GstPropsEntry *entry = (GstPropsEntry *) walk->data;
const gchar *name;
const gchar *str_val;
gint int_val;
GstPropsType type;
name = gst_props_entry_get_name (entry);
type = gst_props_entry_get_props_type (entry);
switch (type) {
case GST_PROPS_STRING_TYPE:
gst_props_entry_get_string (entry, &str_val);
g_print (" %s='%s'\n", name, str_val);
break;
case GST_PROPS_INT_TYPE:
gst_props_entry_get_int (entry, &int_val);
g_print (" %s=%d\n", name, int_val);
break;
default:
break;
}
walk = g_list_next (walk);
}
}
else {
g_print (" unkown caps type\n");
}
} }
static void static void
print_format (GstCaps *caps) print_format (GstCaps *caps)
{ {
g_print (" format:\n"); char *s;
if (!caps || caps->properties == NULL) { s = gst_caps_to_string (caps);
g_print (" unkown\n"); g_print(" format: %s\n", s);
return; g_free (s);
}
if (!strcmp (gst_caps_get_mime (caps), "audio/raw")) {
gint channels;
gint rate;
gst_caps_get_int (caps, "channels", &channels);
gst_caps_get_int (caps, "rate", &rate);
g_print (" channels: %d\n", channels);
g_print (" rate: %d\n", rate);
}
else {
g_print (" unkown format\n");
}
} }
static void static void

View file

@ -39,8 +39,10 @@ sub check_old_typefind();
sub check_bad_casts(); sub check_bad_casts();
sub check_old_plugin(); sub check_old_plugin();
sub check_signal_new(); sub check_signal_new();
sub check_gnuc_const();
sub m_check_plugindir(); sub m_check_plugindir();
sub m_check_interfaces();
open FIND, "find . -name \"*.[ch]\" -print|"; open FIND, "find . -name \"*.[ch]\" -print|";
@ -71,6 +73,7 @@ foreach $filename (<FIND>) {
check_bad_casts(); check_bad_casts();
check_old_plugin(); check_old_plugin();
check_signal_new(); check_signal_new();
check_gnuc_const();
} }
open FIND, "find . -name \"Makefile.am\" -print|"; open FIND, "find . -name \"Makefile.am\" -print|";
@ -84,6 +87,7 @@ foreach $filename (<FIND>) {
print "I: $filename\n"; print "I: $filename\n";
m_check_plugindir(); m_check_plugindir();
m_check_interfaces();
} }
# #
@ -399,3 +403,35 @@ sub check_signal_new()
$lineno++; $lineno++;
} }
} }
#
# Check that libgstinterfaces is in LDADD
#
sub m_check_interfaces()
{
if (grep { /libgstinterfaces.la/ } @lines) {
if (! grep { /libgstinterfaces_la/ } @lines) {
if (! grep { /_LDADD.*libgstinterfaces.la/ } @lines) {
print "E: libgstinterfaces.la not in LDADD\n";
}
}
}
}
#
# Check that get_type() functions return G_CONST_RETURN GType
#
sub check_gnuc_const()
{
my $n = 0;
my $lineno = 1;
foreach $line (@lines){
if($line =~ /GType.*get_type.*/ &&
!($line =~ /GType.*get_type.*G_GNUC_CONST/)) {
print "E: get_type function does not have G_GNUC_CONST attribute\n";
}
}
}

View file

@ -39,8 +39,10 @@ sub check_old_typefind();
sub check_bad_casts(); sub check_bad_casts();
sub check_old_plugin(); sub check_old_plugin();
sub check_signal_new(); sub check_signal_new();
sub check_gnuc_const();
sub m_check_plugindir(); sub m_check_plugindir();
sub m_check_interfaces();
open FIND, "find . -name \"*.[ch]\" -print|"; open FIND, "find . -name \"*.[ch]\" -print|";
@ -71,6 +73,7 @@ foreach $filename (<FIND>) {
check_bad_casts(); check_bad_casts();
check_old_plugin(); check_old_plugin();
check_signal_new(); check_signal_new();
check_gnuc_const();
} }
open FIND, "find . -name \"Makefile.am\" -print|"; open FIND, "find . -name \"Makefile.am\" -print|";
@ -84,6 +87,7 @@ foreach $filename (<FIND>) {
print "I: $filename\n"; print "I: $filename\n";
m_check_plugindir(); m_check_plugindir();
m_check_interfaces();
} }
# #
@ -399,3 +403,35 @@ sub check_signal_new()
$lineno++; $lineno++;
} }
} }
#
# Check that libgstinterfaces is in LDADD
#
sub m_check_interfaces()
{
if (grep { /libgstinterfaces.la/ } @lines) {
if (! grep { /libgstinterfaces_la/ } @lines) {
if (! grep { /_LDADD.*libgstinterfaces.la/ } @lines) {
print "E: libgstinterfaces.la not in LDADD\n";
}
}
}
}
#
# Check that get_type() functions return G_CONST_RETURN GType
#
sub check_gnuc_const()
{
my $n = 0;
my $lineno = 1;
foreach $line (@lines){
if($line =~ /GType.*get_type.*/ &&
!($line =~ /GType.*get_type.*G_GNUC_CONST/)) {
print "E: get_type function does not have G_GNUC_CONST attribute\n";
}
}
}