diff options
Diffstat (limited to 'test/putsurface/putsurface_common.c')
-rwxr-xr-x | test/putsurface/putsurface_common.c | 685 |
1 files changed, 0 insertions, 685 deletions
diff --git a/test/putsurface/putsurface_common.c b/test/putsurface/putsurface_common.c deleted file mode 100755 index fa0249a..0000000 --- a/test/putsurface/putsurface_common.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * Copyright (c) 2008-2009 Intel Corporation. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stdint.h> -#include <getopt.h> - -#include <sys/time.h> - -#include <unistd.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <assert.h> -#include <pthread.h> - -/*currently, if XCheckWindowEvent was called in more than one thread, it would cause - * XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0.0" - * after 87 requests (83 known processed) with 0 events remaining. - * - * X Error of failed request: BadGC (invalid GC parameter) - * Major opcode of failed request: 60 (X_FreeGC) - * Resource id in failed request: 0x600034 - * Serial number of failed request: 398 - * Current serial number in output stream: 399 - * The root cause is unknown. */ - -#define CHECK_VASTATUS(va_status,func) \ -if (va_status != VA_STATUS_SUCCESS) { \ - fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \ - exit(1); \ -} -#include "../loadsurface.h" - -#define SURFACE_NUM 16 - -static void *win_display; -static VADisplay va_dpy; -static VAImageFormat *va_image_formats; -static int va_num_image_formats = -1; -static VAConfigID vpp_config_id = VA_INVALID_ID; -static VASurfaceAttrib *va_surface_attribs; -static int va_num_surface_attribs = -1; -static VASurfaceID surface_id[SURFACE_NUM]; -static pthread_mutex_t surface_mutex[SURFACE_NUM]; - -static void *drawable_thread0, *drawable_thread1; -static int surface_width = 352, surface_height = 288; -static int win_x = 0, win_y = 0; -static int win_width = 352, win_height = 288; -static int frame_rate = 0; -static unsigned long long frame_num_total = ~0; -static int check_event = 1; -static int put_pixmap = 0; -static int test_clip = 0; -static int display_field = VA_FRAME_PICTURE; -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; - -} - -static int -va_value_equals(const VAGenericValue *v1, const VAGenericValue *v2) -{ - if (v1->type != v2->type) - return 0; - - switch (v1->type) { - case VAGenericValueTypeInteger: - return v1->value.i == v2->value.i; - case VAGenericValueTypeFloat: - return v1->value.f == v2->value.f; - case VAGenericValueTypePointer: - return v1->value.p == v2->value.p; - case VAGenericValueTypeFunc: - return v1->value.fn == v2->value.fn; - } - return 0; -} - -static int -ensure_image_formats(void) -{ - VAStatus va_status; - VAImageFormat *image_formats; - int num_image_formats; - - if (va_num_image_formats >= 0) - return va_num_image_formats; - - num_image_formats = vaMaxNumImageFormats(va_dpy); - if (num_image_formats == 0) - return 0; - - image_formats = malloc(num_image_formats * sizeof(*image_formats)); - if (!image_formats) - return 0; - - va_status = vaQueryImageFormats(va_dpy, image_formats, &num_image_formats); - CHECK_VASTATUS(va_status, "vaQuerySurfaceAttributes()"); - - va_image_formats = image_formats; - va_num_image_formats = num_image_formats; - return num_image_formats; -} - -static const VAImageFormat * -lookup_image_format(uint32_t fourcc) -{ - int i; - - if (!ensure_image_formats()) - return NULL; - - for (i = 0; i < va_num_image_formats; i++) { - const VAImageFormat * const image_format = &va_image_formats[i]; - if (image_format->fourcc == fourcc) - return image_format; - } - return NULL; -} - -static int -ensure_surface_attribs(void) -{ - VAStatus va_status; - VASurfaceAttrib *surface_attribs; - unsigned int num_image_formats, num_surface_attribs; - - if (va_num_surface_attribs >= 0) - return va_num_surface_attribs; - - num_image_formats = vaMaxNumImageFormats(va_dpy); - if (num_image_formats == 0) - return 0; - - va_status = vaCreateConfig(va_dpy, VAProfileNone, VAEntrypointVideoProc, - NULL, 0, &vpp_config_id); - CHECK_VASTATUS(va_status, "vaCreateConfig()"); - - /* Guess the number of surface attributes, thus including any - pixel-format supported by the VA driver */ - num_surface_attribs = VASurfaceAttribCount + num_image_formats; - surface_attribs = malloc(num_surface_attribs * sizeof(*surface_attribs)); - if (!surface_attribs) - return 0; - - va_status = vaQuerySurfaceAttributes(va_dpy, vpp_config_id, - surface_attribs, &num_surface_attribs); - if (va_status == VA_STATUS_SUCCESS) - va_surface_attribs = surface_attribs; - else if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) { - va_surface_attribs = realloc(surface_attribs, - num_surface_attribs * sizeof(*va_surface_attribs)); - if (!va_surface_attribs) { - free(surface_attribs); - return 0; - } - va_status = vaQuerySurfaceAttributes(va_dpy, vpp_config_id, - va_surface_attribs, &num_surface_attribs); - } - CHECK_VASTATUS(va_status, "vaQuerySurfaceAttributes()"); - va_num_surface_attribs = num_surface_attribs; - return num_surface_attribs; -} - -static const VASurfaceAttrib * -lookup_surface_attrib(VASurfaceAttribType type, const VAGenericValue *value) -{ - int i; - - if (!ensure_surface_attribs()) - return NULL; - - for (i = 0; i < va_num_surface_attribs; i++) { - const VASurfaceAttrib * const surface_attrib = &va_surface_attribs[i]; - if (surface_attrib->type != type) - continue; - if (!(surface_attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) - continue; - if (va_value_equals(&surface_attrib->value, value)) - return surface_attrib; - } - return NULL; -} - -int csc_preparation () -{ - VAStatus va_status; - - // 1. make sure dst fourcc is supported for vaImage - if (!lookup_image_format(csc_dst_fourcc)) { - test_color_conversion = 0; - printf("VA driver doesn't support %s image, skip additional color conversion\n", map_vafourcc_to_str(csc_dst_fourcc)); - goto cleanup; - } - - // 2. make sure src_fourcc is supported for vaSurface - VASurfaceAttrib surface_attribs[1], * const s_attrib = &surface_attribs[0]; - s_attrib->type = VASurfaceAttribPixelFormat; - s_attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; - s_attrib->value.type = VAGenericValueTypeInteger; - s_attrib->value.value.i = csc_src_fourcc; - - if (!lookup_surface_attrib(VASurfaceAttribPixelFormat, &s_attrib->value)) { - printf("VA driver doesn't support %s surface, skip additional color conversion\n", map_vafourcc_to_str(csc_src_fourcc)); - 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, - surface_attribs, 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->value.value.i = VA_FOURCC_NV12; - va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, - surface_width, surface_height, - &csc_render_surface, 1, - surface_attribs, 1); - CHECK_VASTATUS(va_status,"vaCreateSurfaces"); - - -cleanup: - return test_color_conversion; -} - -static VASurfaceID get_next_free_surface(int *index) -{ - VASurfaceStatus surface_status; - int i; - - assert(index); - - if (multi_thread == 0) { - i = *index; - i++; - if (i == SURFACE_NUM) - i = 0; - *index = i; - - return surface_id[i]; - } - - for (i=0; i<SURFACE_NUM; i++) { - surface_status = (VASurfaceStatus)0; - vaQuerySurfaceStatus(va_dpy, surface_id[i], &surface_status); - if (surface_status == VASurfaceReady) - { - if (0 == pthread_mutex_trylock(&surface_mutex[i])) - { - *index = i; - break; - } - } - } - - if (i==SURFACE_NUM) - return VA_INVALID_SURFACE; - else - return surface_id[i]; -} - -static int upload_source_YUV_once_for_all() -{ - int box_width_loc=8; - int row_shift_loc=0; - int i; - - for (i=0; i<SURFACE_NUM; i++) { - printf("\rLoading data into surface %d.....", i); - upload_surface(va_dpy, surface_id[i], box_width_loc, row_shift_loc, 0); - - row_shift_loc++; - if (row_shift_loc==(2*box_width_loc)) row_shift_loc= 0; - } - printf("\n"); - - return 0; -} - -/* - * Helper function for profiling purposes - */ -static unsigned long get_tick_count(void) -{ - struct timeval tv; - if (gettimeofday(&tv, NULL)) - return 0; - return tv.tv_usec/1000+tv.tv_sec*1000; -} - -static void update_clipbox(VARectangle *cliprects, int width, int height) -{ - if (test_clip == 0) - return; - - srand((unsigned)time(NULL)); - - cliprects[0].x = (rand() % width); - cliprects[0].y = (rand() % height); - cliprects[0].width = (rand() % (width - cliprects[0].x)); - cliprects[0].height = (rand() % (height - cliprects[0].y)); - - cliprects[1].x = (rand() % width); - cliprects[1].y = (rand() % height); - cliprects[1].width = (rand() % (width - cliprects[1].x)); - cliprects[1].height = (rand() % (height - cliprects[1].y)); - printf("\nTest clip (%d,%d, %d x %d) and (%d,%d, %d x %d) \n", - cliprects[0].x, cliprects[0].y, cliprects[0].width, cliprects[0].height, - cliprects[1].x, cliprects[1].y, cliprects[1].width, cliprects[1].height); -} - -static void* putsurface_thread(void *data) -{ - int width=win_width, height=win_height; - void *drawable = data; - int quit = 0; - VAStatus vaStatus; - int row_shift = 0; - int index = 0; - unsigned int frame_num=0, start_time, putsurface_time; - VARectangle cliprects[2]; /* client supplied clip list */ - int continue_display = 0; - - if (drawable == drawable_thread0) - printf("Enter into thread0\n\n"); - if (drawable == drawable_thread1) - printf("Enter into thread1\n\n"); - - putsurface_time = 0; - while (!quit) { - VASurfaceID surface_id = VA_INVALID_SURFACE; - - while (surface_id == VA_INVALID_SURFACE) - surface_id = get_next_free_surface(&index); - - if (verbose) printf("Thread: %p Display surface 0x%x,\n", drawable, surface_id); - - if (multi_thread) - upload_surface(va_dpy, surface_id, box_width, row_shift, display_field); - - if (check_event) - pthread_mutex_lock(&gmutex); - - start_time = get_tick_count(); - if ((continue_display == 0) && getenv("FRAME_STOP")) { - char c; - printf("Press any key to display frame %d...(c/C to continue)\n", frame_num); - c = getchar(); - if (c == 'c' || c == 'C') - continue_display = 1; - } - 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) - pthread_mutex_unlock(&gmutex); - - pthread_mutex_unlock(&surface_mutex[index]); /* locked in get_next_free_surface */ - - if ((frame_num % 0xff) == 0) { - fprintf(stderr, "%.2f FPS \r", 256000.0 / (float)putsurface_time); - putsurface_time = 0; - update_clipbox(cliprects, width, height); - } - - if (check_event) - check_window_event(win_display, drawable, &width, &height, &quit); - - if (multi_thread) { /* reload surface content */ - row_shift++; - if (row_shift==(2*box_width)) row_shift= 0; - } - - if (frame_rate != 0) /* rough framerate control */ - usleep(1000/frame_rate*1000); - - frame_num++; - if (frame_num >= frame_num_total) - quit = 1; - } - - if (drawable == drawable_thread1) - pthread_exit(NULL); - - return 0; -} -int main(int argc,char **argv) -{ - int major_ver, minor_ver; - VAStatus va_status; - pthread_t thread1; - int ret; - int c; - int i; - char str_src_fmt[5], str_dst_fmt[5]; - - 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"); - printf(" -g <widthxheight+x_location+y_location> window geometry\n"); - printf(" -w/-h resolution of surface\n"); - printf(" -r <framerate>\n"); - printf(" -d the dimension of black/write square box, default is 32\n"); - 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; - case 'g': - ret = sscanf(optarg, "%dx%d+%d+%d", &win_width, &win_height, &win_x, &win_y); - if (ret != 4) { - printf("invalid window geometry, must be widthxheight+x_location+y_location\n"); - exit(0); - } else - printf("Create window at (%d, %d), width = %d, height = %d\n", - win_x, win_y, win_width, win_height); - break; - case 'r': - frame_rate = atoi(optarg); - break; - case 'w': - surface_width = atoi(optarg); - break; - case 'h': - surface_height = atoi(optarg); - break; - case 'n': - frame_num_total = atoi(optarg); - break; - case 'd': - box_width = atoi(optarg); - break; - case 't': - multi_thread = 1; - printf("Two threads to do vaPutSurface\n"); - break; - case 'e': - check_event = 0; - break; - case 'p': - put_pixmap = 1; - break; - case 'c': - test_clip = 1; - break; - case 'f': - if (atoi(optarg) == 1) { - printf("Display TOP field\n"); - display_field = VA_TOP_FIELD; - } else if (atoi(optarg) == 2) { - printf("Display BOTTOM field\n"); - display_field = VA_BOTTOM_FIELD; - } 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"); - break; - } - } - - 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"); - exit(-1); - } - create_window(win_display, win_x, win_y, win_width, win_height); - - va_dpy = vaGetDisplay(win_display); - va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); - CHECK_VASTATUS(va_status, "vaInitialize"); - - 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(); - - if (check_event) - pthread_mutex_init(&gmutex, NULL); - - for(i = 0; i< SURFACE_NUM; i++) - pthread_mutex_init(&surface_mutex[i], NULL); - - if (multi_thread == 1) - ret = pthread_create(&thread1, NULL, putsurface_thread, (void*)drawable_thread1); - - putsurface_thread((void *)drawable_thread0); - - 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"); - } - - if (vpp_config_id != VA_INVALID_ID) { - vaDestroyConfig (va_dpy, vpp_config_id); - vpp_config_id = VA_INVALID_ID; - } - - vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM); - vaTerminate(va_dpy); - - free(va_image_formats); - free(va_surface_attribs); - close_display(win_display); - - return 0; -} |