1 /* GStreamer Intel MSDK plugin
2 * Copyright (c) 2018, Intel Corporation
3 * Copyright (c) 2018, Igalia S.L.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
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.
15 *
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.
19 *
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.
31 */
32
33 #ifndef _WIN32
34 #include <unistd.h>
35 #include <va/va.h>
36 #endif
37 #include <stdlib.h>
38 #include "gstmsdkvideomemory.h"
39 #include "gstmsdkallocator.h"
40
41 #define GST_MSDK_BUFFER_SURFACE gst_msdk_buffer_surface_quark_get ()
42 static GQuark
gst_msdk_buffer_surface_quark_get(void)43 gst_msdk_buffer_surface_quark_get (void)
44 {
45 static gsize g_quark;
46
47 if (g_once_init_enter (&g_quark)) {
48 gsize quark = (gsize) g_quark_from_static_string ("GstMsdkBufferSurface");
49 g_once_init_leave (&g_quark, quark);
50 }
51 return g_quark;
52 }
53
54 static mfxFrameSurface1 *
gst_msdk_video_allocator_get_surface(GstAllocator * allocator)55 gst_msdk_video_allocator_get_surface (GstAllocator * allocator)
56 {
57 mfxFrameInfo frame_info = { {0,}, 0, };
58 mfxFrameSurface1 *surface;
59 GstMsdkContext *context = NULL;
60 mfxFrameAllocResponse *resp = NULL;
61 GstVideoInfo *vinfo = NULL;
62
63 if (GST_IS_MSDK_VIDEO_ALLOCATOR (allocator)) {
64 context = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator)->context;
65 resp = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator)->alloc_response;
66 vinfo = &GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator)->image_info;
67 } else if (GST_IS_MSDK_DMABUF_ALLOCATOR (allocator)) {
68 context = GST_MSDK_DMABUF_ALLOCATOR_CAST (allocator)->context;
69 resp = GST_MSDK_DMABUF_ALLOCATOR_CAST (allocator)->alloc_response;
70 vinfo = &GST_MSDK_DMABUF_ALLOCATOR_CAST (allocator)->image_info;
71 } else {
72 return NULL;
73 }
74
75 surface = gst_msdk_context_get_surface_available (context, resp);
76 if (!surface) {
77 GST_ERROR ("failed to get surface available");
78 return NULL;
79 }
80
81 gst_msdk_set_mfx_frame_info_from_video_info (&frame_info, vinfo);
82 surface->Info = frame_info;
83
84 return surface;
85 }
86
87 gboolean
gst_msdk_video_memory_get_surface_available(GstMemory * mem)88 gst_msdk_video_memory_get_surface_available (GstMemory * mem)
89 {
90 GstAllocator *allocator;
91 mfxFrameSurface1 *surface;
92
93 g_return_val_if_fail (mem, FALSE);
94
95 allocator = mem->allocator;
96 surface = gst_msdk_video_allocator_get_surface (allocator);
97
98 if (GST_IS_MSDK_VIDEO_ALLOCATOR (allocator)) {
99 GST_MSDK_VIDEO_MEMORY_CAST (mem)->surface = surface;
100 } else if (GST_IS_MSDK_DMABUF_ALLOCATOR (allocator)) {
101 gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem),
102 GST_MSDK_BUFFER_SURFACE, surface, NULL);
103 }
104
105 return surface ? TRUE : FALSE;
106 }
107
108 /*
109 * Every time releasing a gst buffer, we need to check the status of surface's lock,
110 * so that we could manage locked surfaces separately in the context.
111 * Otherwise, we put the surface to the available list.
112 */
113 void
gst_msdk_video_memory_release_surface(GstMemory * mem)114 gst_msdk_video_memory_release_surface (GstMemory * mem)
115 {
116 mfxFrameSurface1 *surface = NULL;
117 GstMsdkContext *context = NULL;
118 mfxFrameAllocResponse *alloc_response = NULL;
119
120 g_return_if_fail (mem);
121
122 if (GST_IS_MSDK_VIDEO_ALLOCATOR (mem->allocator)) {
123 surface = GST_MSDK_VIDEO_MEMORY_CAST (mem)->surface;
124 context = GST_MSDK_VIDEO_ALLOCATOR_CAST (mem->allocator)->context;
125 alloc_response =
126 GST_MSDK_VIDEO_ALLOCATOR_CAST (mem->allocator)->alloc_response;
127 } else if (GST_IS_MSDK_DMABUF_ALLOCATOR (mem->allocator)) {
128 surface =
129 gst_mini_object_get_qdata (GST_MINI_OBJECT (mem),
130 GST_MSDK_BUFFER_SURFACE);
131 context = GST_MSDK_DMABUF_ALLOCATOR_CAST (mem->allocator)->context;
132 alloc_response =
133 GST_MSDK_DMABUF_ALLOCATOR_CAST (mem->allocator)->alloc_response;
134 } else {
135 return;
136 }
137
138 if (surface->Data.Locked > 0)
139 gst_msdk_context_put_surface_locked (context, alloc_response, surface);
140 else
141 gst_msdk_context_put_surface_available (context, alloc_response, surface);
142
143 if (GST_IS_MSDK_VIDEO_ALLOCATOR (mem->allocator))
144 GST_MSDK_VIDEO_MEMORY_CAST (mem)->surface = NULL;
145 else if (GST_IS_MSDK_DMABUF_ALLOCATOR (mem->allocator))
146 gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem),
147 GST_MSDK_BUFFER_SURFACE, NULL, NULL);
148
149 return;
150 }
151
152 GstMemory *
gst_msdk_video_memory_new(GstAllocator * base_allocator)153 gst_msdk_video_memory_new (GstAllocator * base_allocator)
154 {
155 GstMsdkVideoAllocator *allocator;
156 GstVideoInfo *vip;
157 GstMsdkVideoMemory *mem;
158
159 g_return_val_if_fail (base_allocator, NULL);
160 g_return_val_if_fail (GST_IS_MSDK_VIDEO_ALLOCATOR (base_allocator), NULL);
161
162 allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (base_allocator);
163
164 mem = g_slice_new0 (GstMsdkVideoMemory);
165 if (!mem)
166 return NULL;
167
168 mem->surface = gst_msdk_video_allocator_get_surface (base_allocator);
169 if (!mem->surface) {
170 g_slice_free (GstMsdkVideoMemory, mem);
171 return NULL;
172 }
173
174 vip = &allocator->image_info;
175 gst_memory_init (&mem->parent_instance, 0,
176 base_allocator, NULL, GST_VIDEO_INFO_SIZE (vip), 0, 0,
177 GST_VIDEO_INFO_SIZE (vip));
178
179 return GST_MEMORY_CAST (mem);
180 }
181
182 gboolean
gst_video_meta_map_msdk_memory(GstVideoMeta * meta,guint plane,GstMapInfo * info,gpointer * data,gint * stride,GstMapFlags flags)183 gst_video_meta_map_msdk_memory (GstVideoMeta * meta, guint plane,
184 GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags)
185 {
186 gboolean ret = FALSE;
187 GstAllocator *allocator;
188 GstMsdkVideoAllocator *msdk_video_allocator;
189 GstMsdkVideoMemory *mem =
190 GST_MSDK_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));
191 GstMsdkMemoryID *mem_id;
192 guint offset = 0;
193 gint pitch = 0;
194 guint plane_id = plane;
195
196 g_return_val_if_fail (mem, FALSE);
197
198 allocator = GST_MEMORY_CAST (mem)->allocator;
199 msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
200
201 if (!GST_IS_MSDK_VIDEO_ALLOCATOR (allocator)) {
202 GST_WARNING ("The allocator is not MSDK video allocator");
203 return FALSE;
204 }
205
206 if (!mem->surface) {
207 GST_WARNING ("The surface is not allocated");
208 return FALSE;
209 }
210
211 if ((flags & GST_MAP_WRITE) && mem->surface && mem->surface->Data.Locked) {
212 GST_WARNING ("The surface in memory %p is not still available", mem);
213 return FALSE;
214 }
215
216 if (!mem->mapped) {
217 gst_msdk_frame_lock (msdk_video_allocator->context,
218 mem->surface->Data.MemId, &mem->surface->Data);
219 }
220
221 mem->mapped++;
222 mem_id = mem->surface->Data.MemId;
223
224 /* msdk doesn't support I420 format and we used YV12 internally
225 * So we need to swap U/V planes for mapping */
226 if (meta->format == GST_VIDEO_FORMAT_I420)
227 plane_id = plane ? (plane == 1 ? 2 : 1) : plane;
228
229 #ifndef _WIN32
230 offset = mem_id->image.offsets[plane_id];
231 pitch = mem_id->image.pitches[plane_id];
232 #else
233 /* TODO: This is just to avoid compile errors on Windows.
234 * Implement handling Windows-specific video-memory.
235 */
236 offset = mem_id->offset;
237 pitch = mem_id->pitch;
238 #endif
239
240 switch (meta->format) {
241 case GST_VIDEO_FORMAT_BGRA:
242 case GST_VIDEO_FORMAT_BGRx:
243 *data = mem->surface->Data.B + offset;
244 break;
245
246 /* The first channel in memory is V for GST_VIDEO_FORMAT_VUYA */
247 case GST_VIDEO_FORMAT_VUYA:
248 *data = mem->surface->Data.V + offset;
249 break;
250
251 case GST_VIDEO_FORMAT_Y410:
252 case GST_VIDEO_FORMAT_Y412_LE:
253 *data = mem->surface->Data.U + offset;
254 break;
255
256 default:
257 *data = mem->surface->Data.Y + offset;
258 break;
259 }
260
261 *stride = pitch;
262 info->flags = flags;
263 ret = (*data != NULL);
264
265 return ret;
266 }
267
268 gboolean
gst_video_meta_unmap_msdk_memory(GstVideoMeta * meta,guint plane,GstMapInfo * info)269 gst_video_meta_unmap_msdk_memory (GstVideoMeta * meta, guint plane,
270 GstMapInfo * info)
271 {
272 GstAllocator *allocator;
273 GstMsdkVideoAllocator *msdk_video_allocator;
274 GstMsdkVideoMemory *mem =
275 GST_MSDK_VIDEO_MEMORY_CAST (gst_buffer_peek_memory (meta->buffer, 0));
276
277 g_return_val_if_fail (mem, FALSE);
278
279 allocator = GST_MEMORY_CAST (mem)->allocator;
280 msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
281
282 if (mem->mapped == 1)
283 gst_msdk_frame_unlock (msdk_video_allocator->context,
284 mem->surface->Data.MemId, &mem->surface->Data);
285
286 mem->mapped--;
287
288 return TRUE;
289 }
290
291
292 static gpointer
gst_msdk_video_memory_map_full(GstMemory * base_mem,GstMapInfo * info,gsize maxsize)293 gst_msdk_video_memory_map_full (GstMemory * base_mem, GstMapInfo * info,
294 gsize maxsize)
295 {
296 GstMsdkVideoMemory *const mem = GST_MSDK_VIDEO_MEMORY_CAST (base_mem);
297 GstAllocator *allocator = base_mem->allocator;
298 GstMsdkVideoAllocator *msdk_video_allocator =
299 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
300
301 g_return_val_if_fail (mem, NULL);
302
303 if (!mem->surface) {
304 GST_WARNING ("The surface is not allocated");
305 return NULL;
306 }
307
308 if ((info->flags & GST_MAP_WRITE) && mem->surface
309 && mem->surface->Data.Locked) {
310 GST_WARNING ("The surface in memory %p is not still available", mem);
311 return NULL;
312 }
313
314 gst_msdk_frame_lock (msdk_video_allocator->context, mem->surface->Data.MemId,
315 &mem->surface->Data);
316
317 switch (mem->surface->Info.FourCC) {
318 case MFX_FOURCC_RGB4:
319 return mem->surface->Data.B; /* The first channel is B */
320
321 /* The first channel in memory is V for MFX_FOURCC_AYUV (GST_VIDEO_FORMAT_VUYA) format */
322 case MFX_FOURCC_AYUV:
323 return mem->surface->Data.V;
324
325 #if (MFX_VERSION >= 1027)
326 case MFX_FOURCC_Y410:
327 return mem->surface->Data.U; /* Data.Y410 */
328 #endif
329
330 #if (MFX_VERSION >= 1031)
331 case MFX_FOURCC_Y416:
332 return mem->surface->Data.U;
333 #endif
334
335 #if (MFX_VERSION >= 2004)
336 case MFX_FOURCC_RGBP:
337 return mem->surface->Data.R;
338
339 case MFX_FOURCC_BGRP:
340 return mem->surface->Data.B;
341 #endif
342
343 default:
344 return mem->surface->Data.Y;
345 }
346 }
347
348 static void
gst_msdk_video_memory_unmap(GstMemory * base_mem)349 gst_msdk_video_memory_unmap (GstMemory * base_mem)
350 {
351 GstMsdkVideoMemory *const mem = GST_MSDK_VIDEO_MEMORY_CAST (base_mem);
352 GstAllocator *allocator = base_mem->allocator;
353 GstMsdkVideoAllocator *msdk_video_allocator =
354 GST_MSDK_VIDEO_ALLOCATOR_CAST (allocator);
355
356 gst_msdk_frame_unlock (msdk_video_allocator->context,
357 mem->surface->Data.MemId, &mem->surface->Data);
358 }
359
360 static GstMemory *
gst_msdk_video_memory_copy(GstMemory * base_mem,gssize offset,gssize size)361 gst_msdk_video_memory_copy (GstMemory * base_mem, gssize offset, gssize size)
362 {
363 GstMemory *copy;
364 GstVideoInfo *info;
365 GstMsdkVideoAllocator *msdk_video_allocator;
366 gsize mem_size;
367 GstMapInfo src_map, dst_map;
368
369 /* FIXME: can we consider offset and size here ? */
370 copy = gst_msdk_video_memory_new (base_mem->allocator);
371
372 if (!copy) {
373 GST_ERROR_OBJECT (base_mem->allocator, "Failed to create new video memory");
374 return NULL;
375 }
376
377 msdk_video_allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (base_mem->allocator);
378
379 info = &msdk_video_allocator->image_info;
380 mem_size = GST_VIDEO_INFO_SIZE (info);
381
382 gst_memory_map (base_mem, &src_map, GST_MAP_READ);
383 gst_memory_map (copy, &dst_map, GST_MAP_WRITE);
384
385 memcpy (dst_map.data, src_map.data, mem_size);
386 gst_memory_unmap (copy, &dst_map);
387 gst_memory_unmap (base_mem, &src_map);
388
389 return copy;
390 }
391
392 /* GstMsdkVideoAllocator */
393 G_DEFINE_TYPE (GstMsdkVideoAllocator, gst_msdk_video_allocator,
394 GST_TYPE_ALLOCATOR);
395
396 static GstMemory *
gst_msdk_video_allocator_alloc(GstAllocator * allocator,gsize size,GstAllocationParams * params)397 gst_msdk_video_allocator_alloc (GstAllocator * allocator, gsize size,
398 GstAllocationParams * params)
399 {
400 return gst_msdk_video_memory_new (allocator);
401 }
402
403 static void
gst_msdk_video_allocator_finalize(GObject * object)404 gst_msdk_video_allocator_finalize (GObject * object)
405 {
406 GstMsdkVideoAllocator *allocator = GST_MSDK_VIDEO_ALLOCATOR_CAST (object);
407
408 gst_msdk_frame_free (allocator->context, allocator->alloc_response);
409
410 gst_object_unref (allocator->context);
411 G_OBJECT_CLASS (gst_msdk_video_allocator_parent_class)->finalize (object);
412 }
413
414 static void
gst_msdk_video_allocator_free(GstAllocator * allocator,GstMemory * base_mem)415 gst_msdk_video_allocator_free (GstAllocator * allocator, GstMemory * base_mem)
416 {
417 GstMsdkVideoMemory *const mem = GST_MSDK_VIDEO_MEMORY_CAST (base_mem);
418
419 g_slice_free (GstMsdkVideoMemory, mem);
420 }
421
422 static void
gst_msdk_video_allocator_class_init(GstMsdkVideoAllocatorClass * klass)423 gst_msdk_video_allocator_class_init (GstMsdkVideoAllocatorClass * klass)
424 {
425 GObjectClass *const object_class = G_OBJECT_CLASS (klass);
426 GstAllocatorClass *const allocator_class = GST_ALLOCATOR_CLASS (klass);
427
428 object_class->finalize = gst_msdk_video_allocator_finalize;
429
430 allocator_class->alloc = gst_msdk_video_allocator_alloc;
431 allocator_class->free = gst_msdk_video_allocator_free;
432 }
433
434 static void
gst_msdk_video_allocator_init(GstMsdkVideoAllocator * allocator)435 gst_msdk_video_allocator_init (GstMsdkVideoAllocator * allocator)
436 {
437 GstAllocator *const base_allocator = GST_ALLOCATOR_CAST (allocator);
438
439 base_allocator->mem_type = GST_MSDK_VIDEO_MEMORY_NAME;
440 base_allocator->mem_map_full = gst_msdk_video_memory_map_full;
441 base_allocator->mem_unmap = gst_msdk_video_memory_unmap;
442 base_allocator->mem_copy = gst_msdk_video_memory_copy;
443
444 GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
445 }
446
447 GstAllocator *
gst_msdk_video_allocator_new(GstMsdkContext * context,GstVideoInfo * image_info,mfxFrameAllocResponse * alloc_resp)448 gst_msdk_video_allocator_new (GstMsdkContext * context,
449 GstVideoInfo * image_info, mfxFrameAllocResponse * alloc_resp)
450 {
451 GstMsdkVideoAllocator *allocator;
452 GstMsdkAllocResponse *cached = NULL;
453
454 g_return_val_if_fail (context != NULL, NULL);
455 g_return_val_if_fail (image_info != NULL, NULL);
456
457 cached = gst_msdk_context_get_cached_alloc_responses (context, alloc_resp);
458
459 if (!cached) {
460 GST_ERROR ("Failed to get the cached alloc response");
461 return NULL;
462 }
463
464 allocator = g_object_new (GST_TYPE_MSDK_VIDEO_ALLOCATOR, NULL);
465 if (!allocator)
466 return NULL;
467
468 g_atomic_int_inc (&cached->refcount);
469 allocator->context = gst_object_ref (context);
470 allocator->image_info = *image_info;
471 allocator->mfx_response = *alloc_resp;
472 allocator->alloc_response = &allocator->mfx_response;
473
474 return GST_ALLOCATOR_CAST (allocator);
475 }
476
477 /* GstMsdkDmaBufMemory */
478 GstMemory *
gst_msdk_dmabuf_memory_new(GstAllocator * base_allocator)479 gst_msdk_dmabuf_memory_new (GstAllocator * base_allocator)
480 {
481 #ifndef _WIN32
482 mfxFrameSurface1 *surface;
483
484 g_return_val_if_fail (base_allocator, NULL);
485 g_return_val_if_fail (GST_IS_MSDK_DMABUF_ALLOCATOR (base_allocator), NULL);
486
487 surface = gst_msdk_video_allocator_get_surface (base_allocator);
488 if (!surface)
489 return NULL;
490
491 return gst_msdk_dmabuf_memory_new_with_surface (base_allocator, surface);
492 #else
493 return NULL;
494 #endif
495 }
496
497 GstMemory *
gst_msdk_dmabuf_memory_new_with_surface(GstAllocator * allocator,mfxFrameSurface1 * surface)498 gst_msdk_dmabuf_memory_new_with_surface (GstAllocator * allocator,
499 mfxFrameSurface1 * surface)
500 {
501 #ifndef _WIN32
502 GstMemory *mem;
503 GstMsdkMemoryID *mem_id;
504 gint fd;
505 gsize size;
506
507 g_return_val_if_fail (allocator, NULL);
508 g_return_val_if_fail (GST_IS_MSDK_DMABUF_ALLOCATOR (allocator), NULL);
509
510 mem_id = surface->Data.MemId;
511
512 g_assert (mem_id->desc.num_objects == 1);
513
514 fd = mem_id->desc.objects[0].fd;
515 size = mem_id->desc.objects[0].size;
516
517 if (fd < 0) {
518 GST_ERROR ("Failed to get dmabuf handle");
519 return NULL;
520 }
521
522 mem = gst_fd_allocator_alloc (allocator, fd, size,
523 GST_FD_MEMORY_FLAG_DONT_CLOSE);
524
525 if (!mem) {
526 GST_ERROR ("failed ! dmabuf fd: %d", fd);
527 return NULL;
528 }
529
530 gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem),
531 GST_MSDK_BUFFER_SURFACE, surface, NULL);
532
533 return mem;
534 #else
535 return NULL;
536 #endif
537 }
538
539 /* GstMsdkDmaBufAllocator */
540 G_DEFINE_TYPE (GstMsdkDmaBufAllocator, gst_msdk_dmabuf_allocator,
541 GST_TYPE_DMABUF_ALLOCATOR);
542
543 static void
gst_msdk_dmabuf_allocator_finalize(GObject * object)544 gst_msdk_dmabuf_allocator_finalize (GObject * object)
545 {
546 GstMsdkDmaBufAllocator *allocator = GST_MSDK_DMABUF_ALLOCATOR_CAST (object);
547
548 gst_msdk_frame_free (allocator->context, allocator->alloc_response);
549
550 gst_object_unref (allocator->context);
551 G_OBJECT_CLASS (gst_msdk_dmabuf_allocator_parent_class)->finalize (object);
552 }
553
554 static void
gst_msdk_dmabuf_allocator_class_init(GstMsdkDmaBufAllocatorClass * klass)555 gst_msdk_dmabuf_allocator_class_init (GstMsdkDmaBufAllocatorClass * klass)
556 {
557 GObjectClass *const object_class = G_OBJECT_CLASS (klass);
558
559 object_class->finalize = gst_msdk_dmabuf_allocator_finalize;
560 }
561
562 static void
gst_msdk_dmabuf_allocator_init(GstMsdkDmaBufAllocator * allocator)563 gst_msdk_dmabuf_allocator_init (GstMsdkDmaBufAllocator * allocator)
564 {
565 GstAllocator *const base_allocator = GST_ALLOCATOR_CAST (allocator);
566 base_allocator->mem_type = GST_MSDK_DMABUF_MEMORY_NAME;
567 }
568
569 GstAllocator *
gst_msdk_dmabuf_allocator_new(GstMsdkContext * context,GstVideoInfo * image_info,mfxFrameAllocResponse * alloc_resp)570 gst_msdk_dmabuf_allocator_new (GstMsdkContext * context,
571 GstVideoInfo * image_info, mfxFrameAllocResponse * alloc_resp)
572 {
573 GstMsdkDmaBufAllocator *allocator;
574 GstMsdkAllocResponse *cached = NULL;
575
576 g_return_val_if_fail (context != NULL, NULL);
577 g_return_val_if_fail (image_info != NULL, NULL);
578
579 cached = gst_msdk_context_get_cached_alloc_responses (context, alloc_resp);
580
581 if (!cached) {
582 GST_ERROR ("Failed to get the cached alloc response");
583 return NULL;
584 }
585
586 allocator = g_object_new (GST_TYPE_MSDK_DMABUF_ALLOCATOR, NULL);
587 if (!allocator)
588 return NULL;
589
590 g_atomic_int_inc (&cached->refcount);
591 allocator->context = gst_object_ref (context);
592 allocator->image_info = *image_info;
593 allocator->mfx_response = *alloc_resp;
594 allocator->alloc_response = &allocator->mfx_response;
595
596 return GST_ALLOCATOR_CAST (allocator);
597 }
598