sys/xvimage/xvimagesink.c: I think one day i'll completely undestand how caps negotiation is supposed to work. This r...

Original commit message from CVS:
2006-01-21  Julien MOUTTE  <julien@moutte.net>

* sys/xvimage/xvimagesink.c: (gst_xvimagesink_buffer_alloc):
I think one day i'll completely undestand how caps negotiation
is supposed to work. This refactoring handles buffer_alloc
called with caps we can't handle. We definitely don't want a
set_caps with those caps, so we define and allocate a buffer
we would like to receive.
This commit is contained in:
Julien Moutte 2006-01-21 22:40:03 +00:00
parent 25df39b708
commit db4de40ebf
2 changed files with 96 additions and 6 deletions

View file

@ -1,3 +1,12 @@
2006-01-21 Julien MOUTTE <julien@moutte.net>
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_buffer_alloc):
I think one day i'll completely undestand how caps negotiation
is supposed to work. This refactoring handles buffer_alloc
called with caps we can't handle. We definitely don't want a
set_caps with those caps, so we define and allocate a buffer
we would like to receive.
2006-01-19 Tim-Philipp Müller <tim at centricular dot net>
* gst/playback/gstplaybasebin.c: (setup_source):

View file

@ -1804,11 +1804,86 @@ static GstFlowReturn
gst_xvimagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
GstCaps * caps, GstBuffer ** buf)
{
GstFlowReturn ret = GST_FLOW_OK;
GstXvImageSink *xvimagesink;
GstXvImageBuffer *xvimage = NULL;
GstCaps *intersection = NULL;
GstStructure *structure = NULL;
gint width, height, image_format;
xvimagesink = GST_XVIMAGESINK (bsink);
GST_DEBUG_OBJECT (xvimagesink, "buffer alloc requested with caps %"
GST_PTR_FORMAT "intersecting with our caps %" GST_PTR_FORMAT, caps,
xvimagesink->xcontext->caps);
/* Check the caps against our xcontext */
intersection = gst_caps_intersect (xvimagesink->xcontext->caps, caps);
GST_DEBUG_OBJECT (xvimagesink, "intersection in buffer alloc returned %"
GST_PTR_FORMAT, intersection);
if (gst_caps_is_empty (intersection)) {
/* So we don't support this kind of buffer, let's define one we'd like */
GstCaps *new_caps = gst_caps_copy (caps);
structure = gst_caps_get_structure (new_caps, 0);
/* Try with YUV first */
gst_structure_set_name (structure, "video/x-raw-yuv");
gst_structure_remove_field (structure, "format");
gst_structure_remove_field (structure, "endianness");
gst_structure_remove_field (structure, "depth");
gst_structure_remove_field (structure, "bpp");
gst_structure_remove_field (structure, "red_mask");
gst_structure_remove_field (structure, "green_mask");
gst_structure_remove_field (structure, "blue_mask");
gst_structure_remove_field (structure, "alpha_mask");
/* Reuse intersection with Xcontext */
gst_caps_unref (intersection);
intersection = gst_caps_intersect (xvimagesink->xcontext->caps, new_caps);
if (gst_caps_is_empty (intersection)) {
/* Now try with RGB */
gst_structure_set_name (structure, "video/x-raw-rgb");
/* And interset again */
gst_caps_unref (intersection);
intersection = gst_caps_intersect (xvimagesink->xcontext->caps, new_caps);
if (gst_caps_is_empty (intersection)) {
GST_WARNING_OBJECT (xvimagesink, "we were requested a buffer with "
"caps %" GST_PTR_FORMAT "but our xcontext caps %" GST_PTR_FORMAT
"are completely incompatible with those caps", new_caps,
xvimagesink->xcontext->caps);
gst_caps_unref (new_caps);
ret = GST_FLOW_UNEXPECTED;
goto beach;
}
}
/* Clean this copy */
gst_caps_unref (new_caps);
/* We want fixed caps */
gst_caps_truncate (intersection);
GST_DEBUG_OBJECT (xvimagesink, "allocating a buffer with caps %"
GST_PTR_FORMAT, intersection);
}
/* Get image format from caps */
image_format = gst_xvimagesink_get_format_from_caps (xvimagesink,
intersection);
/* Get geometry from caps */
structure = gst_caps_get_structure (intersection, 0);
if (!gst_structure_get_int (structure, "width", &width) ||
!gst_structure_get_int (structure, "height", &height) || !image_format) {
GST_WARNING_OBJECT (xvimagesink, "invalid caps for buffer allocation %"
GST_PTR_FORMAT, intersection);
ret = GST_FLOW_UNEXPECTED;
goto beach;
}
g_mutex_lock (xvimagesink->pool_lock);
/* Walking through the pool cleaning unusable images and searching for a
@ -1822,9 +1897,8 @@ gst_xvimagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
xvimagesink->image_pool);
/* We check for geometry or image format changes */
if ((xvimage->width != xvimagesink->video_width) ||
(xvimage->height != xvimagesink->video_height) ||
(xvimage->im_format != xvimagesink->xcontext->im_format)) {
if ((xvimage->width != width) ||
(xvimage->height != height) || (xvimage->im_format != image_format)) {
/* This image is unusable. Destroying... */
gst_xvimage_buffer_free (xvimage);
xvimage = NULL;
@ -1841,14 +1915,21 @@ gst_xvimagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
if (!xvimage) {
/* We found no suitable image in the pool. Creating... */
GST_DEBUG_OBJECT (xvimagesink, "no usable image in pool, creating xvimage");
xvimage = gst_xvimagesink_xvimage_new (xvimagesink, caps);
xvimage = gst_xvimagesink_xvimage_new (xvimagesink, intersection);
}
if (xvimage) {
gst_buffer_set_caps (GST_BUFFER (xvimage), caps);
gst_buffer_set_caps (GST_BUFFER (xvimage), intersection);
}
*buf = GST_BUFFER (xvimage);
return GST_FLOW_OK;
beach:
if (intersection) {
gst_caps_unref (intersection);
}
return ret;
}
/* Interfaces stuff */