display: allow image/subpicture formats with additional flags.

Introduce new GstVaapiFormatInfo to store the actual GstVaapiImageFormat
and any additional flags needed. Currently, all flags are set to zero.
This commit is contained in:
Gwenole Beauchesne 2013-01-03 18:02:49 +01:00
parent d4a8e39656
commit fc1f9a64e4

View file

@ -53,6 +53,12 @@ struct _GstVaapiProperty {
gint old_value; gint old_value;
}; };
typedef struct _GstVaapiFormatInfo GstVaapiFormatInfo;
struct _GstVaapiFormatInfo {
GstVaapiImageFormat format;
guint flags;
};
#define DEFAULT_RENDER_MODE GST_VAAPI_RENDER_MODE_TEXTURE #define DEFAULT_RENDER_MODE GST_VAAPI_RENDER_MODE_TEXTURE
#define DEFAULT_ROTATION GST_VAAPI_ROTATION_0 #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0
@ -149,22 +155,28 @@ gst_vaapi_display_type_get_type(void)
/* Append GstVaapiImageFormat to formats array */ /* Append GstVaapiImageFormat to formats array */
static inline void static inline void
append_format(GArray *formats, GstVaapiImageFormat format) append_format(GArray *formats, GstVaapiImageFormat format, guint flags)
{ {
g_array_append_val(formats, format); GstVaapiFormatInfo fi;
fi.format = format;
fi.flags = flags;
g_array_append_val(formats, fi);
} }
/* Append VAImageFormats to formats array */ /* Append VAImageFormats to formats array */
static void static void
append_formats(GArray *formats, const VAImageFormat *va_formats, guint n) append_formats(GArray *formats, const VAImageFormat *va_formats,
guint *flags, guint n)
{ {
GstVaapiImageFormat format; GstVaapiImageFormat format;
gboolean has_YV12 = FALSE; const GstVaapiFormatInfo *YV12_fip = NULL;
gboolean has_I420 = FALSE; const GstVaapiFormatInfo *I420_fip = NULL;
guint i; guint i;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
const VAImageFormat * const va_format = &va_formats[i]; const VAImageFormat * const va_format = &va_formats[i];
const GstVaapiFormatInfo **fipp;
format = gst_vaapi_image_format(va_format); format = gst_vaapi_image_format(va_format);
if (!format) { if (!format) {
@ -172,34 +184,38 @@ append_formats(GArray *formats, const VAImageFormat *va_formats, guint n)
GST_FOURCC_ARGS(va_format->fourcc)); GST_FOURCC_ARGS(va_format->fourcc));
continue; continue;
} }
append_format(formats, format, flags ? flags[i] : 0);
switch (format) { switch (format) {
case GST_VAAPI_IMAGE_YV12: case GST_VAAPI_IMAGE_YV12:
has_YV12 = TRUE; fipp = &YV12_fip;
break; break;
case GST_VAAPI_IMAGE_I420: case GST_VAAPI_IMAGE_I420:
has_I420 = TRUE; fipp = &I420_fip;
break; break;
default: default:
fipp = NULL;
break; break;
} }
append_format(formats, format); if (fipp)
*fipp = &g_array_index(formats, GstVaapiFormatInfo,
formats->len - 1);
} }
/* Append I420 (resp. YV12) format if YV12 (resp. I420) is not /* Append I420 (resp. YV12) format if YV12 (resp. I420) is not
supported by the underlying driver */ supported by the underlying driver */
if (has_YV12 && !has_I420) if (YV12_fip && !I420_fip)
append_format(formats, GST_VAAPI_IMAGE_I420); append_format(formats, GST_VAAPI_IMAGE_I420, YV12_fip->flags);
else if (has_I420 && !has_YV12) else if (I420_fip && !YV12_fip)
append_format(formats, GST_VAAPI_IMAGE_YV12); append_format(formats, GST_VAAPI_IMAGE_YV12, I420_fip->flags);
} }
/* Sort image formats. Prefer YUV formats first */ /* Sort image formats. Prefer YUV formats first */
static gint static gint
compare_yuv_formats(gconstpointer a, gconstpointer b) compare_yuv_formats(gconstpointer a, gconstpointer b)
{ {
const GstVaapiImageFormat fmt1 = *(GstVaapiImageFormat *)a; const GstVaapiImageFormat fmt1 = ((GstVaapiFormatInfo *)a)->format;
const GstVaapiImageFormat fmt2 = *(GstVaapiImageFormat *)b; const GstVaapiImageFormat fmt2 = ((GstVaapiFormatInfo *)b)->format;
const gboolean is_fmt1_yuv = gst_vaapi_image_format_is_yuv(fmt1); const gboolean is_fmt1_yuv = gst_vaapi_image_format_is_yuv(fmt1);
const gboolean is_fmt2_yuv = gst_vaapi_image_format_is_yuv(fmt2); const gboolean is_fmt2_yuv = gst_vaapi_image_format_is_yuv(fmt2);
@ -215,8 +231,8 @@ compare_yuv_formats(gconstpointer a, gconstpointer b)
static gint static gint
compare_rgb_formats(gconstpointer a, gconstpointer b) compare_rgb_formats(gconstpointer a, gconstpointer b)
{ {
const GstVaapiImageFormat fmt1 = *(GstVaapiImageFormat *)a; const GstVaapiImageFormat fmt1 = ((GstVaapiFormatInfo *)a)->format;
const GstVaapiImageFormat fmt2 = *(GstVaapiImageFormat *)b; const GstVaapiImageFormat fmt2 = ((GstVaapiFormatInfo *)b)->format;
const gboolean is_fmt1_rgb = gst_vaapi_image_format_is_rgb(fmt1); const gboolean is_fmt1_rgb = gst_vaapi_image_format_is_rgb(fmt1);
const gboolean is_fmt2_rgb = gst_vaapi_image_format_is_rgb(fmt2); const gboolean is_fmt2_rgb = gst_vaapi_image_format_is_rgb(fmt2);
@ -304,23 +320,33 @@ get_profile_caps(GArray *configs)
return out_caps; return out_caps;
} }
/* Find format info */
static const GstVaapiFormatInfo *
find_format_info(GArray *formats, GstVaapiImageFormat format)
{
const GstVaapiFormatInfo *fip;
guint i;
for (i = 0; i < formats->len; i++) {
fip = &g_array_index(formats, GstVaapiFormatInfo, i);
if (fip->format == format)
return fip;
}
return NULL;
}
/* Check if formats array contains format */ /* Check if formats array contains format */
static inline gboolean static inline gboolean
find_format(GArray *formats, GstVaapiImageFormat format) find_format(GArray *formats, GstVaapiImageFormat format)
{ {
guint i; return find_format_info(formats, format) != NULL;
for (i = 0; i < formats->len; i++)
if (g_array_index(formats, GstVaapiImageFormat, i) == format)
return TRUE;
return FALSE;
} }
/* Convert formats array to GstCaps */ /* Convert formats array to GstCaps */
static GstCaps * static GstCaps *
get_format_caps(GArray *formats) get_format_caps(GArray *formats)
{ {
GstVaapiImageFormat format; const GstVaapiFormatInfo *fip;
GstCaps *out_caps, *caps; GstCaps *out_caps, *caps;
guint i; guint i;
@ -329,8 +355,8 @@ get_format_caps(GArray *formats)
return NULL; return NULL;
for (i = 0; i < formats->len; i++) { for (i = 0; i < formats->len; i++) {
format = g_array_index(formats, GstVaapiImageFormat, i); fip = &g_array_index(formats, GstVaapiFormatInfo, i);
caps = gst_vaapi_image_format_get_caps(format); caps = gst_vaapi_image_format_get_caps(fip->format);
if (caps) if (caps)
gst_caps_append(out_caps, caps); gst_caps_append(out_caps, caps);
} }
@ -676,10 +702,10 @@ gst_vaapi_display_create(GstVaapiDisplay *display)
GST_DEBUG(" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc)); GST_DEBUG(" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc));
priv->image_formats = priv->image_formats =
g_array_new(FALSE, FALSE, sizeof(GstVaapiImageFormat)); g_array_new(FALSE, FALSE, sizeof(GstVaapiFormatInfo));
if (!priv->image_formats) if (!priv->image_formats)
goto end; goto end;
append_formats(priv->image_formats, formats, n); append_formats(priv->image_formats, formats, NULL, n);
g_array_sort(priv->image_formats, compare_yuv_formats); g_array_sort(priv->image_formats, compare_yuv_formats);
/* VA subpicture formats */ /* VA subpicture formats */
@ -697,10 +723,10 @@ gst_vaapi_display_create(GstVaapiDisplay *display)
GST_DEBUG(" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc)); GST_DEBUG(" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS(formats[i].fourcc));
priv->subpicture_formats = priv->subpicture_formats =
g_array_new(FALSE, FALSE, sizeof(GstVaapiImageFormat)); g_array_new(FALSE, FALSE, sizeof(GstVaapiFormatInfo));
if (!priv->subpicture_formats) if (!priv->subpicture_formats)
goto end; goto end;
append_formats(priv->subpicture_formats, formats, n); append_formats(priv->subpicture_formats, formats, NULL, n);
g_array_sort(priv->subpicture_formats, compare_rgb_formats); g_array_sort(priv->subpicture_formats, compare_rgb_formats);
if (!cached_info) { if (!cached_info) {