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"
39 static mfxFrameSurface1 *
40 gst_msdk_video_allocator_get_surface (GstAllocator * allocator)
42 mfxFrameInfo frame_info = { {0,}, 0, };
43 mfxFrameSurface1 *surface;
44 GstMsdkVideoAllocator *msdk_video_allocator =
45 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
48 gst_msdk_context_get_surface_available (msdk_video_allocator->context,
49 msdk_video_allocator->alloc_response);
51 GST_ERROR ("failed to get surface available");
55 gst_msdk_set_mfx_frame_info_from_video_info (&frame_info,
56 &msdk_video_allocator->image_info);
58 surface->Info = frame_info;
64 gst_msdk_video_memory_get_surface_available (GstMsdkVideoMemory * mem)
66 GstAllocator *allocator;
68 allocator = GST_MEMORY_CAST (mem)->allocator;
69 mem->surface = gst_msdk_video_allocator_get_surface (allocator);
70 return mem->surface ? TRUE : FALSE;
74 * Every time releasing a gst buffer, we need to check the status of surface's lock,
75 * so that we could manage locked surfaces seperatedly in the context.
76 * Otherwise, we put the surface to the available list.
79 gst_msdk_video_memory_release_surface (GstMsdkVideoMemory * mem)
81 GstMsdkVideoAllocator *msdk_video_allocator;
83 msdk_video_allocator =
84 GST_MSDK_VIDEO_ALLOCATOR_CAST (GST_MEMORY_CAST (mem)->allocator);
88 if (mem->surface->Data.Locked > 0)
89 gst_msdk_context_put_surface_locked (msdk_video_allocator->context,
90 msdk_video_allocator->alloc_response, mem->surface);
92 gst_msdk_context_put_surface_available (msdk_video_allocator->context,
93 msdk_video_allocator->alloc_response, mem->surface);
100 gst_msdk_video_memory_new (GstAllocator * base_allocator)
102 GstMsdkVideoAllocator *allocator;
104 GstMsdkVideoMemory *mem;
106 g_return_val_if_fail (base_allocator, NULL);
107 g_return_val_if_fail (GST_IS_MSDK_VIDEO_ALLOCATOR (base_allocator), NULL);
109 allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (base_allocator);
111 mem = g_slice_new0 (GstMsdkVideoMemory);
115 mem->surface = gst_msdk_video_allocator_get_surface (base_allocator);
119 vip = &allocator->image_info;
120 gst_memory_init (&mem->parent_instance, GST_MEMORY_FLAG_NO_SHARE,
121 base_allocator, NULL, GST_VIDEO_INFO_SIZE (vip), 0, 0,
122 GST_VIDEO_INFO_SIZE (vip));
124 return GST_MEMORY_CAST (mem);
128 gst_video_meta_map_msdk_memory (GstVideoMeta * meta, guint plane,
129 GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags)
131 gboolean ret = FALSE;
132 GstAllocator *allocator;
133 GstMsdkVideoAllocator *msdk_video_allocator;
134 GstMsdkVideoMemory *mem =
135 GST_MSDK_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));
136 GstMsdkMemoryID *mem_id;
139 guint plane_id = plane;
141 g_return_val_if_fail (mem, FALSE);
143 allocator = GST_MEMORY_CAST (mem)->allocator;
144 msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
146 if (!GST_IS_MSDK_VIDEO_ALLOCATOR (allocator)) {
147 GST_WARNING ("The allocator is not MSDK video allocator");
152 GST_WARNING ("The surface is not allocated");
156 if ((flags & GST_MAP_WRITE) && mem->surface && mem->surface->Data.Locked) {
157 GST_WARNING ("The surface in memory %p is not still avaliable", mem);
162 gst_msdk_frame_lock (msdk_video_allocator->context,
163 mem->surface->Data.MemId, &mem->surface->Data);
167 mem_id = mem->surface->Data.MemId;
169 /* msdk doesn't support I420 format and we used YV12 internally
170 * So we need to swap U/V planes for mapping */
171 if (meta->format == GST_VIDEO_FORMAT_I420)
172 plane_id = plane ? (plane == 1 ? 2 : 1) : plane;
175 offset = mem_id->image.offsets[plane_id];
176 pitch = mem_id->image.pitches[plane_id];
178 /* TODO: This is just to avoid compile errors on Windows.
179 * Implement handling Windows-specific video-memory.
181 offset = mem_id->offset;
182 pitch = mem_id->pitch;
185 *data = mem->surface->Data.Y + offset;
189 ret = (*data != NULL);
195 gst_video_meta_unmap_msdk_memory (GstVideoMeta * meta, guint plane,
198 GstAllocator *allocator;
199 GstMsdkVideoAllocator *msdk_video_allocator;
200 GstMsdkVideoMemory *mem =
201 GST_MSDK_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));
203 g_return_val_if_fail (mem, FALSE);
205 allocator = GST_MEMORY_CAST (mem)->allocator;
206 msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
208 if (mem->mapped == 1)
209 gst_msdk_frame_unlock (msdk_video_allocator->context,
210 mem->surface->Data.MemId, &mem->surface->Data);
219 gst_msdk_video_memory_map_full (GstMemory * base_mem, GstMapInfo * info,
222 GstMsdkVideoMemory *const mem = GST_MSDK_VIDEO_MEMORY_CAST (base_mem);
223 GstAllocator *allocator = base_mem->allocator;
224 GstMsdkVideoAllocator *msdk_video_allocator =
225 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
227 g_return_val_if_fail (mem, NULL);
230 GST_WARNING ("The surface is not allocated");
234 if ((info->flags & GST_MAP_WRITE) && mem->surface
235 && mem->surface->Data.Locked) {
236 GST_WARNING ("The surface in memory %p is not still avaliable", mem);
240 gst_msdk_frame_lock (msdk_video_allocator->context, mem->surface->Data.MemId,
241 &mem->surface->Data);
242 return mem->surface->Data.Y;
246 gst_msdk_video_memory_unmap (GstMemory * base_mem)
248 GstMsdkVideoMemory *const mem = GST_MSDK_VIDEO_MEMORY_CAST (base_mem);
249 GstAllocator *allocator = base_mem->allocator;
250 GstMsdkVideoAllocator *msdk_video_allocator =
251 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
253 gst_msdk_frame_unlock (msdk_video_allocator->context,
254 mem->surface->Data.MemId, &mem->surface->Data);
257 /* GstMsdkVideoAllocator */
258 G_DEFINE_TYPE (GstMsdkVideoAllocator, gst_msdk_video_allocator,
262 gst_msdk_video_allocator_alloc (GstAllocator * allocator, gsize size,
263 GstAllocationParams * params)
265 return gst_msdk_video_memory_new (allocator);
269 gst_msdk_video_allocator_finalize (GObject * object)
271 GstMsdkVideoAllocator *allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (object);
273 gst_object_unref (allocator->context);
274 G_OBJECT_CLASS (gst_msdk_video_allocator_parent_class)->finalize (object);
278 gst_msdk_video_allocator_class_init (GstMsdkVideoAllocatorClass * klass)
280 GObjectClass *const object_class = G_OBJECT_CLASS (klass);
281 GstAllocatorClass *const allocator_class = GST_ALLOCATOR_CLASS (klass);
283 object_class->finalize = gst_msdk_video_allocator_finalize;
285 allocator_class->alloc = gst_msdk_video_allocator_alloc;
289 gst_msdk_video_allocator_init (GstMsdkVideoAllocator * allocator)
291 GstAllocator *const base_allocator = GST_ALLOCATOR_CAST (allocator);
293 base_allocator->mem_type = GST_MSDK_VIDEO_MEMORY_NAME;
294 base_allocator->mem_map_full = gst_msdk_video_memory_map_full;
295 base_allocator->mem_unmap = gst_msdk_video_memory_unmap;
297 GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
301 gst_msdk_video_allocator_new (GstMsdkContext * context,
302 GstVideoInfo * image_info, mfxFrameAllocResponse * alloc_resp)
304 GstMsdkVideoAllocator *allocator;
306 g_return_val_if_fail (context != NULL, NULL);
307 g_return_val_if_fail (image_info != NULL, NULL);
309 allocator = g_object_new (GST_TYPE_MSDK_VIDEO_ALLOCATOR, NULL);
313 allocator->context = gst_object_ref (context);
314 allocator->image_info = *image_info;
315 allocator->alloc_response = alloc_resp;
317 return GST_ALLOCATOR_CAST (allocator);