Allow build against either GStreamer API (0.10 or 1.0).

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.
This commit is contained in:
Gwenole Beauchesne 2013-03-20 14:40:57 +01:00
parent 551ac4c5b3
commit 1b500dee54
11 changed files with 249 additions and 17 deletions

View 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])

View 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 */

View 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 */

View 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,

View 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)

View 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,

View file

@ -35,8 +35,10 @@
#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;
}

View file

@ -70,8 +70,10 @@
#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)
{

View 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;

View 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);

View 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, }
};