mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-29 20:35:40 +00:00
libs: subpicture: Make subpicture a standard GstMiniObject.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/331>
This commit is contained in:
parent
3df1018b02
commit
6333c85316
4 changed files with 84 additions and 62 deletions
|
@ -37,8 +37,6 @@
|
|||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass;
|
||||
|
||||
/**
|
||||
* GstVaapiSubpicture:
|
||||
*
|
||||
|
@ -47,55 +45,56 @@ typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass;
|
|||
struct _GstVaapiSubpicture
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiObject parent_instance;
|
||||
GstMiniObject mini_object;
|
||||
GstVaapiDisplay *display;
|
||||
GstVaapiID object_id;
|
||||
|
||||
GstVaapiImage *image;
|
||||
guint flags;
|
||||
gfloat global_alpha;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiSubpictureClass:
|
||||
*
|
||||
* A VA subpicture wrapper class
|
||||
*/
|
||||
struct _GstVaapiSubpictureClass
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiObjectClass parent_class;
|
||||
};
|
||||
|
||||
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;
|
||||
VAStatus status;
|
||||
|
||||
subpicture_id = GST_VAAPI_OBJECT_ID (subpicture);
|
||||
subpicture_id = subpicture->object_id;
|
||||
GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT,
|
||||
GST_VAAPI_ID_ARGS (subpicture_id));
|
||||
|
||||
if (subpicture_id != VA_INVALID_ID) {
|
||||
if (display) {
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
status = vaDestroySubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
||||
subpicture_id);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
if (!vaapi_check_status (status, "vaDestroySubpicture()"))
|
||||
GST_WARNING ("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT,
|
||||
GST_VAAPI_ID_ARGS (subpicture_id));
|
||||
}
|
||||
GST_VAAPI_OBJECT_ID (subpicture) = VA_INVALID_ID;
|
||||
GST_VAAPI_DISPLAY_LOCK (display);
|
||||
status = vaDestroySubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display),
|
||||
subpicture_id);
|
||||
GST_VAAPI_DISPLAY_UNLOCK (display);
|
||||
if (!vaapi_check_status (status, "vaDestroySubpicture()"))
|
||||
GST_WARNING ("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT,
|
||||
GST_VAAPI_ID_ARGS (subpicture_id));
|
||||
subpicture->object_id = 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
|
||||
gst_vaapi_subpicture_create (GstVaapiSubpicture * subpicture,
|
||||
gst_vaapi_subpicture_bind_image (GstVaapiSubpicture * subpicture,
|
||||
GstVaapiImage * image)
|
||||
{
|
||||
GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (subpicture);
|
||||
GstVaapiDisplay *const display = subpicture->display;
|
||||
VASubpictureID subpicture_id;
|
||||
VAStatus status;
|
||||
|
||||
|
@ -108,15 +107,12 @@ gst_vaapi_subpicture_create (GstVaapiSubpicture * subpicture,
|
|||
|
||||
GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT,
|
||||
GST_VAAPI_ID_ARGS (subpicture_id));
|
||||
GST_VAAPI_OBJECT_ID (subpicture) = subpicture_id;
|
||||
subpicture->object_id = subpicture_id;
|
||||
subpicture->image =
|
||||
(GstVaapiImage *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (image));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define gst_vaapi_subpicture_finalize gst_vaapi_subpicture_destroy
|
||||
GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture)
|
||||
|
||||
/**
|
||||
* gst_vaapi_subpicture_new:
|
||||
* @image: a #GstVaapiImage
|
||||
|
@ -127,8 +123,8 @@ GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture)
|
|||
*
|
||||
* Return value: the newly allocated #GstVaapiSubpicture object
|
||||
*/
|
||||
GstVaapiSubpicture *gst_vaapi_subpicture_new (GstVaapiImage * image,
|
||||
guint flags)
|
||||
GstVaapiSubpicture *
|
||||
gst_vaapi_subpicture_new (GstVaapiImage * image, guint flags)
|
||||
{
|
||||
GstVaapiSubpicture *subpicture;
|
||||
GstVaapiDisplay *display;
|
||||
|
@ -147,19 +143,26 @@ GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiSubpicture, gst_vaapi_subpicture)
|
|||
if (flags & ~va_flags)
|
||||
return NULL;
|
||||
|
||||
subpicture = gst_vaapi_object_new (gst_vaapi_subpicture_class (), display);
|
||||
subpicture = g_slice_new (GstVaapiSubpicture);
|
||||
if (!subpicture)
|
||||
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;
|
||||
if (!gst_vaapi_subpicture_set_image (subpicture, image))
|
||||
|
||||
if (!gst_vaapi_subpicture_bind_image (subpicture, image))
|
||||
goto error;
|
||||
return subpicture;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
gst_vaapi_object_unref (subpicture);
|
||||
gst_vaapi_subpicture_unref (subpicture);
|
||||
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);
|
||||
|
||||
/* XXX: use gst_vaapi_image_format_from_video() */
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GST_VIDEO_FORMAT_BGRA;
|
||||
#else
|
||||
format = GST_VIDEO_FORMAT_ARGB;
|
||||
#endif
|
||||
format = GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB;
|
||||
|
||||
if (!gst_vaapi_display_has_subpicture_format (display, format, &hw_flags))
|
||||
return NULL;
|
||||
|
||||
|
@ -235,12 +234,12 @@ gst_vaapi_subpicture_new_from_overlay_rectangle (GstVaapiDisplay * display,
|
|||
raw_image.stride[0] = stride;
|
||||
if (!gst_vaapi_image_update_from_raw (image, &raw_image, NULL)) {
|
||||
GST_WARNING ("could not update VA image with subtitle data");
|
||||
gst_vaapi_object_unref (image);
|
||||
gst_vaapi_image_unref (image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
if (!subpicture)
|
||||
return NULL;
|
||||
|
@ -266,7 +265,7 @@ gst_vaapi_subpicture_get_id (GstVaapiSubpicture * subpicture)
|
|||
{
|
||||
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 (image != NULL, FALSE);
|
||||
|
||||
gst_vaapi_subpicture_destroy (subpicture);
|
||||
return gst_vaapi_subpicture_create (subpicture, image);
|
||||
gst_vaapi_subpicture_free_image (subpicture);
|
||||
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)
|
||||
return TRUE;
|
||||
|
||||
display = GST_VAAPI_OBJECT_DISPLAY (subpicture);
|
||||
display = subpicture->display;
|
||||
|
||||
GST_VAAPI_DISPLAY_LOCK (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);
|
||||
if (!vaapi_check_status (status, "vaSetSubpictureGlobalAlpha()"))
|
||||
return FALSE;
|
||||
|
|
|
@ -52,6 +52,26 @@ typedef enum {
|
|||
GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA = (1 << 1),
|
||||
} 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 *
|
||||
gst_vaapi_subpicture_new(GstVaapiImage *image, guint flags);
|
||||
|
||||
|
@ -81,6 +101,8 @@ gboolean
|
|||
gst_vaapi_subpicture_set_global_alpha(GstVaapiSubpicture *subpicture,
|
||||
gfloat global_alpha);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiSubpicture, gst_vaapi_subpicture_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_SUBPICTURE_H */
|
||||
|
|
|
@ -53,7 +53,7 @@ static void
|
|||
destroy_subpicture_cb (gpointer subpicture, gpointer surface)
|
||||
{
|
||||
_gst_vaapi_surface_deassociate_subpicture (surface, subpicture);
|
||||
gst_vaapi_object_unref (subpicture);
|
||||
gst_vaapi_subpicture_unref (subpicture);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -804,7 +804,7 @@ gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface,
|
|||
|
||||
if (g_ptr_array_remove_fast (surface->subpictures, subpicture)) {
|
||||
success = _gst_vaapi_surface_deassociate_subpicture (surface, subpicture);
|
||||
gst_vaapi_object_unref (subpicture);
|
||||
gst_vaapi_subpicture_unref (subpicture);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -814,7 +814,8 @@ gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface,
|
|||
if (!success)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -858,7 +859,7 @@ _gst_vaapi_surface_associate_subpicture (GstVaapiSurface * surface,
|
|||
|
||||
GST_VAAPI_DISPLAY_LOCK (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,
|
||||
dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height,
|
||||
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)) {
|
||||
GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT " was not bound to "
|
||||
"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)));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
success = _gst_vaapi_surface_deassociate_subpicture (surface, subpicture);
|
||||
gst_vaapi_object_unref (subpicture);
|
||||
gst_vaapi_subpicture_unref (subpicture);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -923,7 +924,7 @@ _gst_vaapi_surface_deassociate_subpicture (GstVaapiSurface * surface,
|
|||
|
||||
GST_VAAPI_DISPLAY_LOCK (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);
|
||||
if (!vaapi_check_status (status, "vaDeassociateSubpicture()"))
|
||||
return FALSE;
|
||||
|
@ -1047,10 +1048,10 @@ gst_vaapi_surface_set_subpictures_from_composition (GstVaapiSurface * surface,
|
|||
if (!gst_vaapi_surface_associate_subpicture (surface, subpicture,
|
||||
NULL, &sub_rect)) {
|
||||
GST_WARNING ("could not render overlay rectangle %p", rect);
|
||||
gst_vaapi_object_unref (subpicture);
|
||||
gst_vaapi_subpicture_unref (subpicture);
|
||||
return FALSE;
|
||||
}
|
||||
gst_vaapi_object_unref (subpicture);
|
||||
gst_vaapi_subpicture_unref (subpicture);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -395,6 +395,6 @@ image_upload (GstVaapiImage * image, GstVaapiSurface * surface)
|
|||
g_error ("could not associate subpicture to surface");
|
||||
|
||||
/* The surface holds a reference to the subpicture. This is safe */
|
||||
gst_vaapi_object_unref (subpicture);
|
||||
gst_vaapi_subpicture_unref (subpicture);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue