ab70c1adef9397e864fff301bf258c67c6bac460
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / gst-libs / gst / d3d11 / gstd3d11format.cpp
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 *
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
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
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
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 }