diff options
author | Austin Yuan <shengquan.yuan@intel.com> | 2009-11-27 17:54:30 +0800 |
---|---|---|
committer | Austin Yuan <shengquan.yuan@intel.com> | 2009-11-27 17:54:30 +0800 |
commit | b0e4126e953bada974b312cf99732870fc17418d (patch) | |
tree | 4c885491897f68a48c4e60d5201cd25442da51c8 | |
parent | ec0e66e57c4ee66b89a9a886f9d464da5893aac8 (diff) |
re-arrange test programs
Signed-off-by: Austin Yuan <shengquan.yuan@intel.com>
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | test/Makefile.am | 53 | ||||
-rw-r--r-- | test/basic/Makefile.am | 66 | ||||
-rw-r--r-- | test/basic/test.c (renamed from test/test.c) | 0 | ||||
-rw-r--r-- | test/basic/test_01.c (renamed from test/test_01.c) | 0 | ||||
-rw-r--r-- | test/basic/test_02.c (renamed from test/test_02.c) | 0 | ||||
-rw-r--r-- | test/basic/test_03.c (renamed from test/test_03.c) | 0 | ||||
-rw-r--r-- | test/basic/test_04.c (renamed from test/test_04.c) | 0 | ||||
-rw-r--r-- | test/basic/test_05.c (renamed from test/test_05.c) | 0 | ||||
-rw-r--r-- | test/basic/test_06.c (renamed from test/test_06.c) | 0 | ||||
-rw-r--r-- | test/basic/test_07.c (renamed from test/test_07.c) | 0 | ||||
-rw-r--r-- | test/basic/test_08.c (renamed from test/test_08.c) | 0 | ||||
-rw-r--r-- | test/basic/test_09.c (renamed from test/test_09.c) | 0 | ||||
-rw-r--r-- | test/basic/test_10.c (renamed from test/test_10.c) | 0 | ||||
-rw-r--r-- | test/basic/test_11.c (renamed from test/test_11.c) | 0 | ||||
-rw-r--r-- | test/basic/test_common.c (renamed from test/test_common.c) | 0 | ||||
-rw-r--r-- | test/basic/testplan.txt (renamed from test/testplan.txt) | 0 | ||||
-rw-r--r-- | test/decode/Makefile.am | 36 | ||||
-rw-r--r-- | test/decode/mpeg2-I.gif | bin | 0 -> 103275 bytes | |||
-rw-r--r-- | test/decode/mpeg2-I.m2v (renamed from test/mpeg2-I.mpg) | bin | 197 -> 197 bytes | |||
-rw-r--r-- | test/decode/mpeg2vldemo.c (renamed from test/test_12.c) | 196 | ||||
-rw-r--r-- | test/encode/Makefile.am | 36 | ||||
-rw-r--r-- | test/encode/h264encode.c | 428 | ||||
-rw-r--r-- | test/mpeg2-I.jpg | bin | 144089 -> 0 bytes | |||
-rw-r--r-- | test/putsurface/Makefile.am | 36 | ||||
-rw-r--r-- | test/putsurface/loadsurface.h | 97 | ||||
-rw-r--r-- | test/putsurface/putsurface.c | 343 |
27 files changed, 1166 insertions, 129 deletions
diff --git a/configure.ac b/configure.ac index c3aba90..b99c6b1 100644 --- a/configure.ac +++ b/configure.ac @@ -126,6 +126,10 @@ AC_OUTPUT([ i965_drv_video/shaders/mpeg2/vld/Makefile i965_drv_video/shaders/render/Makefile test/Makefile + test/basic/Makefile + test/decode/Makefile + test/putsurface/Makefile + test/encode/Makefile libva.pc libva-x11.pc ]) diff --git a/test/Makefile.am b/test/Makefile.am index 58e1677..5734226 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -20,62 +20,17 @@ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -check_PROGRAMS = test_01 test_02 test_03 test_04 test_05 test_06 \ - test_07 test_08 test_09 test_10 test_11 test_12 bin_PROGRAMS = vainfo -testdir = $(bindir) +AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/test/basic -I$(top_srcdir)/src/x11 -DIN_LIBVA -AM_CFLAGS = -I$(top_srcdir)/../../include/external/ -I$(top_srcdir)/src -I$(top_srcdir)/src/x11 -DIN_LIBVA - -TESTS = $(check_PROGRAMS) - -TEST_LIBS = $(top_srcdir)/src/$(libvabackendlib) vainfo_LDADD = $(top_srcdir)/src/$(libvabackendlib) vainfo_DEPENDENCIES = $(top_srcdir)/src/$(libvabackendlib) vainfo_SOURCES = vainfo.c -test_01_LDADD = $(TEST_LIBS) -test_01_SOURCES = test_01.c - -test_02_LDADD = $(TEST_LIBS) -test_02_SOURCES = test_02.c - -test_03_LDADD = $(TEST_LIBS) -test_03_SOURCES = test_03.c - -test_04_LDADD = $(TEST_LIBS) -test_04_SOURCES = test_04.c - -test_05_LDADD = $(TEST_LIBS) -test_05_SOURCES = test_05.c - -test_06_LDADD = $(TEST_LIBS) -test_06_SOURCES = test_06.c - -test_07_LDADD = $(TEST_LIBS) -test_07_SOURCES = test_07.c - -test_08_LDADD = $(TEST_LIBS) -test_08_SOURCES = test_08.c - -test_09_LDADD = $(TEST_LIBS) -test_09_SOURCES = test_09.c - -test_10_LDADD = $(TEST_LIBS) -test_10_SOURCES = test_10.c - -test_11_LDADD = $(TEST_LIBS) -test_11_SOURCES = test_11.c - -test_12_LDADD = $(TEST_LIBS) -test_12_SOURCES = test_12.c - -EXTRA_DIST = test_common.c mpeg2-I.jpg mpeg2-I.mpg +SUBDIRS = basic decode encode putsurface -valgrind: $(check_PROGRAMS) - for a in $(check_PROGRAMS); do \ - valgrind --leak-check=full --show-reachable=yes .libs/$$a; \ - done +valgrind: vainfo + valgrind --leak-check=full --show-reachable=yes .libs/vainfo; diff --git a/test/basic/Makefile.am b/test/basic/Makefile.am new file mode 100644 index 0000000..78eabcb --- /dev/null +++ b/test/basic/Makefile.am @@ -0,0 +1,66 @@ +# Copyright (c) 2007 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. + +bin_PROGRAMS = test_01 test_02 test_03 test_04 test_05 test_06 \ + test_07 test_08 test_09 test_10 test_11 + +TEST_LIBS = $(top_srcdir)/src/$(libvabackendlib) + +test_01_LDADD = $(TEST_LIBS) +test_01_SOURCES = test_01.c + +test_02_LDADD = $(TEST_LIBS) +test_02_SOURCES = test_02.c + +test_03_LDADD = $(TEST_LIBS) +test_03_SOURCES = test_03.c + +test_04_LDADD = $(TEST_LIBS) +test_04_SOURCES = test_04.c + +test_05_LDADD = $(TEST_LIBS) +test_05_SOURCES = test_05.c + +test_06_LDADD = $(TEST_LIBS) +test_06_SOURCES = test_06.c + +test_07_LDADD = $(TEST_LIBS) +test_07_SOURCES = test_07.c + +test_08_LDADD = $(TEST_LIBS) +test_08_SOURCES = test_08.c + +test_09_LDADD = $(TEST_LIBS) +test_09_SOURCES = test_09.c + +test_10_LDADD = $(TEST_LIBS) +test_10_SOURCES = test_10.c + +test_11_LDADD = $(TEST_LIBS) +test_11_SOURCES = test_11.c + +EXTRA_DIST = test_common.c + +valgrind: $(bin_PROGRAMS) + for a in $(bin_PROGRAMS); do \ + valgrind --leak-check=full --show-reachable=yes .libs/$$a; \ + done diff --git a/test/test.c b/test/basic/test.c index 2e98b12..2e98b12 100644 --- a/test/test.c +++ b/test/basic/test.c diff --git a/test/test_01.c b/test/basic/test_01.c index 4075655..4075655 100644 --- a/test/test_01.c +++ b/test/basic/test_01.c diff --git a/test/test_02.c b/test/basic/test_02.c index 5622a18..5622a18 100644 --- a/test/test_02.c +++ b/test/basic/test_02.c diff --git a/test/test_03.c b/test/basic/test_03.c index d2af494..d2af494 100644 --- a/test/test_03.c +++ b/test/basic/test_03.c diff --git a/test/test_04.c b/test/basic/test_04.c index 2e3329c..2e3329c 100644 --- a/test/test_04.c +++ b/test/basic/test_04.c diff --git a/test/test_05.c b/test/basic/test_05.c index f88dd15..f88dd15 100644 --- a/test/test_05.c +++ b/test/basic/test_05.c diff --git a/test/test_06.c b/test/basic/test_06.c index ca47e50..ca47e50 100644 --- a/test/test_06.c +++ b/test/basic/test_06.c diff --git a/test/test_07.c b/test/basic/test_07.c index cb1edce..cb1edce 100644 --- a/test/test_07.c +++ b/test/basic/test_07.c diff --git a/test/test_08.c b/test/basic/test_08.c index 8c743b6..8c743b6 100644 --- a/test/test_08.c +++ b/test/basic/test_08.c diff --git a/test/test_09.c b/test/basic/test_09.c index 7d6cd4b..7d6cd4b 100644 --- a/test/test_09.c +++ b/test/basic/test_09.c diff --git a/test/test_10.c b/test/basic/test_10.c index 6a7b978..6a7b978 100644 --- a/test/test_10.c +++ b/test/basic/test_10.c diff --git a/test/test_11.c b/test/basic/test_11.c index 8f3c4b8..8f3c4b8 100644 --- a/test/test_11.c +++ b/test/basic/test_11.c diff --git a/test/test_common.c b/test/basic/test_common.c index 91774da..91774da 100644 --- a/test/test_common.c +++ b/test/basic/test_common.c diff --git a/test/testplan.txt b/test/basic/testplan.txt index 1cc573b..1cc573b 100644 --- a/test/testplan.txt +++ b/test/basic/testplan.txt diff --git a/test/decode/Makefile.am b/test/decode/Makefile.am new file mode 100644 index 0000000..9283671 --- /dev/null +++ b/test/decode/Makefile.am @@ -0,0 +1,36 @@ +# Copyright (c) 2007 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. + +bin_PROGRAMS = mpeg2vldemo + +AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/x11 -DIN_LIBVA + +TEST_LIBS = $(top_srcdir)/src/$(libvabackendlib) + +mpeg2vldemo_LDADD = $(TEST_LIBS) +mpeg2vldemo_SOURCES = mpeg2vldemo.c + + +valgrind: $(bin_PROGRAMS) + for a in $(bin_PROGRAMS); do \ + valgrind --leak-check=full --show-reachable=yes .libs/$$a; \ + done diff --git a/test/decode/mpeg2-I.gif b/test/decode/mpeg2-I.gif Binary files differnew file mode 100644 index 0000000..81a25eb --- /dev/null +++ b/test/decode/mpeg2-I.gif diff --git a/test/mpeg2-I.mpg b/test/decode/mpeg2-I.m2v Binary files differindex f00fa01..f00fa01 100644 --- a/test/mpeg2-I.mpg +++ b/test/decode/mpeg2-I.m2v diff --git a/test/test_12.c b/test/decode/mpeg2vldemo.c index c9e4db9..945b69d 100644 --- a/test/test_12.c +++ b/test/decode/mpeg2vldemo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Intel Corporation. All Rights Reserved. + * Copyright (c) 2007-2008 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 @@ -22,23 +22,38 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#define TEST_DESCRIPTION "Sample MPEG2 VLD Decoding" - -#ifdef IN_LIBVA -#include <va_x11.h> -#else -#include <va/va_x11.h> -#endif +/* + * it is a real program to show how VAAPI decode work, + * It does VLD decode for a simple MPEG2 clip "mpeg2-I.m2v" + * "mpeg2-I.m2v" and VA parameters are hardcoded into mpeg2vldemo.c, + * See mpeg2-I.jif to know how those VA parameters come from + * + * gcc -o mpeg2vldemo mpeg2vldemo.c -lva -lva-x11 + * ./mpeg2vldemo : only do decode + * ./mpeg2vldemo <any parameter >: decode+display + * + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> +#include <X11/Xlib.h> -#include "test_common.c" +#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> -void pre() -{ - test_init(); +#include <assert.h> + +#include <va/va.h> +#include <va/va_x11.h> + +#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); \ } /* Data dump of a 16x16 MPEG2 video clip,it has one I frame @@ -120,23 +135,43 @@ static VASliceParameterBufferMPEG2 slice_param={ #define CLIP_WIDTH 16 #define CLIP_HEIGHT 16 -int surf_width=CLIP_WIDTH,surf_height=CLIP_HEIGHT; -int win_width=CLIP_WIDTH<<1,win_height=CLIP_HEIGHT<<1; +#define WIN_WIDTH (CLIP_WIDTH<<1) +#define WIN_HEIGHT (CLIP_HEIGHT<<1) -void test() +int main(int argc,char **argv) { VAEntrypoint entrypoints[5]; int num_entrypoints,vld_entrypoint; VAConfigAttrib attrib; VAConfigID config_id; - VASurfaceID vaSurface; - VAContextID vaContext; - VABufferID vaPicParamBuf,vaIQMatrixBuf,vaSliceParamBuf,vaSliceDataBuf; - Window win = 0; + VASurfaceID surface_id; + VAContextID context_id; + VABufferID pic_param_buf,iqmatrix_buf,slice_param_buf,slice_data_buf; + int major_ver, minor_ver; + Display *x11_display; + VADisplay va_dpy; + VAStatus va_status; + int putsurface=0; + + if (argc > 1) + putsurface=1; + + x11_display = XOpenDisplay(":0.0"); + + if (x11_display == NULL) { + fprintf(stderr, "Can't connect X server!\n"); + exit(-1); + } + + assert(x11_display); + + va_dpy = vaGetDisplay(x11_display); + va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); + assert(va_status == VA_STATUS_SUCCESS); va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileMPEG2Main, entrypoints, &num_entrypoints); - ASSERT( VA_STATUS_SUCCESS == va_status ); + CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints"); for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; vld_entrypoint++) { if (entrypoints[vld_entrypoint] == VAEntrypointVLD) @@ -144,107 +179,108 @@ void test() } if (vld_entrypoint == num_entrypoints) { /* not find VLD entry point */ - ASSERT(0); + assert(0); } /* Assuming finding VLD, find out the format for the render target */ attrib.type = VAConfigAttribRTFormat; - va_status = vaGetConfigAttributes(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD, + vaGetConfigAttributes(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD, &attrib, 1); - ASSERT( VA_STATUS_SUCCESS == va_status ); if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) { /* not find desired YUV420 RT format */ - ASSERT(0); + assert(0); } va_status = vaCreateConfig(va_dpy, VAProfileMPEG2Main, VAEntrypointVLD, &attrib, 1,&config_id); - ASSERT( VA_STATUS_SUCCESS == va_status ); - - va_status = vaCreateSurfaces(va_dpy,surf_width,surf_height, - VA_RT_FORMAT_YUV420, 1, &vaSurface); - ASSERT( VA_STATUS_SUCCESS == va_status ); + CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints"); + + va_status = vaCreateSurfaces(va_dpy,CLIP_WIDTH,CLIP_HEIGHT, + VA_RT_FORMAT_YUV420, 1, &surface_id); + CHECK_VASTATUS(va_status, "vaCreateSurfaces"); /* Create a context for this decode pipe */ va_status = vaCreateContext(va_dpy, config_id, CLIP_WIDTH, ((CLIP_HEIGHT+15)/16)*16, VA_PROGRESSIVE, - &vaSurface, + &surface_id, 1, - &vaContext); - ASSERT( VA_STATUS_SUCCESS == va_status ); + &context_id); + CHECK_VASTATUS(va_status, "vaCreateContext"); - va_status = vaCreateBuffer(va_dpy, vaContext, + va_status = vaCreateBuffer(va_dpy, context_id, VAPictureParameterBufferType, sizeof(VAPictureParameterBufferMPEG2), 1, &pic_param, - &vaPicParamBuf); - ASSERT( VA_STATUS_SUCCESS == va_status ); - - va_status = vaCreateBuffer(va_dpy, vaContext, + &pic_param_buf); + CHECK_VASTATUS(va_status, "vaCreateBuffer"); + + va_status = vaCreateBuffer(va_dpy, context_id, VAIQMatrixBufferType, sizeof(VAIQMatrixBufferMPEG2), 1, &iq_matrix, - &vaIQMatrixBuf ); - ASSERT( VA_STATUS_SUCCESS == va_status ); + &iqmatrix_buf ); + CHECK_VASTATUS(va_status, "vaCreateBuffer"); - va_status = vaCreateBuffer(va_dpy, vaContext, + va_status = vaCreateBuffer(va_dpy, context_id, VASliceParameterBufferType, sizeof(VASliceParameterBufferMPEG2), 1, - &slice_param, &vaSliceParamBuf); - ASSERT( VA_STATUS_SUCCESS == va_status ); + &slice_param, &slice_param_buf); + CHECK_VASTATUS(va_status, "vaCreateBuffer"); - va_status = vaCreateBuffer(va_dpy, vaContext, + va_status = vaCreateBuffer(va_dpy, context_id, VASliceDataBufferType, 0xc4-0x2f+1, 1, mpeg2_clip+0x2f, - &vaSliceDataBuf); - ASSERT( VA_STATUS_SUCCESS == va_status ); - - va_status = vaBeginPicture(va_dpy, vaContext, vaSurface); - ASSERT( VA_STATUS_SUCCESS == va_status ); - - va_status = vaRenderPicture(va_dpy,vaContext, &vaPicParamBuf, 1); - ASSERT( VA_STATUS_SUCCESS == va_status ); - - va_status = vaRenderPicture(va_dpy,vaContext, &vaIQMatrixBuf, 1); - ASSERT( VA_STATUS_SUCCESS == va_status ); + &slice_data_buf); + CHECK_VASTATUS(va_status, "vaCreateBuffer"); - va_status = vaRenderPicture(va_dpy,vaContext, &vaSliceParamBuf, 1); - ASSERT( VA_STATUS_SUCCESS == va_status ); + va_status = vaBeginPicture(va_dpy, context_id, surface_id); + CHECK_VASTATUS(va_status, "vaBeginPicture"); - va_status = vaRenderPicture(va_dpy,vaContext, &vaSliceDataBuf, 1); - ASSERT( VA_STATUS_SUCCESS == va_status ); - - va_status = vaEndPicture(va_dpy,vaContext); - ASSERT( VA_STATUS_SUCCESS == va_status ); - - va_status = vaSyncSurface(va_dpy, vaSurface); - ASSERT( VA_STATUS_SUCCESS == va_status ); + va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1); + CHECK_VASTATUS(va_status, "vaRenderPicture"); + + va_status = vaRenderPicture(va_dpy,context_id, &iqmatrix_buf, 1); + CHECK_VASTATUS(va_status, "vaRenderPicture"); + + va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1); + CHECK_VASTATUS(va_status, "vaRenderPicture"); - win = XCreateSimpleWindow(dpy, RootWindow(dpy, 0), 0, 0, - win_width,win_height, 0, 0, WhitePixel(dpy, 0)); - XMapWindow(dpy, win); - XSync(dpy, False); + va_status = vaRenderPicture(va_dpy,context_id, &slice_data_buf, 1); + CHECK_VASTATUS(va_status, "vaRenderPicture"); + + va_status = vaEndPicture(va_dpy,context_id); + CHECK_VASTATUS(va_status, "vaEndPicture"); - va_status = vaPutSurface(va_dpy, vaSurface, win, - 0,0,surf_width,surf_height, - 0,0,win_width,win_height, - NULL,0,0); - ASSERT( VA_STATUS_SUCCESS == va_status ); + va_status = vaSyncSurface(va_dpy, surface_id); + CHECK_VASTATUS(va_status, "vaSyncSurface"); + + if (putsurface) { + Window win; + win = XCreateSimpleWindow(x11_display, RootWindow(x11_display, 0), 0, 0, + WIN_WIDTH,WIN_HEIGHT, 0, 0, WhitePixel(x11_display, 0)); + XMapWindow(x11_display, win); + XSync(x11_display, False); + va_status = vaPutSurface(va_dpy, surface_id, win, + 0,0,CLIP_WIDTH,CLIP_HEIGHT, + 0,0,WIN_WIDTH,WIN_HEIGHT, + NULL,0,0); + CHECK_VASTATUS(va_status, "vaPutSurface"); + } printf("press any key to exit\n"); getchar(); - - vaDestroySurfaces(va_dpy,&vaSurface,1); + + vaDestroySurfaces(va_dpy,&surface_id,1); vaDestroyConfig(va_dpy,config_id); - vaDestroyContext(va_dpy,vaContext); -} + vaDestroyContext(va_dpy,context_id); -void post() -{ - test_terminate(); + vaTerminate(va_dpy); + XCloseDisplay(x11_display); + + return 0; } diff --git a/test/encode/Makefile.am b/test/encode/Makefile.am new file mode 100644 index 0000000..6d2d5a9 --- /dev/null +++ b/test/encode/Makefile.am @@ -0,0 +1,36 @@ +# Copyright (c) 2007 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. + +bin_PROGRAMS = h264encode + +AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/x11 -DIN_LIBVA + +TEST_LIBS = $(top_srcdir)/src/$(libvabackendlib) + +h264encode_LDADD = $(TEST_LIBS) +h264encode_SOURCES = h264encode.c + + +valgrind: $(bin_PROGRAMS) + for a in $(bin_PROGRAMS); do \ + valgrind --leak-check=full --show-reachable=yes .libs/$$a; \ + done diff --git a/test/encode/h264encode.c b/test/encode/h264encode.c new file mode 100644 index 0000000..4a4d914 --- /dev/null +++ b/test/encode/h264encode.c @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2007-2008 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. + */ + +/* + * it is a real program to show how VAAPI encoding work, + * It does H264 element stream level encoding on auto-generated YUV data + * + * gcc -o h264encode h264encode -lva -lva-x11 -I /usr/include/va + * ./h264encode -w <width> -h <height> -n <frame_num> + * + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> +#include <X11/Xlib.h> + +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <assert.h> + +#include "va.h" +#include "va_x11.h" + + +#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); \ +} + +#define SURFACE_NUM 18 /* 16 surfaces for src, 2 surface for reconstructed/reference */ + +static Display *x11_display; +static VADisplay va_dpy; +static VAContextID context_id; +static VASurfaceID surface_id[SURFACE_NUM]; +static Window display_win = 0; +static int win_width; +static int win_height; + +static int coded_fd; +static char coded_file[256]; + +static int frame_width=352, frame_height=288; +static int frame_rate = 30; +static int frame_count = 1000; +static int intra_count = 30; +static int frame_bitrate = 64000; +static int initial_qp = 15; +static int minimal_qp = 0; + +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=8; + int row_shift=0; + int i; + + for (i=0; i<SURFACE_NUM-2; i++) { + upload_surafce(va_dpy, surface_id[i], box_width, row_shift, 0); + + row_shift++; + if (row_shift==(2*box_width)) row_shift= 0; + } + + return 0; +} + + +static int save_coded_buf(VABufferID coded_buf, int current_frame, int frame_skipped) +{ + void *coded_p=NULL; + int coded_size,coded_offset,wrt_size; + VAStatus va_status; + + va_status = vaMapBuffer(va_dpy,coded_buf,&coded_p); + coded_size = *((unsigned long *) coded_p); /* first DWord is the coded video size */ + coded_offset = *((unsigned long *) (coded_p + 4)); /* second DWord is byte offset */ + wrt_size = write(coded_fd,coded_p+coded_offset,coded_size); + assert(wrt_size==coded_size); + vaUnmapBuffer(va_dpy,coded_buf); + + + printf("\r "); /* return back to startpoint */ + switch (current_frame % 4) { + case 0: + printf("|"); + break; + case 1: + printf("/"); + break; + case 2: + printf("-"); + break; + case 3: + printf("\\"); + break; + } + printf("%08d", current_frame); + if (current_frame % intra_count == 0) + printf("(I)"); + else + printf("(P)"); + + printf("(%06d bytes coded)",coded_size); + if (frame_skipped) + printf("(SKipped)"); + + return; +} + + +static int display_surface(int current_frame, int *exit_encode) +{ + Window win = display_win; + XEvent event; + VAStatus va_status; + + if (current_frame == 0) { + win_width = frame_width; + win_height = frame_height; + } + + if (win == 0) { /* display reconstructed surface */ + win = XCreateSimpleWindow(x11_display, RootWindow(x11_display, 0), 0, 0, + frame_width, frame_height, 0, 0, WhitePixel(x11_display, 0)); + XMapWindow(x11_display, win); + XSync(x11_display, False); + + display_win = win; + } + + *exit_encode = 0; + while(XPending(x11_display)) { + XNextEvent(x11_display, &event); + + /* bail on any focused key press */ + if(event.type == KeyPress) { + *exit_encode = 1; + break; + } + + /* rescale the video to fit the window */ + if(event.type == ConfigureNotify) { + win_width = event.xconfigure.width; + win_height = event.xconfigure.height; + } + } + + va_status = vaPutSurface(va_dpy, surface_id[current_frame], win, + 0,0, frame_width, frame_height, + 0,0, win_width, win_height, + NULL,0,0); + return; +} + +enum { + SH_LEVEL_1=10, + SH_LEVEL_1B=11, + SH_LEVEL_2=20, + SH_LEVEL_3=30, + SH_LEVEL_31=31, + SH_LEVEL_32=32, + SH_LEVEL_4=40, + SH_LEVEL_5=50 +}; + +static int do_h264_encoding(void) +{ + VAEncSequenceParameterBufferH264 seq_h264; + VAEncPictureParameterBufferH264 pic_h264; + VAEncSliceParameterBuffer slice_h264; + VAStatus va_status; + VABufferID coded_buf, seq_param_buf, pic_param_buf, slice_param_buf; + int codedbuf_size; + VASurfaceStatus surface_status; + int src_surface, dst_surface, ref_surface; + int putsurface=0, frame_skipped = 0; + int exit_encode = 0; + int i; + + codedbuf_size = (frame_width * frame_height * 400) / (16*16); + + src_surface = 0; + + /* the last two frames are reference/reconstructed frame */ + dst_surface = SURFACE_NUM - 1; + ref_surface = SURFACE_NUM - 2; + + for (i=0; i < frame_count; i++) { + va_status = vaBeginPicture(va_dpy, context_id, surface_id[src_surface]); + CHECK_VASTATUS(va_status,"vaBeginPicture"); + + if (i == 0) { + seq_h264.level_idc = SH_LEVEL_3; + seq_h264.picture_width_in_mbs = frame_width; + seq_h264.picture_height_in_mbs = frame_height; + seq_h264.bits_per_second = frame_bitrate; + seq_h264.frame_rate = frame_rate; + seq_h264.initial_qp = initial_qp; + seq_h264.min_qp = minimal_qp; + seq_h264.basic_unit_size = 6; + seq_h264.intra_period = intra_count; + + va_status = vaCreateBuffer(va_dpy, context_id, + VAEncSequenceParameterBufferType, + sizeof(seq_h264),1,&seq_h264,&seq_param_buf); + CHECK_VASTATUS(va_status,"vaCreateBuffer");; + + va_status = vaRenderPicture(va_dpy,context_id, &seq_param_buf, 1); + CHECK_VASTATUS(va_status,"vaRenderPicture");; + } + + va_status = vaCreateBuffer(va_dpy,context_id,VAEncCodedBufferType, + codedbuf_size, 1, NULL, &coded_buf); + + /* if a frame is skipped, current frame still use last reference frame */ + if (frame_skipped == 0) { + /* swap ref/dst */ + int tmp = dst_surface; + dst_surface = ref_surface; + ref_surface = tmp; + } + + pic_h264.reference_picture = surface_id[ref_surface]; + pic_h264.reconstructed_picture= surface_id[dst_surface]; + pic_h264.coded_buf = coded_buf; + pic_h264.picture_width = frame_width; + pic_h264.picture_height = frame_height; + pic_h264.last_picture = (i==frame_count); + + va_status = vaCreateBuffer(va_dpy, context_id,VAEncPictureParameterBufferType, + sizeof(pic_h264),1,&pic_h264,&pic_param_buf); + CHECK_VASTATUS(va_status,"vaCreateBuffer");; + + /* one frame, one slice */ + slice_h264.start_row_number = 0; + slice_h264.slice_height = frame_height/16; /* Measured by MB */ + slice_h264.slice_flags.bits.is_intra = i % intra_count; + slice_h264.slice_flags.bits.disable_deblocking_filter_idc = 0; + va_status = vaCreateBuffer(va_dpy,context_id,VAEncSliceParameterBufferType, + sizeof(slice_h264),1,&slice_h264,&slice_param_buf); + CHECK_VASTATUS(va_status,"vaCreateBuffer");; + + va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1); + CHECK_VASTATUS(va_status,"vaRenderPicture");; + + va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1); + CHECK_VASTATUS(va_status,"vaRenderPicture");; + + va_status = vaEndPicture(va_dpy,context_id); + CHECK_VASTATUS(va_status,"vaEndPicture");; + + va_status = vaSyncSurface(va_dpy, surface_id[0]); + CHECK_VASTATUS(va_status,"vaSyncSurface");; + + va_status = vaQuerySurfaceStatus(va_dpy, surface_id[src_surface],&surface_status); + frame_skipped = (surface_status & VASurfaceSkipped); + + save_coded_buf(coded_buf, i, frame_skipped); + + /* should display reconstructed frame, but just diplay source frame */ + display_surface(src_surface, &exit_encode); + if (exit_encode) + frame_count = i; + + /* use next surface */ + src_surface++; + if (src_surface == (SURFACE_NUM - 2)) + src_surface = 0; + } + + return 0; +} + +int main(int argc,char **argv) +{ + VAEntrypoint entrypoints[5]; + int num_entrypoints,slice_entrypoint; + VAConfigAttrib attrib[2]; + VAConfigID config_id; + int major_ver, minor_ver; + VAStatus va_status; + char c; + + strcpy(coded_file, "/tmp/demo.264"); + while ((c =getopt(argc,argv,"w:h:n:p:f:r:q:s:o:?") ) != EOF) { + switch (c) { + case 'w': + frame_width = atoi(optarg); + break; + case 'h': + frame_height = atoi(optarg); + break; + case 'n': + frame_count = atoi(optarg); + break; + case 'p': + intra_count = atoi(optarg); + break; + case 'f': + frame_rate = atoi(optarg); + break; + case 'b': + frame_bitrate = atoi(optarg); + break; + case 'q': + initial_qp = atoi(optarg); + break; + case 's': + minimal_qp = atoi(optarg); + break; + case 'o': + strcpy(coded_file, optarg); + break; + case ':': + case '?': + printf("./h264encode <options>\n"); + printf(" -w -h: resolution\n"); + printf(" -n frame number\n"); + printf(" -p P frame count between two I frames\n"); + printf(" -f frame rate\n"); + printf(" -r bit rate\n"); + printf(" -q initial QP\n"); + printf(" -s maximum QP\n"); + printf(" -s coded file\n"); + exit(0); + } + } + + x11_display = XOpenDisplay(":0.0"); + assert(x11_display); + + va_dpy = vaGetDisplay(x11_display); + va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); + CHECK_VASTATUS(va_status, "vaInitialize"); + + vaQueryConfigEntrypoints(va_dpy, VAProfileH264Baseline, entrypoints, + &num_entrypoints); + for (slice_entrypoint = 0; slice_entrypoint < num_entrypoints; slice_entrypoint++) { + if (entrypoints[slice_entrypoint] == VAEntrypointEncSlice) + break; + } + if (slice_entrypoint == num_entrypoints) { + /* not find Slice entry point */ + assert(0); + } + + /* find out the format for the render target, and rate control mode */ + attrib[0].type = VAConfigAttribRTFormat; + attrib[1].type = VAConfigAttribRateControl; + vaGetConfigAttributes(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice, + &attrib[0], 2); + if ((attrib[0].value & VA_RT_FORMAT_YUV420) == 0) { + /* not find desired YUV420 RT format */ + assert(0); + } + if ((attrib[1].value & VA_RC_VBR) == 0) { + /* Can't find matched RC mode */ + printf("VBR mode doesn't found, exit\n"); + assert(0); + } + attrib[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */ + attrib[1].value = VA_RC_VBR; /* set to desired RC mode */ + + va_status = vaCreateConfig(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice, + &attrib[0], 2,&config_id); + CHECK_VASTATUS(va_status, "vaCreateConfig"); + + va_status = vaCreateSurfaces(va_dpy,frame_width, frame_height, + VA_RT_FORMAT_YUV420, SURFACE_NUM, &surface_id[0]); + CHECK_VASTATUS(va_status, "vaCreateSurfaces"); + + /* Create a context for this decode pipe */ + va_status = vaCreateContext(va_dpy, config_id, + frame_width, ((frame_height+15)/16)*16, + VA_PROGRESSIVE,&surface_id[0],SURFACE_NUM,&context_id); + CHECK_VASTATUS(va_status, "vaCreateContext"); + + /* store coded data into a file */ + coded_fd = open(coded_file,O_CREAT|O_RDWR, 0); + if (coded_fd == -1) { + printf("Open file %s failed, exit\n", coded_file); + exit(1); + } + + printf("Coded %d frames, %dx%d, save the coded file into %s\n", + frame_count, frame_width, frame_height, coded_file); + do_h264_encoding(); + + vaDestroySurfaces(va_dpy,&surface_id[0],3); + vaDestroyConfig(va_dpy,config_id); + vaDestroyContext(va_dpy,context_id); + + vaTerminate(va_dpy); + + XCloseDisplay(x11_display); + + return 0; +} diff --git a/test/mpeg2-I.jpg b/test/mpeg2-I.jpg Binary files differdeleted file mode 100644 index f5a6c50..0000000 --- a/test/mpeg2-I.jpg +++ /dev/null diff --git a/test/putsurface/Makefile.am b/test/putsurface/Makefile.am new file mode 100644 index 0000000..3e5c864 --- /dev/null +++ b/test/putsurface/Makefile.am @@ -0,0 +1,36 @@ +# Copyright (c) 2007 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. + +bin_PROGRAMS = putsurface + +AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/x11 -DIN_LIBVA + +TEST_LIBS = $(top_srcdir)/src/$(libvabackendlib) + +putsurface_LDADD = $(TEST_LIBS) +putsurface_SOURCES = putsurface.c + + +valgrind: $(bin_PROGRAMS) + for a in $(bin_PROGRAMS); do \ + valgrind --leak-check=full --show-reachable=yes .libs/$$a; \ + done diff --git a/test/putsurface/loadsurface.h b/test/putsurface/loadsurface.h new file mode 100644 index 0000000..4c5da2d --- /dev/null +++ b/test/putsurface/loadsurface.h @@ -0,0 +1,97 @@ + + +static int yuvgen_planar(int width, int height, + unsigned char *Y_start, int Y_pitch, + unsigned char *U_start, int U_pitch, + unsigned char *V_start, int V_pitch, + int UV_interleave, int box_width, int row_shift, + int field) +{ + int row; + + /* copy Y plane */ + for (row=0;row<height;row++) { + unsigned char *Y_row = Y_start + row * Y_pitch; + int jj, xpos, ypos; + + ypos = (row / box_width) & 0x1; + + /* fill garbage data into the other field */ + if (((field == VA_TOP_FIELD) && (row &1)) + || ((field == VA_BOTTOM_FIELD) && ((row &1)==0))) { + memset(Y_row, 0xff, width); + continue; + } + + for (jj=0; jj<width; jj++) { + xpos = ((row_shift + jj) / box_width) & 0x1; + + if ((xpos == 0) && (ypos == 0)) + Y_row[jj] = 0xeb; + if ((xpos == 1) && (ypos == 1)) + Y_row[jj] = 0xeb; + + if ((xpos == 1) && (ypos == 0)) + Y_row[jj] = 0x10; + if ((xpos == 0) && (ypos == 1)) + Y_row[jj] = 0x10; + } + } + + /* copy UV data */ + for( row =0; row < height/2; row++) { + unsigned short value = 0x80; + + /* fill garbage data into the other field */ + if (((field == VA_TOP_FIELD) && (row &1)) + || ((field == VA_BOTTOM_FIELD) && ((row &1)==0))) { + value = 0xff; + } + + if (UV_interleave) { + unsigned short *UV_row = (unsigned short *)(U_start + row * U_pitch); + + memset(UV_row, value, width); + } else { + unsigned char *U_row = U_start + row * U_pitch; + unsigned char *V_row = V_start + row * V_pitch; + + memset (U_row,value,width/2); + memset (V_row,value,width/2); + } + } + + return 0; +} + +static int upload_surface(VADisplay va_dpy, VASurfaceID surface_id, + int box_width, int row_shift, + int field) +{ + VAImage surface_image; + void *surface_p=NULL, *U_start,*V_start; + VAStatus va_status; + + va_status = vaDeriveImage(va_dpy,surface_id,&surface_image); + CHECK_VASTATUS(va_status,"vaDeriveImage"); + + vaMapBuffer(va_dpy,surface_image.buf,&surface_p); + assert(VA_STATUS_SUCCESS == va_status); + + U_start = surface_p + surface_image.offsets[1]; + V_start = surface_p + surface_image.offsets[2]; + + /* assume surface is planar format */ + yuvgen_planar(surface_image.width, surface_image.height, + surface_p, surface_image.pitches[0], + U_start, surface_image.pitches[1], + V_start, surface_image.pitches[2], + (surface_image.format.fourcc==VA_FOURCC_NV12), + box_width, row_shift, field); + + vaUnmapBuffer(va_dpy,surface_image.buf); + + vaDestroyImage(va_dpy,surface_image.image_id); + + return 0; +} diff --git a/test/putsurface/putsurface.c b/test/putsurface/putsurface.c new file mode 100644 index 0000000..359d1e0 --- /dev/null +++ b/test/putsurface/putsurface.c @@ -0,0 +1,343 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <sys/time.h> + +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <va/va.h> +#include <va/va_x11.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 5 +static VASurfaceID surface_id[SURFACE_NUM]; +static int surface_width=352, surface_height=288; +static int win_width=352, win_height=288; +static Window win_thread0, win_thread1; +static Pixmap pixmap_thread0, pixmap_thread1; +static GC context_thread0, context_thread1; +static Display *x11_display; +static VADisplay *va_dpy; +static int multi_thread=0; +static int put_pixmap = 0; +static int test_clip = 1; +static int display_field = VA_FRAME_PICTURE; +static int check_event = 1; +static int verbose=0; +static pthread_mutex_t surface_mutex[SURFACE_NUM]; + +static pthread_mutex_t gmutex; + +static int box_width=32; + +static Pixmap create_pixmap(int width, int height) +{ + int screen = DefaultScreen(x11_display); + Window root; + Pixmap pixmap; + XWindowAttributes attr; + + root = RootWindow(x11_display, screen); + + XGetWindowAttributes (x11_display, root, &attr); + + printf("Create a pixmap from ROOT window %dx%d\n\n", attr.width, attr.height); + pixmap = XCreatePixmap(x11_display, root, attr.width, attr.height, + DefaultDepth(x11_display, DefaultScreen(x11_display))); + + return pixmap; +} + +static int create_window(int width, int height) +{ + int screen = DefaultScreen(x11_display); + Window root, win; + + root = RootWindow(x11_display, screen); + + printf("Create window0 for thread0\n"); + win_thread0 = win = XCreateSimpleWindow(x11_display, root, 0, 0, width, height, + 0, 0, WhitePixel(x11_display, 0)); + if (win) { + XSizeHints sizehints; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize; + XSetNormalHints(x11_display, win, &sizehints); + XSetStandardProperties(x11_display, win, "Thread 0", "Thread 0", + None, (char **)NULL, 0, &sizehints); + + XMapWindow(x11_display, win); + } + context_thread0 = XCreateGC(x11_display, win, 0, 0); + XSelectInput(x11_display, win, KeyPressMask | StructureNotifyMask); + XSync(x11_display, False); + + if (put_pixmap) + pixmap_thread0 = create_pixmap(width, height); + + if (multi_thread == 0) + return 0; + + printf("Create window1 for thread1\n"); + + win_thread1 = win = XCreateSimpleWindow(x11_display, root, width, 0, width, height, + 0, 0, WhitePixel(x11_display, 0)); + if (win) { + XSizeHints sizehints; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize; + XSetNormalHints(x11_display, win, &sizehints); + XSetStandardProperties(x11_display, win, "Thread 1", "Thread 1", + None, (char **)NULL, 0, &sizehints); + + XMapWindow(x11_display, win); + } + if (put_pixmap) + pixmap_thread1 = create_pixmap(width, height); + + context_thread1 = XCreateGC(x11_display, win, 0, 0); + XSelectInput(x11_display, win, KeyPressMask | StructureNotifyMask); + XSync(x11_display, False); + + return 0; +} + +static VASurfaceID get_next_free_surface(int *index) +{ + VASurfaceStatus surface_status; + int i; + + assert(index); + + for (i=0; i<SURFACE_NUM; i++) { + surface_status = 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 putsurface_thread(void *data) +{ + int width=win_width, height=win_height; + Drawable draw; + Window win = (Window)data; + Pixmap pixmap = 0; + GC context = NULL; + int quit = 0; + VAStatus vaStatus; + int row_shift = 0; + int index = 0; + Bool is_event; + XEvent event; + + if (win == win_thread0) { + printf("Enter into thread0\n\n"); + pixmap = pixmap_thread0; + context = context_thread0; + } + + if (win == win_thread1) { + printf("Enter into thread1\n\n"); + pixmap = pixmap_thread1; + context = context_thread1; + } + + if (put_pixmap) { + printf("vaPutSurface into a Pixmap, then copy into the Window\n\n"); + draw = pixmap; + } else { + printf("vaPutSurface into a Window directly\n\n"); + draw = win; + } + + 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)win, (void *)surface_id); + + upload_surface(va_dpy, surface_id, box_width, row_shift, display_field); + + vaStatus = vaPutSurface(va_dpy, surface_id, draw, + 0,0,surface_width,surface_height, + 0,0,width,height, + NULL,0,display_field); + CHECK_VASTATUS(vaStatus,"vaPutSurface"); + + if (put_pixmap) + XCopyArea(x11_display, pixmap, win, context, 0, 0, width, height, 0, 0); + + pthread_mutex_unlock(&surface_mutex[index]); + + if (check_event) { + pthread_mutex_lock(&gmutex); + is_event =XCheckWindowEvent(x11_display, win, StructureNotifyMask|KeyPressMask,&event); + pthread_mutex_unlock(&gmutex); + if (is_event) { + /* bail on any focused key press */ + if(event.type == KeyPress) { + quit = 1; + break; + } + + /* rescale the video to fit the window */ + if(event.type == ConfigureNotify) { + width = event.xconfigure.width; + height = event.xconfigure.height; + printf("Scale window to %dx%d\n", width, height); + } + } + } + + row_shift++; + if (row_shift==(2*box_width)) row_shift= 0; + } + + pthread_exit(NULL); +} + + +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:d:f:tep?nv") ) != EOF) { + switch (c) { + case '?': + printf("putsurface <options>\n"); + printf(" -p output to pixmap\n"); + printf(" -d the dimension of black/write square box, default is 32\n"); + printf(" -t multi-threads\n"); + printf(" -e don't check X11 event\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 'w': + win_width = atoi(optarg); + break; + case 'h': + win_height = 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; + } + } + + x11_display = XOpenDisplay(":0.0"); + if (x11_display == NULL) { + fprintf(stderr, "Can't connect X server!\n"); + exit(-1); + } + + create_window(win_width, win_height); + + va_dpy = vaGetDisplay(x11_display); + va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); + CHECK_VASTATUS(va_status, "vaInitialize"); + + surface_width = win_width; + surface_height = win_height; + va_status = vaCreateSurfaces(va_dpy,surface_width, surface_height, + VA_RT_FORMAT_YUV420, SURFACE_NUM, &surface_id[0]); + CHECK_VASTATUS(va_status, "vaCreateSurfaces"); + + 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, (void *)putsurface_thread, (void*)win_thread1); + + putsurface_thread((void *)win_thread0); + + if (multi_thread == 1) + pthread_join(thread1, (void **)&ret); + + vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM); + vaTerminate(va_dpy); + + return 0; +} |