mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 14:36:24 +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;
|
||||
}
|
||||
|
||||
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 *
|
||||
build_convert_frame_pipeline (GstElement ** src_element,
|
||||
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);
|
||||
g_object_set (vcrop, "left", cmeta->x, NULL);
|
||||
g_object_set (vcrop, "top", cmeta->y, NULL);
|
||||
g_object_set (vcrop, "right", GST_VIDEO_INFO_WIDTH (&info) - cmeta->width,
|
||||
NULL);
|
||||
g_object_set (vcrop, "right",
|
||||
GST_VIDEO_INFO_WIDTH (&info) - (cmeta->x + cmeta->width), NULL);
|
||||
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,
|
||||
cmeta->width, cmeta->height);
|
||||
}
|
||||
|
||||
/* FIXME: linking is still way too expensive, profile this properly */
|
||||
if (vcrop) {
|
||||
/* FIXME: linking is still way too expensive, profile this properly */
|
||||
if (!dl) {
|
||||
GST_DEBUG ("linking src->csp2");
|
||||
if (!gst_element_link_pads (src, "src", csp2, "sink"))
|
||||
|
|
Loading…
Reference in a new issue