| Index: third_party/libva/test/putsurface/putsurface_common.c
|
| diff --git a/third_party/libva/test/putsurface/putsurface_common.c b/third_party/libva/test/putsurface/putsurface_common.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..06f394f6586770f32210d23116048a2c62520429
|
| --- /dev/null
|
| +++ b/third_party/libva/test/putsurface/putsurface_common.c
|
| @@ -0,0 +1,367 @@
|
| +/*
|
| + * 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 <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 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 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()
|
| +{
|
| + VAImage surface_image;
|
| + void *surface_p=NULL, *U_start,*V_start;
|
| + VAStatus va_status;
|
| + 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 %x Display surface 0x%p,\n", (unsigned int)drawable, (void *)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;
|
| + }
|
| + 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;
|
| + char c;
|
| + int i;
|
| +
|
| + while ((c =getopt(argc,argv,"w:h:g:r:d:f:tcep?n:v") ) != 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(" -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 'v':
|
| + verbose = 1;
|
| + printf("Enable verbose output\n");
|
| + break;
|
| + }
|
| + }
|
| +
|
| + 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");
|
| +
|
| + va_status = vaCreateSurfaces(va_dpy,surface_width, surface_height,
|
| + VA_RT_FORMAT_YUV420, SURFACE_NUM, &surface_id[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");
|
| +
|
| + vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM);
|
| + vaTerminate(va_dpy);
|
| +
|
| + close_display(win_display);
|
| +
|
| + return 0;
|
| +}
|
|
|