Allow build against either GStreamer API (0.10 or 1.0).
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Wed, 20 Mar 2013 13:40:57 +0000 (14:40 +0100)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Wed, 10 Apr 2013 12:58:17 +0000 (14:58 +0200)
Introduce a new configure option --with-gstreamer-api that determines
the desired GStreamer API to use. By default, GStreamer 1.0 is selected.
Also integrate more compatibility glue into gstcompat.h and plugins.

configure.ac
gst-libs/gst/vaapi/gstcompat.h
gst-libs/gst/vaapi/gstvaapiimageformat.c
gst-libs/gst/vaapi/gstvaapiprofile.c
gst/vaapi/Makefile.am
gst/vaapi/gstvaapi.c
gst/vaapi/gstvaapidecode.c
gst/vaapi/gstvaapisink.c
gst/vaapi/gstvaapisink.h
gst/vaapi/gstvaapiuploader.c
tests/codec.c

index ec7c5d1..649497e 100644 (file)
@@ -46,7 +46,7 @@ m4_define([libva_wld_package_version], [1.1.0])
 # XXX: introspection annotations require gtk-doc >= 1.12
 m4_define([gtkdoc_version], [1.9])
 
-AC_PREREQ([2.58])
+AC_PREREQ([2.66])
 AC_INIT([gst_vaapi], [gst_vaapi_version],
     [gwenole.beauchesne@intel.com],
     [gstreamer-vaapi])
@@ -110,6 +110,12 @@ AC_ARG_ENABLE(wayland,
                    [enable Wayland output @<:@default=yes@:>@]),
     [], [enable_wayland="yes"])
 
+AC_ARG_WITH([gstreamer-api],
+    AC_HELP_STRING([--with-gstreamer-api=VERSION],
+                   [build against the specified GStreamer API version
+                    @<:@default=gst_api_version@:>@]),
+    [GST_API_VERSION="$with_gstreamer_api"], [GST_API_VERSION=gst_api_version])
+
 dnl Check for basic libraries
 AC_CHECK_LIB(m, tan)
 
@@ -131,7 +137,6 @@ dnl -- GStreamer                                                             --
 dnl ---------------------------------------------------------------------------
 
 dnl Versions for GStreamer and plugins-base
-GST_API_VERSION=gst_api_version
 case $GST_API_VERSION in
 0.10)
     GST_VERSION_REQUIRED=gst0_version
@@ -152,6 +157,15 @@ AC_SUBST(GST_VERSION_REQUIRED)
 AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED)
 AC_SUBST(GST_PLUGINS_BAD_VERSION_REQUIRED)
 
+USE_GST_API_0_10="no"
+USE_GST_API_1_0p="no"
+AS_VERSION_COMPARE([$GST_API_VERSION], [0.10],
+    [], [USE_GST_API_0_10="yes"], [])
+AS_VERSION_COMPARE([$GST_API_VERSION], [1.0],
+    [], [USE_GST_API_1_0p="yes"], [USE_GST_API_1_0p="yes"])
+AM_CONDITIONAL([USE_GST_API_0_10], [test "$USE_GST_API_0_10" = "yes"])
+AM_CONDITIONAL([USE_GST_API_1_0p], [test "$USE_GST_API_1_0p" = "yes"])
+
 dnl GStreamer Core
 PKG_CHECK_MODULES([GST],
     [gstreamer-$GST_API_VERSION >= $GST_VERSION_REQUIRED])
index 9d4d82a..aedd93b 100644 (file)
@@ -58,12 +58,153 @@ gst_compat_structure_get_fourcc(const GstStructure *structure,
 typedef const guint8 *(*GstCompatTypeFindPeekFunction)(gpointer, gint64, guint);
 typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, GstCaps *);
 
+/* GstQuery */
+#define GST_PAD_QUERY_FUNCTION_ARGS \
+    GstPad *pad, GstObject *parent, GstQuery *query
+#define GST_PAD_QUERY_FUNCTION_CALL(func, pad, parent, query) \
+    (func)(pad, parent, query)
+
+/* GstPlugin */
+#define GST_PLUGIN_DESC_NAME(NAME) NAME
+
+/* Misc helpers */
+#define GST_MAKE_FORMAT_STRING(FORMAT) \
+    "format=(string)" G_STRINGIFY(FORMAT)
+
 /* ------------------------------------------------------------------------ */
 /* --- GStreamer = 0.10                                                 --- */
 /* ------------------------------------------------------------------------ */
 
 #else
 
+/* GstMemory */
+typedef enum {
+    GST_MEMORY_FLAG_READONLY = GST_MINI_OBJECT_FLAG_READONLY
+} GstMemoryFlags;
+
+typedef enum {
+    GST_MAP_READ        = 1 << 0,
+    GST_MAP_WRITE       = 1 << 1
+} GstMapFlags;
+
+typedef struct {
+    GstMapFlags         flags;
+    guint8             *data;
+    gsize               size;
+} GstMapInfo;
+
+/* GstBuffer */
+#undef  gst_buffer_new_wrapped
+#define gst_buffer_new_wrapped(data, size) \
+    gst_compat_buffer_new_wrapped_full(0, data, size, 0, size, data, g_free)
+#undef  gst_buffer_new_wrapped_full
+#define gst_buffer_new_wrapped_full(flags, data, maxsize, ofs, size, ud, udd) \
+    gst_compat_buffer_new_wrapped_full(flags, data, maxsize, ofs, size, ud, udd)
+#undef  gst_buffer_get_size
+#define gst_buffer_get_size(buffer)     gst_compat_buffer_get_size(buffer)
+#undef  gst_buffer_map
+#define gst_buffer_map(buffer, mip, f)  gst_compat_buffer_map(buffer, mip, f)
+#undef  gst_buffer_unmap
+#define gst_buffer_unmap(buffer, mip)   gst_compat_buffer_unmap(buffer, mip)
+#undef  gst_buffer_extract
+#define gst_buffer_extract(buffer, offset, dest, size) \
+    gst_compat_buffer_extract(buffer, offset, dest, size)
+
+static inline GstBuffer *
+gst_compat_buffer_new_wrapped_full(GstMemoryFlags flags, gpointer data,
+    gsize maxsize, gsize offset, gsize size, gpointer user_data,
+    GDestroyNotify notify)
+{
+    GstBuffer *buffer;
+
+    /* XXX: unsupported */
+    g_return_val_if_fail(user_data == NULL, NULL);
+    g_return_val_if_fail(notify == NULL, NULL);
+    g_return_val_if_fail(maxsize >= size, NULL);
+
+    buffer = gst_buffer_new();
+    if (!buffer)
+        return NULL;
+
+    GST_BUFFER_DATA(buffer) = data + offset;
+    GST_BUFFER_SIZE(buffer) = size;
+    return buffer;
+}
+
+static inline gsize
+gst_compat_buffer_get_size(GstBuffer *buffer)
+{
+    return GST_BUFFER_SIZE(buffer);
+}
+
+static inline gboolean
+gst_compat_buffer_map(GstBuffer *buffer, GstMapInfo *mip, GstMapFlags flags)
+{
+    mip->flags = flags;
+    mip->data  = GST_BUFFER_DATA(buffer);
+    mip->size  = GST_BUFFER_SIZE(buffer);
+    return TRUE;
+}
+
+static inline void
+gst_compat_buffer_unmap(GstBuffer *buffer, GstMapInfo *mip)
+{
+}
+
+static inline gsize
+gst_compat_buffer_extract(GstBuffer *buffer, gsize offset, gpointer dest,
+    gsize size)
+{
+    gsize esize;
+
+    if (!buffer || !dest || offset >= GST_BUFFER_SIZE(buffer))
+        return 0;
+
+    esize = MIN(size, GST_BUFFER_SIZE(buffer) - offset);
+    memcpy(dest, GST_BUFFER_DATA(buffer) + offset, esize);
+    return esize;
+}
+
+/* GstAdapter */
+#include <gst/base/gstadapter.h>
+
+#undef  gst_adapter_map
+#define gst_adapter_map(adapter, size)  gst_compat_adapter_map(adapter, size)
+#undef  gst_adapter_unmap
+#define gst_adapter_unmap(adapter)      gst_compat_adapter_unmap(adapter)
+
+static inline gconstpointer
+gst_compat_adapter_map(GstAdapter *adapter, gsize size)
+{
+    return gst_adapter_peek(adapter, size);
+}
+
+static inline void
+gst_compat_adapter_unmap(GstAdapter *adapter)
+{
+}
+
+/* GstCaps */
+#undef  gst_caps_merge
+#define gst_caps_merge(caps1, caps2)    gst_compat_caps_merge(caps1, caps2)
+#undef  gst_caps_merge_structure
+#define gst_caps_merge_structure(caps, structure) \
+    gst_compat_caps_merge_structure(caps, structure)
+
+static inline GstCaps *
+gst_compat_caps_merge(GstCaps *caps1, GstCaps *caps2)
+{
+    (gst_caps_merge)(caps1, caps2);
+    return caps1;
+}
+
+static inline GstCaps *
+gst_compat_caps_merge_structure(GstCaps *caps, GstStructure *structure)
+{
+    (gst_caps_merge_structure)(caps, structure);
+    return caps;
+}
+
 /* GstVideoOverlayComposition */
 #include <gst/video/video-overlay-composition.h>
 
@@ -90,6 +231,10 @@ gst_compat_video_overlay_rectangle_get_pixels_unscaled_raw(
         &width, &height, &stride, flags);
 }
 
+/* GstPad */
+#undef  GST_FLOW_EOS
+#define GST_FLOW_EOS GST_FLOW_UNEXPECTED
+
 /* GstElement */
 #undef  gst_element_class_set_static_metadata
 #define gst_element_class_set_static_metadata(klass, name, path, desc, author) \
@@ -111,6 +256,19 @@ gst_compat_element_class_set_static_metadata(GstElementClass *klass,
 typedef guint8 *(*GstCompatTypeFindPeekFunction)(gpointer, gint64, guint);
 typedef void (*GstCompatTypeFindSuggestFunction)(gpointer, guint, const GstCaps *);
 
+/* GstQuery */
+#define GST_PAD_QUERY_FUNCTION_ARGS \
+    GstPad *pad, GstQuery *query
+#define GST_PAD_QUERY_FUNCTION_CALL(func, pad, parent, query) \
+    (func)(pad, query)
+
+/* GstPlugin */
+#define GST_PLUGIN_DESC_NAME(NAME) G_STRINGIFY(NAME)
+
+/* Misc helpers */
+#define GST_MAKE_FORMAT_STRING(FORMAT) \
+    "format=(fourcc)" G_STRINGIFY(FORMAT)
+
 #endif
 
 #endif /* GST_COMPAT_H */
index 1bbd6f3..54c94aa 100644 (file)
@@ -45,15 +45,27 @@ struct _GstVaapiImageFormatMap {
     VAImageFormat               va_format;
 };
 
+#if GST_CHECK_VERSION(1,0,0)
+# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \
+    GST_VIDEO_CAPS_MAKE(#FORMAT)
+# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \
+    GST_VIDEO_CAPS_MAKE(#FORMAT)
+#else
+# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \
+    GST_VIDEO_CAPS_YUV(#FORMAT)
+# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \
+    GST_VIDEO_CAPS_##FORMAT
+#endif
+
 #define DEF(TYPE, FORMAT, CAPS_STR)                                     \
     GST_VAAPI_IMAGE_FORMAT_TYPE_##TYPE,                                 \
     GST_VAAPI_IMAGE_##FORMAT,                                           \
     CAPS_STR
 #define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP)                            \
-    { DEF(YCBCR, FORMAT, GST_VIDEO_CAPS_MAKE(#FORMAT)),                 \
+    { DEF(YCBCR, FORMAT, GST_VIDEO_CAPS_MAKE_YUV(FORMAT)),              \
         { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, }
 #define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A)            \
-    { DEF(RGB, FORMAT, GST_VIDEO_CAPS_MAKE(#FORMAT)),                   \
+    { DEF(RGB, FORMAT, GST_VIDEO_CAPS_MAKE_RGB(FORMAT)),                \
         { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, }
 
 /* Image formats, listed in HW order preference */
index 6208919..1c5c515 100644 (file)
@@ -91,7 +91,7 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = {
       "video/x-wmv, wmvversion=3", "main"
     },
     { GST_VAAPI_PROFILE_VC1_ADVANCED, VAProfileVC1Advanced,
-      "video/x-wmv, wmvversion=3, format=(string)WVC1", "advanced"
+      "video/x-wmv, wmvversion=3, " GST_MAKE_FORMAT_STRING(WVC1), "advanced"
     },
 #if VA_CHECK_VERSION(0,32,0)
     { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline,
index dd730bb..3f104e4 100644 (file)
@@ -53,6 +53,7 @@ libgstvaapi_source_c          += gstvaapivideoconverter_glx.c
 libgstvaapi_source_h           += gstvaapivideoconverter_glx.h
 endif
 
+if USE_GST_API_1_0p
 libgstvaapi_source_c += \
        gstvaapivideobufferpool.c \
        gstvaapivideomemory.c   \
@@ -62,6 +63,21 @@ libgstvaapi_source_h += \
        gstvaapivideobufferpool.h \
        gstvaapivideomemory.h   \
        $(NULL)
+endif
+
+if USE_GST_API_0_10
+libgstvaapi_source_c += \
+       gstvaapidownload.c      \
+       gstvaapipostproc.c      \
+       gstvaapiupload.c        \
+       $(NULL)
+
+libgstvaapi_source_h += \
+       gstvaapidownload.h      \
+       gstvaapipostproc.h      \
+       gstvaapiupload.h        \
+       $(NULL)
+endif
 
 libgstvaapi_la_SOURCES         = $(libgstvaapi_source_c)
 noinst_HEADERS                 = $(libgstvaapi_source_h)
index 909be71..407989d 100644 (file)
@@ -56,7 +56,7 @@ plugin_init (GstPlugin *plugin)
 
 GST_PLUGIN_DEFINE(
     GST_VERSION_MAJOR, GST_VERSION_MINOR,
-    vaapi,
+    GST_PLUGIN_DESC_NAME(vaapi),
     "VA-API based elements",
     plugin_init,
     PACKAGE_VERSION,
index dd3327b..fe99ee5 100644 (file)
 #include "gstvaapidecode.h"
 #include "gstvaapipluginutil.h"
 #include "gstvaapivideobuffer.h"
+#if GST_CHECK_VERSION(1,0,0)
 #include "gstvaapivideobufferpool.h"
 #include "gstvaapivideomemory.h"
+#endif
 
 #include <gst/vaapi/gstvaapidecoder_h264.h>
 #include <gst/vaapi/gstvaapidecoder_jpeg.h>
@@ -327,6 +329,7 @@ error_create_buffer:
         gst_video_codec_frame_unref(out_frame);
         return GST_FLOW_EOS;
     }
+#if GST_CHECK_VERSION(1,0,0)
 error_get_meta:
     {
         GST_ERROR("failed to get vaapi video meta attached to video buffer");
@@ -334,6 +337,7 @@ error_get_meta:
         gst_video_codec_frame_unref(out_frame);
         return GST_FLOW_EOS;
     }
+#endif
 error_commit_buffer:
     {
         GST_DEBUG("video sink rejected the video buffer (error %d)", ret);
@@ -372,6 +376,7 @@ error_flush:
     }
 }
 
+#if GST_CHECK_VERSION(1,0,0)
 static gboolean
 gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query)
 {
@@ -443,6 +448,7 @@ error_create_pool:
         return FALSE;
     }
 }
+#endif
 
 static inline gboolean
 gst_vaapidecode_ensure_display(GstVaapiDecode *decode)
@@ -665,8 +671,10 @@ gst_vaapidecode_class_init(GstVaapiDecodeClass *klass)
     vdec_class->handle_frame = GST_DEBUG_FUNCPTR(gst_vaapidecode_handle_frame);
     vdec_class->finish       = GST_DEBUG_FUNCPTR(gst_vaapidecode_finish);
 
+#if GST_CHECK_VERSION(1,0,0)
     vdec_class->decide_allocation =
         GST_DEBUG_FUNCPTR(gst_vaapidecode_decide_allocation);
+#endif
 
     gst_element_class_set_static_metadata(element_class,
         "VA-API decoder",
@@ -757,20 +765,24 @@ gst_vaapidecode_get_caps(GstPad *pad)
 }
 
 static gboolean
-gst_vaapidecode_query (GstPad *pad, GstObject *parent, GstQuery *query) {
-    GstVaapiDecode *decode = GST_VAAPIDECODE (gst_pad_get_parent_element (pad));
+gst_vaapidecode_query(GST_PAD_QUERY_FUNCTION_ARGS)
+{
+    GstVaapiDecode * const decode =
+        GST_VAAPIDECODE(gst_pad_get_parent_element(pad));
     gboolean res;
 
-    GST_DEBUG ("sharing display %p", decode->display);
+    GST_DEBUG("sharing display %p", decode->display);
 
-    if (gst_vaapi_reply_to_query (query, decode->display))
-      res = TRUE;
+    if (gst_vaapi_reply_to_query(query, decode->display))
+        res = TRUE;
     else if (GST_PAD_IS_SINK(pad))
-        res = decode->sinkpad_query(decode->sinkpad, parent, query);
+        res = GST_PAD_QUERY_FUNCTION_CALL(decode->sinkpad_query,
+            decode->sinkpad, parent, query);
     else
-      res = decode->srcpad_query(decode->srcpad, parent, query);
+        res = GST_PAD_QUERY_FUNCTION_CALL(decode->srcpad_query,
+            decode->srcpad, parent, query);
 
-    g_object_unref (decode);
+    g_object_unref(decode);
     return res;
 }
 
index 7393aab..6c0cf90 100644 (file)
 #include "gstvaapisink.h"
 #include "gstvaapipluginutil.h"
 #include "gstvaapivideometa.h"
+#if GST_CHECK_VERSION(1,0,0)
 #include "gstvaapivideobufferpool.h"
 #include "gstvaapivideomemory.h"
+#endif
 
 #define GST_PLUGIN_NAME "vaapisink"
 #define GST_PLUGIN_DESC "A VA-API based videosink"
@@ -593,6 +595,7 @@ end:
 static gboolean
 gst_vaapisink_ensure_video_buffer_pool(GstVaapiSink *sink, GstCaps *caps)
 {
+#if GST_CHECK_VERSION(1,0,0)
     GstBufferPool *pool;
     GstCaps *pool_caps;
     GstStructure *config;
@@ -648,6 +651,9 @@ error_pool_config:
         g_object_unref(pool);
         return FALSE;
     }
+#else
+    return TRUE;
+#endif
 }
 
 static gboolean
@@ -670,7 +676,9 @@ gst_vaapisink_stop(GstBaseSink *base_sink)
     GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
 
     gst_buffer_replace(&sink->video_buffer, NULL);
+#if GST_CHECK_VERSION(1,0,0)
     g_clear_object(&sink->video_buffer_pool);
+#endif
     g_clear_object(&sink->window);
     g_clear_object(&sink->display);
     g_clear_object(&sink->uploader);
@@ -679,7 +687,7 @@ gst_vaapisink_stop(GstBaseSink *base_sink)
 }
 
 static GstCaps *
-gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter)
+gst_vaapisink_get_caps_impl(GstBaseSink *base_sink)
 {
     GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
     GstCaps *out_caps, *yuv_caps;
@@ -696,6 +704,16 @@ gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter)
     return out_caps;
 }
 
+#if GST_CHECK_VERSION(1,0,0)
+static inline GstCaps *
+gst_vaapisink_get_caps(GstBaseSink *base_sink, GstCaps *filter)
+{
+    return gst_vaapisink_get_caps_impl(base_sink);
+}
+#else
+#define gst_vaapisink_get_caps gst_vaapisink_get_caps_impl
+#endif
+
 static gboolean
 gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)
 {
index c68efd6..58abb46 100644 (file)
@@ -76,7 +76,9 @@ struct _GstVaapiSink {
     guint               window_width;
     guint               window_height;
     GstVaapiTexture    *texture;
+#if GST_CHECK_VERSION(1,0,0)
     GstBufferPool      *video_buffer_pool;
+#endif
     guint               video_buffer_size;
     GstBuffer          *video_buffer;
     guint               video_width;
index ac7afd7..f2c341f 100644 (file)
@@ -449,7 +449,7 @@ gst_vaapi_uploader_get_buffer(GstVaapiUploader *uploader)
         goto error;
     }
 
-#if 0
+#if !GST_CHECK_VERSION(1,0,0)
     GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0);
     GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image);
 
index a1dd081..ff9b125 100644 (file)
@@ -41,7 +41,7 @@ static const CodecMap g_codec_map[] = {
     { "wmv3",   GST_VAAPI_CODEC_VC1,
       "video/x-wmv, wmvversion=3" },
     { "vc1",    GST_VAAPI_CODEC_VC1,
-      "video/x-wmv, wmvversion=3, format=(string)WVC1" },
+      "video/x-wmv, wmvversion=3, " GST_MAKE_FORMAT_STRING(WVC1) },
     { NULL, }
 };