diff --git a/sys/va/gstvadisplay.c b/sys/va/gstvadisplay.c index 0b03da7e34..c5416f5f3e 100644 --- a/sys/va/gstvadisplay.c +++ b/sys/va/gstvadisplay.c @@ -24,6 +24,7 @@ #include "gstvadisplay.h" #include "gstvaprofile.h" +#include "gstvavideoformat.h" GST_DEBUG_CATEGORY (gst_va_display_debug); #define GST_CAT_DEFAULT gst_va_display_debug @@ -367,3 +368,47 @@ bail: g_free (profiles); return ret; } + +GArray * +gst_va_display_get_image_formats (GstVaDisplay * self) +{ + GArray *ret = NULL; + GstVideoFormat format; + VADisplay dpy = gst_va_display_get_va_dpy (self); + VAImageFormat *va_formats; + VAStatus status; + int i, max, num = 0; + + gst_va_display_lock (self); + max = vaMaxNumImageFormats (dpy); + gst_va_display_unlock (self); + if (max == 0) + return NULL; + + va_formats = g_new (VAImageFormat, max); + + gst_va_display_lock (self); + status = vaQueryImageFormats (dpy, va_formats, &num); + gst_va_display_unlock (self); + + if (status != VA_STATUS_SUCCESS) { + GST_ERROR ("vaQueryImageFormats: %s", vaErrorStr (status)); + goto bail; + } + + ret = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), num); + for (i = 0; i < num; i++) { + format = gst_va_video_format_from_va_image_format (&va_formats[i]); + if (format != GST_VIDEO_FORMAT_UNKNOWN) + g_array_append_val (ret, format); + } + + if (ret->len == 0) { + g_array_unref (ret); + ret = NULL; + } + +bail: + g_free (va_formats); + return ret; +} diff --git a/sys/va/gstvadisplay.h b/sys/va/gstvadisplay.h index 87bd39f1bc..a110b463e2 100644 --- a/sys/va/gstvadisplay.h +++ b/sys/va/gstvadisplay.h @@ -44,5 +44,6 @@ VADisplay gst_va_display_get_va_dpy (GstVaDisplay * self); GArray * gst_va_display_get_profiles (GstVaDisplay * self, guint32 codec, VAEntrypoint entrypoint); +GArray * gst_va_display_get_image_formats (GstVaDisplay * display); G_END_DECLS diff --git a/sys/va/gstvavideoformat.c b/sys/va/gstvavideoformat.c index 5dbccf6a9b..fbf8c53e90 100644 --- a/sys/va/gstvavideoformat.c +++ b/sys/va/gstvavideoformat.c @@ -125,6 +125,46 @@ get_format_map_from_video_format (GstVideoFormat format) return NULL; } +static inline gboolean +va_format_is_rgb (const VAImageFormat * va_format) +{ + return va_format->depth != 0; +} + +static inline gboolean +va_format_is_same_rgb (const VAImageFormat * fmt1, const VAImageFormat * fmt2) +{ + return (fmt1->red_mask == fmt2->red_mask + && fmt1->green_mask == fmt2->green_mask + && fmt1->blue_mask == fmt2->blue_mask + && fmt1->alpha_mask == fmt2->alpha_mask); +} + +static inline gboolean +va_format_is_same (const VAImageFormat * fmt1, const VAImageFormat * fmt2) +{ + if (fmt1->fourcc != fmt2->fourcc) + return FALSE; + if (fmt1->byte_order != VA_NSB_FIRST + && fmt2->byte_order != VA_NSB_FIRST + && fmt1->byte_order != fmt2->byte_order) + return FALSE; + return va_format_is_rgb (fmt1) ? va_format_is_same_rgb (fmt1, fmt2) : TRUE; +} + +static const struct FormatMap * +get_format_map_from_va_image_format (const VAImageFormat * va_format) +{ + int i; + + for (i = 0; i < G_N_ELEMENTS (format_map); i++) { + if (va_format_is_same (&format_map[i].va_format, va_format)) + return &format_map[i]; + } + + return NULL; +} + GstVideoFormat gst_va_video_format_from_va_fourcc (guint va_fourcc) { @@ -156,3 +196,11 @@ gst_va_image_format_from_video_format (GstVideoFormat format) return map ? &map->va_format : NULL; } + +GstVideoFormat +gst_va_video_format_from_va_image_format (const VAImageFormat * va_format) +{ + const struct FormatMap *map = get_format_map_from_va_image_format (va_format); + + return map ? map->format : GST_VIDEO_FORMAT_UNKNOWN; +} diff --git a/sys/va/gstvavideoformat.h b/sys/va/gstvavideoformat.h index c73aa7685f..1856c172d0 100644 --- a/sys/va/gstvavideoformat.h +++ b/sys/va/gstvavideoformat.h @@ -29,5 +29,6 @@ GstVideoFormat gst_va_video_format_from_va_fourcc (guint fourcc); guint gst_va_fourcc_from_video_format (GstVideoFormat format); guint gst_va_chroma_from_video_format (GstVideoFormat format); const VAImageFormat * gst_va_image_format_from_video_format (GstVideoFormat format); +GstVideoFormat gst_va_video_format_from_va_image_format (const VAImageFormat * va_format); G_END_DECLS