2 * gstvaapiimageformat.c - VA image format abstraction
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
5 * Copyright (C) 2011 Intel Corporation
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
24 * SECTION:gstvaapiimageformat
25 * @short_description: VA image format abstraction
29 #include <gst/video/video.h>
30 #include "gstvaapicompat.h"
31 #include "gstvaapiimageformat.h"
33 typedef enum _GstVaapiImageFormatType GstVaapiImageFormatType;
34 typedef struct _GstVaapiImageFormatMap GstVaapiImageFormatMap;
36 enum _GstVaapiImageFormatType {
37 GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR = 1, /* YUV */
38 GST_VAAPI_IMAGE_FORMAT_TYPE_RGB, /* RGB */
39 GST_VAAPI_IMAGE_FORMAT_TYPE_INDEXED /* paletted */
42 struct _GstVaapiImageFormatMap {
43 GstVaapiImageFormatType type;
44 GstVaapiImageFormat format;
46 VAImageFormat va_format;
49 #define DEF(TYPE, FORMAT, CAPS_STR) \
50 GST_VAAPI_IMAGE_FORMAT_TYPE_##TYPE, \
51 GST_VAAPI_IMAGE_##FORMAT, \
53 #define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP) \
54 { DEF(YCBCR, FORMAT, GST_VIDEO_CAPS_YUV(#FORMAT)), \
55 { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, }
56 #define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \
57 { DEF(RGB, FORMAT, GST_VIDEO_CAPS_##FORMAT), \
58 { VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, }
60 /* Image formats, listed in HW order preference */
61 static const GstVaapiImageFormatMap gst_vaapi_image_formats[] = {
62 DEF_YUV(NV12, ('N','V','1','2'), LSB, 12),
63 DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12),
64 DEF_YUV(I420, ('I','4','2','0'), LSB, 12),
65 DEF_YUV(AYUV, ('A','Y','U','V'), LSB, 32),
66 #if G_BYTE_ORDER == G_BIG_ENDIAN
67 DEF_RGB(ARGB, ('A','R','G','B'), MSB, 32,
68 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000),
69 DEF_RGB(ABGR, ('A','B','G','R'), MSB, 32,
70 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
71 #elif G_BYTE_ORDER == G_LITTLE_ENDIAN
72 DEF_RGB(BGRA, ('B','G','R','A'), LSB, 32,
73 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000),
74 DEF_RGB(RGBA, ('R','G','B','A'), LSB, 32,
75 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
84 static inline gboolean
85 match_va_format_rgb(const VAImageFormat *fmt1, const VAImageFormat *fmt2)
87 return (fmt1->byte_order == fmt2->byte_order &&
88 fmt1->red_mask == fmt2->red_mask &&
89 fmt1->green_mask == fmt2->green_mask &&
90 fmt1->blue_mask == fmt2->blue_mask &&
91 fmt1->alpha_mask == fmt2->alpha_mask);
94 static const GstVaapiImageFormatMap *
95 get_map(GstVaapiImageFormat format)
97 const GstVaapiImageFormatMap *m;
99 for (m = gst_vaapi_image_formats; m->format; m++)
100 if (m->format == format)
106 * gst_vaapi_image_format_is_rgb:
107 * @format: a #GstVaapiImageFormat
109 * Checks whether the format is an RGB format.
111 * Return value: %TRUE if @format is RGB format
114 gst_vaapi_image_format_is_rgb(GstVaapiImageFormat format)
116 const GstVaapiImageFormatMap * const m = get_map(format);
118 return m ? (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB) : FALSE;
122 * gst_vaapi_image_format_is_yuv:
123 * @format: a #GstVaapiImageFormat
125 * Checks whether the format is an YUV format.
127 * Return value: %TRUE if @format is YUV format
130 gst_vaapi_image_format_is_yuv(GstVaapiImageFormat format)
132 const GstVaapiImageFormatMap * const m = get_map(format);
134 return m ? (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR) : FALSE;
138 * gst_vaapi_image_format:
139 * @va_format: a #VAImageFormat
141 * Converts a VA image format into the corresponding #GstVaapiImageFormat.
142 * If the image format cannot be represented by #GstVaapiImageFormat,
143 * then zero is returned.
145 * Return value: the #GstVaapiImageFormat describing the @va_format
148 gst_vaapi_image_format(const VAImageFormat *va_format)
150 const GstVaapiImageFormatMap *m;
152 for (m = gst_vaapi_image_formats; m->format; m++)
153 if (m->va_format.fourcc == va_format->fourcc &&
154 (m->type == GST_VAAPI_IMAGE_FORMAT_TYPE_RGB ?
155 match_va_format_rgb(&m->va_format, va_format) :
163 * gst_vaapi_image_format_from_caps:
166 * Converts @caps into the corresponding #GstVaapiImageFormat. If the
167 * image format cannot be represented by #GstVaapiImageFormat, then
170 * Return value: the #GstVaapiImageFormat describing the @caps
173 gst_vaapi_image_format_from_caps(GstCaps *caps)
175 const GstVaapiImageFormatMap *m;
176 GstStructure *structure;
177 VAImageFormat *va_format, va_formats[2];
178 gint endian, rmask, gmask, bmask, amask = 0;
184 structure = gst_caps_get_structure(caps, 0);
188 /* Check for YUV format */
189 if (gst_structure_get_fourcc(structure, "format", &fourcc))
190 return gst_vaapi_image_format_from_fourcc(fourcc);
192 /* Check for RGB format */
193 gst_structure_get_int(structure, "endianness", &endian);
194 gst_structure_get_int(structure, "red_mask", &rmask);
195 gst_structure_get_int(structure, "green_mask", &gmask);
196 gst_structure_get_int(structure, "blue_mask", &bmask);
197 gst_structure_get_int(structure, "alpha_mask", &amask);
199 va_format = &va_formats[0];
200 va_format->byte_order = endian == G_BIG_ENDIAN ? VA_MSB_FIRST : VA_LSB_FIRST;
201 va_format->red_mask = rmask;
202 va_format->green_mask = gmask;
203 va_format->blue_mask = bmask;
204 va_format->alpha_mask = amask;
206 va_format = &va_formats[1];
207 va_format->byte_order = endian == G_BIG_ENDIAN ? VA_LSB_FIRST : VA_MSB_FIRST;
208 va_format->red_mask = GUINT32_SWAP_LE_BE(rmask);
209 va_format->green_mask = GUINT32_SWAP_LE_BE(gmask);
210 va_format->blue_mask = GUINT32_SWAP_LE_BE(bmask);
211 va_format->alpha_mask = GUINT32_SWAP_LE_BE(amask);
213 for (m = gst_vaapi_image_formats; m->format; m++)
214 if (match_va_format_rgb(&m->va_format, &va_formats[0]) ||
215 match_va_format_rgb(&m->va_format, &va_formats[1]))
222 * gst_vaapi_image_format_from_fourcc:
223 * @fourcc: a FOURCC value
225 * Converts a FOURCC value into the corresponding #GstVaapiImageFormat.
226 * If the image format cannot be represented by #GstVaapiImageFormat,
227 * then zero is returned.
229 * Return value: the #GstVaapiImageFormat describing the FOURCC value
232 gst_vaapi_image_format_from_fourcc(guint32 fourcc)
234 return (GstVaapiImageFormat)fourcc;
238 * gst_vaapi_image_format_from_video:
239 * @format: a #GstVideoFormat
241 * Converts a #GstVideoFormat into the corresponding
242 * #GstVaapiImageFormat. If the image format cannot be represented by
243 * #GstVaapiImageFormat, then zero is returned.
245 * Return value: the #GstVaapiImageFormat describing the video format
248 gst_vaapi_image_format_from_video(GstVideoFormat format)
250 GstVaapiImageFormat va_format;
253 case GST_VIDEO_FORMAT_NV12: va_format = GST_VAAPI_IMAGE_NV12; break;
254 case GST_VIDEO_FORMAT_YV12: va_format = GST_VAAPI_IMAGE_YV12; break;
255 case GST_VIDEO_FORMAT_I420: va_format = GST_VAAPI_IMAGE_I420; break;
256 case GST_VIDEO_FORMAT_AYUV: va_format = GST_VAAPI_IMAGE_AYUV; break;
257 case GST_VIDEO_FORMAT_ARGB: va_format = GST_VAAPI_IMAGE_ARGB; break;
258 case GST_VIDEO_FORMAT_RGBA: va_format = GST_VAAPI_IMAGE_RGBA; break;
259 case GST_VIDEO_FORMAT_ABGR: va_format = GST_VAAPI_IMAGE_ABGR; break;
260 case GST_VIDEO_FORMAT_BGRA: va_format = GST_VAAPI_IMAGE_BGRA; break;
261 default: va_format = (GstVaapiImageFormat)0; break;
267 * gst_vaapi_image_format_get_va_format:
268 * @format: a #GstVaapiImageFormat
270 * Converts a #GstVaapiImageFormat into the corresponding VA image
271 * format. If no matching VA image format was found, %NULL is returned
272 * and this error must be reported to be fixed.
274 * Return value: the VA image format, or %NULL if none was found
276 const VAImageFormat *
277 gst_vaapi_image_format_get_va_format(GstVaapiImageFormat format)
279 const GstVaapiImageFormatMap * const m = get_map(format);
281 return m ? &m->va_format : NULL;
285 * gst_vaapi_image_format_get_caps:
286 * @format: a #GstVaapiImageFormat
288 * Converts a #GstVaapiImageFormat into the corresponding #GstCaps. If
289 * no matching caps were found, %NULL is returned.
291 * Return value: the newly allocated #GstCaps, or %NULL if none was found
294 gst_vaapi_image_format_get_caps(GstVaapiImageFormat format)
296 const GstVaapiImageFormatMap * const m = get_map(format);
298 return m ? gst_caps_from_string(m->caps_str) : NULL;
302 * gst_vaapi_image_format_get_score:
303 * @format: a #GstVaapiImageFormat
305 * Determines how "native" is this @format. The lower is the returned
306 * score, the best format this is for the underlying hardware.
308 * Return value: the @format score, or %G_MAXUINT if none was found
311 gst_vaapi_image_format_get_score(GstVaapiImageFormat format)
313 const GstVaapiImageFormatMap * const m = get_map(format);
315 return m ? (m - &gst_vaapi_image_formats[0]) : G_MAXUINT;