2 * Copyright (C) 2021 Seungha Yang <seungha@centricular.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
24 #include "gstqsvallocator_va.h"
26 GST_DEBUG_CATEGORY_EXTERN (gst_qsv_allocator_debug);
27 #define GST_CAT_DEFAULT gst_qsv_allocator_debug
29 struct _GstQsvVaAllocator
31 GstQsvAllocator parent;
33 GstVaDisplay *display;
36 #define gst_qsv_va_allocator_parent_class parent_class
37 G_DEFINE_TYPE (GstQsvVaAllocator, gst_qsv_va_allocator, GST_TYPE_QSV_ALLOCATOR);
39 static void gst_qsv_va_allocator_dispose (GObject * object);
40 static mfxStatus gst_qsv_va_allocator_alloc (GstQsvAllocator * allocator,
41 gboolean dummy_alloc, mfxFrameAllocRequest * request,
42 mfxFrameAllocResponse * response);
43 static GstBuffer *gst_qsv_va_allocator_upload (GstQsvAllocator * allocator,
44 const GstVideoInfo * info, GstBuffer * buffer, GstBufferPool * pool);
45 static GstBuffer *gst_qsv_va_allocator_download (GstQsvAllocator * allocator,
46 const GstVideoInfo * info, gboolean force_copy, GstQsvFrame * frame,
47 GstBufferPool * pool);
50 gst_qsv_va_allocator_class_init (GstQsvVaAllocatorClass * klass)
52 GObjectClass *object_class = G_OBJECT_CLASS (klass);
53 GstQsvAllocatorClass *alloc_class = GST_QSV_ALLOCATOR_CLASS (klass);
55 object_class->dispose = gst_qsv_va_allocator_dispose;
57 alloc_class->alloc = GST_DEBUG_FUNCPTR (gst_qsv_va_allocator_alloc);
58 alloc_class->upload = GST_DEBUG_FUNCPTR (gst_qsv_va_allocator_upload);
59 alloc_class->download = GST_DEBUG_FUNCPTR (gst_qsv_va_allocator_download);
63 gst_qsv_va_allocator_init (GstQsvVaAllocator * self)
68 gst_qsv_va_allocator_dispose (GObject * object)
70 GstQsvVaAllocator *self = GST_QSV_VA_ALLOCATOR (object);
72 gst_clear_object (&self->display);
74 G_OBJECT_CLASS (parent_class)->dispose (object);
78 gst_qsv_va_allocator_alloc (GstQsvAllocator * allocator, gboolean dummy_alloc,
79 mfxFrameAllocRequest * request, mfxFrameAllocResponse * response)
81 GST_ERROR_OBJECT (allocator, "Not implemented");
83 return MFX_ERR_UNSUPPORTED;
87 gst_qsv_va_allocator_upload (GstQsvAllocator * allocator,
88 const GstVideoInfo * info, GstBuffer * buffer, GstBufferPool * pool)
90 GstVideoFrame src_frame, dst_frame;
95 /* TODO: handle buffer from different VA display */
96 surface = gst_va_buffer_get_surface (buffer);
97 if (surface != VA_INVALID_ID)
98 return gst_buffer_ref (buffer);
100 ret = gst_buffer_pool_acquire_buffer (pool, &dst_buf, nullptr);
101 if (ret != GST_FLOW_OK) {
102 GST_WARNING_OBJECT (allocator, "Failed to acquire buffer");
106 if (!gst_video_frame_map (&src_frame, info, buffer, GST_MAP_READ)) {
107 GST_WARNING_OBJECT (allocator, "Failed to map src frame");
108 gst_buffer_unref (dst_buf);
112 if (!gst_video_frame_map (&dst_frame, info, dst_buf, GST_MAP_WRITE)) {
113 GST_WARNING_OBJECT (allocator, "Failed to map src frame");
114 gst_video_frame_unmap (&src_frame);
115 gst_buffer_unref (dst_buf);
119 for (guint i = 0; i < GST_VIDEO_FRAME_N_PLANES (&src_frame); i++) {
120 guint src_width_in_bytes, src_height;
121 guint dst_width_in_bytes, dst_height;
122 guint width_in_bytes, height;
123 guint src_stride, dst_stride;
124 guint8 *src_data, *dst_data;
126 src_width_in_bytes = GST_VIDEO_FRAME_COMP_WIDTH (&src_frame, i) *
127 GST_VIDEO_FRAME_COMP_PSTRIDE (&src_frame, i);
128 src_height = GST_VIDEO_FRAME_COMP_HEIGHT (&src_frame, i);
129 src_stride = GST_VIDEO_FRAME_COMP_STRIDE (&src_frame, i);
131 dst_width_in_bytes = GST_VIDEO_FRAME_COMP_WIDTH (&dst_frame, i) *
132 GST_VIDEO_FRAME_COMP_PSTRIDE (&src_frame, i);
133 dst_height = GST_VIDEO_FRAME_COMP_HEIGHT (&src_frame, i);
134 dst_stride = GST_VIDEO_FRAME_COMP_STRIDE (&dst_frame, i);
136 width_in_bytes = MIN (src_width_in_bytes, dst_width_in_bytes);
137 height = MIN (src_height, dst_height);
139 src_data = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&src_frame, i);
140 dst_data = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&dst_frame, i);
142 for (guint j = 0; j < height; j++) {
143 memcpy (dst_data, src_data, width_in_bytes);
144 dst_data += dst_stride;
145 src_data += src_stride;
149 gst_video_frame_unmap (&dst_frame);
150 gst_video_frame_unmap (&src_frame);
156 gst_qsv_va_allocator_download (GstQsvAllocator * allocator,
157 const GstVideoInfo * info, gboolean force_copy, GstQsvFrame * frame,
158 GstBufferPool * pool)
160 GST_ERROR_OBJECT (allocator, "Not implemented");
166 gst_qsv_va_allocator_new (GstVaDisplay * display)
168 GstQsvVaAllocator *self;
170 g_return_val_if_fail (GST_IS_VA_DISPLAY (display), nullptr);
172 self = (GstQsvVaAllocator *)
173 g_object_new (GST_TYPE_QSV_VA_ALLOCATOR, nullptr);
174 self->display = (GstVaDisplay *) gst_object_ref (display);
176 gst_object_ref_sink (self);
178 return GST_QSV_ALLOCATOR (self);