decoder: add support for video cropping.

Add gst_vaapi_picture_set_crop_rect() helper function to copy the video
cropping information from raw bitstreams to each picture being decoded.
Also add helper function to surface proxy to propagate that information
outside of libgstvaapi. e.g. plug-in elements or standalone applications.

Signed-off-by: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
Sreerenj Balachandran 2013-02-15 18:42:12 +02:00 committed by Gwenole Beauchesne
parent 746631c64c
commit e66e72e7e3
5 changed files with 104 additions and 0 deletions

View file

@ -128,6 +128,11 @@ gst_vaapi_picture_create(
}
GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAG_FF);
}
if (parent_picture->has_crop_rect) {
picture->has_crop_rect = TRUE;
picture->crop_rect = parent_picture->crop_rect;
}
}
else {
picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
@ -308,6 +313,10 @@ gst_vaapi_picture_output(GstVaapiPicture *picture)
return FALSE;
proxy = gst_vaapi_surface_proxy_ref(picture->proxy);
if (picture->has_crop_rect)
gst_vaapi_surface_proxy_set_crop_rect(proxy, &picture->crop_rect);
gst_video_codec_frame_set_user_data(out_frame,
proxy, (GDestroyNotify)gst_vaapi_mini_object_unref);
@ -330,6 +339,17 @@ gst_vaapi_picture_output(GstVaapiPicture *picture)
return TRUE;
}
void
gst_vaapi_picture_set_crop_rect(GstVaapiPicture *picture,
const GstVaapiRectangle *crop_rect)
{
g_return_if_fail(GST_VAAPI_IS_PICTURE(picture));
picture->has_crop_rect = crop_rect != NULL;
if (picture->has_crop_rect)
picture->crop_rect = *crop_rect;
}
/* ------------------------------------------------------------------------- */
/* --- Slices --- */
/* ------------------------------------------------------------------------- */

View file

@ -131,6 +131,8 @@ struct _GstVaapiPicture {
GstClockTime pts;
gint32 poc;
guint structure;
GstVaapiRectangle crop_rect;
guint has_crop_rect : 1;
};
G_GNUC_INTERNAL
@ -166,6 +168,11 @@ G_GNUC_INTERNAL
gboolean
gst_vaapi_picture_output(GstVaapiPicture *picture);
G_GNUC_INTERNAL
void
gst_vaapi_picture_set_crop_rect(GstVaapiPicture *picture,
const GstVaapiRectangle *crop_rect);
static inline gpointer
gst_vaapi_picture_ref(gpointer ptr)
{

View file

@ -33,6 +33,27 @@
#define DEBUG 1
#include "gstvaapidebug.h"
static void
set_crop_rect_from_surface(GstVaapiSurfaceProxy *proxy)
{
guint width, height;
gst_vaapi_surface_get_size(proxy->surface, &width, &height);
proxy->crop_rect.x = 0;
proxy->crop_rect.y = 0;
proxy->crop_rect.width = width;
proxy->crop_rect.height = height;
}
static inline void
set_crop_rect(GstVaapiSurfaceProxy *proxy, const GstVaapiRectangle *crop_rect)
{
if (crop_rect)
proxy->crop_rect = *crop_rect;
else
set_crop_rect_from_surface(proxy);
}
static void
gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy)
{
@ -74,6 +95,8 @@ gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool)
proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool);
if (!proxy->surface)
goto error;
set_crop_rect_from_surface(proxy);
proxy->timestamp = GST_CLOCK_TIME_NONE;
proxy->duration = GST_CLOCK_TIME_NONE;
proxy->destroy_func = NULL;
@ -238,3 +261,37 @@ gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy,
proxy->destroy_func = destroy_func;
proxy->destroy_data = user_data;
}
/**
* gst_vaapi_surface_proxy_get_crop_rect:
* @proxy: a #GstVaapiSurfaceProxy
*
* Returns the #GstVaapiRectangle stored in the @proxy and that
* represents the cropping rectangle for the underlying surface to be
* used for rendering.
*
* Return value: the #GstVaapiRectangle
*/
const GstVaapiRectangle *
gst_vaapi_surface_proxy_get_crop_rect(GstVaapiSurfaceProxy *proxy)
{
g_return_val_if_fail(proxy != NULL, NULL);
return GST_VAAPI_SURFACE_PROXY_CROP_RECT(proxy);
}
/**
* gst_vaapi_surface_proxy_set_crop_rect:
* @proxy: #GstVaapiSurfaceProxy
* @crop_rect: the #GstVaapiRectangle to be stored in @proxy
*
* Associates the @crop_rect with the @proxy
*/
void
gst_vaapi_surface_proxy_set_crop_rect(GstVaapiSurfaceProxy *proxy,
const GstVaapiRectangle *crop_rect)
{
g_return_if_fail(proxy != NULL);
set_crop_rect(proxy, crop_rect);
}

View file

@ -117,6 +117,13 @@ void
gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy,
GDestroyNotify destroy_func, gpointer user_data);
const GstVaapiRectangle *
gst_vaapi_surface_proxy_get_crop_rect(GstVaapiSurfaceProxy *proxy);
void
gst_vaapi_surface_proxy_set_crop_rect(GstVaapiSurfaceProxy *proxy,
const GstVaapiRectangle *crop_rect);
G_END_DECLS
#endif /* GST_VAAPI_SURFACE_PROXY_H */

View file

@ -41,6 +41,7 @@ struct _GstVaapiSurfaceProxy {
GstClockTime duration;
GDestroyNotify destroy_func;
gpointer destroy_data;
GstVaapiRectangle crop_rect;
};
#define GST_VAAPI_SURFACE_PROXY_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS
@ -98,4 +99,16 @@ struct _GstVaapiSurfaceProxy {
#define GST_VAAPI_SURFACE_PROXY_DURATION(proxy) \
proxy->duration
/**
* GST_VAAPI_SURFACE_PROXY_CROP_RECT:
* @proxy: a #GstVaapiSurfaceProxy
*
* Macro that evaluates to the video cropping rectangle of the underlying @proxy surface.
*
* This is an internal macro that does not do any run-time type check.
*/
#undef GST_VAAPI_SURFACE_PROXY_CROP_RECT
#define GST_VAAPI_SURFACE_PROXY_CROP_RECT(proxy) \
&(proxy)->crop_rect
#endif /* GST_VAAPI_SURFACE_PROXY_PRIV_H */