libs: subpicture: Make subpicture a standard GstMiniObject.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/331>
This commit is contained in:
He Junyan 2020-05-23 14:00:58 +08:00
parent 3df1018b02
commit 6333c85316
4 changed files with 84 additions and 62 deletions

View file

@ -37,8 +37,6 @@
#define DEBUG 1 #define DEBUG 1
#include "gstvaapidebug.h" #include "gstvaapidebug.h"
typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass;
/** /**
* GstVaapiSubpicture: * GstVaapiSubpicture:
* *
@ -47,55 +45,56 @@ typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass;
struct _GstVaapiSubpicture struct _GstVaapiSubpicture
{ {
/*< private > */ /*< private > */
GstVaapiObject parent_instance; GstMiniObject mini_object;
GstVaapiDisplay *display;
GstVaapiID object_id;
GstVaapiImage *image; GstVaapiImage *image;
guint flags; guint flags;
gfloat global_alpha; gfloat global_alpha;
}; };
/**
* GstVaapiSubpictureClass:
*
* A VA subpicture wrapper class
*/
struct _GstVaapiSubpictureClass
{
/*< private > */
GstVaapiObjectClass parent_class;
};
static void static void
gst_vaapi_subpicture_destroy (GstVaapiSubpicture * subpicture) gst_vaapi_subpicture_free_image (GstVaapiSubpicture * subpicture)
{ {
GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (subpicture); GstVaapiDisplay *const display = subpicture->display;
VASubpictureID subpicture_id; VASubpictureID subpicture_id;
VAStatus status; VAStatus status;
subpicture_id = GST_VAAPI_OBJECT_ID (subpicture); subpicture_id = subpicture->object_id;
GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT, GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT,
GST_VAAPI_ID_ARGS (subpicture_id)); GST_VAAPI_ID_ARGS (subpicture_id));
if (subpicture_id != VA_INVALID_ID) { if (subpicture_id != VA_INVALID_ID) {
if (display) { GST_VAAPI_DISPLAY_LOCK (display);
GST_VAAPI_DISPLAY_LOCK (display); status = vaDestroySubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display),
status = vaDestroySubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), subpicture_id);
subpicture_id); GST_VAAPI_DISPLAY_UNLOCK (display);
GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaDestroySubpicture()"))
if (!vaapi_check_status (status, "vaDestroySubpicture()")) GST_WARNING ("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT,
GST_WARNING ("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (subpicture_id));
GST_VAAPI_ID_ARGS (subpicture_id)); subpicture->object_id = VA_INVALID_ID;
}
GST_VAAPI_OBJECT_ID (subpicture) = VA_INVALID_ID;
} }
gst_mini_object_replace ((GstMiniObject **) & subpicture->image, NULL);
if (subpicture->image)
gst_mini_object_replace ((GstMiniObject **) & subpicture->image, NULL);
} }
static void
gst_vaapi_subpicture_free (GstVaapiSubpicture * subpicture)
{
gst_vaapi_subpicture_free_image (subpicture);
gst_vaapi_display_replace (&subpicture->display, NULL);
g_slice_free1 (sizeof (GstVaapiSubpicture), subpicture);
}
GST_DEFINE_MINI_OBJECT_TYPE (GstVaapiSubpicture, gst_vaapi_subpicture);
static gboolean static gboolean
gst_vaapi_subpicture_create (GstVaapiSubpicture * subpicture, gst_vaapi_subpicture_bind_image (GstVaapiSubpicture * subpicture,
GstVaapiImage * image) GstVaapiImage * image)
{ {
GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (subpicture); GstVaapiDisplay *const display = subpicture->display;
VASubpictureID subpicture_id; VASubpictureID subpicture_id;
VAStatus status; VAStatus status;
@ -108,15 +107,12 @@ gst_vaapi_subpicture_create (GstVaapiSubpicture * subpicture,
GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT, GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT,
GST_VAAPI_ID_ARGS (subpicture_id)); GST_VAAPI_ID_ARGS (subpicture_id));
GST_VAAPI_OBJECT_ID (subpicture) = subpicture_id; subpicture->object_id = subpicture_id;
subpicture->image = subpicture->image =
(GstVaapiImage *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (image)); (GstVaapiImage *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (image));
return TRUE; return TRUE;
} }
#define gst_vaapi_subpicture_finalize gst_vaapi_subpicture_destroy
GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture)
/** /**
* gst_vaapi_subpicture_new: * gst_vaapi_subpicture_new:
* @image: a #GstVaapiImage * @image: a #GstVaapiImage
@ -127,8 +123,8 @@ GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture)
* *
* Return value: the newly allocated #GstVaapiSubpicture object * Return value: the newly allocated #GstVaapiSubpicture object
*/ */
GstVaapiSubpicture *gst_vaapi_subpicture_new (GstVaapiImage * image, GstVaapiSubpicture *
guint flags) gst_vaapi_subpicture_new (GstVaapiImage * image, guint flags)
{ {
GstVaapiSubpicture *subpicture; GstVaapiSubpicture *subpicture;
GstVaapiDisplay *display; GstVaapiDisplay *display;
@ -147,19 +143,26 @@ GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture)
if (flags & ~va_flags) if (flags & ~va_flags)
return NULL; return NULL;
subpicture = gst_vaapi_object_new (gst_vaapi_subpicture_class (), display); subpicture = g_slice_new (GstVaapiSubpicture);
if (!subpicture) if (!subpicture)
return NULL; return NULL;
gst_mini_object_init (GST_MINI_OBJECT_CAST (subpicture), 0,
GST_TYPE_VAAPI_SUBPICTURE, NULL, NULL,
(GstMiniObjectFreeFunction) gst_vaapi_subpicture_free);
subpicture->display = gst_object_ref (display);
subpicture->object_id = VA_INVALID_ID;
subpicture->flags = flags;
subpicture->global_alpha = 1.0f; subpicture->global_alpha = 1.0f;
if (!gst_vaapi_subpicture_set_image (subpicture, image))
if (!gst_vaapi_subpicture_bind_image (subpicture, image))
goto error; goto error;
return subpicture; return subpicture;
/* ERRORS */ /* ERRORS */
error: error:
{ {
gst_vaapi_object_unref (subpicture); gst_vaapi_subpicture_unref (subpicture);
return NULL; return NULL;
} }
} }
@ -194,12 +197,8 @@ gst_vaapi_subpicture_new_from_overlay_rectangle (GstVaapiDisplay * display,
g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rect), NULL); g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rect), NULL);
/* XXX: use gst_vaapi_image_format_from_video() */ format = GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
format = GST_VIDEO_FORMAT_BGRA;
#else
format = GST_VIDEO_FORMAT_ARGB;
#endif
if (!gst_vaapi_display_has_subpicture_format (display, format, &hw_flags)) if (!gst_vaapi_display_has_subpicture_format (display, format, &hw_flags))
return NULL; return NULL;
@ -235,12 +234,12 @@ gst_vaapi_subpicture_new_from_overlay_rectangle (GstVaapiDisplay * display,
raw_image.stride[0] = stride; raw_image.stride[0] = stride;
if (!gst_vaapi_image_update_from_raw (image, &raw_image, NULL)) { if (!gst_vaapi_image_update_from_raw (image, &raw_image, NULL)) {
GST_WARNING ("could not update VA image with subtitle data"); GST_WARNING ("could not update VA image with subtitle data");
gst_vaapi_object_unref (image); gst_vaapi_image_unref (image);
return NULL; return NULL;
} }
subpicture = gst_vaapi_subpicture_new (image, flags); subpicture = gst_vaapi_subpicture_new (image, flags);
gst_vaapi_object_unref (image); gst_vaapi_image_unref (image);
gst_video_meta_unmap (vmeta, 0, &map_info); gst_video_meta_unmap (vmeta, 0, &map_info);
if (!subpicture) if (!subpicture)
return NULL; return NULL;
@ -266,7 +265,7 @@ gst_vaapi_subpicture_get_id (GstVaapiSubpicture * subpicture)
{ {
g_return_val_if_fail (subpicture != NULL, VA_INVALID_ID); g_return_val_if_fail (subpicture != NULL, VA_INVALID_ID);
return GST_VAAPI_OBJECT_ID (subpicture); return subpicture->object_id;
} }
/** /**
@ -318,8 +317,8 @@ gst_vaapi_subpicture_set_image (GstVaapiSubpicture * subpicture,
g_return_val_if_fail (subpicture != NULL, FALSE); g_return_val_if_fail (subpicture != NULL, FALSE);
g_return_val_if_fail (image != NULL, FALSE); g_return_val_if_fail (image != NULL, FALSE);
gst_vaapi_subpicture_destroy (subpicture); gst_vaapi_subpicture_free_image (subpicture);
return gst_vaapi_subpicture_create (subpicture, image); return gst_vaapi_subpicture_bind_image (subpicture, image);
} }
/** /**
@ -364,11 +363,11 @@ gst_vaapi_subpicture_set_global_alpha (GstVaapiSubpicture * subpicture,
if (subpicture->global_alpha == global_alpha) if (subpicture->global_alpha == global_alpha)
return TRUE; return TRUE;
display = GST_VAAPI_OBJECT_DISPLAY (subpicture); display = subpicture->display;
GST_VAAPI_DISPLAY_LOCK (display); GST_VAAPI_DISPLAY_LOCK (display);
status = vaSetSubpictureGlobalAlpha (GST_VAAPI_DISPLAY_VADISPLAY (display), status = vaSetSubpictureGlobalAlpha (GST_VAAPI_DISPLAY_VADISPLAY (display),
GST_VAAPI_OBJECT_ID (subpicture), global_alpha); subpicture->object_id, global_alpha);
GST_VAAPI_DISPLAY_UNLOCK (display); GST_VAAPI_DISPLAY_UNLOCK (display);
if (!vaapi_check_status (status, "vaSetSubpictureGlobalAlpha()")) if (!vaapi_check_status (status, "vaSetSubpictureGlobalAlpha()"))
return FALSE; return FALSE;

View file

@ -52,6 +52,26 @@ typedef enum {
GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA = (1 << 1), GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA = (1 << 1),
} GstVaapiSubpictureFlags; } GstVaapiSubpictureFlags;
#define GST_TYPE_VAAPI_SUBPICTURE (gst_vaapi_subpicture_get_type ())
#define GST_VAAPI_SUBPICTURE_ID(subpicture) (gst_vaapi_subpicture_get_id (subpicture))
GType
gst_vaapi_subpicture_get_type (void) G_GNUC_CONST;
/**
* gst_vaapi_subpicture_unref: (skip)
* @subpicture: (transfer full): a #GstVaapiSubpicture.
*
* Decreases the refcount of the subpicture. If the refcount reaches 0, the
* subpicture will be freed.
*/
static inline void
gst_vaapi_subpicture_unref (GstVaapiSubpicture *subpicture)
{
gst_mini_object_unref (GST_MINI_OBJECT_CAST (subpicture));
}
GstVaapiSubpicture * GstVaapiSubpicture *
gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags); gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags);
@ -81,6 +101,8 @@ gboolean
gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture, gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture,
gfloat global_alpha); gfloat global_alpha);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiSubpicture, gst_vaapi_subpicture_unref)
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_SUBPICTURE_H */ #endif /* GST_VAAPI_SUBPICTURE_H */

View file

@ -53,7 +53,7 @@ static void
destroy_subpicture_cb (gpointer subpicture, gpointer surface) destroy_subpicture_cb (gpointer subpicture, gpointer surface)
{ {
_gst_vaapi_surface_deassociate_subpicture (surface, subpicture); _gst_vaapi_surface_deassociate_subpicture (surface, subpicture);
gst_vaapi_object_unref (subpicture); gst_vaapi_subpicture_unref (subpicture);
} }
static void static void
@ -804,7 +804,7 @@ gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface,
if (g_ptr_array_remove_fast (surface->subpictures, subpicture)) { if (g_ptr_array_remove_fast (surface->subpictures, subpicture)) {
success = _gst_vaapi_surface_deassociate_subpicture (surface, subpicture); success = _gst_vaapi_surface_deassociate_subpicture (surface, subpicture);
gst_vaapi_object_unref (subpicture); gst_vaapi_subpicture_unref (subpicture);
if (!success) if (!success)
return FALSE; return FALSE;
} }
@ -814,7 +814,8 @@ gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface,
if (!success) if (!success)
return FALSE; return FALSE;
g_ptr_array_add (surface->subpictures, gst_vaapi_object_ref (subpicture)); g_ptr_array_add (surface->subpictures,
gst_mini_object_ref (GST_MINI_OBJECT_CAST (subpicture)));
return TRUE; return TRUE;
} }
@ -858,7 +859,7 @@ _gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface,
GST_VAAPI_DISPLAY_LOCK (display); GST_VAAPI_DISPLAY_LOCK (display);
status = vaAssociateSubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), status = vaAssociateSubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display),
GST_VAAPI_OBJECT_ID (subpicture), &surface_id, 1, GST_VAAPI_SUBPICTURE_ID (subpicture), &surface_id, 1,
src_rect->x, src_rect->y, src_rect->width, src_rect->height, src_rect->x, src_rect->y, src_rect->width, src_rect->height,
dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height, dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height,
from_GstVaapiSubpictureFlags (gst_vaapi_subpicture_get_flags from_GstVaapiSubpictureFlags (gst_vaapi_subpicture_get_flags
@ -895,13 +896,13 @@ gst_vaapi_surface_deassociate_subpicture (GstVaapiSurface * surface,
if (!g_ptr_array_remove_fast (surface->subpictures, subpicture)) { if (!g_ptr_array_remove_fast (surface->subpictures, subpicture)) {
GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT " was not bound to " GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT " was not bound to "
"surface %" GST_VAAPI_ID_FORMAT, "surface %" GST_VAAPI_ID_FORMAT,
GST_VAAPI_ID_ARGS (GST_VAAPI_OBJECT_ID (subpicture)), GST_VAAPI_ID_ARGS (GST_VAAPI_SUBPICTURE_ID (subpicture)),
GST_VAAPI_ID_ARGS (GST_VAAPI_SURFACE_ID (surface))); GST_VAAPI_ID_ARGS (GST_VAAPI_SURFACE_ID (surface)));
return TRUE; return TRUE;
} }
success = _gst_vaapi_surface_deassociate_subpicture (surface, subpicture); success = _gst_vaapi_surface_deassociate_subpicture (surface, subpicture);
gst_vaapi_object_unref (subpicture); gst_vaapi_subpicture_unref (subpicture);
return success; return success;
} }
@ -923,7 +924,7 @@ _gst_vaapi_surface_deassociate_subpicture (GstVaapiSurface * surface,
GST_VAAPI_DISPLAY_LOCK (display); GST_VAAPI_DISPLAY_LOCK (display);
status = vaDeassociateSubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), status = vaDeassociateSubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display),
GST_VAAPI_OBJECT_ID (subpicture), &surface_id, 1); GST_VAAPI_SUBPICTURE_ID (subpicture), &surface_id, 1);
GST_VAAPI_DISPLAY_UNLOCK (display); GST_VAAPI_DISPLAY_UNLOCK (display);
if (!vaapi_check_status (status, "vaDeassociateSubpicture()")) if (!vaapi_check_status (status, "vaDeassociateSubpicture()"))
return FALSE; return FALSE;
@ -1047,10 +1048,10 @@ gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface,
if (!gst_vaapi_surface_associate_subpicture (surface, subpicture, if (!gst_vaapi_surface_associate_subpicture (surface, subpicture,
NULL, &sub_rect)) { NULL, &sub_rect)) {
GST_WARNING ("could not render overlay rectangle %p", rect); GST_WARNING ("could not render overlay rectangle %p", rect);
gst_vaapi_object_unref (subpicture); gst_vaapi_subpicture_unref (subpicture);
return FALSE; return FALSE;
} }
gst_vaapi_object_unref (subpicture); gst_vaapi_subpicture_unref (subpicture);
} }
return TRUE; return TRUE;
} }

View file

@ -395,6 +395,6 @@ image_upload (GstVaapiImage * image, GstVaapiSurface * surface)
g_error ("could not associate subpicture to surface"); g_error ("could not associate subpicture to surface");
/* The surface holds a reference to the subpicture. This is safe */ /* The surface holds a reference to the subpicture. This is safe */
gst_vaapi_object_unref (subpicture); gst_vaapi_subpicture_unref (subpicture);
return TRUE; return TRUE;
} }