mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-10 10:04:23 +00:00
ximagsink: do not access uninitialized height variable.
Exit like in xvimagesink, if we have partial caps.
This commit is contained in:
parent
ea2e208cc1
commit
bc4388c413
1 changed files with 80 additions and 76 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue