1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2009 Younes Manton. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci/* Force assertions, even on release builds. */ 29bf215546Sopenharmony_ci#undef NDEBUG 30bf215546Sopenharmony_ci#include <assert.h> 31bf215546Sopenharmony_ci#include <stdio.h> 32bf215546Sopenharmony_ci#include <string.h> 33bf215546Sopenharmony_ci#include <stdlib.h> 34bf215546Sopenharmony_ci#include <sys/time.h> 35bf215546Sopenharmony_ci#include "testlib.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#define MACROBLOCK_WIDTH 16 38bf215546Sopenharmony_ci#define MACROBLOCK_HEIGHT 16 39bf215546Sopenharmony_ci#define BLOCKS_PER_MACROBLOCK 6 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci#define DEFAULT_INPUT_WIDTH 720 42bf215546Sopenharmony_ci#define DEFAULT_INPUT_HEIGHT 480 43bf215546Sopenharmony_ci#define DEFAULT_REPS 100 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci#define PIPELINE_STEP_MC 1 46bf215546Sopenharmony_ci#define PIPELINE_STEP_CSC 2 47bf215546Sopenharmony_ci#define PIPELINE_STEP_SWAP 4 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci#define MB_TYPE_I 1 50bf215546Sopenharmony_ci#define MB_TYPE_P 2 51bf215546Sopenharmony_ci#define MB_TYPE_B 4 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_cistruct Config 54bf215546Sopenharmony_ci{ 55bf215546Sopenharmony_ci unsigned int input_width; 56bf215546Sopenharmony_ci unsigned int input_height; 57bf215546Sopenharmony_ci unsigned int output_width; 58bf215546Sopenharmony_ci unsigned int output_height; 59bf215546Sopenharmony_ci unsigned int pipeline; 60bf215546Sopenharmony_ci unsigned int mb_types; 61bf215546Sopenharmony_ci unsigned int reps; 62bf215546Sopenharmony_ci}; 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_civoid ParseArgs(int argc, char **argv, struct Config *config); 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_civoid ParseArgs(int argc, char **argv, struct Config *config) 67bf215546Sopenharmony_ci{ 68bf215546Sopenharmony_ci int fail = 0; 69bf215546Sopenharmony_ci int i; 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci config->input_width = DEFAULT_INPUT_WIDTH; 72bf215546Sopenharmony_ci config->input_height = DEFAULT_INPUT_HEIGHT; 73bf215546Sopenharmony_ci config->output_width = 0; 74bf215546Sopenharmony_ci config->output_height = 0; 75bf215546Sopenharmony_ci config->pipeline = 0; 76bf215546Sopenharmony_ci config->mb_types = 0; 77bf215546Sopenharmony_ci config->reps = DEFAULT_REPS; 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci for (i = 1; i < argc && !fail; ++i) 80bf215546Sopenharmony_ci { 81bf215546Sopenharmony_ci if (!strcmp(argv[i], "-iw")) 82bf215546Sopenharmony_ci { 83bf215546Sopenharmony_ci if (sscanf(argv[++i], "%u", &config->input_width) != 1) 84bf215546Sopenharmony_ci fail = 1; 85bf215546Sopenharmony_ci } 86bf215546Sopenharmony_ci else if (!strcmp(argv[i], "-ih")) 87bf215546Sopenharmony_ci { 88bf215546Sopenharmony_ci if (sscanf(argv[++i], "%u", &config->input_height) != 1) 89bf215546Sopenharmony_ci fail = 1; 90bf215546Sopenharmony_ci } 91bf215546Sopenharmony_ci else if (!strcmp(argv[i], "-ow")) 92bf215546Sopenharmony_ci { 93bf215546Sopenharmony_ci if (sscanf(argv[++i], "%u", &config->output_width) != 1) 94bf215546Sopenharmony_ci fail = 1; 95bf215546Sopenharmony_ci } 96bf215546Sopenharmony_ci else if (!strcmp(argv[i], "-oh")) 97bf215546Sopenharmony_ci { 98bf215546Sopenharmony_ci if (sscanf(argv[++i], "%u", &config->output_height) != 1) 99bf215546Sopenharmony_ci fail = 1; 100bf215546Sopenharmony_ci } 101bf215546Sopenharmony_ci else if (!strcmp(argv[i], "-p")) 102bf215546Sopenharmony_ci { 103bf215546Sopenharmony_ci char *token = strtok(argv[++i], ","); 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci while (token && !fail) 106bf215546Sopenharmony_ci { 107bf215546Sopenharmony_ci if (!strcmp(token, "mc")) 108bf215546Sopenharmony_ci config->pipeline |= PIPELINE_STEP_MC; 109bf215546Sopenharmony_ci else if (!strcmp(token, "csc")) 110bf215546Sopenharmony_ci config->pipeline |= PIPELINE_STEP_CSC; 111bf215546Sopenharmony_ci else if (!strcmp(token, "swp")) 112bf215546Sopenharmony_ci config->pipeline |= PIPELINE_STEP_SWAP; 113bf215546Sopenharmony_ci else 114bf215546Sopenharmony_ci fail = 1; 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci if (!fail) 117bf215546Sopenharmony_ci token = strtok(NULL, ","); 118bf215546Sopenharmony_ci } 119bf215546Sopenharmony_ci } 120bf215546Sopenharmony_ci else if (!strcmp(argv[i], "-mb")) 121bf215546Sopenharmony_ci { 122bf215546Sopenharmony_ci char *token = strtok(argv[++i], ","); 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci while (token && !fail) 125bf215546Sopenharmony_ci { 126bf215546Sopenharmony_ci if (strcmp(token, "i") == 0) 127bf215546Sopenharmony_ci config->mb_types |= MB_TYPE_I; 128bf215546Sopenharmony_ci else if (strcmp(token, "p") == 0) 129bf215546Sopenharmony_ci config->mb_types |= MB_TYPE_P; 130bf215546Sopenharmony_ci else if (strcmp(token, "b") == 0) 131bf215546Sopenharmony_ci config->mb_types |= MB_TYPE_B; 132bf215546Sopenharmony_ci else 133bf215546Sopenharmony_ci fail = 1; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci if (!fail) 136bf215546Sopenharmony_ci token = strtok(NULL, ","); 137bf215546Sopenharmony_ci } 138bf215546Sopenharmony_ci } 139bf215546Sopenharmony_ci else if (!strcmp(argv[i], "-r")) 140bf215546Sopenharmony_ci { 141bf215546Sopenharmony_ci if (sscanf(argv[++i], "%u", &config->reps) != 1) 142bf215546Sopenharmony_ci fail = 1; 143bf215546Sopenharmony_ci } 144bf215546Sopenharmony_ci else 145bf215546Sopenharmony_ci fail = 1; 146bf215546Sopenharmony_ci } 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci if (fail) 149bf215546Sopenharmony_ci { 150bf215546Sopenharmony_ci fprintf( 151bf215546Sopenharmony_ci stderr, 152bf215546Sopenharmony_ci "Bad argument.\n" 153bf215546Sopenharmony_ci "\n" 154bf215546Sopenharmony_ci "Usage: %s [options]\n" 155bf215546Sopenharmony_ci "\t-iw <width>\tInput width\n" 156bf215546Sopenharmony_ci "\t-ih <height>\tInput height\n" 157bf215546Sopenharmony_ci "\t-ow <width>\tOutput width\n" 158bf215546Sopenharmony_ci "\t-oh <height>\tOutput height\n" 159bf215546Sopenharmony_ci "\t-p <pipeline>\tPipeline to test\n" 160bf215546Sopenharmony_ci "\t-mb <mb type>\tMacroBlock types to use\n" 161bf215546Sopenharmony_ci "\t-r <reps>\tRepetitions\n\n" 162bf215546Sopenharmony_ci "\tPipeline steps: mc,csc,swap\n" 163bf215546Sopenharmony_ci "\tMB types: i,p,b\n", 164bf215546Sopenharmony_ci argv[0] 165bf215546Sopenharmony_ci ); 166bf215546Sopenharmony_ci exit(1); 167bf215546Sopenharmony_ci } 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci if (config->output_width == 0) 170bf215546Sopenharmony_ci config->output_width = config->input_width; 171bf215546Sopenharmony_ci if (config->output_height == 0) 172bf215546Sopenharmony_ci config->output_height = config->input_height; 173bf215546Sopenharmony_ci if (!config->pipeline) 174bf215546Sopenharmony_ci config->pipeline = PIPELINE_STEP_MC | PIPELINE_STEP_CSC | PIPELINE_STEP_SWAP; 175bf215546Sopenharmony_ci if (!config->mb_types) 176bf215546Sopenharmony_ci config->mb_types = MB_TYPE_I | MB_TYPE_P | MB_TYPE_B; 177bf215546Sopenharmony_ci} 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ciint main(int argc, char **argv) 180bf215546Sopenharmony_ci{ 181bf215546Sopenharmony_ci struct Config config; 182bf215546Sopenharmony_ci Display *display; 183bf215546Sopenharmony_ci Window root, window; 184bf215546Sopenharmony_ci const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2}; 185bf215546Sopenharmony_ci XvPortID port_num; 186bf215546Sopenharmony_ci int surface_type_id; 187bf215546Sopenharmony_ci unsigned int is_overlay, intra_unsigned; 188bf215546Sopenharmony_ci int colorkey; 189bf215546Sopenharmony_ci XvMCContext context; 190bf215546Sopenharmony_ci XvMCSurface surface; 191bf215546Sopenharmony_ci XvMCBlockArray block_array; 192bf215546Sopenharmony_ci XvMCMacroBlockArray mb_array; 193bf215546Sopenharmony_ci unsigned int mbw, mbh; 194bf215546Sopenharmony_ci unsigned int mbx, mby; 195bf215546Sopenharmony_ci unsigned int reps; 196bf215546Sopenharmony_ci struct timeval start, stop, diff; 197bf215546Sopenharmony_ci double diff_secs; 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci ParseArgs(argc, argv, &config); 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci mbw = align(config.input_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH; 202bf215546Sopenharmony_ci mbh = align(config.input_height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci display = XOpenDisplay(NULL); 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci if (!GetPort 207bf215546Sopenharmony_ci ( 208bf215546Sopenharmony_ci display, 209bf215546Sopenharmony_ci config.input_width, 210bf215546Sopenharmony_ci config.input_height, 211bf215546Sopenharmony_ci XVMC_CHROMA_FORMAT_420, 212bf215546Sopenharmony_ci mc_types, 213bf215546Sopenharmony_ci 2, 214bf215546Sopenharmony_ci &port_num, 215bf215546Sopenharmony_ci &surface_type_id, 216bf215546Sopenharmony_ci &is_overlay, 217bf215546Sopenharmony_ci &intra_unsigned 218bf215546Sopenharmony_ci )) 219bf215546Sopenharmony_ci { 220bf215546Sopenharmony_ci XCloseDisplay(display); 221bf215546Sopenharmony_ci fprintf(stderr, "Error, unable to find a good port.\n"); 222bf215546Sopenharmony_ci exit(1); 223bf215546Sopenharmony_ci } 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci if (is_overlay) 226bf215546Sopenharmony_ci { 227bf215546Sopenharmony_ci Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0); 228bf215546Sopenharmony_ci XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey); 229bf215546Sopenharmony_ci } 230bf215546Sopenharmony_ci else 231bf215546Sopenharmony_ci { 232bf215546Sopenharmony_ci colorkey = 0; 233bf215546Sopenharmony_ci } 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci root = XDefaultRootWindow(display); 236bf215546Sopenharmony_ci window = XCreateSimpleWindow(display, root, 0, 0, config.output_width, config.output_height, 0, 0, colorkey); 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci assert(XvMCCreateContext(display, port_num, surface_type_id, config.input_width, config.input_height, XVMC_DIRECT, &context) == Success); 239bf215546Sopenharmony_ci assert(XvMCCreateSurface(display, &context, &surface) == Success); 240bf215546Sopenharmony_ci assert(XvMCCreateBlocks(display, &context, mbw * mbh * BLOCKS_PER_MACROBLOCK, &block_array) == Success); 241bf215546Sopenharmony_ci assert(XvMCCreateMacroBlocks(display, &context, mbw * mbh, &mb_array) == Success); 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci for (mby = 0; mby < mbh; ++mby) 244bf215546Sopenharmony_ci for (mbx = 0; mbx < mbw; ++mbx) 245bf215546Sopenharmony_ci { 246bf215546Sopenharmony_ci mb_array.macro_blocks[mby * mbw + mbx].x = mbx; 247bf215546Sopenharmony_ci mb_array.macro_blocks[mby * mbw + mbx].y = mby; 248bf215546Sopenharmony_ci mb_array.macro_blocks[mby * mbw + mbx].macroblock_type = XVMC_MB_TYPE_INTRA; 249bf215546Sopenharmony_ci /*mb->motion_type = ;*/ 250bf215546Sopenharmony_ci /*mb->motion_vertical_field_select = ;*/ 251bf215546Sopenharmony_ci mb_array.macro_blocks[mby * mbw + mbx].dct_type = XVMC_DCT_TYPE_FRAME; 252bf215546Sopenharmony_ci /*mb->PMV[0][0][0] = ; 253bf215546Sopenharmony_ci mb->PMV[0][0][1] = ; 254bf215546Sopenharmony_ci mb->PMV[0][1][0] = ; 255bf215546Sopenharmony_ci mb->PMV[0][1][1] = ; 256bf215546Sopenharmony_ci mb->PMV[1][0][0] = ; 257bf215546Sopenharmony_ci mb->PMV[1][0][1] = ; 258bf215546Sopenharmony_ci mb->PMV[1][1][0] = ; 259bf215546Sopenharmony_ci mb->PMV[1][1][1] = ;*/ 260bf215546Sopenharmony_ci mb_array.macro_blocks[mby * mbw + mbx].index = (mby * mbw + mbx) * BLOCKS_PER_MACROBLOCK; 261bf215546Sopenharmony_ci mb_array.macro_blocks[mby * mbw + mbx].coded_block_pattern = 0x3F; 262bf215546Sopenharmony_ci } 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci XSelectInput(display, window, ExposureMask | KeyPressMask); 265bf215546Sopenharmony_ci XMapWindow(display, window); 266bf215546Sopenharmony_ci XSync(display, 0); 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci gettimeofday(&start, NULL); 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ci for (reps = 0; reps < config.reps; ++reps) 271bf215546Sopenharmony_ci { 272bf215546Sopenharmony_ci if (config.pipeline & PIPELINE_STEP_MC) 273bf215546Sopenharmony_ci { 274bf215546Sopenharmony_ci assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, mbw * mbh, 0, &mb_array, &block_array) == Success); 275bf215546Sopenharmony_ci assert(XvMCFlushSurface(display, &surface) == Success); 276bf215546Sopenharmony_ci } 277bf215546Sopenharmony_ci if (config.pipeline & PIPELINE_STEP_CSC) 278bf215546Sopenharmony_ci assert(XvMCPutSurface(display, &surface, window, 0, 0, config.input_width, config.input_height, 0, 0, config.output_width, config.output_height, XVMC_FRAME_PICTURE) == Success); 279bf215546Sopenharmony_ci } 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci gettimeofday(&stop, NULL); 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci timeval_subtract(&diff, &stop, &start); 284bf215546Sopenharmony_ci diff_secs = (double)diff.tv_sec + (double)diff.tv_usec / 1000000.0; 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci printf("XvMC Benchmark\n"); 287bf215546Sopenharmony_ci printf("Input: %u,%u\nOutput: %u,%u\n", config.input_width, config.input_height, config.output_width, config.output_height); 288bf215546Sopenharmony_ci printf("Pipeline: "); 289bf215546Sopenharmony_ci if (config.pipeline & PIPELINE_STEP_MC) 290bf215546Sopenharmony_ci printf("|mc|"); 291bf215546Sopenharmony_ci if (config.pipeline & PIPELINE_STEP_CSC) 292bf215546Sopenharmony_ci printf("|csc|"); 293bf215546Sopenharmony_ci if (config.pipeline & PIPELINE_STEP_SWAP) 294bf215546Sopenharmony_ci printf("|swap|"); 295bf215546Sopenharmony_ci printf("\n"); 296bf215546Sopenharmony_ci printf("Reps: %u\n", config.reps); 297bf215546Sopenharmony_ci printf("Total time: %.2lf (%.2lf reps / sec)\n", diff_secs, config.reps / diff_secs); 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci assert(XvMCDestroyBlocks(display, &block_array) == Success); 300bf215546Sopenharmony_ci assert(XvMCDestroyMacroBlocks(display, &mb_array) == Success); 301bf215546Sopenharmony_ci assert(XvMCDestroySurface(display, &surface) == Success); 302bf215546Sopenharmony_ci assert(XvMCDestroyContext(display, &context) == Success); 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci XvUngrabPort(display, port_num, CurrentTime); 305bf215546Sopenharmony_ci XDestroyWindow(display, window); 306bf215546Sopenharmony_ci XCloseDisplay(display); 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci return 0; 309bf215546Sopenharmony_ci} 310