diff options
author | Zhao Halley <halley.zhao@intel.com> | 2012-09-05 17:23:22 +0800 |
---|---|---|
committer | Xiang, Haihao <haihao.xiang@intel.com> | 2013-06-07 15:32:43 +0800 |
commit | 19bb972bf4ba5b5369164072e2e8cd77ae6e65a4 (patch) | |
tree | e8c7ecaa20355fbd3832c342cd1eeb7d9fe4b98a /test | |
parent | 824a70ae1ef79458e65079374209a0cb16b65c31 (diff) | |
download | libva-19bb972bf4ba5b5369164072e2e8cd77ae6e65a4.tar.gz |
test: add color conversion test option in putsurface
- 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
Diffstat (limited to 'test')
-rwxr-xr-x[-rw-r--r--] | test/putsurface/putsurface_common.c | 233 |
1 files changed, 217 insertions, 16 deletions
diff --git a/test/putsurface/putsurface_common.c b/test/putsurface/putsurface_common.c index 5b5058e..1fddbbe 100644..100755 --- 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); |