[Libva] [PATCH 5/5 libva v2 resend] test: add color conversion test option in putsurface
Zhao Halley
halley.zhao at intel.com
Wed Aug 15 23:06:59 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