mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 13:41:48 +00:00
plugins: add support for video cropping.
Add support for GstVideoCropMeta in GStreamer >= 1.0.x builds and gst-vaapi specific meta information to hold video cropping details. Make the sink support video cropping in X11 and GLX modes.
This commit is contained in:
parent
dbb58f4152
commit
5bbab30859
3 changed files with 82 additions and 17 deletions
|
@ -276,10 +276,13 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec)
|
|||
GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
|
||||
GstVaapiSurfaceProxy *proxy;
|
||||
GstVaapiDecoderStatus status;
|
||||
GstVaapiVideoMeta *meta;
|
||||
GstVideoCodecFrame *out_frame;
|
||||
GstFlowReturn ret;
|
||||
#if GST_CHECK_VERSION(1,0,0)
|
||||
const GstVaapiRectangle *crop_rect;
|
||||
GstVaapiVideoMeta *meta;
|
||||
guint flags;
|
||||
#endif
|
||||
|
||||
status = gst_vaapi_decoder_get_frame_with_timeout(decode->decoder,
|
||||
&out_frame, 100000);
|
||||
|
@ -313,6 +316,18 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec)
|
|||
out_flags |= GST_VIDEO_BUFFER_FLAG_ONEFIELD;
|
||||
GST_BUFFER_FLAG_SET(out_frame->output_buffer, out_flags);
|
||||
}
|
||||
|
||||
crop_rect = gst_vaapi_surface_proxy_get_crop_rect(proxy);
|
||||
if (crop_rect) {
|
||||
GstVideoCropMeta * const crop_meta =
|
||||
gst_buffer_add_video_crop_meta(out_frame->output_buffer);
|
||||
if (crop_meta) {
|
||||
crop_meta->x = crop_rect->x;
|
||||
crop_meta->y = crop_rect->y;
|
||||
crop_meta->width = crop_rect->width;
|
||||
crop_meta->height = crop_rect->height;
|
||||
}
|
||||
}
|
||||
#else
|
||||
out_frame->output_buffer =
|
||||
gst_vaapi_video_buffer_new_with_surface_proxy(proxy);
|
||||
|
|
|
@ -827,20 +827,37 @@ render_background(GstVaapiSink *sink)
|
|||
}
|
||||
|
||||
static void
|
||||
render_frame(GstVaapiSink *sink)
|
||||
render_frame(GstVaapiSink *sink, GstVaapiSurface *surface,
|
||||
const GstVaapiRectangle *surface_rect)
|
||||
{
|
||||
const guint x1 = sink->display_rect.x;
|
||||
const guint x2 = sink->display_rect.x + sink->display_rect.width;
|
||||
const guint y1 = sink->display_rect.y;
|
||||
const guint y2 = sink->display_rect.y + sink->display_rect.height;
|
||||
gfloat tx1, tx2, ty1, ty2;
|
||||
guint width, height;
|
||||
|
||||
if (surface_rect) {
|
||||
gst_vaapi_surface_get_size(surface, &width, &height);
|
||||
tx1 = (gfloat)surface_rect->x / width;
|
||||
ty1 = (gfloat)surface_rect->y / height;
|
||||
tx2 = (gfloat)(surface_rect->x + surface_rect->width) / width;
|
||||
ty2 = (gfloat)(surface_rect->y + surface_rect->height) / height;
|
||||
}
|
||||
else {
|
||||
tx1 = 0.0f;
|
||||
ty1 = 0.0f;
|
||||
tx2 = 1.0f;
|
||||
ty2 = 1.0f;
|
||||
}
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glBegin(GL_QUADS);
|
||||
{
|
||||
glTexCoord2f(0.0f, 0.0f); glVertex2i(x1, y1);
|
||||
glTexCoord2f(0.0f, 1.0f); glVertex2i(x1, y2);
|
||||
glTexCoord2f(1.0f, 1.0f); glVertex2i(x2, y2);
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex2i(x2, y1);
|
||||
glTexCoord2f(tx1, ty1); glVertex2i(x1, y1);
|
||||
glTexCoord2f(tx1, ty2); glVertex2i(x1, y2);
|
||||
glTexCoord2f(tx2, ty2); glVertex2i(x2, y2);
|
||||
glTexCoord2f(tx2, ty1); glVertex2i(x2, y1);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
@ -869,9 +886,10 @@ render_reflection(GstVaapiSink *sink)
|
|||
|
||||
static gboolean
|
||||
gst_vaapisink_show_frame_glx(
|
||||
GstVaapiSink *sink,
|
||||
GstVaapiSurface *surface,
|
||||
guint flags
|
||||
GstVaapiSink *sink,
|
||||
GstVaapiSurface *surface,
|
||||
const GstVaapiRectangle *surface_rect,
|
||||
guint flags
|
||||
)
|
||||
{
|
||||
GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window);
|
||||
|
@ -909,7 +927,7 @@ gst_vaapisink_show_frame_glx(
|
|||
glRotatef(20.0f, 0.0f, 1.0f, 0.0f);
|
||||
glTranslatef(50.0f, 0.0f, 0.0f);
|
||||
}
|
||||
render_frame(sink);
|
||||
render_frame(sink, surface, surface_rect);
|
||||
if (sink->use_reflection) {
|
||||
glPushMatrix();
|
||||
glTranslatef(0.0, (GLfloat)sink->display_rect.height + 5.0f, 0.0f);
|
||||
|
@ -939,13 +957,14 @@ error_transfer_surface:
|
|||
|
||||
static inline gboolean
|
||||
gst_vaapisink_put_surface(
|
||||
GstVaapiSink *sink,
|
||||
GstVaapiSurface *surface,
|
||||
guint flags
|
||||
GstVaapiSink *sink,
|
||||
GstVaapiSurface *surface,
|
||||
const GstVaapiRectangle *surface_rect,
|
||||
guint flags
|
||||
)
|
||||
{
|
||||
if (!gst_vaapi_window_put_surface(sink->window, surface,
|
||||
NULL, &sink->display_rect, flags)) {
|
||||
surface_rect, &sink->display_rect, flags)) {
|
||||
GST_DEBUG("could not render VA surface");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -961,12 +980,26 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer)
|
|||
GstBuffer *buffer;
|
||||
guint flags;
|
||||
gboolean success;
|
||||
GstVaapiRectangle *surface_rect = NULL;
|
||||
#if GST_CHECK_VERSION(1,0,0)
|
||||
GstVaapiRectangle tmp_rect;
|
||||
#endif
|
||||
|
||||
meta = gst_buffer_get_vaapi_video_meta(src_buffer);
|
||||
#if GST_CHECK_VERSION(1,0,0)
|
||||
if (!meta)
|
||||
return GST_FLOW_EOS;
|
||||
buffer = gst_buffer_ref(src_buffer);
|
||||
|
||||
GstVideoCropMeta * const crop_meta =
|
||||
gst_buffer_get_video_crop_meta(buffer);
|
||||
if (crop_meta) {
|
||||
surface_rect = &tmp_rect;
|
||||
surface_rect->x = crop_meta->x;
|
||||
surface_rect->y = crop_meta->y;
|
||||
surface_rect->width = crop_meta->width;
|
||||
surface_rect->height = crop_meta->height;
|
||||
}
|
||||
#else
|
||||
if (meta)
|
||||
buffer = gst_buffer_ref(src_buffer);
|
||||
|
@ -1004,6 +1037,15 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer)
|
|||
GST_DEBUG("render surface %" GST_VAAPI_ID_FORMAT,
|
||||
GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface)));
|
||||
|
||||
if (!surface_rect)
|
||||
surface_rect = (GstVaapiRectangle *)
|
||||
gst_vaapi_video_meta_get_render_rect(meta);
|
||||
|
||||
if (surface_rect)
|
||||
GST_DEBUG("render rect (%d,%d), size %ux%u",
|
||||
surface_rect->x, surface_rect->y,
|
||||
surface_rect->width, surface_rect->height);
|
||||
|
||||
flags = gst_vaapi_video_meta_get_render_flags(meta);
|
||||
|
||||
if (!gst_vaapi_apply_composition(surface, src_buffer))
|
||||
|
@ -1019,18 +1061,19 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer)
|
|||
case GST_VAAPI_DISPLAY_TYPE_GLX:
|
||||
if (!sink->use_glx)
|
||||
goto put_surface_x11;
|
||||
success = gst_vaapisink_show_frame_glx(sink, surface, flags);
|
||||
success = gst_vaapisink_show_frame_glx(sink, surface, surface_rect,
|
||||
flags);
|
||||
break;
|
||||
#endif
|
||||
#if USE_X11
|
||||
case GST_VAAPI_DISPLAY_TYPE_X11:
|
||||
put_surface_x11:
|
||||
success = gst_vaapisink_put_surface(sink, surface, flags);
|
||||
success = gst_vaapisink_put_surface(sink, surface, surface_rect, flags);
|
||||
break;
|
||||
#endif
|
||||
#if USE_WAYLAND
|
||||
case GST_VAAPI_DISPLAY_TYPE_WAYLAND:
|
||||
success = gst_vaapisink_put_surface(sink, surface, flags);
|
||||
success = gst_vaapisink_put_surface(sink, surface, surface_rect, flags);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -1075,6 +1118,8 @@ gst_vaapisink_propose_allocation(GstBaseSink *base_sink, GstQuery *query)
|
|||
GST_VAAPI_VIDEO_META_API_TYPE, NULL);
|
||||
gst_query_add_allocation_meta(query,
|
||||
GST_VIDEO_META_API_TYPE, NULL);
|
||||
gst_query_add_allocation_meta(query,
|
||||
GST_VIDEO_CROP_META_API_TYPE, NULL);
|
||||
gst_query_add_allocation_meta(query,
|
||||
GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
|
||||
return TRUE;
|
||||
|
|
|
@ -637,6 +637,7 @@ gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta,
|
|||
GstVaapiSurfaceProxy *proxy)
|
||||
{
|
||||
GstVaapiSurface *surface;
|
||||
const GstVaapiRectangle *crop_rect;
|
||||
|
||||
g_return_if_fail(GST_VAAPI_IS_VIDEO_META(meta));
|
||||
|
||||
|
@ -648,6 +649,10 @@ gst_vaapi_video_meta_set_surface_proxy(GstVaapiVideoMeta *meta,
|
|||
return;
|
||||
set_surface(meta, surface);
|
||||
meta->proxy = gst_vaapi_surface_proxy_ref(proxy);
|
||||
|
||||
crop_rect = gst_vaapi_surface_proxy_get_crop_rect(proxy);
|
||||
if (crop_rect)
|
||||
gst_vaapi_video_meta_set_render_rect(meta, crop_rect);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue