plugins: add new base object, store display in there.

Introduce a new GstVaapiPluginBase object that will contain all common
data structures and perform all common tasks. First step is to have a
single place to hold VA displays.

While we are at it, also make sure to store and subsequently release
the appropriate debug category for the subclasses.
This commit is contained in:
Gwenole Beauchesne 2013-12-13 10:24:26 +01:00
parent 61f6cbffc6
commit 7e58d60854
15 changed files with 391 additions and 136 deletions

View file

@ -36,6 +36,7 @@ endif
libgstvaapi_source_c = \
gstvaapi.c \
gstvaapidecode.c \
gstvaapipluginbase.c \
gstvaapipluginutil.c \
gstvaapipostproc.c \
gstvaapisink.c \
@ -47,6 +48,7 @@ libgstvaapi_source_c = \
libgstvaapi_source_h = \
gstvaapidecode.h \
gstvaapipluginbase.h \
gstvaapipluginutil.h \
gstvaapipostproc.h \
gstvaapisink.h \

View file

@ -120,7 +120,7 @@ gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type,
const GValue *value)
{
GstVaapiDecode *decode = GST_VAAPIDECODE (context);
gst_vaapi_set_display (type, value, &decode->display);
gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(decode));
}
static void
@ -518,7 +518,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query)
gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12,
GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi));
g_return_val_if_fail(decode->display != NULL, FALSE);
g_return_val_if_fail(GST_VAAPI_PLUGIN_BASE_DISPLAY(decode) != NULL, FALSE);
if (gst_query_get_n_allocation_pools(query) > 0) {
gst_query_parse_nth_allocation_pool(query, 0, &pool, &size, &min, &max);
@ -536,7 +536,8 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query)
GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) {
GST_INFO("no pool or doesn't support GstVaapiVideoMeta, "
"making new pool");
pool = gst_vaapi_video_buffer_pool_new(decode->display);
pool = gst_vaapi_video_buffer_pool_new(
GST_VAAPI_PLUGIN_BASE_DISPLAY(decode));
if (!pool)
goto error_create_pool;
@ -593,7 +594,7 @@ gst_vaapidecode_set_context(GstElement *element, GstContext *context)
if (gst_vaapi_video_context_get_display(context, &display)) {
GST_INFO_OBJECT(element, "set display %p", display);
gst_vaapi_display_replace(&decode->display, display);
GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(decode, display);
gst_vaapi_display_unref(display);
}
}
@ -603,7 +604,7 @@ static inline gboolean
gst_vaapidecode_ensure_display(GstVaapiDecode *decode)
{
return gst_vaapi_ensure_display(decode, GST_VAAPI_DISPLAY_TYPE_ANY,
&decode->display);
&GST_VAAPI_PLUGIN_BASE_DISPLAY(decode));
}
static inline guint
@ -619,7 +620,7 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps)
if (!gst_vaapidecode_ensure_display(decode))
return FALSE;
dpy = decode->display;
dpy = GST_VAAPI_PLUGIN_BASE_DISPLAY(decode);
switch (gst_vaapi_codec_from_caps(caps)) {
case GST_VAAPI_CODEC_MPEG2:
@ -716,12 +717,11 @@ gst_vaapidecode_finalize(GObject *object)
gst_caps_replace(&decode->srcpad_caps, NULL);
gst_caps_replace(&decode->allowed_caps, NULL);
gst_vaapi_display_replace(&decode->display, NULL);
g_cond_clear(&decode->decoder_finish_done);
g_cond_clear(&decode->decoder_ready);
g_mutex_clear(&decode->decoder_mutex);
gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object));
G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object);
}
@ -729,15 +729,18 @@ static gboolean
gst_vaapidecode_open(GstVideoDecoder *vdec)
{
GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
GstVaapiDisplay * const old_display = decode->display;
GstVaapiDisplay * const old_display = GST_VAAPI_PLUGIN_BASE_DISPLAY(decode);
gboolean success;
if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(decode)))
return FALSE;
/* Let GstVideoContext ask for a proper display to its neighbours */
/* Note: steal old display that may be allocated from get_caps()
so that to retain a reference to it, thus avoiding extra
initialization steps if we turn out to simply re-use the
existing (cached) VA display */
decode->display = NULL;
GST_VAAPI_PLUGIN_BASE_DISPLAY(decode) = NULL;
success = gst_vaapidecode_ensure_display(decode);
if (old_display)
gst_vaapi_display_unref(old_display);
@ -750,7 +753,7 @@ gst_vaapidecode_close(GstVideoDecoder *vdec)
GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
gst_vaapidecode_destroy(decode);
gst_vaapi_display_replace(&decode->display, NULL);
gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(decode));
return TRUE;
}
@ -835,6 +838,8 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass)
GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode,
GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass));
object_class->finalize = gst_vaapidecode_finalize;
vdec_class->open = GST_DEBUG_FUNCPTR(gst_vaapidecode_open);
@ -881,7 +886,8 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode)
if (!gst_vaapidecode_ensure_display(decode))
goto error_no_display;
decode_caps = gst_vaapi_display_get_decode_caps(decode->display);
decode_caps = gst_vaapi_display_get_decode_caps(
GST_VAAPI_PLUGIN_BASE_DISPLAY(decode));
if (!decode_caps)
goto error_no_decode_caps;
n_decode_caps = gst_caps_get_size(decode_caps);
@ -945,8 +951,8 @@ gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS)
GST_INFO_OBJECT(decode, "query type %s", GST_QUERY_TYPE_NAME(query));
if (gst_vaapi_reply_to_query(query, decode->display)) {
GST_DEBUG("sharing display %p", decode->display);
if (gst_vaapi_reply_to_query(query, GST_VAAPI_PLUGIN_BASE_DISPLAY(decode))) {
GST_DEBUG("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(decode));
res = TRUE;
}
else if (GST_PAD_IS_SINK(pad)) {
@ -979,7 +985,8 @@ gst_vaapidecode_init(GstVaapiDecode *decode)
{
GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
decode->display = NULL;
gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(decode), GST_CAT_DEFAULT);
decode->decoder = NULL;
decode->decoder_caps = NULL;
decode->allowed_caps = NULL;

View file

@ -25,10 +25,7 @@
#ifndef GST_VAAPIDECODE_H
#define GST_VAAPIDECODE_H
#include <gst/gst.h>
#include <gst/gsttask.h>
#include <gst/video/gstvideodecoder.h>
#include <gst/vaapi/gstvaapidisplay.h>
#include "gstvaapipluginbase.h"
#include <gst/vaapi/gstvaapidecoder.h>
G_BEGIN_DECLS
@ -62,7 +59,7 @@ typedef struct _GstVaapiDecodeClass GstVaapiDecodeClass;
struct _GstVaapiDecode {
/*< private >*/
GstVideoDecoder parent_instance;
GstVaapiPluginBase parent_instance;
GstPad *sinkpad;
GstCaps *sinkpad_caps;
@ -70,7 +67,6 @@ struct _GstVaapiDecode {
GstPad *srcpad;
GstCaps *srcpad_caps;
GstPadQueryFunction srcpad_query;
GstVaapiDisplay *display;
GstVaapiDecoder *decoder;
GMutex decoder_mutex;
GCond decoder_ready;
@ -85,7 +81,7 @@ struct _GstVaapiDecode {
struct _GstVaapiDecodeClass {
/*< private >*/
GstVideoDecoderClass parent_class;
GstVaapiPluginBaseClass parent_class;
};
GType

View file

@ -75,9 +75,8 @@ struct _TransformSizeCache {
struct _GstVaapiDownload {
/*< private >*/
GstBaseTransform parent_instance;
GstVaapiPluginBase parent_instance;
GstVaapiDisplay *display;
GstCaps *allowed_caps;
TransformSizeCache transform_size_cache[2];
GstVaapiVideoPool *images;
@ -89,7 +88,7 @@ struct _GstVaapiDownload {
struct _GstVaapiDownloadClass {
/*< private >*/
GstBaseTransformClass parent_class;
GstVaapiPluginBaseClass parent_class;
};
/* GstImplementsInterface interface */
@ -114,7 +113,7 @@ gst_vaapidownload_set_video_context(GstVideoContext *context, const gchar *type,
const GValue *value)
{
GstVaapiDownload *download = GST_VAAPIDOWNLOAD (context);
gst_vaapi_set_display (type, value, &download->display);
gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(download));
}
static void
@ -199,7 +198,7 @@ gst_vaapidownload_destroy(GstVaapiDownload *download)
}
gst_vaapi_video_pool_replace(&download->images, NULL);
gst_vaapi_display_replace(&download->display, NULL);
GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(download, NULL);
}
static void
@ -207,6 +206,7 @@ gst_vaapidownload_finalize(GObject *object)
{
gst_vaapidownload_destroy(GST_VAAPIDOWNLOAD(object));
gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object));
G_OBJECT_CLASS(gst_vaapidownload_parent_class)->finalize(object);
}
@ -221,6 +221,8 @@ gst_vaapidownload_class_init(GstVaapiDownloadClass *klass)
GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidownload,
GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass));
object_class->finalize = gst_vaapidownload_finalize;
trans_class->start = gst_vaapidownload_start;
trans_class->stop = gst_vaapidownload_stop;
@ -250,7 +252,8 @@ gst_vaapidownload_init(GstVaapiDownload *download)
{
GstPad *sinkpad, *srcpad;
download->display = NULL;
gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(download), GST_CAT_DEFAULT);
download->allowed_caps = NULL;
download->images = NULL;
download->images_reset = FALSE;
@ -273,7 +276,7 @@ static inline gboolean
gst_vaapidownload_ensure_display(GstVaapiDownload *download)
{
return gst_vaapi_ensure_display(download, GST_VAAPI_DISPLAY_TYPE_ANY,
&download->display);
&GST_VAAPI_PLUGIN_BASE_DISPLAY(download));
}
static gboolean
@ -281,6 +284,8 @@ gst_vaapidownload_start(GstBaseTransform *trans)
{
GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans);
if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(trans)))
return FALSE;
if (!gst_vaapidownload_ensure_display(download))
return FALSE;
return TRUE;
@ -289,9 +294,7 @@ gst_vaapidownload_start(GstBaseTransform *trans)
static gboolean
gst_vaapidownload_stop(GstBaseTransform *trans)
{
GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans);
gst_vaapi_display_replace(&download->display, NULL);
gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(trans));
return TRUE;
}
@ -443,7 +446,8 @@ gst_vaapidownload_transform_caps(
if (download->allowed_caps)
allowed_caps = gst_caps_ref(download->allowed_caps);
else {
allowed_caps = gst_vaapi_display_get_image_caps(download->display);
allowed_caps = gst_vaapi_display_get_image_caps(
GST_VAAPI_PLUGIN_BASE_DISPLAY(download));
if (!allowed_caps)
return NULL;
}
@ -504,7 +508,8 @@ gst_vaapidownload_ensure_image_pool(GstVaapiDownload *download, GstCaps *caps)
download->image_width = width;
download->image_height = height;
gst_vaapi_video_pool_replace(&download->images, NULL);
download->images = gst_vaapi_image_pool_new(download->display, &vi);
download->images = gst_vaapi_image_pool_new(
GST_VAAPI_PLUGIN_BASE_DISPLAY(download), &vi);
if (!download->images)
return FALSE;
download->images_reset = TRUE;
@ -587,11 +592,12 @@ static gboolean
gst_vaapidownload_query(GstPad *pad, GstQuery *query)
{
GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(gst_pad_get_parent_element(pad));
GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(download);
gboolean res;
GST_DEBUG("sharing display %p", download->display);
GST_DEBUG("sharing display %p", display);
if (gst_vaapi_reply_to_query(query, download->display))
if (gst_vaapi_reply_to_query(query, display))
res = TRUE;
else
res = gst_pad_query_default(pad, query);

View file

@ -25,8 +25,7 @@
#ifndef GST_VAAPIDOWNLOAD_H
#define GST_VAAPIDOWNLOAD_H
#include <gst/base/gstbasetransform.h>
#include <gst/vaapi/gstvaapidisplay.h>
#include "gstvaapipluginbase.h"
#include <gst/vaapi/gstvaapisurface.h>
#include <gst/vaapi/gstvaapiimagepool.h>
#include <gst/vaapi/gstvaapisurfacepool.h>

View file

@ -68,7 +68,7 @@ gst_vaapiencode_set_context (GstElement * element, GstContext * context)
if (gst_vaapi_video_context_get_display (context, &display)) {
GST_INFO_OBJECT (element, "set display %p", display);
gst_vaapi_display_replace (&encode->display, display);
GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE (encode, display);
gst_vaapi_display_unref (display);
}
}
@ -79,7 +79,7 @@ gst_vaapiencode_set_video_context (GstVideoContext * context,
{
GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (context);
gst_vaapi_set_display (type, value, &encode->display);
gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY (encode));
}
static void
@ -114,7 +114,7 @@ static inline gboolean
ensure_display (GstVaapiEncode * encode)
{
return gst_vaapi_ensure_display (encode,
GST_VAAPI_DISPLAY_TYPE_ANY, &encode->display);
GST_VAAPI_DISPLAY_TYPE_ANY, &GST_VAAPI_PLUGIN_BASE_DISPLAY (encode));
}
static gboolean
@ -125,12 +125,14 @@ ensure_uploader (GstVaapiEncode * encode)
return FALSE;
if (!encode->uploader) {
encode->uploader = gst_vaapi_uploader_new (encode->display);
encode->uploader = gst_vaapi_uploader_new (
GST_VAAPI_PLUGIN_BASE_DISPLAY (encode));
if (!encode->uploader)
return FALSE;
}
if (!gst_vaapi_uploader_ensure_display (encode->uploader, encode->display))
if (!gst_vaapi_uploader_ensure_display (encode->uploader,
GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)))
return FALSE;
#endif
return TRUE;
@ -157,7 +159,7 @@ gst_vaapiencode_query (GST_PAD_QUERY_FUNCTION_ARGS)
GST_INFO_OBJECT (encode, "query type %s", GST_QUERY_TYPE_NAME (query));
if (gst_vaapi_reply_to_query (query, encode->display))
if (gst_vaapi_reply_to_query (query, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)))
success = TRUE;
else if (GST_PAD_IS_SINK (pad))
success = GST_PAD_QUERY_FUNCTION_CALL (encode->sinkpad_query,
@ -379,7 +381,6 @@ gst_vaapiencode_destroy (GstVaapiEncode * encode)
g_clear_object (&encode->uploader);
gst_caps_replace (&encode->sinkpad_caps, NULL);
gst_caps_replace (&encode->srcpad_caps, NULL);
gst_vaapi_display_replace (&encode->display, NULL);
return TRUE;
}
@ -397,7 +398,8 @@ ensure_encoder (GstVaapiEncode * encode)
if (!ensure_uploader_caps (encode))
return FALSE;
encode->encoder = klass->create_encoder (encode, encode->display);
encode->encoder = klass->create_encoder (encode,
GST_VAAPI_PLUGIN_BASE_DISPLAY (encode));
if (!encode->encoder)
return FALSE;
return TRUE;
@ -407,10 +409,13 @@ static gboolean
gst_vaapiencode_open (GstVideoEncoder * venc)
{
GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc);
GstVaapiDisplay *const old_display = encode->display;
GstVaapiDisplay *const old_display = GST_VAAPI_PLUGIN_BASE_DISPLAY (encode);
gboolean success;
encode->display = NULL;
if (!gst_vaapi_plugin_base_open (GST_VAAPI_PLUGIN_BASE (encode)))
return FALSE;
GST_VAAPI_PLUGIN_BASE_DISPLAY (encode) = NULL;
success = ensure_display (encode);
if (old_display)
gst_vaapi_display_unref (old_display);
@ -422,7 +427,9 @@ gst_vaapiencode_close (GstVideoEncoder * venc)
{
GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc);
return gst_vaapiencode_destroy (encode);
gst_vaapiencode_destroy (encode);
gst_vaapi_plugin_base_close (GST_VAAPI_PLUGIN_BASE (encode));
return TRUE;
}
static inline gboolean
@ -436,7 +443,7 @@ gst_vaapiencode_update_sink_caps (GstVaapiEncode * encode,
if (GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) {
/* Ensure the uploader is set up for upstream allocated buffers */
GstVaapiUploader *const uploader = encode->uploader;
if (!gst_vaapi_uploader_ensure_display (uploader, encode->display))
if (!gst_vaapi_uploader_ensure_display (uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)))
return FALSE;
if (!gst_vaapi_uploader_ensure_caps (uploader, state->caps, NULL))
return FALSE;
@ -527,7 +534,7 @@ gst_vaapiencode_ensure_video_buffer_pool (GstVaapiEncode * encode,
encode->video_buffer_size = 0;
}
pool = gst_vaapi_video_buffer_pool_new (encode->display);
pool = gst_vaapi_video_buffer_pool_new (GST_VAAPI_PLUGIN_BASE_DISPLAY (encode));
if (!pool)
goto error_create_pool;
@ -903,12 +910,15 @@ gst_vaapiencode_finalize (GObject * object)
encode->sinkpad = NULL;
encode->srcpad = NULL;
gst_vaapi_plugin_base_finalize (GST_VAAPI_PLUGIN_BASE (object));
G_OBJECT_CLASS (gst_vaapiencode_parent_class)->finalize (object);
}
static void
gst_vaapiencode_init (GstVaapiEncode * encode)
{
gst_vaapi_plugin_base_init (GST_VAAPI_PLUGIN_BASE (encode), GST_CAT_DEFAULT);
/* sink pad */
encode->sinkpad = GST_VIDEO_ENCODER_SINK_PAD (encode);
encode->sinkpad_query = GST_PAD_QUERYFUNC (encode->sinkpad);
@ -935,6 +945,8 @@ gst_vaapiencode_class_init (GstVaapiEncodeClass * klass)
GST_DEBUG_CATEGORY_INIT (gst_vaapiencode_debug,
GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
gst_vaapi_plugin_base_class_init (GST_VAAPI_PLUGIN_BASE_CLASS (klass));
object_class->finalize = gst_vaapiencode_finalize;
object_class->set_property = gst_vaapiencode_set_property;
object_class->get_property = gst_vaapiencode_get_property;

View file

@ -22,8 +22,7 @@
#ifndef GST_VAAPIENCODE_H
#define GST_VAAPIENCODE_H
#include <gst/gst.h>
#include <gst/video/gstvideoencoder.h>
#include "gstvaapipluginbase.h"
#include <gst/vaapi/gstvaapiencoder.h>
#include "gstvaapiuploader.h"
@ -50,7 +49,7 @@ typedef struct _GstVaapiEncodeClass GstVaapiEncodeClass;
struct _GstVaapiEncode
{
/*< private >*/
GstVideoEncoder parent_instance;
GstVaapiPluginBase parent_instance;
GstPad *sinkpad;
GstCaps *sinkpad_caps;
@ -61,7 +60,6 @@ struct _GstVaapiEncode
GstCaps *srcpad_caps;
GstPadQueryFunction srcpad_query;
GstVaapiDisplay *display;
GstVaapiEncoder *encoder;
GstVaapiUploader *uploader;
@ -79,7 +77,7 @@ struct _GstVaapiEncode
struct _GstVaapiEncodeClass
{
/*< private >*/
GstVideoEncoderClass parent_class;
GstVaapiPluginBaseClass parent_class;
gboolean (*check_ratecontrol) (GstVaapiEncode * encode,
GstVaapiRateControl rate_control);

View file

@ -0,0 +1,76 @@
/*
* gstvaapipluginbase.c - Base GStreamer VA-API Plugin element
*
* Copyright (C) 2010-2011 Splitted-Desktop Systems
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
* Copyright (C) 2011-2013 Intel Corporation
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
*
* 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
*/
#include "gst/vaapi/sysdeps.h"
#include "gstvaapipluginbase.h"
#define GST_CAT_DEFAULT (plugin->debug_category)
void
gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass)
{
}
void
gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin,
GstDebugCategory * debug_category)
{
plugin->debug_category = debug_category;
}
void
gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin)
{
gst_vaapi_plugin_base_close (plugin);
gst_debug_category_free (plugin->debug_category);
}
/**
* gst_vaapi_plugin_base_open:
* @plugin: a #GstVaapiPluginBase
*
* Allocates any internal resources needed for correct operation from
* the subclass.
*
* Returns: %TRUE if successful, %FALSE otherwise.
*/
gboolean
gst_vaapi_plugin_base_open (GstVaapiPluginBase * plugin)
{
return TRUE;
}
/**
* gst_vaapi_plugin_base_close:
* @plugin: a #GstVaapiPluginBase
*
* Deallocates all internal resources that were allocated so
* far. i.e. put the base plugin object into a clean state.
*/
void
gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin)
{
gst_vaapi_display_replace (&plugin->display, NULL);
}

View file

@ -0,0 +1,130 @@
/*
* gstvaapipluginbase.h - Base GStreamer VA-API Plugin element
*
* Copyright (C) 2010-2011 Splitted-Desktop Systems
* Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
* Copyright (C) 2011-2013 Intel Corporation
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
*
* 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_PLUGIN_BASE_H
#define GST_VAAPI_PLUGIN_BASE_H
#include <gst/base/gstbasetransform.h>
#include <gst/video/gstvideodecoder.h>
#include <gst/video/gstvideoencoder.h>
#include <gst/video/gstvideosink.h>
#include <gst/vaapi/gstvaapidisplay.h>
G_BEGIN_DECLS
typedef struct _GstVaapiPluginBase GstVaapiPluginBase;
typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass;
#define GST_VAAPI_PLUGIN_BASE(plugin) \
((GstVaapiPluginBase *)(plugin))
#define GST_VAAPI_PLUGIN_BASE_CLASS(plugin) \
((GstVaapiPluginBaseClass *)(plugin))
#define GST_VAAPI_PLUGIN_BASE_GET_CLASS(plugin) \
GST_VAAPI_PLUGIN_BASE_CLASS(GST_ELEMENT_GET_CLASS( \
GST_VAAPI_PLUGIN_BASE_ELEMENT(plugin)))
#define GST_VAAPI_PLUGIN_BASE_PARENT(plugin) \
(&GST_VAAPI_PLUGIN_BASE(plugin)->parent_instance)
#define GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin) \
(&GST_VAAPI_PLUGIN_BASE_CLASS(plugin)->parent_class)
#define GST_VAAPI_PLUGIN_BASE_ELEMENT(plugin) \
(&GST_VAAPI_PLUGIN_BASE_PARENT(plugin)->element)
#define GST_VAAPI_PLUGIN_BASE_ELEMENT_CLASS(plugin) \
(&GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin)->element)
#define GST_VAAPI_PLUGIN_BASE_DECODER(plugin) \
(&GST_VAAPI_PLUGIN_BASE_PARENT(plugin)->decoder)
#define GST_VAAPI_PLUGIN_BASE_DECODER_CLASS(plugin) \
(&GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin)->decoder)
#define GST_VAAPI_PLUGIN_BASE_ENCODER(plugin) \
(&GST_VAAPI_PLUGIN_BASE_PARENT(plugin)->encoder)
#define GST_VAAPI_PLUGIN_BASE_ENCODER_CLASS(plugin) \
(&GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin)->encoder)
#define GST_VAAPI_PLUGIN_BASE_TRANSFORM(plugin) \
(&GST_VAAPI_PLUGIN_BASE_PARENT(plugin)->transform)
#define GST_VAAPI_PLUGIN_BASE_TRANSFORM_CLASS(plugin) \
(&GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin)->transform)
#define GST_VAAPI_PLUGIN_BASE_SINK(plugin) \
(&GST_VAAPI_PLUGIN_BASE_PARENT(plugin)->sink)
#define GST_VAAPI_PLUGIN_BASE_SINK_CLASS(plugin) \
(&GST_VAAPI_PLUGIN_BASE_PARENT_CLASS(plugin)->sink)
#define GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin) \
(GST_VAAPI_PLUGIN_BASE(plugin)->display)
#define GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(plugin, new_display) \
(gst_vaapi_display_replace(&GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin), \
(new_display)))
struct _GstVaapiPluginBase
{
/*< private >*/
union
{
GstElement element;
GstVideoDecoder decoder;
GstVideoEncoder encoder;
GstBaseTransform transform;
GstVideoSink sink;
} parent_instance;
GstDebugCategory *debug_category;
GstVaapiDisplay *display;
};
struct _GstVaapiPluginBaseClass
{
/*< private >*/
union
{
GstElementClass element;
GstVideoDecoderClass decoder;
GstVideoEncoderClass encoder;
GstBaseTransformClass transform;
GstVideoSinkClass sink;
} parent_class;
};
G_GNUC_INTERNAL
void
gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass);
G_GNUC_INTERNAL
void
gst_vaapi_plugin_base_init (GstVaapiPluginBase * plugin,
GstDebugCategory * debug_category);
G_GNUC_INTERNAL
void
gst_vaapi_plugin_base_finalize (GstVaapiPluginBase * plugin);
G_GNUC_INTERNAL
gboolean
gst_vaapi_plugin_base_open (GstVaapiPluginBase * plugin);
G_GNUC_INTERNAL
void
gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin);
G_END_DECLS
#endif /* GST_VAAPI_PLUGIN_BASE_H */

View file

@ -118,10 +118,10 @@ gst_vaapipostproc_set_video_context(
{
GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(context);
gst_vaapi_set_display(type, value, &postproc->display);
gst_vaapi_set_display(type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc));
if (postproc->uploader)
gst_vaapi_uploader_ensure_display(postproc->uploader, postproc->display);
gst_vaapi_uploader_ensure_display(postproc->uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc));
}
static void
@ -263,7 +263,7 @@ gst_vaapipostproc_set_context(GstElement *element, GstContext *context)
if (gst_vaapi_video_context_get_display(context, &display)) {
GST_INFO_OBJECT(element, "set display %p", display);
gst_vaapi_display_replace(&postproc->display, display);
GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(postproc, display);
gst_vaapi_display_unref(display);
}
}
@ -273,7 +273,7 @@ static inline gboolean
gst_vaapipostproc_ensure_display(GstVaapiPostproc *postproc)
{
return gst_vaapi_ensure_display(postproc, GST_VAAPI_DISPLAY_TYPE_ANY,
&postproc->display);
&GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc));
}
static gboolean
@ -283,13 +283,14 @@ gst_vaapipostproc_ensure_uploader(GstVaapiPostproc *postproc)
return FALSE;
if (!postproc->uploader) {
postproc->uploader = gst_vaapi_uploader_new(postproc->display);
postproc->uploader = gst_vaapi_uploader_new(
GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc));
if (!postproc->uploader)
return FALSE;
}
if (!gst_vaapi_uploader_ensure_display(postproc->uploader,
postproc->display))
GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)))
return FALSE;
return TRUE;
}
@ -314,7 +315,8 @@ gst_vaapipostproc_ensure_filter(GstVaapiPostproc *postproc)
if (!gst_vaapipostproc_ensure_display(postproc))
return FALSE;
postproc->filter = gst_vaapi_filter_new(postproc->display);
postproc->filter = gst_vaapi_filter_new(
GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc));
if (!postproc->filter)
return FALSE;
return TRUE;
@ -339,6 +341,8 @@ gst_vaapipostproc_ensure_filter_caps(GstVaapiPostproc *postproc)
static gboolean
gst_vaapipostproc_create(GstVaapiPostproc *postproc)
{
if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(postproc)))
return FALSE;
if (!gst_vaapipostproc_ensure_display(postproc))
return FALSE;
if (!gst_vaapipostproc_ensure_uploader(postproc))
@ -375,12 +379,12 @@ gst_vaapipostproc_destroy(GstVaapiPostproc *postproc)
#endif
g_clear_object(&postproc->uploader);
gst_vaapipostproc_destroy_filter(postproc);
gst_vaapi_display_replace(&postproc->display, NULL);
gst_caps_replace(&postproc->allowed_sinkpad_caps, NULL);
gst_caps_replace(&postproc->sinkpad_caps, NULL);
gst_caps_replace(&postproc->allowed_srcpad_caps, NULL);
gst_caps_replace(&postproc->srcpad_caps, NULL);
gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(postproc));
}
static gboolean
@ -389,6 +393,8 @@ gst_vaapipostproc_start(GstBaseTransform *trans)
GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans);
ds_reset(&postproc->deinterlace_state);
if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(postproc)))
return FALSE;
if (!gst_vaapipostproc_ensure_display(postproc))
return FALSE;
return TRUE;
@ -400,7 +406,7 @@ gst_vaapipostproc_stop(GstBaseTransform *trans)
GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans);
ds_reset(&postproc->deinterlace_state);
gst_vaapi_display_replace(&postproc->display, NULL);
gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(postproc));
return TRUE;
}
@ -859,7 +865,7 @@ gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps,
if (postproc->is_raw_yuv) {
/* Ensure the uploader is set up for upstream allocated buffers */
GstVaapiUploader * const uploader = postproc->uploader;
if (!gst_vaapi_uploader_ensure_display(uploader, postproc->display))
if (!gst_vaapi_uploader_ensure_display(uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)))
return FALSE;
if (!gst_vaapi_uploader_ensure_caps(uploader, caps, NULL))
return FALSE;
@ -1360,7 +1366,8 @@ ensure_sinkpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps)
postproc->sinkpad_buffer_size = 0;
}
pool = gst_vaapi_video_buffer_pool_new(postproc->display);
pool = gst_vaapi_video_buffer_pool_new(
GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc));
if (!pool)
goto error_create_pool;
@ -1417,7 +1424,7 @@ ensure_srcpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps)
return TRUE;
postproc->filter_pool_info = vi;
pool = gst_vaapi_surface_pool_new(postproc->display,
pool = gst_vaapi_surface_pool_new(GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc),
&postproc->filter_pool_info);
if (!pool)
return FALSE;
@ -1462,8 +1469,8 @@ gst_vaapipostproc_query(GstBaseTransform *trans, GstPadDirection direction,
GST_INFO_OBJECT(trans, "query type `%s'", GST_QUERY_TYPE_NAME(query));
if (gst_vaapi_reply_to_query(query, postproc->display)) {
GST_DEBUG("sharing display %p", postproc->display);
if (gst_vaapi_reply_to_query(query, GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc))) {
GST_DEBUG("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc));
return TRUE;
}
@ -1521,6 +1528,7 @@ gst_vaapipostproc_finalize(GObject *object)
gst_vaapipostproc_destroy(postproc);
gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(postproc));
G_OBJECT_CLASS(gst_vaapipostproc_parent_class)->finalize(object);
}
@ -1621,6 +1629,8 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass)
GST_DEBUG_CATEGORY_INIT(gst_debug_vaapipostproc,
GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass));
object_class->finalize = gst_vaapipostproc_finalize;
object_class->set_property = gst_vaapipostproc_set_property;
object_class->get_property = gst_vaapipostproc_get_property;
@ -1778,6 +1788,8 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass)
static void
gst_vaapipostproc_init(GstVaapiPostproc *postproc)
{
gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(postproc), GST_CAT_DEFAULT);
postproc->format = DEFAULT_FORMAT;
postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE;
postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD;

View file

@ -23,8 +23,7 @@
#ifndef GST_VAAPIPOSTPROC_H
#define GST_VAAPIPOSTPROC_H
#include <gst/base/gstbasetransform.h>
#include <gst/vaapi/gstvaapidisplay.h>
#include "gstvaapipluginbase.h"
#include <gst/vaapi/gstvaapisurface.h>
#include <gst/vaapi/gstvaapisurfacepool.h>
#include <gst/vaapi/gstvaapifilter.h>
@ -135,9 +134,8 @@ struct _GstVaapiDeinterlaceState {
struct _GstVaapiPostproc {
/*< private >*/
GstBaseTransform parent_instance;
GstVaapiPluginBase parent_instance;
GstVaapiDisplay *display;
GstVaapiUploader *uploader;
GstVaapiFilter *filter;
GPtrArray *filter_ops;
@ -177,7 +175,7 @@ struct _GstVaapiPostproc {
struct _GstVaapiPostprocClass {
/*< private >*/
GstBaseTransformClass parent_class;
GstVaapiPluginBaseClass parent_class;
};
GType

View file

@ -133,7 +133,7 @@ gst_vaapisink_set_video_context(GstVideoContext *context, const gchar *type,
const GValue *value)
{
GstVaapiSink *sink = GST_VAAPISINK (context);
gst_vaapi_set_display (type, value, &sink->display);
gst_vaapi_set_display (type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(sink));
}
static void
@ -272,10 +272,10 @@ gst_vaapisink_destroy(GstVaapiSink *sink)
#if USE_GLX
gst_vaapi_texture_replace(&sink->texture, NULL);
#endif
gst_vaapi_display_replace(&sink->display, NULL);
g_clear_object(&sink->uploader);
gst_caps_replace(&sink->caps, NULL);
gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(sink));
}
#if USE_X11
@ -313,6 +313,8 @@ configure_notify_event_pending(
guint height
)
{
GstVaapiDisplayX11 * const display =
GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink));
ConfigureNotifyEventPendingArgs args;
XEvent xev;
@ -323,7 +325,7 @@ configure_notify_event_pending(
/* XXX: don't use XPeekIfEvent() because it might block */
XCheckIfEvent(
gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)),
gst_vaapi_display_x11_get_display(display),
&xev,
configure_notify_event_pending_cb, (XPointer)&args
);
@ -347,24 +349,24 @@ gst_vaapisink_ensure_display(GstVaapiSink *sink)
{
GstVaapiDisplayType display_type;
GstVaapiRenderMode render_mode;
const gboolean had_display = sink->display != NULL;
const gboolean had_display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink) != NULL;
if (!gst_vaapi_ensure_display(sink, sink->display_type, &sink->display))
if (!gst_vaapi_ensure_display(sink, sink->display_type, &GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)))
return FALSE;
display_type = gst_vaapi_display_get_display_type(sink->display);
if (display_type != sink->display_type || (!had_display && sink->display)) {
display_type = gst_vaapi_display_get_display_type(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink));
if (display_type != sink->display_type || (!had_display && GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) {
GST_INFO("created %s %p", get_display_type_name(display_type),
sink->display);
GST_VAAPI_PLUGIN_BASE_DISPLAY(sink));
sink->display_type = display_type;
sink->use_overlay =
gst_vaapi_display_get_render_mode(sink->display, &render_mode) &&
gst_vaapi_display_get_render_mode(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink), &render_mode) &&
render_mode == GST_VAAPI_RENDER_MODE_OVERLAY;
GST_DEBUG("use %s rendering mode", sink->use_overlay ? "overlay" : "texture");
sink->use_rotation = gst_vaapi_display_has_property(
sink->display, GST_VAAPI_DISPLAY_PROP_ROTATION);
GST_VAAPI_PLUGIN_BASE_DISPLAY(sink), GST_VAAPI_DISPLAY_PROP_ROTATION);
}
return TRUE;
}
@ -376,7 +378,8 @@ gst_vaapisink_ensure_uploader(GstVaapiSink *sink)
return FALSE;
if (!sink->uploader) {
sink->uploader = gst_vaapi_uploader_new(sink->display);
sink->uploader = gst_vaapi_uploader_new(
GST_VAAPI_PLUGIN_BASE_DISPLAY(sink));
if (!sink->uploader)
return FALSE;
}
@ -410,7 +413,7 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height)
GST_DEBUG("ensure render rect within %ux%u bounds", width, height);
gst_vaapi_display_get_pixel_aspect_ratio(
sink->display,
GST_VAAPI_PLUGIN_BASE_DISPLAY(sink),
&display_par_n, &display_par_d
);
GST_DEBUG("display pixel-aspect-ratio %d/%d",
@ -455,6 +458,7 @@ gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height)
static void
gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheight)
{
GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
GstVideoRectangle src_rect, dst_rect, out_rect;
guint num, den, display_width, display_height, display_par_n, display_par_d;
gboolean success, scale;
@ -465,7 +469,7 @@ gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheig
return;
}
gst_vaapi_display_get_size(sink->display, &display_width, &display_height);
gst_vaapi_display_get_size(display, &display_width, &display_height);
if (sink->fullscreen) {
*pwidth = display_width;
*pheight = display_height;
@ -473,7 +477,7 @@ gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheig
}
gst_vaapi_display_get_pixel_aspect_ratio(
sink->display,
display,
&display_par_n, &display_par_d
);
@ -505,7 +509,7 @@ gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheig
static inline gboolean
gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height)
{
GstVaapiDisplay * const display = sink->display;
GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
if (!sink->window) {
switch (sink->display_type) {
@ -543,6 +547,7 @@ gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height)
static gboolean
gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id)
{
GstVaapiDisplay *display;
Window rootwin;
unsigned int width, height, border_width, depth;
int x, y;
@ -550,15 +555,16 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id)
if (!gst_vaapisink_ensure_display(sink))
return FALSE;
display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
gst_vaapi_display_lock(sink->display);
gst_vaapi_display_lock(display);
XGetGeometry(
gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)),
gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)),
xid,
&rootwin,
&x, &y, &width, &height, &border_width, &depth
);
gst_vaapi_display_unlock(sink->display);
gst_vaapi_display_unlock(display);
if ((width != sink->window_width || height != sink->window_height) &&
!configure_notify_event_pending(sink, xid, width, height)) {
@ -577,11 +583,11 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id)
switch (sink->display_type) {
#if USE_GLX
case GST_VAAPI_DISPLAY_TYPE_GLX:
sink->window = gst_vaapi_window_glx_new_with_xid(sink->display, xid);
sink->window = gst_vaapi_window_glx_new_with_xid(display, xid);
break;
#endif
case GST_VAAPI_DISPLAY_TYPE_X11:
sink->window = gst_vaapi_window_x11_new_with_xid(sink->display, xid);
sink->window = gst_vaapi_window_x11_new_with_xid(display, xid);
break;
default:
GST_ERROR("unsupported display type %d", sink->display_type);
@ -594,9 +600,10 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id)
static gboolean
gst_vaapisink_ensure_rotation(GstVaapiSink *sink, gboolean recalc_display_rect)
{
GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
gboolean success = FALSE;
g_return_val_if_fail(sink->display, FALSE);
g_return_val_if_fail(display, FALSE);
if (sink->rotation == sink->rotation_req)
return TRUE;
@ -606,9 +613,9 @@ gst_vaapisink_ensure_rotation(GstVaapiSink *sink, gboolean recalc_display_rect)
goto end;
}
gst_vaapi_display_lock(sink->display);
success = gst_vaapi_display_set_rotation(sink->display, sink->rotation_req);
gst_vaapi_display_unlock(sink->display);
gst_vaapi_display_lock(display);
success = gst_vaapi_display_set_rotation(display, sink->rotation_req);
gst_vaapi_display_unlock(display);
if (!success) {
GST_ERROR("failed to change VA display rotation mode");
goto end;
@ -654,7 +661,7 @@ gst_vaapisink_ensure_video_buffer_pool(GstVaapiSink *sink, GstCaps *caps)
sink->video_buffer_size = 0;
}
pool = gst_vaapi_video_buffer_pool_new(sink->display);
pool = gst_vaapi_video_buffer_pool_new(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink));
if (!pool)
goto error_create_pool;
@ -701,6 +708,8 @@ gst_vaapisink_start(GstBaseSink *base_sink)
{
GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(sink)))
return FALSE;
return gst_vaapisink_ensure_uploader(sink);
}
@ -714,9 +723,8 @@ gst_vaapisink_stop(GstBaseSink *base_sink)
g_clear_object(&sink->video_buffer_pool);
#endif
gst_vaapi_window_replace(&sink->window, NULL);
gst_vaapi_display_replace(&sink->display, NULL);
g_clear_object(&sink->uploader);
gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(sink));
return TRUE;
}
@ -769,6 +777,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)
{
GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
GstVideoInfo * const vip = &sink->video_info;
GstVaapiDisplay *display;
guint win_width, win_height;
#if USE_DRM
@ -793,11 +802,12 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)
if (!gst_vaapisink_ensure_display(sink))
return FALSE;
display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
#if !GST_CHECK_VERSION(1,0,0)
if (sink->use_video_raw) {
/* Ensure the uploader is set up for upstream allocated buffers */
if (!gst_vaapi_uploader_ensure_display(sink->uploader, sink->display))
if (!gst_vaapi_uploader_ensure_display(sink->uploader, display))
return FALSE;
if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL))
return FALSE;
@ -812,9 +822,9 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)
gst_vaapi_window_set_size(sink->window, win_width, win_height);
}
else {
gst_vaapi_display_lock(sink->display);
gst_vaapi_display_lock(display);
gst_video_overlay_prepare_window_handle(GST_VIDEO_OVERLAY(sink));
gst_vaapi_display_unlock(sink->display);
gst_vaapi_display_unlock(display);
if (sink->window)
return TRUE;
if (!gst_vaapisink_ensure_window(sink, win_width, win_height))
@ -935,6 +945,7 @@ render_reflection(GstVaapiSink *sink)
static gboolean
gst_vaapisink_ensure_texture(GstVaapiSink *sink, GstVaapiSurface *surface)
{
GstVaapiDisplay * display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
GstVideoRectangle tex_rect, dis_rect, out_rect;
guint width, height;
@ -947,7 +958,7 @@ gst_vaapisink_ensure_texture(GstVaapiSink *sink, GstVaapiSurface *surface)
tex_rect.w = width;
tex_rect.h = height;
gst_vaapi_display_get_size(sink->display, &width, &height);
gst_vaapi_display_get_size(display, &width, &height);
dis_rect.x = 0;
dis_rect.y = 0;
dis_rect.w = width;
@ -963,7 +974,7 @@ gst_vaapisink_ensure_texture(GstVaapiSink *sink, GstVaapiSurface *surface)
height = tex_rect.h;
GST_INFO("texture size %ux%u", width, height);
sink->texture = gst_vaapi_texture_new(sink->display,
sink->texture = gst_vaapi_texture_new(display,
GL_TEXTURE_2D, GL_BGRA, width, height);
return sink->texture != NULL;
}
@ -1188,9 +1199,8 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer)
return ret;
meta = gst_buffer_get_vaapi_video_meta(buffer);
if (sink->display != gst_vaapi_video_meta_get_display(meta))
gst_vaapi_display_replace(&sink->display,
gst_vaapi_video_meta_get_display(meta));
GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(sink,
gst_vaapi_video_meta_get_display(meta));
if (!sink->window)
goto error;
@ -1325,7 +1335,7 @@ gst_vaapisink_buffer_alloc(
return GST_FLOW_OK;
}
if (!gst_vaapi_uploader_ensure_display(sink->uploader, sink->display))
if (!gst_vaapi_uploader_ensure_display(sink->uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)))
return GST_FLOW_NOT_SUPPORTED;
if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL))
return GST_FLOW_NOT_SUPPORTED;
@ -1350,7 +1360,7 @@ gst_vaapisink_set_context(GstElement *element, GstContext *context)
if (gst_vaapi_video_context_get_display(context, &display)) {
GST_INFO_OBJECT(element, "set display %p", display);
gst_vaapi_display_replace(&sink->display, display);
GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(sink, display);
gst_vaapi_display_unref(display);
}
}
@ -1363,8 +1373,8 @@ gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query)
GST_INFO_OBJECT(sink, "query type %s", GST_QUERY_TYPE_NAME(query));
if (gst_vaapi_reply_to_query(query, sink->display)) {
GST_DEBUG("sharing display %p", sink->display);
if (gst_vaapi_reply_to_query(query, GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) {
GST_DEBUG("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(sink));
return TRUE;
}
@ -1377,6 +1387,7 @@ gst_vaapisink_finalize(GObject *object)
{
gst_vaapisink_destroy(GST_VAAPISINK(object));
gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object));
G_OBJECT_CLASS(gst_vaapisink_parent_class)->finalize(object);
}
@ -1467,6 +1478,8 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass)
GST_DEBUG_CATEGORY_INIT(gst_debug_vaapisink,
GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass));
object_class->finalize = gst_vaapisink_finalize;
object_class->set_property = gst_vaapisink_set_property;
object_class->get_property = gst_vaapisink_get_property;
@ -1585,8 +1598,9 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass)
static void
gst_vaapisink_init(GstVaapiSink *sink)
{
gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(sink), GST_CAT_DEFAULT);
sink->caps = NULL;
sink->display = NULL;
sink->window = NULL;
sink->window_width = 0;
sink->window_height = 0;

View file

@ -25,8 +25,7 @@
#ifndef GST_VAAPISINK_H
#define GST_VAAPISINK_H
#include <gst/video/gstvideosink.h>
#include <gst/vaapi/gstvaapidisplay.h>
#include "gstvaapipluginbase.h"
#include <gst/vaapi/gstvaapiwindow.h>
#if USE_GLX
#include <gst/vaapi/gstvaapitexture.h>
@ -68,11 +67,10 @@ typedef struct _GstVaapiTexture GstVaapiTexture;
struct _GstVaapiSink {
/*< private >*/
GstVideoSink parent_instance;
GstVaapiPluginBase parent_instance;
GstVaapiUploader *uploader;
GstCaps *caps;
GstVaapiDisplay *display;
GstVaapiDisplayType display_type;
GstVaapiWindow *window;
guint window_width;
@ -104,7 +102,7 @@ struct _GstVaapiSink {
struct _GstVaapiSinkClass {
/*< private >*/
GstVideoSinkClass parent_class;
GstVaapiPluginBaseClass parent_class;
};
GType

View file

@ -92,10 +92,11 @@ gst_vaapiupload_set_video_context(GstVideoContext *context, const gchar *type,
{
GstVaapiUpload * const upload = GST_VAAPIUPLOAD(context);
gst_vaapi_set_display(type, value, &upload->display);
gst_vaapi_set_display(type, value, &GST_VAAPI_PLUGIN_BASE_DISPLAY(upload));
if (upload->uploader)
gst_vaapi_uploader_ensure_display(upload->uploader, upload->display);
gst_vaapi_uploader_ensure_display(upload->uploader,
GST_VAAPI_PLUGIN_BASE_DISPLAY(upload));
}
static void
@ -176,7 +177,6 @@ static void
gst_vaapiupload_destroy(GstVaapiUpload *upload)
{
g_clear_object(&upload->uploader);
gst_vaapi_display_replace(&upload->display, NULL);
}
static void
@ -184,6 +184,7 @@ gst_vaapiupload_finalize(GObject *object)
{
gst_vaapiupload_destroy(GST_VAAPIUPLOAD(object));
gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object));
G_OBJECT_CLASS(gst_vaapiupload_parent_class)->finalize(object);
}
@ -198,6 +199,8 @@ gst_vaapiupload_class_init(GstVaapiUploadClass *klass)
GST_DEBUG_CATEGORY_INIT(gst_debug_vaapiupload,
GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass));
object_class->finalize = gst_vaapiupload_finalize;
trans_class->start = gst_vaapiupload_start;
@ -228,6 +231,8 @@ gst_vaapiupload_init(GstVaapiUpload *upload)
{
GstPad *sinkpad, *srcpad;
gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(upload), GST_CAT_DEFAULT);
/* Override buffer allocator on sink pad */
sinkpad = gst_element_get_static_pad(GST_ELEMENT(upload), "sink");
gst_pad_set_bufferalloc_function(
@ -247,7 +252,7 @@ static inline gboolean
gst_vaapiupload_ensure_display(GstVaapiUpload *upload)
{
return gst_vaapi_ensure_display(upload, GST_VAAPI_DISPLAY_TYPE_ANY,
&upload->display);
&GST_VAAPI_PLUGIN_BASE_DISPLAY(upload));
}
static gboolean
@ -257,11 +262,13 @@ gst_vaapiupload_ensure_uploader(GstVaapiUpload *upload)
return FALSE;
if (!upload->uploader) {
upload->uploader = gst_vaapi_uploader_new(upload->display);
upload->uploader = gst_vaapi_uploader_new(
GST_VAAPI_PLUGIN_BASE_DISPLAY(upload));
if (!upload->uploader)
return FALSE;
}
if (!gst_vaapi_uploader_ensure_display(upload->uploader, upload->display))
if (!gst_vaapi_uploader_ensure_display(upload->uploader,
GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)))
return FALSE;
return TRUE;
}
@ -271,6 +278,8 @@ gst_vaapiupload_start(GstBaseTransform *trans)
{
GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(trans)))
return FALSE;
if (!gst_vaapiupload_ensure_uploader(upload))
return FALSE;
return TRUE;
@ -279,9 +288,7 @@ gst_vaapiupload_start(GstBaseTransform *trans)
static gboolean
gst_vaapiupload_stop(GstBaseTransform *trans)
{
GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
gst_vaapi_display_replace(&upload->display, NULL);
gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(trans));
return TRUE;
}
@ -396,7 +403,8 @@ gst_vaapiupload_buffer_alloc(
*pbuf = NULL;
if (!gst_vaapi_uploader_ensure_display(upload->uploader, upload->display))
if (!gst_vaapi_uploader_ensure_display(upload->uploader,
GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)))
return GST_FLOW_NOT_SUPPORTED;
if (!gst_vaapi_uploader_ensure_caps(upload->uploader, caps, NULL))
return GST_FLOW_NOT_SUPPORTED;
@ -465,9 +473,9 @@ gst_vaapiupload_query(GstPad *pad, GstQuery *query)
GstVaapiUpload *upload = GST_VAAPIUPLOAD (gst_pad_get_parent_element (pad));
gboolean res;
GST_DEBUG ("sharing display %p", upload->display);
GST_DEBUG ("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(upload));
if (gst_vaapi_reply_to_query (query, upload->display))
if (gst_vaapi_reply_to_query (query, GST_VAAPI_PLUGIN_BASE_DISPLAY(upload)))
res = TRUE;
else
res = gst_pad_query_default (pad, query);

View file

@ -25,7 +25,7 @@
#ifndef GST_VAAPIUPLOAD_H
#define GST_VAAPIUPLOAD_H
#include <gst/base/gstbasetransform.h>
#include "gstvaapipluginbase.h"
#include "gstvaapiuploader.h"
G_BEGIN_DECLS
@ -59,15 +59,14 @@ typedef struct _GstVaapiUploadClass GstVaapiUploadClass;
struct _GstVaapiUpload {
/*< private >*/
GstBaseTransform parent_instance;
GstVaapiPluginBase parent_instance;
GstVaapiDisplay *display;
GstVaapiUploader *uploader;
};
struct _GstVaapiUploadClass {
/*< private >*/
GstBaseTransformClass parent_class;
GstVaapiPluginBaseClass parent_class;
};
GType