1 /*
2  *  gstvaapiutils.c - VA-API utilities
3  *
4  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5  *    Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6  *  Copyright (C) 2011-2014 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 #include "sysdeps.h"
26 #include "gstvaapicompat.h"
27 #include "gstvaapiutils.h"
28 #include "gstvaapisurface.h"
29 #include "gstvaapisubpicture.h"
30 #include "gstvaapifilter.h"
31 #include <stdio.h>
32 #include <stdarg.h>
33 
34 #define DEBUG 1
35 #include "gstvaapidebug.h"
36 
37 /* string case an enum */
38 #define STRCASEP(p, x)  STRCASE(G_PASTE(p, x))
39 #define STRCASE(x)      case x: return G_STRINGIFY(x)
40 
41 /* string case a macro */
42 #define STRCASEM(p, x)  case G_PASTE(p, x): return G_STRINGIFY(x)
43 
44 #if VA_CHECK_VERSION (0,40,0)
45 static gchar *
strip_msg(const char * message)46 strip_msg (const char *message)
47 {
48   gchar *msg;
49 
50   msg = g_strdup (message);
51   if (!msg)
52     return NULL;
53   return g_strstrip (msg);
54 }
55 
56 #if VA_CHECK_VERSION (1,0,0)
57 static void
gst_vaapi_err(void * data,const char * message)58 gst_vaapi_err (void *data, const char *message)
59 {
60   gchar *msg;
61 
62   msg = strip_msg (message);
63   if (!msg)
64     return;
65   GST_ERROR ("%s", msg);
66   g_free (msg);
67 }
68 
69 static void
gst_vaapi_warning(void * data,const char * message)70 gst_vaapi_warning (void *data, const char *message)
71 {
72   gchar *msg;
73 
74   msg = strip_msg (message);
75   if (!msg)
76     return;
77   GST_WARNING ("%s", msg);
78   g_free (msg);
79 }
80 #endif
81 
82 static void
gst_vaapi_log(void * data,const char * message)83 gst_vaapi_log (
84 #if VA_CHECK_VERSION (1,0,0)
85     void *data,
86 #endif
87     const char *message)
88 {
89   gchar *msg;
90 
91   msg = strip_msg (message);
92   if (!msg)
93     return;
94   GST_INFO ("%s", msg);
95   g_free (msg);
96 }
97 #endif
98 
99 gboolean
vaapi_initialize(VADisplay dpy)100 vaapi_initialize (VADisplay dpy)
101 {
102   gint major_version, minor_version;
103   VAStatus status;
104 
105 #if VA_CHECK_VERSION (1,0,0)
106   vaSetErrorCallback (dpy, gst_vaapi_warning, NULL);
107   vaSetInfoCallback (dpy, gst_vaapi_log, NULL);
108 #elif VA_CHECK_VERSION (0,40,0)
109   vaSetInfoCallback (gst_vaapi_log);
110 #endif
111 
112   status = vaInitialize (dpy, &major_version, &minor_version);
113 
114 #if VA_CHECK_VERSION (1,0,0)
115   vaSetErrorCallback (dpy, gst_vaapi_err, NULL);
116 #endif
117 
118   if (!vaapi_check_status (status, "vaInitialize()"))
119     return FALSE;
120 
121   GST_INFO ("VA-API version %d.%d", major_version, minor_version);
122   return TRUE;
123 }
124 
125 /* Check VA status for success or print out an error */
126 gboolean
vaapi_check_status(VAStatus status,const gchar * msg)127 vaapi_check_status (VAStatus status, const gchar * msg)
128 {
129   if (status != VA_STATUS_SUCCESS) {
130     GST_DEBUG ("%s: %s", msg, vaErrorStr (status));
131     return FALSE;
132   }
133   return TRUE;
134 }
135 
136 /* Maps VA buffer */
137 gpointer
vaapi_map_buffer(VADisplay dpy,VABufferID buf_id)138 vaapi_map_buffer (VADisplay dpy, VABufferID buf_id)
139 {
140   VAStatus status;
141   gpointer data = NULL;
142 
143   status = vaMapBuffer (dpy, buf_id, &data);
144   if (!vaapi_check_status (status, "vaMapBuffer()"))
145     return NULL;
146   return data;
147 }
148 
149 /* Unmaps VA buffer */
150 void
vaapi_unmap_buffer(VADisplay dpy,VABufferID buf_id,gpointer * pbuf)151 vaapi_unmap_buffer (VADisplay dpy, VABufferID buf_id, gpointer * pbuf)
152 {
153   VAStatus status;
154 
155   if (pbuf)
156     *pbuf = NULL;
157 
158   status = vaUnmapBuffer (dpy, buf_id);
159   if (!vaapi_check_status (status, "vaUnmapBuffer()"))
160     return;
161 }
162 
163 /* Creates and maps VA buffer */
164 gboolean
vaapi_create_buffer(VADisplay dpy,VAContextID ctx,int type,guint size,gconstpointer buf,VABufferID * buf_id_ptr,gpointer * mapped_data)165 vaapi_create_buffer (VADisplay dpy, VAContextID ctx, int type, guint size,
166     gconstpointer buf, VABufferID * buf_id_ptr, gpointer * mapped_data)
167 {
168   VABufferID buf_id;
169   VAStatus status;
170   gpointer data = (gpointer) buf;
171 
172   status = vaCreateBuffer (dpy, ctx, type, size, 1, data, &buf_id);
173   if (!vaapi_check_status (status, "vaCreateBuffer()"))
174     return FALSE;
175 
176   if (mapped_data) {
177     data = vaapi_map_buffer (dpy, buf_id);
178     if (!data)
179       goto error;
180     *mapped_data = data;
181   }
182 
183   *buf_id_ptr = buf_id;
184   return TRUE;
185 
186   /* ERRORS */
187 error:
188   {
189     vaapi_destroy_buffer (dpy, &buf_id);
190     return FALSE;
191   }
192 }
193 
194 /* Destroy VA buffer */
195 void
vaapi_destroy_buffer(VADisplay dpy,VABufferID * buf_id_ptr)196 vaapi_destroy_buffer (VADisplay dpy, VABufferID * buf_id_ptr)
197 {
198   if (!buf_id_ptr || *buf_id_ptr == VA_INVALID_ID)
199     return;
200 
201   vaDestroyBuffer (dpy, *buf_id_ptr);
202   *buf_id_ptr = VA_INVALID_ID;
203 }
204 
205 /* Return a string representation of a VAProfile */
206 const gchar *
string_of_VAProfile(VAProfile profile)207 string_of_VAProfile (VAProfile profile)
208 {
209   switch (profile) {
210 #define MAP(profile) \
211         STRCASEP(VAProfile, profile)
212       MAP (MPEG2Simple);
213       MAP (MPEG2Main);
214       MAP (MPEG4Simple);
215       MAP (MPEG4AdvancedSimple);
216       MAP (MPEG4Main);
217       MAP (JPEGBaseline);
218       MAP (H263Baseline);
219       MAP (H264ConstrainedBaseline);
220 #if !VA_CHECK_VERSION(1,0,0)
221       MAP (H264Baseline);
222 #endif
223       MAP (H264Main);
224       MAP (H264High);
225       MAP (H264MultiviewHigh);
226       MAP (H264StereoHigh);
227 #if VA_CHECK_VERSION(1,2,0)
228       MAP (HEVCMain422_10);
229       MAP (HEVCMain444);
230 #endif
231       MAP (HEVCMain);
232       MAP (HEVCMain10);
233       MAP (VC1Simple);
234       MAP (VC1Main);
235       MAP (VC1Advanced);
236       MAP (VP8Version0_3);
237       MAP (VP9Profile0);
238       MAP (VP9Profile1);
239       MAP (VP9Profile2);
240       MAP (VP9Profile3);
241 #undef MAP
242     default:
243       break;
244   }
245   return "<unknown>";
246 }
247 
248 /* Return a string representation of a VAEntrypoint */
249 const gchar *
string_of_VAEntrypoint(VAEntrypoint entrypoint)250 string_of_VAEntrypoint (VAEntrypoint entrypoint)
251 {
252   switch (entrypoint) {
253 #define MAP(entrypoint) \
254         STRCASEP(VAEntrypoint, entrypoint)
255       MAP (VLD);
256       MAP (IZZ);
257       MAP (IDCT);
258       MAP (MoComp);
259       MAP (Deblocking);
260 #undef MAP
261     default:
262       break;
263   }
264   return "<unknown>";
265 }
266 
267 /* Return a string representation of a VADisplayAttributeType */
268 const gchar *
string_of_VADisplayAttributeType(VADisplayAttribType attribute_type)269 string_of_VADisplayAttributeType (VADisplayAttribType attribute_type)
270 {
271   switch (attribute_type) {
272 #define MAP(attribute_type) \
273         STRCASEP(VADisplayAttrib, attribute_type)
274       MAP (Brightness);
275       MAP (Contrast);
276       MAP (Hue);
277       MAP (Saturation);
278       MAP (BackgroundColor);
279       MAP (Rotation);
280       MAP (OutofLoopDeblock);
281       MAP (CSCMatrix);
282       MAP (BlendColor);
283       MAP (OverlayAutoPaintColorKey);
284       MAP (OverlayColorKey);
285       MAP (RenderMode);
286       MAP (RenderDevice);
287       MAP (RenderRect);
288 #undef MAP
289     default:
290       break;
291   }
292   return "<unknown>";
293 }
294 
295 /* Return a string representation of a VA chroma format */
296 const gchar *
string_of_va_chroma_format(guint chroma_format)297 string_of_va_chroma_format (guint chroma_format)
298 {
299   switch (chroma_format) {
300 #define MAP(value) \
301         STRCASEM(VA_RT_FORMAT_, value)
302       MAP (YUV420);
303       MAP (YUV422);
304       MAP (YUV444);
305       MAP (YUV400);
306       MAP (RGB16);
307       MAP (RGB32);
308       MAP (RGBP);
309       MAP (YUV420_10BPP);
310 #if VA_CHECK_VERSION(1,2,0)
311       MAP (YUV422_10);
312       MAP (YUV444_10);
313       MAP (YUV420_12);
314       MAP (YUV422_12);
315       MAP (YUV444_12);
316       MAP (RGB32_10);
317 #endif
318 #undef MAP
319     default:
320       break;
321   }
322   return "<unknown>";
323 }
324 
325 const gchar *
string_of_VARateControl(guint rate_control)326 string_of_VARateControl (guint rate_control)
327 {
328   switch (rate_control) {
329     case VA_RC_NONE:
330       return "None";
331 #ifdef VA_RC_CQP
332     case VA_RC_CQP:
333       return "CQP";
334 #endif
335     case VA_RC_CBR:
336       return "CBR";
337     case VA_RC_VCM:
338       return "VCM";
339     case VA_RC_VBR:
340       return "VBR";
341 #ifdef VA_RC_VBR_CONSTRAINED
342     case VA_RC_VBR_CONSTRAINED:
343       return "VBR-Constrained";
344 #endif
345     default:
346       break;
347   }
348   return "<unknown>";
349 }
350 
351 /**
352  * to_GstVaapiChromaType:
353  * @va_rt_format: the value of VAConfigAttribRTFormat
354  *
355  * Converts the VA_RT_FORMAT_* to #GstVaapiChromaType
356  *
357  * Returns: the #GstVaapiChromaType associated to @va_rt_format or
358  * zero.
359  **/
360 guint
to_GstVaapiChromaType(guint va_rt_format)361 to_GstVaapiChromaType (guint va_rt_format)
362 {
363   guint chroma_type;
364 
365   switch (va_rt_format) {
366     case VA_RT_FORMAT_YUV420:
367       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
368       break;
369     case VA_RT_FORMAT_YUV422:
370       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
371       break;
372     case VA_RT_FORMAT_YUV444:
373       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
374       break;
375     case VA_RT_FORMAT_YUV411:
376       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV411;
377       break;
378     case VA_RT_FORMAT_YUV400:
379       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400;
380       break;
381     case VA_RT_FORMAT_RGB32:
382       chroma_type = GST_VAAPI_CHROMA_TYPE_RGB32;
383       break;
384     case VA_RT_FORMAT_RGB16:
385       chroma_type = GST_VAAPI_CHROMA_TYPE_RGB16;
386       break;
387     case VA_RT_FORMAT_RGBP:
388       chroma_type = GST_VAAPI_CHROMA_TYPE_RGBP;
389       break;
390     case VA_RT_FORMAT_YUV420_10BPP:
391       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP;
392       break;
393 #if VA_CHECK_VERSION(1,2,0)
394     case VA_RT_FORMAT_YUV422_10:
395       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_10BPP;
396       break;
397     case VA_RT_FORMAT_YUV444_10:
398       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_10BPP;
399       break;
400     case VA_RT_FORMAT_YUV420_12:
401       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_12BPP;
402       break;
403     case VA_RT_FORMAT_YUV422_12:
404       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_12BPP;
405       break;
406     case VA_RT_FORMAT_YUV444_12:
407       chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_12BPP;
408       break;
409     case VA_RT_FORMAT_RGB32_10:
410       chroma_type = GST_VAAPI_CHROMA_TYPE_RGB32_10BPP;
411       break;
412 #endif
413     default:
414       chroma_type = 0;
415       break;
416   }
417   return chroma_type;
418 }
419 
420 /**
421  * from_GstVaapiChromaType:
422  * @chroma_type: the #GstVaapiChromaType
423  *
424  * Converts #GstVaapiChromaType to a chroma format suitable for
425  * vaCreateSurfaces().
426  */
427 guint
from_GstVaapiChromaType(guint chroma_type)428 from_GstVaapiChromaType (guint chroma_type)
429 {
430   guint format;
431 
432   switch (chroma_type) {
433     case GST_VAAPI_CHROMA_TYPE_YUV420:
434       format = VA_RT_FORMAT_YUV420;
435       break;
436     case GST_VAAPI_CHROMA_TYPE_YUV422:
437       format = VA_RT_FORMAT_YUV422;
438       break;
439     case GST_VAAPI_CHROMA_TYPE_YUV444:
440       format = VA_RT_FORMAT_YUV444;
441       break;
442     case GST_VAAPI_CHROMA_TYPE_YUV411:
443       format = VA_RT_FORMAT_YUV411;
444       break;
445     case GST_VAAPI_CHROMA_TYPE_YUV400:
446       format = VA_RT_FORMAT_YUV400;
447       break;
448     case GST_VAAPI_CHROMA_TYPE_RGB32:
449       format = VA_RT_FORMAT_RGB32;
450       break;
451     case GST_VAAPI_CHROMA_TYPE_RGB16:
452       format = VA_RT_FORMAT_RGB16;
453       break;
454     case GST_VAAPI_CHROMA_TYPE_RGBP:
455       format = VA_RT_FORMAT_RGBP;
456       break;
457     case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP:
458       format = VA_RT_FORMAT_YUV420_10BPP;
459       break;
460 #if VA_CHECK_VERSION(1,2,0)
461     case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP:
462       format = VA_RT_FORMAT_YUV422_10;
463       break;
464     case GST_VAAPI_CHROMA_TYPE_YUV444_10BPP:
465       format = VA_RT_FORMAT_YUV444_10;
466       break;
467     case GST_VAAPI_CHROMA_TYPE_YUV420_12BPP:
468       format = VA_RT_FORMAT_YUV420_12;
469       break;
470     case GST_VAAPI_CHROMA_TYPE_YUV422_12BPP:
471       format = VA_RT_FORMAT_YUV422_12;
472       break;
473     case GST_VAAPI_CHROMA_TYPE_YUV444_12BPP:
474       format = VA_RT_FORMAT_YUV444_12;
475       break;
476     case GST_VAAPI_CHROMA_TYPE_RGB32_10BPP:
477       format = VA_RT_FORMAT_RGB32_10;
478       break;
479 #endif
480     default:
481       format = 0;
482       break;
483   }
484   return format;
485 }
486 
487 /**
488  * from_GstVaapiSubpictureFlags:
489  * @flags: the #GstVaapiSubpictureFlags
490  *
491  * Converts #GstVaapiSubpictureFlags to flags suitable for
492  * vaAssociateSubpicture().
493  */
494 guint
from_GstVaapiSubpictureFlags(guint flags)495 from_GstVaapiSubpictureFlags (guint flags)
496 {
497   guint va_flags = 0;
498 
499   if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA)
500     va_flags |= VA_SUBPICTURE_GLOBAL_ALPHA;
501 #ifdef VA_SUBPICTURE_PREMULTIPLIED_ALPHA
502   if (flags & GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA)
503     flags |= VA_SUBPICTURE_PREMULTIPLIED_ALPHA;
504 #endif
505   return va_flags;
506 }
507 
508 /**
509  * to_GstVaapiSubpictureFlags:
510  * @flags: the #GstVaapiSubpictureFlags flags to translate
511  *
512  * Converts vaQuerySubpictureFormats() @flags to #GstVaapiSubpictureFlags
513  * flags.
514  *
515  * Return value: the #GstVaapiSubpictureFlags flags
516  */
517 guint
to_GstVaapiSubpictureFlags(guint va_flags)518 to_GstVaapiSubpictureFlags (guint va_flags)
519 {
520   guint flags = 0;
521 
522   if (va_flags & VA_SUBPICTURE_GLOBAL_ALPHA)
523     flags |= GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA;
524 #ifdef VA_SUBPICTURE_PREMULTIPLIED_ALPHA
525   if (va_flags & VA_SUBPICTURE_PREMULTIPLIED_ALPHA)
526     flags |= GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA;
527 #endif
528   return flags;
529 }
530 
531 /**
532  * from_GstVideoOverlayFormatFlags:
533  * @flags: the #GstVideoOverlayFormatFlags flags to translate
534  *
535  * Converts #GstVaapiSubpictureFlags to #GstVaapiSubpictureFlags.
536  *
537  * Return value: the #GstVaapiSubpictureFlags flags
538  */
539 guint
from_GstVideoOverlayFormatFlags(guint ovl_flags)540 from_GstVideoOverlayFormatFlags (guint ovl_flags)
541 {
542   guint flags = 0;
543 
544   if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA)
545     flags |= GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA;
546   if (ovl_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)
547     flags |= GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA;
548   return flags;
549 }
550 
551 /**
552  * to_GstVideoOverlayFormatFlags:
553  * @flags: the #GstVaapiSubpictureFlags flags to translate
554  *
555  * Converts #GstVaapiSubpictureFlags to #GstVideoOverlayFormatFlags.
556  *
557  * Return value: the #GstVideoOverlayFormatFlags flags
558  */
559 guint
to_GstVideoOverlayFormatFlags(guint flags)560 to_GstVideoOverlayFormatFlags (guint flags)
561 {
562   guint ovl_flags = 0;
563 
564   if (flags & GST_VAAPI_SUBPICTURE_FLAG_PREMULTIPLIED_ALPHA)
565     ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA;
566   if (flags & GST_VAAPI_SUBPICTURE_FLAG_GLOBAL_ALPHA)
567     ovl_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA;
568   return ovl_flags;
569 }
570 
571 /**
572  * from_GstVaapiSurfaceRenderFlags:
573  * @flags: the #GstVaapiSurfaceRenderFlags
574  *
575  * Converts #GstVaapiSurfaceRenderFlags to flags suitable for
576  * vaPutSurface().
577  */
578 guint
from_GstVaapiSurfaceRenderFlags(guint flags)579 from_GstVaapiSurfaceRenderFlags (guint flags)
580 {
581   guint va_fields, va_csc;
582 
583   /* Picture structure */
584   switch (flags & GST_VAAPI_PICTURE_STRUCTURE_MASK) {
585     case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
586       va_fields = VA_TOP_FIELD;
587       break;
588     case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
589       va_fields = VA_BOTTOM_FIELD;
590       break;
591     default:
592       va_fields = VA_FRAME_PICTURE;
593       break;
594   }
595 
596   /* Color standard */
597   switch (flags & GST_VAAPI_COLOR_STANDARD_MASK) {
598 #ifdef VA_SRC_BT601
599     case GST_VAAPI_COLOR_STANDARD_ITUR_BT_601:
600       va_csc = VA_SRC_BT601;
601       break;
602 #endif
603 #ifdef VA_SRC_BT709
604     case GST_VAAPI_COLOR_STANDARD_ITUR_BT_709:
605       va_csc = VA_SRC_BT709;
606       break;
607 #endif
608 #ifdef VA_SRC_SMPTE_240
609     case GST_VAAPI_COLOR_STANDARD_SMPTE_240M:
610       va_csc = VA_SRC_SMPTE_240;
611       break;
612 #endif
613     default:
614       va_csc = 0;
615       break;
616   }
617   return va_fields | va_csc;
618 }
619 
620 /**
621  * to_GstVaapiSurfaceStatus:
622  * @flags: the #GstVaapiSurfaceStatus flags to translate
623  *
624  * Converts vaQuerySurfaceStatus() @flags to #GstVaapiSurfaceStatus
625  * flags.
626  *
627  * Return value: the #GstVaapiSurfaceStatus flags
628  */
629 guint
to_GstVaapiSurfaceStatus(guint va_flags)630 to_GstVaapiSurfaceStatus (guint va_flags)
631 {
632   guint flags;
633   const guint va_flags_mask = (VASurfaceReady |
634       VASurfaceRendering | VASurfaceDisplaying);
635 
636   /* Check for core status */
637   switch (va_flags & va_flags_mask) {
638     case VASurfaceReady:
639       flags = GST_VAAPI_SURFACE_STATUS_IDLE;
640       break;
641     case VASurfaceRendering:
642       flags = GST_VAAPI_SURFACE_STATUS_RENDERING;
643       break;
644     case VASurfaceDisplaying:
645       flags = GST_VAAPI_SURFACE_STATUS_DISPLAYING;
646       break;
647     default:
648       flags = 0;
649       break;
650   }
651 
652   /* Check for encoder status */
653   if (va_flags & VASurfaceSkipped)
654     flags |= GST_VAAPI_SURFACE_STATUS_SKIPPED;
655   return flags;
656 }
657 
658 /* Translate GstVaapiRotation value to VA-API rotation value */
659 guint
from_GstVaapiRotation(guint value)660 from_GstVaapiRotation (guint value)
661 {
662   switch (value) {
663     case GST_VAAPI_ROTATION_0:
664       return VA_ROTATION_NONE;
665     case GST_VAAPI_ROTATION_90:
666       return VA_ROTATION_90;
667     case GST_VAAPI_ROTATION_180:
668       return VA_ROTATION_180;
669     case GST_VAAPI_ROTATION_270:
670       return VA_ROTATION_270;
671   }
672   GST_ERROR ("unsupported GstVaapiRotation value %d", value);
673   return VA_ROTATION_NONE;
674 }
675 
676 /* Translate VA-API rotation value to GstVaapiRotation value */
677 guint
to_GstVaapiRotation(guint value)678 to_GstVaapiRotation (guint value)
679 {
680   switch (value) {
681     case VA_ROTATION_NONE:
682       return GST_VAAPI_ROTATION_0;
683     case VA_ROTATION_90:
684       return GST_VAAPI_ROTATION_90;
685     case VA_ROTATION_180:
686       return GST_VAAPI_ROTATION_180;
687     case VA_ROTATION_270:
688       return GST_VAAPI_ROTATION_270;
689   }
690   GST_ERROR ("unsupported VA-API rotation value %d", value);
691   return GST_VAAPI_ROTATION_0;
692 }
693 
694 guint
from_GstVaapiRateControl(guint value)695 from_GstVaapiRateControl (guint value)
696 {
697   switch (value) {
698     case GST_VAAPI_RATECONTROL_NONE:
699       return VA_RC_NONE;
700 #ifdef VA_RC_CQP
701     case GST_VAAPI_RATECONTROL_CQP:
702       return VA_RC_CQP;
703 #endif
704     case GST_VAAPI_RATECONTROL_CBR:
705       return VA_RC_CBR;
706     case GST_VAAPI_RATECONTROL_VCM:
707       return VA_RC_VCM;
708     case GST_VAAPI_RATECONTROL_VBR:
709       return VA_RC_VBR;
710 #ifdef VA_RC_VBR_CONSTRAINED
711     case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED:
712       return VA_RC_VBR_CONSTRAINED;
713 #endif
714 #ifdef VA_RC_MB
715     case GST_VAAPI_RATECONTROL_MB:
716       return VA_RC_MB;
717 #endif
718   }
719   GST_ERROR ("unsupported GstVaapiRateControl value %u", value);
720   return VA_RC_NONE;
721 }
722 
723 guint
to_GstVaapiRateControl(guint value)724 to_GstVaapiRateControl (guint value)
725 {
726   switch (value) {
727     case VA_RC_NONE:
728       return GST_VAAPI_RATECONTROL_NONE;
729 #ifdef VA_RC_CQP
730     case VA_RC_CQP:
731       return GST_VAAPI_RATECONTROL_CQP;
732 #endif
733     case VA_RC_CBR:
734       return GST_VAAPI_RATECONTROL_CBR;
735     case VA_RC_VCM:
736       return GST_VAAPI_RATECONTROL_VCM;
737     case VA_RC_VBR:
738       return GST_VAAPI_RATECONTROL_VBR;
739 #ifdef VA_RC_VBR_CONSTRAINED
740     case VA_RC_VBR_CONSTRAINED:
741       return GST_VAAPI_RATECONTROL_VBR_CONSTRAINED;
742 #endif
743 #ifdef VA_RC_MB
744     case VA_RC_MB:
745       return GST_VAAPI_RATECONTROL_MB;
746 #endif
747   }
748   GST_ERROR ("unsupported VA-API Rate Control value %u", value);
749   return GST_VAAPI_RATECONTROL_NONE;
750 }
751 
752 /* VPP: translate GstVaapiDeinterlaceMethod to VA deinterlacing algorithm */
753 guint
from_GstVaapiDeinterlaceMethod(guint value)754 from_GstVaapiDeinterlaceMethod (guint value)
755 {
756   switch (value) {
757     case GST_VAAPI_DEINTERLACE_METHOD_NONE:
758       return 0;
759     case GST_VAAPI_DEINTERLACE_METHOD_BOB:
760       return VAProcDeinterlacingBob;
761     case GST_VAAPI_DEINTERLACE_METHOD_WEAVE:
762       return VAProcDeinterlacingWeave;
763     case GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE:
764       return VAProcDeinterlacingMotionAdaptive;
765     case GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED:
766       return VAProcDeinterlacingMotionCompensated;
767   }
768   GST_ERROR ("unsupported GstVaapiDeinterlaceMethod value %d", value);
769   return 0;
770 }
771 
772 /* VPP: translate GstVaapiDeinterlaceFlags into VA deinterlacing flags */
773 guint
from_GstVaapiDeinterlaceFlags(guint flags)774 from_GstVaapiDeinterlaceFlags (guint flags)
775 {
776   guint va_flags = 0;
777 
778   if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF))
779     va_flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST;
780 
781   if (flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD)
782     va_flags |= VA_DEINTERLACING_ONE_FIELD;
783 
784   if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD))
785     va_flags |= VA_DEINTERLACING_BOTTOM_FIELD;
786   return va_flags;
787 }
788 
789 /* VPP: translate GstVaapiScaleMethod into VA scaling flags */
790 guint
from_GstVaapiScaleMethod(guint value)791 from_GstVaapiScaleMethod (guint value)
792 {
793   guint va_flags;
794 
795   switch (value) {
796     case GST_VAAPI_SCALE_METHOD_DEFAULT:
797       va_flags = VA_FILTER_SCALING_DEFAULT;
798       break;
799     case GST_VAAPI_SCALE_METHOD_FAST:
800       va_flags = VA_FILTER_SCALING_FAST;
801       break;
802     case GST_VAAPI_SCALE_METHOD_HQ:
803       va_flags = VA_FILTER_SCALING_HQ;
804       break;
805     default:
806       va_flags = 0;
807       break;
808   }
809   return va_flags;
810 }
811 
812 /* VPP: translate VA scaling flags into GstVaapiScale Method */
813 guint
to_GstVaapiScaleMethod(guint flags)814 to_GstVaapiScaleMethod (guint flags)
815 {
816   GstVaapiScaleMethod method;
817 
818   switch (flags) {
819     case VA_FILTER_SCALING_FAST:
820       method = GST_VAAPI_SCALE_METHOD_FAST;
821       break;
822     case VA_FILTER_SCALING_HQ:
823       method = GST_VAAPI_SCALE_METHOD_HQ;
824       break;
825     default:
826       method = GST_VAAPI_SCALE_METHOD_DEFAULT;
827       break;
828   }
829   return method;
830 }
831