summaryrefslogtreecommitdiff
path: root/va/va.c
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2013-05-27 20:39:29 +0200
committerXiang, Haihao <haihao.xiang@intel.com>2013-06-05 09:38:35 +0800
commit285b384c60a326936f40f52a69b6b2e3f3189929 (patch)
tree408800903d9302df8e1ac0bc2eec1dcba9efb72c /va/va.c
parent8dccd7a279cdc9667c01a99257e89d652ee5194c (diff)
Add default implementation for vaQuerySurfaceAttributes().
Add an initial implementation for vaQuerySurfaceAttributes() in terms of vaGetSurfaceAttributes(). This is an inefficient approach because it dynamically allocates the whole set of surface attributes we guessed are available. This code is to be removed once the VA drivers are updated. Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
Diffstat (limited to 'va/va.c')
-rw-r--r--va/va.c139
1 files changed, 138 insertions, 1 deletions
diff --git a/va/va.c b/va/va.c
index ebfd994..45ff5f2 100644
--- a/va/va.c
+++ b/va/va.c
@@ -655,6 +655,142 @@ VAStatus vaQueryConfigAttributes (
return ctx->vtable->vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
}
+/* XXX: this is a slow implementation that will be removed */
+static VAStatus
+va_impl_query_surface_attributes(
+ VADriverContextP ctx,
+ VAConfigID config,
+ VASurfaceAttrib *out_attribs,
+ unsigned int *out_num_attribs_ptr
+)
+{
+ VASurfaceAttrib *attribs = NULL;
+ unsigned int num_attribs, n;
+ VASurfaceAttrib *out_attrib;
+ unsigned int out_num_attribs;
+ VAImageFormat *image_formats = NULL;
+ int num_image_formats, i;
+ VAStatus va_status;
+
+ /* List of surface attributes to query */
+ struct va_surface_attrib_map {
+ VASurfaceAttribType type;
+ VAGenericValueType value_type;
+ };
+ static const struct va_surface_attrib_map attribs_map[] = {
+ { VASurfaceAttribMinWidth, VAGenericValueTypeInteger },
+ { VASurfaceAttribMaxWidth, VAGenericValueTypeInteger },
+ { VASurfaceAttribMinHeight, VAGenericValueTypeInteger },
+ { VASurfaceAttribMaxHeight, VAGenericValueTypeInteger },
+ { VASurfaceAttribMemoryType, VAGenericValueTypeInteger },
+ { VASurfaceAttribNone, }
+ };
+
+ if (!out_attribs || !out_num_attribs_ptr)
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+ if (!ctx->vtable->vaGetSurfaceAttributes)
+ return VA_STATUS_ERROR_UNIMPLEMENTED;
+
+ num_image_formats = ctx->max_image_formats;
+ image_formats = malloc(num_image_formats * sizeof(*image_formats));
+ if (!image_formats) {
+ va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
+ goto end;
+ }
+
+ va_status = ctx->vtable->vaQueryImageFormats(
+ ctx, image_formats, &num_image_formats);
+ if (va_status != VA_STATUS_SUCCESS)
+ goto end;
+
+ num_attribs = VASurfaceAttribCount + num_image_formats;
+ attribs = malloc(num_attribs * sizeof(*attribs));
+ if (!attribs) {
+ va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
+ goto end;
+ }
+
+ /* Initialize with base surface attributes, except pixel-formats */
+ for (n = 0; attribs_map[n].type != VASurfaceAttribNone; n++) {
+ VASurfaceAttrib * const attrib = &attribs[n];
+ attrib->type = attribs_map[n].type;
+ attrib->flags = VA_SURFACE_ATTRIB_GETTABLE;
+ attrib->value.type = attribs_map[n].value_type;
+ }
+
+ /* Append image formats */
+ for (i = 0; i < num_image_formats; i++) {
+ VASurfaceAttrib * const attrib = &attribs[n];
+ attrib->type = VASurfaceAttribPixelFormat;
+ attrib->flags = VA_SURFACE_ATTRIB_GETTABLE|VA_SURFACE_ATTRIB_SETTABLE;
+ attrib->value.type = VAGenericValueTypeInteger;
+ attrib->value.value.i = image_formats[i].fourcc;
+ if (++n == num_attribs) {
+ va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
+ goto end;
+ }
+ }
+ num_attribs = n;
+
+ va_status = ctx->vtable->vaGetSurfaceAttributes(
+ ctx, config, attribs, num_attribs);
+ if (va_status != VA_STATUS_SUCCESS)
+ goto end;
+
+ /* Remove invalid entries */
+ out_num_attribs = 0;
+ for (n = 0; n < num_attribs; n++) {
+ VASurfaceAttrib * const attrib = &attribs[n];
+
+ if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
+ continue;
+
+ // Accept all surface attributes that are not pixel-formats
+ if (attrib->type != VASurfaceAttribPixelFormat) {
+ out_num_attribs++;
+ continue;
+ }
+
+ // Drop invalid pixel-format attribute
+ if (!attrib->value.value.i) {
+ attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
+ continue;
+ }
+
+ // Check for duplicates
+ int is_duplicate = 0;
+ for (i = n - 1; i >= 0 && !is_duplicate; i--) {
+ const VASurfaceAttrib * const prev_attrib = &attribs[i];
+ if (prev_attrib->type != VASurfaceAttribPixelFormat)
+ break;
+ is_duplicate = prev_attrib->value.value.i == attrib->value.value.i;
+ }
+ if (is_duplicate)
+ attrib->flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
+ else
+ out_num_attribs++;
+ }
+
+ if (*out_num_attribs_ptr < out_num_attribs) {
+ *out_num_attribs_ptr = out_num_attribs;
+ va_status = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
+ goto end;
+ }
+
+ out_attrib = out_attribs;
+ for (n = 0; n < num_attribs; n++) {
+ const VASurfaceAttrib * const attrib = &attribs[n];
+ if (attrib->flags == VA_SURFACE_ATTRIB_NOT_SUPPORTED)
+ continue;
+ *out_attrib++ = *attrib;
+ }
+
+end:
+ free(attribs);
+ free(image_formats);
+ return va_status;
+}
+
VAStatus
vaQuerySurfaceAttributes(
VADisplay dpy,
@@ -672,7 +808,8 @@ vaQuerySurfaceAttributes(
return VA_STATUS_ERROR_INVALID_DISPLAY;
if (!ctx->vtable->vaQuerySurfaceAttributes)
- return VA_STATUS_ERROR_UNIMPLEMENTED;
+ return va_impl_query_surface_attributes(ctx, config,
+ attrib_list, num_attribs);
vaStatus = ctx->vtable->vaQuerySurfaceAttributes(ctx, config,
attrib_list, num_attribs);