~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libvo/vo_x11.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:45:33 UTC
  • Revision ID: siretart@tauware.de-20060708084533-dbc155bde7122e78
imported mplayer_0.99+1.0pre7try2+cvs20060117

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#include <stdio.h>
 
3
#include <stdlib.h>
 
4
#include <string.h>
 
5
#include <signal.h>
 
6
 
 
7
#include "config.h"
 
8
#include "video_out.h"
 
9
#include "video_out_internal.h"
 
10
 
 
11
 
 
12
#include <X11/Xlib.h>
 
13
#include <X11/Xutil.h>
 
14
 
 
15
#ifdef HAVE_XF86VM
 
16
#include <X11/extensions/xf86vmode.h>
 
17
#endif
 
18
#include <errno.h>
 
19
 
 
20
#include "x11_common.h"
 
21
 
 
22
#ifdef HAVE_SHM
 
23
#include <sys/ipc.h>
 
24
#include <sys/shm.h>
 
25
#include <X11/extensions/XShm.h>
 
26
 
 
27
static int Shmem_Flag;
 
28
 
 
29
//static int Quiet_Flag;  Here also what is this for. It's used but isn't inited ?
 
30
static XShmSegmentInfo Shminfo[1];
 
31
static int gXErrorFlag;
 
32
static int CompletionType = -1;
 
33
 
 
34
/* since it doesn't seem to be defined on some platforms */
 
35
int XShmGetEventBase(Display *);
 
36
#endif
 
37
 
 
38
#include "fastmemcpy.h"
 
39
#include "sub.h"
 
40
 
 
41
#include "postproc/swscale.h"
 
42
#include "postproc/swscale_internal.h"       //FIXME
 
43
#include "postproc/rgb2rgb.h"
 
44
#include "libmpcodecs/vf_scale.h"
 
45
 
 
46
#include "mp_msg.h"
 
47
 
 
48
#ifdef HAVE_NEW_GUI
 
49
#include "Gui/interface.h"
 
50
#include "mplayer.h"
 
51
#endif
 
52
 
 
53
static vo_info_t info = {
 
54
    "X11 ( XImage/Shm )",
 
55
    "x11",
 
56
    "Aaron Holtzman <aholtzma@ess.engr.uvic.ca>",
 
57
    ""
 
58
};
 
59
 
 
60
LIBVO_EXTERN(x11)
 
61
/* private prototypes */
 
62
static void Display_Image(XImage * myximage, unsigned char *ImageData);
 
63
static void (*draw_alpha_fnc) (int x0, int y0, int w, int h,
 
64
                               unsigned char *src, unsigned char *srca,
 
65
                               int stride);
 
66
 
 
67
/* local data */
 
68
static unsigned char *ImageData;
 
69
 
 
70
/* X11 related variables */
 
71
static XImage *myximage = NULL;
 
72
static int depth, bpp, mode;
 
73
static XWindowAttributes attribs;
 
74
 
 
75
static int int_pause;
 
76
 
 
77
static int Flip_Flag;
 
78
static int zoomFlag;
 
79
 
 
80
 
 
81
static uint32_t image_width;
 
82
static uint32_t image_height;
 
83
static uint32_t in_format;
 
84
static uint32_t out_format = 0;
 
85
static int srcW = -1;
 
86
static int srcH = -1;
 
87
static int aspect;              // 1<<16 based fixed point aspect, so that the aspect stays correct during resizing
 
88
 
 
89
static int old_vo_dwidth = -1;
 
90
static int old_vo_dheight = -1;
 
91
 
 
92
static void check_events()
 
93
{
 
94
    int ret = vo_x11_check_events(mDisplay);
 
95
 
 
96
    /* clear left over borders and redraw frame if we are paused */
 
97
    if (ret & VO_EVENT_EXPOSE && int_pause)
 
98
    {
 
99
        vo_x11_clearwindow_part(mDisplay, vo_window, myximage->width,
 
100
                                myximage->height, 0);
 
101
        flip_page();
 
102
    } else if ((ret & VO_EVENT_RESIZE) || (ret & VO_EVENT_EXPOSE))
 
103
        vo_x11_clearwindow_part(mDisplay, vo_window, myximage->width,
 
104
                                myximage->height, 0);
 
105
 
 
106
}
 
107
 
 
108
static void draw_alpha_32(int x0, int y0, int w, int h, unsigned char *src,
 
109
                          unsigned char *srca, int stride)
 
110
{
 
111
    vo_draw_alpha_rgb32(w, h, src, srca, stride,
 
112
                        ImageData + 4 * (y0 * image_width + x0),
 
113
                        4 * image_width);
 
114
}
 
115
 
 
116
static void draw_alpha_24(int x0, int y0, int w, int h, unsigned char *src,
 
117
                          unsigned char *srca, int stride)
 
118
{
 
119
    vo_draw_alpha_rgb24(w, h, src, srca, stride,
 
120
                        ImageData + 3 * (y0 * image_width + x0),
 
121
                        3 * image_width);
 
122
}
 
123
 
 
124
static void draw_alpha_16(int x0, int y0, int w, int h, unsigned char *src,
 
125
                          unsigned char *srca, int stride)
 
126
{
 
127
    vo_draw_alpha_rgb16(w, h, src, srca, stride,
 
128
                        ImageData + 2 * (y0 * image_width + x0),
 
129
                        2 * image_width);
 
130
}
 
131
 
 
132
static void draw_alpha_15(int x0, int y0, int w, int h, unsigned char *src,
 
133
                          unsigned char *srca, int stride)
 
134
{
 
135
    vo_draw_alpha_rgb15(w, h, src, srca, stride,
 
136
                        ImageData + 2 * (y0 * image_width + x0),
 
137
                        2 * image_width);
 
138
}
 
139
 
 
140
static void draw_alpha_null(int x0, int y0, int w, int h,
 
141
                            unsigned char *src, unsigned char *srca,
 
142
                            int stride)
 
143
{
 
144
}
 
145
 
 
146
static SwsContext *swsContext = NULL;
 
147
extern int sws_flags;
 
148
 
 
149
static XVisualInfo vinfo;
 
150
 
 
151
static void getMyXImage()
 
152
{
 
153
#ifdef HAVE_SHM
 
154
    if (mLocalDisplay && XShmQueryExtension(mDisplay))
 
155
        Shmem_Flag = 1;
 
156
    else
 
157
    {
 
158
        Shmem_Flag = 0;
 
159
        mp_msg(MSGT_VO, MSGL_WARN,
 
160
               "Shared memory not supported\nReverting to normal Xlib\n");
 
161
    }
 
162
    if (Shmem_Flag)
 
163
        CompletionType = XShmGetEventBase(mDisplay) + ShmCompletion;
 
164
 
 
165
    if (Shmem_Flag)
 
166
    {
 
167
        myximage =
 
168
            XShmCreateImage(mDisplay, vinfo.visual, depth, ZPixmap, NULL,
 
169
                            &Shminfo[0], image_width, image_height);
 
170
        if (myximage == NULL)
 
171
        {
 
172
            if (myximage != NULL)
 
173
                XDestroyImage(myximage);
 
174
            mp_msg(MSGT_VO, MSGL_WARN,
 
175
                   "Shared memory error,disabling ( Ximage error )\n");
 
176
            goto shmemerror;
 
177
        }
 
178
        Shminfo[0].shmid = shmget(IPC_PRIVATE,
 
179
                                  myximage->bytes_per_line *
 
180
                                  myximage->height, IPC_CREAT | 0777);
 
181
        if (Shminfo[0].shmid < 0)
 
182
        {
 
183
            XDestroyImage(myximage);
 
184
            mp_msg(MSGT_VO, MSGL_V, "%s\n", strerror(errno));
 
185
            //perror( strerror( errno ) );
 
186
            mp_msg(MSGT_VO, MSGL_WARN,
 
187
                   "Shared memory error,disabling ( seg id error )\n");
 
188
            goto shmemerror;
 
189
        }
 
190
        Shminfo[0].shmaddr = (char *) shmat(Shminfo[0].shmid, 0, 0);
 
191
 
 
192
        if (Shminfo[0].shmaddr == ((char *) -1))
 
193
        {
 
194
            XDestroyImage(myximage);
 
195
            if (Shminfo[0].shmaddr != ((char *) -1))
 
196
                shmdt(Shminfo[0].shmaddr);
 
197
            mp_msg(MSGT_VO, MSGL_WARN,
 
198
                   "Shared memory error,disabling ( address error )\n");
 
199
            goto shmemerror;
 
200
        }
 
201
        myximage->data = Shminfo[0].shmaddr;
 
202
        ImageData = (unsigned char *) myximage->data;
 
203
        Shminfo[0].readOnly = False;
 
204
        XShmAttach(mDisplay, &Shminfo[0]);
 
205
 
 
206
        XSync(mDisplay, False);
 
207
 
 
208
        if (gXErrorFlag)
 
209
        {
 
210
            XDestroyImage(myximage);
 
211
            shmdt(Shminfo[0].shmaddr);
 
212
            mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling.\n");
 
213
            gXErrorFlag = 0;
 
214
            goto shmemerror;
 
215
        } else
 
216
            shmctl(Shminfo[0].shmid, IPC_RMID, 0);
 
217
 
 
218
        {
 
219
            static int firstTime = 1;
 
220
 
 
221
            if (firstTime)
 
222
            {
 
223
                mp_msg(MSGT_VO, MSGL_V, "Sharing memory.\n");
 
224
                firstTime = 0;
 
225
            }
 
226
        }
 
227
    } else
 
228
    {
 
229
      shmemerror:
 
230
        Shmem_Flag = 0;
 
231
#endif
 
232
        myximage = XGetImage(mDisplay, vo_window, 0, 0,
 
233
                             image_width, image_height, AllPlanes,
 
234
                             ZPixmap);
 
235
        ImageData = myximage->data;
 
236
#ifdef HAVE_SHM
 
237
    }
 
238
#endif
 
239
}
 
240
 
 
241
static void freeMyXImage()
 
242
{
 
243
#ifdef HAVE_SHM
 
244
    if (Shmem_Flag)
 
245
    {
 
246
        XShmDetach(mDisplay, &Shminfo[0]);
 
247
        XDestroyImage(myximage);
 
248
        shmdt(Shminfo[0].shmaddr);
 
249
    } else
 
250
#endif
 
251
    {
 
252
        XDestroyImage(myximage);
 
253
    }
 
254
    myximage = NULL;
 
255
}
 
256
 
 
257
static int config(uint32_t width, uint32_t height, uint32_t d_width,
 
258
                       uint32_t d_height, uint32_t flags, char *title,
 
259
                       uint32_t format)
 
260
{
 
261
// int screen;
 
262
    int fullscreen = 0;
 
263
    int vm = 0;
 
264
 
 
265
// int interval, prefer_blank, allow_exp, nothing;
 
266
    unsigned int fg, bg;
 
267
    XEvent xev;
 
268
    XGCValues xgcv;
 
269
    Colormap theCmap;
 
270
    XSetWindowAttributes xswa;
 
271
    unsigned long xswamask;
 
272
 
 
273
#ifdef HAVE_XF86VM
 
274
    unsigned int modeline_width, modeline_height;
 
275
    static uint32_t vm_width;
 
276
    static uint32_t vm_height;
 
277
#endif
 
278
 
 
279
    vo_mouse_autohide = 1;
 
280
    old_vo_dwidth = -1;
 
281
    old_vo_dheight = -1;
 
282
 
 
283
    if (!title)
 
284
        title = strdup("MPlayer X11 (XImage/Shm) render");
 
285
 
 
286
    in_format = format;
 
287
    srcW = width;
 
288
    srcH = height;
 
289
    vo_dx = (vo_screenwidth - d_width) / 2;
 
290
    vo_dy = (vo_screenheight - d_height) / 2;
 
291
    geometry(&vo_dx, &vo_dy, &d_width, &d_height, vo_screenwidth,
 
292
             vo_screenheight);
 
293
    vo_dwidth = d_width;
 
294
    vo_dheight = d_height;
 
295
 
 
296
    if (flags & (VOFLAG_FULLSCREEN|VOFLAG_MODESWITCHING))
 
297
        fullscreen = 1;
 
298
    if (flags & VOFLAG_MODESWITCHING)
 
299
        vm = 1;
 
300
    if (flags & VOFLAG_FLIPPING)
 
301
        Flip_Flag = 1;
 
302
    zoomFlag = flags & VOFLAG_SWSCALE;
 
303
 
 
304
    int_pause = 0;
 
305
// if(!fullscreen) zoomFlag=1; //it makes no sense to avoid zooming on windowd mode
 
306
 
 
307
//printf( "w: %d h: %d\n\n",vo_dwidth,vo_dheight );
 
308
 
 
309
    XGetWindowAttributes(mDisplay, mRootWin, &attribs);
 
310
    depth = attribs.depth;
 
311
 
 
312
    if (depth != 15 && depth != 16 && depth != 24 && depth != 32)
 
313
    {
 
314
        Visual *visual;
 
315
 
 
316
        depth = vo_find_depth_from_visuals(mDisplay, mScreen, &visual);
 
317
    }
 
318
    if (!XMatchVisualInfo(mDisplay, mScreen, depth, DirectColor, &vinfo) ||
 
319
        (WinID > 0
 
320
         && vinfo.visualid != XVisualIDFromVisual(attribs.visual)))
 
321
        XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo);
 
322
 
 
323
    /* set image size (which is indeed neither the input nor output size), 
 
324
       if zoom is on it will be changed during draw_slice anyway so we don't duplicate the aspect code here 
 
325
     */
 
326
    image_width = (width + 7) & (~7);
 
327
    image_height = height;
 
328
 
 
329
    aspect = ((1 << 16) * d_width + d_height / 2) / d_height;
 
330
 
 
331
#ifdef HAVE_NEW_GUI
 
332
    if (use_gui)
 
333
        guiGetEvent(guiSetShVideo, 0);  // the GUI will set up / resize the window
 
334
    else
 
335
#endif
 
336
    {
 
337
#ifdef HAVE_XF86VM
 
338
        if (vm)
 
339
        {
 
340
            if ((d_width == 0) && (d_height == 0))
 
341
            {
 
342
                vm_width = image_width;
 
343
                vm_height = image_height;
 
344
            } else
 
345
            {
 
346
                vm_width = d_width;
 
347
                vm_height = d_height;
 
348
            }
 
349
            vo_vm_switch(vm_width, vm_height, &modeline_width,
 
350
                         &modeline_height);
 
351
            vo_dx = (vo_screenwidth - modeline_width) / 2;
 
352
            vo_dy = (vo_screenheight - modeline_height) / 2;
 
353
            vo_dwidth = modeline_width;
 
354
            vo_dheight = modeline_height;
 
355
        }
 
356
#endif
 
357
        bg = WhitePixel(mDisplay, mScreen);
 
358
        fg = BlackPixel(mDisplay, mScreen);
 
359
 
 
360
        theCmap = vo_x11_create_colormap(&vinfo);
 
361
 
 
362
        xswa.background_pixel = 0;
 
363
        xswa.border_pixel = 0;
 
364
        xswa.colormap = theCmap;
 
365
        xswamask = CWBackPixel | CWBorderPixel | CWColormap;
 
366
 
 
367
#ifdef HAVE_XF86VM
 
368
        if (vm)
 
369
        {
 
370
            xswa.override_redirect = True;
 
371
            xswamask |= CWOverrideRedirect;
 
372
        }
 
373
#endif
 
374
 
 
375
        if (WinID >= 0)
 
376
        {
 
377
            vo_window = WinID ? ((Window) WinID) : mRootWin;
 
378
            if (WinID)
 
379
            {
 
380
                int border;
 
381
                Window win;
 
382
                XUnmapWindow(mDisplay, vo_window);
 
383
                XChangeWindowAttributes(mDisplay, vo_window, xswamask,
 
384
                                        &xswa);
 
385
                vo_x11_selectinput_witherr(mDisplay, vo_window,
 
386
                                           StructureNotifyMask |
 
387
                                           KeyPressMask |
 
388
                                           PropertyChangeMask |
 
389
                                           PointerMotionMask |
 
390
                                           ButtonPressMask |
 
391
                                           ButtonReleaseMask |
 
392
                                           ExposureMask);
 
393
                XMapWindow(mDisplay, vo_window);
 
394
                XGetGeometry(mDisplay, vo_window, &mRootWin,
 
395
                             &vo_dx, &vo_dy, &vo_dwidth, &vo_dheight,
 
396
                             &border, &depth);
 
397
            } else
 
398
                XSelectInput(mDisplay, vo_window, ExposureMask);
 
399
        } else
 
400
        {
 
401
            if (vo_window == None)
 
402
            {
 
403
                vo_window =
 
404
                    vo_x11_create_smooth_window(mDisplay, mRootWin,
 
405
                                                vinfo.visual, vo_dx, vo_dy,
 
406
                                                vo_dwidth, vo_dheight,
 
407
                                                depth, theCmap);
 
408
 
 
409
                vo_x11_classhint(mDisplay, vo_window, "x11");
 
410
                vo_hidecursor(mDisplay, vo_window);
 
411
                vo_x11_sizehint(vo_dx, vo_dy, vo_dwidth, vo_dheight, 0);
 
412
                XSelectInput(mDisplay, vo_window, StructureNotifyMask);
 
413
                XStoreName(mDisplay, vo_window, title);
 
414
                XMapWindow(mDisplay, vo_window);
 
415
//      if(WinID!=0)
 
416
                do
 
417
                {
 
418
                    XNextEvent(mDisplay, &xev);
 
419
                }
 
420
                while (xev.type != MapNotify
 
421
                       || xev.xmap.event != vo_window);
 
422
 
 
423
                if (fullscreen)
 
424
                    vo_x11_fullscreen();
 
425
#ifdef HAVE_XINERAMA
 
426
                vo_x11_xinerama_move(mDisplay, vo_window);
 
427
#endif
 
428
            } else if (!fullscreen)
 
429
                XMoveResizeWindow(mDisplay, vo_window, vo_dx, vo_dy,
 
430
                                  vo_dwidth, vo_dheight);
 
431
        }
 
432
 
 
433
        XSync(mDisplay, False);
 
434
 
 
435
        // we cannot grab mouse events on root window :(
 
436
        vo_x11_selectinput_witherr(mDisplay, vo_window,
 
437
                                   StructureNotifyMask | KeyPressMask |
 
438
                                   PropertyChangeMask | ExposureMask |
 
439
                                   ((WinID ==
 
440
                                     0) ? 0 : (ButtonPressMask |
 
441
                                               ButtonReleaseMask |
 
442
                                               PointerMotionMask)));
 
443
 
 
444
#ifdef HAVE_XF86VM
 
445
        if (vm)
 
446
        {
 
447
            /* Grab the mouse pointer in our window */
 
448
            if (vo_grabpointer)
 
449
                XGrabPointer(mDisplay, vo_window, True, 0,
 
450
                             GrabModeAsync, GrabModeAsync,
 
451
                             vo_window, None, CurrentTime);
 
452
            XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime);
 
453
        }
 
454
#endif
 
455
    }
 
456
 
 
457
    if (vo_gc != None)
 
458
        XFreeGC(mDisplay, vo_gc);
 
459
    vo_gc = XCreateGC(mDisplay, vo_window, 0L, &xgcv);
 
460
 
 
461
    if (myximage)
 
462
    {
 
463
        freeMyXImage();
 
464
        sws_freeContext(swsContext);
 
465
    }
 
466
    getMyXImage();
 
467
 
 
468
    if (!WinID)
 
469
    {
 
470
        vo_dwidth = vo_screenwidth;
 
471
        vo_dheight = vo_screenheight;
 
472
    }
 
473
 
 
474
    switch ((bpp = myximage->bits_per_pixel))
 
475
    {
 
476
        case 24:
 
477
            draw_alpha_fnc = draw_alpha_24;
 
478
            out_format = IMGFMT_BGR24;
 
479
            break;
 
480
        case 32:
 
481
            draw_alpha_fnc = draw_alpha_32;
 
482
            out_format = IMGFMT_BGR32;
 
483
            break;
 
484
        case 15:
 
485
        case 16:
 
486
            if (depth == 15)
 
487
            {
 
488
                draw_alpha_fnc = draw_alpha_15;
 
489
                out_format = IMGFMT_BGR15;
 
490
            } else
 
491
            {
 
492
                draw_alpha_fnc = draw_alpha_16;
 
493
                out_format = IMGFMT_BGR16;
 
494
            }
 
495
            break;
 
496
        case 8:
 
497
            draw_alpha_fnc = draw_alpha_null;
 
498
            out_format = IMGFMT_BGR8;
 
499
            break;
 
500
        default:
 
501
            draw_alpha_fnc = draw_alpha_null;
 
502
    }
 
503
 
 
504
    /* always allocate swsContext as size could change between frames */
 
505
    swsContext =
 
506
        sws_getContextFromCmdLine(width, height, in_format, width, height,
 
507
                                  out_format);
 
508
    if (!swsContext)
 
509
        return -1;
 
510
 
 
511
    //printf( "X11 bpp: %d  color mask:  R:%lX  G:%lX  B:%lX\n",bpp,myximage->red_mask,myximage->green_mask,myximage->blue_mask );
 
512
 
 
513
    // If we have blue in the lowest bit then obviously RGB
 
514
    mode = ((myximage->blue_mask & 0x01) != 0) ? MODE_RGB : MODE_BGR;
 
515
#ifdef WORDS_BIGENDIAN
 
516
    if (myximage->byte_order != MSBFirst)
 
517
#else
 
518
    if (myximage->byte_order != LSBFirst)
 
519
#endif
 
520
    {
 
521
        mode = ((myximage->blue_mask & 0x01) != 0) ? MODE_BGR : MODE_RGB;
 
522
//   printf( "No support for non-native XImage byte order!\n" );
 
523
//   return -1;
 
524
    }
 
525
#ifdef WORDS_BIGENDIAN
 
526
    if (mode == MODE_BGR && bpp != 32)
 
527
    {
 
528
        mp_msg(MSGT_VO, MSGL_ERR,
 
529
               "BGR%d not supported, please contact the developers\n",
 
530
               bpp);
 
531
        return -1;
 
532
    }
 
533
#else
 
534
    if (mode == MODE_BGR)
 
535
    {
 
536
        mp_msg(MSGT_VO, MSGL_ERR,
 
537
               "BGR not supported, please contact the developers\n");
 
538
        return -1;
 
539
    }
 
540
#endif
 
541
 
 
542
    if (vo_ontop)
 
543
        vo_x11_setlayer(mDisplay, vo_window, vo_ontop);
 
544
 
 
545
    return 0;
 
546
}
 
547
 
 
548
static void Display_Image(XImage * myximage, uint8_t * ImageData)
 
549
{
 
550
#ifdef HAVE_SHM
 
551
    if (Shmem_Flag)
 
552
    {
 
553
        XShmPutImage(mDisplay, vo_window, vo_gc, myximage,
 
554
                     0, 0,
 
555
                     (vo_dwidth - swsContext->dstW) / 2,
 
556
                     (vo_dheight - myximage->height) / 2, swsContext->dstW,
 
557
                     myximage->height, True);
 
558
    } else
 
559
#endif
 
560
    {
 
561
        XPutImage(mDisplay, vo_window, vo_gc, myximage,
 
562
                  0, 0,
 
563
                  (vo_dwidth - swsContext->dstW) / 2,
 
564
                  (vo_dheight - myximage->height) / 2, swsContext->dstW,
 
565
                  myximage->height);
 
566
    }
 
567
}
 
568
 
 
569
static void draw_osd(void)
 
570
{
 
571
    vo_draw_text(image_width, image_height, draw_alpha_fnc);
 
572
}
 
573
 
 
574
static void flip_page(void)
 
575
{
 
576
    Display_Image(myximage, ImageData);
 
577
    XSync(mDisplay, False);
 
578
}
 
579
 
 
580
static int draw_slice(uint8_t * src[], int stride[], int w, int h,
 
581
                           int x, int y)
 
582
{
 
583
    uint8_t *dst[3];
 
584
    int dstStride[3];
 
585
 
 
586
    if ((old_vo_dwidth != vo_dwidth
 
587
         || old_vo_dheight != vo_dheight) /*&& y==0 */  && zoomFlag)
 
588
    {
 
589
        int newW = vo_dwidth;
 
590
        int newH = vo_dheight;
 
591
        int newAspect = (newW * (1 << 16) + (newH >> 1)) / newH;
 
592
        SwsContext *oldContext = swsContext;
 
593
 
 
594
        if (newAspect > aspect)
 
595
            newW = (newH * aspect + (1 << 15)) >> 16;
 
596
        else
 
597
            newH = ((newW << 16) + (aspect >> 1)) / aspect;
 
598
 
 
599
        old_vo_dwidth = vo_dwidth;
 
600
        old_vo_dheight = vo_dheight;
 
601
 
 
602
        if (sws_flags == 0)
 
603
            newW &= (~31);      // not needed but, if the user wants the FAST_BILINEAR SCALER, then its needed
 
604
 
 
605
        swsContext = sws_getContextFromCmdLine(srcW, srcH, in_format,
 
606
                                               newW, newH, out_format);
 
607
        if (swsContext)
 
608
        {
 
609
            image_width = (newW + 7) & (~7);
 
610
            image_height = newH;
 
611
 
 
612
            freeMyXImage();
 
613
            getMyXImage();
 
614
            sws_freeContext(oldContext);
 
615
        } else
 
616
        {
 
617
            swsContext = oldContext;
 
618
        }
 
619
    }
 
620
    dstStride[1] = dstStride[2] = 0;
 
621
    dst[1] = dst[2] = NULL;
 
622
 
 
623
    if (Flip_Flag)
 
624
    {
 
625
        dstStride[0] = -image_width * ((bpp + 7) / 8);
 
626
        dst[0] = ImageData - dstStride[0] * (image_height - 1);
 
627
        sws_scale_ordered(swsContext, src, stride, y, h, dst, dstStride);
 
628
    } else
 
629
    {
 
630
        dstStride[0] = image_width * ((bpp + 7) / 8);
 
631
        dst[0] = ImageData;
 
632
        sws_scale_ordered(swsContext, src, stride, y, h, dst, dstStride);
 
633
    }
 
634
    return 0;
 
635
}
 
636
 
 
637
static int draw_frame(uint8_t * src[])
 
638
{
 
639
#if 0
 
640
    int stride[3] = { 0, 0, 0 };
 
641
 
 
642
    if (in_format == IMGFMT_YUY2)
 
643
        stride[0] = srcW * 2;
 
644
    else if (in_format == IMGFMT_BGR8)
 
645
        stride[0] = srcW;
 
646
    else if (in_format == IMGFMT_BGR15)
 
647
        stride[0] = srcW * 2;
 
648
    else if (in_format == IMGFMT_BGR16)
 
649
        stride[0] = srcW * 2;
 
650
    else if (in_format == IMGFMT_BGR24)
 
651
        stride[0] = srcW * 3;
 
652
    else if (in_format == IMGFMT_BGR32)
 
653
        stride[0] = srcW * 4;
 
654
 
 
655
    return draw_slice(src, stride, srcW, srcH, 0, 0);
 
656
#else
 
657
    printf("draw_frame() called!!!!!!\n");
 
658
    return -1;
 
659
#endif
 
660
}
 
661
 
 
662
static uint32_t get_image(mp_image_t * mpi)
 
663
{
 
664
    if (zoomFlag ||
 
665
        !IMGFMT_IS_BGR(mpi->imgfmt) ||
 
666
        (IMGFMT_BGR_DEPTH(mpi->imgfmt) != vo_depthonscreen) ||
 
667
        ((mpi->type != MP_IMGTYPE_STATIC)
 
668
         && (mpi->type != MP_IMGTYPE_TEMP))
 
669
        || (mpi->flags & MP_IMGFLAG_PLANAR)
 
670
        || (mpi->flags & MP_IMGFLAG_YUV) || (mpi->width != image_width)
 
671
        || (mpi->height != image_height))
 
672
        return (VO_FALSE);
 
673
 
 
674
    if (Flip_Flag)
 
675
    {
 
676
        mpi->stride[0] = -image_width * ((bpp + 7) / 8);
 
677
        mpi->planes[0] = ImageData - mpi->stride[0] * (image_height - 1);
 
678
    } else
 
679
    {
 
680
        mpi->stride[0] = image_width * ((bpp + 7) / 8);
 
681
        mpi->planes[0] = ImageData;
 
682
    }
 
683
    mpi->flags |= MP_IMGFLAG_DIRECT;
 
684
 
 
685
    return (VO_TRUE);
 
686
}
 
687
 
 
688
static int query_format(uint32_t format)
 
689
{
 
690
    mp_msg(MSGT_VO, MSGL_DBG2,
 
691
           "vo_x11: query_format was called: %x (%s)\n", format,
 
692
           vo_format_name(format));
 
693
    if (IMGFMT_IS_BGR(format))
 
694
    {
 
695
        if (IMGFMT_BGR_DEPTH(format) <= 8)
 
696
            return 0;           // TODO 8bpp not yet fully implemented
 
697
        if (IMGFMT_BGR_DEPTH(format) == vo_depthonscreen)
 
698
            return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_SWSCALE | VFCAP_FLIP |
 
699
                VFCAP_ACCEPT_STRIDE;
 
700
        else
 
701
            return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_SWSCALE | VFCAP_FLIP |
 
702
                VFCAP_ACCEPT_STRIDE;
 
703
    }
 
704
 
 
705
    switch (format)
 
706
    {
 
707
//   case IMGFMT_BGR8:  
 
708
//   case IMGFMT_BGR15:
 
709
//   case IMGFMT_BGR16:
 
710
//   case IMGFMT_BGR24:
 
711
//   case IMGFMT_BGR32:
 
712
//    return 0x2;
 
713
//   case IMGFMT_YUY2: 
 
714
        case IMGFMT_I420:
 
715
        case IMGFMT_IYUV:
 
716
        case IMGFMT_YV12:
 
717
            return VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_SWSCALE | VFCAP_ACCEPT_STRIDE;
 
718
    }
 
719
    return 0;
 
720
}
 
721
 
 
722
 
 
723
static void uninit(void)
 
724
{
 
725
    if (!myximage)
 
726
        return;
 
727
 
 
728
    freeMyXImage();
 
729
 
 
730
#ifdef HAVE_XF86VM
 
731
    vo_vm_close(mDisplay);
 
732
#endif
 
733
 
 
734
    zoomFlag = 0;
 
735
    vo_x11_uninit();
 
736
 
 
737
    sws_freeContext(swsContext);
 
738
}
 
739
 
 
740
static int preinit(const char *arg)
 
741
{
 
742
    if (arg)
 
743
    {
 
744
        mp_msg(MSGT_VO, MSGL_ERR, "vo_x11: Unknown subdevice: %s\n", arg);
 
745
        return ENOSYS;
 
746
    }
 
747
 
 
748
    if (!vo_init())
 
749
        return -1;              // Can't open X11
 
750
    return 0;
 
751
}
 
752
 
 
753
static int control(uint32_t request, void *data, ...)
 
754
{
 
755
    switch (request)
 
756
    {
 
757
        case VOCTRL_PAUSE:
 
758
            return (int_pause = 1);
 
759
        case VOCTRL_RESUME:
 
760
            return (int_pause = 0);
 
761
        case VOCTRL_QUERY_FORMAT:
 
762
            return query_format(*((uint32_t *) data));
 
763
        case VOCTRL_GUISUPPORT:
 
764
            return VO_TRUE;
 
765
        case VOCTRL_GET_IMAGE:
 
766
            return get_image(data);
 
767
        case VOCTRL_SET_EQUALIZER:
 
768
            {
 
769
                va_list ap;
 
770
                int value;
 
771
 
 
772
                va_start(ap, data);
 
773
                value = va_arg(ap, int);
 
774
 
 
775
                va_end(ap);
 
776
                return vo_x11_set_equalizer(data, value);
 
777
            }
 
778
        case VOCTRL_GET_EQUALIZER:
 
779
            {
 
780
                va_list ap;
 
781
                int *value;
 
782
 
 
783
                va_start(ap, data);
 
784
                value = va_arg(ap, int *);
 
785
 
 
786
                va_end(ap);
 
787
                return vo_x11_get_equalizer(data, value);
 
788
            }
 
789
        case VOCTRL_ONTOP:
 
790
            vo_x11_ontop();
 
791
            return VO_TRUE;
 
792
        case VOCTRL_FULLSCREEN:
 
793
            {
 
794
                vo_x11_fullscreen();
 
795
                vo_x11_clearwindow(mDisplay, vo_window);
 
796
            }
 
797
            return VO_TRUE;
 
798
    }
 
799
    return VO_NOTIMPL;
 
800
}