Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5362 | serge | 1 | /* |
2 | * Copyright (c) 2008-2009 Intel Corporation. All Rights Reserved. |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
5 | * copy of this software and associated documentation files (the |
||
6 | * "Software"), to deal in the Software without restriction, including |
||
7 | * without limitation the rights to use, copy, modify, merge, publish, |
||
8 | * distribute, sub license, and/or sell copies of the Software, and to |
||
9 | * permit persons to whom the Software is furnished to do so, subject to |
||
10 | * the following conditions: |
||
11 | * |
||
12 | * The above copyright notice and this permission notice (including the |
||
13 | * next paragraph) shall be included in all copies or substantial portions |
||
14 | * of the Software. |
||
15 | * |
||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
||
19 | * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR |
||
20 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||
21 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||
22 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
23 | */ |
||
24 | |||
25 | #include |
||
26 | #include |
||
27 | #include |
||
28 | #include |
||
29 | #include |
||
30 | |||
31 | #include |
||
32 | |||
33 | #include |
||
34 | |||
35 | #include |
||
36 | #include |
||
37 | #include |
||
38 | #include |
||
39 | #include |
||
40 | |||
41 | /*currently, if XCheckWindowEvent was called in more than one thread, it would cause |
||
42 | * XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0.0" |
||
43 | * after 87 requests (83 known processed) with 0 events remaining. |
||
44 | * |
||
45 | * X Error of failed request: BadGC (invalid GC parameter) |
||
46 | * Major opcode of failed request: 60 (X_FreeGC) |
||
47 | * Resource id in failed request: 0x600034 |
||
48 | * Serial number of failed request: 398 |
||
49 | * Current serial number in output stream: 399 |
||
50 | * The root cause is unknown. */ |
||
51 | |||
52 | #define CHECK_VASTATUS(va_status,func) \ |
||
53 | if (va_status != VA_STATUS_SUCCESS) { \ |
||
54 | fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \ |
||
55 | exit(1); \ |
||
56 | } |
||
57 | #include "../loadsurface.h" |
||
58 | |||
59 | #define SURFACE_NUM 16 |
||
60 | |||
61 | static void *win_display; |
||
62 | static VADisplay va_dpy; |
||
63 | static VAImageFormat *va_image_formats; |
||
64 | static int va_num_image_formats = -1; |
||
65 | static VAConfigID vpp_config_id = VA_INVALID_ID; |
||
66 | static VASurfaceAttrib *va_surface_attribs; |
||
67 | static int va_num_surface_attribs = -1; |
||
68 | static VASurfaceID surface_id[SURFACE_NUM]; |
||
69 | static pthread_mutex_t surface_mutex[SURFACE_NUM]; |
||
70 | |||
71 | static void *drawable_thread0, *drawable_thread1; |
||
72 | static int surface_width = 352, surface_height = 288; |
||
73 | static int win_x = 0, win_y = 0; |
||
74 | static int win_width = 352, win_height = 288; |
||
75 | static int frame_rate = 0; |
||
76 | static unsigned long long frame_num_total = ~0; |
||
77 | static int check_event = 1; |
||
78 | static int put_pixmap = 0; |
||
79 | static int test_clip = 0; |
||
80 | static int display_field = VA_FRAME_PICTURE; |
||
81 | static pthread_mutex_t gmutex; |
||
82 | static int box_width = 32; |
||
83 | static int multi_thread = 0; |
||
84 | static int verbose = 0; |
||
85 | static int test_color_conversion = 0; |
||
86 | static int csc_src_fourcc = 0, csc_dst_fourcc = 0; |
||
87 | static VAImage csc_dst_fourcc_image; |
||
88 | static VASurfaceID csc_render_surface; |
||
89 | |||
90 | |||
91 | typedef struct { |
||
92 | char* fmt_str; |
||
93 | unsigned int fourcc; |
||
94 | } fourcc_map; |
||
95 | fourcc_map va_fourcc_map[] = { |
||
96 | {"YUYV", VA_FOURCC_YUY2}, |
||
97 | {"YUY2", VA_FOURCC_YUY2}, |
||
98 | {"NV12", VA_FOURCC_NV12}, |
||
99 | {"YV12", VA_FOURCC_YV12}, |
||
100 | {"BGRA", VA_FOURCC_BGRA}, |
||
101 | {"RGBA", VA_FOURCC_RGBA}, |
||
102 | {"BGRX", VA_FOURCC_BGRX}, |
||
103 | {"RGBX", VA_FOURCC_RGBX}, |
||
104 | }; |
||
105 | unsigned int map_str_to_vafourcc (char * str) |
||
106 | { |
||
107 | int i; |
||
108 | for (i=0; i< sizeof(va_fourcc_map)/sizeof(fourcc_map); i++) { |
||
109 | if (!strcmp(va_fourcc_map[i].fmt_str, str)) { |
||
110 | return va_fourcc_map[i].fourcc; |
||
111 | } |
||
112 | } |
||
113 | |||
114 | return 0; |
||
115 | |||
116 | } |
||
117 | char* map_vafourcc_to_str (unsigned int format) |
||
118 | { |
||
119 | static char unknown_format[] = "unknown-format"; |
||
120 | int i; |
||
121 | for (i=0; i< sizeof(va_fourcc_map)/sizeof(fourcc_map); i++) { |
||
122 | if (va_fourcc_map[i].fourcc == format) { |
||
123 | return va_fourcc_map[i].fmt_str; |
||
124 | } |
||
125 | } |
||
126 | |||
127 | return unknown_format; |
||
128 | |||
129 | } |
||
130 | |||
131 | static int |
||
132 | va_value_equals(const VAGenericValue *v1, const VAGenericValue *v2) |
||
133 | { |
||
134 | if (v1->type != v2->type) |
||
135 | return 0; |
||
136 | |||
137 | switch (v1->type) { |
||
138 | case VAGenericValueTypeInteger: |
||
139 | return v1->value.i == v2->value.i; |
||
140 | case VAGenericValueTypeFloat: |
||
141 | return v1->value.f == v2->value.f; |
||
142 | case VAGenericValueTypePointer: |
||
143 | return v1->value.p == v2->value.p; |
||
144 | case VAGenericValueTypeFunc: |
||
145 | return v1->value.fn == v2->value.fn; |
||
146 | } |
||
147 | return 0; |
||
148 | } |
||
149 | |||
150 | static int |
||
151 | ensure_image_formats(void) |
||
152 | { |
||
153 | VAStatus va_status; |
||
154 | VAImageFormat *image_formats; |
||
155 | int num_image_formats; |
||
156 | |||
157 | if (va_num_image_formats >= 0) |
||
158 | return va_num_image_formats; |
||
159 | |||
160 | num_image_formats = vaMaxNumImageFormats(va_dpy); |
||
161 | if (num_image_formats == 0) |
||
162 | return 0; |
||
163 | |||
164 | image_formats = malloc(num_image_formats * sizeof(*image_formats)); |
||
165 | if (!image_formats) |
||
166 | return 0; |
||
167 | |||
168 | va_status = vaQueryImageFormats(va_dpy, image_formats, &num_image_formats); |
||
169 | CHECK_VASTATUS(va_status, "vaQuerySurfaceAttributes()"); |
||
170 | |||
171 | va_image_formats = image_formats; |
||
172 | va_num_image_formats = num_image_formats; |
||
173 | return num_image_formats; |
||
174 | } |
||
175 | |||
176 | static const VAImageFormat * |
||
177 | lookup_image_format(uint32_t fourcc) |
||
178 | { |
||
179 | int i; |
||
180 | |||
181 | if (!ensure_image_formats()) |
||
182 | return NULL; |
||
183 | |||
184 | for (i = 0; i < va_num_image_formats; i++) { |
||
185 | const VAImageFormat * const image_format = &va_image_formats[i]; |
||
186 | if (image_format->fourcc == fourcc) |
||
187 | return image_format; |
||
188 | } |
||
189 | return NULL; |
||
190 | } |
||
191 | |||
192 | static int |
||
193 | ensure_surface_attribs(void) |
||
194 | { |
||
195 | VAStatus va_status; |
||
196 | VASurfaceAttrib *surface_attribs; |
||
197 | unsigned int num_image_formats, num_surface_attribs; |
||
198 | |||
199 | if (va_num_surface_attribs >= 0) |
||
200 | return va_num_surface_attribs; |
||
201 | |||
202 | num_image_formats = vaMaxNumImageFormats(va_dpy); |
||
203 | if (num_image_formats == 0) |
||
204 | return 0; |
||
205 | |||
206 | va_status = vaCreateConfig(va_dpy, VAProfileNone, VAEntrypointVideoProc, |
||
207 | NULL, 0, &vpp_config_id); |
||
208 | CHECK_VASTATUS(va_status, "vaCreateConfig()"); |
||
209 | |||
210 | /* Guess the number of surface attributes, thus including any |
||
211 | pixel-format supported by the VA driver */ |
||
212 | num_surface_attribs = VASurfaceAttribCount + num_image_formats; |
||
213 | surface_attribs = malloc(num_surface_attribs * sizeof(*surface_attribs)); |
||
214 | if (!surface_attribs) |
||
215 | return 0; |
||
216 | |||
217 | va_status = vaQuerySurfaceAttributes(va_dpy, vpp_config_id, |
||
218 | surface_attribs, &num_surface_attribs); |
||
219 | if (va_status == VA_STATUS_SUCCESS) |
||
220 | va_surface_attribs = surface_attribs; |
||
221 | else if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) { |
||
222 | va_surface_attribs = realloc(surface_attribs, |
||
223 | num_surface_attribs * sizeof(*va_surface_attribs)); |
||
224 | if (!va_surface_attribs) { |
||
225 | free(surface_attribs); |
||
226 | return 0; |
||
227 | } |
||
228 | va_status = vaQuerySurfaceAttributes(va_dpy, vpp_config_id, |
||
229 | va_surface_attribs, &num_surface_attribs); |
||
230 | } |
||
231 | CHECK_VASTATUS(va_status, "vaQuerySurfaceAttributes()"); |
||
232 | va_num_surface_attribs = num_surface_attribs; |
||
233 | return num_surface_attribs; |
||
234 | } |
||
235 | |||
236 | static const VASurfaceAttrib * |
||
237 | lookup_surface_attrib(VASurfaceAttribType type, const VAGenericValue *value) |
||
238 | { |
||
239 | int i; |
||
240 | |||
241 | if (!ensure_surface_attribs()) |
||
242 | return NULL; |
||
243 | |||
244 | for (i = 0; i < va_num_surface_attribs; i++) { |
||
245 | const VASurfaceAttrib * const surface_attrib = &va_surface_attribs[i]; |
||
246 | if (surface_attrib->type != type) |
||
247 | continue; |
||
248 | if (!(surface_attrib->flags & VA_SURFACE_ATTRIB_SETTABLE)) |
||
249 | continue; |
||
250 | if (va_value_equals(&surface_attrib->value, value)) |
||
251 | return surface_attrib; |
||
252 | } |
||
253 | return NULL; |
||
254 | } |
||
255 | |||
256 | int csc_preparation () |
||
257 | { |
||
258 | VAStatus va_status; |
||
259 | |||
260 | // 1. make sure dst fourcc is supported for vaImage |
||
261 | if (!lookup_image_format(csc_dst_fourcc)) { |
||
262 | test_color_conversion = 0; |
||
263 | printf("VA driver doesn't support %s image, skip additional color conversion\n", map_vafourcc_to_str(csc_dst_fourcc)); |
||
264 | goto cleanup; |
||
265 | } |
||
266 | |||
267 | // 2. make sure src_fourcc is supported for vaSurface |
||
268 | VASurfaceAttrib surface_attribs[1], * const s_attrib = &surface_attribs[0]; |
||
269 | s_attrib->type = VASurfaceAttribPixelFormat; |
||
270 | s_attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; |
||
271 | s_attrib->value.type = VAGenericValueTypeInteger; |
||
272 | s_attrib->value.value.i = csc_src_fourcc; |
||
273 | |||
274 | if (!lookup_surface_attrib(VASurfaceAttribPixelFormat, &s_attrib->value)) { |
||
275 | printf("VA driver doesn't support %s surface, skip additional color conversion\n", map_vafourcc_to_str(csc_src_fourcc)); |
||
276 | test_color_conversion = 0; |
||
277 | goto cleanup; |
||
278 | } |
||
279 | |||
280 | // 3 create all objs required by csc |
||
281 | // 3.1 vaSurface with src fourcc |
||
282 | va_status = vaCreateSurfaces( |
||
283 | va_dpy, |
||
284 | VA_RT_FORMAT_YUV420, surface_width, surface_height, |
||
285 | &surface_id[0], SURFACE_NUM, |
||
286 | surface_attribs, 1 |
||
287 | ); |
||
288 | CHECK_VASTATUS(va_status,"vaCreateSurfaces"); |
||
289 | |||
290 | // 3.2 vaImage with dst fourcc |
||
291 | VAImageFormat image_format; |
||
292 | image_format.fourcc = csc_dst_fourcc; |
||
293 | image_format.byte_order = VA_LSB_FIRST; |
||
294 | image_format.bits_per_pixel = 16; |
||
295 | |||
296 | va_status = vaCreateImage(va_dpy, &image_format, |
||
297 | surface_width, surface_height, |
||
298 | &csc_dst_fourcc_image); |
||
299 | CHECK_VASTATUS(va_status,"vaCreateImage"); |
||
300 | |||
301 | |||
302 | // 3.3 create a temp VASurface for final rendering(vaPutSurface) |
||
303 | s_attrib->value.value.i = VA_FOURCC_NV12; |
||
304 | va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, |
||
305 | surface_width, surface_height, |
||
306 | &csc_render_surface, 1, |
||
307 | surface_attribs, 1); |
||
308 | CHECK_VASTATUS(va_status,"vaCreateSurfaces"); |
||
309 | |||
310 | |||
311 | cleanup: |
||
312 | return test_color_conversion; |
||
313 | } |
||
314 | |||
315 | static VASurfaceID get_next_free_surface(int *index) |
||
316 | { |
||
317 | VASurfaceStatus surface_status; |
||
318 | int i; |
||
319 | |||
320 | assert(index); |
||
321 | |||
322 | if (multi_thread == 0) { |
||
323 | i = *index; |
||
324 | i++; |
||
325 | if (i == SURFACE_NUM) |
||
326 | i = 0; |
||
327 | *index = i; |
||
328 | |||
329 | return surface_id[i]; |
||
330 | } |
||
331 | |||
332 | for (i=0; i |
||
333 | surface_status = (VASurfaceStatus)0; |
||
334 | vaQuerySurfaceStatus(va_dpy, surface_id[i], &surface_status); |
||
335 | if (surface_status == VASurfaceReady) |
||
336 | { |
||
337 | if (0 == pthread_mutex_trylock(&surface_mutex[i])) |
||
338 | { |
||
339 | *index = i; |
||
340 | break; |
||
341 | } |
||
342 | } |
||
343 | } |
||
344 | |||
345 | if (i==SURFACE_NUM) |
||
346 | return VA_INVALID_SURFACE; |
||
347 | else |
||
348 | return surface_id[i]; |
||
349 | } |
||
350 | |||
351 | static int upload_source_YUV_once_for_all() |
||
352 | { |
||
353 | VAImage surface_image; |
||
354 | void *surface_p=NULL, *U_start,*V_start; |
||
355 | VAStatus va_status; |
||
356 | int box_width_loc=8; |
||
357 | int row_shift_loc=0; |
||
358 | int i; |
||
359 | |||
360 | for (i=0; i |
||
361 | printf("\rLoading data into surface %d.....", i); |
||
362 | upload_surface(va_dpy, surface_id[i], box_width_loc, row_shift_loc, 0); |
||
363 | |||
364 | row_shift_loc++; |
||
365 | if (row_shift_loc==(2*box_width_loc)) row_shift_loc= 0; |
||
366 | } |
||
367 | printf("\n"); |
||
368 | |||
369 | return 0; |
||
370 | } |
||
371 | |||
372 | /* |
||
373 | * Helper function for profiling purposes |
||
374 | */ |
||
375 | static unsigned long get_tick_count(void) |
||
376 | { |
||
377 | struct timeval tv; |
||
378 | if (gettimeofday(&tv, NULL)) |
||
379 | return 0; |
||
380 | return tv.tv_usec/1000+tv.tv_sec*1000; |
||
381 | } |
||
382 | |||
383 | static void update_clipbox(VARectangle *cliprects, int width, int height) |
||
384 | { |
||
385 | if (test_clip == 0) |
||
386 | return; |
||
387 | |||
388 | srand((unsigned)time(NULL)); |
||
389 | |||
390 | cliprects[0].x = (rand() % width); |
||
391 | cliprects[0].y = (rand() % height); |
||
392 | cliprects[0].width = (rand() % (width - cliprects[0].x)); |
||
393 | cliprects[0].height = (rand() % (height - cliprects[0].y)); |
||
394 | |||
395 | cliprects[1].x = (rand() % width); |
||
396 | cliprects[1].y = (rand() % height); |
||
397 | cliprects[1].width = (rand() % (width - cliprects[1].x)); |
||
398 | cliprects[1].height = (rand() % (height - cliprects[1].y)); |
||
399 | printf("\nTest clip (%d,%d, %d x %d) and (%d,%d, %d x %d) \n", |
||
400 | cliprects[0].x, cliprects[0].y, cliprects[0].width, cliprects[0].height, |
||
401 | cliprects[1].x, cliprects[1].y, cliprects[1].width, cliprects[1].height); |
||
402 | } |
||
403 | |||
404 | static void* putsurface_thread(void *data) |
||
405 | { |
||
406 | int width=win_width, height=win_height; |
||
407 | void *drawable = data; |
||
408 | int quit = 0; |
||
409 | VAStatus vaStatus; |
||
410 | int row_shift = 0; |
||
411 | int index = 0; |
||
412 | unsigned int frame_num=0, start_time, putsurface_time; |
||
413 | VARectangle cliprects[2]; /* client supplied clip list */ |
||
414 | int continue_display = 0; |
||
415 | |||
416 | if (drawable == drawable_thread0) |
||
417 | printf("Enter into thread0\n\n"); |
||
418 | if (drawable == drawable_thread1) |
||
419 | printf("Enter into thread1\n\n"); |
||
420 | |||
421 | putsurface_time = 0; |
||
422 | while (!quit) { |
||
423 | VASurfaceID surface_id = VA_INVALID_SURFACE; |
||
424 | |||
425 | while (surface_id == VA_INVALID_SURFACE) |
||
426 | surface_id = get_next_free_surface(&index); |
||
427 | |||
428 | if (verbose) printf("Thread: %p Display surface 0x%x,\n", drawable, surface_id); |
||
429 | |||
430 | if (multi_thread) |
||
431 | upload_surface(va_dpy, surface_id, box_width, row_shift, display_field); |
||
432 | |||
433 | if (check_event) |
||
434 | pthread_mutex_lock(&gmutex); |
||
435 | |||
436 | start_time = get_tick_count(); |
||
437 | if ((continue_display == 0) && getenv("FRAME_STOP")) { |
||
438 | char c; |
||
439 | printf("Press any key to display frame %d...(c/C to continue)\n", frame_num); |
||
440 | c = getchar(); |
||
441 | if (c == 'c' || c == 'C') |
||
442 | continue_display = 1; |
||
443 | } |
||
444 | if (test_color_conversion) { |
||
445 | static int _put_surface_count = 0; |
||
446 | if (_put_surface_count++ %50 == 0) { |
||
447 | printf("do additional colorcoversion from %s to %s\n", map_vafourcc_to_str(csc_src_fourcc), map_vafourcc_to_str(csc_dst_fourcc)); |
||
448 | } |
||
449 | // get image from surface, csc_src_fourcc to csc_dst_fourcc conversion happens |
||
450 | vaStatus = vaGetImage(va_dpy, surface_id, 0, 0, |
||
451 | surface_width, surface_height, csc_dst_fourcc_image.image_id); |
||
452 | CHECK_VASTATUS(vaStatus,"vaGetImage"); |
||
453 | |||
454 | // render csc_dst_fourcc image to temp surface |
||
455 | vaStatus = vaPutImage(va_dpy, csc_render_surface, csc_dst_fourcc_image.image_id, |
||
456 | 0, 0, surface_width, surface_height, |
||
457 | 0, 0, surface_width, surface_height); |
||
458 | CHECK_VASTATUS(vaStatus,"vaPutImage"); |
||
459 | |||
460 | // render the temp surface, it should be same with original surface without color conversion test |
||
461 | vaStatus = vaPutSurface(va_dpy, csc_render_surface, CAST_DRAWABLE(drawable), |
||
462 | 0,0,surface_width,surface_height, |
||
463 | 0,0,width,height, |
||
464 | (test_clip==0)?NULL:&cliprects[0], |
||
465 | (test_clip==0)?0:2, |
||
466 | display_field); |
||
467 | CHECK_VASTATUS(vaStatus,"vaPutSurface"); |
||
468 | |||
469 | } |
||
470 | else { |
||
471 | vaStatus = vaPutSurface(va_dpy, surface_id, CAST_DRAWABLE(drawable), |
||
472 | 0,0,surface_width,surface_height, |
||
473 | 0,0,width,height, |
||
474 | (test_clip==0)?NULL:&cliprects[0], |
||
475 | (test_clip==0)?0:2, |
||
476 | display_field); |
||
477 | CHECK_VASTATUS(vaStatus,"vaPutSurface"); |
||
478 | } |
||
479 | |||
480 | putsurface_time += (get_tick_count() - start_time); |
||
481 | |||
482 | if (check_event) |
||
483 | pthread_mutex_unlock(&gmutex); |
||
484 | |||
485 | pthread_mutex_unlock(&surface_mutex[index]); /* locked in get_next_free_surface */ |
||
486 | |||
487 | if ((frame_num % 0xff) == 0) { |
||
488 | fprintf(stderr, "%.2f FPS \r", 256000.0 / (float)putsurface_time); |
||
489 | putsurface_time = 0; |
||
490 | update_clipbox(cliprects, width, height); |
||
491 | } |
||
492 | |||
493 | if (check_event) |
||
494 | check_window_event(win_display, drawable, &width, &height, &quit); |
||
495 | |||
496 | if (multi_thread) { /* reload surface content */ |
||
497 | row_shift++; |
||
498 | if (row_shift==(2*box_width)) row_shift= 0; |
||
499 | } |
||
500 | |||
501 | if (frame_rate != 0) /* rough framerate control */ |
||
502 | usleep(1000/frame_rate*1000); |
||
503 | |||
504 | frame_num++; |
||
505 | if (frame_num >= frame_num_total) |
||
506 | quit = 1; |
||
507 | } |
||
508 | |||
509 | if (drawable == drawable_thread1) |
||
510 | pthread_exit(NULL); |
||
511 | |||
512 | return 0; |
||
513 | } |
||
514 | int main(int argc,char **argv) |
||
515 | { |
||
516 | int major_ver, minor_ver; |
||
517 | VAStatus va_status; |
||
518 | pthread_t thread1; |
||
519 | int ret; |
||
520 | char c; |
||
521 | int i; |
||
522 | char str_src_fmt[5], str_dst_fmt[5]; |
||
523 | |||
524 | static struct option long_options[] = |
||
525 | { |
||
526 | {"fmt1", required_argument, NULL, '1'}, |
||
527 | {"fmt2", required_argument, NULL, '2'}, |
||
528 | {0, 0, 0, 0} |
||
529 | }; |
||
530 | |||
531 | while ((c =getopt_long(argc,argv,"w:h:g:r:d:f:tcep?n:1:2:v", long_options, NULL)) != EOF) { |
||
532 | switch (c) { |
||
533 | case '?': |
||
534 | printf("putsurface |
||
535 | printf(" -g |
||
536 | printf(" -w/-h resolution of surface\n"); |
||
537 | printf(" -r |
||
538 | printf(" -d the dimension of black/write square box, default is 32\n"); |
||
539 | printf(" -t multi-threads\n"); |
||
540 | printf(" -c test clipbox\n"); |
||
541 | printf(" -f <1/2> top field, or bottom field\n"); |
||
542 | printf(" -1 source format (fourcc) for color conversion test\n"); |
||
543 | printf(" -2 dest format (fourcc) for color conversion test\n"); |
||
544 | printf(" --fmt1 same to -1\n"); |
||
545 | printf(" --fmt2 same to -2\n"); |
||
546 | printf(" -v verbose output\n"); |
||
547 | exit(0); |
||
548 | break; |
||
549 | case 'g': |
||
550 | ret = sscanf(optarg, "%dx%d+%d+%d", &win_width, &win_height, &win_x, &win_y); |
||
551 | if (ret != 4) { |
||
552 | printf("invalid window geometry, must be widthxheight+x_location+y_location\n"); |
||
553 | exit(0); |
||
554 | } else |
||
555 | printf("Create window at (%d, %d), width = %d, height = %d\n", |
||
556 | win_x, win_y, win_width, win_height); |
||
557 | break; |
||
558 | case 'r': |
||
559 | frame_rate = atoi(optarg); |
||
560 | break; |
||
561 | case 'w': |
||
562 | surface_width = atoi(optarg); |
||
563 | break; |
||
564 | case 'h': |
||
565 | surface_height = atoi(optarg); |
||
566 | break; |
||
567 | case 'n': |
||
568 | frame_num_total = atoi(optarg); |
||
569 | break; |
||
570 | case 'd': |
||
571 | box_width = atoi(optarg); |
||
572 | break; |
||
573 | case 't': |
||
574 | multi_thread = 1; |
||
575 | printf("Two threads to do vaPutSurface\n"); |
||
576 | break; |
||
577 | case 'e': |
||
578 | check_event = 0; |
||
579 | break; |
||
580 | case 'p': |
||
581 | put_pixmap = 1; |
||
582 | break; |
||
583 | case 'c': |
||
584 | test_clip = 1; |
||
585 | break; |
||
586 | case 'f': |
||
587 | if (atoi(optarg) == 1) { |
||
588 | printf("Display TOP field\n"); |
||
589 | display_field = VA_TOP_FIELD; |
||
590 | } else if (atoi(optarg) == 2) { |
||
591 | printf("Display BOTTOM field\n"); |
||
592 | display_field = VA_BOTTOM_FIELD; |
||
593 | } else |
||
594 | printf("The validate input for -f is: 1(top field)/2(bottom field)\n"); |
||
595 | break; |
||
596 | case '1': |
||
597 | sscanf(optarg, "%s", str_src_fmt); |
||
598 | csc_src_fourcc = map_str_to_vafourcc (str_src_fmt); |
||
599 | |||
600 | if (!csc_src_fourcc) { |
||
601 | printf("invalid fmt1: %s\n", str_src_fmt ); |
||
602 | exit(0); |
||
603 | } |
||
604 | break; |
||
605 | case '2': |
||
606 | sscanf(optarg, "%s", str_dst_fmt); |
||
607 | csc_dst_fourcc = map_str_to_vafourcc (str_dst_fmt); |
||
608 | |||
609 | if (!csc_dst_fourcc) { |
||
610 | printf("invalid fmt1: %s\n", str_dst_fmt ); |
||
611 | exit(0); |
||
612 | } |
||
613 | break; |
||
614 | case 'v': |
||
615 | verbose = 1; |
||
616 | printf("Enable verbose output\n"); |
||
617 | break; |
||
618 | } |
||
619 | } |
||
620 | |||
621 | if (csc_src_fourcc && csc_dst_fourcc) { |
||
622 | test_color_conversion = 1; |
||
623 | } |
||
624 | |||
625 | win_display = (void *)open_display(); |
||
626 | if (win_display == NULL) { |
||
627 | fprintf(stderr, "Can't open the connection of display!\n"); |
||
628 | exit(-1); |
||
629 | } |
||
630 | create_window(win_display, win_x, win_y, win_width, win_height); |
||
631 | |||
632 | va_dpy = vaGetDisplay(win_display); |
||
633 | va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); |
||
634 | CHECK_VASTATUS(va_status, "vaInitialize"); |
||
635 | |||
636 | if (test_color_conversion) { |
||
637 | ret = csc_preparation(); |
||
638 | } |
||
639 | if (!test_color_conversion || !ret ) { |
||
640 | va_status = vaCreateSurfaces( |
||
641 | va_dpy, |
||
642 | VA_RT_FORMAT_YUV420, surface_width, surface_height, |
||
643 | &surface_id[0], SURFACE_NUM, |
||
644 | NULL, 0 |
||
645 | ); |
||
646 | } |
||
647 | CHECK_VASTATUS(va_status, "vaCreateSurfaces"); |
||
648 | if (multi_thread == 0) /* upload the content for all surfaces */ |
||
649 | upload_source_YUV_once_for_all(); |
||
650 | |||
651 | if (check_event) |
||
652 | pthread_mutex_init(&gmutex, NULL); |
||
653 | |||
654 | for(i = 0; i< SURFACE_NUM; i++) |
||
655 | pthread_mutex_init(&surface_mutex[i], NULL); |
||
656 | |||
657 | if (multi_thread == 1) |
||
658 | ret = pthread_create(&thread1, NULL, putsurface_thread, (void*)drawable_thread1); |
||
659 | |||
660 | putsurface_thread((void *)drawable_thread0); |
||
661 | |||
662 | if (multi_thread == 1) |
||
663 | pthread_join(thread1, (void **)&ret); |
||
664 | printf("thread1 is free\n"); |
||
665 | |||
666 | if (test_color_conversion) { |
||
667 | // destroy temp surface/image |
||
668 | va_status = vaDestroySurfaces(va_dpy, &csc_render_surface, 1); |
||
669 | CHECK_VASTATUS(va_status,"vaDestroySurfaces"); |
||
670 | |||
671 | va_status = vaDestroyImage(va_dpy, csc_dst_fourcc_image.image_id); |
||
672 | CHECK_VASTATUS(va_status,"vaDestroyImage"); |
||
673 | } |
||
674 | |||
675 | if (vpp_config_id != VA_INVALID_ID) { |
||
676 | vaDestroyConfig (va_dpy, vpp_config_id); |
||
677 | vpp_config_id = VA_INVALID_ID; |
||
678 | } |
||
679 | |||
680 | vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM); |
||
681 | vaTerminate(va_dpy); |
||
682 | |||
683 | free(va_image_formats); |
||
684 | free(va_surface_attribs); |
||
685 | close_display(win_display); |
||
686 | |||
687 | return 0; |
||
688 | }>1/2>>>>> |