[Libva] [PATCH 4/6 v2 libva] test: add color conversion test option in putsurface

Zhao Halley halley.zhao at intel.com
Tue Jun 26 23:45:20 PDT 2012


- command line:  ./putsurface -x "fmt1==>fmt2"
- example:       ./putsurface -x "YUYV==>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 |  200 ++++++++++++++++++++++++++++++++---
 1 files changed, 186 insertions(+), 14 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..2728e20
--- 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,10 @@ 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;
 
 static VASurfaceID get_next_free_surface(int *index)
 {
@@ -206,13 +211,38 @@ 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) {
+            // 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)
@@ -248,7 +278,110 @@ static void* putsurface_thread(void *data)
     return 0;
 }
 
+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},
+};
+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;
+
+}
+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_src_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 == VA_FOURCC_YUY2) {
+            find_src_fourcc = 1;
+        }
+    }
+    if (!find_src_fourcc) {
+        test_color_conversion = 0;
+        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)) {
+        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)
+    va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, 
+                                 surface_width, surface_height,
+                                 &csc_render_surface, 1, 
+                                 NULL, 0);
+    CHECK_VASTATUS(va_status,"vaCreateSurfaces");
+    
+    // decide surface format here by derive an image 
+    // so surface is renderable for vaPutSurface
+    VAImage temp_image;
+    va_status = vaDeriveImage(va_dpy,csc_render_surface,&temp_image);
+    vaDestroyImage(va_dpy,temp_image.image_id);
+
+cleanup:
+    return test_color_conversion;
+}
 int main(int argc,char **argv)
 {
     int major_ver, minor_ver;
@@ -257,8 +390,9 @@ 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) {
+    while ((c =getopt(argc,argv,"w:h:g:r:d:f:tcep?nx:v") ) != EOF) {
         switch (c) {
             case '?':
                 printf("putsurface <options>\n");
@@ -269,6 +403,8 @@ 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("           -x fmt1==>fmt2 (test color conversion, for example: YV12==>YUY2) \n");
+                printf("              additionally, fmt2 is converted for rendering when possible) \n");
                 printf("           -v verbose output\n");
                 exit(0);
                 break;
@@ -319,6 +455,27 @@ int main(int argc,char **argv)
                 } else
                     printf("The validate input for -f is: 1(top field)/2(bottom field)\n");
                 break;
+            case 'x':
+                ret = sscanf(optarg, "%c%c%c%c==>%c%c%c%c", str_src_fmt, str_src_fmt+1, str_src_fmt+2, str_src_fmt+3, 
+                    str_dst_fmt, str_dst_fmt+1, str_dst_fmt+2, str_dst_fmt+3);
+                if (ret != 8) {
+                    printf("invalid color conversion, an valid example: NV12==>YUY2\n");
+                    exit(0);
+                } else {
+                    str_src_fmt[4] = '\0';
+                    str_dst_fmt[4] = '\0';
+                    printf("color conversion: %s ==> %s\n", str_src_fmt, str_dst_fmt);
+                }
+
+                csc_src_fourcc = map_str_to_vafourcc (str_src_fmt);
+                csc_dst_fourcc = map_str_to_vafourcc (str_dst_fmt);
+
+                if (!csc_src_fourcc || ! csc_dst_fourcc) {
+                    printf("invalid color format, exit\n");
+                    exit(0);
+                }
+                test_color_conversion = 1;
+                break;
             case 'v':
                 verbose = 1;
                 printf("Enable verbose output\n");
@@ -337,12 +494,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 +523,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.4.1



More information about the Libva mailing list