1 /* GStreamer
2 * Copyright (C) 2020 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 "gstd3d11format.h"
25 #include "gstd3d11utils.h"
26 #include "gstd3d11device.h"
27 #include "gstd3d11memory.h"
28
29 #include <string.h>
30
31 #ifndef GST_DISABLE_GST_DEBUG
32 #define GST_CAT_DEFAULT ensure_debug_category()
33 static GstDebugCategory *
ensure_debug_category(void)34 ensure_debug_category (void)
35 {
36 static gsize cat_gonce = 0;
37
38 if (g_once_init_enter (&cat_gonce)) {
39 gsize cat_done;
40
41 cat_done = (gsize) _gst_debug_category_new ("d3d11format", 0,
42 "d3d11 specific formats");
43
44 g_once_init_leave (&cat_gonce, cat_done);
45 }
46
47 return (GstDebugCategory *) cat_gonce;
48 }
49 #else
50 #define ensure_debug_category() /* NOOP */
51 #endif /* GST_DISABLE_GST_DEBUG */
52
53 /**
54 * gst_d3d11_dxgi_format_n_planes:
55 * @format: a DXGI_FORMAT
56 *
57 * Returns: the number of planes for @format
58 *
59 * Since: 1.20
60 */
61 guint
gst_d3d11_dxgi_format_n_planes(DXGI_FORMAT format)62 gst_d3d11_dxgi_format_n_planes (DXGI_FORMAT format)
63 {
64 switch (format) {
65 case DXGI_FORMAT_B8G8R8A8_UNORM:
66 case DXGI_FORMAT_R8G8B8A8_UNORM:
67 case DXGI_FORMAT_R10G10B10A2_UNORM:
68 case DXGI_FORMAT_AYUV:
69 case DXGI_FORMAT_YUY2:
70 case DXGI_FORMAT_R8_UNORM:
71 case DXGI_FORMAT_R8G8_UNORM:
72 case DXGI_FORMAT_R16_UNORM:
73 case DXGI_FORMAT_R16G16_UNORM:
74 case DXGI_FORMAT_G8R8_G8B8_UNORM:
75 case DXGI_FORMAT_R8G8_B8G8_UNORM:
76 case DXGI_FORMAT_Y210:
77 case DXGI_FORMAT_Y410:
78 case DXGI_FORMAT_R16G16B16A16_UNORM:
79 return 1;
80 case DXGI_FORMAT_NV12:
81 case DXGI_FORMAT_P010:
82 case DXGI_FORMAT_P016:
83 return 2;
84 default:
85 break;
86 }
87
88 return 0;
89 }
90
91 /**
92 * gst_d3d11_dxgi_format_get_size:
93 * @format: a DXGI_FORMAT
94 * @width: a texture width
95 * @height: a texture height
96 * @pitch: a pitch of texture
97 * @offset: offset for each plane
98 * @stride: stride for each plane
99 * @size: (out): required memory size for given format
100 *
101 * Calculate required memory size and per plane stride with
102 * based on information
103 *
104 * Returns: %TRUE if @size can be calculated with given information
105 *
106 * Since: 1.20
107 */
108 gboolean
gst_d3d11_dxgi_format_get_size(DXGI_FORMAT format,guint width,guint height,guint pitch,gsize offset[GST_VIDEO_MAX_PLANES],gint stride[GST_VIDEO_MAX_PLANES],gsize * size)109 gst_d3d11_dxgi_format_get_size (DXGI_FORMAT format, guint width, guint height,
110 guint pitch, gsize offset[GST_VIDEO_MAX_PLANES],
111 gint stride[GST_VIDEO_MAX_PLANES], gsize * size)
112 {
113 g_return_val_if_fail (format != DXGI_FORMAT_UNKNOWN, FALSE);
114
115 switch (format) {
116 case DXGI_FORMAT_B8G8R8A8_UNORM:
117 case DXGI_FORMAT_R8G8B8A8_UNORM:
118 case DXGI_FORMAT_R10G10B10A2_UNORM:
119 case DXGI_FORMAT_AYUV:
120 case DXGI_FORMAT_YUY2:
121 case DXGI_FORMAT_R8_UNORM:
122 case DXGI_FORMAT_R8G8_UNORM:
123 case DXGI_FORMAT_R16_UNORM:
124 case DXGI_FORMAT_R16G16_UNORM:
125 case DXGI_FORMAT_G8R8_G8B8_UNORM:
126 case DXGI_FORMAT_R8G8_B8G8_UNORM:
127 case DXGI_FORMAT_Y210:
128 case DXGI_FORMAT_Y410:
129 case DXGI_FORMAT_R16G16B16A16_UNORM:
130 offset[0] = 0;
131 stride[0] = pitch;
132 *size = pitch * height;
133 break;
134 case DXGI_FORMAT_NV12:
135 case DXGI_FORMAT_P010:
136 case DXGI_FORMAT_P016:
137 offset[0] = 0;
138 stride[0] = pitch;
139 offset[1] = offset[0] + stride[0] * height;
140 stride[1] = pitch;
141 *size = offset[1] + stride[1] * GST_ROUND_UP_2 (height / 2);
142 break;
143 default:
144 return FALSE;
145 }
146
147 GST_LOG ("Calculated buffer size: %" G_GSIZE_FORMAT
148 " (dxgi format:%d, %dx%d, Pitch %d)",
149 *size, format, width, height, pitch);
150
151 return TRUE;
152 }
153
154 /**
155 * gst_d3d11_dxgi_format_to_gst:
156 * @format: a DXGI_FORMAT
157 *
158 * Converts the @format to its #GstVideoFormat representation.
159 *
160 * Returns: a #GstVideoFormat equivalent to @format
161 *
162 * Since: 1.20
163 */
164 GstVideoFormat
gst_d3d11_dxgi_format_to_gst(DXGI_FORMAT format)165 gst_d3d11_dxgi_format_to_gst (DXGI_FORMAT format)
166 {
167 switch (format) {
168 case DXGI_FORMAT_B8G8R8A8_UNORM:
169 return GST_VIDEO_FORMAT_BGRA;
170 case DXGI_FORMAT_R8G8B8A8_UNORM:
171 return GST_VIDEO_FORMAT_RGBA;
172 case DXGI_FORMAT_R10G10B10A2_UNORM:
173 return GST_VIDEO_FORMAT_RGB10A2_LE;
174 case DXGI_FORMAT_AYUV:
175 return GST_VIDEO_FORMAT_VUYA;
176 case DXGI_FORMAT_YUY2:
177 return GST_VIDEO_FORMAT_YUY2;
178 case DXGI_FORMAT_Y210:
179 return GST_VIDEO_FORMAT_Y210;
180 case DXGI_FORMAT_Y410:
181 return GST_VIDEO_FORMAT_Y410;
182 case DXGI_FORMAT_NV12:
183 return GST_VIDEO_FORMAT_NV12;
184 case DXGI_FORMAT_P010:
185 return GST_VIDEO_FORMAT_P010_10LE;
186 case DXGI_FORMAT_P016:
187 return GST_VIDEO_FORMAT_P016_LE;
188 default:
189 break;
190 }
191
192 return GST_VIDEO_FORMAT_UNKNOWN;
193 }
194