1 /* GStreamer Intel MSDK plugin
2 * Copyright (c) 2018, Intel Corporation
3 * Copyright (c) 2018, Igalia S.L.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * 3. Neither the name of the copyright holder nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGDECE
29 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include "gstmsdkvideomemory.h"
37 #include "gstmsdkallocator.h"
40 ensure_data (GstMsdkVideoMemory * mem, GstMsdkVideoAllocator * allocator)
42 GstMsdkMemoryID *mem_id;
43 GstMsdkAllocResponse *resp =
44 gst_msdk_context_get_cached_alloc_responses (allocator->context,
45 allocator->alloc_response);
48 GST_WARNING ("failed to get allocation response");
52 mem_id = (GstMsdkMemoryID *) resp->mem_ids[resp->num_used_memory++];
53 mem->surface->Data.MemId = mem_id;
58 static mfxFrameSurface1 *
59 gst_msdk_video_allocator_create_surface (GstAllocator * allocator)
61 mfxFrameInfo frame_info = { {0,}, 0, };
62 mfxFrameSurface1 *surface;
63 GstMsdkVideoAllocator *msdk_video_allocator =
64 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
66 surface = (mfxFrameSurface1 *) g_slice_new0 (mfxFrameSurface1);
69 GST_ERROR ("failed to allocate surface");
73 gst_msdk_set_mfx_frame_info_from_video_info (&frame_info,
74 &msdk_video_allocator->image_info);
76 surface->Info = frame_info;
82 gst_msdk_video_memory_new (GstAllocator * base_allocator)
84 GstMsdkVideoAllocator *allocator;
86 GstMsdkVideoMemory *mem;
88 g_return_val_if_fail (base_allocator, NULL);
89 g_return_val_if_fail (GST_IS_MSDK_VIDEO_ALLOCATOR (base_allocator), NULL);
91 allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (base_allocator);
93 mem = g_slice_new0 (GstMsdkVideoMemory);
97 mem->surface = gst_msdk_video_allocator_create_surface (base_allocator);
99 vip = &allocator->image_info;
100 gst_memory_init (&mem->parent_instance, GST_MEMORY_FLAG_NO_SHARE,
101 base_allocator, NULL, GST_VIDEO_INFO_SIZE (vip), 0, 0,
102 GST_VIDEO_INFO_SIZE (vip));
104 if (!ensure_data (mem, allocator))
107 return GST_MEMORY_CAST (mem);
111 gst_video_meta_map_msdk_memory (GstVideoMeta * meta, guint plane,
112 GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags)
114 gboolean ret = FALSE;
115 GstAllocator *allocator;
116 GstMsdkVideoAllocator *msdk_video_allocator;
117 GstMsdkVideoMemory *mem =
118 GST_MSDK_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));
119 GstMsdkMemoryID *mem_id;
123 g_return_val_if_fail (mem, FALSE);
125 allocator = GST_MEMORY_CAST (mem)->allocator;
126 msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
128 if (!GST_IS_MSDK_VIDEO_ALLOCATOR (allocator)) {
129 GST_WARNING ("The allocator is not MSDK video allocator");
134 GST_WARNING ("The surface is not allocated");
138 if ((flags & GST_MAP_WRITE) && mem->surface && mem->surface->Data.Locked) {
139 GST_WARNING ("The surface in memory %p is not still avaliable", mem);
144 gst_msdk_frame_lock (msdk_video_allocator->context,
145 mem->surface->Data.MemId, &mem->surface->Data);
149 mem_id = mem->surface->Data.MemId;
152 offset = mem_id->image.offsets[plane];
153 pitch = mem_id->image.pitches[plane];
155 /* TODO: This is just to avoid compile errors on Windows.
156 * Implement handling Windows-specific video-memory.
158 offset = mem_id->offset;
159 pitch = mem_id->pitch;
162 *data = mem->surface->Data.Y + offset;
166 ret = (*data != NULL);
172 gst_video_meta_unmap_msdk_memory (GstVideoMeta * meta, guint plane,
175 GstAllocator *allocator;
176 GstMsdkVideoAllocator *msdk_video_allocator;
177 GstMsdkVideoMemory *mem =
178 GST_MSDK_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));
180 g_return_val_if_fail (mem, FALSE);
182 allocator = GST_MEMORY_CAST (mem)->allocator;
183 msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
185 if (mem->mapped == 1)
186 gst_msdk_frame_unlock (msdk_video_allocator->context,
187 mem->surface->Data.MemId, &mem->surface->Data);
196 gst_msdk_video_memory_map_full (GstMemory * base_mem, GstMapInfo * info,
199 GstMsdkVideoMemory *const mem = GST_MSDK_VIDEO_MEMORY_CAST (base_mem);
200 GstAllocator *allocator = base_mem->allocator;
201 GstMsdkVideoAllocator *msdk_video_allocator =
202 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
204 g_return_val_if_fail (mem, NULL);
207 GST_WARNING ("The surface is not allocated");
211 if ((info->flags & GST_MAP_WRITE) && mem->surface
212 && mem->surface->Data.Locked) {
213 GST_WARNING ("The surface in memory %p is not still avaliable", mem);
217 gst_msdk_frame_lock (msdk_video_allocator->context, mem->surface->Data.MemId,
218 &mem->surface->Data);
219 return mem->surface->Data.Y;
223 gst_msdk_video_memory_unmap (GstMemory * base_mem)
225 GstMsdkVideoMemory *const mem = GST_MSDK_VIDEO_MEMORY_CAST (base_mem);
226 GstAllocator *allocator = base_mem->allocator;
227 GstMsdkVideoAllocator *msdk_video_allocator =
228 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
230 gst_msdk_frame_unlock (msdk_video_allocator->context,
231 mem->surface->Data.MemId, &mem->surface->Data);
234 /* GstMsdkVideoAllocator */
235 G_DEFINE_TYPE (GstMsdkVideoAllocator, gst_msdk_video_allocator,
239 gst_msdk_video_allocator_alloc (GstAllocator * allocator, gsize size,
240 GstAllocationParams * params)
242 return gst_msdk_video_memory_new (allocator);
246 gst_msdk_video_allocator_free (GstAllocator * allocator, GstMemory * memory)
248 GstMsdkVideoAllocator *msdk_video_allocator =
249 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
250 GstMsdkAllocResponse *resp =
251 gst_msdk_context_get_cached_alloc_responses
252 (msdk_video_allocator->context, msdk_video_allocator->alloc_response);
255 resp->num_used_memory--;
259 gst_msdk_video_allocator_finalize (GObject * object)
261 GstMsdkVideoAllocator *allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (object);
263 gst_object_unref (allocator->context);
264 G_OBJECT_CLASS (gst_msdk_video_allocator_parent_class)->finalize (object);
268 gst_msdk_video_allocator_class_init (GstMsdkVideoAllocatorClass * klass)
270 GObjectClass *const object_class = G_OBJECT_CLASS (klass);
271 GstAllocatorClass *const allocator_class = GST_ALLOCATOR_CLASS (klass);
273 object_class->finalize = gst_msdk_video_allocator_finalize;
275 allocator_class->alloc = gst_msdk_video_allocator_alloc;
276 allocator_class->free = gst_msdk_video_allocator_free;
280 gst_msdk_video_allocator_init (GstMsdkVideoAllocator * allocator)
282 GstAllocator *const base_allocator = GST_ALLOCATOR_CAST (allocator);
284 base_allocator->mem_type = GST_MSDK_VIDEO_MEMORY_NAME;
285 base_allocator->mem_map_full = gst_msdk_video_memory_map_full;
286 base_allocator->mem_unmap = gst_msdk_video_memory_unmap;
288 GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
292 gst_msdk_video_allocator_new (GstMsdkContext * context,
293 GstVideoInfo * image_info, mfxFrameAllocResponse * alloc_resp)
295 GstMsdkVideoAllocator *allocator;
297 g_return_val_if_fail (context != NULL, NULL);
298 g_return_val_if_fail (image_info != NULL, NULL);
300 allocator = g_object_new (GST_TYPE_MSDK_VIDEO_ALLOCATOR, NULL);
304 allocator->context = gst_object_ref (context);
305 allocator->image_info = *image_info;
306 allocator->alloc_response = alloc_resp;
308 return GST_ALLOCATOR_CAST (allocator);