qt: playlist: use item title if available
[vlc.git] / src / misc / fourcc.c
blob40aecdc1a7db887b33e3654fb7847ed5231ef858
1 /*****************************************************************************
2 * fourcc.c: fourcc helpers functions
3 *****************************************************************************
4 * Copyright © 2009-2011 Laurent Aimar
6 * Authors: Laurent Aimar <fenrir@videolan.org>
7 * Jean-Baptiste Kempf <jb@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program 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
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #include <vlc_common.h>
32 #include <vlc_fourcc.h>
33 #include <vlc_es.h>
34 #include <assert.h>
36 #include "fourcc_tables.h"
38 static int fourcc_cmp(const void *key, const void *ent)
40 return memcmp(key, ent, 4);
43 static vlc_fourcc_t Lookup(vlc_fourcc_t fourcc, const char **restrict dsc,
44 const struct fourcc_mapping *mapv, size_t mapc,
45 const struct fourcc_desc *dscv, size_t dscc)
47 const struct fourcc_mapping *mapping;
48 const struct fourcc_desc *desc;
50 mapping = bsearch(&fourcc, mapv, mapc, sizeof (*mapv), fourcc_cmp);
51 if (mapping != NULL)
53 if (dsc != NULL)
55 desc = bsearch(&fourcc, dscv, dscc, sizeof (*dscv), fourcc_cmp);
56 if (desc != NULL)
58 *dsc = desc->desc;
59 return mapping->fourcc;
62 fourcc = mapping->fourcc;
65 desc = bsearch(&fourcc, dscv, dscc, sizeof (*dscv), fourcc_cmp);
66 if (desc == NULL)
67 return 0; /* Unknown FourCC */
68 if (dsc != NULL)
69 *dsc = desc->desc;
70 return fourcc; /* Known FourCC (has a description) */
73 static vlc_fourcc_t LookupVideo(vlc_fourcc_t fourcc, const char **restrict dsc)
75 return Lookup(fourcc, dsc, mapping_video, ARRAY_SIZE(mapping_video),
76 desc_video, ARRAY_SIZE(desc_video));
79 static vlc_fourcc_t LookupAudio(vlc_fourcc_t fourcc, const char **restrict dsc)
81 return Lookup(fourcc, dsc, mapping_audio, ARRAY_SIZE(mapping_audio),
82 desc_audio, ARRAY_SIZE(desc_audio));
85 static vlc_fourcc_t LookupSpu(vlc_fourcc_t fourcc, const char **restrict dsc)
87 return Lookup(fourcc, dsc, mapping_spu, ARRAY_SIZE(mapping_spu),
88 desc_spu, ARRAY_SIZE(desc_spu));
91 static vlc_fourcc_t LookupCat(vlc_fourcc_t fourcc, const char **restrict dsc,
92 int cat)
94 switch (cat)
96 case VIDEO_ES:
97 return LookupVideo(fourcc, dsc);
98 case AUDIO_ES:
99 return LookupAudio(fourcc, dsc);
100 case SPU_ES:
101 return LookupSpu(fourcc, dsc);
104 vlc_fourcc_t ret = LookupVideo(fourcc, dsc);
105 if (!ret)
106 ret = LookupAudio(fourcc, dsc);
107 if (!ret)
108 ret = LookupSpu(fourcc, dsc);
109 return ret;
112 vlc_fourcc_t vlc_fourcc_GetCodec(int cat, vlc_fourcc_t fourcc)
114 vlc_fourcc_t codec = LookupCat(fourcc, NULL, cat);
115 return codec ? codec : fourcc;
118 vlc_fourcc_t vlc_fourcc_GetCodecFromString( int i_cat, const char *psz_fourcc )
120 if( !psz_fourcc || strlen(psz_fourcc) != 4 )
121 return 0;
122 return vlc_fourcc_GetCodec( i_cat,
123 VLC_FOURCC( psz_fourcc[0], psz_fourcc[1],
124 psz_fourcc[2], psz_fourcc[3] ) );
127 vlc_fourcc_t vlc_fourcc_GetCodecAudio( vlc_fourcc_t i_fourcc, int i_bits )
129 const int i_bytes = ( i_bits + 7 ) / 8;
131 if( i_fourcc == VLC_FOURCC( 'a', 'f', 'l', 't' ) )
133 switch( i_bytes )
135 case 4:
136 return VLC_CODEC_FL32;
137 case 8:
138 return VLC_CODEC_FL64;
139 default:
140 return 0;
143 else if( i_fourcc == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
145 switch( i_bytes )
147 case 1:
148 return VLC_CODEC_U8;
149 case 2:
150 return VLC_CODEC_S16L;
151 case 3:
152 return VLC_CODEC_S24L;
153 case 4:
154 return VLC_CODEC_S32L;
155 default:
156 return 0;
159 else if( i_fourcc == VLC_FOURCC( 't', 'w', 'o', 's' ) )
161 switch( i_bytes )
163 case 1:
164 return VLC_CODEC_S8;
165 case 2:
166 return VLC_CODEC_S16B;
167 case 3:
168 return VLC_CODEC_S24B;
169 case 4:
170 return VLC_CODEC_S32B;
171 default:
172 return 0;
175 else if( i_fourcc == VLC_FOURCC( 's', 'o', 'w', 't' ) )
177 switch( i_bytes )
179 case 1:
180 return VLC_CODEC_S8;
181 case 2:
182 return VLC_CODEC_S16L;
183 case 3:
184 return VLC_CODEC_S24L;
185 case 4:
186 return VLC_CODEC_S32L;
187 default:
188 return 0;
191 else
193 return vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc );
197 const char *vlc_fourcc_GetDescription(int cat, vlc_fourcc_t fourcc)
199 const char *ret;
201 return LookupCat(fourcc, &ret, cat) ? ret : "";
205 /* */
206 #define VLC_CODEC_YUV_PLANAR_410 \
207 VLC_CODEC_I410, VLC_CODEC_YV9
209 #define VLC_CODEC_YUV_PLANAR_420 \
210 VLC_CODEC_I420, VLC_CODEC_YV12, VLC_CODEC_J420
212 #define VLC_CODEC_YUV_SEMIPLANAR_420 \
213 VLC_CODEC_NV12, VLC_CODEC_NV21
215 #define VLC_CODEC_YUV_PLANAR_420_16 \
216 VLC_CODEC_I420_16L, VLC_CODEC_I420_16B, VLC_CODEC_I420_12L, VLC_CODEC_I420_12B, VLC_CODEC_I420_10L, VLC_CODEC_I420_10B, VLC_CODEC_I420_9L, VLC_CODEC_I420_9B
218 #define VLC_CODEC_YUV_SEMIPLANAR_420_16 \
219 VLC_CODEC_P010, VLC_CODEC_P016
221 #define VLC_CODEC_YUV_PLANAR_422 \
222 VLC_CODEC_I422, VLC_CODEC_J422
224 #define VLC_CODEC_YUV_SEMIPLANAR_422 \
225 VLC_CODEC_NV16, VLC_CODEC_NV61
227 #define VLC_CODEC_YUV_PLANAR_422_16 \
228 VLC_CODEC_I422_12L, VLC_CODEC_I422_12B, VLC_CODEC_I422_10L, VLC_CODEC_I422_10B, VLC_CODEC_I422_9L, VLC_CODEC_I422_9B
230 #define VLC_CODEC_YUV_PLANAR_440 \
231 VLC_CODEC_I440, VLC_CODEC_J440
233 #define VLC_CODEC_YUV_PLANAR_444 \
234 VLC_CODEC_I444, VLC_CODEC_J444
236 #define VLC_CODEC_YUV_PLANAR_444_ALPHA \
237 VLC_CODEC_YUVA, VLC_CODEC_YUVA_444_10L, VLC_CODEC_YUVA_444_10B
239 #define VLC_CODEC_YUV_SEMIPLANAR_444 \
240 VLC_CODEC_NV24, VLC_CODEC_NV42
242 #define VLC_CODEC_YUV_PLANAR_444_16 \
243 VLC_CODEC_I444_10L, VLC_CODEC_I444_10B, VLC_CODEC_I444_9L, VLC_CODEC_I444_9B, \
244 VLC_CODEC_I444_16L, VLC_CODEC_I444_16B, VLC_CODEC_I444_12L, VLC_CODEC_I444_12B
246 #define VLC_CODEC_YUV_PACKED \
247 VLC_CODEC_YUYV, VLC_CODEC_YVYU, \
248 VLC_CODEC_UYVY, VLC_CODEC_VYUY, \
249 VLC_CODEC_VUYA, VLC_CODEC_Y210, \
250 VLC_CODEC_Y410
252 #define VLC_CODEC_FALLBACK_420 \
253 VLC_CODEC_YUV_PLANAR_422, VLC_CODEC_YUV_PACKED, \
254 VLC_CODEC_YUV_PLANAR_444, VLC_CODEC_YUV_PLANAR_440, \
255 VLC_CODEC_I411, VLC_CODEC_YUV_PLANAR_410, VLC_CODEC_Y211
257 static const vlc_fourcc_t p_I420_fallback[] = {
258 VLC_CODEC_I420, VLC_CODEC_YV12, VLC_CODEC_J420, VLC_CODEC_FALLBACK_420, 0
260 static const vlc_fourcc_t p_J420_fallback[] = {
261 VLC_CODEC_J420, VLC_CODEC_I420, VLC_CODEC_YV12, VLC_CODEC_FALLBACK_420, 0
263 static const vlc_fourcc_t p_YV12_fallback[] = {
264 VLC_CODEC_YV12, VLC_CODEC_I420, VLC_CODEC_J420, VLC_CODEC_FALLBACK_420, 0
266 static const vlc_fourcc_t p_NV12_fallback[] = {
267 VLC_CODEC_NV12, VLC_CODEC_I420, VLC_CODEC_J420, VLC_CODEC_FALLBACK_420, 0
270 #define VLC_CODEC_FALLBACK_420_16 \
271 VLC_CODEC_I420, VLC_CODEC_YV12, VLC_CODEC_J420, VLC_CODEC_FALLBACK_420
273 static const vlc_fourcc_t p_I420_9L_fallback[] = {
274 VLC_CODEC_I420_9L, VLC_CODEC_I420_9B, VLC_CODEC_FALLBACK_420_16, 0
276 static const vlc_fourcc_t p_I420_9B_fallback[] = {
277 VLC_CODEC_I420_9B, VLC_CODEC_I420_9L, VLC_CODEC_FALLBACK_420_16, 0
279 static const vlc_fourcc_t p_I420_10L_fallback[] = {
280 VLC_CODEC_I420_10L, VLC_CODEC_I420_10B, VLC_CODEC_FALLBACK_420_16, 0
282 static const vlc_fourcc_t p_I420_10B_fallback[] = {
283 VLC_CODEC_I420_10B, VLC_CODEC_I420_10L, VLC_CODEC_FALLBACK_420_16, 0
285 static const vlc_fourcc_t p_I420_12L_fallback[] = {
286 VLC_CODEC_I420_12L, VLC_CODEC_I420_12B, VLC_CODEC_FALLBACK_420_16, 0
288 static const vlc_fourcc_t p_I420_12B_fallback[] = {
289 VLC_CODEC_I420_12B, VLC_CODEC_I420_12L, VLC_CODEC_FALLBACK_420_16, 0
291 static const vlc_fourcc_t p_I420_16L_fallback[] = {
292 VLC_CODEC_I420_16L, VLC_CODEC_I420_16B, VLC_CODEC_FALLBACK_420_16, 0
294 static const vlc_fourcc_t p_I420_16B_fallback[] = {
295 VLC_CODEC_I420_16B, VLC_CODEC_I420_16L, VLC_CODEC_FALLBACK_420_16, 0
297 static const vlc_fourcc_t p_P010_fallback[] = {
298 VLC_CODEC_P010, VLC_CODEC_FALLBACK_420_16, 0
302 #define VLC_CODEC_FALLBACK_422 \
303 VLC_CODEC_YUV_PACKED, VLC_CODEC_YUV_PLANAR_420, \
304 VLC_CODEC_YUV_PLANAR_444, VLC_CODEC_YUV_PLANAR_440, \
305 VLC_CODEC_I411, VLC_CODEC_YUV_PLANAR_410, VLC_CODEC_Y211
307 static const vlc_fourcc_t p_I422_fallback[] = {
308 VLC_CODEC_I422, VLC_CODEC_J422, VLC_CODEC_FALLBACK_422, 0
310 static const vlc_fourcc_t p_J422_fallback[] = {
311 VLC_CODEC_J422, VLC_CODEC_I422, VLC_CODEC_FALLBACK_422, 0
314 #define VLC_CODEC_FALLBACK_422_16 \
315 VLC_CODEC_I422, VLC_CODEC_J422, VLC_CODEC_FALLBACK_422
317 static const vlc_fourcc_t p_I422_9L_fallback[] = {
318 VLC_CODEC_I422_9L, VLC_CODEC_I422_9B, VLC_CODEC_FALLBACK_422_16, 0
320 static const vlc_fourcc_t p_I422_9B_fallback[] = {
321 VLC_CODEC_I422_9B, VLC_CODEC_I422_9L, VLC_CODEC_FALLBACK_422_16, 0
323 static const vlc_fourcc_t p_I422_10L_fallback[] = {
324 VLC_CODEC_I422_10L, VLC_CODEC_I422_10B, VLC_CODEC_FALLBACK_422_16, 0
326 static const vlc_fourcc_t p_I422_10B_fallback[] = {
327 VLC_CODEC_I422_10B, VLC_CODEC_I422_10L, VLC_CODEC_FALLBACK_422_16, 0
329 static const vlc_fourcc_t p_I422_12L_fallback[] = {
330 VLC_CODEC_I422_12L, VLC_CODEC_I422_12B, VLC_CODEC_FALLBACK_422_16, 0
332 static const vlc_fourcc_t p_I422_12B_fallback[] = {
333 VLC_CODEC_I422_12B, VLC_CODEC_I422_12L, VLC_CODEC_FALLBACK_422_16, 0
336 #define VLC_CODEC_FALLBACK_444 \
337 VLC_CODEC_YUV_PLANAR_422, VLC_CODEC_YUV_PACKED, \
338 VLC_CODEC_YUV_PLANAR_420, VLC_CODEC_YUV_PLANAR_440, \
339 VLC_CODEC_I411, VLC_CODEC_YUV_PLANAR_410, VLC_CODEC_Y211
341 static const vlc_fourcc_t p_I444_fallback[] = {
342 VLC_CODEC_I444, VLC_CODEC_J444, VLC_CODEC_FALLBACK_444, 0
344 static const vlc_fourcc_t p_J444_fallback[] = {
345 VLC_CODEC_J444, VLC_CODEC_I444, VLC_CODEC_FALLBACK_444, 0
348 #define VLC_CODEC_FALLBACK_444_16 \
349 VLC_CODEC_I444, VLC_CODEC_J444, VLC_CODEC_FALLBACK_444
351 static const vlc_fourcc_t p_I444_9L_fallback[] = {
352 VLC_CODEC_I444_9L, VLC_CODEC_I444_9B, VLC_CODEC_FALLBACK_444_16, 0
354 static const vlc_fourcc_t p_I444_9B_fallback[] = {
355 VLC_CODEC_I444_9B, VLC_CODEC_I444_9L, VLC_CODEC_FALLBACK_444_16, 0
357 static const vlc_fourcc_t p_I444_10L_fallback[] = {
358 VLC_CODEC_I444_10L, VLC_CODEC_I444_10B, VLC_CODEC_FALLBACK_444_16, 0
360 static const vlc_fourcc_t p_I444_10B_fallback[] = {
361 VLC_CODEC_I444_10B, VLC_CODEC_I444_10L, VLC_CODEC_FALLBACK_444_16, 0
363 static const vlc_fourcc_t p_I444_12L_fallback[] = {
364 VLC_CODEC_I444_12L, VLC_CODEC_I444_12B, VLC_CODEC_FALLBACK_444_16, 0
366 static const vlc_fourcc_t p_I444_12B_fallback[] = {
367 VLC_CODEC_I444_12B, VLC_CODEC_I444_12L, VLC_CODEC_FALLBACK_444_16, 0
369 static const vlc_fourcc_t p_I444_16L_fallback[] = {
370 VLC_CODEC_I444_16L, VLC_CODEC_I444_16B, VLC_CODEC_FALLBACK_444_16, 0
372 static const vlc_fourcc_t p_I444_16B_fallback[] = {
373 VLC_CODEC_I444_16B, VLC_CODEC_I444_16L, VLC_CODEC_FALLBACK_444_16, 0
377 /* Fallbacks for cvpx */
378 static const vlc_fourcc_t p_CVPX_VIDEO_NV12_fallback[] = {
379 VLC_CODEC_CVPX_NV12, VLC_CODEC_NV12, VLC_CODEC_I420, 0,
381 static const vlc_fourcc_t p_CVPX_VIDEO_UYVY_fallback[] = {
382 VLC_CODEC_CVPX_UYVY, VLC_CODEC_UYVY, 0,
384 static const vlc_fourcc_t p_CVPX_VIDEO_I420_fallback[] = {
385 VLC_CODEC_CVPX_I420, VLC_CODEC_I420, 0,
387 static const vlc_fourcc_t p_CVPX_VIDEO_BGRA_fallback[] = {
388 VLC_CODEC_CVPX_BGRA, VLC_CODEC_BGRA, 0,
390 static const vlc_fourcc_t p_CVPX_VIDEO_P010_fallback[] = {
391 VLC_CODEC_CVPX_P010, VLC_CODEC_P010, VLC_CODEC_I420_10L, 0
394 static const vlc_fourcc_t p_VAAPI_420_fallback[] = {
395 VLC_CODEC_VAAPI_420, VLC_CODEC_I420, 0,
398 static const vlc_fourcc_t p_VAAPI_420_10BPP_fallback[] = {
399 VLC_CODEC_VAAPI_420_10BPP, VLC_CODEC_P010, VLC_CODEC_I420_10L, 0,
402 static const vlc_fourcc_t p_D3D9_OPAQUE_fallback[] = {
403 VLC_CODEC_D3D9_OPAQUE, VLC_CODEC_I420, 0,
406 static const vlc_fourcc_t p_D3D9_OPAQUE_10B_fallback[] = {
407 VLC_CODEC_D3D9_OPAQUE_10B, VLC_CODEC_P010, VLC_CODEC_I420_10L, 0,
410 static const vlc_fourcc_t p_D3D11_OPAQUE_fallback[] = {
411 VLC_CODEC_D3D11_OPAQUE, VLC_CODEC_NV12, 0,
414 static const vlc_fourcc_t p_D3D11_OPAQUE_10B_fallback[] = {
415 VLC_CODEC_D3D11_OPAQUE_10B, VLC_CODEC_P010, VLC_CODEC_I420_10L, 0,
418 static const vlc_fourcc_t p_D3D11_OPAQUE_RGBA_fallback[] = {
419 VLC_CODEC_D3D11_OPAQUE_RGBA, VLC_CODEC_RGBA, 0,
422 static const vlc_fourcc_t p_NVDEC_OPAQUE_fallback[] = {
423 VLC_CODEC_NVDEC_OPAQUE, VLC_CODEC_NV12, 0,
426 static const vlc_fourcc_t p_NVDEC_OPAQUE_10B_fallback[] = {
427 VLC_CODEC_NVDEC_OPAQUE_10B,
428 VLC_CODEC_P010,
429 VLC_CODEC_I420_10L, 0,
432 static const vlc_fourcc_t p_NVDEC_OPAQUE_16B_fallback[] = {
433 VLC_CODEC_NVDEC_OPAQUE_16B,
434 VLC_CODEC_P016, VLC_CODEC_P010,
435 VLC_CODEC_I420_16L, VLC_CODEC_I420_12L, VLC_CODEC_I420_10L, 0,
438 static const vlc_fourcc_t p_I440_fallback[] = {
439 VLC_CODEC_I440,
440 VLC_CODEC_YUV_PLANAR_420,
441 VLC_CODEC_YUV_PLANAR_422,
442 VLC_CODEC_YUV_PLANAR_444,
443 VLC_CODEC_YUV_PACKED,
444 VLC_CODEC_I411, VLC_CODEC_YUV_PLANAR_410, VLC_CODEC_Y211, 0
447 #define VLC_CODEC_FALLBACK_PACKED \
448 VLC_CODEC_YUV_PLANAR_422, VLC_CODEC_YUV_PLANAR_420, \
449 VLC_CODEC_YUV_PLANAR_444, VLC_CODEC_YUV_PLANAR_440, \
450 VLC_CODEC_I411, VLC_CODEC_YUV_PLANAR_410, VLC_CODEC_Y211
452 static const vlc_fourcc_t p_YUYV_fallback[] = {
453 VLC_CODEC_YUYV,
454 VLC_CODEC_YVYU,
455 VLC_CODEC_UYVY,
456 VLC_CODEC_VYUY,
457 VLC_CODEC_FALLBACK_PACKED, 0
459 static const vlc_fourcc_t p_YVYU_fallback[] = {
460 VLC_CODEC_YVYU,
461 VLC_CODEC_YUYV,
462 VLC_CODEC_UYVY,
463 VLC_CODEC_VYUY,
464 VLC_CODEC_FALLBACK_PACKED, 0
466 static const vlc_fourcc_t p_UYVY_fallback[] = {
467 VLC_CODEC_UYVY,
468 VLC_CODEC_VYUY,
469 VLC_CODEC_YUYV,
470 VLC_CODEC_YVYU,
471 VLC_CODEC_FALLBACK_PACKED, 0
473 static const vlc_fourcc_t p_VYUY_fallback[] = {
474 VLC_CODEC_VYUY,
475 VLC_CODEC_UYVY,
476 VLC_CODEC_YUYV,
477 VLC_CODEC_YVYU,
478 VLC_CODEC_FALLBACK_PACKED, 0
481 static const vlc_fourcc_t *pp_YUV_fallback[] = {
482 p_YV12_fallback,
483 p_I420_fallback,
484 p_I420_9L_fallback,
485 p_I420_9B_fallback,
486 p_I420_10L_fallback,
487 p_I420_10B_fallback,
488 p_I420_12L_fallback,
489 p_I420_12B_fallback,
490 p_I420_16L_fallback,
491 p_I420_16B_fallback,
492 p_J420_fallback,
493 p_I422_fallback,
494 p_I422_9L_fallback,
495 p_I422_9B_fallback,
496 p_I422_10L_fallback,
497 p_I422_10B_fallback,
498 p_I422_12L_fallback,
499 p_I422_12B_fallback,
500 p_J422_fallback,
501 p_I444_fallback,
502 p_J444_fallback,
503 p_I444_9L_fallback,
504 p_I444_9B_fallback,
505 p_I444_10L_fallback,
506 p_I444_10B_fallback,
507 p_I444_12L_fallback,
508 p_I444_12B_fallback,
509 p_I444_16L_fallback,
510 p_I444_16B_fallback,
511 p_I440_fallback,
512 p_YUYV_fallback,
513 p_YVYU_fallback,
514 p_UYVY_fallback,
515 p_VYUY_fallback,
516 p_NV12_fallback,
517 p_P010_fallback,
518 p_CVPX_VIDEO_NV12_fallback,
519 p_CVPX_VIDEO_UYVY_fallback,
520 p_CVPX_VIDEO_I420_fallback,
521 p_CVPX_VIDEO_P010_fallback,
522 p_VAAPI_420_fallback,
523 p_VAAPI_420_10BPP_fallback,
524 p_D3D9_OPAQUE_fallback,
525 p_D3D9_OPAQUE_10B_fallback,
526 p_D3D11_OPAQUE_fallback,
527 p_D3D11_OPAQUE_10B_fallback,
528 p_NVDEC_OPAQUE_fallback,
529 p_NVDEC_OPAQUE_10B_fallback,
530 p_NVDEC_OPAQUE_16B_fallback,
531 NULL,
534 static const vlc_fourcc_t p_list_YUV[] = {
535 VLC_CODEC_YUV_PLANAR_420,
536 VLC_CODEC_YUV_SEMIPLANAR_420,
537 VLC_CODEC_YUV_PLANAR_422,
538 VLC_CODEC_YUV_SEMIPLANAR_422,
539 VLC_CODEC_YUV_PLANAR_440,
540 VLC_CODEC_YUV_PLANAR_444,
541 VLC_CODEC_YUV_PLANAR_444_ALPHA,
542 VLC_CODEC_YUV_SEMIPLANAR_444,
543 VLC_CODEC_YUV_PACKED,
544 VLC_CODEC_I411, VLC_CODEC_YUV_PLANAR_410, VLC_CODEC_Y211,
545 VLC_CODEC_YUV_PLANAR_420_16,
546 VLC_CODEC_YUV_SEMIPLANAR_420_16,
547 VLC_CODEC_YUV_PLANAR_422_16,
548 VLC_CODEC_YUV_PLANAR_444_16,
549 VLC_CODEC_VDPAU_VIDEO_420,
550 VLC_CODEC_VDPAU_VIDEO_422,
551 VLC_CODEC_VDPAU_VIDEO_444,
552 VLC_CODEC_CVPX_NV12,
553 VLC_CODEC_CVPX_UYVY,
554 VLC_CODEC_CVPX_I420,
555 VLC_CODEC_CVPX_P010,
556 VLC_CODEC_VAAPI_420,
557 VLC_CODEC_VAAPI_420_10BPP,
558 VLC_CODEC_D3D9_OPAQUE,
559 VLC_CODEC_D3D9_OPAQUE_10B,
560 VLC_CODEC_D3D11_OPAQUE,
561 VLC_CODEC_D3D11_OPAQUE_10B,
562 VLC_CODEC_NVDEC_OPAQUE,
563 VLC_CODEC_NVDEC_OPAQUE_10B,
564 VLC_CODEC_NVDEC_OPAQUE_16B,
565 VLC_CODEC_NVDEC_OPAQUE_444,
566 VLC_CODEC_NVDEC_OPAQUE_444_16B,
570 /* */
571 static const vlc_fourcc_t p_RGB32_fallback[] = {
572 VLC_CODEC_RGB32,
573 VLC_CODEC_RGB24,
574 VLC_CODEC_RGB16,
575 VLC_CODEC_RGB15,
576 VLC_CODEC_RGB8,
579 static const vlc_fourcc_t p_RGB24_fallback[] = {
580 VLC_CODEC_RGB24,
581 VLC_CODEC_RGB32,
582 VLC_CODEC_RGB16,
583 VLC_CODEC_RGB15,
584 VLC_CODEC_RGB8,
587 static const vlc_fourcc_t p_RGB16_fallback[] = {
588 VLC_CODEC_RGB16,
589 VLC_CODEC_RGB24,
590 VLC_CODEC_RGB32,
591 VLC_CODEC_RGB15,
592 VLC_CODEC_RGB8,
595 static const vlc_fourcc_t p_RGB15_fallback[] = {
596 VLC_CODEC_RGB15,
597 VLC_CODEC_RGB16,
598 VLC_CODEC_RGB24,
599 VLC_CODEC_RGB32,
600 VLC_CODEC_RGB8,
603 static const vlc_fourcc_t p_RGB8_fallback[] = {
604 VLC_CODEC_RGB8,
605 VLC_CODEC_RGB15,
606 VLC_CODEC_RGB16,
607 VLC_CODEC_RGB24,
608 VLC_CODEC_RGB32,
611 static const vlc_fourcc_t *pp_RGB_fallback[] = {
612 p_RGB32_fallback,
613 p_RGB24_fallback,
614 p_RGB16_fallback,
615 p_RGB15_fallback,
616 p_RGB8_fallback,
617 p_CVPX_VIDEO_BGRA_fallback,
618 p_D3D11_OPAQUE_RGBA_fallback,
620 NULL,
624 /* */
625 static const vlc_fourcc_t *GetFallback( vlc_fourcc_t i_fourcc,
626 const vlc_fourcc_t *pp_fallback[],
627 const vlc_fourcc_t p_list[] )
629 for( unsigned i = 0; pp_fallback[i]; i++ )
631 if( pp_fallback[i][0] == i_fourcc )
632 return pp_fallback[i];
634 return p_list;
637 const vlc_fourcc_t *vlc_fourcc_GetYUVFallback( vlc_fourcc_t i_fourcc )
639 return GetFallback( i_fourcc, pp_YUV_fallback, p_list_YUV );
641 const vlc_fourcc_t *vlc_fourcc_GetRGBFallback( vlc_fourcc_t i_fourcc )
643 return GetFallback( i_fourcc, pp_RGB_fallback, p_RGB32_fallback );
646 const vlc_fourcc_t *vlc_fourcc_GetFallback( vlc_fourcc_t i_fourcc )
648 return vlc_fourcc_IsYUV( i_fourcc)
649 ? vlc_fourcc_GetYUVFallback( i_fourcc )
650 : vlc_fourcc_GetRGBFallback( i_fourcc );
653 bool vlc_fourcc_AreUVPlanesSwapped( vlc_fourcc_t a, vlc_fourcc_t b )
655 static const vlc_fourcc_t pp_swapped[][4] = {
656 { VLC_CODEC_YV12, VLC_CODEC_I420, VLC_CODEC_J420, 0 },
657 { VLC_CODEC_YV9, VLC_CODEC_I410, 0 },
658 { 0 }
661 for( int i = 0; pp_swapped[i][0]; i++ )
663 if( pp_swapped[i][0] == b )
665 vlc_fourcc_t t = a;
666 a = b;
667 b = t;
669 if( pp_swapped[i][0] != a )
670 continue;
671 for( int j = 1; pp_swapped[i][j]; j++ )
673 if( pp_swapped[i][j] == b )
674 return true;
677 return false;
680 bool vlc_fourcc_IsYUV(vlc_fourcc_t fcc)
682 for( unsigned i = 0; p_list_YUV[i]; i++ )
684 if( p_list_YUV[i] == fcc )
685 return true;
687 return false;
690 #define PLANAR(n, w_den, h_den, size, bits) \
691 { .plane_count = n, \
692 .p = { {.w = {1, 1}, .h = {1, 1}}, \
693 {.w = {1,w_den}, .h = {1,h_den}}, \
694 {.w = {1,w_den}, .h = {1,h_den}}, \
695 {.w = {1, 1}, .h = {1, 1}} }, \
696 .pixel_size = size, \
697 .pixel_bits = bits }
699 #define PLANAR_8(n, w_den, h_den) PLANAR(n, w_den, h_den, 1, 8)
700 #define PLANAR_16(n, w_den, h_den, bits) PLANAR(n, w_den, h_den, 2, bits)
702 #define SEMIPLANAR(w_den, h_den, size, bits) \
703 { .plane_count = 2, \
704 .p = { {.w = {1, 1}, .h = {1, 1}}, \
705 {.w = {2,w_den}, .h = {1,h_den}} }, \
706 .pixel_size = size, \
707 .pixel_bits = bits }
709 #define PACKED_FMT(size, bits) \
710 { .plane_count = 1, \
711 .p = { {.w = {1,1}, .h = {1,1}} }, \
712 .pixel_size = size, \
713 .pixel_bits = bits }
715 /* Zero planes for hardware picture handles. Cannot be manipulated directly. */
716 #define FAKE_FMT() \
717 { .plane_count = 0, \
718 .p = { {.w = {1,1}, .h = {1,1}} }, \
719 .pixel_size = 0, \
720 .pixel_bits = 0 }
722 static const struct
724 vlc_fourcc_t p_fourcc[4];
725 vlc_chroma_description_t description;
726 } p_list_chroma_description[] = {
727 { { VLC_CODEC_I411 }, PLANAR_8(3, 4, 1) },
728 { { VLC_CODEC_YUV_PLANAR_410 }, PLANAR_8(3, 4, 4) },
729 { { VLC_CODEC_YUV_PLANAR_420 }, PLANAR_8(3, 2, 2) },
730 { { VLC_CODEC_NV12, VLC_CODEC_NV21 }, SEMIPLANAR(2, 2, 1, 8) },
731 { { VLC_CODEC_YUV_PLANAR_422 }, PLANAR_8(3, 2, 1) },
732 { { VLC_CODEC_NV16, VLC_CODEC_NV61 }, PLANAR_8(2, 1, 1) },
733 { { VLC_CODEC_YUV_PLANAR_440 }, PLANAR_8(3, 1, 2) },
734 { { VLC_CODEC_YUV_PLANAR_444 }, PLANAR_8(3, 1, 1) },
735 { { VLC_CODEC_YUVA }, PLANAR_8(4, 1, 1) },
736 { { VLC_CODEC_YUV420A }, PLANAR_8(4, 2, 2) },
737 { { VLC_CODEC_YUV422A }, PLANAR_8(4, 2, 1) },
739 { { VLC_CODEC_GBR_PLANAR }, PLANAR_8(3, 1, 1) },
740 { { VLC_CODEC_GBR_PLANAR_9L,
741 VLC_CODEC_GBR_PLANAR_9B }, PLANAR_16(3, 1, 1, 9) },
742 { { VLC_CODEC_GBR_PLANAR_10L,
743 VLC_CODEC_GBR_PLANAR_10B }, PLANAR_16(3, 1, 1, 10) },
744 { { VLC_CODEC_GBR_PLANAR_12L,
745 VLC_CODEC_GBR_PLANAR_12B }, PLANAR_16(3, 1, 1, 12) },
746 { { VLC_CODEC_GBR_PLANAR_14L,
747 VLC_CODEC_GBR_PLANAR_14B }, PLANAR_16(3, 1, 1, 14) },
748 { { VLC_CODEC_GBR_PLANAR_16L,
749 VLC_CODEC_GBR_PLANAR_16B }, PLANAR_16(3, 1, 1, 16) },
750 { { VLC_CODEC_GBRA_PLANAR }, PLANAR_8(4, 1, 1) },
751 { { VLC_CODEC_GBRA_PLANAR_10L,
752 VLC_CODEC_GBRA_PLANAR_10B }, PLANAR_16(4, 1, 1, 10) },
753 { { VLC_CODEC_GBRA_PLANAR_12L,
754 VLC_CODEC_GBRA_PLANAR_12B }, PLANAR_16(4, 1, 1, 12) },
755 { { VLC_CODEC_GBRA_PLANAR_16L,
756 VLC_CODEC_GBRA_PLANAR_16B }, PLANAR_16(4, 1, 1, 16) },
758 { { VLC_CODEC_I420_16L,
759 VLC_CODEC_I420_16B }, PLANAR_16(3, 2, 2, 16) },
760 { { VLC_CODEC_I420_12L,
761 VLC_CODEC_I420_12B }, PLANAR_16(3, 2, 2, 12) },
762 { { VLC_CODEC_I420_10L,
763 VLC_CODEC_I420_10B }, PLANAR_16(3, 2, 2, 10) },
764 { { VLC_CODEC_I420_9L,
765 VLC_CODEC_I420_9B }, PLANAR_16(3, 2, 2, 9) },
766 { { VLC_CODEC_I422_16L,
767 VLC_CODEC_I422_16B }, PLANAR_16(3, 2, 1, 16) },
768 { { VLC_CODEC_I422_12L,
769 VLC_CODEC_I422_12B }, PLANAR_16(3, 2, 1, 12) },
770 { { VLC_CODEC_I422_10L,
771 VLC_CODEC_I422_10B }, PLANAR_16(3, 2, 1, 10) },
772 { { VLC_CODEC_I422_9L,
773 VLC_CODEC_I422_9B }, PLANAR_16(3, 2, 1, 9) },
774 { { VLC_CODEC_I444_12L,
775 VLC_CODEC_I444_12B }, PLANAR_16(3, 1, 1, 12) },
776 { { VLC_CODEC_I444_10L,
777 VLC_CODEC_I444_10B }, PLANAR_16(3, 1, 1, 10) },
778 { { VLC_CODEC_I444_9L,
779 VLC_CODEC_I444_9B }, PLANAR_16(3, 1, 1, 9) },
780 { { VLC_CODEC_I444_16L,
781 VLC_CODEC_I444_16B }, PLANAR_16(3, 1, 1, 16) },
782 { { VLC_CODEC_YUVA_444_10L,
783 VLC_CODEC_YUVA_444_10B }, PLANAR_16(4, 1, 1, 10) },
784 { { VLC_CODEC_P010 }, SEMIPLANAR(2, 2, 2, 10) },
785 { { VLC_CODEC_P016 }, SEMIPLANAR(2, 2, 2, 16) },
787 { { VLC_CODEC_YUYV, VLC_CODEC_YVYU,
788 VLC_CODEC_UYVY, VLC_CODEC_VYUY }, PACKED_FMT(2, 16) },
789 { { VLC_CODEC_YUV2 }, PACKED_FMT(2, 16) },
790 { { VLC_CODEC_RGB8, VLC_CODEC_GREY,
791 VLC_CODEC_YUVP, VLC_CODEC_RGBP }, PACKED_FMT(1, 8) },
793 { { VLC_CODEC_GREY_10L,
794 VLC_CODEC_GREY_10B }, PACKED_FMT(2, 10) },
795 { { VLC_CODEC_GREY_12L,
796 VLC_CODEC_GREY_12B }, PACKED_FMT(2, 12) },
797 { { VLC_CODEC_GREY_16L,
798 VLC_CODEC_GREY_16B }, PACKED_FMT(2, 16) },
800 { { VLC_CODEC_RGB15, 0 }, PACKED_FMT(2, 15) },
801 { { VLC_CODEC_RGB12, 0 }, PACKED_FMT(2, 12) },
802 { { VLC_CODEC_RGB16, 0 }, PACKED_FMT(2, 16) },
803 { { VLC_CODEC_RGB24, 0 }, PACKED_FMT(3, 24) },
804 { { VLC_CODEC_RGB32, 0 }, PACKED_FMT(4, 24) },
805 { { VLC_CODEC_RGBA, VLC_CODEC_ARGB,
806 VLC_CODEC_BGRA, VLC_CODEC_RGBA10 }, PACKED_FMT(4, 32) },
807 { { VLC_CODEC_RGBA64, 0 }, PACKED_FMT(8, 64) },
808 { { VLC_CODEC_VUYA, VLC_CODEC_Y210,
809 VLC_CODEC_Y410, 0 }, PACKED_FMT(4, 32) },
811 { { VLC_CODEC_Y211, 0 }, { 1, { {{1,4}, {1,1}} }, 4, 32 } },
812 { { VLC_CODEC_XYZ12, 0 }, PACKED_FMT(6, 48) },
814 { { VLC_CODEC_VDPAU_VIDEO_420, VLC_CODEC_VDPAU_VIDEO_422,
815 VLC_CODEC_VDPAU_VIDEO_444, VLC_CODEC_VDPAU_OUTPUT },
816 FAKE_FMT() },
817 { { VLC_CODEC_ANDROID_OPAQUE, VLC_CODEC_MMAL_OPAQUE,
818 VLC_CODEC_D3D9_OPAQUE, VLC_CODEC_D3D11_OPAQUE },
819 FAKE_FMT() },
820 { { VLC_CODEC_D3D11_OPAQUE_10B, VLC_CODEC_D3D9_OPAQUE_10B,
821 VLC_CODEC_D3D11_OPAQUE_RGBA, VLC_CODEC_D3D11_OPAQUE_BGRA },
822 FAKE_FMT() },
824 { { VLC_CODEC_NVDEC_OPAQUE_16B,
825 VLC_CODEC_NVDEC_OPAQUE_10B, VLC_CODEC_NVDEC_OPAQUE },
826 FAKE_FMT() },
828 { { VLC_CODEC_NVDEC_OPAQUE_444, VLC_CODEC_NVDEC_OPAQUE_444_16B },
829 FAKE_FMT() },
831 { { VLC_CODEC_CVPX_NV12, VLC_CODEC_CVPX_UYVY,
832 VLC_CODEC_CVPX_I420, VLC_CODEC_CVPX_BGRA },
833 FAKE_FMT() },
835 { { VLC_CODEC_CVPX_P010, 0 }, FAKE_FMT() },
837 { { VLC_CODEC_VAAPI_420, VLC_CODEC_VAAPI_420_10BPP },
838 FAKE_FMT() },
840 { { 0 }, FAKE_FMT() }
843 #undef PACKED_FMT
844 #undef PLANAR_16
845 #undef PLANAR_8
846 #undef PLANAR
848 const vlc_chroma_description_t *vlc_fourcc_GetChromaDescription( vlc_fourcc_t i_fourcc )
850 for( unsigned i = 0; p_list_chroma_description[i].p_fourcc[0]; i++ )
852 const vlc_fourcc_t *p_fourcc = p_list_chroma_description[i].p_fourcc;
853 for( unsigned j = 0; j < 4 && p_fourcc[j] != 0; j++ )
855 if( p_fourcc[j] == i_fourcc )
856 return &p_list_chroma_description[i].description;
859 return NULL;