Commit 6fca1869 authored by Younes Manton's avatar Younes Manton
Browse files

g3dvl: Update XvMC unit tests.

parent 3122f2be
......@@ -15,11 +15,11 @@ static Status Validate
unsigned int width,
unsigned int height,
int flags,
int *found_port,
int *chroma_format,
int *mc_type
)
{
unsigned int found_port = 0;
unsigned int found_surface = 0;
XvAdaptorInfo *adaptor_info;
unsigned int num_adaptors;
......@@ -30,22 +30,24 @@ static Status Validate
assert(display && chroma_format);
*found_port = 0;
ret = XvQueryAdaptors(display, XDefaultRootWindow(display), &num_adaptors, &adaptor_info);
if (ret != Success)
return ret;
/* Scan through all adaptors looking for this port and surface */
for (i = 0; i < num_adaptors && !found_port; ++i)
for (i = 0; i < num_adaptors && !*found_port; ++i)
{
/* Scan through all ports of this adaptor looking for our port */
for (j = 0; j < adaptor_info[i].num_ports && !found_port; ++j)
for (j = 0; j < adaptor_info[i].num_ports && !*found_port; ++j)
{
/* If this is our port, scan through all its surfaces looking for our surface */
if (adaptor_info[i].base_id + j == port)
{
XvMCSurfaceInfo *surface_info;
found_port = 1;
*found_port = 1;
surface_info = XvMCListSurfaceTypes(display, adaptor_info[i].base_id, &num_types);
if (surface_info)
......@@ -75,7 +77,7 @@ static Status Validate
XvFreeAdaptorInfo(adaptor_info);
if (!found_port)
if (!*found_port)
return XvBadPort;
if (!found_surface)
return BadMatch;
......@@ -127,6 +129,7 @@ static enum vlFormat FormatToVL(int xvmc_format)
Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context)
{
int found_port;
int chroma_format;
int mc_type;
Status ret;
......@@ -140,8 +143,10 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, i
if (!context)
return XvMCBadContext;
ret = Validate(display, port, surface_type_id, width, height, flags, &chroma_format, &mc_type);
if (ret != Success)
ret = Validate(display, port, surface_type_id, width, height, flags, &found_port, &chroma_format, &mc_type);
/* XXX: Success and XvBadPort have the same value */
if (ret != Success || !found_port)
return ret;
/* XXX: Assumes default screen, should check which screen port is on */
......
......@@ -2,4 +2,4 @@ test_context
test_surface
test_blocks
test_rendering
xvmc_bench
CFLAGS += -g -Wall -Werror
CFLAGS += -g -Wall
LDFLAGS +=
LIBS += -lXvMCW -lXvMC -lXv
......@@ -6,7 +6,7 @@ LIBS += -lXvMCW -lXvMC -lXv
.PHONY = all clean
all: test_context test_surface test_blocks test_rendering
all: test_context test_surface test_blocks test_rendering xvmc_bench
test_context: test_context.o testlib.o
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
......@@ -20,6 +20,8 @@ test_blocks: test_blocks.o testlib.o
test_rendering: test_rendering.o testlib.o
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
clean:
rm -rf *.o test_context test_surface test_blocks test_rendering
xvmc_bench: xvmc_bench.o testlib.o
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
clean:
rm -rf *.o test_context test_surface test_blocks test_rendering xvmc_bench
......@@ -7,7 +7,7 @@ int main(int argc, char **argv)
const unsigned int width = 16, height = 16;
const unsigned int min_required_blocks = 1, min_required_macroblocks = 1;
const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
Display *display;
XvPortID port_num;
int surface_type_id;
......@@ -17,9 +17,9 @@ int main(int argc, char **argv)
XvMCSurface surface;
XvMCBlockArray blocks = {0};
XvMCMacroBlockArray macroblocks = {0};
display = XOpenDisplay(NULL);
if (!GetPort
(
display,
......@@ -37,25 +37,20 @@ int main(int argc, char **argv)
XCloseDisplay(display);
error(1, 0, "Error, unable to find a good port.\n");
}
if (is_overlay)
{
Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
}
assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success);
assert(XvMCCreateSurface(display, &context, &surface) == Success);
/* Test NULL context */
assert(XvMCCreateBlocks(display, NULL, 1, &blocks) == XvMCBadContext);
/* Test 0 blocks */
assert(XvMCCreateBlocks(display, &context, 0, &blocks) == BadValue);
/* Test too many blocks */
/*assert(XvMCCreateBlocks(display, &context, 16384, &blocks) == BadAlloc);*/
/* Note: No XvMCBadBlock(s) error in spec */
/* Test valid params */
assert(XvMCCreateBlocks(display, &context, min_required_blocks, &blocks) == Success);
/* Test context id assigned and correct */
......@@ -68,11 +63,6 @@ int main(int argc, char **argv)
assert(XvMCCreateMacroBlocks(display, NULL, 1, &macroblocks) == XvMCBadContext);
/* Test 0 macroblocks */
assert(XvMCCreateMacroBlocks(display, &context, 0, &macroblocks) == BadValue);
/* Test too many macroblocks */
/*assert(XvMCCreateMacroBlocks(display, &context, 16384, &macroblocks) == BadAlloc);*/
/* Note: No XvMCBadMacroBlock(s) error in spec */
/* Test valid params */
assert(XvMCCreateMacroBlocks(display, &context, min_required_macroblocks, &macroblocks) == Success);
/* Test context id assigned and correct */
......@@ -83,13 +73,12 @@ int main(int argc, char **argv)
assert(XvMCDestroyMacroBlocks(display, &macroblocks) == Success);
/* Test valid params */
assert(XvMCDestroyBlocks(display, &blocks) == Success);
assert(XvMCDestroySurface(display, &surface) == Success);
assert(XvMCDestroyContext(display, &context) == Success);
XvUngrabPort(display, port_num, CurrentTime);
XCloseDisplay(display);
return 0;
}
......@@ -6,16 +6,16 @@ int main(int argc, char **argv)
{
const unsigned int width = 16, height = 16;
const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
Display *display;
XvPortID port_num;
int surface_type_id;
unsigned int is_overlay, intra_unsigned;
int colorkey;
XvMCContext context = {0};
display = XOpenDisplay(NULL);
if (!GetPort
(
display,
......@@ -33,22 +33,21 @@ int main(int argc, char **argv)
XCloseDisplay(display);
error(1, 0, "Error, unable to find a good port.\n");
}
if (is_overlay)
{
Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
}
/* Note: XvMCBadContext not a valid return for XvMCCreateContext in the XvMC API, but openChrome driver returns it */
/* Note: Nvidia binary driver segfaults on NULL context, halts with debug output on bad port */
/* Test NULL context */
/* XXX: XvMCBadContext not a valid return for XvMCCreateContext in the XvMC API, but openChrome driver returns it */
assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, NULL) == XvMCBadContext);
/* Test invalid port */
assert(XvMCCreateContext(display, port_num + 1, surface_type_id, width, height, XVMC_DIRECT, &context) == XvBadPort);
/* XXX: Success and XvBadPort have the same value, if this call actually gets passed the validation step as of now we'll crash later */
assert(XvMCCreateContext(display, -1, surface_type_id, width, height, XVMC_DIRECT, &context) == XvBadPort);
/* Test invalid surface */
assert(XvMCCreateContext(display, port_num, surface_type_id + 1, width, height, XVMC_DIRECT, &context) == BadMatch);
assert(XvMCCreateContext(display, port_num, -1, width, height, XVMC_DIRECT, &context) == BadMatch);
/* Test invalid flags */
assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, -1, &context) == BadValue);
/* Test huge width */
......@@ -85,10 +84,9 @@ int main(int argc, char **argv)
assert(XvMCCreateContext(display, port_num, surface_type_id, width + 1, height + 1, XVMC_DIRECT, &context) == Success);
assert(context.width >= width + 1 && context.height >= height + 1);
assert(XvMCDestroyContext(display, &context) == Success);
XvUngrabPort(display, port_num, CurrentTime);
XCloseDisplay(display);
return 0;
}
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <error.h>
#include "testlib.h"
#define BLOCK_WIDTH 8
#define BLOCK_HEIGHT 8
#define BLOCK_SIZE (BLOCK_WIDTH * BLOCK_HEIGHT)
#define MACROBLOCK_WIDTH 16
#define MACROBLOCK_HEIGHT 16
#define MACROBLOCK_WIDTH_IN_BLOCKS (MACROBLOCK_WIDTH / BLOCK_WIDTH)
#define MACROBLOCK_HEIGHT_IN_BLOCKS (MACROBLOCK_HEIGHT / BLOCK_HEIGHT)
#define BLOCKS_PER_MACROBLOCK 6
#define INPUT_WIDTH 16
#define INPUT_HEIGHT 16
#define INPUT_WIDTH_IN_MACROBLOCKS (INPUT_WIDTH / MACROBLOCK_WIDTH)
#define INPUT_HEIGHT_IN_MACROBLOCKS (INPUT_HEIGHT / MACROBLOCK_HEIGHT)
#define NUM_MACROBLOCKS (INPUT_WIDTH_IN_MACROBLOCKS * INPUT_HEIGHT_IN_MACROBLOCKS)
#define DEFAULT_OUTPUT_WIDTH INPUT_WIDTH
#define DEFAULT_OUTPUT_HEIGHT INPUT_HEIGHT
#define DEFAULT_ACCEPTABLE_ERR 0.01
void ParseArgs(int argc, char **argv, unsigned int *output_width, unsigned int *output_height, double *acceptable_error, int *prompt)
{
int fail = 0;
int i;
*output_width = DEFAULT_OUTPUT_WIDTH;
*output_height = DEFAULT_OUTPUT_WIDTH;
*acceptable_error = DEFAULT_ACCEPTABLE_ERR;
*prompt = 1;
for (i = 1; i < argc && !fail; ++i)
{
if (!strcmp(argv[i], "-w"))
{
if (sscanf(argv[++i], "%u", output_width) != 1)
fail = 1;
}
else if (!strcmp(argv[i], "-h"))
{
if (sscanf(argv[++i], "%u", output_height) != 1)
fail = 1;
}
else if (!strcmp(argv[i], "-e"))
{
if (sscanf(argv[++i], "%lf", acceptable_error) != 1)
fail = 1;
}
else if (strcmp(argv[i], "-n"))
*prompt = 0;
else
fail = 1;
}
if (fail)
error
(
1, 0,
"Bad argument.\n"
"\n"
"Usage: %s [options]\n"
"\t-w <width>\tOutput width\n"
"\t-h <height>\tOutput height\n"
"\t-e <error>\tAcceptable margin of error per pixel, from 0 to 1\n"
"\t-n\tDon't prompt for quit\n",
argv[0]
);
}
void Gradient(short *block, unsigned int start, unsigned int stop, int horizontal)
{
unsigned int x, y;
unsigned int range = stop - start;
if (horizontal)
{
for (y = 0; y < BLOCK_HEIGHT; ++y)
for (x = 0; x < BLOCK_WIDTH; ++x)
block[y * BLOCK_WIDTH + x] = (short)(start + range * (x / (float)(BLOCK_WIDTH - 1)));
}
else
{
for (y = 0; y < BLOCK_HEIGHT; ++y)
for (x = 0; x < BLOCK_WIDTH; ++x)
block[y * BLOCK_WIDTH + x] = (short)(start + range * (y / (float)(BLOCK_HEIGHT - 1)));
}
}
int main(int argc, char **argv)
{
const unsigned int width = 32, height = 32;
const unsigned int mwidth = width / 16, mheight = height / 16;
const unsigned int num_macroblocks = mwidth * mheight;
const unsigned int num_blocks = num_macroblocks * 6;
const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
int quit = 0;
unsigned int output_width;
unsigned int output_height;
double acceptable_error;
int prompt;
Display *display;
Window root, window;
Pixmap framebuffer;
XEvent event;
const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
XvPortID port_num;
int surface_type_id;
unsigned int is_overlay, intra_unsigned;
int colorkey;
XvMCContext context;
XvMCSurface surface;
XvMCBlockArray blocks;
XvMCMacroBlockArray macroblocks;
unsigned int b, x, y;
XvMCBlockArray block_array;
XvMCMacroBlockArray mb_array;
int mbx, mby, bx, by;
XvMCMacroBlock *mb;
short *blocks;
int quit = 0;
ParseArgs(argc, argv, &output_width, &output_height, &acceptable_error, &prompt);
display = XOpenDisplay(NULL);
if (!GetPort
(
display,
width,
height,
INPUT_WIDTH,
INPUT_HEIGHT,
XVMC_CHROMA_FORMAT_420,
mc_types,
2,
......@@ -45,109 +133,155 @@ int main(int argc, char **argv)
XCloseDisplay(display);
error(1, 0, "Error, unable to find a good port.\n");
}
if (is_overlay)
{
Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
}
root = XDefaultRootWindow(display);
window = XCreateSimpleWindow(display, root, 0, 0, width, height, 0, 0, colorkey);
framebuffer = XCreatePixmap(display, root, width, height, 24);
XSelectInput(display, window, ExposureMask | KeyPressMask);
XMapWindow(display, window);
XSync(display, 0);
assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success);
window = XCreateSimpleWindow(display, root, 0, 0, output_width, output_height, 0, 0, colorkey);
assert(XvMCCreateContext(display, port_num, surface_type_id, INPUT_WIDTH, INPUT_HEIGHT, XVMC_DIRECT, &context) == Success);
assert(XvMCCreateSurface(display, &context, &surface) == Success);
assert(XvMCCreateBlocks(display, &context, num_blocks, &blocks) == Success);
assert(XvMCCreateMacroBlocks(display, &context, num_macroblocks, &macroblocks) == Success);
for (b = 0; b < 6; ++b)
{
for (y = 0; y < 8; ++y)
{
for (x = 0; x < 8; ++x)
{
blocks.blocks[b * 64 + y * 8 + x] = 0xFFFF;
}
}
}
for (y = 0; y < mheight; ++y)
{
for (x = 0; x < mwidth; ++x)
assert(XvMCCreateBlocks(display, &context, NUM_MACROBLOCKS * BLOCKS_PER_MACROBLOCK, &block_array) == Success);
assert(XvMCCreateMacroBlocks(display, &context, NUM_MACROBLOCKS, &mb_array) == Success);
mb = mb_array.macro_blocks;
blocks = block_array.blocks;
for (mby = 0; mby < INPUT_HEIGHT_IN_MACROBLOCKS; ++mby)
for (mbx = 0; mbx < INPUT_WIDTH_IN_MACROBLOCKS; ++mbx)
{
macroblocks.macro_blocks[y * mwidth + x].x = x;
macroblocks.macro_blocks[y * mwidth + x].y = y;
macroblocks.macro_blocks[y * mwidth + x].index = (y * mwidth + x) * 6;
macroblocks.macro_blocks[y * mwidth + x].macroblock_type = XVMC_MB_TYPE_INTRA;
macroblocks.macro_blocks[y * mwidth + x].coded_block_pattern = 0x3F;
macroblocks.macro_blocks[y * mwidth + x].dct_type = XVMC_DCT_TYPE_FRAME;
mb->x = mbx;
mb->y = mby;
mb->macroblock_type = XVMC_MB_TYPE_INTRA;
/*mb->motion_type = ;*/
/*mb->motion_vertical_field_select = ;*/
mb->dct_type = XVMC_DCT_TYPE_FRAME;
/*mb->PMV[0][0][0] = ;
mb->PMV[0][0][1] = ;
mb->PMV[0][1][0] = ;
mb->PMV[0][1][1] = ;
mb->PMV[1][0][0] = ;
mb->PMV[1][0][1] = ;
mb->PMV[1][1][0] = ;
mb->PMV[1][1][1] = ;*/
mb->index = (mby * INPUT_WIDTH_IN_MACROBLOCKS + mbx) * BLOCKS_PER_MACROBLOCK;
mb->coded_block_pattern = 0x3F;
mb++;
for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS; ++by)
for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS; ++bx)
{
const int start = 16, stop = 235, range = stop - start;
Gradient
(
blocks,
(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
1
);
blocks += BLOCK_SIZE;
}
for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS / 2; ++by)
for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS / 2; ++bx)
{
const int start = 16, stop = 240, range = stop - start;
Gradient
(
blocks,
(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
1
);
blocks += BLOCK_SIZE;
Gradient
(
blocks,
(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
(short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
1
);
blocks += BLOCK_SIZE;
}
}
}
XSelectInput(display, window, ExposureMask | KeyPressMask);
XMapWindow(display, window);
XSync(display, 0);
/* Test NULL context */
assert(XvMCRenderSurface(display, NULL, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, 1, 0, &macroblocks, &blocks) == XvMCBadContext);
assert(XvMCRenderSurface(display, NULL, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadContext);
/* Test NULL surface */
assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, NULL, NULL, NULL, 0, 1, 0, &macroblocks, &blocks) == XvMCBadSurface);
assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, NULL, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadSurface);
/* Test bad picture structure */
assert(XvMCRenderSurface(display, &context, 0, &surface, NULL, NULL, 0, 1, 0, &macroblocks, &blocks) == BadValue);
assert(XvMCRenderSurface(display, &context, 0, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == BadValue);
/* Test valid params */
assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, num_macroblocks, 0, &macroblocks, &blocks) == Success);
assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == Success);
/* Test NULL surface */
assert(XvMCPutSurface(display, NULL, window, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == XvMCBadSurface);
assert(XvMCPutSurface(display, NULL, window, 0, 0, INPUT_WIDTH, INPUT_HEIGHT, 0, 0, output_width, output_height, XVMC_FRAME_PICTURE) == XvMCBadSurface);
/* Test bad window */
/* X halts with a bad drawable for some reason, doesn't return BadDrawable as expected */
/* XXX: X halts with a bad drawable for some reason, doesn't return BadDrawable as expected */
/*assert(XvMCPutSurface(display, &surface, 0, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == BadDrawable);*/
/* Test valid params */
assert(XvMCPutSurface(display, &surface, framebuffer, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == Success);
puts("Press any key to continue...");
while (!quit)
if (prompt)
{
XNextEvent(display, &event);
switch (event.type)
puts("Press any button to quit...");
while (!quit)
{
case Expose:
{
XCopyArea
(
display,
framebuffer,
window,
XDefaultGC(display, XDefaultScreen(display)),
0,
0,
width,
height,
0,
0
);
break;
}
case KeyPress:
if (XPending(display) > 0)
{
quit = 1;
break;
XEvent event;
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
{
/* Test valid params */
assert
(
XvMCPutSurface
(
display, &surface, window,
0, 0, INPUT_WIDTH, INPUT_HEIGHT,
0, 0, output_width, output_height,
XVMC_FRAME_PICTURE
) == Success
);
break;
}
case KeyPress:
{
quit = 1;
break;
}
}
}
}
}
assert(XvMCDestroyBlocks(display, &blocks) == Success);
assert(XvMCDestroyMacroBlocks(display, &macroblocks) == Success);
assert(XvMCDestroySurface(display, &surface) == Success);
assert(XvMCDestroyBlocks(display, &block_array) == Success);