AUTOMAKE_OPTIONS = foreign
SUBDIRS = src man
+if HAVE_FT
+SUBDIRS += tests/functional
+endif
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
AC_PROG_CC
+AC_PROG_CC_STDC
AM_PROG_AS
+AM_PROG_CC_C_O
AH_TOP([#include "xorg-server.h"])
[Enable use of libpciaccess (default: disabled)]),
[PCIACCESS=$enableval], [PCIACCESS=no])
+AC_ARG_ENABLE(ftests,
+AS_HELP_STRING([--enable-ftests], [Enable functional tests (default: no)]),
+ [FT="$enableval"], [FT="no"])
# Checks for extensions
+PKG_CHECK_MODULES(XORG, xorg-server)
XORG_DRIVER_CHECK_EXT(RANDR, randrproto)
XORG_DRIVER_CHECK_EXT(RENDER, renderproto)
XORG_DRIVER_CHECK_EXT(XV, videoproto)
# Checks for pkg-config packages
PKG_CHECK_MODULES(PROTO, [xproto fontsproto])
-PKG_CHECK_MODULES(XORG, xorg-server >= 1.15.0,
- [AC_DEFINE(LATEST_XORG, [1], ["temp define for backward compatibility with old xorg-server"])],
- [PKG_CHECK_MODULES(XORG, xorg-server >= 1.0.0)])
+
+if pkg-config --exists 'xorg-server >= 1.15.0'; then
+ AC_DEFINE([LATEST_XORG], 1, [define for backward compatibility with old xorg-server])
+fi
sdkdir=$(pkg-config --variable=sdkdir xorg-server)
-# check the conditions
-EXYNOS_CFALGS=""
+
+ftests=no
+FT_CFLAGS=""
+FT_LIBS=""
+EXYNOS_CFLAGS=""
EXYNOS_LIBS=""
+if test "x$FT" != "xno"; then
+ PKG_CHECK_MODULES(XCB, [xcb xcb-atom xcb-shm xcb-xv xcb-util xcb-dri2], [ftests=yes],
+ [ftests=no])
+ if test "x$FT" = "xyes" -a "x$ftests" != "xyes"; then
+ AC_MSG_ERROR([Not find xcb library for functional tests])
+ fi
+ FT_CFLAGS="$XCB_CFLAGS "
+ FT_LIBS="$XCB_LIBS "
+fi
+
+AM_CONDITIONAL(HAVE_FT, test "x$ftests" = "xyes")
-PKG_CHECK_MODULES(XDBG, xdbg)
+# check the conditions
+PKG_CHECK_MODULES(XDBG, [xdbg], [xdbg=yes], [xdbg=no])
PKG_CHECK_MODULES(DRM, libdrm)
PKG_CHECK_MODULES(LIBTBM, libtbm)
PKG_CHECK_MODULES(UDEV, [libudev], [udev=yes], [udev=no])
+
+if test x"$xdbg" = xno; then
+ AC_MSG_ERROR([Not find xdbg lib])
+fi
+
if test x"$udev" = xyes; then
AC_DEFINE(HAVE_UDEV,1,[Enable udev-based monitor hotplug detection])
fi
-EXYNOS_CFLAGS="$EXYNOS_CFLAGS $PROTO_CFLAGS $XDBG_CFLAGS"
-EXYNOS_LIBS="$EXYNOS_LIBS $PROTO_CFLAGS $XDBG_LIBS"
-
-EXYNOS_CFLAGS="$EXYNOS_CFLAGS $DRM_CFLAGS $LIBTBM_CFLAGS "
-EXYNOS_LIBS="$EXYNOS_LIBS $DRM_LIBS $LIBTBM_LIBS "
-
-EXYNOS_CFLAGS="$EXYNOS_CFLAGS $UDEV_CFALGS "
-EXYNOS_LIBS="$EXYNOS_LIBS $UDEV_LIBS "
+EXYNOS_CFLAGS="$EXYNOS_CFLAGS $PROTO_CFLAGS $XDBG_CFLAGS $DRM_CFLAGS $LIBTBM_CFLAGS $UDEV_CFALGS"
+EXYNOS_LIBS="$EXYNOS_LIBS $XDBG_LIBS $DRM_LIBS $LIBTBM_LIBS $UDEV_LIBS $XDBG_LIBS"
+FT_CFLAGS="$FT_CFLAGS $EXYNOS_CFLAGS"
+FT_LIBS="$FT_LIBS $EXYNOS_LIBS"
AM_CONDITIONAL(PCIACCESS, [test "x$PCIACCESS" = xyes])
if test "x$PCIACCESS" = xyes; then
AC_SUBST([EXYNOS_CFLAGS])
AC_SUBST([EXYNOS_LIBS])
+AC_SUBST([FT_CFLAGS])
+AC_SUBST([FT_LIBS])
AC_SUBST([XORG_CFLAGS])
AC_SUBST([moduledir])
XORG_MANPAGE_SECTIONS
XORG_RELEASE_VERSION
-AC_OUTPUT([
+AC_CONFIG_FILES([
Makefile
src/Makefile
man/Makefile
+ tests/functional/Makefile
+ tests/functional/xv_test/Makefile
])
+AC_OUTPUT
--- /dev/null
+SUBDIRS = xv_test
--- /dev/null
+if HAVE_FT
+bin_PROGRAMS = test_xv
+test_xv_CFLAGS = @FT_CFLAGS@ \
+-I@top_srcdir@/tests/functional/xv_test \
+-I@top_srcdir@/src/xv
+test_xv_LDADD = @FT_LIBS@
+test_xv_SOURCES = \
+@top_srcdir@/tests/functional/xv_test/xv_test.c \
+@top_srcdir@/tests/functional/xv_test/data.c \
+@top_srcdir@/tests/functional/xv_test/xcb_api.c \
+@top_srcdir@/tests/functional/xv_test/test_xv_resize.c
+endif
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include "data.h"
+#include <xcb/shm.h>
+#include <xcb/dri2.h>
+#include <tbm_bufmgr.h>
+#include <xf86drm.h>
+#include <assert.h>
+#include <sys/shm.h>
+#include <fcntl.h>
+#include "xv_types.h"
+#include <string.h>
+
+static tbm_bufmgr bufmgr_p = NULL;
+typedef struct
+{
+ int fd;
+ error_s error;
+} dri_fd_s;
+
+static dri_fd_s
+open_dri2 (xcb_connection_t *c, xcb_screen_t *screen)
+{
+ xcb_dri2_connect_cookie_t dri2_conn_ck;
+ xcb_dri2_connect_reply_t *dri2_conn_reply_p = NULL;
+ xcb_dri2_authenticate_cookie_t dri2_auth_ck;
+ xcb_dri2_authenticate_reply_t *dri2_auth_reply_p = NULL;
+ xcb_generic_error_t *error_p = NULL;
+ int error = -1;
+ dri_fd_s ret = {};
+ char *device_name_p = NULL;
+ drm_magic_t drm_magic;
+ xcb_window_t window_id = screen->root;
+
+ dri2_conn_ck = xcb_dri2_connect(c, window_id, XCB_DRI2_DRIVER_TYPE_DRI);
+ dri2_conn_reply_p = xcb_dri2_connect_reply(c, dri2_conn_ck, &error_p);
+ if (error_p)
+ {
+ ret.error.error_str = "Can't connect to DRI2 driver";
+ ret.error.error_code = error_p->error_code;
+ goto close;
+ }
+
+ device_name_p = strndup(xcb_dri2_connect_device_name (dri2_conn_reply_p),
+ xcb_dri2_connect_device_name_length (dri2_conn_reply_p));
+
+ ret.fd = open(device_name_p, O_RDWR);
+
+ if (ret.fd < 0)
+ {
+ ret.error.error_str = "Can't open DRI2 file descriptor";
+ ret.error.error_code = ret.fd;
+ goto close;
+ }
+
+ error = drmGetMagic(ret.fd, &drm_magic);
+ if (error < 0)
+ {
+ ret.error.error_str = "Can't get drm magic";
+ ret.error.error_code = error;
+ goto close;
+ }
+
+ dri2_auth_ck = xcb_dri2_authenticate(c, window_id, drm_magic);
+ dri2_auth_reply_p = xcb_dri2_authenticate_reply(c, dri2_auth_ck, &error_p);
+ if (error_p)
+ {
+ ret.error.error_str = "Can't auth DRI2";
+ ret.error.error_code = error_p->error_code;
+ goto close;
+ }
+
+close:
+ if (error_p)
+ free(error_p);
+ if (dri2_conn_reply_p)
+ free(dri2_conn_reply_p);
+ if (dri2_auth_reply_p)
+ free(dri2_auth_reply_p);
+ if (device_name_p)
+ free(device_name_p);
+ return ret;
+}
+
+static shm_data_s
+open_shm(xcb_connection_t *c, size_t data_size)
+{
+ xcb_generic_error_t *error_p = NULL;
+ shm_data_s ret_shm = {};
+
+ ret_shm.shm_seg_id = xcb_generate_id (c);
+
+ int shm_id = shmget (IPC_PRIVATE, data_size, IPC_CREAT | 0777);
+ if (shm_id == -1)
+ {
+ ret_shm.error.error_str = "shm alloc error";
+ ret_shm.error.error_code = shm_id;
+ goto close;
+ }
+
+ ret_shm.shm_seg_addr = shmat (shm_id, NULL, 0);
+ if (!ret_shm.shm_seg_addr)
+ {
+ ret_shm.error.error_str = "shm attach error";
+ goto close;
+ }
+ xcb_void_cookie_t xcb_shm_c =
+ xcb_shm_attach_checked (c, ret_shm.shm_seg_id, shm_id, 0);
+ error_p = xcb_request_check (c, xcb_shm_c);
+ if (error_p)
+ {
+ ret_shm.error.error_str = "xcb_shm attach error";
+ goto close;
+ }
+close:
+ shmctl (shm_id, IPC_RMID, NULL);
+ if (error_p)
+ free(error_p);
+ return ret_shm;
+}
+
+static tbm_bo
+get_data_random (size_t size, tbm_bufmgr bufmgr)
+{
+ FILE *fp = fopen ("/dev/urandom", "r");
+ if (fp == NULL)
+ {
+ return NULL;
+ }
+
+ tbm_bo tbo = tbm_bo_alloc (bufmgr, size, TBM_BO_DEFAULT);
+ if (tbo == NULL)
+ {
+ return NULL;
+ }
+
+ /* copy raw data to tizen buffer object */
+ tbm_bo_handle bo_handle = tbm_bo_map (tbo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
+ size_t error = fread (bo_handle.ptr, 1, size , fp);
+ tbm_bo_unmap (tbo);
+ fclose (fp);
+ if (error == 0)
+ {
+ tbm_bo_unref(tbo);
+ tbo = NULL;
+ }
+ return tbo;
+}
+
+shm_data_s
+get_image_random (xcb_connection_t *p_xcb_conn, xcb_screen_t *screen,
+ size_t *sizes, int num_planes)
+{
+ shm_data_s ret = {0,};
+ XV_DATA_PTR xv_data = NULL;
+ if (bufmgr_p == NULL)
+ {
+ dri_fd_s dri2 = open_dri2 (p_xcb_conn, screen);
+ if (dri2.error.error_str)
+ {
+ ret.error = dri2.error;
+ goto close_l;
+ }
+ bufmgr_p = tbm_bufmgr_init (dri2.fd);
+ if (!bufmgr_p)
+ {
+ ret.error.error_str = "Can't open TBM connection\n";
+ ret.error.error_code = 0;
+ goto close_l;
+ }
+ }
+
+ if (sizes == NULL)
+ {
+ ret.error.error_str = "Sizes argument is NULL";
+ goto close_l;
+ }
+
+ if (num_planes > 3 || num_planes < 1)
+ {
+ ret.error.error_str = "Wrong num_planes argument";
+ goto close_l;
+ }
+ size_t full_size = 0;
+ int i;
+ for (i = 0; i < num_planes; i++)
+ {
+ full_size += sizes[i];
+ }
+ ret = open_shm(p_xcb_conn, full_size);
+ if (ret.error.error_str)
+ goto close_l;
+
+ xv_data = ret.shm_seg_addr;
+ XV_INIT_DATA (xv_data);
+ tbm_bo temp_bo = NULL;
+ switch (num_planes)
+ {
+ case 3:
+ temp_bo = get_data_random (sizes[2], bufmgr_p);
+ if (temp_bo == NULL)
+ {
+ ret.error.error_str = "Can't alloc tbm object";
+ goto close_l;
+ }
+ xv_data->CrBuf = tbm_bo_export(temp_bo);
+ case 2:
+ temp_bo = get_data_random (sizes[1], bufmgr_p);
+ if (temp_bo == NULL)
+ {
+ ret.error.error_str = "Can't alloc tbm object";
+ goto close_l;
+ }
+ xv_data->CbBuf = tbm_bo_export(temp_bo);
+ case 1:
+ temp_bo = get_data_random (sizes[0], bufmgr_p);
+ if (temp_bo == NULL)
+ {
+ ret.error.error_str = "Can't alloc tbm object\n";
+ goto close_l;
+ }
+ xv_data->YBuf = tbm_bo_export(temp_bo);
+ break;
+ }
+
+ return ret;
+close_l:
+ // TODO: Close DRI
+ // TODO: Close tbm
+ if (xv_data)
+ {
+ if (xv_data->YBuf != 0)
+ tbm_bo_unref(tbm_bo_import(bufmgr_p, xv_data->YBuf));
+ if (xv_data->CbBuf != 0)
+ tbm_bo_unref(tbm_bo_import(bufmgr_p, xv_data->CbBuf));
+ if (xv_data->CrBuf != 0)
+ tbm_bo_unref(tbm_bo_import(bufmgr_p, xv_data->CrBuf));
+ }
+
+ return ret;
+}
+
--- /dev/null
+#ifndef DATA_H
+#define DATA_H
+#include <xcb/xcb.h>
+#include <xcb/shm.h>
+#include <xcb/xv.h>
+#include "xv_test.h"
+
+typedef struct
+{
+ xcb_shm_seg_t shm_seg_id;
+ void *shm_seg_addr;
+ error_s error;
+} shm_data_s;
+
+shm_data_s get_image_random (xcb_connection_t *xcb_conn_p, xcb_screen_t *screen,
+ size_t * sizes, int num_planes);
+
+#endif // DATA_H
--- /dev/null
+#include <xcb/xcb.h>
+#include <xcb/xv.h>
+#include <xcb/shm.h>
+#include <xcb/dri2.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <xf86drm.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <tbm_bufmgr.h>
+#include <assert.h>
+#include "xv_test.h"
+#include "data.h"
+#include "xcb_api.h"
+
+typedef struct
+{
+ xcb_atom_t atom_hflip;
+ xcb_atom_t atom_vflip;
+ xcb_atom_t atom_rotate;
+ xcb_atom_t atom_buffer;
+ error_s error;
+} test_atom_s;
+
+typedef struct
+{
+ size_t steps;
+ rectangle_s *src_crop_p;
+ rectangle_s *dst_crop_p;
+} route_map_s;
+
+typedef struct
+{
+ error_s error;
+ route_map_s route_map;
+} get_route_map_s;
+
+typedef struct
+{
+ xcb_xv_port_t xv_open_port;
+ test_atom_s atoms;
+ xcb_connection_t *xcb_conn_p;
+ xcb_screen_t *screen_p;
+ xcb_window_t window_id;
+ xcb_gcontext_t gc_id;
+ route_map_s route_map;
+} test_data_s;
+
+static test_data_s *st_test_data_p = NULL;
+
+static error_s test_xv_resize_prepare(xcb_connection_t *xcb_conn_p,
+ xcb_screen_t * screen_p, rule_s rule);
+
+static error_s test_xv_resize_run(xcb_connection_t *xcb_conn_p,
+ xcb_screen_t * screen_p, rule_s rule);
+
+static error_s test_xv_resize_close(xcb_connection_t *xcb_conn_p,
+ xcb_screen_t * screen_p, rule_s rule);
+
+test_atom_s
+create_atoms (xcb_connection_t *xcb_conn_p)
+{
+ char const *atom_name_a[4] = {
+ "_USER_WM_PORT_ATTRIBUTE_HFLIP",
+ "_USER_WM_PORT_ATTRIBUTE_VFLIP",
+ "_USER_WM_PORT_ATTRIBUTE_ROTATION",
+ "XV_RETURN_BUFFER"};
+ xcb_intern_atom_cookie_t atom_ck_a[4] = {};
+ xcb_intern_atom_reply_t *atom_reply_p = NULL;
+ test_atom_s ret = {};
+ xcb_generic_error_t *error_p = NULL;
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ atom_ck_a[i] =
+ xcb_intern_atom (xcb_conn_p, 0, (uint16_t) strlen(atom_name_a[i]),
+ atom_name_a[i]);
+ }
+ for (i = 0; i < 4; i++)
+ {
+ atom_reply_p =
+ xcb_intern_atom_reply (xcb_conn_p , atom_ck_a[i], &error_p);
+
+ if (error_p)
+ {
+ ret.error.error_str = "Can't register atom";
+ ret.error.error_code = error_p->error_code;
+ goto close_l;
+ }
+ if (atom_reply_p == NULL)
+ {
+ ret.error.error_str = "Can't register atom";
+ goto close_l;
+ }
+ switch (i)
+ {
+ case 0:
+ ret.atom_hflip = atom_reply_p->atom;
+ break;
+ case 1:
+ ret.atom_vflip = atom_reply_p->atom;
+ break;
+ case 2:
+ ret.atom_rotate = atom_reply_p->atom;
+ break;
+ case 3:
+ ret.atom_buffer = atom_reply_p->atom;
+ break;
+ }
+ free(atom_reply_p);
+ atom_reply_p = NULL;
+ }
+
+close_l:
+
+ if (error_p)
+ free(error_p);
+ if (atom_reply_p)
+ free(atom_reply_p);
+ return ret;
+}
+
+get_route_map_s
+create_route_map (rule_s *rules)
+{
+ get_route_map_s ret = {};
+ rectangle_s *src_crop_p = NULL;
+ rectangle_s *dst_crop_p = NULL;
+ if (rules == NULL)
+ {
+ ret.error.error_str = "Wrong input arguments";
+ goto close_l;
+ }
+ size_t steps_width = (rules->max_width - rules->min_width)/10;
+ size_t steps_height = (rules->max_height - rules->max_height)/10;
+ size_t steps = (max(steps_width, steps_height))*2;
+
+ src_crop_p = calloc(steps, sizeof(rectangle_s));
+ if (!src_crop_p)
+ {
+ ret.error.error_str = "Can't alloc memory";
+ goto close_l;
+ }
+ dst_crop_p = calloc(steps, sizeof(rectangle_s));
+ if (!dst_crop_p)
+ {
+ ret.error.error_str = "Can't alloc memory";
+ goto close_l;
+ }
+// pace_dst_crop.height = (uint32_t)
+// ((double)(rules->max_size.height - rules->min_size.height)/
+// (rules->steps * 2));
+// pace_dst_crop.width = (uint32_t)
+// ((double)(rules->max_size.width - rules->min_size.width)/
+// (rules->steps * 2));
+// pace_src_crop.height = (uint32_t)
+// ((double)(rules->image_height - rules->min_size.height)/
+// (rules->steps * 2));
+// pace_src_crop.width = (uint32_t)
+// ((double)(rules->image_width - rules->min_size.width)/
+// (rules->steps * 2));
+ if (!rules->src_change)
+ {
+ src_crop_p[0].x = 0;
+ src_crop_p[0].y = 0;
+ src_crop_p[0].width = rules->image_width;
+ src_crop_p[0].height = rules->image_height;
+ }
+ else
+ {
+ src_crop_p[0].x = 0;
+ src_crop_p[0].y = 0;
+ src_crop_p[0].width = rules->min_width;
+ src_crop_p[0].height = rules->min_height;
+ }
+
+ if (!rules->dst_change)
+ {
+ dst_crop_p[0].x = 0;
+ dst_crop_p[0].y = 0;
+ dst_crop_p[0].width = rules->image_width;
+ dst_crop_p[0].height = rules->image_height;
+ }
+ else
+ {
+ dst_crop_p[0].x = 0;
+ dst_crop_p[0].y = 0;
+ dst_crop_p[0].width = rules->min_width;
+ dst_crop_p[0].height = rules->min_height;
+ }
+ int i;
+ for (i = 1; i < (steps/2); i++)
+ {
+ if (!rules->src_change)
+ {
+ src_crop_p[i].x = 0;
+ src_crop_p[i].y = 0;
+ src_crop_p[i].width = rules->image_width;
+ src_crop_p[i].height = rules->image_height;
+ }
+ else
+ {
+ src_crop_p[i].x = 0;
+ src_crop_p[i].y = 0;
+ src_crop_p[i].width =
+ ((src_crop_p[i-1].width + 10) <= rules->image_width) ?
+ (src_crop_p[i-1].width + 10) : src_crop_p[i-1].width;
+ src_crop_p[i].height =
+ ((src_crop_p[i-1].height + 10) <= rules->image_height) ?
+ (src_crop_p[i-1].height + 10) : src_crop_p[i-1].height;
+ }
+ if (!rules->dst_change)
+ {
+ dst_crop_p[i].x = 0;
+ dst_crop_p[i].y = 0;
+ dst_crop_p[i].width = rules->image_width;
+ dst_crop_p[i].height = rules->image_height;
+ }
+ else
+ {
+ dst_crop_p[i].x = 0;
+ dst_crop_p[i].y = 0;
+ dst_crop_p[i].width =
+ ((dst_crop_p[i-1].width + 10) <= rules->max_width) ?
+ (dst_crop_p[i-1].width + 10) : dst_crop_p[i-1].width;
+ dst_crop_p[i].height =
+ ((dst_crop_p[i-1].height + 10) <= rules->max_height) ?
+ (dst_crop_p[i-1].height + 10) : dst_crop_p[i-1].height;
+ }
+ }
+ for (i = (steps/2); i < steps; i++)
+ {
+ if (!rules->src_change)
+ {
+ src_crop_p[i].x = 0;
+ src_crop_p[i].y = 0;
+ src_crop_p[i].width = rules->image_width;
+ src_crop_p[i].height = rules->image_height;
+ }
+ else
+ {
+ src_crop_p[i].x = 0;
+ src_crop_p[i].y = 0;
+ src_crop_p[i].width =
+ ((src_crop_p[i-1].width - 10) >= rules->min_width) ?
+ (src_crop_p[i-1].width - 10) : src_crop_p[i-1].width;
+ src_crop_p[i].height =
+ ((src_crop_p[i-1].height - 10) >= rules->min_height) ?
+ (src_crop_p[i-1].height - 10) : src_crop_p[i-1].height;
+ }
+ if (!rules->dst_change)
+ {
+ dst_crop_p[i].x = 0;
+ dst_crop_p[i].y = 0;
+ dst_crop_p[i].width = rules->image_width;
+ dst_crop_p[i].height = rules->image_height;
+ }
+ else
+ {
+ dst_crop_p[i].x = 0;
+ dst_crop_p[i].y = 0;
+ dst_crop_p[i].width =
+ ((dst_crop_p[i-1].width - 10) >= rules->min_width) ?
+ (dst_crop_p[i-1].width - 10) : dst_crop_p[i-1].width;
+ dst_crop_p[i].height =
+ ((dst_crop_p[i-1].height - 10) >= rules->min_height) ?
+ (dst_crop_p[i-1].height - 10) : dst_crop_p[i-1].height;
+ }
+ }
+
+ ret.route_map.src_crop_p = src_crop_p;
+ ret.route_map.dst_crop_p = dst_crop_p;
+ ret.route_map.steps = steps;
+ return ret;
+close_l:
+ if (src_crop_p)
+ free(src_crop_p);
+ if (dst_crop_p)
+ free(dst_crop_p);
+ return ret;
+}
+test_case_s
+test_xv_resize_init (void)
+{
+ test_case_s ret = {};
+ ret.prepare_test = test_xv_resize_prepare;
+ ret.run_test = test_xv_resize_run;
+ ret.close_test = test_xv_resize_close;
+ return ret;
+}
+
+
+static error_s
+test_xv_resize_prepare(xcb_connection_t *xcb_conn_p, xcb_screen_t * screen_p, rule_s rule)
+{
+ error_s ret = {};
+ st_test_data_p = malloc(sizeof(test_data_s));
+ DBG;
+ if (!st_test_data_p)
+ {
+ ret.error_str = "Can't alloc memory for test_data_s";
+ ret.error_code = 0;
+ goto close_l;
+ }
+ st_test_data_p->xcb_conn_p = xcb_conn_p;
+ st_test_data_p->screen_p = screen_p;
+ DBG;
+ get_xv_port_s xv_port = open_adaptor (xcb_conn_p, screen_p->root);
+ if (xv_port.error.error_str)
+ {
+ ret = xv_port.error;
+ goto close_l;
+ }
+ DBG;
+ st_test_data_p->xv_open_port = xv_port.xv_port_id;
+ st_test_data_p->atoms = create_atoms (xcb_conn_p);
+ if(st_test_data_p->atoms.error.error_str)
+ {
+ ret = st_test_data_p->atoms.error;
+ goto close_l;
+ }
+ DBG;
+
+ get_window_s window = create_window(xcb_conn_p, screen_p);
+ if (window.error.error_str)
+ {
+ ret = window.error;
+ goto close_l;
+ }
+ st_test_data_p->window_id = window.window_id;
+ get_gc_s gc = create_gc (xcb_conn_p, st_test_data_p->window_id, screen_p);
+ if (gc.error.error_str)
+ {
+ ret = gc.error;
+ goto close_l;
+ }
+ st_test_data_p->gc_id = gc.gc_id;
+
+ get_route_map_s route = create_route_map (&rule);
+
+ if (route.error.error_str)
+ {
+ ret = route.error;
+ goto close_l;
+ }
+
+ st_test_data_p->route_map = route.route_map;
+ return ret;
+
+close_l:
+ DBG;
+ if (st_test_data_p)
+ free(st_test_data_p);
+/* TODO: close port */
+ st_test_data_p = NULL;
+ return ret;
+}
+static
+error_s
+test_xv_resize_run(xcb_connection_t *xcb_conn_p, xcb_screen_t * screen_p, rule_s rule)
+{
+
+ DBG;
+ xcb_generic_error_t *error_p = NULL;
+ error_s ret = {};
+ shm_data_s shm;
+ if (st_test_data_p == NULL)
+ {
+ ret.error_str = "Wrong argument";
+ return ret;
+ }
+ frame_attr_s frame[st_test_data_p->route_map.steps];
+
+ DBG;
+ get_image_attr_s image_attr =
+ get_image_attr (xcb_conn_p, st_test_data_p->xv_open_port,
+ rule.image_fourcc, rule.image_width, rule.image_height);
+ DBG;
+ if (image_attr.error.error_str)
+ {
+ ret = image_attr.error;
+ goto close_l;
+ }
+ /* get raw data */
+
+ size_t max_j = rule.count_uniqes_frames;
+ DBG;
+ int i,j = 0;
+ for (i = 0; i < st_test_data_p->route_map.steps; i++)
+ {
+
+ if (i == 0)
+ printf("Generate data:\n");
+ if (i < max_j)
+ {
+ shm = get_image_random (xcb_conn_p, screen_p,
+ image_attr.image.sizes,
+ image_attr.image.num_planes);
+ if (shm.error.error_str)
+ {
+ ret = shm.error;
+ goto close_l;
+ }
+ frame[i].segment = shm.shm_seg_id;
+ printf("%f%%\n", ((double)i/max_j));
+ }
+ else
+ {
+ if (j == max_j)
+ {
+ j = 0;
+ }
+ frame[i].segment = frame[j].segment;
+ j++;
+ }
+
+ frame[i].image_p = &image_attr.image;
+ frame[i].src_crop_p = &st_test_data_p->route_map.src_crop_p[i];
+ frame[i].dst_crop_p = &st_test_data_p->route_map.dst_crop_p[i];
+
+ }
+ DBG;
+ xcb_void_cookie_t map_window_ck =
+ xcb_map_window_checked (xcb_conn_p, st_test_data_p->window_id);
+ xcb_void_cookie_t put_image_ck =
+ put_image (xcb_conn_p, st_test_data_p->xv_open_port,
+ st_test_data_p->window_id, st_test_data_p->gc_id, &frame[0]);
+ j = 1;
+
+ error_p = xcb_request_check (xcb_conn_p, map_window_ck);
+ if (error_p)
+ {
+ ret.error_str = "Can't make transparent window";
+ ret.error_code = error_p->error_code;
+ goto close_l;
+ }
+
+ xcb_generic_event_t *e;
+ xcb_client_message_event_t* msg;
+ DBG;
+ while (1)
+ {
+ e = xcb_poll_for_event(xcb_conn_p);
+ while (e)
+ {
+ switch (e->response_type)
+ {
+ case XCB_CLIENT_MESSAGE:
+ msg = (xcb_client_message_event_t *)e;
+ if (msg->type == st_test_data_p->atoms.atom_buffer)
+ {
+ unsigned int keys[3] = {0, };
+ keys[0] = msg->data.data32[0];
+ keys[1] = msg->data.data32[1];
+ keys[2] = msg->data.data32[2];
+ printf ("receive: %d, %d, %d (<= Xorg)\n",
+ keys[0], keys[1], keys[2]);
+ }
+
+ break;
+ case XCB_EXPOSE:
+ break;
+ default:
+ break;
+ }
+ free(e);
+ e = xcb_poll_for_event(xcb_conn_p);
+ }
+
+ error_p = xcb_request_check (xcb_conn_p, put_image_ck);
+ if (error_p)
+ {
+ ret.error_str = "Can't draw image frame";
+ ret.error_code = error_p->error_code;
+ goto close_l;
+ }
+ if (j >= st_test_data_p->route_map.steps)
+ j = 0;
+ put_image_ck = put_image (xcb_conn_p, st_test_data_p->xv_open_port,
+ st_test_data_p->window_id, st_test_data_p->gc_id,
+ &frame[j]);
+ printf("src:(%dwx%dh) dst: (%dwx%dh)\n",
+ frame[j].src_crop_p->width, frame[j].src_crop_p->height,
+ frame[j].dst_crop_p->width, frame[j].dst_crop_p->height);
+ j++;
+ usleep(1000000/rule.frame_per_second);
+ }
+
+close_l:
+ if (error_p)
+ free(error_p);
+ return ret;
+}
+
+static error_s
+test_xv_resize_close(xcb_connection_t *xcb_conn_p, xcb_screen_t * screen_p, rule_s rule)
+{
+ error_s ret = {};
+ return ret;
+}
+
+#if 0
+xcb_xv_list_image_formats_reply_t *list =
+ xcb_xv_list_image_formats_reply (conn,
+ xcb_xv_list_image_formats (conn, a->base_id), NULL);
+if (list == NULL)
+ return NULL;
+
+/* Check available XVideo chromas */
+xcb_xv_query_image_attributes_reply_t *attr = NULL;
+unsigned rank = UINT_MAX;
+
+for (const xcb_xv_image_format_info_t *f =
+ xcb_xv_list_image_formats_format (list),
+ *f_end =
+ f + xcb_xv_list_image_formats_format_length (list);
+ f < f_end;
+ f++)
+#endif
--- /dev/null
+#ifndef TEST_XV_RESIZE_H
+#define TEST_XV_RESIZE_H
+#include "xv_test.h"
+test_case_s test_xv_resize_init (void);
+
+#endif // TEST_XV_RESIZE_H
--- /dev/null
+#include "xcb_api.h"
+get_image_attr_s
+get_image_attr(xcb_connection_t * xcb_conn_p, xcb_xv_port_t xv_port,
+ uint32_t fourcc_id, uint16_t width, uint16_t height)
+{
+ get_image_attr_s ret = {};
+ xcb_generic_error_t *error_p = NULL;
+ xcb_xv_query_image_attributes_reply_t * xv_attr_reply_p = NULL;
+
+ if (!xcb_conn_p || xv_port == XCB_XV_BAD_PORT)
+ {
+ ret.error.error_str = "Wrong arguments";
+ ret.error.error_code = 0;
+ goto close;
+ }
+
+ xcb_xv_query_image_attributes_cookie_t xv_attr_ck =
+ xcb_xv_query_image_attributes (xcb_conn_p /**< */,
+ xv_port /**< */,
+ fourcc_id /**< */,
+ width /**< */,
+ height /**< */);
+ xv_attr_reply_p =
+ xcb_xv_query_image_attributes_reply (xcb_conn_p /**< */,
+ xv_attr_ck /**< */,
+ &error_p /**< */);
+ if (error_p)
+ {
+ ret.error.error_str = "Can't query image attr";
+ ret.error.error_code = error_p->error_code;
+ goto close;
+ }
+
+ if (xv_attr_reply_p->data_size == 0)
+ {
+ ret.error.error_str = "Wrong input data format";
+ ret.error.error_code = 0;
+ goto close;
+ }
+
+ const uint32_t *offsets=
+ xcb_xv_query_image_attributes_offsets (xv_attr_reply_p);
+ const uint32_t *pitches=
+ xcb_xv_query_image_attributes_pitches (xv_attr_reply_p);
+ ret.image.num_planes = xv_attr_reply_p->num_planes;
+ ret.image.full_size = xv_attr_reply_p->data_size;
+ ret.image.fourcc_id = fourcc_id;
+ ret.image.width = xv_attr_reply_p->width;
+ ret.image.height = xv_attr_reply_p->height;
+ switch (ret.image.num_planes)
+ {
+ case 3:
+ ret.image.sizes[0] = offsets[1];
+ ret.image.sizes[1] = offsets[2] - offsets[1];
+ ret.image.sizes[2] = ret.image.full_size - offsets[2];
+ break;
+ case 2:
+ ret.image.sizes[1] = ret.image.full_size - offsets[1];
+ ret.image.sizes[0] = offsets[1];
+ break;
+ case 1:
+ ret.image.sizes[0] = ret.image.full_size;
+ break;
+ default:
+ ret.error.error_str = "Wrong input data format";
+ goto close;
+ break;
+ }
+ int i;
+ for (i = 0; i < ret.image.num_planes; ++i)
+ {
+ ret.image.offsets[i] = offsets[i];
+ ret.image.pitches[i] = pitches[i];
+ }
+
+close:
+
+ if (error_p)
+ free(error_p);
+ if (xv_attr_reply_p)
+ free(xv_attr_reply_p);
+
+ return ret;
+}
+
+xcb_void_cookie_t
+put_image (xcb_connection_t * xcb_conn_p, xcb_xv_port_t xv_port,
+ xcb_window_t window_id, xcb_gcontext_t gc_id, frame_attr_s *frame_p)
+{
+ xcb_void_cookie_t ret = {};
+ ret = xcb_xv_shm_put_image_checked (
+ xcb_conn_p, xv_port, window_id, gc_id,
+ frame_p->segment, frame_p->image_p->fourcc_id, 0,
+ frame_p->src_crop_p->x, frame_p->src_crop_p->y,
+ frame_p->src_crop_p->width, frame_p->src_crop_p->height,
+ frame_p->dst_crop_p->x, frame_p->dst_crop_p->y,
+ frame_p->dst_crop_p->width, frame_p->dst_crop_p->height,
+ frame_p->image_p->width, frame_p->image_p->height, 0);
+ return ret;
+}
+
+get_xv_port_s
+open_adaptor (xcb_connection_t *xcb_conn_p, xcb_window_t window_id)
+{
+ xcb_generic_error_t *error_p = NULL;
+ get_xv_port_s ret = {};
+ xcb_xv_adaptor_info_iterator_t xv_adaptor_iter;
+ xcb_xv_grab_port_reply_t *xv_grab_port_p = NULL;
+ xcb_xv_query_adaptors_cookie_t xv_adaptor_ck =
+ xcb_xv_query_adaptors (xcb_conn_p, window_id);
+ xcb_xv_query_adaptors_reply_t *xv_adaptors_list_p =
+ xcb_xv_query_adaptors_reply (xcb_conn_p, xv_adaptor_ck, &error_p);
+ if (error_p)
+ {
+ ret.error.error_str = "Can't query xv adaptor";
+ ret.error.error_code = error_p->error_code;
+ goto close;
+ }
+
+ for (xv_adaptor_iter = xcb_xv_query_adaptors_info_iterator (xv_adaptors_list_p);
+ xv_adaptor_iter.rem > 0;
+ xcb_xv_adaptor_info_next (&xv_adaptor_iter))
+ {
+ if (!(xv_adaptor_iter.data->type & XCB_XV_TYPE_IMAGE_MASK))
+ continue;
+ int i;
+ for (i = 0; i < xv_adaptor_iter.data->num_ports; i++)
+ {
+ xcb_xv_port_t xv_port = xv_adaptor_iter.data->base_id + i;
+ xcb_xv_grab_port_cookie_t xv_grab_port_c =
+ xcb_xv_grab_port (xcb_conn_p, xv_port, XCB_CURRENT_TIME);
+ xv_grab_port_p =
+ xcb_xv_grab_port_reply (xcb_conn_p, xv_grab_port_c, &error_p);
+ if (error_p)
+ {
+ ret.error.error_str = "Can't query xv adaptor";
+ ret.error.error_code = error_p->error_code;
+ goto close;
+ }
+
+ if (xv_grab_port_p && xv_grab_port_p->result == 0)
+ {
+ ret.xv_port_id = xv_port;
+ break;
+ }
+ }
+ if (ret.xv_port_id != 0)
+ {
+ break;
+ }
+ }
+
+close:
+ if (xv_adaptors_list_p)
+ free(xv_adaptors_list_p);
+ if (xv_grab_port_p)
+ free(xv_grab_port_p);
+ if (error_p)
+ free(error_p);
+
+ return ret;
+}
+
+get_gc_s
+create_gc (xcb_connection_t *xcb_conn_p, xcb_drawable_t drawable_id, xcb_screen_t * screen_p)
+{
+ get_gc_s ret = {};
+ xcb_void_cookie_t gc_ck;
+ xcb_generic_error_t *error_p = NULL;
+ uint32_t values[2];
+ ret.gc_id = xcb_generate_id (xcb_conn_p);
+ uint32_t mask = XCB_GC_GRAPHICS_EXPOSURES;
+ values[0] = 0;
+// values[0] = screen_p->white_pixel;
+ gc_ck = xcb_create_gc_checked (xcb_conn_p, ret.gc_id, drawable_id, mask, values);
+
+ error_p = xcb_request_check (xcb_conn_p, gc_ck);
+ if (error_p)
+ {
+ ret.error.error_str = "Can't create graphic context";
+ ret.error.error_code = error_p->error_code;
+ goto close;
+ }
+close:
+ if (error_p)
+ free(error_p);
+ return ret;
+}
+
+get_window_s
+create_window (xcb_connection_t *xcb_conn_p, xcb_screen_t * screen_p)
+{
+ get_window_s ret = {};
+ ret.window_id = xcb_generate_id (xcb_conn_p);
+ uint32_t mask;
+ uint32_t values[3];
+ xcb_generic_error_t *error_p = NULL;
+ mask = XCB_CW_EVENT_MASK;
+// values[0] = screen_p->black_pixel;
+ values[0] = XCB_EVENT_MASK_EXPOSURE;
+ xcb_void_cookie_t window_ck =
+ xcb_create_window_checked (xcb_conn_p,
+ screen_p->root_depth,
+ ret.window_id, screen_p->root,
+ 0, 0, screen_p->width_in_pixels,
+ screen_p->height_in_pixels,
+ 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ screen_p->root_visual,
+ mask, values);
+
+ error_p = xcb_request_check (xcb_conn_p, window_ck);
+ if (error_p)
+ {
+ ret.error.error_str = "Can't create window";
+ ret.error.error_code = error_p->error_code;
+ goto close;
+ }
+
+close:
+ if (error_p)
+ free(error_p);
+ return ret;
+}
+
+static xcb_format_t *
+find_format_by_depth (const xcb_setup_t *setup, uint8_t depth)
+{
+ xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
+ xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
+ for(; fmt != fmtend; ++fmt)
+ if(fmt->depth == depth)
+ return fmt;
+ return 0;
+}
+
+#if 1
+xcb_void_cookie_t
+make_transparent (xcb_connection_t *xcb_conn_p, xcb_screen_t * screen_p,
+ xcb_drawable_t drawable_id, xcb_gcontext_t gc_id)
+{
+ xcb_format_t *fmt = find_format_by_depth(xcb_get_setup (xcb_conn_p), 32);
+
+ uint32_t base = 1920 * fmt->bits_per_pixel;
+ uint32_t pad = fmt->scanline_pad >> 3;
+ uint32_t b = base + pad - 1;
+ /* faster if pad is a power of two */
+ if (((pad - 1) & pad) == 0)
+ b = b & -pad;
+ else
+ b = b - b % pad;
+ uint32_t size = 1080 * b;
+ uint8_t *data = (uint8_t *)calloc (1, size);
+ return
+ xcb_put_image_checked (xcb_conn_p, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable_id, gc_id,
+ screen_p->width_in_pixels, screen_p->height_in_pixels, 0, 0,
+ 0, 32, size, data);
+}
+#endif
--- /dev/null
+#ifndef XV_API_H
+#define XV_API_H
+#include <xcb/xcb.h>
+#include <xcb/xv.h>
+#include <xcb/xfixes.h>
+
+#include <xcb/xcb_util.h>
+#include "xv_test.h"
+
+typedef struct
+{
+ uint32_t width;
+ uint32_t height;
+} size_s;
+
+typedef struct
+{
+ int32_t x;
+ int32_t y;
+ uint32_t width;
+ uint32_t height;
+} rectangle_s;
+
+typedef struct
+{
+ uint32_t fourcc_id;
+ uint16_t num_planes;
+ size_t full_size;
+ size_t sizes[3];
+ uint32_t offsets[3];
+ uint32_t pitches[3];
+ uint32_t width;
+ uint32_t height;
+} image_attr_s;
+
+typedef struct
+{
+ rectangle_s *src_crop_p;
+ rectangle_s *dst_crop_p;
+ image_attr_s *image_p;
+ xcb_shm_seg_t segment;
+} frame_attr_s;
+
+typedef struct
+{
+ xcb_xv_port_t xv_port_id;
+ error_s error;
+} get_xv_port_s;
+
+typedef struct
+{
+ error_s error;
+ image_attr_s image;
+} get_image_attr_s;
+
+typedef struct
+{
+ xcb_window_t window_id;
+ error_s error;
+} get_window_s;
+
+typedef struct
+{
+ xcb_gcontext_t gc_id;
+ error_s error;
+} get_gc_s;
+
+get_gc_s create_gc (xcb_connection_t *xcb_conn_p, xcb_drawable_t drawable_id, xcb_screen_t * screen_p);
+get_window_s create_window (xcb_connection_t *xcb_conn_p, xcb_screen_t * screen_p);
+
+
+get_image_attr_s get_image_attr(xcb_connection_t * xcb_conn_p, xcb_xv_port_t xv_port,
+ uint32_t fourcc_id, uint16_t width, uint16_t height);
+get_xv_port_s open_adaptor (xcb_connection_t *xcb_conn_p, xcb_window_t window_id);
+xcb_void_cookie_t put_image (xcb_connection_t * xcb_conn_p, xcb_xv_port_t xv_port,
+ xcb_window_t window_id, xcb_gcontext_t gc_id, frame_attr_s *frame_p);
+
+xcb_void_cookie_t make_transparent (xcb_connection_t *xcb_conn_p, xcb_screen_t * screen_p,
+ xcb_drawable_t drawable_id, xcb_gcontext_t gc_id);
+#endif // XV_API_H
--- /dev/null
+#include "xv_test.h"
+#include <xcb/xcb.h>
+#include <xcb/xv.h>
+#include <xcb/shm.h>
+#include <xcb/dri2.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <xcb/dri2.h>
+#include <xf86drm.h>
+#include <fcntl.h>
+#include "xv_types.h"
+#include <tbm_bufmgr.h>
+#include "data.h"
+#include <sys/time.h>
+#include "test_xv_resize.h"
+
+typedef struct
+{
+ size_t num_tests;
+ test_case_s * test_case_array;
+ error_s * error_array;
+} test_map_s;
+
+error_s
+check_xv (xcb_connection_t *xcb_conn_p)
+{
+ xcb_xv_query_extension_cookie_t xv_cookie;
+ xcb_xv_query_extension_reply_t *xv_reply = NULL;
+ xcb_generic_error_t * error_p = NULL;
+ error_s ret = {};
+ xv_cookie = xcb_xv_query_extension (xcb_conn_p);
+ xv_reply = xcb_xv_query_extension_reply (xcb_conn_p, xv_cookie, &error_p);
+ if (error_p)
+ {
+ ret.error_str = "Can't find xv extension";
+ ret.error_code = error_p->error_code;
+ }
+
+ if (xv_reply)
+ free(xv_reply);
+ if (error_p)
+ free(error_p);
+ return ret;
+}
+
+error_s
+check_shm (xcb_connection_t *xcb_conn_p)
+{
+ xcb_shm_query_version_cookie_t shm_cookie;
+ xcb_shm_query_version_reply_t *shm_reply_p = NULL;
+ xcb_generic_error_t * error_p = NULL;
+ error_s ret = {};
+ shm_cookie = xcb_shm_query_version (xcb_conn_p);
+ shm_reply_p = xcb_shm_query_version_reply (xcb_conn_p, shm_cookie, &error_p);
+ if (error_p)
+ {
+ ret.error_str = "Can't find shm extension";
+ ret.error_code = error_p->error_code;
+ }
+
+ if (shm_reply_p)
+ free(shm_reply_p);
+ if (error_p)
+ free(error_p);
+ return ret;
+}
+
+error_s
+check_dri2 (xcb_connection_t *xcb_conn_p)
+{
+ error_s ret = {};
+ xcb_generic_error_t *error_p = NULL;
+ xcb_dri2_query_version_cookie_t xcb_dri2_ck =
+ xcb_dri2_query_version (xcb_conn_p,
+ XCB_DRI2_MAJOR_VERSION,
+ XCB_DRI2_MINOR_VERSION);
+ xcb_dri2_query_version_reply_t * xcb_dri2_reply_p =
+ xcb_dri2_query_version_reply (xcb_conn_p,
+ xcb_dri2_ck,
+ &error_p);
+ if (error_p)
+ {
+ ret.error_str = "Can't find dri2 extension";
+ ret.error_code = error_p->error_code;
+ }
+
+ if (xcb_dri2_reply_p)
+ free(xcb_dri2_reply_p);
+ if (error_p)
+ free(error_p);
+ return ret;
+}
+
+rule_s
+make_rule (xcb_connection_t *xcb_conn_p, xcb_screen_t *screen_p)
+{
+ rule_s ret = {};
+ ret.count_frame_per_change = 2;
+ ret.count_uniqes_frames = 10;
+ ret.frame_per_second = 30;
+ ret.max_width = screen_p->width_in_pixels;
+ ret.max_height = screen_p->height_in_pixels;
+ ret.dst_change = 1;
+ ret.src_change = 0;
+ ret.min_height = 100;
+ ret.min_width = 100;
+ ret.image_width = 640;
+ ret.image_height = 480;
+ ret.image_fourcc = FOURCC_SR32;
+ return ret;
+}
+
+test_map_s
+init_tests (void)
+{
+ test_map_s ret = {};
+ ret.num_tests = 1;
+ ret.test_case_array = calloc(ret.num_tests, sizeof(test_case_s));
+ if (ret.test_case_array == NULL)
+ {
+ fprintf(stderr, "Can't alloc memory for test");
+ ret.num_tests = 0;
+ goto error_close;
+ }
+
+ ret.error_array = calloc(ret.num_tests, sizeof(error_s));
+ if (ret.error_array == NULL)
+ {
+ fprintf(stderr, "Can't alloc memory for test");
+ ret.num_tests = 0;
+ goto error_close;
+ }
+ ret.test_case_array[0] = test_xv_resize_init();
+ return ret;
+error_close:
+ if (ret.test_case_array)
+ free(ret.test_case_array);
+ if (ret.error_array)
+ free(ret.error_array);
+
+ return ret;
+}
+
+int main ()
+{
+ xcb_screen_iterator_t screen_iter;
+ xcb_connection_t *xcb_conn_p;
+ const xcb_setup_t *setup;
+ xcb_screen_t *screen_p;
+ int screen_number;
+ test_map_s tests = {};
+ rule_s rule_p = {};
+ error_s ret;
+ /* getting the connection */
+ xcb_conn_p = xcb_connect (NULL, &screen_number);
+ if (!xcb_conn_p)
+ {
+ fprintf(stderr, "ERROR: can't connect to an X server\n");
+ }
+ ret = check_xv (xcb_conn_p);
+ exit_if_fail (ret);
+ ret = check_shm (xcb_conn_p);
+ exit_if_fail (ret);
+ ret = check_dri2 (xcb_conn_p);
+ exit_if_fail (ret);
+ DBG;
+ /* getting the current screen */
+ setup = xcb_get_setup (xcb_conn_p);
+ screen_p = NULL;
+ screen_iter = xcb_setup_roots_iterator (setup);
+ for (; screen_iter.rem != 0; --screen_number, xcb_screen_next (&screen_iter))
+ if (screen_number == 0)
+ {
+ screen_p = screen_iter.data;
+ break;
+ }
+ if (!screen_p) {
+ fprintf (stderr, "ERROR: can't get the current screen\n");
+ xcb_disconnect (xcb_conn_p);
+ return -1;
+ }
+ rule_p = make_rule (xcb_conn_p, screen_p);
+ tests = init_tests();
+ if (tests.num_tests == 0)
+ {
+ fprintf (stderr, "Nothing to test. num_tests = 0\n");
+ return 0;
+ }
+ int i;
+ DBG;
+ for (i = 0; i < tests.num_tests; i++)
+ {
+ ret = tests.test_case_array[i].prepare_test(xcb_conn_p, screen_p, rule_p);
+ if (ret.error_str)
+ {
+ tests.error_array[i] = ret;
+ continue;
+ }
+ ret = tests.test_case_array[i].run_test(xcb_conn_p, screen_p, rule_p);
+ if (ret.error_str)
+ {
+ tests.error_array[i] = ret;
+ continue;
+ }
+ ret = tests.test_case_array[i].close_test(xcb_conn_p, screen_p, rule_p);
+ if (ret.error_str)
+ {
+ tests.error_array[i] = ret;
+ continue;
+ }
+ }
+ for (i = 0; i < tests.num_tests; i++)
+ {
+ fprintf(stderr, "%s %d\n", tests.error_array[i].error_str,
+ tests.error_array[i].error_code);
+ }
+ return 0;
+}
--- /dev/null
+#ifndef __MAIN_H__
+#define __MAIN_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <xcb/xcb.h>
+
+#include <xf86drm.h>
+#include <tbm_bufmgr.h>
+
+#include "xv_types.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define max(a,b) \
+ ({ __typeof__ (a) _a = (a); \
+ __typeof__ (b) _b = (b); \
+ _a > _b ? _a : _b; })
+#define min(a,b) \
+ ({ __typeof__ (a) _a = (a); \
+ __typeof__ (b) _b = (b); \
+ _a < _b ? _a : _b; })
+
+#define exit_if_fail(error_s) \
+ {if (error_s.error_str) {\
+ fprintf (stderr, "Error: '%s' code: '%d'\n", \
+ error_s.error_str, error_s.error_code); \
+ exit(-1);}}
+
+#define C(b,m) (((b) >> (m)) & 0xFF)
+#define B(c,s) ((((unsigned int)(c)) & 0xff) << (s))
+#define FOURCC(a,b,c,d) (B(d,24) | B(c,16) | B(b,8) | B(a,0))
+#define FOURCC_STR(id) C(id,0), C(id,8), C(id,16), C(id,24)
+#define FOURCC_RGB565 FOURCC('R','G','B','P')
+#define FOURCC_RGB32 FOURCC('R','G','B','4')
+#define FOURCC_I420 FOURCC('I','4','2','0')
+#define FOURCC_SR16 FOURCC('S','R','1','6')
+#define FOURCC_SR32 FOURCC('S','R','3','2')
+#define FOURCC_S420 FOURCC('S','4','2','0')
+
+#define FOURCC_SN12 FOURCC('S','N','1','2')
+#define XVIMAGE_SN12 \
+ { \
+ FOURCC_SN12, \
+ XvYUV, \
+ LSBFirst, \
+ {'S','N','1','2', \
+ 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
+ 12, \
+ XvPlanar, \
+ 2, \
+ 0, 0, 0, 0, \
+ 8, 8, 8, \
+ 1, 2, 2, \
+ 1, 2, 2, \
+ {'Y','U','V', \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
+ XvTopToBottom \
+ }
+
+#define DBG \
+{printf("%s %d\n", __FUNCTION__, __LINE__);}
+
+typedef struct
+{
+ uint32_t min_width;
+ uint32_t min_height;
+ uint32_t max_width;
+ uint32_t max_height;
+ int src_change;
+ int dst_change;
+ uint32_t image_width;
+ uint32_t image_height;
+ uint32_t image_fourcc;
+ size_t count_frame_per_change;
+ size_t frame_per_second;
+ size_t count_uniqes_frames;
+ /* TODO: More rules */
+} rule_s;
+
+typedef struct
+{
+ uint8_t error_code;
+ char const * error_str;
+} error_s;
+
+typedef error_s (*prepare_test_case) (xcb_connection_t *, xcb_screen_t *, rule_s);
+typedef error_s (*run_test_case) (xcb_connection_t *, xcb_screen_t *, rule_s);
+typedef error_s (*close_test_case)(xcb_connection_t *, xcb_screen_t *, rule_s);
+
+typedef struct _test_case_s
+{
+ prepare_test_case prepare_test;
+ run_test_case run_test;
+ close_test_case close_test;
+} test_case_s;
+#endif