mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
vaapipostproc: advertise crop meta is handled
Advertise to upstream that vaapipostproc can handle crop meta. When used in conjunction with videocrop plugin, the videocrop plugin will only do in-place transform on the crop meta when vaapipostproc advertises the ability to handle it. This allows vaapipostproc to apply the crop meta on the output buffer using vaapi acceleration. Without this advertisement, the videocrop plugin will crop the output buffer directly via software methods, which is not what we desire. vaapipostproc will not apply the crop meta if downstream advertises crop meta handling; vaapipostproc will just forward the crop meta to downstream. If crop meta is not advertised by downstream, then vaapipostproc will apply the crop meta. Examples: 1. vaapipostproc will forward crop meta to vaapisink gst-launch-1.0 videotestsrc \ ! videocrop left=10 \ ! vaapipostproc \ ! vaapisink 2. vaapipostproc will do the cropping gst-launch-1.0 videotestsrc \ ! videocrop left=10 \ ! vaapipostproc \ ! identity drop-allocation=1 \ ! vaapisink
This commit is contained in:
parent
f52d545fd0
commit
6700f642fc
2 changed files with 69 additions and 20 deletions
|
@ -672,6 +672,12 @@ replace_to_dumb_buffer_if_required (GstVaapiPostproc * postproc,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
use_vpp_crop (GstVaapiPostproc * postproc)
|
||||
{
|
||||
return !postproc->forward_crop;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf,
|
||||
GstBuffer * outbuf)
|
||||
|
@ -698,7 +704,9 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf,
|
|||
inbuf_surface = gst_vaapi_video_meta_get_surface (inbuf_meta);
|
||||
|
||||
crop_meta = gst_buffer_get_video_crop_meta (inbuf);
|
||||
if (crop_meta) {
|
||||
if (crop_meta && use_vpp_crop (postproc)) {
|
||||
GST_DEBUG_OBJECT (postproc, "cropping x=%d,y=%d,w=%d,h=%d",
|
||||
crop_meta->x, crop_meta->y, crop_meta->width, crop_meta->height);
|
||||
crop_rect = &tmp_rect;
|
||||
crop_rect->x = crop_meta->x;
|
||||
crop_rect->y = crop_meta->y;
|
||||
|
@ -860,6 +868,7 @@ gst_vaapipostproc_process_vpp (GstBaseTransform * trans, GstBuffer * inbuf,
|
|||
discont = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
copy_metadata (postproc, outbuf, inbuf);
|
||||
|
||||
if (deint && deint_refs)
|
||||
|
@ -1332,8 +1341,9 @@ gst_vaapipostproc_transform_meta (GstBaseTransform * trans, GstBuffer * outbuf,
|
|||
{
|
||||
GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans);
|
||||
|
||||
/* dont' GstVideoCropMeta if use_vpp */
|
||||
if (meta->info->api == GST_VIDEO_CROP_META_API_TYPE && postproc->use_vpp)
|
||||
/* don't copy GstVideoCropMeta if we are using vpp crop */
|
||||
if (meta->info->api == GST_VIDEO_CROP_META_API_TYPE
|
||||
&& use_vpp_crop (postproc))
|
||||
return FALSE;
|
||||
|
||||
/* don't copy GstParentBufferMeta if use_vpp */
|
||||
|
@ -1401,17 +1411,56 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_buffer_pool (GstVaapiPostproc * postproc, GstVideoInfo * vi)
|
||||
{
|
||||
GstVaapiVideoPool *pool;
|
||||
|
||||
if (!vi)
|
||||
return FALSE;
|
||||
|
||||
gst_video_info_change_format (vi, postproc->format,
|
||||
GST_VIDEO_INFO_WIDTH (vi), GST_VIDEO_INFO_HEIGHT (vi));
|
||||
|
||||
if (postproc->filter_pool
|
||||
&& !video_info_changed (&postproc->filter_pool_info, vi))
|
||||
return TRUE;
|
||||
postproc->filter_pool_info = *vi;
|
||||
|
||||
pool =
|
||||
gst_vaapi_surface_pool_new_full (GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc),
|
||||
&postproc->filter_pool_info, 0);
|
||||
if (!pool)
|
||||
return FALSE;
|
||||
|
||||
gst_vaapi_video_pool_replace (&postproc->filter_pool, pool);
|
||||
gst_vaapi_video_pool_unref (pool);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_vaapipostproc_prepare_output_buffer (GstBaseTransform * trans,
|
||||
GstBuffer * inbuf, GstBuffer ** outbuf_ptr)
|
||||
{
|
||||
GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans);
|
||||
const GstVideoCropMeta *crop_meta;
|
||||
GstVideoInfo info;
|
||||
|
||||
if (gst_base_transform_is_passthrough (trans)) {
|
||||
*outbuf_ptr = inbuf;
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
/* If we are not using vpp crop (i.e. forwarding crop meta to downstream)
|
||||
* then, ensure our output buffer pool is sized for uncropped output */
|
||||
crop_meta = gst_buffer_get_video_crop_meta (inbuf);
|
||||
if (crop_meta && !use_vpp_crop (postproc)) {
|
||||
info = postproc->srcpad_info;
|
||||
info.width += crop_meta->x;
|
||||
info.height += crop_meta->y;
|
||||
ensure_buffer_pool (postproc, &info);
|
||||
}
|
||||
|
||||
if (GST_VAAPI_PLUGIN_BASE_COPY_OUTPUT_FRAME (trans)) {
|
||||
*outbuf_ptr = create_output_dump_buffer (postproc);
|
||||
} else {
|
||||
|
@ -1428,27 +1477,11 @@ static gboolean
|
|||
ensure_srcpad_buffer_pool (GstVaapiPostproc * postproc, GstCaps * caps)
|
||||
{
|
||||
GstVideoInfo vi;
|
||||
GstVaapiVideoPool *pool;
|
||||
|
||||
if (!gst_video_info_from_caps (&vi, caps))
|
||||
return FALSE;
|
||||
gst_video_info_change_format (&vi, postproc->format,
|
||||
GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi));
|
||||
|
||||
if (postproc->filter_pool
|
||||
&& !video_info_changed (&postproc->filter_pool_info, &vi))
|
||||
return TRUE;
|
||||
postproc->filter_pool_info = vi;
|
||||
|
||||
pool =
|
||||
gst_vaapi_surface_pool_new_full (GST_VAAPI_PLUGIN_BASE_DISPLAY (postproc),
|
||||
&postproc->filter_pool_info, 0);
|
||||
if (!pool)
|
||||
return FALSE;
|
||||
|
||||
gst_vaapi_video_pool_replace (&postproc->filter_pool, pool);
|
||||
gst_vaapi_video_pool_unref (pool);
|
||||
return TRUE;
|
||||
return ensure_buffer_pool (postproc, &vi);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -1552,6 +1585,10 @@ gst_vaapipostproc_propose_allocation (GstBaseTransform * trans,
|
|||
gint allocation_width, allocation_height;
|
||||
gint negotiated_width, negotiated_height;
|
||||
|
||||
/* advertise to upstream that we can handle crop meta */
|
||||
if (decide_query)
|
||||
gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL);
|
||||
|
||||
negotiated_width = GST_VIDEO_INFO_WIDTH (&postproc->sinkpad_info);
|
||||
negotiated_height = GST_VIDEO_INFO_HEIGHT (&postproc->sinkpad_info);
|
||||
|
||||
|
@ -1588,6 +1625,16 @@ bail:
|
|||
static gboolean
|
||||
gst_vaapipostproc_decide_allocation (GstBaseTransform * trans, GstQuery * query)
|
||||
{
|
||||
GstVaapiPostproc *const postproc = GST_VAAPIPOSTPROC (trans);
|
||||
|
||||
g_mutex_lock (&postproc->postproc_lock);
|
||||
/* Let downstream handle the crop meta if they support it */
|
||||
postproc->forward_crop = (gst_query_find_allocation_meta (query,
|
||||
GST_VIDEO_CROP_META_API_TYPE, NULL) &&
|
||||
gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL));
|
||||
GST_DEBUG_OBJECT (postproc, "use_vpp_crop=%d", use_vpp_crop (postproc));
|
||||
g_mutex_unlock (&postproc->postproc_lock);
|
||||
|
||||
return gst_vaapi_plugin_base_decide_allocation (GST_VAAPI_PLUGIN_BASE (trans),
|
||||
query);
|
||||
}
|
||||
|
@ -2172,6 +2219,7 @@ gst_vaapipostproc_init (GstVaapiPostproc * postproc)
|
|||
postproc->field_duration = GST_CLOCK_TIME_NONE;
|
||||
postproc->keep_aspect = TRUE;
|
||||
postproc->get_va_surfaces = TRUE;
|
||||
postproc->forward_crop = FALSE;
|
||||
|
||||
/* AUTO is not valid for tag_video_direction, this is just to
|
||||
* ensure we setup the method as sink event tag */
|
||||
|
|
|
@ -175,6 +175,7 @@ struct _GstVaapiPostproc
|
|||
gfloat contrast;
|
||||
|
||||
gboolean skintone_enhance;
|
||||
gboolean forward_crop;
|
||||
|
||||
guint get_va_surfaces:1;
|
||||
guint has_vpp:1;
|
||||
|
|
Loading…
Reference in a new issue