mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-24 06:56:26 +00:00
convertframe: Fix video crop meta handling
Cropping parameters were being miscalculated - getting the output width/height wrong when an x/y crop offset was given. Cropping was also incorrectly being applied twice (because at some point after the convertframe code was written, `videocrop` also started paying attention to the GstVideoCropMeta, but not in useful ways for this purpose). Add a buffer probe to strip the crop meta from the input buffer so videocrop can do its job correctly. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8526>
This commit is contained in:
parent
8d42a7e233
commit
ae33acda5d
1 changed files with 34 additions and 6 deletions
|
@ -218,6 +218,25 @@ failed:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstPadProbeReturn
|
||||||
|
strip_video_crop_meta (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||||
|
{
|
||||||
|
GstBuffer *buf = gst_pad_probe_info_get_buffer (info);
|
||||||
|
GstVideoCropMeta *cmeta = gst_buffer_get_video_crop_meta (buf);
|
||||||
|
|
||||||
|
if (cmeta != NULL) {
|
||||||
|
/* Make the buffer writable before stripping the meta and
|
||||||
|
* putting the possibly-replaced buffer back into
|
||||||
|
* the pad probe data */
|
||||||
|
GST_DEBUG ("Removing video crop meta from input buffer");
|
||||||
|
buf = gst_buffer_make_writable (buf);
|
||||||
|
gst_buffer_remove_meta (buf, GST_META_CAST (cmeta));
|
||||||
|
GST_PAD_PROBE_INFO_DATA (info) = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GST_PAD_PROBE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static GstElement *
|
static GstElement *
|
||||||
build_convert_frame_pipeline (GstElement ** src_element,
|
build_convert_frame_pipeline (GstElement ** src_element,
|
||||||
GstElement ** sink_element, GstCaps * from_caps,
|
GstElement ** sink_element, GstCaps * from_caps,
|
||||||
|
@ -291,16 +310,25 @@ build_convert_frame_pipeline (GstElement ** src_element,
|
||||||
gst_video_info_from_caps (&info, from_caps);
|
gst_video_info_from_caps (&info, from_caps);
|
||||||
g_object_set (vcrop, "left", cmeta->x, NULL);
|
g_object_set (vcrop, "left", cmeta->x, NULL);
|
||||||
g_object_set (vcrop, "top", cmeta->y, NULL);
|
g_object_set (vcrop, "top", cmeta->y, NULL);
|
||||||
g_object_set (vcrop, "right", GST_VIDEO_INFO_WIDTH (&info) - cmeta->width,
|
g_object_set (vcrop, "right",
|
||||||
NULL);
|
GST_VIDEO_INFO_WIDTH (&info) - (cmeta->x + cmeta->width), NULL);
|
||||||
g_object_set (vcrop, "bottom",
|
g_object_set (vcrop, "bottom",
|
||||||
GST_VIDEO_INFO_HEIGHT (&info) - cmeta->height, NULL);
|
GST_VIDEO_INFO_HEIGHT (&info) - (cmeta->y + cmeta->height), NULL);
|
||||||
|
|
||||||
|
/* Because we are asking videocrop to apply the cropping explicitly,
|
||||||
|
* we need to give it a buffer without crop meta, or the crop amounts end up
|
||||||
|
* getting applied twice. Add a probe to strip the meta and use videocrop's
|
||||||
|
* properties */
|
||||||
|
GstPad *sink = gst_element_get_static_pad (vcrop, "sink");
|
||||||
|
g_assert (sink != NULL);
|
||||||
|
gst_pad_add_probe (sink, GST_PAD_PROBE_TYPE_BUFFER,
|
||||||
|
strip_video_crop_meta, NULL, NULL);
|
||||||
|
gst_object_unref (sink);
|
||||||
|
|
||||||
GST_DEBUG ("crop meta [x,y,width,height]: %d %d %d %d", cmeta->x, cmeta->y,
|
GST_DEBUG ("crop meta [x,y,width,height]: %d %d %d %d", cmeta->x, cmeta->y,
|
||||||
cmeta->width, cmeta->height);
|
cmeta->width, cmeta->height);
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: linking is still way too expensive, profile this properly */
|
/* FIXME: linking is still way too expensive, profile this properly */
|
||||||
if (vcrop) {
|
|
||||||
if (!dl) {
|
if (!dl) {
|
||||||
GST_DEBUG ("linking src->csp2");
|
GST_DEBUG ("linking src->csp2");
|
||||||
if (!gst_element_link_pads (src, "src", csp2, "sink"))
|
if (!gst_element_link_pads (src, "src", csp2, "sink"))
|
||||||
|
|
Loading…
Reference in a new issue