1 /**************************************************************************
3 * Copyright 2009 Younes Manton.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
35 #define BLOCK_HEIGHT 8
36 #define BLOCK_SIZE (BLOCK_WIDTH * BLOCK_HEIGHT)
37 #define MACROBLOCK_WIDTH 16
38 #define MACROBLOCK_HEIGHT 16
39 #define MACROBLOCK_WIDTH_IN_BLOCKS (MACROBLOCK_WIDTH / BLOCK_WIDTH)
40 #define MACROBLOCK_HEIGHT_IN_BLOCKS (MACROBLOCK_HEIGHT / BLOCK_HEIGHT)
41 #define BLOCKS_PER_MACROBLOCK 6
43 #define INPUT_WIDTH 16
44 #define INPUT_HEIGHT 16
45 #define INPUT_WIDTH_IN_MACROBLOCKS (INPUT_WIDTH / MACROBLOCK_WIDTH)
46 #define INPUT_HEIGHT_IN_MACROBLOCKS (INPUT_HEIGHT / MACROBLOCK_HEIGHT)
47 #define NUM_MACROBLOCKS (INPUT_WIDTH_IN_MACROBLOCKS * INPUT_HEIGHT_IN_MACROBLOCKS)
49 #define DEFAULT_OUTPUT_WIDTH INPUT_WIDTH
50 #define DEFAULT_OUTPUT_HEIGHT INPUT_HEIGHT
51 #define DEFAULT_ACCEPTABLE_ERR 0.01
53 void ParseArgs(int argc, char **argv, unsigned int *output_width, unsigned int *output_height, double *acceptable_error, int *prompt);
54 void Gradient(short *block, unsigned int start, unsigned int stop, int horizontal);
56 void ParseArgs(int argc, char **argv, unsigned int *output_width, unsigned int *output_height, double *acceptable_error, int *prompt)
61 *output_width = DEFAULT_OUTPUT_WIDTH;
62 *output_height = DEFAULT_OUTPUT_WIDTH;
63 *acceptable_error = DEFAULT_ACCEPTABLE_ERR;
66 for (i = 1; i < argc && !fail; ++i)
68 if (!strcmp(argv[i], "-w"))
70 if (sscanf(argv[++i], "%u", output_width) != 1)
73 else if (!strcmp(argv[i], "-h"))
75 if (sscanf(argv[++i], "%u", output_height) != 1)
78 else if (!strcmp(argv[i], "-e"))
80 if (sscanf(argv[++i], "%lf", acceptable_error) != 1)
83 else if (strcmp(argv[i], "-n"))
95 "Usage: %s [options]\n"
96 "\t-w <width>\tOutput width\n"
97 "\t-h <height>\tOutput height\n"
98 "\t-e <error>\tAcceptable margin of error per pixel, from 0 to 1\n"
99 "\t-n\tDon't prompt for quit\n",
104 void Gradient(short *block, unsigned int start, unsigned int stop, int horizontal)
107 unsigned int range = stop - start;
111 for (y = 0; y < BLOCK_HEIGHT; ++y)
112 for (x = 0; x < BLOCK_WIDTH; ++x)
113 block[y * BLOCK_WIDTH + x] = (short)(start + range * (x / (float)(BLOCK_WIDTH - 1)));
117 for (y = 0; y < BLOCK_HEIGHT; ++y)
118 for (x = 0; x < BLOCK_WIDTH; ++x)
119 block[y * BLOCK_WIDTH + x] = (short)(start + range * (y / (float)(BLOCK_HEIGHT - 1)));
123 int main(int argc, char **argv)
125 unsigned int output_width;
126 unsigned int output_height;
127 double acceptable_error;
131 const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
134 unsigned int is_overlay, intra_unsigned;
138 XvMCBlockArray block_array;
139 XvMCMacroBlockArray mb_array;
140 int mbx, mby, bx, by;
145 ParseArgs(argc, argv, &output_width, &output_height, &acceptable_error, &prompt);
147 display = XOpenDisplay(NULL);
154 XVMC_CHROMA_FORMAT_420,
163 XCloseDisplay(display);
164 error(1, 0, "Error, unable to find a good port.\n");
169 Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
170 XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
173 root = XDefaultRootWindow(display);
174 window = XCreateSimpleWindow(display, root, 0, 0, output_width, output_height, 0, 0, colorkey);
176 assert(XvMCCreateContext(display, port_num, surface_type_id, INPUT_WIDTH, INPUT_HEIGHT, XVMC_DIRECT, &context) == Success);
177 assert(XvMCCreateSurface(display, &context, &surface) == Success);
178 assert(XvMCCreateBlocks(display, &context, NUM_MACROBLOCKS * BLOCKS_PER_MACROBLOCK, &block_array) == Success);
179 assert(XvMCCreateMacroBlocks(display, &context, NUM_MACROBLOCKS, &mb_array) == Success);
181 mb = mb_array.macro_blocks;
182 blocks = block_array.blocks;
184 for (mby = 0; mby < INPUT_HEIGHT_IN_MACROBLOCKS; ++mby)
185 for (mbx = 0; mbx < INPUT_WIDTH_IN_MACROBLOCKS; ++mbx)
189 mb->macroblock_type = XVMC_MB_TYPE_INTRA;
190 /*mb->motion_type = ;*/
191 /*mb->motion_vertical_field_select = ;*/
192 mb->dct_type = XVMC_DCT_TYPE_FRAME;
193 /*mb->PMV[0][0][0] = ;
200 mb->PMV[1][1][1] = ;*/
201 mb->index = (mby * INPUT_WIDTH_IN_MACROBLOCKS + mbx) * BLOCKS_PER_MACROBLOCK;
202 mb->coded_block_pattern = 0x3F;
206 for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS; ++by)
207 for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS; ++bx)
209 const int start = 16, stop = 235, range = stop - start;
214 (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
215 (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
219 blocks += BLOCK_SIZE;
222 for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS / 2; ++by)
223 for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS / 2; ++bx)
225 const int start = 16, stop = 240, range = stop - start;
230 (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
231 (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
235 blocks += BLOCK_SIZE;
240 (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
241 (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
245 blocks += BLOCK_SIZE;
249 XSelectInput(display, window, ExposureMask | KeyPressMask);
250 XMapWindow(display, window);
253 /* Test NULL context */
254 assert(XvMCRenderSurface(display, NULL, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadContext);
255 /* Test NULL surface */
256 assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, NULL, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadSurface);
257 /* Test bad picture structure */
258 assert(XvMCRenderSurface(display, &context, 0, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == BadValue);
259 /* Test valid params */
260 assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == Success);
262 /* Test NULL surface */
263 assert(XvMCPutSurface(display, NULL, window, 0, 0, INPUT_WIDTH, INPUT_HEIGHT, 0, 0, output_width, output_height, XVMC_FRAME_PICTURE) == XvMCBadSurface);
264 /* Test bad window */
265 /* XXX: X halts with a bad drawable for some reason, doesn't return BadDrawable as expected */
266 /*assert(XvMCPutSurface(display, &surface, 0, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == BadDrawable);*/
270 puts("Press any button to quit...");
274 if (XPending(display) > 0)
278 XNextEvent(display, &event);
284 /* Test valid params */
289 display, &surface, window,
290 0, 0, INPUT_WIDTH, INPUT_HEIGHT,
291 0, 0, output_width, output_height,
307 assert(XvMCDestroyBlocks(display, &block_array) == Success);
308 assert(XvMCDestroyMacroBlocks(display, &mb_array) == Success);
309 assert(XvMCDestroySurface(display, &surface) == Success);
310 assert(XvMCDestroyContext(display, &context) == Success);
312 XvUngrabPort(display, port_num, CurrentTime);
313 XDestroyWindow(display, window);
314 XCloseDisplay(display);