mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
va: basetransform: Check the crop meta when importing
When the input buffer has crop meta, and we need to do copy, we should consider the uncropped video size and copy the full size of video memory. The video meta in this case should contain the full uncropped resolution info. We can use it to create full size va buffers. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4887>
This commit is contained in:
parent
703ab45334
commit
ff2a75a2dd
1 changed files with 67 additions and 2 deletions
|
@ -49,6 +49,8 @@ struct _GstVaBaseTransformPrivate
|
||||||
GstCaps *sinkpad_caps;
|
GstCaps *sinkpad_caps;
|
||||||
GstVideoInfo sinkpad_info;
|
GstVideoInfo sinkpad_info;
|
||||||
GstBufferPool *sinkpad_pool;
|
GstBufferPool *sinkpad_pool;
|
||||||
|
guint uncropped_width;
|
||||||
|
guint uncropped_height;
|
||||||
|
|
||||||
GstCaps *filter_caps;
|
GstCaps *filter_caps;
|
||||||
};
|
};
|
||||||
|
@ -756,8 +758,54 @@ _try_import_dmabuf_unlocked (GstVaBaseTransform * self, GstBuffer * inbuf)
|
||||||
mems, fd, offset, VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ);
|
mems, fd, offset, VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_check_uncropped_size (GstVaBaseTransform * self, GstBuffer * inbuf)
|
||||||
|
{
|
||||||
|
GstVideoCropMeta *crop_meta;
|
||||||
|
GstVideoMeta *video_meta;
|
||||||
|
|
||||||
|
crop_meta = gst_buffer_get_video_crop_meta (inbuf);
|
||||||
|
video_meta = gst_buffer_get_video_meta (inbuf);
|
||||||
|
|
||||||
|
if (!crop_meta) {
|
||||||
|
if (self->priv->uncropped_width > 0 || self->priv->uncropped_height > 0) {
|
||||||
|
self->priv->uncropped_width = 0;
|
||||||
|
self->priv->uncropped_height = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!video_meta) {
|
||||||
|
GST_WARNING_OBJECT (self, "The buffer has video crop meta without "
|
||||||
|
"video meta, the cropped result may be wrong.");
|
||||||
|
self->priv->uncropped_width = 0;
|
||||||
|
self->priv->uncropped_height = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (video_meta->width < crop_meta->x + crop_meta->width ||
|
||||||
|
video_meta->height < crop_meta->y + crop_meta->height) {
|
||||||
|
GST_WARNING_OBJECT (self, "Invalid video meta or crop meta, "
|
||||||
|
"the cropped result may be wrong.");
|
||||||
|
self->priv->uncropped_width = 0;
|
||||||
|
self->priv->uncropped_height = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->priv->uncropped_width != video_meta->width ||
|
||||||
|
self->priv->uncropped_height != video_meta->height) {
|
||||||
|
self->priv->uncropped_width = video_meta->width;
|
||||||
|
self->priv->uncropped_height = video_meta->height;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static GstBufferPool *
|
static GstBufferPool *
|
||||||
_get_sinkpad_pool (GstVaBaseTransform * self)
|
_get_sinkpad_pool (GstVaBaseTransform * self, GstBuffer * inbuf)
|
||||||
{
|
{
|
||||||
GstAllocator *allocator;
|
GstAllocator *allocator;
|
||||||
GstAllocationParams params = { 0, };
|
GstAllocationParams params = { 0, };
|
||||||
|
@ -765,6 +813,13 @@ _get_sinkpad_pool (GstVaBaseTransform * self)
|
||||||
GstVideoInfo in_info;
|
GstVideoInfo in_info;
|
||||||
guint size, usage_hint = VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ;
|
guint size, usage_hint = VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ;
|
||||||
|
|
||||||
|
if (_check_uncropped_size (self, inbuf)) {
|
||||||
|
if (self->priv->sinkpad_pool)
|
||||||
|
gst_buffer_pool_set_active (self->priv->sinkpad_pool, FALSE);
|
||||||
|
|
||||||
|
gst_clear_object (&self->priv->sinkpad_pool);
|
||||||
|
}
|
||||||
|
|
||||||
if (self->priv->sinkpad_pool)
|
if (self->priv->sinkpad_pool)
|
||||||
return self->priv->sinkpad_pool;
|
return self->priv->sinkpad_pool;
|
||||||
|
|
||||||
|
@ -776,6 +831,16 @@ _get_sinkpad_pool (GstVaBaseTransform * self)
|
||||||
gst_caps_set_features_simple (caps,
|
gst_caps_set_features_simple (caps,
|
||||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VA));
|
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VA));
|
||||||
|
|
||||||
|
/* When the input buffer contains video crop meta, the real video
|
||||||
|
resolution can be bigger than the caps. The video meta should
|
||||||
|
contain the real video resolution. */
|
||||||
|
if (self->priv->uncropped_width > 0)
|
||||||
|
gst_caps_set_simple (caps, "width", G_TYPE_INT,
|
||||||
|
self->priv->uncropped_width, NULL);
|
||||||
|
if (self->priv->uncropped_height > 0)
|
||||||
|
gst_caps_set_simple (caps, "height", G_TYPE_INT,
|
||||||
|
self->priv->uncropped_height, NULL);
|
||||||
|
|
||||||
if (!gst_video_info_from_caps (&in_info, caps)) {
|
if (!gst_video_info_from_caps (&in_info, caps)) {
|
||||||
GST_ERROR_OBJECT (self, "Cannot parse caps %" GST_PTR_FORMAT, caps);
|
GST_ERROR_OBJECT (self, "Cannot parse caps %" GST_PTR_FORMAT, caps);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
@ -849,7 +914,7 @@ gst_va_base_transform_import_buffer (GstVaBaseTransform * self,
|
||||||
/* input buffer doesn't come from a vapool, thus it is required to
|
/* input buffer doesn't come from a vapool, thus it is required to
|
||||||
* have a pool, grab from it a new buffer and copy the input
|
* have a pool, grab from it a new buffer and copy the input
|
||||||
* buffer to the new one */
|
* buffer to the new one */
|
||||||
if (!(pool = _get_sinkpad_pool (self)))
|
if (!(pool = _get_sinkpad_pool (self, inbuf)))
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
|
||||||
ret = gst_buffer_pool_acquire_buffer (pool, &buffer, NULL);
|
ret = gst_buffer_pool_acquire_buffer (pool, &buffer, NULL);
|
||||||
|
|
Loading…
Reference in a new issue