summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/msdk/Makefile.am6
-rw-r--r--sys/msdk/gstmsdkbufferpool.c274
-rw-r--r--sys/msdk/gstmsdkbufferpool.h95
-rw-r--r--sys/msdk/gstmsdksystemmemory.c255
-rw-r--r--sys/msdk/gstmsdksystemmemory.h119
-rw-r--r--sys/msdk/gstmsdkvideomemory.c296
-rw-r--r--sys/msdk/gstmsdkvideomemory.h130
-rw-r--r--sys/msdk/meson.build3
8 files changed, 1178 insertions, 0 deletions
diff --git a/sys/msdk/Makefile.am b/sys/msdk/Makefile.am
index d968c7602..f0b22b2a2 100644
--- a/sys/msdk/Makefile.am
+++ b/sys/msdk/Makefile.am
@@ -2,6 +2,9 @@ plugin_LTLIBRARIES = libgstmsdk.la
libgstmsdk_la_SOURCES = \
gstmsdkcontext.c \
+ gstmsdksystemmemory.c \
+ gstmsdkvideomemory.c \
+ gstmsdkbufferpool.c \
gstmsdkh264dec.c \
gstmsdkh264enc.c \
gstmsdkh265dec.c \
@@ -22,6 +25,9 @@ nodist_EXTRA_libgstmsdk_la_SOURCES = not_present.cxx
noinst_HEADERS = \
msdk.h \
gstmsdkcontext.h \
+ gstmsdksystemmemory.h \
+ gstmsdkvideomemory.h \
+ gstmsdkbufferpool.h \
gstmsdkh264dec.h \
gstmsdkh264enc.h \
gstmsdkh265dec.h \
diff --git a/sys/msdk/gstmsdkbufferpool.c b/sys/msdk/gstmsdkbufferpool.c
new file mode 100644
index 000000000..51d36c0f5
--- /dev/null
+++ b/sys/msdk/gstmsdkbufferpool.c
@@ -0,0 +1,274 @@
+/* GStreamer Intel MSDK plugin
+ * Copyright (c) 2018, Intel Corporation
+ * Copyright (c) 2018, Igalia S.L.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGDECE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gstmsdkbufferpool.h"
+#include "gstmsdksystemmemory.h"
+#include "gstmsdkvideomemory.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_debug_msdkbufferpool);
+#define GST_CAT_DEFAULT gst_debug_msdkbufferpool
+
+#define GST_MSDK_BUFFER_POOL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_MSDK_BUFFER_POOL, \
+ GstMsdkBufferPoolPrivate))
+
+#define gst_msdk_buffer_pool_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstMsdkBufferPool, gst_msdk_buffer_pool,
+ GST_TYPE_VIDEO_BUFFER_POOL,
+ GST_DEBUG_CATEGORY_INIT (gst_debug_msdkbufferpool, "msdkbufferpool", 0,
+ "MSDK Buffer Pool"));
+
+struct _GstMsdkBufferPoolPrivate
+{
+ GstMsdkContext *context;
+ GstAllocator *allocator;
+ mfxFrameAllocResponse *alloc_response;
+ gboolean use_video_memory;
+ gboolean add_videometa;
+};
+
+static const gchar **
+gst_msdk_buffer_pool_get_options (GstBufferPool * pool)
+{
+ static const gchar *options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META,
+ GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT,
+ GST_BUFFER_POOL_OPTION_MSDK_USE_VIDEO_MEMORY,
+ NULL
+ };
+
+ return options;
+}
+
+static gboolean
+gst_msdk_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
+{
+ GstMsdkBufferPool *msdk_pool = GST_MSDK_BUFFER_POOL_CAST (pool);
+ GstMsdkBufferPoolPrivate *priv = msdk_pool->priv;
+ GstCaps *caps = NULL;
+ GstAllocator *allocator = NULL;
+ GstVideoInfo video_info;
+ guint size, min_buffers, max_buffers;
+
+ if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers,
+ &max_buffers))
+ goto error_invalid_config;
+
+ if (!caps)
+ goto error_no_caps;
+
+ if (!gst_video_info_from_caps (&video_info, caps))
+ goto error_invalid_caps;
+
+ if (!gst_buffer_pool_config_get_allocator (config, &allocator, NULL))
+ goto error_invalid_allocator;
+
+ if (allocator
+ && (g_strcmp0 (allocator->mem_type, GST_MSDK_SYSTEM_MEMORY_NAME) != 0
+ && g_strcmp0 (allocator->mem_type,
+ GST_MSDK_VIDEO_MEMORY_NAME) != 0)) {
+ GST_INFO_OBJECT (pool,
+ "This is not MSDK allocator. So this will be ignored");
+ gst_object_unref (allocator);
+ allocator = NULL;
+ }
+
+ priv->add_videometa = gst_buffer_pool_config_has_option (config,
+ GST_BUFFER_POOL_OPTION_VIDEO_META);
+
+ if (priv->add_videometa && gst_buffer_pool_config_has_option (config,
+ GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) {
+ GstVideoAlignment alignment;
+
+ gst_msdk_set_video_alignment (&video_info, &alignment);
+ gst_video_info_align (&video_info, &alignment);
+ gst_buffer_pool_config_set_video_alignment (config, &alignment);
+ }
+
+ priv->use_video_memory = gst_buffer_pool_config_has_option (config,
+ GST_BUFFER_POOL_OPTION_MSDK_USE_VIDEO_MEMORY);
+
+ if (priv->use_video_memory && (!priv->context || !priv->alloc_response)) {
+ GST_ERROR_OBJECT (pool,
+ "No MSDK context or Allocation response for using video memory");
+ goto error_invalid_config;
+ }
+
+ /* create a new allocator if needed */
+ if (!allocator) {
+ GstAllocationParams params = { 0, 31, 0, 0, };
+
+ if (priv->use_video_memory)
+ allocator =
+ gst_msdk_video_allocator_new (priv->context, &video_info,
+ priv->alloc_response);
+ else
+ allocator = gst_msdk_system_allocator_new (&video_info);
+
+ if (!allocator)
+ goto error_no_allocator;
+
+ GST_INFO_OBJECT (pool, "created new allocator %" GST_PTR_FORMAT, allocator);
+
+ gst_buffer_pool_config_set_allocator (config, allocator, &params);
+ gst_object_unref (allocator);
+ }
+
+ if (priv->allocator)
+ gst_object_unref (priv->allocator);
+ priv->allocator = gst_object_ref (allocator);
+
+ return GST_BUFFER_POOL_CLASS
+ (gst_msdk_buffer_pool_parent_class)->set_config (pool, config);
+
+error_invalid_config:
+ {
+ GST_ERROR_OBJECT (pool, "invalid config");
+ return FALSE;
+ }
+error_no_caps:
+ {
+ GST_ERROR_OBJECT (pool, "no caps in config");
+ return FALSE;
+ }
+error_invalid_caps:
+ {
+ GST_ERROR_OBJECT (pool, "invalid caps %" GST_PTR_FORMAT, caps);
+ return FALSE;
+ }
+error_invalid_allocator:
+ {
+ GST_ERROR_OBJECT (pool, "no allocator in config");
+ return FALSE;
+ }
+error_no_allocator:
+ {
+ GST_ERROR_OBJECT (pool, "no allocator defined");
+ return FALSE;
+ }
+}
+
+static GstFlowReturn
+gst_msdk_buffer_pool_alloc_buffer (GstBufferPool * pool,
+ GstBuffer ** out_buffer_ptr, GstBufferPoolAcquireParams * params)
+{
+ GstMsdkBufferPool *msdk_pool = GST_MSDK_BUFFER_POOL_CAST (pool);
+ GstMsdkBufferPoolPrivate *priv = msdk_pool->priv;
+ GstMemory *mem;
+ GstBuffer *buf;
+
+ buf = gst_buffer_new ();
+
+ if (priv->use_video_memory)
+ mem = gst_msdk_video_memory_new (priv->allocator);
+ else
+ mem = gst_msdk_system_memory_new (priv->allocator);
+
+ if (!mem)
+ goto no_memory;
+
+ gst_buffer_append_memory (buf, mem);
+
+ if (priv->add_videometa) {
+ GstVideoMeta *vmeta;
+ GstVideoInfo *info;
+
+ if (priv->use_video_memory)
+ info = &GST_MSDK_VIDEO_ALLOCATOR_CAST (priv->allocator)->image_info;
+ else
+ info = &GST_MSDK_SYSTEM_ALLOCATOR_CAST (priv->allocator)->image_info;
+
+ vmeta = gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
+ GST_VIDEO_INFO_FORMAT (info),
+ GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info),
+ GST_VIDEO_INFO_N_PLANES (info), info->offset, info->stride);
+
+ if (priv->use_video_memory) {
+ vmeta->map = gst_video_meta_map_msdk_memory;
+ vmeta->unmap = gst_video_meta_unmap_msdk_memory;
+ }
+ }
+
+ *out_buffer_ptr = buf;
+ return GST_FLOW_OK;
+
+no_memory:
+ {
+ GST_ERROR_OBJECT (pool, "failed to create new MSDK memory");
+ return GST_FLOW_ERROR;
+ }
+}
+
+static void
+gst_msdk_buffer_pool_finalize (GObject * object)
+{
+ GstMsdkBufferPool *pool = GST_MSDK_BUFFER_POOL_CAST (object);
+ GstMsdkBufferPoolPrivate *priv = pool->priv;
+
+ if (priv->allocator)
+ gst_object_unref (priv->allocator);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_msdk_buffer_pool_init (GstMsdkBufferPool * pool)
+{
+ pool->priv = GST_MSDK_BUFFER_POOL_GET_PRIVATE (pool);
+}
+
+static void
+gst_msdk_buffer_pool_class_init (GstMsdkBufferPoolClass * klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GstBufferPoolClass *pool_class = GST_BUFFER_POOL_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GstMsdkBufferPoolPrivate));
+
+ object_class->finalize = gst_msdk_buffer_pool_finalize;
+
+ pool_class->get_options = gst_msdk_buffer_pool_get_options;
+ pool_class->set_config = gst_msdk_buffer_pool_set_config;
+ pool_class->alloc_buffer = gst_msdk_buffer_pool_alloc_buffer;
+}
+
+GstBufferPool *
+gst_msdk_buffer_pool_new (GstMsdkContext * context,
+ mfxFrameAllocResponse * alloc_resp)
+{
+ GstMsdkBufferPool *pool = g_object_new (GST_TYPE_MSDK_BUFFER_POOL, NULL);
+
+ /* Doesn't need to count reference of the context */
+ pool->priv->context = context;
+ pool->priv->alloc_response = alloc_resp;
+
+ return GST_BUFFER_POOL_CAST (pool);
+}
diff --git a/sys/msdk/gstmsdkbufferpool.h b/sys/msdk/gstmsdkbufferpool.h
new file mode 100644
index 000000000..c0813dddf
--- /dev/null
+++ b/sys/msdk/gstmsdkbufferpool.h
@@ -0,0 +1,95 @@
+/* GStreamer Intel MSDK plugin
+ * Copyright (c) 2018, Intel Corporation
+ * Copyright (c) 2018, Igalia S.L.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGDECE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GST_MSDK_BUFFER_POOL_H
+#define GST_MSDK_BUFFER_POOL_H
+
+#include "msdk.h"
+#include "gstmsdkcontext.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_MSDK_BUFFER_POOL \
+ (gst_msdk_buffer_pool_get_type ())
+#define GST_MSDK_BUFFER_POOL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MSDK_BUFFER_POOL, \
+ GstMsdkBufferPool))
+#define GST_MSDK_BUFFER_POOL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MSDK_BUFFER_POOL, \
+ GstMsdkBufferPoolClass))
+#define GST_IS_MSDK_BUFFER_POOL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MSDK_BUFFER_POOL))
+#define GST_IS_MSDK_BUFFER_POOL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MSDK_BUFFER_POOL))
+#define GST_MSDK_BUFFER_POOL_CAST(obj) ((GstMsdkBufferPool*)(obj))
+
+typedef struct _GstMsdkBufferPool GstMsdkBufferPool;
+typedef struct _GstMsdkBufferPoolClass GstMsdkBufferPoolClass;
+typedef struct _GstMsdkBufferPoolPrivate GstMsdkBufferPoolPrivate;
+
+/*
+ * GST_BUFFER_POOL_OPTION_MSDK_USE_VIDEO_MEMORY:
+ *
+ * An option that presents if the bufferpool will use
+ * MsdkSystemAllocator or MsdkVideoAllocator.
+ */
+#define GST_BUFFER_POOL_OPTION_MSDK_USE_VIDEO_MEMORY "GstBufferPoolOptionMsdkUseVideoMemory"
+
+/**
+ * GstMsdkBufferPool:
+ *
+ * A MSDK buffer pool object.
+ */
+struct _GstMsdkBufferPool
+{
+ GstVideoBufferPool parent_instance;
+ GstMsdkBufferPoolPrivate *priv;
+};
+
+/**
+ * GstMsdkBufferPoolClass:
+ *
+ * A MSDK buffer pool class.
+ */
+struct _GstMsdkBufferPoolClass
+{
+ GstVideoBufferPoolClass parent_class;
+};
+
+GType gst_msdk_buffer_pool_get_type (void);
+
+GstBufferPool * gst_msdk_buffer_pool_new (GstMsdkContext * context,
+ mfxFrameAllocResponse * alloc_resp);
+
+G_END_DECLS
+
+#endif /* GST_MSDK_BUFFER_POOL_H */
diff --git a/sys/msdk/gstmsdksystemmemory.c b/sys/msdk/gstmsdksystemmemory.c
new file mode 100644
index 000000000..a7636c546
--- /dev/null
+++ b/sys/msdk/gstmsdksystemmemory.c
@@ -0,0 +1,255 @@
+/* GStreamer Intel MSDK plugin
+ * Copyright (c) 2018, Intel Corporation
+ * Copyright (c) 2018, Igalia S.L.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGDECE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include "gstmsdksystemmemory.h"
+
+#ifdef _WIN32
+#define posix_memalign(d, a, s) ((*((void**)d) = _aligned_malloc(s, a)) ? 0 : -1)
+#endif
+
+#ifndef _WIN32
+#define _aligned_free free
+#endif
+
+static gboolean
+ensure_data (GstMsdkSystemMemory * mem)
+{
+ gsize size;
+ void *data;
+ GstVideoInfo *info;
+ GstAllocator *allocator;
+ GstMsdkSystemAllocator *msdk_allocator;
+
+ allocator = GST_MEMORY_CAST (mem)->allocator;
+ msdk_allocator = GST_MSDK_SYSTEM_ALLOCATOR_CAST (allocator);
+
+ info = &msdk_allocator->image_info;
+ size = GST_VIDEO_INFO_SIZE (info);
+
+ if (mem->cache)
+ return TRUE;
+
+ if (posix_memalign (&data, 32, size) != 0) {
+ GST_ERROR ("Memory allocation failed");
+ return FALSE;
+ }
+
+ mem->cache = data;
+ mem->cached_data[0] = mem->cache;
+ mem->cached_data[1] = mem->cache + GST_VIDEO_INFO_PLANE_OFFSET (info, 1);
+ mem->cached_data[2] = mem->cache + GST_VIDEO_INFO_PLANE_OFFSET (info, 2);
+
+ mem->destination_pitches[0] = GST_VIDEO_INFO_PLANE_STRIDE (info, 0);
+ mem->destination_pitches[1] = GST_VIDEO_INFO_PLANE_STRIDE (info, 1);
+ mem->destination_pitches[2] = GST_VIDEO_INFO_PLANE_STRIDE (info, 2);
+
+ switch (GST_VIDEO_INFO_FORMAT (info)) {
+ case GST_VIDEO_FORMAT_NV12:
+ mem->surface->Data.Y = mem->cached_data[0];
+ mem->surface->Data.UV = mem->cached_data[1];
+ mem->surface->Data.Pitch = mem->destination_pitches[0];
+ break;
+ case GST_VIDEO_FORMAT_YV12:
+ mem->surface->Data.Y = mem->cached_data[0];
+ mem->surface->Data.U = mem->cached_data[2];
+ mem->surface->Data.V = mem->cached_data[1];
+ mem->surface->Data.Pitch = mem->destination_pitches[0];
+ break;
+ case GST_VIDEO_FORMAT_I420:
+ mem->surface->Data.Y = mem->cached_data[0];
+ mem->surface->Data.U = mem->cached_data[1];
+ mem->surface->Data.V = mem->cached_data[2];
+ mem->surface->Data.Pitch = mem->destination_pitches[0];
+ break;
+ case GST_VIDEO_FORMAT_YUY2:
+ mem->surface->Data.Y = mem->cached_data[0];
+ mem->surface->Data.U = mem->surface->Data.Y + 1;
+ mem->surface->Data.V = mem->surface->Data.Y + 3;
+ mem->surface->Data.Pitch = mem->destination_pitches[0];
+ break;
+ case GST_VIDEO_FORMAT_UYVY:
+ mem->surface->Data.Y = mem->cached_data[0];
+ mem->surface->Data.U = mem->surface->Data.Y;
+ mem->surface->Data.V = mem->surface->Data.U + 2;
+ mem->surface->Data.Pitch = mem->destination_pitches[0];
+ break;
+ case GST_VIDEO_FORMAT_BGRA:
+ mem->surface->Data.R = mem->cached_data[0];
+ mem->surface->Data.G = mem->surface->Data.R + 1;
+ mem->surface->Data.B = mem->surface->Data.R + 2;
+ mem->surface->Data.Pitch = mem->destination_pitches[0];
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ return TRUE;
+}
+
+static mfxFrameSurface1 *
+gst_msdk_system_allocator_create_surface (GstAllocator * allocator)
+{
+ mfxFrameInfo frame_info = { {0,}, 0, };
+ mfxFrameSurface1 *surface;
+ GstMsdkSystemAllocator *msdk_system_allocator =
+ GST_MSDK_SYSTEM_ALLOCATOR_CAST (allocator);
+
+ surface = (mfxFrameSurface1 *) g_slice_new0 (mfxFrameSurface1);
+
+ if (!surface) {
+ GST_ERROR ("failed to allocate surface");
+ return NULL;
+ }
+
+ gst_msdk_set_mfx_frame_info_from_video_info (&frame_info,
+ &msdk_system_allocator->image_info);
+
+ surface->Info = frame_info;
+
+ return surface;
+}
+
+GstMemory *
+gst_msdk_system_memory_new (GstAllocator * base_allocator)
+{
+ GstMsdkSystemAllocator *allocator;
+ GstVideoInfo *vip;
+ GstMsdkSystemMemory *mem;
+
+ g_return_val_if_fail (base_allocator, NULL);
+ g_return_val_if_fail (GST_IS_MSDK_SYSTEM_ALLOCATOR (base_allocator), NULL);
+
+ allocator = GST_MSDK_SYSTEM_ALLOCATOR_CAST (base_allocator);
+
+ mem = g_slice_new0 (GstMsdkSystemMemory);
+ if (!mem)
+ return NULL;
+
+ mem->surface = gst_msdk_system_allocator_create_surface (base_allocator);
+
+ vip = &allocator->image_info;
+ gst_memory_init (&mem->parent_instance, GST_MEMORY_FLAG_NO_SHARE,
+ base_allocator, NULL, GST_VIDEO_INFO_SIZE (vip), 0, 0,
+ GST_VIDEO_INFO_SIZE (vip));
+
+ if (!ensure_data (mem))
+ return FALSE;
+
+ return GST_MEMORY_CAST (mem);
+}
+
+static gpointer
+gst_msdk_system_memory_map_full (GstMemory * base_mem, GstMapInfo * info,
+ gsize maxsize)
+{
+ GstMsdkSystemMemory *const mem = GST_MSDK_SYSTEM_MEMORY_CAST (base_mem);
+
+ g_return_val_if_fail (mem, NULL);
+
+ if (!mem->surface) {
+ GST_WARNING ("The surface is not allocated");
+ return FALSE;
+ }
+
+ if ((info->flags & GST_MAP_WRITE) && mem->surface
+ && mem->surface->Data.Locked) {
+ GST_WARNING ("The surface in memory %p is not still avaliable", mem);
+ return FALSE;
+ }
+
+ return mem->surface->Data.Y;
+}
+
+static void
+gst_msdk_system_memory_unmap (GstMemory * base_mem)
+{
+}
+
+/* GstMsdkSystemAllocator */
+G_DEFINE_TYPE (GstMsdkSystemAllocator, gst_msdk_system_allocator,
+ GST_TYPE_ALLOCATOR);
+
+static void
+gst_msdk_system_allocator_free (GstAllocator * allocator, GstMemory * base_mem)
+{
+ GstMsdkSystemMemory *const mem = GST_MSDK_SYSTEM_MEMORY_CAST (base_mem);
+
+ _aligned_free (mem->cache);
+ g_slice_free (mfxFrameSurface1, mem->surface);
+}
+
+static GstMemory *
+gst_msdk_system_allocator_alloc (GstAllocator * allocator, gsize size,
+ GstAllocationParams * params)
+{
+ return gst_msdk_system_memory_new (allocator);
+}
+
+static void
+gst_msdk_system_allocator_class_init (GstMsdkSystemAllocatorClass * klass)
+{
+ GstAllocatorClass *const allocator_class = GST_ALLOCATOR_CLASS (klass);
+
+ allocator_class->alloc = gst_msdk_system_allocator_alloc;
+ allocator_class->free = gst_msdk_system_allocator_free;
+}
+
+static void
+gst_msdk_system_allocator_init (GstMsdkSystemAllocator * allocator)
+{
+ GstAllocator *const base_allocator = GST_ALLOCATOR_CAST (allocator);
+
+ base_allocator->mem_type = GST_MSDK_SYSTEM_MEMORY_NAME;
+ base_allocator->mem_map_full = gst_msdk_system_memory_map_full;
+ base_allocator->mem_unmap = gst_msdk_system_memory_unmap;
+
+ GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
+}
+
+GstAllocator *
+gst_msdk_system_allocator_new (GstVideoInfo * image_info)
+{
+ GstMsdkSystemAllocator *allocator;
+
+ g_return_val_if_fail (image_info != NULL, NULL);
+
+ allocator = g_object_new (GST_TYPE_MSDK_SYSTEM_ALLOCATOR, NULL);
+ if (!allocator)
+ return NULL;
+
+ allocator->image_info = *image_info;
+
+ return GST_ALLOCATOR_CAST (allocator);
+}
diff --git a/sys/msdk/gstmsdksystemmemory.h b/sys/msdk/gstmsdksystemmemory.h
new file mode 100644
index 000000000..d0bcbe37b
--- /dev/null
+++ b/sys/msdk/gstmsdksystemmemory.h
@@ -0,0 +1,119 @@
+/* GStreamer Intel MSDK plugin
+ * Copyright (c) 2018, Intel Corporation
+ * Copyright (c) 2018, Igalia S.L.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGDECE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GST_MSDK_SYSTEM_MEMORY_H
+#define GST_MSDK_SYSTEM_MEMORY_H
+
+#include "msdk.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GstMsdkSystemMemory GstMsdkSystemMemory;
+typedef struct _GstMsdkSystemAllocator GstMsdkSystemAllocator;
+typedef struct _GstMsdkSystemAllocatorClass GstMsdkSystemAllocatorClass;
+
+/* ---------------------------------------------------------------------*/
+/* GstMsdkSystemMemory */
+/* ---------------------------------------------------------------------*/
+
+#define GST_MSDK_SYSTEM_MEMORY_CAST(mem) \
+ ((GstMsdkSystemMemory *) (mem))
+
+#define GST_IS_MSDK_SYSTEM_MEMORY(mem) \
+ ((mem) && (mem)->allocator && GST_IS_MSDK_SYSTEM_ALLOCATOR((mem)->allocator))
+
+#define GST_MSDK_SYSTEM_MEMORY_NAME "GstMsdkSystemMemory"
+
+/**
+ * GstMsdkSystemMemory:
+ *
+ * A MSDK memory object holder, including mfxFrameSurface,
+ * video info of the surface.
+ */
+struct _GstMsdkSystemMemory
+{
+ GstMemory parent_instance;
+
+ mfxFrameSurface1 *surface;
+
+ guint8 *cache;
+ mfxU8 *cached_data[4];
+ guint destination_pitches[4];
+};
+
+GstMemory *
+gst_msdk_system_memory_new (GstAllocator * base_allocator);
+
+/* ---------------------------------------------------------------------*/
+/* GstMsdkSystemAllocator */
+/* ---------------------------------------------------------------------*/
+
+#define GST_MSDK_SYSTEM_ALLOCATOR_CAST(allocator) \
+ ((GstMsdkSystemAllocator *) (allocator))
+
+#define GST_TYPE_MSDK_SYSTEM_ALLOCATOR \
+ (gst_msdk_system_allocator_get_type ())
+#define GST_MSDK_SYSTEM_ALLOCATOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MSDK_SYSTEM_ALLOCATOR, \
+ GstMsdkSystemAllocator))
+#define GST_IS_MSDK_SYSTEM_ALLOCATOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MSDK_SYSTEM_ALLOCATOR))
+
+/**
+ * GstMsdkSystemAllocator:
+ *
+ * A MSDK memory allocator object.
+ */
+struct _GstMsdkSystemAllocator
+{
+ GstAllocator parent_instance;
+
+ GstVideoInfo image_info;
+};
+
+/**
+ * GstMsdkSystemAllocatorClass:
+ *
+ * A MSDK memory allocator class.
+ */
+struct _GstMsdkSystemAllocatorClass
+{
+ GstAllocatorClass parent_class;
+};
+
+GType gst_msdk_system_allocator_get_type (void);
+
+GstAllocator * gst_msdk_system_allocator_new (GstVideoInfo *image_info);
+
+G_END_DECLS
+
+#endif /* GST_MSDK_SYSTEM_MEMORY_H */
diff --git a/sys/msdk/gstmsdkvideomemory.c b/sys/msdk/gstmsdkvideomemory.c
new file mode 100644
index 000000000..6428b5963
--- /dev/null
+++ b/sys/msdk/gstmsdkvideomemory.c
@@ -0,0 +1,296 @@
+/* GStreamer Intel MSDK plugin
+ * Copyright (c) 2018, Intel Corporation
+ * Copyright (c) 2018, Igalia S.L.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGDECE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <va/va.h>
+#include "gstmsdkvideomemory.h"
+#include "gstmsdkallocator.h"
+
+static gboolean
+ensure_data (GstMsdkVideoMemory * mem, GstMsdkVideoAllocator * allocator)
+{
+ GstMsdkMemoryID *mem_id;
+ GstMsdkAllocResponse *resp =
+ gst_msdk_context_get_cached_alloc_responses (allocator->context,
+ allocator->alloc_response);
+
+ if (!resp) {
+ GST_WARNING ("failed to get allocation response");
+ return FALSE;
+ }
+
+ mem_id = (GstMsdkMemoryID *) resp->mem_ids[resp->num_used_memory++];
+ mem->surface->Data.MemId = mem_id;
+
+ return TRUE;
+}
+
+static mfxFrameSurface1 *
+gst_msdk_video_allocator_create_surface (GstAllocator * allocator)
+{
+ mfxFrameInfo frame_info = { {0,}, 0, };
+ mfxFrameSurface1 *surface;
+ GstMsdkVideoAllocator *msdk_video_allocator =
+ GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
+
+ surface = (mfxFrameSurface1 *) g_slice_new0 (mfxFrameSurface1);
+
+ if (!surface) {
+ GST_ERROR ("failed to allocate surface");
+ return NULL;
+ }
+
+ gst_msdk_set_mfx_frame_info_from_video_info (&frame_info,
+ &msdk_video_allocator->image_info);
+
+ surface->Info = frame_info;
+
+ return surface;
+}
+
+GstMemory *
+gst_msdk_video_memory_new (GstAllocator * base_allocator)
+{
+ GstMsdkVideoAllocator *allocator;
+ GstVideoInfo *vip;
+ GstMsdkVideoMemory *mem;
+
+ g_return_val_if_fail (base_allocator, NULL);
+ g_return_val_if_fail (GST_IS_MSDK_VIDEO_ALLOCATOR (base_allocator), NULL);
+
+ allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (base_allocator);
+
+ mem = g_slice_new0 (GstMsdkVideoMemory);
+ if (!mem)
+ return NULL;
+
+ mem->surface = gst_msdk_video_allocator_create_surface (base_allocator);
+
+ vip = &allocator->image_info;
+ gst_memory_init (&mem->parent_instance, GST_MEMORY_FLAG_NO_SHARE,
+ base_allocator, NULL, GST_VIDEO_INFO_SIZE (vip), 0, 0,
+ GST_VIDEO_INFO_SIZE (vip));
+
+ if (!ensure_data (mem, allocator))
+ return FALSE;
+
+ return GST_MEMORY_CAST (mem);
+}
+
+gboolean
+gst_video_meta_map_msdk_memory (GstVideoMeta * meta, guint plane,
+ GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags)
+{
+ gboolean ret = FALSE;
+ GstAllocator *allocator;
+ GstMsdkVideoAllocator *msdk_video_allocator;
+ GstMsdkVideoMemory *mem =
+ GST_MSDK_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));
+ GstMsdkMemoryID *mem_id;
+
+ g_return_val_if_fail (mem, FALSE);
+
+ allocator = GST_MEMORY_CAST (mem)->allocator;
+ msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
+
+ if (!GST_IS_MSDK_VIDEO_ALLOCATOR (allocator)) {
+ GST_WARNING ("The allocator is not MSDK video allocator");
+ return FALSE;
+ }
+
+ if (!mem->surface) {
+ GST_WARNING ("The surface is not allocated");
+ return FALSE;
+ }
+
+ if ((flags & GST_MAP_WRITE) && mem->surface && mem->surface->Data.Locked) {
+ GST_WARNING ("The surface in memory %p is not still avaliable", mem);
+ return FALSE;
+ }
+
+ if (!mem->mapped) {
+ gst_msdk_frame_lock (msdk_video_allocator->context,
+ mem->surface->Data.MemId, &mem->surface->Data);
+ }
+
+ mem->mapped++;
+ mem_id = mem->surface->Data.MemId;
+
+ *data = mem->surface->Data.Y + mem_id->image.offsets[plane];
+ *stride = mem_id->image.pitches[plane];
+
+ info->flags = flags;
+ ret = (*data != NULL);
+
+ return ret;
+}
+
+gboolean
+gst_video_meta_unmap_msdk_memory (GstVideoMeta * meta, guint plane,
+ GstMapInfo * info)
+{
+ GstAllocator *allocator;
+ GstMsdkVideoAllocator *msdk_video_allocator;
+ GstMsdkVideoMemory *mem =
+ GST_MSDK_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));
+
+ g_return_val_if_fail (mem, FALSE);
+
+ allocator = GST_MEMORY_CAST (mem)->allocator;
+ msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
+
+ if (mem->mapped == 1)
+ gst_msdk_frame_unlock (msdk_video_allocator->context,
+ mem->surface->Data.MemId, &mem->surface->Data);
+
+ mem->mapped--;
+
+ return TRUE;
+}
+
+
+static gpointer
+gst_msdk_video_memory_map_full (GstMemory * base_mem, GstMapInfo * info,
+ gsize maxsize)
+{
+ GstMsdkVideoMemory *const mem = GST_MSDK_VIDEO_MEMORY_CAST (base_mem);
+ GstAllocator *allocator = base_mem->allocator;
+ GstMsdkVideoAllocator *msdk_video_allocator =
+ GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
+
+ g_return_val_if_fail (mem, NULL);
+
+ if (!mem->surface) {
+ GST_WARNING ("The surface is not allocated");
+ return FALSE;
+ }
+
+ if ((info->flags & GST_MAP_WRITE) && mem->surface
+ && mem->surface->Data.Locked) {
+ GST_WARNING ("The surface in memory %p is not still avaliable", mem);
+ return FALSE;
+ }
+
+ gst_msdk_frame_lock (msdk_video_allocator->context, mem->surface->Data.MemId,
+ &mem->surface->Data);
+ return mem->surface->Data.Y;
+}
+
+static void
+gst_msdk_video_memory_unmap (GstMemory * base_mem)
+{
+ GstMsdkVideoMemory *const mem = GST_MSDK_VIDEO_MEMORY_CAST (base_mem);
+ GstAllocator *allocator = base_mem->allocator;
+ GstMsdkVideoAllocator *msdk_video_allocator =
+ GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
+
+ gst_msdk_frame_unlock (msdk_video_allocator->context,
+ mem->surface->Data.MemId, &mem->surface->Data);
+}
+
+/* GstMsdkVideoAllocator */
+G_DEFINE_TYPE (GstMsdkVideoAllocator, gst_msdk_video_allocator,
+ GST_TYPE_ALLOCATOR);
+
+static GstMemory *
+gst_msdk_video_allocator_alloc (GstAllocator * allocator, gsize size,
+ GstAllocationParams * params)
+{
+ return gst_msdk_video_memory_new (allocator);
+}
+
+static void
+gst_msdk_video_allocator_free (GstAllocator * allocator, GstMemory * memory)
+{
+ GstMsdkVideoAllocator *msdk_video_allocator =
+ GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
+ GstMsdkAllocResponse *resp =
+ gst_msdk_context_get_cached_alloc_responses
+ (msdk_video_allocator->context, msdk_video_allocator->alloc_response);
+
+ if (resp)
+ resp->num_used_memory--;
+}
+
+static void
+gst_msdk_video_allocator_finalize (GObject * object)
+{
+ GstMsdkVideoAllocator *allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (object);
+
+ gst_object_unref (allocator->context);
+ G_OBJECT_CLASS (gst_msdk_video_allocator_parent_class)->finalize (object);
+}
+
+static void
+gst_msdk_video_allocator_class_init (GstMsdkVideoAllocatorClass * klass)
+{
+ GObjectClass *const object_class = G_OBJECT_CLASS (klass);
+ GstAllocatorClass *const allocator_class = GST_ALLOCATOR_CLASS (klass);
+
+ object_class->finalize = gst_msdk_video_allocator_finalize;
+
+ allocator_class->alloc = gst_msdk_video_allocator_alloc;
+ allocator_class->free = gst_msdk_video_allocator_free;
+}
+
+static void
+gst_msdk_video_allocator_init (GstMsdkVideoAllocator * allocator)
+{
+ GstAllocator *const base_allocator = GST_ALLOCATOR_CAST (allocator);
+
+ base_allocator->mem_type = GST_MSDK_VIDEO_MEMORY_NAME;
+ base_allocator->mem_map_full = gst_msdk_video_memory_map_full;
+ base_allocator->mem_unmap = gst_msdk_video_memory_unmap;
+
+ GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
+}
+
+GstAllocator *
+gst_msdk_video_allocator_new (GstMsdkContext * context,
+ GstVideoInfo * image_info, mfxFrameAllocResponse * alloc_resp)
+{
+ GstMsdkVideoAllocator *allocator;
+
+ g_return_val_if_fail (context != NULL, NULL);
+ g_return_val_if_fail (image_info != NULL, NULL);
+
+ allocator = g_object_new (GST_TYPE_MSDK_VIDEO_ALLOCATOR, NULL);
+ if (!allocator)
+ return NULL;
+
+ allocator->context = gst_object_ref (context);
+ allocator->image_info = *image_info;
+ allocator->alloc_response = alloc_resp;
+
+ return GST_ALLOCATOR_CAST (allocator);
+}
diff --git a/sys/msdk/gstmsdkvideomemory.h b/sys/msdk/gstmsdkvideomemory.h
new file mode 100644
index 000000000..481ec9c1d
--- /dev/null
+++ b/sys/msdk/gstmsdkvideomemory.h
@@ -0,0 +1,130 @@
+/* GStreamer Intel MSDK plugin
+ * Copyright (c) 2018, Intel Corporation
+ * Copyright (c) 2018, Igalia S.L.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGDECE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GST_MSDK_VIDEO_MEMORY_H
+#define GST_MSDK_VIDEO_MEMORY_H
+
+#include "msdk.h"
+#include "gstmsdkcontext.h"
+#include "gstmsdkallocator.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GstMsdkVideoMemory GstMsdkVideoMemory;
+typedef struct _GstMsdkVideoAllocator GstMsdkVideoAllocator;
+typedef struct _GstMsdkVideoAllocatorClass GstMsdkVideoAllocatorClass;
+
+/* ---------------------------------------------------------------------*/
+/* GstMsdkVideoMemory */
+/* ---------------------------------------------------------------------*/
+
+#define GST_MSDK_VIDEO_MEMORY_CAST(mem) \
+ ((GstMsdkVideoMemory *) (mem))
+
+#define GST_IS_MSDK_VIDEO_MEMORY(mem) \
+ ((mem) && (mem)->allocator && GST_IS_MSDK_VIDEO_ALLOCATOR((mem)->allocator))
+
+#define GST_MSDK_VIDEO_MEMORY_NAME "GstMsdkVideoMemory"
+
+/*
+ * GstMsdkVideoMemory:
+ *
+ * A MSDK memory object holder, including mfxFrameSurface,
+ * video info of the surface.
+ */
+struct _GstMsdkVideoMemory
+{
+ GstMemory parent_instance;
+
+ mfxFrameSurface1 *surface;
+ guint mapped;
+};
+
+GstMemory *
+gst_msdk_video_memory_new (GstAllocator * allocator);
+
+gboolean
+gst_video_meta_map_msdk_memory (GstVideoMeta * meta, guint plane,
+ GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags);
+
+gboolean
+gst_video_meta_unmap_msdk_memory (GstVideoMeta * meta, guint plane,
+ GstMapInfo * info);
+
+
+/* ---------------------------------------------------------------------*/
+/* GstMsdkVideoAllocator */
+/* ---------------------------------------------------------------------*/
+
+#define GST_MSDK_VIDEO_ALLOCATOR_CAST(allocator) \
+ ((GstMsdkVideoAllocator *) (allocator))
+
+#define GST_TYPE_MSDK_VIDEO_ALLOCATOR \
+ (gst_msdk_video_allocator_get_type ())
+#define GST_MSDK_VIDEO_ALLOCATOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MSDK_VIDEO_ALLOCATOR, \
+ GstMsdkVideoAllocator))
+#define GST_IS_MSDK_VIDEO_ALLOCATOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MSDK_VIDEO_ALLOCATOR))
+
+/*
+ * GstMsdkVideoAllocator:
+ *
+ * A MSDK video memory allocator object.
+ */
+struct _GstMsdkVideoAllocator
+{
+ GstAllocator parent_instance;
+
+ GstMsdkContext *context;
+ GstVideoInfo image_info;
+ mfxFrameAllocResponse *alloc_response;
+};
+
+/*
+ * GstMsdkVideoAllocatorClass:
+ *
+ * A MSDK video memory allocator class.
+ */
+struct _GstMsdkVideoAllocatorClass
+{
+ GstAllocatorClass parent_class;
+};
+
+GType gst_msdk_video_allocator_get_type (void);
+
+GstAllocator * gst_msdk_video_allocator_new (GstMsdkContext * context,
+ GstVideoInfo *image_info, mfxFrameAllocResponse * alloc_resp);
+
+G_END_DECLS
+
+#endif /* GST_MSDK_VIDEO_MEMORY_H */
diff --git a/sys/msdk/meson.build b/sys/msdk/meson.build
index 222883901..e689cc2df 100644
--- a/sys/msdk/meson.build
+++ b/sys/msdk/meson.build
@@ -1,6 +1,9 @@
msdk_sources = [
'gstmsdk.c',
'gstmsdkcontext.c',
+ 'gstmsdksystemmemory.c',
+ 'gstmsdkvideomemory.c',
+ 'gstmsdkbufferpool.c',
'gstmsdkdec.c',
'gstmsdkenc.c',
'gstmsdkh264dec.c',