1 /*
2 * display.c
3 *
4 * Copyright (C) Charles 'Buck' Krasic - April 2000
5 * Copyright (C) Erik Walthinsen - April 2000
6 *
7 * This file is part of libdv, a free DV (IEC 61834/SMPTE 314M)
8 * codec.
9 *
10 * libdv is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your
13 * option) any later version.
14 *
15 * libdv is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with GNU Make; see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * The libdv homepage is http://libdv.sourceforge.net/.
25 */
26
27 /* Most of this file is derived from patches 101018 and 101136 submitted by
28 * Stefan Lucke <lucke@berlin.snafu.de> */
29
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <unistd.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <math.h>
39 #include <string.h>
40
41 #include <libdv/dv_types.h>
42 #include "display.h"
43
44 #include "libtc/libtc.h"
45
46 #if HAVE_LIBXV
47 #include <sys/ipc.h>
48 #include <sys/shm.h>
49 #endif
50
51 // FIXME: Use autoconf for this!!
52 // MacOSX SDL uses native GUI frameworks, but this is an X11
53 // application setup.
54 #ifdef __APPLE__
55 #undef HAVE_SDL
56 #endif
57
58 static int dv_display_SDL_init(dv_display_t *dv_dpy, char *w_name, char *i_name );
59 static int dv_display_gdk_init(dv_display_t *dv_dpy, int *argc, char ***argv );
60
61 #if HAVE_SDL
62 static void dv_center_window(SDL_Surface *screen);
63 #endif
64
65 #if HAVE_LIBXV
66
67 #define XV_FORMAT_MASK 0x03
68 #define XV_FORMAT_ASIS 0x00
69 #define XV_FORMAT_NORMAL 0x01
70 #define XV_FORMAT_WIDE 0x02
71
72 #define XV_SIZE_MASK 0x0c
73 #define XV_SIZE_NORMAL 0x04
74 #define XV_SIZE_QUARTER 0x08
75
76 #define XV_NOSAWINDOW 0x10 /* not use at the moment */
77
78 #define DV_FORMAT_UNKNOWN -1
79 #define DV_FORMAT_NORMAL 0
80 #define DV_FORMAT_WIDE 1
81
82 static void dv_display_event (dv_display_t *dv_dpy);
83 static int dv_display_Xv_init (dv_display_t *dv_dpy, char *w_name,
84 char *i_name, int flags, int size);
85 #endif
86
87 dv_display_t *
dv_display_new(void)88 dv_display_new(void)
89 {
90 dv_display_t *result;
91
92 result = (dv_display_t *)calloc(1,sizeof(dv_display_t));
93 if(!result) goto no_mem;
94
95 no_mem:
96 return(result);
97 } /* dv_display_new */
98
99 void
dv_display_show(dv_display_t * dv_dpy)100 dv_display_show(dv_display_t *dv_dpy) {
101 switch(dv_dpy->lib) {
102 case e_dv_dpy_Xv:
103 #if HAVE_LIBXV
104 dv_display_event(dv_dpy);
105 if (!dv_dpy->dontdraw) {
106 XvShmPutImage(dv_dpy->dpy, dv_dpy->port,
107 dv_dpy->win, dv_dpy->gc,
108 dv_dpy->xv_image,
109 0, 0, /* sx, sy */
110 dv_dpy->swidth, dv_dpy->sheight, /* sw, sh */
111 dv_dpy->lxoff, dv_dpy->lyoff, /* dx, dy */
112 dv_dpy->lwidth, dv_dpy->lheight, /* dw, dh */
113 True);
114 XFlush(dv_dpy->dpy);
115 }
116 #endif /* HAVE_LIBXV */
117 break;
118 case e_dv_dpy_XShm:
119 break;
120 case e_dv_dpy_gtk:
121 break;
122 case e_dv_dpy_SDL:
123 #if HAVE_SDL
124 {
125 SDL_Event event;
126 if (SDL_PollEvent(&event)) {
127 if ( event.type == SDL_KEYDOWN ) {
128 switch(event.key.keysym.sym) {
129 case SDLK_ESCAPE:
130 case SDLK_q:
131 dv_dpy->dontdraw = 1;
132 break;
133 default:
134 break;
135 }
136 }
137 }
138
139 if (!dv_dpy->dontdraw) {
140 SDL_UnlockYUVOverlay(dv_dpy->overlay);
141 SDL_DisplayYUVOverlay(dv_dpy->overlay, &dv_dpy->rect);
142 SDL_LockYUVOverlay(dv_dpy->overlay);
143 } else {
144 SDL_Quit();
145 }
146 }
147 #endif
148 break;
149 default:
150 break;
151 } /* switch */
152 } /* dv_display_show */
153
154 void
dv_display_exit(dv_display_t * dv_dpy)155 dv_display_exit(dv_display_t *dv_dpy) {
156 if(!dv_dpy)
157 return;
158
159 switch(dv_dpy->lib) {
160 case e_dv_dpy_Xv:
161 #if HAVE_LIBXV
162
163 XvStopVideo(dv_dpy->dpy, dv_dpy->port, dv_dpy->win);
164
165 if(dv_dpy->shminfo.shmaddr)
166 shmdt(dv_dpy->shminfo.shmaddr);
167
168 if(dv_dpy->shminfo.shmid > 0)
169 shmctl(dv_dpy->shminfo.shmid, IPC_RMID, 0);
170
171 if(dv_dpy->xv_image)
172 free(dv_dpy->xv_image);
173 dv_dpy->xv_image = NULL;
174
175 #endif /* HAVE_LIBXV */
176 break;
177 case e_dv_dpy_gtk:
178 break;
179 case e_dv_dpy_XShm:
180 break;
181 case e_dv_dpy_SDL:
182 #if HAVE_SDL
183 SDL_Quit();
184 #endif /* HAVE_SDL */
185 break;
186 } /* switch */
187
188 free(dv_dpy);
189 dv_dpy = NULL;
190 } /* dv_display_exit */
191
192 static int
dv_display_gdk_init(dv_display_t * dv_dpy,int * argc,char *** argv)193 dv_display_gdk_init(dv_display_t *dv_dpy, int *argc, char ***argv) {
194
195 return FALSE;
196 } /* dv_display_gdk_init */
197
198 #if HAVE_LIBXV
199
200 static int xv_pause=0;
201
202 /* ----------------------------------------------------------------------------
203 */
204 static void
dv_display_event(dv_display_t * dv_dpy)205 dv_display_event (dv_display_t *dv_dpy)
206 {
207 int old_pic_format;
208 KeySym keysym;
209 char buf[16];
210
211
212 while (XCheckTypedWindowEvent (dv_dpy->dpy, dv_dpy->win,
213 ConfigureNotify, &dv_dpy->event) ||
214 XCheckTypedWindowEvent (dv_dpy->dpy, dv_dpy->win,
215 KeyPress, &dv_dpy->event)) {
216 switch (dv_dpy->event.type) {
217 case ConfigureNotify:
218 dv_dpy->dwidth = dv_dpy->event.xconfigure.width;
219 dv_dpy->dheight = dv_dpy->event.xconfigure.height;
220 /* --------------------------------------------------------------------
221 * set current picture format to unknown, so that .._check_format
222 * does some work.
223 */
224 old_pic_format = dv_dpy->pic_format;
225 dv_dpy->pic_format = DV_FORMAT_UNKNOWN;
226 dv_display_check_format (dv_dpy, old_pic_format);
227 break;
228 case KeyPress:
229
230 XLookupString (&dv_dpy->event.xkey, buf, 16, &keysym, NULL);
231
232 switch(keysym) {
233
234 case XK_Escape:
235 dv_dpy->dontdraw = 1;
236 xv_pause=0;
237 XvStopVideo(dv_dpy->dpy, dv_dpy->port, dv_dpy->win);
238 XDestroyWindow(dv_dpy->dpy, dv_dpy->win);
239 break;
240
241 case XK_Q:
242 case XK_q:
243 xv_pause=0;
244 dv_dpy->dontdraw = (dv_dpy->dontdraw) ? 0:1;
245 break;
246
247 case XK_space:
248 xv_pause = (xv_pause)?0:1;
249 while(xv_pause) {
250 dv_display_event(dv_dpy);
251 usleep(10000);
252 }
253
254 default:
255 break;
256 }
257 break;
258 default:
259 break;
260 } /* switch */
261 } /* while */
262 } /* dv_display_event */
263
264 #endif /* HAVE_LIBXV */
265
266 /* ----------------------------------------------------------------------------
267 */
268 void
dv_display_set_norm(dv_display_t * dv_dpy,dv_system_t norm)269 dv_display_set_norm (dv_display_t *dv_dpy, dv_system_t norm)
270 {
271 #if HAVE_LIBXV
272 dv_dpy->sheight = (norm == e_dv_system_625_50) ? 576: 480;
273 #endif /* HAVE_LIBXV */
274 } /* dv_display_set_norm */
275
276 /* ----------------------------------------------------------------------------
277 */
278 void
dv_display_check_format(dv_display_t * dv_dpy,int pic_format)279 dv_display_check_format(dv_display_t *dv_dpy, int pic_format)
280 {
281 #if HAVE_LIBXV
282 /* return immediate if ther is no format change or no format
283 * specific flag was set upon initialisation
284 */
285 if (pic_format == dv_dpy->pic_format ||
286 !(dv_dpy->flags & XV_FORMAT_MASK))
287 return;
288
289 /* --------------------------------------------------------------------
290 * check if there are some aspect ratio constraints
291 */
292 if (dv_dpy->flags & XV_FORMAT_NORMAL) {
293 if (pic_format == DV_FORMAT_NORMAL) {
294 dv_dpy->lxoff = dv_dpy->lyoff = 0;
295 dv_dpy->lwidth = dv_dpy->dwidth;
296 dv_dpy->lheight = dv_dpy->dheight;
297 } else if (pic_format == DV_FORMAT_WIDE) {
298 dv_dpy->lxoff = 0;
299 dv_dpy->lyoff = dv_dpy->dheight / 8;
300 dv_dpy->lwidth = dv_dpy->dwidth;
301 dv_dpy->lheight = (dv_dpy->dheight * 3) / 4;
302 }
303 } else if (dv_dpy->flags & XV_FORMAT_WIDE) {
304 if (pic_format == DV_FORMAT_NORMAL) {
305 dv_dpy->lxoff = dv_dpy->dwidth / 8;
306 dv_dpy->lyoff = 0;
307 dv_dpy->lwidth = (dv_dpy->dwidth * 3) / 4;
308 dv_dpy->lheight = dv_dpy->dheight;
309 } else if (pic_format == DV_FORMAT_WIDE) {
310 dv_dpy->lxoff = dv_dpy->lyoff = 0;
311 dv_dpy->lwidth = dv_dpy->dwidth;
312 dv_dpy->lheight = dv_dpy->dheight;
313 }
314 } else {
315 dv_dpy->lwidth = dv_dpy->dwidth;
316 dv_dpy->lheight = dv_dpy->dheight;
317 }
318 dv_dpy->pic_format = pic_format;
319 #endif /* HAVE_LIBXV */
320 } /* dv_display_check_format */
321
322 #if HAVE_LIBXV
323 /* ----------------------------------------------------------------------------
324 */
325 static int
dv_display_Xv_init(dv_display_t * dv_dpy,char * w_name,char * i_name,int flags,int size)326 dv_display_Xv_init(dv_display_t *dv_dpy, char *w_name, char *i_name,
327 int flags, int size) {
328 int scn_id,
329 ad_cnt, fmt_cnt,
330 got_port, got_fmt,
331 i, k;
332 XGCValues values;
333 XSizeHints hints;
334 XWMHints wmhints;
335 XTextProperty x_wname, x_iname;
336
337 XvAdaptorInfo *ad_info;
338 XvImageFormatValues *fmt_info;
339
340 if(!(dv_dpy->dpy = XOpenDisplay(NULL))) {
341 return 0;
342 } /* if */
343
344 dv_dpy->rwin = DefaultRootWindow(dv_dpy->dpy);
345 scn_id = DefaultScreen(dv_dpy->dpy);
346
347 /*
348 * So let's first check for an available adaptor and port
349 */
350 if(Success == XvQueryAdaptors(dv_dpy->dpy, dv_dpy->rwin, &ad_cnt, &ad_info)) {
351
352 for(i = 0, got_port = False; i < ad_cnt; ++i) {
353 tc_log_msg(__FILE__,
354 "Xv: %s: ports %ld - %ld",
355 ad_info[i].name,
356 ad_info[i].base_id,
357 ad_info[i].base_id +
358 ad_info[i].num_ports - 1);
359
360 if (dv_dpy->arg_xv_port != 0 &&
361 (dv_dpy->arg_xv_port < ad_info[i].base_id ||
362 dv_dpy->arg_xv_port >= ad_info[i].base_id+ad_info[i].num_ports)) {
363 tc_log_msg(__FILE__,
364 "Xv: %s: skipping (looking for port %i)",
365 ad_info[i].name,
366 dv_dpy->arg_xv_port);
367 continue;
368 }
369
370 if (!(ad_info[i].type & XvImageMask)) {
371 tc_log_warn(__FILE__,
372 "Xv: %s: XvImage NOT in capabilty list (%s%s%s%s%s )",
373 ad_info[i].name,
374 (ad_info[i].type & XvInputMask) ? " XvInput" : "",
375 (ad_info[i]. type & XvOutputMask) ? " XvOutput" : "",
376 (ad_info[i]. type & XvVideoMask) ? " XvVideo" : "",
377 (ad_info[i]. type & XvStillMask) ? " XvStill" : "",
378 (ad_info[i]. type & XvImageMask) ? " XvImage" : "");
379 continue;
380 } /* if */
381 fmt_info = XvListImageFormats(dv_dpy->dpy, ad_info[i].base_id,&fmt_cnt);
382 if (!fmt_info || fmt_cnt == 0) {
383 tc_log_warn(__FILE__, "Xv: %s: NO supported formats", ad_info[i].name);
384 continue;
385 } /* if */
386 for(got_fmt = False, k = 0; k < fmt_cnt; ++k) {
387 if (dv_dpy->format == fmt_info[k].id) {
388 got_fmt = True;
389 break;
390 } /* if */
391 } /* for */
392 if (!got_fmt) {
393 char tmpbuf[1000];
394 *tmpbuf = 0;
395 for (k = 0; k < fmt_cnt; ++k) {
396 tc_snprintf(tmpbuf+strlen(tmpbuf), sizeof(tmpbuf)-strlen(tmpbuf),
397 "%s%#08x[%s]", k>0 ? " " : "", fmt_info[k].id,
398 fmt_info[k].guid);
399 }
400 tc_log_warn(__FILE__,
401 "Xv: %s: format %#08x is NOT in format list (%s)",
402 ad_info[i].name,
403 dv_dpy->format,
404 tmpbuf);
405 continue;
406 } /* if */
407
408 for(dv_dpy->port = ad_info[i].base_id, k = 0;
409 k < ad_info[i].num_ports;
410 ++k, ++(dv_dpy->port)) {
411 if (dv_dpy->arg_xv_port != 0 && dv_dpy->arg_xv_port != dv_dpy->port) continue;
412 if(!XvGrabPort(dv_dpy->dpy, dv_dpy->port, CurrentTime)) {
413 tc_log_msg(__FILE__, "Xv: grabbed port %ld",
414 dv_dpy->port);
415 got_port = True;
416 break;
417 } /* if */
418 } /* for */
419 if(got_port)
420 break;
421 } /* for */
422
423 } else {
424 /* Xv extension probably not present */
425 return 0;
426 } /* else */
427
428 if(!ad_cnt) {
429 tc_log_warn(__FILE__, "Xv: (ERROR) no adaptor found!");
430 return 0;
431 }
432 if(!got_port) {
433 tc_log_warn(__FILE__, "Xv: (ERROR) could not grab any port!");
434 return 0;
435 }
436
437 /* --------------------------------------------------------------------------
438 * default settings which allow arbitraray resizing of the window
439 */
440 hints.flags = PSize | PMaxSize | PMinSize;
441 hints.min_width = dv_dpy->width / 16;
442 hints.min_height = dv_dpy->height / 16;
443
444 /* --------------------------------------------------------------------------
445 * maximum dimensions for Xv support are about 2048x2048
446 */
447 hints.max_width = 2048;
448 hints.max_height = 2048;
449
450 wmhints.input = True;
451 wmhints.flags = InputHint;
452
453 XStringListToTextProperty(&w_name, 1 ,&x_wname);
454 XStringListToTextProperty(&i_name, 1 ,&x_iname);
455
456 /*
457 * default settings: source, destination and logical widht/height
458 * are set to our well known dimensions.
459 */
460 dv_dpy->lwidth = dv_dpy->dwidth = dv_dpy->swidth = dv_dpy->width;
461 dv_dpy->lheight = dv_dpy->dheight = dv_dpy->sheight = dv_dpy->height;
462 dv_dpy->lxoff = dv_dpy->lyoff = 0;
463 dv_dpy-> flags = flags;
464
465 if (flags & XV_FORMAT_MASK) {
466 dv_dpy->lwidth = dv_dpy->dwidth = 768;
467 dv_dpy->lheight = dv_dpy->dheight = 576;
468 dv_dpy->pic_format = DV_FORMAT_UNKNOWN;
469 if (flags & XV_FORMAT_WIDE) {
470 dv_dpy->lwidth = dv_dpy->dwidth = 1024;
471 }
472 }
473 if (size) {
474 dv_dpy->lwidth = (int)(((double)dv_dpy->lwidth * (double)size)/100.0);
475 dv_dpy->lheight = (int)(((double)dv_dpy->lheight * (double)size)/100.0);
476 dv_dpy->dwidth = (int)(((double)dv_dpy->dwidth * (double)size)/100.0);
477 dv_dpy->dheight = (int)(((double)dv_dpy->dheight * (double)size)/100.0);
478 }
479 if (flags & XV_FORMAT_MASK) {
480 hints.flags |= PAspect;
481 if (flags & XV_FORMAT_WIDE) {
482 hints.min_aspect.x = hints.max_aspect.x = 1024;
483 } else {
484 hints.min_aspect.x = hints.max_aspect.x = 768;
485 }
486 hints.min_aspect.y = hints.max_aspect.y = 576;
487 }
488
489 if (!(flags & XV_NOSAWINDOW)) {
490 dv_dpy->win = XCreateSimpleWindow(dv_dpy->dpy,
491 dv_dpy->rwin,
492 0, 0,
493 dv_dpy->dwidth, dv_dpy->dheight,
494 0,
495 XWhitePixel(dv_dpy->dpy, scn_id),
496 XBlackPixel(dv_dpy->dpy, scn_id));
497 } else {
498 }
499 XSetWMProperties(dv_dpy->dpy, dv_dpy->win,
500 &x_wname, &x_iname,
501 NULL, 0,
502 &hints, &wmhints, NULL);
503
504 XSelectInput(dv_dpy->dpy, dv_dpy->win, ExposureMask | StructureNotifyMask | KeyPressMask);
505 XMapRaised(dv_dpy->dpy, dv_dpy->win);
506 XNextEvent(dv_dpy->dpy, &dv_dpy->event);
507
508 dv_dpy->gc = XCreateGC(dv_dpy->dpy, dv_dpy->win, 0, &values);
509
510 /*
511 * Now we do shared memory allocation etc..
512 */
513 dv_dpy->xv_image = XvShmCreateImage(dv_dpy->dpy, dv_dpy->port,
514 dv_dpy->format, dv_dpy->pixels[0],
515 dv_dpy->width, dv_dpy->height,
516 &dv_dpy->shminfo);
517
518 dv_dpy->shminfo.shmid = shmget(IPC_PRIVATE,
519 dv_dpy->len,
520 IPC_CREAT | 0777);
521
522 dv_dpy->xv_image->data = dv_dpy->pixels[0] = dv_dpy->shminfo.shmaddr =
523 shmat(dv_dpy->shminfo.shmid, 0, 0);
524
525 XShmAttach(dv_dpy->dpy, &dv_dpy->shminfo);
526 XSync(dv_dpy->dpy, False);
527
528 return 1;
529 } /* dv_display_Xv_init */
530 #endif /* HAVE_LIBXV */
531
532
533 #if HAVE_SDL
534
535 static void
dv_center_window(SDL_Surface * screen)536 dv_center_window(SDL_Surface *screen)
537 {
538 SDL_SysWMinfo info;
539
540 SDL_VERSION(&info.version);
541 if ( SDL_GetWMInfo(&info) > 0 ) {
542 int x, y;
543 int w, h;
544 if ( info.subsystem == SDL_SYSWM_X11 ) {
545 info.info.x11.lock_func();
546 w = DisplayWidth(info.info.x11.display,
547 DefaultScreen(info.info.x11.display));
548 h = DisplayHeight(info.info.x11.display,
549 DefaultScreen(info.info.x11.display));
550 x = (w - screen->w)/2;
551 y = (h - screen->h)/2;
552 XMoveWindow(info.info.x11.display, info.info.x11.wmwindow, x, y);
553 info.info.x11.unlock_func();
554 } /* if */
555 } /* if */
556 } /* dv_center_window */
557
558 static int
dv_display_SDL_init(dv_display_t * dv_dpy,char * w_name,char * i_name)559 dv_display_SDL_init(dv_display_t *dv_dpy, char *w_name, char *i_name) {
560 const SDL_VideoInfo *video_info;
561 int video_bpp;
562
563 if(SDL_Init(SDL_INIT_VIDEO) < 0) goto no_sdl;
564 /* Get the "native" video mode */
565 video_info = SDL_GetVideoInfo();
566 switch (video_info->vfmt->BitsPerPixel) {
567 case 16:
568 case 32:
569 video_bpp = video_info->vfmt->BitsPerPixel;
570 break;
571 default:
572 video_bpp = 16;
573 break;
574 } /* switch */
575 dv_dpy->sdl_screen = SDL_SetVideoMode(dv_dpy->width,dv_dpy->height,
576 video_bpp,SDL_HWSURFACE);
577 SDL_WM_SetCaption(w_name, i_name);
578 dv_dpy->overlay = SDL_CreateYUVOverlay(dv_dpy->width, dv_dpy->height, dv_dpy->format,
579 dv_dpy->sdl_screen);
580 if((!dv_dpy->overlay || (!dv_dpy->overlay->hw_overlay) || /* we only want HW overlays */
581 SDL_LockYUVOverlay(dv_dpy->overlay)<0)) {
582 goto no_overlay;
583 } /* if */
584 dv_center_window(dv_dpy->sdl_screen);
585 dv_dpy->rect.x = 0;
586 dv_dpy->rect.y = 0;
587 dv_dpy->rect.w = dv_dpy->overlay->w;
588 dv_dpy->rect.h = dv_dpy->overlay->h;
589 dv_dpy->pixels[0] = dv_dpy->overlay->pixels[0];
590 dv_dpy->pixels[1] = dv_dpy->overlay->pixels[1];
591 dv_dpy->pixels[2] = dv_dpy->overlay->pixels[2];
592 dv_dpy->pitches[0] = dv_dpy->overlay->pitches[0];
593 dv_dpy->pitches[1] = dv_dpy->overlay->pitches[1];
594 dv_dpy->pitches[2] = dv_dpy->overlay->pitches[2];
595 return(True);
596
597 no_overlay:
598 if(dv_dpy->overlay)
599 SDL_FreeYUVOverlay(dv_dpy->overlay);
600 SDL_Quit();
601 no_sdl:
602 return(False);
603
604 } /* dv_display_SDL_init */
605
606 #else
607
608 static int
dv_display_SDL_init(dv_display_t * dv_dpy,char * w_name,char * i_name)609 dv_display_SDL_init(dv_display_t *dv_dpy, char *w_name, char *i_name) {
610 tc_log_warn(__FILE__,"playdv was compiled without SDL support");
611 return(FALSE);
612 } /* dv_display_SDL_init */
613
614 #endif /* HAVE_SDL */
615
616 int
dv_display_init(dv_display_t * dv_dpy,int * argc,char *** argv,int width,int height,dv_sample_t sampling,char * w_name,char * i_name)617 dv_display_init(dv_display_t *dv_dpy, int *argc, char ***argv, int width, int height,
618 dv_sample_t sampling, char *w_name, char *i_name) {
619
620 dv_dpy->width = width;
621 dv_dpy->height = height;
622
623 dv_dpy->dontdraw = 0;
624
625 switch(sampling) {
626
627 case e_dv_sample_420:
628 dv_dpy->format = DV_FOURCC_YV12;
629 dv_dpy->len = (dv_dpy->width * dv_dpy->height * 3) / 2;
630 break;
631
632 default:
633 /* Not possible */
634 break;
635 } /* switch */
636
637 switch(dv_dpy->arg_display) {
638 case 0:
639 /* Autoselect */
640 #if HAVE_LIBXV
641 /* Try to use Xv first, then SDL */
642 if(dv_display_Xv_init(dv_dpy, w_name, i_name,
643 dv_dpy->arg_aspect_val,
644 dv_dpy->arg_size_val)) {
645 goto Xv_ok;
646 } else
647 #endif /* HAVE_LIBXV */
648 if(dv_display_SDL_init(dv_dpy, w_name, i_name)) {
649 goto SDL_ok;
650 } else {
651 goto use_gtk;
652 } /* else */
653 break;
654 case 1:
655 /* Gtk */
656 goto use_gtk;
657 break;
658 case 2:
659 #if HAVE_LIBXV
660 /* Xv */
661 if(dv_display_Xv_init(dv_dpy, w_name, i_name,
662 dv_dpy->arg_aspect_val,
663 dv_dpy->arg_size_val)) {
664 goto Xv_ok;
665 } else {
666 tc_log_error(__FILE__, "Attempt to display via Xv failed");
667 goto fail;
668 }
669 #else /* HAVE_LIBXV */
670 tc_log_error(__FILE__, "Attempt to display via Xv failed");
671 goto fail;
672 #endif /* HAVE_LIBXV */
673 break;
674 case 3:
675 /* SDL */
676 if(dv_display_SDL_init(dv_dpy, w_name, i_name)) {
677 goto SDL_ok;
678 } else {
679 tc_log_error(__FILE__, "Attempt to display via SDL failed");
680 goto fail;
681 }
682 break;
683 default:
684 break;
685 } /* switch */
686
687 #if HAVE_LIBXV
688 Xv_ok:
689 tc_log_info(__FILE__, " Using Xv for display");
690 dv_dpy->lib = e_dv_dpy_Xv;
691 goto yuv_ok;
692 #endif /* HAVE_LIBXV */
693
694 SDL_ok:
695 tc_log_info(__FILE__, " Using SDL for display");
696 dv_dpy->lib = e_dv_dpy_SDL;
697 goto yuv_ok;
698
699 yuv_ok:
700
701 dv_dpy->color_space = e_dv_color_yuv;
702
703 switch(dv_dpy->format) {
704 case DV_FOURCC_YUY2:
705 dv_dpy->pitches[0] = width * 2;
706 break;
707 case DV_FOURCC_YV12:
708 dv_dpy->pixels[1] = dv_dpy->pixels[0] + (width * height);
709 dv_dpy->pixels[2] = dv_dpy->pixels[1] + (width * height / 4);
710 dv_dpy->pitches[0] = width;
711 dv_dpy->pitches[1] = width / 2;
712 dv_dpy->pitches[2] = width / 2;
713 break;
714 } /* switch */
715
716 goto ok;
717
718 use_gtk:
719
720 /* Try to use GDK since we couldn't get a HW YUV surface */
721 dv_dpy->color_space = e_dv_color_rgb;
722 dv_dpy->lib = e_dv_dpy_gtk;
723 dv_dpy->len = dv_dpy->width * dv_dpy->height * 3;
724 if(!dv_display_gdk_init(dv_dpy, argc, argv)) {
725 tc_log_error(__FILE__, "Attempt to use gtk for display failed");
726 goto fail;
727 } /* if */
728 dv_dpy->pitches[0] = width * 3;
729 tc_log_info(__FILE__, " Using gtk for display");
730
731 ok:
732 return(TRUE);
733
734 fail:
735 tc_log_error(__FILE__, " Unable to establish a display method");
736 return(FALSE);
737 } /* dv_display_init */
738