Add initial Pixmap API.

Add API to transfer VA urfaces to native pixmaps. Also add an API to
render a native pixmap, for completeness. In general, rendering to
pixmap would only be useful to certain VA drivers and use cases on
X11 display servers. e.g. GLX_EXT_texture_from_pixmap (TFP) handled
in an upper layer.
This commit is contained in:
Gwenole Beauchesne 2013-07-22 10:00:21 +02:00
parent 4a8a80061f
commit 5cabf4e305
9 changed files with 584 additions and 0 deletions

View file

@ -16,6 +16,7 @@
<xi:include href="xml/gstvaapiwindow.xml"/>
<xi:include href="xml/gstvaapiwindow_x11.xml"/>
<xi:include href="xml/gstvaapiwindow_glx.xml"/>
<xi:include href="xml/gstvaapipixmap.xml"/>
<xi:include href="xml/gstvaapiobject.xml"/>
<xi:include href="xml/gstvaapisurface.xml"/>
<xi:include href="xml/gstvaapiimage.xml"/>

View file

@ -140,6 +140,22 @@ GstVaapiPoint
GstVaapiRectangle
</SECTION>
<SECTION>
<FILE>gstvaapipixmap</FILE>
<TITLE>GstVaapiPixmap</TITLE>
GstVaapiPixmap
gst_vaapi_pixmap_ref
gst_vaapi_pixmap_unref
gst_vaapi_pixmap_replace
gst_vaapi_pixmap_get_format
gst_vaapi_pixmap_get_width
gst_vaapi_pixmap_get_height
gst_vaapi_pixmap_get_size
gst_vaapi_pixmap_put_surface
<SUBSECTION Standard>
GST_VAAPI_PIXMAP
</SECTION>
<SECTION>
<FILE>gstvaapiwindow</FILE>
<TITLE>GstVaapiWindow</TITLE>
@ -155,6 +171,7 @@ gst_vaapi_window_get_size
gst_vaapi_window_set_width
gst_vaapi_window_set_height
gst_vaapi_window_set_size
gst_vaapi_window_put_pixmap
gst_vaapi_window_put_surface
<SUBSECTION Standard>
GST_VAAPI_WINDOW

View file

@ -60,6 +60,7 @@ libgstvaapi_source_c = \
gstvaapiminiobject.c \
gstvaapiobject.c \
gstvaapiparser_frame.c \
gstvaapipixmap.c \
gstvaapiprofile.c \
gstvaapisubpicture.c \
gstvaapisurface.c \
@ -84,6 +85,7 @@ libgstvaapi_source_h = \
gstvaapiimage.h \
gstvaapiimagepool.h \
gstvaapiobject.h \
gstvaapipixmap.h \
gstvaapiprofile.h \
gstvaapisubpicture.h \
gstvaapisurface.h \
@ -110,6 +112,7 @@ libgstvaapi_source_priv_h = \
gstvaapiminiobject.h \
gstvaapiobject_priv.h \
gstvaapiparser_frame.h \
gstvaapipixmap_priv.h \
gstvaapisurface_priv.h \
gstvaapisurfaceproxy_priv.h \
gstvaapiutils.h \

View file

@ -0,0 +1,259 @@
/*
* gstvaapipixmap.c - Pixmap abstraction
*
* Copyright (C) 2013 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/**
* SECTION:gstvaapipixmap
* @short_description: Pixmap abstraction
*/
#include "sysdeps.h"
#include "gstvaapipixmap.h"
#include "gstvaapipixmap_priv.h"
#include "gstvaapisurface_priv.h"
#define DEBUG 1
#include "gstvaapidebug.h"
/* Ensure those symbols are actually defined in the resulting libraries */
#undef gst_vaapi_pixmap_ref
#undef gst_vaapi_pixmap_unref
#undef gst_vaapi_pixmap_replace
static inline GstVaapiPixmap *
gst_vaapi_pixmap_new_internal(const GstVaapiPixmapClass *pixmap_class,
GstVaapiDisplay *display)
{
g_assert(pixmap_class->create != NULL);
g_assert(pixmap_class->render != NULL);
return gst_vaapi_object_new(GST_VAAPI_OBJECT_CLASS(pixmap_class), display);
}
GstVaapiPixmap *
gst_vaapi_pixmap_new(const GstVaapiPixmapClass *pixmap_class,
GstVaapiDisplay *display, GstVideoFormat format, guint width, guint height)
{
GstVaapiPixmap *pixmap;
g_return_val_if_fail(format != GST_VIDEO_FORMAT_UNKNOWN &&
format != GST_VIDEO_FORMAT_ENCODED, NULL);
g_return_val_if_fail(width > 0, NULL);
g_return_val_if_fail(height > 0, NULL);
pixmap = gst_vaapi_pixmap_new_internal(pixmap_class, display);
if (!pixmap)
return NULL;
pixmap->format = format;
pixmap->width = width;
pixmap->height = height;
if (!pixmap_class->create(pixmap))
goto error;
return pixmap;
error:
gst_vaapi_pixmap_unref_internal(pixmap);
return NULL;
}
GstVaapiPixmap *
gst_vaapi_pixmap_new_from_native(const GstVaapiPixmapClass *pixmap_class,
GstVaapiDisplay *display, gpointer native_pixmap)
{
GstVaapiPixmap *pixmap;
pixmap = gst_vaapi_pixmap_new_internal(pixmap_class, display);
if (!pixmap)
return NULL;
GST_VAAPI_OBJECT_ID(pixmap) = GPOINTER_TO_SIZE(native_pixmap);
pixmap->use_foreign_pixmap = TRUE;
if (!pixmap_class->create(pixmap))
goto error;
return pixmap;
error:
gst_vaapi_pixmap_unref_internal(pixmap);
return NULL;
}
/**
* gst_vaapi_pixmap_ref:
* @pixmap: a #GstVaapiPixmap
*
* Atomically increases the reference count of the given @pixmap by one.
*
* Returns: The same @pixmap argument
*/
GstVaapiPixmap *
gst_vaapi_pixmap_ref(GstVaapiPixmap *pixmap)
{
return gst_vaapi_pixmap_ref_internal(pixmap);
}
/**
* gst_vaapi_pixmap_unref:
* @pixmap: a #GstVaapiPixmap
*
* Atomically decreases the reference count of the @pixmap by one. If
* the reference count reaches zero, the pixmap will be free'd.
*/
void
gst_vaapi_pixmap_unref(GstVaapiPixmap *pixmap)
{
gst_vaapi_pixmap_unref_internal(pixmap);
}
/**
* gst_vaapi_pixmap_replace:
* @old_pixmap_ptr: a pointer to a #GstVaapiPixmap
* @new_pixmap: a #GstVaapiPixmap
*
* Atomically replaces the pixmap pixmap held in @old_pixmap_ptr with
* @new_pixmap. This means that @old_pixmap_ptr shall reference a
* valid pixmap. However, @new_pixmap can be NULL.
*/
void
gst_vaapi_pixmap_replace(GstVaapiPixmap **old_pixmap_ptr,
GstVaapiPixmap *new_pixmap)
{
gst_vaapi_pixmap_replace_internal(old_pixmap_ptr, new_pixmap);
}
/**
* gst_vaapi_pixmap_get_display:
* @pixmap: a #GstVaapiPixmap
*
* Returns the #GstVaapiDisplay this @pixmap is bound to.
*
* Return value: the parent #GstVaapiDisplay object
*/
GstVaapiDisplay *
gst_vaapi_pixmap_get_display(GstVaapiPixmap *pixmap)
{
g_return_val_if_fail(pixmap != NULL, NULL);
return GST_VAAPI_OBJECT_DISPLAY(pixmap);
}
/**
* gst_vaapi_pixmap_get_format:
* @pixmap: a #GstVaapiPixmap
*
* Retrieves the format of a #GstVaapiPixmap.
*
* Return value: the format of the @pixmap
*/
GstVideoFormat
gst_vaapi_pixmap_get_format(GstVaapiPixmap *pixmap)
{
g_return_val_if_fail(pixmap != NULL, GST_VIDEO_FORMAT_UNKNOWN);
return GST_VAAPI_PIXMAP_FORMAT(pixmap);
}
/**
* gst_vaapi_pixmap_get_width:
* @pixmap: a #GstVaapiPixmap
*
* Retrieves the width of a #GstVaapiPixmap.
*
* Return value: the width of the @pixmap, in pixels
*/
guint
gst_vaapi_pixmap_get_width(GstVaapiPixmap *pixmap)
{
g_return_val_if_fail(pixmap != NULL, 0);
return GST_VAAPI_PIXMAP_WIDTH(pixmap);
}
/**
* gst_vaapi_pixmap_get_height:
* @pixmap: a #GstVaapiPixmap
*
* Retrieves the height of a #GstVaapiPixmap
*
* Return value: the height of the @pixmap, in pixels
*/
guint
gst_vaapi_pixmap_get_height(GstVaapiPixmap *pixmap)
{
g_return_val_if_fail(pixmap != NULL, 0);
return GST_VAAPI_PIXMAP_HEIGHT(pixmap);
}
/**
* gst_vaapi_pixmap_get_size:
* @pixmap: a #GstVaapiPixmap
* @width: return location for the width, or %NULL
* @height: return location for the height, or %NULL
*
* Retrieves the dimensions of a #GstVaapiPixmap.
*/
void
gst_vaapi_pixmap_get_size(GstVaapiPixmap *pixmap, guint *width, guint *height)
{
g_return_if_fail(pixmap != NULL);
if (width)
*width = GST_VAAPI_PIXMAP_WIDTH(pixmap);
if (height)
*height = GST_VAAPI_PIXMAP_HEIGHT(pixmap);
}
/**
* gst_vaapi_pixmap_put_surface:
* @pixmap: a #GstVaapiPixmap
* @surface: a #GstVaapiSurface
* @crop_rect: the video cropping rectangle, or %NULL if the entire
* surface is to be used.
* @flags: postprocessing flags. See #GstVaapiSurfaceRenderFlags
*
* Renders the whole @surface, or a cropped region defined with
* @crop_rect, into the @pixmap, while scaling to fit the target
* pixmap. The @flags specify how de-interlacing (if needed), color
* space conversion, scaling and other postprocessing transformations
* are performed.
*
* Return value: %TRUE on success
*/
gboolean
gst_vaapi_pixmap_put_surface(GstVaapiPixmap *pixmap, GstVaapiSurface *surface,
const GstVaapiRectangle *crop_rect, guint flags)
{
GstVaapiRectangle src_rect;
g_return_val_if_fail(pixmap != NULL, FALSE);
g_return_val_if_fail(surface != NULL, FALSE);
if (!crop_rect) {
src_rect.x = 0;
src_rect.y = 0;
src_rect.width = GST_VAAPI_SURFACE_WIDTH(surface);
src_rect.height = GST_VAAPI_SURFACE_HEIGHT(surface);
crop_rect = &src_rect;
}
return GST_VAAPI_PIXMAP_GET_CLASS(pixmap)->render(pixmap, surface,
crop_rect, flags);
}

View file

@ -0,0 +1,97 @@
/*
* gstvaapipixmap.h - Pixmap abstraction
*
* Copyright (C) 2013 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef GST_VAAPI_PIXMAP_H
#define GST_VAAPI_PIXMAP_H
#include <gst/vaapi/gstvaapitypes.h>
#include <gst/vaapi/gstvaapiobject.h>
#include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapisurface.h>
#include <gst/vaapi/video-format.h>
G_BEGIN_DECLS
#define GST_VAAPI_PIXMAP(obj) \
((GstVaapiPixmap *)(obj))
typedef struct _GstVaapiPixmap GstVaapiPixmap;
typedef struct _GstVaapiPixmapClass GstVaapiPixmapClass;
/**
* GST_VAAPI_PIXMAP_FORMAT:
* @pixmap: a #GstVaapiPixmap
*
* Macro that evaluates to the format in pixels of the @pixmap.
*/
#define GST_VAAPI_PIXMAP_FORMAT(pixmap) \
gst_vaapi_pixmap_get_format(GST_VAAPI_PIXMAP(pixmap))
/**
* GST_VAAPI_PIXMAP_WIDTH:
* @pixmap: a #GstVaapiPixmap
*
* Macro that evaluates to the width in pixels of the @pixmap.
*/
#define GST_VAAPI_PIXMAP_WIDTH(pixmap) \
gst_vaapi_pixmap_get_width(GST_VAAPI_PIXMAP(pixmap))
/**
* GST_VAAPI_PIXMAP_HEIGHT:
* @pixmap: a #GstVaapiPixmap
*
* Macro that evaluates to the height in pixels of the @pixmap.
*/
#define GST_VAAPI_PIXMAP_HEIGHT(pixmap) \
gst_vaapi_pixmap_get_height(GST_VAAPI_PIXMAP(pixmap))
GstVaapiPixmap *
gst_vaapi_pixmap_ref(GstVaapiPixmap *pixmap);
void
gst_vaapi_pixmap_unref(GstVaapiPixmap *pixmap);
void
gst_vaapi_pixmap_replace(GstVaapiPixmap **old_pixmap_ptr,
GstVaapiPixmap *new_pixmap);
GstVaapiDisplay *
gst_vaapi_pixmap_get_display(GstVaapiPixmap *pixmap);
GstVideoFormat
gst_vaapi_pixmap_get_format(GstVaapiPixmap *pixmap);
guint
gst_vaapi_pixmap_get_width(GstVaapiPixmap *pixmap);
guint
gst_vaapi_pixmap_get_height(GstVaapiPixmap *pixmap);
void
gst_vaapi_pixmap_get_size(GstVaapiPixmap *pixmap, guint *width, guint *height);
gboolean
gst_vaapi_pixmap_put_surface(GstVaapiPixmap *pixmap, GstVaapiSurface *surface,
const GstVaapiRectangle *crop_rect, guint flags);
G_END_DECLS
#endif /* GST_VAAPI_PIXMAP_H */

View file

@ -0,0 +1,137 @@
/*
* gstvaapipixmap_priv.h - Pixmap abstraction (private definitions)
*
* Copyright (C) 2013 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef GST_VAAPI_PIXMAP_PRIV_H
#define GST_VAAPI_PIXMAP_PRIV_H
#include "gstvaapiobject_priv.h"
G_BEGIN_DECLS
#define GST_VAAPI_PIXMAP_CLASS(klass) \
((GstVaapiPixmapClass *)(klass))
#define GST_VAAPI_PIXMAP_GET_CLASS(obj) \
GST_VAAPI_PIXMAP_CLASS(GST_VAAPI_OBJECT_GET_CLASS(obj))
/**
* GST_VAAPI_PIXMAP_FORMAT:
* @pixmap: a #GstVaapiPixmap
*
* Macro that evaluates to the format in pixels of the @pixmap.
*/
#undef GST_VAAPI_PIXMAP_FORMAT
#define GST_VAAPI_PIXMAP_FORMAT(pixmap) \
(GST_VAAPI_PIXMAP(pixmap)->format)
/**
* GST_VAAPI_PIXMAP_WIDTH:
* @pixmap: a #GstVaapiPixmap
*
* Macro that evaluates to the width in pixels of the @pixmap.
*/
#undef GST_VAAPI_PIXMAP_WIDTH
#define GST_VAAPI_PIXMAP_WIDTH(pixmap) \
(GST_VAAPI_PIXMAP(pixmap)->width)
/**
* GST_VAAPI_PIXMAP_HEIGHT:
* @pixmap: a #GstVaapiPixmap
*
* Macro that evaluates to the height in pixels of the @pixmap.
*/
#undef GST_VAAPI_PIXMAP_HEIGHT
#define GST_VAAPI_PIXMAP_HEIGHT(pixmap) \
(GST_VAAPI_PIXMAP(pixmap)->height)
/* GstVaapiPixmapClass hooks */
typedef gboolean (*GstVaapiPixmapCreateFunc) (GstVaapiPixmap *pixmap);
typedef gboolean (*GstVaapiPixmapRenderFunc) (GstVaapiPixmap *pixmap,
GstVaapiSurface *surface, const GstVaapiRectangle *crop_rect, guint flags);
/**
* GstVaapiPixmap:
*
* Base class for system-dependent pixmaps.
*/
struct _GstVaapiPixmap {
/*< private >*/
GstVaapiObject parent_instance;
/*< protected >*/
GstVideoFormat format;
guint width;
guint height;
guint use_foreign_pixmap : 1;
};
/**
* GstVaapiPixmapClass:
* @create: virtual function to create a pixmap with width and height
* @render: virtual function to render a #GstVaapiSurface into a pixmap
*
* Base class for system-dependent pixmaps.
*/
struct _GstVaapiPixmapClass {
/*< private >*/
GstVaapiObjectClass parent_class;
/*< protected >*/
GstVaapiPixmapCreateFunc create;
GstVaapiPixmapRenderFunc render;
};
GstVaapiPixmap *
gst_vaapi_pixmap_new(const GstVaapiPixmapClass *pixmap_class,
GstVaapiDisplay *display, GstVideoFormat format, guint width, guint height);
GstVaapiPixmap *
gst_vaapi_pixmap_new_from_native(const GstVaapiPixmapClass *pixmap_class,
GstVaapiDisplay *display, gpointer native_pixmap);
/* Inline reference counting for core libgstvaapi library */
#ifdef GST_VAAPI_CORE
#define gst_vaapi_pixmap_ref_internal(pixmap) \
((gpointer)gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pixmap)))
#define gst_vaapi_pixmap_unref_internal(pixmap) \
gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pixmap))
#define gst_vaapi_pixmap_replace_internal(old_pixmap_ptr, new_pixmap) \
gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pixmap_ptr), \
GST_VAAPI_MINI_OBJECT(new_pixmap))
#undef gst_vaapi_pixmap_ref
#define gst_vaapi_pixmap_ref(pixmap) \
gst_vaapi_pixmap_ref_internal((pixmap))
#undef gst_vaapi_pixmap_unref
#define gst_vaapi_pixmap_unref(pixmap) \
gst_vaapi_pixmap_unref_internal((pixmap))
#undef gst_vaapi_pixmap_replace
#define gst_vaapi_pixmap_replace(old_pixmap_ptr, new_pixmap) \
gst_vaapi_pixmap_replace_internal((old_pixmap_ptr), (new_pixmap))
#endif
G_END_DECLS
#endif /* GST_VAAPI_PIXMAP_PRIV_H */

View file

@ -434,3 +434,60 @@ gst_vaapi_window_put_surface(
return klass->render(window, surface, src_rect, dst_rect, flags);
}
static inline void
get_pixmap_rect(GstVaapiPixmap *pixmap, GstVaapiRectangle *rect)
{
guint width, height;
gst_vaapi_pixmap_get_size(pixmap, &width, &height);
rect->x = 0;
rect->y = 0;
rect->width = width;
rect->height = height;
}
/**
* gst_vaapi_window_put_pixmap:
* @window: a #GstVaapiWindow
* @pixmap: a #GstVaapiPixmap
* @src_rect: the sub-rectangle of the source pixmap to
* extract and process. If %NULL, the entire pixmap will be used.
* @dst_rect: the sub-rectangle of the destination
* window into which the pixmap is rendered. If %NULL, the entire
* window will be used.
*
* Renders the @pixmap region specified by @src_rect into the @window
* region specified by @dst_rect.
*
* Return value: %TRUE on success
*/
gboolean
gst_vaapi_window_put_pixmap(
GstVaapiWindow *window,
GstVaapiPixmap *pixmap,
const GstVaapiRectangle *src_rect,
const GstVaapiRectangle *dst_rect
)
{
const GstVaapiWindowClass *klass;
GstVaapiRectangle src_rect_default, dst_rect_default;
g_return_val_if_fail(window != NULL, FALSE);
g_return_val_if_fail(pixmap != NULL, FALSE);
klass = GST_VAAPI_WINDOW_GET_CLASS(window);
if (!klass->render_pixmap)
return FALSE;
if (!src_rect) {
src_rect = &src_rect_default;
get_pixmap_rect(pixmap, &src_rect_default);
}
if (!dst_rect) {
dst_rect = &dst_rect_default;
get_window_rect(window, &dst_rect_default);
}
return klass->render_pixmap(window, pixmap, src_rect, dst_rect);
}

View file

@ -28,6 +28,7 @@
#include <gst/vaapi/gstvaapiobject.h>
#include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapisurface.h>
#include <gst/vaapi/gstvaapipixmap.h>
G_BEGIN_DECLS
@ -89,6 +90,14 @@ gst_vaapi_window_put_surface(
guint flags
);
gboolean
gst_vaapi_window_put_pixmap(
GstVaapiWindow *window,
GstVaapiPixmap *pixmap,
const GstVaapiRectangle *src_rect,
const GstVaapiRectangle *dst_rect
);
G_END_DECLS
#endif /* GST_VAAPI_WINDOW_H */

View file

@ -47,6 +47,9 @@ typedef gboolean (*GstVaapiWindowResizeFunc) (GstVaapiWindow *window,
typedef gboolean (*GstVaapiWindowRenderFunc) (GstVaapiWindow *window,
GstVaapiSurface *surface, const GstVaapiRectangle *src_rect,
const GstVaapiRectangle *dst_rect, guint flags);
typedef gboolean (*GstVaapiWindowRenderPixmapFunc)(GstVaapiWindow *window,
GstVaapiPixmap *pixmap, const GstVaapiRectangle *src_rect,
const GstVaapiRectangle *dst_rect);
/**
* GstVaapiWindow:
@ -91,6 +94,7 @@ struct _GstVaapiWindowClass {
GstVaapiWindowSetFullscreenFunc set_fullscreen;
GstVaapiWindowResizeFunc resize;
GstVaapiWindowRenderFunc render;
GstVaapiWindowRenderPixmapFunc render_pixmap;
};
GstVaapiWindow *