OSDN Git Service

Add imported surface alignment check
authorWang, Tiantian <tiantian.wang@intel.com>
Thu, 30 Mar 2017 01:22:03 +0000 (21:22 -0400)
committerXiang, Haihao <haihao.xiang@intel.com>
Mon, 12 Jun 2017 05:09:02 +0000 (13:09 +0800)
This fixes issues #62
https://github.com/01org/intel-vaapi-driver/issues/62

Signed-off-by: Wang Tiantian <tiantian.wang@intel.com>
Reviewed-by: Zhao Yakui <yakui.zhao@intel.com>
(cherry picked from commit 43a75eaadf2c5226654be438e0223a28f577d27a)

src/i965_drv_video.c

index 7232c6c..0e8ecb9 100644 (file)
@@ -1385,6 +1385,18 @@ i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
     object_heap_free(heap, obj);
 }
 
+/* byte-per-pixel of the first plane */
+static int
+bpp_1stplane_by_fourcc(unsigned int fourcc)
+{
+    const i965_fourcc_info *info = get_fourcc_info(fourcc);
+
+    if (info && (info->flag & I_S))
+        return info->bpp[0] / 8;
+    else
+        return 0;
+}
+
 static VAStatus
 i965_surface_native_memory(VADriverContextP ctx,
                            struct object_surface *obj_surface,
@@ -1416,7 +1428,22 @@ i965_suface_external_memory(VADriverContextP ctx,
                             int index)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
+    unsigned int tiling,swizzle;
 
+    obj_surface->size = memory_attibute->data_size;
+    if (external_memory_type == I965_SURFACE_MEM_GEM_FLINK)
+         obj_surface->bo = drm_intel_bo_gem_create_from_name(i965->intel.bufmgr,
+                                                            "gem flinked vaapi surface",
+                                                             memory_attibute->buffers[index]);
+    else if (external_memory_type == I965_SURFACE_MEM_DRM_PRIME)
+             obj_surface->bo = drm_intel_bo_gem_create_from_prime(i965->intel.bufmgr,
+                                                              memory_attibute->buffers[index],
+                                                             obj_surface->size);
+
+    if (!obj_surface->bo)
+        return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
     if (!memory_attibute ||
         !memory_attibute->buffers ||
         index > memory_attibute->num_buffers)
@@ -1428,15 +1455,33 @@ i965_suface_external_memory(VADriverContextP ctx,
 
     obj_surface->fourcc = memory_attibute->pixel_format;
     obj_surface->width = memory_attibute->pitches[0];
-    obj_surface->size = memory_attibute->data_size;
+    int bpp_1stplane = bpp_1stplane_by_fourcc(obj_surface->fourcc);
+    ASSERT_RET(IS_ALIGNED(obj_surface->width, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
+    ASSERT_RET(obj_surface->width >= obj_surface->orig_width * bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
 
     if (memory_attibute->num_planes == 1)
         obj_surface->height = memory_attibute->data_size / obj_surface->width;
     else 
         obj_surface->height = memory_attibute->offsets[1] / obj_surface->width;
+    ASSERT_RET(IS_ALIGNED(obj_surface->height, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
+    ASSERT_RET(obj_surface->height >= obj_surface->orig_height, VA_STATUS_ERROR_INVALID_PARAMETER);
+
+    if (tiling) {
+        ASSERT_RET(IS_ALIGNED(obj_surface->width,128),VA_STATUS_ERROR_INVALID_PARAMETER);
+        ASSERT_RET(IS_ALIGNED(obj_surface->height,32),VA_STATUS_ERROR_INVALID_PARAMETER);
+    } else {
+        ASSERT_RET(IS_ALIGNED(obj_surface->width,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
+        ASSERT_RET(IS_ALIGNED(obj_surface->height,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
+    }
 
     obj_surface->x_cb_offset = 0; /* X offset is always 0 */
     obj_surface->x_cr_offset = 0;
+    if ((obj_surface->fourcc == VA_FOURCC_I420 ||
+         obj_surface->fourcc == VA_FOURCC_IYUV ||
+         obj_surface->fourcc == VA_FOURCC_I010 ||
+         obj_surface->fourcc == VA_FOURCC_YV12 ||
+         obj_surface->fourcc == VA_FOURCC_YV16) && tiling)
+        return VA_STATUS_ERROR_INVALID_PARAMETER;
 
     switch (obj_surface->fourcc) {
     case VA_FOURCC_NV12:
@@ -1450,6 +1495,10 @@ i965_suface_external_memory(VADriverContextP ctx,
         obj_surface->cb_cr_width = obj_surface->orig_width / 2;
         obj_surface->cb_cr_height = obj_surface->orig_height / 2;
         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
+        if (tiling)
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
+        else
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
 
         break;
 
@@ -1464,7 +1513,11 @@ i965_suface_external_memory(VADriverContextP ctx,
         obj_surface->cb_cr_width = obj_surface->orig_width / 2;
         obj_surface->cb_cr_height = obj_surface->orig_height / 2;
         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
-        
+        if (tiling)
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
+        else
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
+
         break;
 
     case VA_FOURCC_I420:
@@ -1480,6 +1533,10 @@ i965_suface_external_memory(VADriverContextP ctx,
         obj_surface->cb_cr_width = obj_surface->orig_width / 2;
         obj_surface->cb_cr_height = obj_surface->orig_height / 2;
         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
+        if (tiling)
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
+        else
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
 
         break;
 
@@ -1513,7 +1570,7 @@ i965_suface_external_memory(VADriverContextP ctx,
 
     case VA_FOURCC_Y800: /* monochrome surface */
         ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
-        
+
         obj_surface->subsampling = SUBSAMPLE_YUV400;
         obj_surface->y_cb_offset = 0;
         obj_surface->y_cr_offset = 0;
@@ -1533,7 +1590,10 @@ i965_suface_external_memory(VADriverContextP ctx,
         obj_surface->cb_cr_width = obj_surface->orig_width / 4;
         obj_surface->cb_cr_height = obj_surface->orig_height;
         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
-
+        if (tiling)
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
+        else
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
         break;
 
     case VA_FOURCC_422H:
@@ -1546,12 +1606,16 @@ i965_suface_external_memory(VADriverContextP ctx,
         obj_surface->cb_cr_width = obj_surface->orig_width / 2;
         obj_surface->cb_cr_height = obj_surface->orig_height;
         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
+        if (tiling)
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
+        else
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
 
         break;
 
     case VA_FOURCC_YV16:
-        assert(memory_attibute->num_planes == 3);
-        assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
+        ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
+        ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
 
         obj_surface->subsampling = SUBSAMPLE_YUV422H;
         obj_surface->y_cr_offset = memory_attibute->offsets[1] / obj_surface->width;
@@ -1559,6 +1623,7 @@ i965_suface_external_memory(VADriverContextP ctx,
         obj_surface->cb_cr_width = obj_surface->orig_width / 2;
         obj_surface->cb_cr_height = obj_surface->orig_height;
         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
+        ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
 
         break;
 
@@ -1572,6 +1637,10 @@ i965_suface_external_memory(VADriverContextP ctx,
         obj_surface->cb_cr_width = obj_surface->orig_width;
         obj_surface->cb_cr_height = obj_surface->orig_height / 2;
         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
+        if (tiling)
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
+        else
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
 
         break;
 
@@ -1585,41 +1654,20 @@ i965_suface_external_memory(VADriverContextP ctx,
         obj_surface->cb_cr_width = obj_surface->orig_width;
         obj_surface->cb_cr_height = obj_surface->orig_height;
         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
+        if (tiling)
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
+        else
+            ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
 
         break;
 
     default:
-
         return VA_STATUS_ERROR_INVALID_PARAMETER;
     }
 
-    if (external_memory_type == I965_SURFACE_MEM_GEM_FLINK)
-        obj_surface->bo = drm_intel_bo_gem_create_from_name(i965->intel.bufmgr,
-                                                            "gem flinked vaapi surface",
-                                                            memory_attibute->buffers[index]);
-    else if (external_memory_type == I965_SURFACE_MEM_DRM_PRIME)
-        obj_surface->bo = drm_intel_bo_gem_create_from_prime(i965->intel.bufmgr,
-                                                             memory_attibute->buffers[index],
-                                                             obj_surface->size);
-
-    if (!obj_surface->bo)
-        return VA_STATUS_ERROR_INVALID_PARAMETER;
-
     return VA_STATUS_SUCCESS;
 }
 
-/* byte-per-pixel of the first plane */
-static int
-bpp_1stplane_by_fourcc(unsigned int fourcc)
-{
-    const i965_fourcc_info *info = get_fourcc_info(fourcc);
-
-    if (info && (info->flag & I_S))
-        return info->bpp[0] / 8;
-    else
-        return 0;
-}
-
 static VAStatus
 i965_CreateSurfaces2(
     VADriverContextP    ctx,