plugins: add new base object, store display in there.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Fri, 13 Dec 2013 09:24:26 +0000 (10:24 +0100)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Wed, 18 Dec 2013 15:38:57 +0000 (16:38 +0100)
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.

15 files changed:
gst/vaapi/Makefile.am
gst/vaapi/gstvaapidecode.c
gst/vaapi/gstvaapidecode.h
gst/vaapi/gstvaapidownload.c
gst/vaapi/gstvaapidownload.h
gst/vaapi/gstvaapiencode.c
gst/vaapi/gstvaapiencode.h
gst/vaapi/gstvaapipluginbase.c [new file with mode: 0644]
gst/vaapi/gstvaapipluginbase.h [new file with mode: 0644]
gst/vaapi/gstvaapipostproc.c
gst/vaapi/gstvaapipostproc.h
gst/vaapi/gstvaapisink.c
gst/vaapi/gstvaapisink.h
gst/vaapi/gstvaapiupload.c
gst/vaapi/gstvaapiupload.h

index 9e57d0d..9bef588 100644 (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          \
index 763eace..102f0d4 100644 (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;
index e28266b..ed1e9bf 100644 (file)
 #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
index 8e5e0ce..c596625 100644 (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);
index 28a9398..bb29fca 100644 (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>
index bcb3f1d..4227377 100644 (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;
index 09a97c7..1bf0dbc 100644 (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);
diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c
new file mode 100644 (file)
index 0000000..b2d7d80
--- /dev/null
@@ -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);
+}
diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h
new file mode 100644 (file)
index 0000000..2e3c27d
--- /dev/null
@@ -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 */
index 292405f..97eea32 100755 (executable)
@@ -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;
index e15472e..55dabae 100755 (executable)
@@ -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
index 74f584b..bb2f68a 100644 (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;
index fe2bf14..491f1b4 100644 (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
index df63cff..ce84d20 100644 (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);
index 41c1a2f..6a2c077 100644 (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