qsv: Update SDK version to v2022.2.4
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / sys / qsv / gstqsvallocator_va.cpp
1 /* GStreamer
2  * Copyright (C) 2021 Seungha Yang <seungha@centricular.com>
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "gstqsvallocator_va.h"
25
26 GST_DEBUG_CATEGORY_EXTERN (gst_qsv_allocator_debug);
27 #define GST_CAT_DEFAULT gst_qsv_allocator_debug
28
29 struct _GstQsvVaAllocator
30 {
31   GstQsvAllocator parent;
32
33   GstVaDisplay *display;
34 };
35
36 #define gst_qsv_va_allocator_parent_class parent_class
37 G_DEFINE_TYPE (GstQsvVaAllocator, gst_qsv_va_allocator, GST_TYPE_QSV_ALLOCATOR);
38
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);
48
49 static void
50 gst_qsv_va_allocator_class_init (GstQsvVaAllocatorClass * klass)
51 {
52   GObjectClass *object_class = G_OBJECT_CLASS (klass);
53   GstQsvAllocatorClass *alloc_class = GST_QSV_ALLOCATOR_CLASS (klass);
54
55   object_class->dispose = gst_qsv_va_allocator_dispose;
56
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);
60 }
61
62 static void
63 gst_qsv_va_allocator_init (GstQsvVaAllocator * self)
64 {
65 }
66
67 static void
68 gst_qsv_va_allocator_dispose (GObject * object)
69 {
70   GstQsvVaAllocator *self = GST_QSV_VA_ALLOCATOR (object);
71
72   gst_clear_object (&self->display);
73
74   G_OBJECT_CLASS (parent_class)->dispose (object);
75 }
76
77 static mfxStatus
78 gst_qsv_va_allocator_alloc (GstQsvAllocator * allocator, gboolean dummy_alloc,
79     mfxFrameAllocRequest * request, mfxFrameAllocResponse * response)
80 {
81   GST_ERROR_OBJECT (allocator, "Not implemented");
82
83   return MFX_ERR_UNSUPPORTED;
84 }
85
86 static GstBuffer *
87 gst_qsv_va_allocator_upload (GstQsvAllocator * allocator,
88     const GstVideoInfo * info, GstBuffer * buffer, GstBufferPool * pool)
89 {
90   GstVideoFrame src_frame, dst_frame;
91   VASurfaceID surface;
92   GstBuffer *dst_buf;
93   GstFlowReturn ret;
94
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);
99
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");
103     return nullptr;
104   }
105
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);
109     return nullptr;
110   }
111
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);
116     return nullptr;
117   }
118
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;
125
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);
130
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);
135
136     width_in_bytes = MIN (src_width_in_bytes, dst_width_in_bytes);
137     height = MIN (src_height, dst_height);
138
139     src_data = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&src_frame, i);
140     dst_data = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (&dst_frame, i);
141
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;
146     }
147   }
148
149   gst_video_frame_unmap (&dst_frame);
150   gst_video_frame_unmap (&src_frame);
151
152   return dst_buf;
153 }
154
155 static GstBuffer *
156 gst_qsv_va_allocator_download (GstQsvAllocator * allocator,
157     const GstVideoInfo * info, gboolean force_copy, GstQsvFrame * frame,
158     GstBufferPool * pool)
159 {
160   GST_ERROR_OBJECT (allocator, "Not implemented");
161
162   return nullptr;
163 }
164
165 GstQsvAllocator *
166 gst_qsv_va_allocator_new (GstVaDisplay * display)
167 {
168   GstQsvVaAllocator *self;
169
170   g_return_val_if_fail (GST_IS_VA_DISPLAY (display), nullptr);
171
172   self = (GstQsvVaAllocator *)
173       g_object_new (GST_TYPE_QSV_VA_ALLOCATOR, nullptr);
174   self->display = (GstVaDisplay *) gst_object_ref (display);
175
176   gst_object_ref_sink (self);
177
178   return GST_QSV_ALLOCATOR (self);
179 }