5fd35e3d6e1e794b41953f7f5726329f8a8dcc53
[platform/upstream/gstreamer.git] / subprojects / gstreamer-vaapi / gst-libs / gst / vaapi / video-format.c
1 /*
2  *  video-format.h - Video format helpers for VA-API
3  *
4  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5  *    Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6  *  Copyright (C) 2011-2013 Intel Corporation
7  *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public License
11  *  as published by the Free Software Foundation; either version 2.1
12  *  of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Lesser General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Lesser General Public
20  *  License along with this library; if not, write to the Free
21  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  *  Boston, MA 02110-1301 USA
23  */
24
25 /**
26  * SECTION:videoformat
27  * @short_description: Video format helpers for VA-API
28  */
29
30 #include "sysdeps.h"
31 #include "gstvaapicompat.h"
32 #include "gstvaapisurface.h"
33 #include "video-format.h"
34
35 #define DEBUG 1
36 #include "gst/vaapi/gstvaapidebug.h"
37
38 #if USE_DRM
39 #include <drm_fourcc.h>
40 #endif
41
42 typedef struct _GstVideoFormatMapMap
43 {
44   GstVideoFormat format;
45   uint32_t drm_format;
46   GstVaapiChromaType chroma_type;
47   VAImageFormat va_format;
48 } GstVideoFormatMap;
49
50 #define VA_BYTE_ORDER_NOT_CARE 0
51
52 #if USE_DRM
53 #define MAKE_DRM_FORMAT(DRM_FORMAT) G_PASTE(DRM_FORMAT_,DRM_FORMAT)
54 #else
55 #define MAKE_DRM_FORMAT(DRM_FORMAT) 0
56 #endif
57
58 #define DEF_YUV(BYTE_ORDER, FORMAT, DRM_FORMAT, FOURCC, BPP, SUB)       \
59   { G_PASTE(GST_VIDEO_FORMAT_,FORMAT),                                  \
60     MAKE_DRM_FORMAT(DRM_FORMAT),                                        \
61     G_PASTE(GST_VAAPI_CHROMA_TYPE_YUV,SUB),                             \
62     { VA_FOURCC FOURCC, BYTE_ORDER, BPP, }, }
63
64 #define DEF_RGB(BYTE_ORDER, FORMAT, DRM, FOURCC, BPP, DEPTH, R,G,B,A)   \
65   { G_PASTE(GST_VIDEO_FORMAT_,FORMAT),                                  \
66     MAKE_DRM_FORMAT(DRM),                                               \
67     G_PASTE(GST_VAAPI_CHROMA_TYPE_RGB,BPP),                             \
68     { VA_FOURCC FOURCC, BYTE_ORDER, BPP, DEPTH, R, G, B, A }, }
69
70 /* Image formats, listed in HW order preference */
71 /* XXX: The new added video format must be added to
72  * GST_VAAPI_FORMATS_ALL in header file to make it available to all
73  * vaapi element's pad cap template. */
74 /* *INDENT-OFF* */
75 static const GstVideoFormatMap gst_vaapi_video_default_formats[] = {
76   /* LSB and MSB video formats definitions are unclear and ambiguous.
77    *
78    * For MSB, there is no ambiguity: same order in define, memory and
79    * CPU. For example,
80    *
81    *  RGBA is RGBA in memory and RGBA with channel mask R:0xFF0000
82    *  G:0x00FF0000 B:0x0000FF00 A:0x000000FF in CPU.
83    *
84    * For LSB, CPU's perspective and memory's perspective are
85    * different. For example,
86    *
87    *  RGBA in LSB, from CPU's perspective, it's RGBA order in memory,
88    *  but when it is stored in memory, because CPU's little
89    *  endianness, it will be re-ordered, with mask R:0x000000FF
90    *  G:0x0000FF00 B:0x00FF0000 A:0xFF000000. In other words, from
91    *  memory's perspective, RGBA LSB is equal as ABGR MSB.
92    *
93    * These definitions are mixed used all over the media system and we
94    * need to correct the mapping form VA video format to GStreamer
95    * video format in both manners, especially for RGB format.
96    */
97
98   /* YUV formats */
99   DEF_YUV (VA_BYTE_ORDER_NOT_CARE, NV12, NV12, ('N', 'V', '1', '2'), 12, 420),
100   DEF_YUV (VA_BYTE_ORDER_NOT_CARE, YV12, YVU420, ('Y', 'V', '1', '2'), 12, 420),
101   DEF_YUV (VA_BYTE_ORDER_NOT_CARE, I420, YUV420, ('I', '4', '2', '0'), 12, 420),
102   DEF_YUV (VA_BYTE_ORDER_NOT_CARE, YUY2, YUYV, ('Y', 'U', 'Y', '2'), 16, 422),
103   DEF_YUV (VA_BYTE_ORDER_NOT_CARE, UYVY, UYVY, ('U', 'Y', 'V', 'Y'), 16, 422),
104
105   DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y444, YUV444, ('4', '4', '4', 'P'), 24, 444),
106   DEF_YUV (VA_BYTE_ORDER_NOT_CARE, GRAY8, INVALID, ('Y', '8', '0', '0'), 8, 400),
107
108   DEF_YUV (VA_LSB_FIRST, P010_10LE, P010, ('P', '0', '1', '0'), 24, 420_10BPP),
109   DEF_YUV (VA_LSB_FIRST, P012_LE, P012, ('P', '0', '1', '2'), 24, 420_12BPP),
110   /* AYUV is a clear defined format by doc */
111   DEF_YUV (VA_LSB_FIRST, VUYA, AYUV, ('A', 'Y', 'U', 'V'), 32, 444),
112
113   DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y210, Y210, ('Y', '2', '1', '0'), 32, 422_10BPP),
114   DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y410, Y410, ('Y', '4', '1', '0'), 32, 444_10BPP),
115   DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y212_LE, Y212, ('Y', '2', '1', '2'), 32, 422_12BPP),
116   DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y412_LE, Y412, ('Y', '4', '1', '2'), 32, 444_12BPP),
117
118   /* RGB formats */
119   DEF_RGB (VA_LSB_FIRST, ARGB, BGRA8888, ('A', 'R', 'G', 'B'), 32, 32, 0x0000ff00,
120       0x00ff0000, 0xff000000, 0x000000ff),
121   DEF_RGB (VA_LSB_FIRST, ARGB, BGRA8888, ('B', 'G', 'R', 'A'), 32, 32, 0x0000ff00,
122       0x00ff0000, 0xff000000, 0x000000ff),
123   DEF_RGB (VA_MSB_FIRST, ARGB, BGRA8888, ('A', 'R', 'G', 'B'), 32, 32, 0x00ff0000,
124       0x0000ff00, 0x000000ff, 0xff000000),
125
126   DEF_RGB (VA_LSB_FIRST, xRGB, BGRX8888, ('X', 'R', 'G', 'B'), 32, 24, 0x0000ff00,
127       0x00ff0000, 0xff000000, 0x00000000),
128   DEF_RGB (VA_LSB_FIRST, xRGB, BGRX8888, ('B', 'G', 'R', 'X'), 32, 24, 0x0000ff00,
129       0x00ff0000, 0xff000000, 0x00000000),
130   DEF_RGB (VA_MSB_FIRST, xRGB, BGRX8888, ('X', 'R', 'G', 'B'), 32, 24, 0x00ff0000,
131       0x0000ff00, 0x000000ff, 0x00000000),
132
133   DEF_RGB (VA_LSB_FIRST, RGBA, ABGR8888, ('R', 'G', 'B', 'A'), 32, 32, 0x000000ff,
134       0x0000ff00, 0x00ff0000, 0xff000000),
135   DEF_RGB (VA_LSB_FIRST, RGBA, ABGR8888, ('A', 'B', 'G', 'R'), 32, 32, 0x000000ff,
136       0x0000ff00, 0x00ff0000, 0xff000000),
137   DEF_RGB (VA_MSB_FIRST, RGBA, ABGR8888, ('R', 'G', 'B', 'A'), 32, 32, 0xff000000,
138       0x00ff0000, 0x0000ff00, 0x000000ff),
139
140   DEF_RGB (VA_LSB_FIRST, RGBx, XBGR8888, ('R', 'G', 'B', 'X'), 32, 24, 0x000000ff,
141       0x0000ff00, 0x00ff0000, 0x00000000),
142   DEF_RGB (VA_LSB_FIRST, RGBx, XBGR8888, ('X', 'B', 'G', 'R'), 32, 24, 0x000000ff,
143       0x0000ff00, 0x00ff0000, 0x00000000),
144   DEF_RGB (VA_MSB_FIRST, RGBx, XBGR8888, ('R', 'G', 'B', 'X'), 32, 24, 0xff000000,
145       0x00ff0000, 0x0000ff00, 0x00000000),
146
147   DEF_RGB (VA_LSB_FIRST, ABGR, RGBA8888, ('A', 'B', 'G', 'R'), 32, 32, 0xff000000,
148       0x00ff0000, 0x0000ff00, 0x000000ff),
149   DEF_RGB (VA_LSB_FIRST, ABGR, RGBA8888, ('R', 'G', 'B', 'A'), 32, 32, 0xff000000,
150       0x00ff0000, 0x0000ff00, 0x000000ff),
151   DEF_RGB (VA_MSB_FIRST, ABGR, RGBA8888, ('A', 'B', 'G', 'R'), 32, 32, 0x000000ff,
152       0x0000ff00, 0x00ff0000, 0xff000000),
153
154   DEF_RGB (VA_LSB_FIRST, xBGR, RGBX8888, ('X', 'B', 'G', 'R'), 32, 24, 0xff000000,
155       0x00ff0000, 0x0000ff00, 0x00000000),
156   DEF_RGB (VA_LSB_FIRST, xBGR, RGBX8888, ('R', 'G', 'B', 'X'), 32, 24, 0xff000000,
157       0x00ff0000, 0x0000ff00, 0x00000000),
158   DEF_RGB (VA_MSB_FIRST, xBGR, RGBX8888, ('X', 'B', 'G', 'R'), 32, 24, 0x000000ff,
159       0x0000ff00, 0x00ff0000, 0x00000000),
160
161   DEF_RGB (VA_LSB_FIRST, BGRA, ARGB8888, ('B', 'G', 'R', 'A'), 32, 32, 0x00ff0000,
162       0x0000ff00, 0x000000ff, 0xff000000),
163   DEF_RGB (VA_LSB_FIRST, BGRA, ARGB8888, ('A', 'R', 'G', 'B'), 32, 32, 0x00ff0000,
164       0x0000ff00, 0x000000ff, 0xff000000),
165   DEF_RGB (VA_MSB_FIRST, BGRA, ARGB8888, ('B', 'G', 'R', 'A'), 32, 32, 0x0000ff00,
166       0x00ff0000, 0xff000000, 0x000000ff),
167
168   DEF_RGB (VA_LSB_FIRST, BGRx, XRGB8888, ('B', 'G', 'R', 'X'), 32, 24, 0x00ff0000,
169       0x0000ff00, 0x000000ff, 0x00000000),
170   DEF_RGB (VA_LSB_FIRST, BGRx, XRGB8888, ('X', 'R', 'G', 'B'), 32, 24, 0x00ff0000,
171       0x0000ff00, 0x000000ff, 0x00000000),
172   DEF_RGB (VA_MSB_FIRST, BGRx, XRGB8888, ('B', 'G', 'R', 'X'), 32, 24, 0x0000ff00,
173       0x00ff0000, 0xff000000, 0x00000000),
174
175   DEF_RGB (VA_BYTE_ORDER_NOT_CARE, RGB16, RGB565, ('R', 'G', '1', '6'), 16, 16,
176       0x0000f800, 0x000007e0, 0x0000001f, 0x00000000),
177   DEF_RGB (VA_BYTE_ORDER_NOT_CARE, RGB, RGB888, ('R', 'G', '2', '4'), 32, 24,
178       0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000),
179   DEF_RGB (VA_LSB_FIRST, BGR10A2_LE, ARGB2101010, ('A', 'R', '3', '0'), 32, 30,
180       0x3ff00000, 0x000ffc00, 0x000003ff, 0x30000000),
181   {0,}
182 };
183 /* *INDENT-ON* */
184
185 #undef DEF_RGB
186 #undef DEF_YUV
187
188 static GArray *gst_vaapi_video_formats_map = NULL;
189
190 static inline gboolean
191 va_format_is_rgb (const VAImageFormat * va_format)
192 {
193   return va_format->depth != 0;
194 }
195
196 static inline gboolean
197 va_format_is_yuv (const VAImageFormat * va_format)
198 {
199   return va_format->depth == 0;
200 }
201
202 static inline gboolean
203 va_format_is_same_rgb (const VAImageFormat * fmt1, const VAImageFormat * fmt2)
204 {
205   return (fmt1->red_mask == fmt2->red_mask &&
206       fmt1->green_mask == fmt2->green_mask &&
207       fmt1->blue_mask == fmt2->blue_mask &&
208       fmt1->alpha_mask == fmt2->alpha_mask);
209 }
210
211 static inline gboolean
212 va_format_is_same (const VAImageFormat * fmt1, const VAImageFormat * fmt2)
213 {
214   if (fmt1->fourcc != fmt2->fourcc)
215     return FALSE;
216   if (fmt1->byte_order != VA_BYTE_ORDER_NOT_CARE &&
217       fmt2->byte_order != VA_BYTE_ORDER_NOT_CARE &&
218       fmt1->byte_order != fmt2->byte_order)
219     return FALSE;
220
221   return va_format_is_rgb (fmt1) ? va_format_is_same_rgb (fmt1, fmt2) : TRUE;
222 }
223
224 static const GstVideoFormatMap *
225 get_map_in_default_by_gst_format (GstVideoFormat format)
226 {
227   const GstVideoFormatMap *m;
228   for (m = gst_vaapi_video_default_formats; m->format; m++) {
229     if (m->format == format)
230       return m;
231   }
232   return NULL;
233 }
234
235 static const GstVideoFormatMap *
236 get_map_in_default_by_va_format (const VAImageFormat * va_format)
237 {
238   const GstVideoFormatMap *m, *n;
239
240   n = NULL;
241   for (m = gst_vaapi_video_default_formats; m->format; m++) {
242     if (va_format_is_same (&m->va_format, va_format)) {
243       /* Should not map to VAImageFormat to same GstVideoFormat */
244       g_assert (n == NULL);
245       n = m;
246     }
247   }
248   return n;
249 }
250
251 static const GstVideoFormatMap *
252 get_map_by_gst_format (const GArray * formats, GstVideoFormat format)
253 {
254   const GstVideoFormatMap *entry;
255   guint i;
256
257   if (!formats)
258     return NULL;
259
260   for (i = 0; i < formats->len; i++) {
261     entry = &g_array_index (formats, GstVideoFormatMap, i);
262     if (entry->format == format)
263       return entry;
264   }
265   return NULL;
266 }
267
268 static const GstVideoFormatMap *
269 get_map_by_va_format (const VAImageFormat * va_format)
270 {
271   const GArray *formats = gst_vaapi_video_formats_map;
272   const GstVideoFormatMap *entry;
273   guint i;
274
275   if (!formats)
276     return NULL;
277
278   for (i = 0; i < formats->len; i++) {
279     entry = &g_array_index (formats, GstVideoFormatMap, i);
280     if (va_format_is_same (&entry->va_format, va_format))
281       return entry;
282   }
283   return NULL;
284 }
285
286
287 static guint
288 get_fmt_score_in_default (GstVideoFormat format)
289 {
290   const GstVideoFormatMap *const m = get_map_in_default_by_gst_format (format);
291
292   return m ? (m - &gst_vaapi_video_default_formats[0]) : G_MAXUINT;
293 }
294
295 static gint
296 video_format_compare_by_score (gconstpointer a, gconstpointer b)
297 {
298   const GstVideoFormatMap *m1 = (GstVideoFormatMap *) a;
299   const GstVideoFormatMap *m2 = (GstVideoFormatMap *) b;
300
301   return ((gint) get_fmt_score_in_default (m1->format) -
302       (gint) get_fmt_score_in_default (m2->format));
303 }
304
305 /**
306  * gst_vaapi_video_format_to_string:
307  * @format: a #GstVideoFormat
308  *
309  * Returns the string representation of the @format argument.
310  *
311  * Return value: string representation of @format, or %NULL if unknown
312  *   or unsupported.
313  */
314 const gchar *
315 gst_vaapi_video_format_to_string (GstVideoFormat format)
316 {
317   return gst_video_format_to_string (format);
318 }
319
320 /**
321  * gst_vaapi_video_format_is_rgb:
322  * @format: a #GstVideoFormat
323  *
324  * Checks whether the format is an RGB format.
325  *
326  * Return value: %TRUE if @format is RGB format
327  */
328 gboolean
329 gst_vaapi_video_format_is_rgb (GstVideoFormat format)
330 {
331   const GstVideoFormatMap *const m =
332       get_map_by_gst_format (gst_vaapi_video_formats_map, format);
333   return m && va_format_is_rgb (&m->va_format);
334 }
335
336 /**
337  * gst_vaapi_video_format_is_yuv:
338  * @format: a #GstVideoFormat
339  *
340  * Checks whether the format is an YUV format.
341  *
342  * Return value: %TRUE if @format is YUV format
343  */
344 gboolean
345 gst_vaapi_video_format_is_yuv (GstVideoFormat format)
346 {
347   const GstVideoFormatMap *const m =
348       get_map_by_gst_format (gst_vaapi_video_formats_map, format);
349   return m && va_format_is_yuv (&m->va_format);
350 }
351
352 /**
353  * gst_vaapi_video_format_from_va_fourcc:
354  * @fourcc: a FOURCC value
355  *
356  * Converts a VA fourcc into the corresponding #GstVideoFormat. If no
357  * matching fourcc was found, then zero is returned.
358  *
359  * Return value: the #GstVideoFormat corresponding to the VA @fourcc
360  */
361 GstVideoFormat
362 gst_vaapi_video_format_from_va_fourcc (guint32 fourcc)
363 {
364   const GArray *map = gst_vaapi_video_formats_map;
365   const GstVideoFormatMap *m;
366   guint i;
367
368   /* Note: VA fourcc values are now standardized and shall represent
369      a unique format. The associated VAImageFormat is just a hint to
370      determine RGBA component ordering */
371   for (i = 0; i < map->len; i++) {
372     m = &g_array_index (map, GstVideoFormatMap, i);
373     if (m->va_format.fourcc == fourcc)
374       return m->format;
375   }
376   return GST_VIDEO_FORMAT_UNKNOWN;
377 }
378
379 /**
380  * gst_vaapi_video_format_from_va_format:
381  * @va_format: a #VAImageFormat
382  *
383  * Converts a VA image format into the corresponding #GstVideoFormat.
384  * If the image format cannot be represented by #GstVideoFormat,
385  * then zero is returned.
386  *
387  * Return value: the #GstVideoFormat describing the @va_format
388  */
389 GstVideoFormat
390 gst_vaapi_video_format_from_va_format (const VAImageFormat * va_format)
391 {
392   const GstVideoFormatMap *const m = get_map_by_va_format (va_format);
393   return m ? m->format : GST_VIDEO_FORMAT_UNKNOWN;
394 }
395
396 /**
397  * gst_vaapi_video_format_to_va_format:
398  * @format: a #GstVideoFormat
399  *
400  * Converts a #GstVideoFormat into the corresponding VA image
401  * format. If no matching VA image format was found, %NULL is returned
402  * and this error must be reported to be fixed.
403  *
404  * Return value: the VA image format, or %NULL if none was found
405  */
406 const VAImageFormat *
407 gst_vaapi_video_format_to_va_format (GstVideoFormat format)
408 {
409   const GstVideoFormatMap *const m =
410       get_map_by_gst_format (gst_vaapi_video_formats_map, format);
411   return m ? &m->va_format : NULL;
412 }
413
414 /**
415  * gst_vaapi_video_format_get_chroma_type:
416  * @format: a #GstVideoFormat
417  *
418  * Converts a #GstVideoFormat into the corresponding #GstVaapiChromaType
419  * format.
420  *
421  * Return value: the #GstVaapiChromaType format, or zero if no match
422  *   was found.
423  */
424 guint
425 gst_vaapi_video_format_get_chroma_type (GstVideoFormat format)
426 {
427   const GstVideoFormatMap *const m =
428       get_map_by_gst_format (gst_vaapi_video_formats_map, format);
429   return m ? m->chroma_type : 0;
430 }
431
432 /**
433  * gst_vaapi_video_format_get_score:
434  * @format: a #GstVideoFormat
435  *
436  * Determines how "native" is this @format. The lower is the returned
437  * score, the best format this is for the underlying hardware.
438  *
439  * Return value: the @format score, or %G_MAXUINT if none was found
440  */
441 guint
442 gst_vaapi_video_format_get_score (GstVideoFormat format)
443 {
444   return get_fmt_score_in_default (format);
445 }
446
447 /**
448  * gst_vaapi_video_format_from_chroma:
449  * @chroma_type: a #GstVaapiChromaType
450  *
451  * Returns the "preferred" pixel format that matches with
452  * @chroma_type.
453  *
454  * Returns: the preferred pixel format for @chroma_type
455  **/
456 GstVideoFormat
457 gst_vaapi_video_format_from_chroma (guint chroma_type)
458 {
459   switch (chroma_type) {
460     case GST_VAAPI_CHROMA_TYPE_YUV422:
461       return GST_VIDEO_FORMAT_YUY2;
462     case GST_VAAPI_CHROMA_TYPE_YUV400:
463       return GST_VIDEO_FORMAT_GRAY8;
464     case GST_VAAPI_CHROMA_TYPE_YUV420:
465     case GST_VAAPI_CHROMA_TYPE_RGB32:  /* GstVideoGLTextureUploadMeta */
466       return GST_VIDEO_FORMAT_NV12;
467     case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP:
468       return GST_VIDEO_FORMAT_P010_10LE;
469     case GST_VAAPI_CHROMA_TYPE_YUV420_12BPP:
470       return GST_VIDEO_FORMAT_P012_LE;
471     case GST_VAAPI_CHROMA_TYPE_YUV444:
472       return GST_VIDEO_FORMAT_VUYA;
473     case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP:
474       return GST_VIDEO_FORMAT_Y210;
475     case GST_VAAPI_CHROMA_TYPE_YUV444_10BPP:
476       return GST_VIDEO_FORMAT_Y410;
477     case GST_VAAPI_CHROMA_TYPE_YUV444_12BPP:
478       return GST_VIDEO_FORMAT_Y412_LE;
479     case GST_VAAPI_CHROMA_TYPE_YUV422_12BPP:
480       return GST_VIDEO_FORMAT_Y212_LE;
481     default:
482       return GST_VIDEO_FORMAT_UNKNOWN;
483   }
484 }
485
486 /**
487  * gst_vaapi_video_format_get_best_native:
488  * @format: a #GstVideoFormat
489  *
490  * Returns the best "native" pixel format that matches a particular
491  * color-space.
492  *
493  * Returns: the #GstVideoFormat with the corresponding best native
494  * format for #GstVaapiSurface
495  **/
496 GstVideoFormat
497 gst_vaapi_video_format_get_best_native (GstVideoFormat format)
498 {
499   GstVaapiChromaType chroma_type;
500
501   if (format == GST_VIDEO_FORMAT_ENCODED)
502     return GST_VIDEO_FORMAT_NV12;
503   chroma_type = gst_vaapi_video_format_get_chroma_type (format);
504   return gst_vaapi_video_format_from_chroma (chroma_type);
505 }
506
507 /**
508  * gst_vaapi_video_format_get_formats_by_chroma:
509  * @chroma: a #GstVaapiChromaType
510  *
511  * Get all #GstVideoFormat which belong to #GstVaapiChromaType.
512  *
513  * Returns: an array of #GstVideoFormat.
514  **/
515 GArray *
516 gst_vaapi_video_format_get_formats_by_chroma (guint chroma)
517 {
518   const GstVideoFormatMap *entry;
519   GArray *formats;
520   guint i;
521
522   formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat));
523   if (!formats)
524     return NULL;
525
526   for (i = 0; i < gst_vaapi_video_formats_map->len; i++) {
527     entry = &g_array_index (gst_vaapi_video_formats_map, GstVideoFormatMap, i);
528     if (entry->chroma_type == chroma)
529       g_array_append_val (formats, entry->format);
530   }
531
532   if (formats->len == 0) {
533     g_array_unref (formats);
534     return NULL;
535   }
536
537   return formats;
538 }
539
540 struct ImageFormatsData
541 {
542   VAImageFormat *formats;
543   guint n;
544 };
545
546 static gpointer
547 video_format_create_map_once (gpointer data)
548 {
549   const GstVideoFormatMap *src_entry, *entry;
550   guint i;
551   VAImageFormat *formats = ((struct ImageFormatsData *) data)->formats;
552   guint n = ((struct ImageFormatsData *) data)->n;
553   GArray *array = NULL;
554
555   array = g_array_new (FALSE, TRUE, sizeof (GstVideoFormatMap));
556   if (array == NULL)
557     return NULL;
558
559   /* All the YUV format has no ambiguity */
560   for (i = 0; i < G_N_ELEMENTS (gst_vaapi_video_default_formats); i++) {
561     if (va_format_is_yuv (&gst_vaapi_video_default_formats[i].va_format))
562       g_array_append_val (array, gst_vaapi_video_default_formats[i]);
563   }
564
565   if (formats) {
566     for (i = 0; i < n; i++) {
567       if (!va_format_is_rgb (&formats[i]))
568         continue;
569
570       src_entry = get_map_in_default_by_va_format (&formats[i]);
571       if (src_entry) {
572         entry = get_map_by_gst_format (array, src_entry->format);
573         if (entry && !va_format_is_same (&entry->va_format, &formats[i])) {
574           GST_INFO ("va_format1 with fourcc %" GST_FOURCC_FORMAT
575               " byte order: %d, BPP: %d, depth %d, red mask 0x%4x,"
576               " green mask 0x%4x, blue mask 0x%4x, alpha mask 0x%4x"
577               " conflict with va_foramt2 fourcc %" GST_FOURCC_FORMAT
578               " byte order: %d, BPP: %d, depth %d, red mask 0x%4x,"
579               " green mask 0x%4x, blue mask 0x%4x, alpha mask 0x%4x."
580               " Both map to the same GST format: %s, which is not"
581               " allowed, va_format1 will be skipped",
582               GST_FOURCC_ARGS (entry->va_format.fourcc),
583               entry->va_format.byte_order, entry->va_format.bits_per_pixel,
584               entry->va_format.depth, entry->va_format.red_mask,
585               entry->va_format.green_mask, entry->va_format.blue_mask,
586               entry->va_format.alpha_mask,
587               GST_FOURCC_ARGS (formats[i].fourcc),
588               formats[i].byte_order, formats[i].bits_per_pixel,
589               formats[i].depth, formats[i].red_mask, formats[i].green_mask,
590               formats[i].blue_mask, formats[i].alpha_mask,
591               gst_video_format_to_string (entry->format));
592           continue;
593         }
594         g_array_append_val (array, (*src_entry));
595       }
596
597       GST_LOG ("%s to map RGB va_format with fourcc: %"
598           GST_FOURCC_FORMAT
599           ", byte order: %d BPP: %d, depth %d, red mask %4x,"
600           " green mask %4x, blue mask %4x, alpha mask %4x to %s gstreamer"
601           " video format", src_entry ? "succeed" : "failed",
602           GST_FOURCC_ARGS (formats[i].fourcc), formats[i].byte_order,
603           formats[i].bits_per_pixel, formats[i].depth, formats[i].red_mask,
604           formats[i].green_mask, formats[i].blue_mask, formats[i].alpha_mask,
605           src_entry ? gst_video_format_to_string (src_entry->format) : "any");
606     }
607   }
608
609   g_array_sort (array, video_format_compare_by_score);
610   gst_vaapi_video_formats_map = array;
611   return array;
612 }
613
614 /**
615  * gst_vaapi_video_format_new_map:
616  * @formats: all #VAImageFormat need to map
617  * @n: the number of VAImageFormat
618  *
619  * Return: True if create successfully.
620  **/
621 gboolean
622 gst_vaapi_video_format_create_map (VAImageFormat * formats, guint n)
623 {
624   static GOnce once = G_ONCE_INIT;
625   struct ImageFormatsData data = { formats, n };
626
627   g_once (&once, video_format_create_map_once, &data);
628
629   return once.retval != NULL;
630 }
631
632 /**
633  * gst_vaapi_drm_format_from_va_fourcc:
634  * @fourcc: a FOURCC value
635  *
636  * Converts a VA fourcc into the corresponding DRM_FORMAT_*. If no
637  * matching fourcc was found, then DRM_FORMAT_INVALID is returned.
638  *
639  * Return value: the DRM_FORMAT_* corresponding to the VA @fourcc
640  *
641  * Since: 1.18
642  */
643 guint
644 gst_vaapi_drm_format_from_va_fourcc (guint32 fourcc)
645 {
646 #if USE_DRM
647   const GArray *map = gst_vaapi_video_formats_map;
648   const GstVideoFormatMap *m;
649   guint i;
650
651   if (!map)
652     return GST_VIDEO_FORMAT_UNKNOWN;
653
654   /* Note: VA fourcc values are now standardized and shall represent
655      a unique format. The associated VAImageFormat is just a hint to
656      determine RGBA component ordering */
657   for (i = 0; i < map->len; i++) {
658     m = &g_array_index (map, GstVideoFormatMap, i);
659     if (m->va_format.fourcc == fourcc)
660       return m->drm_format;
661   }
662   return DRM_FORMAT_INVALID;
663 #else
664   return 0;
665 #endif
666 }
667
668 /**
669  * gst_vaapi_video_format_from_drm_format:
670  * @drm_format: a DRM format value
671  *
672  * Converts a DRM_FORMAT_* to the corresponding GstVideoFormat. If no
673  * matching fourcc was found, then DRM_FORMAT_INVALID is returned.
674  *
675  * Return value: GstVideoFormat corresponding to the @drm_format
676  *
677  * Since: 1.18
678  */
679 GstVideoFormat
680 gst_vaapi_video_format_from_drm_format (guint drm_format)
681 {
682 #if USE_DRM
683   const GArray *map = gst_vaapi_video_formats_map;
684   const GstVideoFormatMap *m;
685   guint i;
686
687   if (!map)
688     return GST_VIDEO_FORMAT_UNKNOWN;
689
690   for (i = 0; i < map->len; i++) {
691     m = &g_array_index (map, GstVideoFormatMap, i);
692     if (m->drm_format == drm_format)
693       return m->format;
694   }
695 #endif
696   return GST_VIDEO_FORMAT_UNKNOWN;
697 }