[Libva] [PATCH 5/5 v3] test: add color conversion test option in putsurface

Zhao Halley halley.zhao at intel.com
Wed Sep 5 02:23:22 PDT 2012


- command line:  ./putsurface --fmt1 format1 --fmt2 format2
              or ./putsurface -1 format1 -2 format2
- example:       ./putsurface -1 NV12 -2 YV12
- implementation:
  - vaSurface is created with fmt1
  - get image (with fmt2) from vaSurface,
    it leads to color conversion
  - put the above image to a temp surface
    color conversion may happen
  - render the above temp surface instead of original one
---
 test/putsurface/putsurface_common.c |  233 ++++++++++++++++++++++++++++++++---
 1 file changed, 217 insertions(+), 16 deletions(-)
 mode change 100644 => 100755 test/putsurface/putsurface_common.c

diff --git a/test/putsurface/putsurface_common.c b/test/putsurface/putsurface_common.c
old mode 100644
new mode 100755
index 54ae8d3..e461683
--- a/test/putsurface/putsurface_common.c
+++ b/test/putsurface/putsurface_common.c
@@ -59,6 +59,7 @@ if (va_status != VA_STATUS_SUCCESS) {                                   \
 
 static  void *win_display;
 static  VADisplay va_dpy;
+static  VAConfigID config_id;
 static  VASurfaceID surface_id[SURFACE_NUM];
 static  pthread_mutex_t surface_mutex[SURFACE_NUM];
 
@@ -76,6 +77,130 @@ static  pthread_mutex_t gmutex;
 static  int box_width = 32;
 static  int multi_thread = 0;
 static  int verbose = 0;
+static  int test_color_conversion = 0;
+static  int csc_src_fourcc = 0, csc_dst_fourcc = 0;
+static  VAImage csc_dst_fourcc_image;
+static  VASurfaceID csc_render_surface;
+
+
+typedef struct {
+    char* fmt_str;
+    unsigned int fourcc;
+} fourcc_map;
+fourcc_map va_fourcc_map[] = {
+    {"YUYV", VA_FOURCC_YUY2},
+    {"YUY2", VA_FOURCC_YUY2},
+    {"NV12", VA_FOURCC_NV12},
+    {"YV12", VA_FOURCC_YV12},
+    {"BGRA", VA_FOURCC_BGRA},
+    {"RGBA", VA_FOURCC_RGBA},
+    {"BGRX", VA_FOURCC_BGRX},
+    {"RGBX", VA_FOURCC_RGBX},
+};
+unsigned int map_str_to_vafourcc (char * str)
+{
+    int i;
+    for (i=0; i< sizeof(va_fourcc_map)/sizeof(fourcc_map); i++) {
+        if (!strcmp(va_fourcc_map[i].fmt_str, str)) {
+            return va_fourcc_map[i].fourcc;
+        }
+    }
+
+    return 0;
+
+}
+char* map_vafourcc_to_str (unsigned int format)
+{
+    static char unknown_format[] = "unknown-format";
+    int i;
+    for (i=0; i< sizeof(va_fourcc_map)/sizeof(fourcc_map); i++) {
+        if (va_fourcc_map[i].fourcc == format) {
+            return va_fourcc_map[i].fmt_str;
+        }
+    }
+
+    return unknown_format;
+
+}
+
+int csc_preparation ()
+{
+    VAStatus va_status;
+    int i;
+    
+    // 1. make sure dst fourcc is supported for vaImage
+    #define MAX_IMAGE_FORMAT_COUNT      10
+    VAImageFormat format_list[MAX_IMAGE_FORMAT_COUNT];
+    int num_formats = 0, find_dst_fourcc = 0;
+    
+    va_status = vaQueryImageFormats(va_dpy, format_list,&num_formats);
+    printf("num_formats: %d\n", num_formats);
+    assert(num_formats<MAX_IMAGE_FORMAT_COUNT);
+    for (i=0; i<num_formats; i++) {
+        if (format_list[i].fourcc == csc_dst_fourcc) {
+            find_dst_fourcc = 1;
+        }
+    }
+    if (!find_dst_fourcc) {
+        test_color_conversion = 0;
+        printf("vaImage doesn't support %s, skip additional color conversion\n",  map_vafourcc_to_str(csc_dst_fourcc));
+        goto cleanup;
+    }
+
+    // 2. make sure src_fourcc is supported for vaSurface
+    VASurfaceAttrib s_attrib[1];
+    va_status = vaCreateConfig(va_dpy, VAProfileNone, VAEntrypointVideoProc,
+                                          NULL, 0,&config_id);
+    CHECK_VASTATUS(va_status, "vaCreateConfig");
+
+    s_attrib[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
+    s_attrib[0].type = VASurfaceAttribPixelFormat;
+    s_attrib[0].value.type = VAGenericValueTypeInteger;
+    s_attrib[0].value.value.i = csc_src_fourcc;
+
+    va_status = vaGetSurfaceAttributes(va_dpy, config_id, s_attrib, 1);
+    CHECK_VASTATUS(va_status,"vaGetSurfaceAttributes");
+    if (! (s_attrib[0].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
+        printf("vaSurface doesn't support %s, skip additional color conversion\n",  map_vafourcc_to_str(csc_src_fourcc));
+        vaDestroyConfig (va_dpy, config_id);
+        test_color_conversion = 0;
+        goto cleanup;
+    }
+
+    // 3 create all objs required by csc
+    // 3.1 vaSurface with src fourcc
+    va_status = vaCreateSurfaces(
+        va_dpy,
+        VA_RT_FORMAT_YUV420, surface_width, surface_height,
+        &surface_id[0], SURFACE_NUM,
+        s_attrib, 1
+    );
+    CHECK_VASTATUS(va_status,"vaCreateSurfaces");
+
+    // 3.2 vaImage with dst fourcc
+    VAImageFormat image_format;
+    image_format.fourcc = csc_dst_fourcc;
+    image_format.byte_order = VA_LSB_FIRST;
+    image_format.bits_per_pixel = 16;
+    
+    va_status = vaCreateImage(va_dpy, &image_format,
+                    surface_width, surface_height,
+                    &csc_dst_fourcc_image);
+    CHECK_VASTATUS(va_status,"vaCreateImage");
+    
+
+    // 3.3 create a temp VASurface for final rendering(vaPutSurface)
+    s_attrib[0].value.value.i = VA_FOURCC_NV12;
+    va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, 
+                                 surface_width, surface_height,
+                                 &csc_render_surface, 1, 
+                                 s_attrib, 1);
+    CHECK_VASTATUS(va_status,"vaCreateSurfaces");
+
+
+cleanup:
+    return test_color_conversion;
+}
 
 static VASurfaceID get_next_free_surface(int *index)
 {
@@ -206,13 +331,42 @@ static void* putsurface_thread(void *data)
             if (c == 'c' || c == 'C')
                 continue_display = 1;
         }
-        vaStatus = vaPutSurface(va_dpy, surface_id, CAST_DRAWABLE(drawable),
-                                0,0,surface_width,surface_height,
-                                0,0,width,height,
-                                (test_clip==0)?NULL:&cliprects[0],
-                                (test_clip==0)?0:2,
-                                display_field);
-        CHECK_VASTATUS(vaStatus,"vaPutSurface");
+        if (test_color_conversion) {
+            static int _put_surface_count = 0;
+            if (_put_surface_count++ %50 == 0) {
+                printf("do additional colorcoversion from %s to %s\n", map_vafourcc_to_str(csc_src_fourcc), map_vafourcc_to_str(csc_dst_fourcc));
+            }
+            // get image from surface, csc_src_fourcc to csc_dst_fourcc conversion happens
+            vaStatus = vaGetImage(va_dpy, surface_id, 0, 0, 
+                surface_width, surface_height, csc_dst_fourcc_image.image_id);
+            CHECK_VASTATUS(vaStatus,"vaGetImage");
+            
+            // render csc_dst_fourcc image to temp surface
+            vaStatus = vaPutImage(va_dpy, csc_render_surface, csc_dst_fourcc_image.image_id,
+                                    0, 0, surface_width, surface_height, 
+                                    0, 0, surface_width, surface_height);
+            CHECK_VASTATUS(vaStatus,"vaPutImage");
+            
+            // render the temp surface, it should be same with original surface without color conversion test
+            vaStatus = vaPutSurface(va_dpy, csc_render_surface, CAST_DRAWABLE(drawable),
+                                    0,0,surface_width,surface_height,
+                                    0,0,width,height,
+                                    (test_clip==0)?NULL:&cliprects[0],
+                                    (test_clip==0)?0:2,
+                                    display_field);
+            CHECK_VASTATUS(vaStatus,"vaPutSurface");
+    
+        }
+        else {
+            vaStatus = vaPutSurface(va_dpy, surface_id, CAST_DRAWABLE(drawable),
+                                    0,0,surface_width,surface_height,
+                                    0,0,width,height,
+                                    (test_clip==0)?NULL:&cliprects[0],
+                                    (test_clip==0)?0:2,
+                                    display_field);
+            CHECK_VASTATUS(vaStatus,"vaPutSurface");
+        }
+    
         putsurface_time += (get_tick_count() - start_time);
         
         if (check_event)
@@ -247,8 +401,6 @@ static void* putsurface_thread(void *data)
     
     return 0;
 }
-
-
 int main(int argc,char **argv)
 {
     int major_ver, minor_ver;
@@ -257,8 +409,16 @@ int main(int argc,char **argv)
     int ret;
     char c;
     int i;
+    char str_src_fmt[5], str_dst_fmt[5];
 
-    while ((c =getopt(argc,argv,"w:h:g:r:d:f:tcep?n:v") ) != EOF) {
+    static struct option long_options[] =
+                 {
+                   {"fmt1",  required_argument,       NULL, '1'},
+                   {"fmt2",  required_argument,       NULL, '2'},
+                   {0, 0, 0, 0}
+                 };
+
+    while ((c =getopt_long(argc,argv,"w:h:g:r:d:f:tcep?n:1:2:v", long_options, NULL)) != EOF) {
         switch (c) {
             case '?':
                 printf("putsurface <options>\n");
@@ -269,6 +429,10 @@ int main(int argc,char **argv)
                 printf("           -t multi-threads\n");
                 printf("           -c test clipbox\n");
                 printf("           -f <1/2> top field, or bottom field\n");
+                printf("           -1 source format (fourcc) for color conversion test\n");
+                printf("           -2 dest   format (fourcc) for color conversion test\n");
+                printf("           --fmt1 same to -1\n");
+                printf("           --fmt2 same to -2\n");
                 printf("           -v verbose output\n");
                 exit(0);
                 break;
@@ -319,6 +483,24 @@ int main(int argc,char **argv)
                 } else
                     printf("The validate input for -f is: 1(top field)/2(bottom field)\n");
                 break;
+            case '1':
+                sscanf(optarg, "%s", str_src_fmt);
+                csc_src_fourcc = map_str_to_vafourcc (str_src_fmt);
+                
+				if (!csc_src_fourcc) {
+                    printf("invalid fmt1: %s\n", str_src_fmt );
+                    exit(0);
+                }
+                break;
+            case '2':
+                sscanf(optarg, "%s", str_dst_fmt);
+                csc_dst_fourcc = map_str_to_vafourcc (str_dst_fmt);
+                
+				if (!csc_dst_fourcc) {
+                    printf("invalid fmt1: %s\n", str_dst_fmt );
+                    exit(0);
+                }
+                break;
             case 'v':
                 verbose = 1;
                 printf("Enable verbose output\n");
@@ -326,6 +508,10 @@ int main(int argc,char **argv)
         }
     }
 
+    if (csc_src_fourcc && csc_dst_fourcc) {
+        test_color_conversion = 1;
+    }
+    
     win_display = (void *)open_display();
     if (win_display == NULL) {
         fprintf(stderr, "Can't open the connection of display!\n");
@@ -337,12 +523,17 @@ int main(int argc,char **argv)
     va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
     CHECK_VASTATUS(va_status, "vaInitialize");
 
-    va_status = vaCreateSurfaces(
-        va_dpy,
-        VA_RT_FORMAT_YUV420, surface_width, surface_height,
-        &surface_id[0], SURFACE_NUM,
-        NULL, 0
-    );
+    if (test_color_conversion) {
+        ret = csc_preparation();
+    }
+    if (!test_color_conversion || !ret ) {
+        va_status = vaCreateSurfaces(
+            va_dpy,
+            VA_RT_FORMAT_YUV420, surface_width, surface_height,
+            &surface_id[0], SURFACE_NUM,
+            NULL, 0
+        );
+	}
     CHECK_VASTATUS(va_status, "vaCreateSurfaces");
     if (multi_thread == 0) /* upload the content for all surfaces */
         upload_source_YUV_once_for_all();
@@ -361,6 +552,16 @@ int main(int argc,char **argv)
     if (multi_thread == 1) 
         pthread_join(thread1, (void **)&ret);
     printf("thread1 is free\n");
+
+    if (test_color_conversion) {
+        // destroy temp surface/image
+        va_status = vaDestroySurfaces(va_dpy, &csc_render_surface, 1);
+        CHECK_VASTATUS(va_status,"vaDestroySurfaces");
+        
+        va_status = vaDestroyImage(va_dpy, csc_dst_fourcc_image.image_id);
+        CHECK_VASTATUS(va_status,"vaDestroyImage");
+        vaDestroyConfig (va_dpy, config_id);
+    }
     
     vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM);    
     vaTerminate(va_dpy);
-- 
1.7.9.5



More information about the Libva mailing list