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;
121 g_return_val_if_fail (mem, FALSE);
123 allocator = GST_MEMORY_CAST (mem)->allocator;
124 msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
126 if (!GST_IS_MSDK_VIDEO_ALLOCATOR (allocator)) {
127 GST_WARNING ("The allocator is not MSDK video allocator");
132 GST_WARNING ("The surface is not allocated");
136 if ((flags & GST_MAP_WRITE) && mem->surface && mem->surface->Data.Locked) {
137 GST_WARNING ("The surface in memory %p is not still avaliable", mem);
142 gst_msdk_frame_lock (msdk_video_allocator->context,
143 mem->surface->Data.MemId, &mem->surface->Data);
147 mem_id = mem->surface->Data.MemId;
149 *data = mem->surface->Data.Y + mem_id->image.offsets[plane];
150 *stride = mem_id->image.pitches[plane];
153 ret = (*data != NULL);
159 gst_video_meta_unmap_msdk_memory (GstVideoMeta * meta, guint plane,
162 GstAllocator *allocator;
163 GstMsdkVideoAllocator *msdk_video_allocator;
164 GstMsdkVideoMemory *mem =
165 GST_MSDK_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));
167 g_return_val_if_fail (mem, FALSE);
169 allocator = GST_MEMORY_CAST (mem)->allocator;
170 msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
172 if (mem->mapped == 1)
173 gst_msdk_frame_unlock (msdk_video_allocator->context,
174 mem->surface->Data.MemId, &mem->surface->Data);
183 gst_msdk_video_memory_map_full (GstMemory * base_mem, GstMapInfo * info,
186 GstMsdkVideoMemory *const mem = GST_MSDK_VIDEO_MEMORY_CAST (base_mem);
187 GstAllocator *allocator = base_mem->allocator;
188 GstMsdkVideoAllocator *msdk_video_allocator =
189 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
191 g_return_val_if_fail (mem, NULL);
194 GST_WARNING ("The surface is not allocated");
198 if ((info->flags & GST_MAP_WRITE) && mem->surface
199 && mem->surface->Data.Locked) {
200 GST_WARNING ("The surface in memory %p is not still avaliable", mem);
204 gst_msdk_frame_lock (msdk_video_allocator->context, mem->surface->Data.MemId,
205 &mem->surface->Data);
206 return mem->surface->Data.Y;
210 gst_msdk_video_memory_unmap (GstMemory * base_mem)
212 GstMsdkVideoMemory *const mem = GST_MSDK_VIDEO_MEMORY_CAST (base_mem);
213 GstAllocator *allocator = base_mem->allocator;
214 GstMsdkVideoAllocator *msdk_video_allocator =
215 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
217 gst_msdk_frame_unlock (msdk_video_allocator->context,
218 mem->surface->Data.MemId, &mem->surface->Data);
221 /* GstMsdkVideoAllocator */
222 G_DEFINE_TYPE (GstMsdkVideoAllocator, gst_msdk_video_allocator,
226 gst_msdk_video_allocator_alloc (GstAllocator * allocator, gsize size,
227 GstAllocationParams * params)
229 return gst_msdk_video_memory_new (allocator);
233 gst_msdk_video_allocator_free (GstAllocator * allocator, GstMemory * memory)
235 GstMsdkVideoAllocator *msdk_video_allocator =
236 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
237 GstMsdkAllocResponse *resp =
238 gst_msdk_context_get_cached_alloc_responses
239 (msdk_video_allocator->context, msdk_video_allocator->alloc_response);
242 resp->num_used_memory--;
246 gst_msdk_video_allocator_finalize (GObject * object)
248 GstMsdkVideoAllocator *allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (object);
250 gst_object_unref (allocator->context);
251 G_OBJECT_CLASS (gst_msdk_video_allocator_parent_class)->finalize (object);
255 gst_msdk_video_allocator_class_init (GstMsdkVideoAllocatorClass * klass)
257 GObjectClass *const object_class = G_OBJECT_CLASS (klass);
258 GstAllocatorClass *const allocator_class = GST_ALLOCATOR_CLASS (klass);
260 object_class->finalize = gst_msdk_video_allocator_finalize;
262 allocator_class->alloc = gst_msdk_video_allocator_alloc;
263 allocator_class->free = gst_msdk_video_allocator_free;
267 gst_msdk_video_allocator_init (GstMsdkVideoAllocator * allocator)
269 GstAllocator *const base_allocator = GST_ALLOCATOR_CAST (allocator);
271 base_allocator->mem_type = GST_MSDK_VIDEO_MEMORY_NAME;
272 base_allocator->mem_map_full = gst_msdk_video_memory_map_full;
273 base_allocator->mem_unmap = gst_msdk_video_memory_unmap;
275 GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
279 gst_msdk_video_allocator_new (GstMsdkContext * context,
280 GstVideoInfo * image_info, mfxFrameAllocResponse * alloc_resp)
282 GstMsdkVideoAllocator *allocator;
284 g_return_val_if_fail (context != NULL, NULL);
285 g_return_val_if_fail (image_info != NULL, NULL);
287 allocator = g_object_new (GST_TYPE_MSDK_VIDEO_ALLOCATOR, NULL);
291 allocator->context = gst_object_ref (context);
292 allocator->image_info = *image_info;
293 allocator->alloc_response = alloc_resp;
295 return GST_ALLOCATOR_CAST (allocator);