diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c index 8358779f9b..c6bd95c651 100644 --- a/sys/ximage/ximagesink.c +++ b/sys/ximage/ximagesink.c @@ -1659,6 +1659,7 @@ gst_ximagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, GstCaps *alloc_caps; gboolean alloc_unref = FALSE; gint width, height; + GstVideoRectangle dst, src, result; ximagesink = GST_XIMAGESINK (bsink); @@ -1674,88 +1675,90 @@ gst_ximagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, /* get struct to see what is requested */ structure = gst_caps_get_structure (caps, 0); + if (!gst_structure_get_int (structure, "width", &width) || + !gst_structure_get_int (structure, "height", &height)) { + GST_WARNING_OBJECT (ximagesink, "invalid caps for buffer allocation %" + GST_PTR_FORMAT, caps); + ret = GST_FLOW_UNEXPECTED; + goto beach; + } - if (gst_structure_get_int (structure, "width", &width) && - gst_structure_get_int (structure, "height", &height)) { - GstVideoRectangle dst, src, result; - - src.w = width; - src.h = height; - - /* We take the flow_lock because the window might go away */ - g_mutex_lock (ximagesink->flow_lock); - if (!ximagesink->xwindow) { - g_mutex_unlock (ximagesink->flow_lock); - goto alloc; - } - - /* What is our geometry */ - gst_ximagesink_xwindow_update_geometry (ximagesink, ximagesink->xwindow); - dst.w = ximagesink->xwindow->width; - dst.h = ximagesink->xwindow->height; + src.w = width; + src.h = height; + /* We take the flow_lock because the window might go away */ + g_mutex_lock (ximagesink->flow_lock); + if (!ximagesink->xwindow) { g_mutex_unlock (ximagesink->flow_lock); + goto alloc; + } - if (ximagesink->keep_aspect) { - GST_LOG_OBJECT (ximagesink, "enforcing aspect ratio in reverse caps " - "negotiation"); - gst_video_sink_center_rect (src, dst, &result, TRUE); - } else { - GST_LOG_OBJECT (ximagesink, "trying to resize to window geometry " - "ignoring aspect ratio"); - result.x = result.y = 0; - result.w = dst.w; - result.h = dst.h; + /* What is our geometry */ + gst_ximagesink_xwindow_update_geometry (ximagesink, ximagesink->xwindow); + dst.w = ximagesink->xwindow->width; + dst.h = ximagesink->xwindow->height; + + g_mutex_unlock (ximagesink->flow_lock); + + if (ximagesink->keep_aspect) { + GST_LOG_OBJECT (ximagesink, "enforcing aspect ratio in reverse caps " + "negotiation"); + gst_video_sink_center_rect (src, dst, &result, TRUE); + } else { + GST_LOG_OBJECT (ximagesink, "trying to resize to window geometry " + "ignoring aspect ratio"); + result.x = result.y = 0; + result.w = dst.w; + result.h = dst.h; + } + + /* We would like another geometry */ + if (width != result.w || height != result.h) { + int nom, den; + GstCaps *desired_caps; + GstStructure *desired_struct; + + /* make a copy of the incomming caps to create the new + * suggestion. We can't use make_writable because we might + * then destroy the original caps which we still need when the + * peer does not accept the suggestion. */ + desired_caps = gst_caps_copy (caps); + desired_struct = gst_caps_get_structure (desired_caps, 0); + + GST_DEBUG ("we would love to receive a %dx%d video", result.w, result.h); + gst_structure_set (desired_struct, "width", G_TYPE_INT, result.w, NULL); + gst_structure_set (desired_struct, "height", G_TYPE_INT, result.h, NULL); + + /* PAR property overrides the X calculated one */ + if (ximagesink->par) { + nom = gst_value_get_fraction_numerator (ximagesink->par); + den = gst_value_get_fraction_denominator (ximagesink->par); + gst_structure_set (desired_struct, "pixel-aspect-ratio", + GST_TYPE_FRACTION, nom, den, NULL); + } else if (ximagesink->xcontext->par) { + nom = gst_value_get_fraction_numerator (ximagesink->xcontext->par); + den = gst_value_get_fraction_denominator (ximagesink->xcontext->par); + gst_structure_set (desired_struct, "pixel-aspect-ratio", + GST_TYPE_FRACTION, nom, den, NULL); } - /* We would like another geometry */ - if (width != result.w || height != result.h) { - int nom, den; - GstCaps *desired_caps; - GstStructure *desired_struct; - - /* make a copy of the incomming caps to create the new - * suggestion. We can't use make_writable because we might - * then destroy the original caps which we still need when the - * peer does not accept the suggestion. */ - desired_caps = gst_caps_copy (caps); - desired_struct = gst_caps_get_structure (desired_caps, 0); - - GST_DEBUG ("we would love to receive a %dx%d video", result.w, result.h); - gst_structure_set (desired_struct, "width", G_TYPE_INT, result.w, NULL); - gst_structure_set (desired_struct, "height", G_TYPE_INT, result.h, NULL); - - /* PAR property overrides the X calculated one */ - if (ximagesink->par) { - nom = gst_value_get_fraction_numerator (ximagesink->par); - den = gst_value_get_fraction_denominator (ximagesink->par); - gst_structure_set (desired_struct, "pixel-aspect-ratio", - GST_TYPE_FRACTION, nom, den, NULL); - } else if (ximagesink->xcontext->par) { - nom = gst_value_get_fraction_numerator (ximagesink->xcontext->par); - den = gst_value_get_fraction_denominator (ximagesink->xcontext->par); - gst_structure_set (desired_struct, "pixel-aspect-ratio", - GST_TYPE_FRACTION, nom, den, NULL); - } - - /* see if peer accepts our new suggestion, if there is no peer, this - * function returns true. */ - if (gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (ximagesink), - desired_caps)) { - /* we will not alloc a buffer of the new suggested caps. Make sure - * we also unref this new caps after we set it on the buffer. */ - alloc_caps = desired_caps; - alloc_unref = TRUE; - width = result.w; - height = result.h; - GST_DEBUG ("peer pad accepts our desired caps %" GST_PTR_FORMAT, - desired_caps); - } else { - GST_DEBUG ("peer pad does not accept our desired caps %" GST_PTR_FORMAT, - desired_caps); - /* we alloc a buffer with the original incomming caps already in the - * width and height variables */ - } + /* see if peer accepts our new suggestion, if there is no peer, this + * function returns true. */ + if (gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (ximagesink), + desired_caps)) { + /* we will not alloc a buffer of the new suggested caps. Make sure + * we also unref this new caps after we set it on the buffer. */ + alloc_caps = desired_caps; + alloc_unref = TRUE; + width = result.w; + height = result.h; + GST_DEBUG ("peer pad accepts our desired caps %" GST_PTR_FORMAT, + desired_caps); + } else { + GST_DEBUG ("peer pad does not accept our desired caps %" GST_PTR_FORMAT, + desired_caps); + /* we alloc a buffer with the original incomming caps already in the + * width and height variables */ } } @@ -1799,6 +1802,7 @@ alloc: *buf = GST_BUFFER_CAST (ximage); +beach: return ret; }