~medibuntu-maintainers/mplayer/medibuntu.precise

« back to all changes in this revision

Viewing changes to libvo/vo_directx.c

  • Committer: Gauvain Pocentek
  • Date: 2012-03-06 11:59:12 UTC
  • mfrom: (66.1.15 precise)
  • Revision ID: gauvain@pocentek.net-20120306115912-h9d6kt9j0l532oo5
* Merge from Ubuntu:
  - put back faac support
  - recommends apport-hooks-medibuntu
  - change Maintainer, Uploaders & Vcs-* fields.
* New upstream snapshot
* upload to unstable
* Build against external libmpeg2
* drop 51_FTBFS_arm.patch again
* no longer build depend on libcdparanoia-dev on the Hurd
* Fix FTBFS on the hurd.
  Thanks to Samuel Thibault <sthibault@debian.org> (Closes: #654974)
* Fix FTBFS on arm
* New upstream snapshot, Closes: #650339, #643621, #481807
* Imported Upstream version 1.0~rc4+svn34492
* Bump standards version
* Bump dependency on libav >= 4:0.8~, Closes: #653887
* Fix build-indep
* Build mplayer-gui again, Closes: #568514
* Drop debian/all-lang-config-mak.sh, no longer needed
* include .dfsg1 in version number
* remove get-orig-source target
* no longer prune compiler flags from the environment
* No longer advertise nor build 3fdx, mga and dxr3 backends,
  Closes: #496106, #442181, #533546
* beautify mplayer version identification string
* Brown paperbag upload.
* Next try to fix build failure on sparce after recent binutils change.
* Brown paperbag upload.
* Really fix build failure on sparc after recent binutils change.
* Properly set Replaces/Conflicts on mplayer2{,-dbg} to avoid
  file overwrite errors.
* Adjust versioning of mplayer listed in the mplayer-dbg's Depends field.
* Fix build failure on sparc after recent binutils change.
* Urgency medium bumped because of RC-level bugfix
  and speeding up x264 transition.
* Update to my @debian.org email.
* Upload to unstable
* Enable joystick support on Linux only, Closes: #638408
* Rebuild fixes toolchain issue on arm, Closes: #637077
* New upstream snapshot
* following the discussion started by Diego Biurrun <diego@biurrun.de>
  in debian-devel, I have prepared a new packaging of 'mplayer'
  (with code that comes from CVS)
* the upstream tar.bz cannot be distributed by Debian, since it contains
   CSS code; so I am repackaging it 
* I have tried my best to address all known issues:
  - the package contains the detailed Copyright made by Diego Biurrun 
  - the package does not contain CSS code, or  AFAIK other code on which 
     there is active patent enforcement
  - there is a script  debian/cvs-changelog.sh  that shows all changes
     done to files included in this source.
    This should comply with GPLv2 sec 2.a  (in spirit if not in letter)
    For this reason, the source code contains CVS directories.
* needs   make (>= 3.80) for 'html-chunked-$(1)' in DOCS/xml/Makefile

* some corrections, as suggested Diego Biurrun
  - binary codecs should go into /usr/lib/codecs (upstream default)
  - better template 'mplayer/install_codecs'
  - an empty 'font=' in mplayer.conf breaks mplayer: postinst corrected
* correction in 'mplayer/cfgnote'
* better mplayer.postinst and mplayer.config

* New upstream release
* better debian/copyright file
* do not ship a skin
* New upstream release
* changed DEB_BUILD_OPTIONS to DEB_BUILD_CONFIGURE ,
  DEB_BUILD_OPTIONS is used as in debian policy
* use gcc-3.4
* changed xlibs-dev to a long list of dependencies, for Debian/etch
* try to adhere to  http://www.mplayerhq.hu/DOCS/tech/binary-packaging.txt
  (see README.Debian for details)
* removed dependency on xlibmesa-dev, disabled opengl
* New upstream release
* Simon McVittie <hacks@pseudorandom.co.uk> wonderful work:
- Work around Debian bug #267442 (glibc's sys/uio.h and gcc's altivec.h have
  conflicting uses for __vector) by re-ordering #includes
- Fix potential symlink attack in ./configure
- Disable support for binary codecs on platforms for which those codecs
  aren't available; also disable the corresponding Debconf note when it's
  inappropriate
- Changed Build-Depends: so it works in pbuilder
- Explicitly build-depend on libjpeg62-dev, libfontconfig1-dev,
  libungif4-dev 
- Tweak debian/rules to avoid certain errors being ignored
- Use --language=all
* provide a target  'debian/rules get-orig-source' 
  that recreates the orig.tar.gz ; then use the above orig.tar.gz
* rewrote some parts of debian/rules
* don't clean and recompile docs if upstream ships them
* mplayer-doc was shipping too much stuff
* translated man pages where not installed properly
* compile with libdv4-dev
* correct README.Debian
* Forgot build-dep on libtheora
* Must not depend on libxvidcore
* New upstream release
* new release.
* rc1 to become 0.90
* new pre-release
* new pre-release
* gtk bug fixed.
* new release.
* version bumped
* 0.60 pre2 release
* 0.60 pre-release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include "sub/sub.h"
38
38
#include "w32_common.h"
39
39
 
40
 
static LPDIRECTDRAWCOLORCONTROL g_cc = NULL;            //color control interface
41
 
static LPDIRECTDRAW7        g_lpdd = NULL;          //DirectDraw Object
42
 
static LPDIRECTDRAWSURFACE7  g_lpddsPrimary = NULL;  //Primary Surface: viewport through the Desktop
43
 
static LPDIRECTDRAWSURFACE7  g_lpddsOverlay = NULL;  //Overlay Surface
44
 
static LPDIRECTDRAWSURFACE7  g_lpddsBack = NULL;     //Back surface
45
 
static LPDIRECTDRAWCLIPPER  g_lpddclipper;          //clipper object, can only be used without overlay
46
 
static DDSURFACEDESC2           ddsdsf;                 //surface descripiton needed for locking
47
 
static HINSTANCE            hddraw_dll;             //handle to ddraw.dll
48
 
static RECT                 rd;                     //rect of our stretched image
49
 
static RECT                 rs;                     //rect of our source image
50
 
static HBRUSH               colorbrush = NULL;      // Handle to colorkey brush
51
 
static HBRUSH               blackbrush = NULL;      // Handle to black brush
 
40
static LPDIRECTDRAWCOLORCONTROL g_cc = NULL;            //color control interface
 
41
static LPDIRECTDRAW7 g_lpdd = NULL;                 //DirectDraw Object
 
42
static LPDIRECTDRAWSURFACE7 g_lpddsPrimary = NULL;   //Primary Surface: viewport through the Desktop
 
43
static LPDIRECTDRAWSURFACE7 g_lpddsOverlay = NULL;   //Overlay Surface
 
44
static LPDIRECTDRAWSURFACE7 g_lpddsBack    = NULL;   //Back surface
 
45
static LPDIRECTDRAWCLIPPER g_lpddclipper;           //clipper object, can only be used without overlay
 
46
static DDSURFACEDESC2 ddsdsf;                           //surface descripiton needed for locking
 
47
static HINSTANCE hddraw_dll;                        //handle to ddraw.dll
 
48
static RECT rd;                                     //rect of our stretched image
 
49
static RECT rs;                                     //rect of our source image
 
50
static HBRUSH colorbrush = NULL;                    // Handle to colorkey brush
 
51
static HBRUSH blackbrush = NULL;                    // Handle to black brush
52
52
static uint32_t image_width, image_height;          //image width and height
53
 
static uint8_t  *image=NULL;                        //image data
54
 
static void* tmp_image = NULL;
55
 
static uint32_t image_format=0;                       //image format
 
53
static uint8_t *image        = NULL;                //image data
 
54
static void *tmp_image       = NULL;
 
55
static uint32_t image_format = 0;                       //image format
56
56
static uint32_t primary_image_format;
57
 
static uint32_t vm_height=0;
58
 
static uint32_t vm_width=0;
59
 
static uint32_t vm_bpp=0;
 
57
static uint32_t vm_height = 0;
 
58
static uint32_t vm_width  = 0;
 
59
static uint32_t vm_bpp    = 0;
60
60
static uint32_t dstride;                            //surface stride
61
61
static uint32_t nooverlay = 0;                      //NonOverlay mode
62
 
static DWORD    destcolorkey;                       //colorkey for our surface
63
 
static COLORREF windowcolor = RGB(0,0,16);          //windowcolor == colorkey
64
 
static int adapter_count=0;
 
62
static DWORD destcolorkey;                          //colorkey for our surface
 
63
static COLORREF windowcolor = RGB(0, 0, 16);          //windowcolor == colorkey
 
64
static int adapter_count    = 0;
65
65
static GUID selected_guid;
66
66
static GUID *selected_guid_ptr = NULL;
67
67
 
71
71
 * the linking stage.
72
72
 *****************************************************************************/
73
73
#define IID_IDirectDraw7 MP_IID_IDirectDraw7
74
 
static const GUID MP_IID_IDirectDraw7 =
75
 
{
76
 
        0x15e65ec0,0x3b9c,0x11d2,{0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b}
 
74
static const GUID MP_IID_IDirectDraw7 = {
 
75
    0x15e65ec0, 0x3b9c, 0x11d2, { 0xb9, 0x2f, 0x00, 0x60, 0x97, 0x97, 0xea, 0x5b }
77
76
};
78
77
 
79
78
#define IID_IDirectDrawColorControl MP_IID_IDirectDrawColorControl
80
 
static const GUID MP_IID_IDirectDrawColorControl =
81
 
{
82
 
        0x4b9f0ee0,0x0d7e,0x11d0,{0x9b,0x06,0x00,0xa0,0xc9,0x03,0xa3,0xb8}
 
79
static const GUID MP_IID_IDirectDrawColorControl = {
 
80
    0x4b9f0ee0, 0x0d7e, 0x11d0, { 0x9b, 0x06, 0x00, 0xa0, 0xc9, 0x03, 0xa3, 0xb8 }
83
81
};
84
82
 
85
 
 
86
 
typedef struct directx_fourcc_caps
87
 
{
88
 
   char*  img_format_name;      //human readable name
89
 
   uint32_t img_format;         //as MPlayer image format
90
 
   uint32_t drv_caps;           //what hw supports with this format
91
 
   DDPIXELFORMAT g_ddpfOverlay; //as Directx Sourface description
92
 
} directx_fourcc_caps;
93
 
 
94
 
 
95
 
static directx_fourcc_caps g_ddpf[] =
96
 
{
97
 
        {"YV12 ",IMGFMT_YV12 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','V','1','2'),0,0,0,0,0}},
98
 
        {"I420 ",IMGFMT_I420 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('I','4','2','0'),0,0,0,0,0}},   //yv12 with swapped uv
99
 
        {"IYUV ",IMGFMT_IYUV ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('I','Y','U','V'),0,0,0,0,0}},   //same as i420
100
 
        {"YVU9 ",IMGFMT_YVU9 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','V','U','9'),0,0,0,0,0}},
101
 
        {"YUY2 ",IMGFMT_YUY2 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','U','Y','2'),0,0,0,0,0}},
102
 
        {"UYVY ",IMGFMT_UYVY ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0}},
103
 
        {"BGR8 ",IMGFMT_BGR8 ,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 8,  0x00000000, 0x00000000, 0x00000000, 0}},
104
 
        {"RGB15",IMGFMT_RGB15,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000001F, 0x000003E0, 0x00007C00, 0}},   //RGB 5:5:5
105
 
        {"BGR15",IMGFMT_BGR15,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x00007C00, 0x000003E0, 0x0000001F, 0}},
106
 
        {"RGB16",IMGFMT_RGB16,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000001F, 0x000007E0, 0x0000F800, 0}},   //RGB 5:6:5
107
 
    {"BGR16",IMGFMT_BGR16,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000F800, 0x000007E0, 0x0000001F, 0}},
108
 
        {"RGB24",IMGFMT_RGB24,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24,  0x000000FF, 0x0000FF00, 0x00FF0000, 0}},
109
 
    {"BGR24",IMGFMT_BGR24,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24,  0x00FF0000, 0x0000FF00, 0x000000FF, 0}},
110
 
    {"RGB32",IMGFMT_RGB32,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32,  0x000000FF, 0x0000FF00, 0x00FF0000, 0}},
111
 
    {"BGR32",IMGFMT_BGR32,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32,  0x00FF0000, 0x0000FF00, 0x000000FF, 0}}
 
83
struct directx_fourcc_caps {
 
84
    char img_format_name[6];    //human readable name
 
85
    uint32_t img_format;        //as MPlayer image format
 
86
    DDPIXELFORMAT g_ddpfOverlay; //as Directx Sourface description
 
87
} static const g_ddpf[] = {
 
88
    { "YV12 ", IMGFMT_YV12,  { sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y', 'V', '1', '2'), 0, 0, 0, 0, 0 } },
 
89
    { "I420 ", IMGFMT_I420,  { sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('I', '4', '2', '0'), 0, 0, 0, 0, 0 } }, //yv12 with swapped uv
 
90
    { "IYUV ", IMGFMT_IYUV,  { sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('I', 'Y', 'U', 'V'), 0, 0, 0, 0, 0 } }, //same as i420
 
91
    { "YVU9 ", IMGFMT_YVU9,  { sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y', 'V', 'U', '9'), 0, 0, 0, 0, 0 } },
 
92
    { "YUY2 ", IMGFMT_YUY2,  { sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y', 'U', 'Y', '2'), 0, 0, 0, 0, 0 } },
 
93
    { "UYVY ", IMGFMT_UYVY,  { sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('U', 'Y', 'V', 'Y'), 0, 0, 0, 0, 0 } },
 
94
    { "BGR8 ", IMGFMT_BGR8,  { sizeof(DDPIXELFORMAT), DDPF_RGB,    0,  8,  0x00000000, 0x00000000, 0x00000000, 0 } },
 
95
    { "RGB15", IMGFMT_RGB15, { sizeof(DDPIXELFORMAT), DDPF_RGB,    0,  16, 0x0000001F, 0x000003E0, 0x00007C00, 0 } }, //RGB 5:5:5
 
96
    { "BGR15", IMGFMT_BGR15, { sizeof(DDPIXELFORMAT), DDPF_RGB,    0,  16, 0x00007C00, 0x000003E0, 0x0000001F, 0 } },
 
97
    { "RGB16", IMGFMT_RGB16, { sizeof(DDPIXELFORMAT), DDPF_RGB,    0,  16, 0x0000001F, 0x000007E0, 0x0000F800, 0 } }, //RGB 5:6:5
 
98
    { "BGR16", IMGFMT_BGR16, { sizeof(DDPIXELFORMAT), DDPF_RGB,    0,  16, 0x0000F800, 0x000007E0, 0x0000001F, 0 } },
 
99
    { "RGB24", IMGFMT_RGB24, { sizeof(DDPIXELFORMAT), DDPF_RGB,    0,  24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0 } },
 
100
    { "BGR24", IMGFMT_BGR24, { sizeof(DDPIXELFORMAT), DDPF_RGB,    0,  24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0 } },
 
101
    { "RGB32", IMGFMT_RGB32, { sizeof(DDPIXELFORMAT), DDPF_RGB,    0,  32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0 } },
 
102
    { "BGR32", IMGFMT_BGR32, { sizeof(DDPIXELFORMAT), DDPF_RGB,    0,  32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0 } }
112
103
};
113
104
#define NUM_FORMATS (sizeof(g_ddpf) / sizeof(g_ddpf[0]))
114
105
 
115
 
static const vo_info_t info =
116
 
{
117
 
        "Directx DDraw YUV/RGB/BGR renderer",
118
 
        "directx",
119
 
        "Sascha Sommer <saschasommer@freenet.de>",
120
 
        ""
 
106
// what hw supports with corresponding format in g_ddpf
 
107
static uint32_t drv_caps[NUM_FORMATS];
 
108
 
 
109
static const vo_info_t info = {
 
110
    "Directx DDraw YUV/RGB/BGR renderer",
 
111
    "directx",
 
112
    "Sascha Sommer <saschasommer@freenet.de>",
 
113
    ""
121
114
};
122
115
 
123
116
const LIBVO_EXTERN(directx)
124
117
 
125
118
static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
126
 
                unsigned char *srca, int stride)
 
119
                       unsigned char *srca, int stride)
127
120
{
128
 
    switch(image_format) {
129
 
    case IMGFMT_YV12 :
130
 
    case IMGFMT_I420 :
131
 
        case IMGFMT_IYUV :
132
 
        case IMGFMT_YVU9 :
133
 
        vo_draw_alpha_yv12(w,h,src,srca,stride,((uint8_t *) image) + dstride*y0 + x0,dstride);
134
 
        break;
135
 
        case IMGFMT_YUY2 :
136
 
            vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) image)+ dstride*y0 + 2*x0 ,dstride);
137
 
    break;
138
 
    case IMGFMT_UYVY :
139
 
        vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) image) + dstride*y0 + 2*x0 + 1,dstride);
140
 
    break;
141
 
        case IMGFMT_RGB15:
 
121
    switch (image_format) {
 
122
    case IMGFMT_YV12:
 
123
    case IMGFMT_I420:
 
124
    case IMGFMT_IYUV:
 
125
    case IMGFMT_YVU9:
 
126
        vo_draw_alpha_yv12(w, h, src, srca, stride, ((uint8_t *)image) + dstride * y0 + x0, dstride);
 
127
        break;
 
128
    case IMGFMT_YUY2:
 
129
        vo_draw_alpha_yuy2(w, h, src, srca, stride, ((uint8_t *)image) + dstride * y0 + 2 * x0, dstride);
 
130
        break;
 
131
    case IMGFMT_UYVY:
 
132
        vo_draw_alpha_yuy2(w, h, src, srca, stride, ((uint8_t *)image) + dstride * y0 + 2 * x0 + 1, dstride);
 
133
        break;
 
134
    case IMGFMT_RGB15:
142
135
    case IMGFMT_BGR15:
143
 
                vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+2*x0,dstride);
144
 
    break;
 
136
        vo_draw_alpha_rgb15(w, h, src, srca, stride, ((uint8_t *)image) + dstride * y0 + 2 * x0, dstride);
 
137
        break;
145
138
    case IMGFMT_RGB16:
146
 
        case IMGFMT_BGR16:
147
 
        vo_draw_alpha_rgb16(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+2*x0,dstride);
148
 
    break;
 
139
    case IMGFMT_BGR16:
 
140
        vo_draw_alpha_rgb16(w, h, src, srca, stride, ((uint8_t *)image) + dstride * y0 + 2 * x0, dstride);
 
141
        break;
149
142
    case IMGFMT_RGB24:
150
 
        case IMGFMT_BGR24:
151
 
        vo_draw_alpha_rgb24(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+4*x0,dstride);
152
 
    break;
 
143
    case IMGFMT_BGR24:
 
144
        vo_draw_alpha_rgb24(w, h, src, srca, stride, ((uint8_t *)image) + dstride * y0 + 4 * x0, dstride);
 
145
        break;
153
146
    case IMGFMT_RGB32:
154
 
        case IMGFMT_BGR32:
155
 
        vo_draw_alpha_rgb32(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+4*x0,dstride);
156
 
    break;
 
147
    case IMGFMT_BGR32:
 
148
        vo_draw_alpha_rgb32(w, h, src, srca, stride, ((uint8_t *)image) + dstride * y0 + 4 * x0, dstride);
 
149
        break;
157
150
    }
158
151
}
159
152
 
160
153
static void draw_osd(void)
161
154
{
162
 
    vo_draw_text(image_width,image_height,draw_alpha);
 
155
    vo_draw_text(image_width, image_height, draw_alpha);
163
156
}
164
157
 
165
 
static int
166
 
query_format(uint32_t format)
 
158
static int query_format(uint32_t format)
167
159
{
168
 
    uint32_t i=0;
169
 
    while ( i < NUM_FORMATS )
170
 
    {
171
 
                if (g_ddpf[i].img_format == format)
172
 
                    return g_ddpf[i].drv_caps;
173
 
            i++;
174
 
    }
 
160
    int i;
 
161
    for (i = 0; i < NUM_FORMATS; i++)
 
162
        if (g_ddpf[i].img_format == format)
 
163
            return drv_caps[i];
175
164
    return 0;
176
165
}
177
166
 
 
167
struct errmap {
 
168
    HRESULT err;
 
169
    const char *errstr;
 
170
} static const dd_errmap[] = {
 
171
    {DDERR_INCOMPATIBLEPRIMARY, "incompatible primary surface"},
 
172
    {DDERR_INVALIDCAPS, "invalid caps"},
 
173
    {DDERR_INVALIDOBJECT, "invalid object"},
 
174
    {DDERR_INVALIDPARAMS, "invalid parameters"},
 
175
    {DDERR_INVALIDRECT, "invalid rectangle"},
 
176
    {DDERR_INVALIDSURFACETYPE, "invalid surfacetype"},
 
177
    {DDERR_NODIRECTDRAWHW, "no directdraw hardware"},
 
178
    {DDERR_NOEMULATION, "can't emulate"},
 
179
    {DDERR_NOFLIPHW, "hardware can't do flip"},
 
180
    {DDERR_NOOVERLAYHW, "hardware can't do overlay"},
 
181
    {DDERR_NOSTRETCHHW, "hardware can't stretch: try to size the window back"},
 
182
    {DDERR_OUTOFMEMORY, "not enough system memory"},
 
183
    {DDERR_OUTOFVIDEOMEMORY, "not enough video memory"},
 
184
    {DDERR_UNSUPPORTED, "unsupported"},
 
185
    {DDERR_UNSUPPORTEDMODE, "unsupported mode"},
 
186
    {DDERR_HEIGHTALIGN, "height align"},
 
187
    {DDERR_XALIGN, "x align"},
 
188
    {DDERR_SURFACELOST, "surfaces lost"},
 
189
    {0, NULL}
 
190
};
 
191
 
 
192
static const char *dd_errstr(HRESULT res)
 
193
{
 
194
    int i;
 
195
    for (i = 0; dd_errmap[i].errstr; i++)
 
196
        if (dd_errmap[i].err == res)
 
197
            return dd_errmap[i].errstr;
 
198
    return "unknown error";
 
199
}
 
200
 
178
201
static uint32_t Directx_CreatePrimarySurface(void)
179
202
{
180
 
    DDSURFACEDESC2   ddsd;
 
203
    DDSURFACEDESC2 ddsd = { .dwSize = sizeof(ddsd) };
181
204
    //cleanup
182
 
        if(g_lpddsPrimary)g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
183
 
        g_lpddsPrimary=NULL;
 
205
    if (g_lpddsPrimary)
 
206
        g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
 
207
    g_lpddsPrimary = NULL;
184
208
 
185
 
    if(vidmode)g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,vm_width,vm_height,vm_bpp,vo_refresh_rate,0);
186
 
    ZeroMemory(&ddsd, sizeof(ddsd));
187
 
    ddsd.dwSize = sizeof(ddsd);
 
209
    if (vidmode)
 
210
        g_lpdd->lpVtbl->SetDisplayMode(g_lpdd, vm_width, vm_height, vm_bpp, vo_refresh_rate, 0);
188
211
    //set flags and create a primary surface.
189
212
    ddsd.dwFlags = DDSD_CAPS;
190
213
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
191
 
    if(g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsd, &g_lpddsPrimary, NULL )== DD_OK)
192
 
                mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>primary surface created\n");
193
 
        else
194
 
        {
195
 
                mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>could not create primary surface\n");
196
 
                return 1;
197
 
        }
198
 
        return 0;
 
214
    if (g_lpdd->lpVtbl->CreateSurface(g_lpdd, &ddsd, &g_lpddsPrimary, NULL) == DD_OK)
 
215
        mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>primary surface created\n");
 
216
    else {
 
217
        mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>could not create primary surface\n");
 
218
        return 1;
 
219
    }
 
220
    return 0;
199
221
}
200
222
 
201
223
static uint32_t Directx_CreateOverlay(uint32_t imgfmt)
202
224
{
203
225
    HRESULT ddrval;
204
 
    DDSURFACEDESC2   ddsdOverlay;
205
 
    uint32_t        i=0;
206
 
        while ( i < NUM_FORMATS && imgfmt != g_ddpf[i].img_format)
207
 
        {
208
 
                i++;
209
 
        }
210
 
        if (!g_lpdd || !g_lpddsPrimary || i == NUM_FORMATS)
 
226
    DDSURFACEDESC2 ddsdOverlay = {
 
227
        .dwSize = sizeof(ddsdOverlay),
 
228
        .ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY,
 
229
        .dwFlags  = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT,
 
230
        .dwWidth  = image_width,
 
231
        .dwHeight = image_height,
 
232
    };
 
233
    uint32_t i = 0;
 
234
    ddsdOverlay.dwBackBufferCount = 2;
 
235
    while (i < NUM_FORMATS && imgfmt != g_ddpf[i].img_format)
 
236
        i++;
 
237
    if (!g_lpdd || !g_lpddsPrimary || i == NUM_FORMATS)
211
238
        return 1;
212
239
    //cleanup
213
 
        if (g_lpddsOverlay)g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);
214
 
        if (g_lpddsBack)g_lpddsBack->lpVtbl->Release(g_lpddsBack);
215
 
        g_lpddsOverlay= NULL;
216
 
        g_lpddsBack = NULL;
217
 
        //create our overlay
218
 
    ZeroMemory(&ddsdOverlay, sizeof(ddsdOverlay));
219
 
    ddsdOverlay.dwSize = sizeof(ddsdOverlay);
220
 
    ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY;
221
 
    ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT| DDSD_PIXELFORMAT;
222
 
    ddsdOverlay.dwWidth=image_width;
223
 
    ddsdOverlay.dwHeight=image_height;
224
 
    ddsdOverlay.dwBackBufferCount=2;
225
 
        ddsdOverlay.ddpfPixelFormat=g_ddpf[i].g_ddpfOverlay;
226
 
        if(vo_doublebuffering)   //tribblebuffering
227
 
        {
228
 
                if (g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsdOverlay, &g_lpddsOverlay, NULL)== DD_OK)
229
 
                {
230
 
                        mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>overlay with format %s created\n",g_ddpf[i].img_format_name);
 
240
    if (g_lpddsOverlay)
 
241
        g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);
 
242
    if (g_lpddsBack)
 
243
        g_lpddsBack->lpVtbl->Release(g_lpddsBack);
 
244
    g_lpddsOverlay = NULL;
 
245
    g_lpddsBack    = NULL;
 
246
    //create our overlay
 
247
    ddsdOverlay.ddpfPixelFormat   = g_ddpf[i].g_ddpfOverlay;
 
248
    if (vo_doublebuffering) {    //tribblebuffering
 
249
        if (g_lpdd->lpVtbl->CreateSurface(g_lpdd, &ddsdOverlay, &g_lpddsOverlay, NULL) == DD_OK) {
 
250
            mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>overlay with format %s created\n", g_ddpf[i].img_format_name);
231
251
            //get the surface directly attached to the primary (the back buffer)
232
252
            ddsdOverlay.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
233
 
            if(g_lpddsOverlay->lpVtbl->GetAttachedSurface(g_lpddsOverlay,&ddsdOverlay.ddsCaps, &g_lpddsBack) != DD_OK)
234
 
                        {
235
 
                                mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't get attached surface\n");
236
 
                                return 1;
237
 
                        }
238
 
                        return 0;
239
 
                }
240
 
                vo_doublebuffering=0; //disable tribblebuffering
241
 
                mp_msg(MSGT_VO, MSGL_V,"<vo_directx><WARN>cannot create tribblebuffer overlay with format %s\n",g_ddpf[i].img_format_name);
242
 
        }
243
 
        //single buffer
244
 
        mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>using singlebuffer overlay\n");
245
 
    ddsdOverlay.dwBackBufferCount=0;
246
 
    ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
247
 
    ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
248
 
    ddsdOverlay.ddpfPixelFormat=g_ddpf[i].g_ddpfOverlay;
249
 
        // try to create the overlay surface
250
 
        ddrval = g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsdOverlay, &g_lpddsOverlay, NULL);
251
 
        if(ddrval != DD_OK)
252
 
        {
253
 
           if(ddrval == DDERR_INVALIDPIXELFORMAT)mp_msg(MSGT_VO,MSGL_V,"<vo_directx><ERROR> invalid pixelformat: %s\n",g_ddpf[i].img_format_name);
254
 
       else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>");
255
 
       switch(ddrval)
256
 
           {
257
 
              case DDERR_INCOMPATIBLEPRIMARY:
258
 
                         {mp_msg(MSGT_VO, MSGL_ERR,"incompatible primary surface\n");break;}
259
 
                  case DDERR_INVALIDCAPS:
260
 
                         {mp_msg(MSGT_VO, MSGL_ERR,"invalid caps\n");break;}
261
 
              case DDERR_INVALIDOBJECT:
262
 
                     {mp_msg(MSGT_VO, MSGL_ERR,"invalid object\n");break;}
263
 
              case DDERR_INVALIDPARAMS:
264
 
                     {mp_msg(MSGT_VO, MSGL_ERR,"invalid parameters\n");break;}
265
 
              case DDERR_NODIRECTDRAWHW:
266
 
                     {mp_msg(MSGT_VO, MSGL_ERR,"no directdraw hardware\n");break;}
267
 
              case DDERR_NOEMULATION:
268
 
                     {mp_msg(MSGT_VO, MSGL_ERR,"can't emulate\n");break;}
269
 
              case DDERR_NOFLIPHW:
270
 
                     {mp_msg(MSGT_VO, MSGL_ERR,"hardware can't do flip\n");break;}
271
 
              case DDERR_NOOVERLAYHW:
272
 
                     {mp_msg(MSGT_VO, MSGL_ERR,"hardware can't do overlay\n");break;}
273
 
              case DDERR_OUTOFMEMORY:
274
 
                     {mp_msg(MSGT_VO, MSGL_ERR,"not enough system memory\n");break;}
275
 
              case DDERR_UNSUPPORTEDMODE:
276
 
                         {mp_msg(MSGT_VO, MSGL_ERR,"unsupported mode\n");break;}
277
 
                  case DDERR_OUTOFVIDEOMEMORY:
278
 
                         {mp_msg(MSGT_VO, MSGL_ERR,"not enough video memory\n");break;}
279
 
          default:
280
 
             mp_msg(MSGT_VO, MSGL_ERR,"create surface failed with 0x%x\n",ddrval);
281
 
           }
282
 
           return 1;
283
 
        }
 
253
            if (g_lpddsOverlay->lpVtbl->GetAttachedSurface(g_lpddsOverlay, &ddsdOverlay.ddsCaps, &g_lpddsBack) != DD_OK) {
 
254
                mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>can't get attached surface\n");
 
255
                return 1;
 
256
            }
 
257
            return 0;
 
258
        }
 
259
        vo_doublebuffering = 0;       //disable tribblebuffering
 
260
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><WARN>cannot create tribblebuffer overlay with format %s\n", g_ddpf[i].img_format_name);
 
261
    }
 
262
    //single buffer
 
263
    mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>using singlebuffer overlay\n");
 
264
    ddsdOverlay.dwBackBufferCount = 0;
 
265
    ddsdOverlay.ddsCaps.dwCaps    = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
 
266
    ddsdOverlay.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
 
267
    ddsdOverlay.ddpfPixelFormat = g_ddpf[i].g_ddpfOverlay;
 
268
    // try to create the overlay surface
 
269
    ddrval = g_lpdd->lpVtbl->CreateSurface(g_lpdd, &ddsdOverlay, &g_lpddsOverlay, NULL);
 
270
    if (ddrval != DD_OK) {
 
271
        if (ddrval == DDERR_INVALIDPIXELFORMAT)
 
272
            mp_msg(MSGT_VO, MSGL_V, "<vo_directx><ERROR> invalid pixelformat: %s\n", g_ddpf[i].img_format_name);
 
273
        else
 
274
            mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>create surface failed: %s (0x%x)\n", dd_errstr(ddrval), ddrval);
 
275
        return 1;
 
276
    }
284
277
    g_lpddsBack = g_lpddsOverlay;
285
 
        return 0;
 
278
    return 0;
286
279
}
287
280
 
288
281
static uint32_t Directx_CreateBackpuffer(void)
289
282
{
290
 
    DDSURFACEDESC2   ddsd;
291
 
        //cleanup
292
 
        if (g_lpddsBack)g_lpddsBack->lpVtbl->Release(g_lpddsBack);
293
 
        g_lpddsBack=NULL;
294
 
        ZeroMemory(&ddsd, sizeof(ddsd));
295
 
    ddsd.dwSize = sizeof(ddsd);
296
 
    ddsd.ddsCaps.dwCaps= DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
297
 
    ddsd.dwFlags= DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
298
 
    ddsd.dwWidth=image_width;
299
 
    ddsd.dwHeight=image_height;
300
 
    if(g_lpdd->lpVtbl->CreateSurface( g_lpdd, &ddsd, &g_lpddsBack, 0 ) != DD_OK )
301
 
        {
302
 
                mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't create backpuffer\n");
303
 
                return 1;
304
 
        }
305
 
    mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>backbuffer created\n");
306
 
        return 0;
 
283
    DDSURFACEDESC2 ddsd = {
 
284
        .dwSize = sizeof(ddsd),
 
285
        .ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY,
 
286
        .dwFlags  = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT,
 
287
        .dwWidth  = image_width,
 
288
        .dwHeight = image_height,
 
289
    };
 
290
    //cleanup
 
291
    if (g_lpddsBack)
 
292
        g_lpddsBack->lpVtbl->Release(g_lpddsBack);
 
293
    g_lpddsBack = NULL;
 
294
    if (g_lpdd->lpVtbl->CreateSurface(g_lpdd, &ddsd, &g_lpddsBack, 0) != DD_OK) {
 
295
        mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>can't create backpuffer\n");
 
296
        return 1;
 
297
    }
 
298
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>backbuffer created\n");
 
299
    return 0;
307
300
}
308
301
 
309
302
static void uninit(void)
310
303
{
311
 
        if (g_cc != NULL)
312
 
        {
313
 
                g_cc->lpVtbl->Release(g_cc);
314
 
        }
315
 
        g_cc=NULL;
316
 
        if (g_lpddclipper != NULL) g_lpddclipper->lpVtbl->Release(g_lpddclipper);
317
 
        g_lpddclipper = NULL;
318
 
        mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>clipper released\n");
319
 
        if (g_lpddsBack != NULL) g_lpddsBack->lpVtbl->Release(g_lpddsBack);
320
 
        g_lpddsBack = NULL;
321
 
        mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>back surface released\n");
322
 
        if(vo_doublebuffering && !nooverlay)
323
 
        {
324
 
                if (g_lpddsOverlay != NULL)g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);
 
304
    if (g_cc)
 
305
        g_cc->lpVtbl->Release(g_cc);
 
306
    g_cc = NULL;
 
307
    if (g_lpddclipper)
 
308
        g_lpddclipper->lpVtbl->Release(g_lpddclipper);
 
309
    g_lpddclipper = NULL;
 
310
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>clipper released\n");
 
311
    if (g_lpddsBack)
 
312
        g_lpddsBack->lpVtbl->Release(g_lpddsBack);
 
313
    g_lpddsBack = NULL;
 
314
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>back surface released\n");
 
315
    if (vo_doublebuffering && !nooverlay) {
 
316
        if (g_lpddsOverlay)
 
317
            g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);
325
318
        g_lpddsOverlay = NULL;
326
 
                mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surface released\n");
327
 
        }
328
 
        if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
 
319
        mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>overlay surface released\n");
 
320
    }
 
321
    if (g_lpddsPrimary)
 
322
        g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
329
323
    g_lpddsPrimary = NULL;
330
 
        mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>primary released\n");
331
 
        if (colorbrush) DeleteObject(colorbrush);
332
 
        colorbrush = NULL;
333
 
        mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>GDI resources deleted\n");
334
 
        if (g_lpdd != NULL){
335
 
            if(vidmode)g_lpdd->lpVtbl->RestoreDisplayMode(g_lpdd);
336
 
            g_lpdd->lpVtbl->Release(g_lpdd);
337
 
        }
338
 
        mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>directdrawobject released\n");
339
 
        FreeLibrary( hddraw_dll);
340
 
        hddraw_dll= NULL;
341
 
        mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>ddraw.dll freed\n");
342
 
        mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>uninitialized\n");
343
 
        vo_w32_uninit();
 
324
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>primary released\n");
 
325
    if (colorbrush)
 
326
        DeleteObject(colorbrush);
 
327
    colorbrush = NULL;
 
328
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>GDI resources deleted\n");
 
329
    if (g_lpdd) {
 
330
        if (vidmode)
 
331
            g_lpdd->lpVtbl->RestoreDisplayMode(g_lpdd);
 
332
        g_lpdd->lpVtbl->Release(g_lpdd);
 
333
    }
 
334
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>directdrawobject released\n");
 
335
    FreeLibrary(hddraw_dll);
 
336
    hddraw_dll = NULL;
 
337
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>ddraw.dll freed\n");
 
338
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>uninitialized\n");
 
339
    vo_w32_uninit();
344
340
}
345
341
 
346
 
static BOOL WINAPI EnumCallbackEx(GUID FAR *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext, HMONITOR  hm)
 
342
static BOOL WINAPI EnumCallbackEx(GUID FAR *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext, HMONITOR hm)
347
343
{
348
344
    if (!lpGUID)
349
345
        lpDriverDescription = "Primary Display Adapter";
350
 
    mp_msg(MSGT_VO, MSGL_INFO ,"<vo_directx> adapter %d: %s", adapter_count, lpDriverDescription);
 
346
    mp_msg(MSGT_VO, MSGL_INFO, "<vo_directx> adapter %d: %s", adapter_count, lpDriverDescription);
351
347
 
352
 
    if(adapter_count == vo_adapter_num){
 
348
    if (adapter_count == vo_adapter_num) {
353
349
        if (!lpGUID)
354
350
            selected_guid_ptr = NULL;
355
 
        else
356
 
        {
357
 
            selected_guid = *lpGUID;
 
351
        else {
 
352
            selected_guid     = *lpGUID;
358
353
            selected_guid_ptr = &selected_guid;
359
354
        }
360
355
 
361
 
        mp_msg(MSGT_VO, MSGL_INFO ,"\t\t<--");
 
356
        mp_msg(MSGT_VO, MSGL_INFO, "\t\t<--");
362
357
    }
363
 
    mp_msg(MSGT_VO, MSGL_INFO ,"\n");
 
358
    mp_msg(MSGT_VO, MSGL_INFO, "\n");
364
359
 
365
360
    adapter_count++;
366
361
 
369
364
 
370
365
static uint32_t Directx_InitDirectDraw(void)
371
366
{
372
 
        HRESULT    (WINAPI *OurDirectDrawCreateEx)(GUID *,LPVOID *, REFIID,IUnknown FAR *);
373
 
        DDSURFACEDESC2 ddsd;
374
 
        LPDIRECTDRAWENUMERATEEX OurDirectDrawEnumerateEx;
375
 
 
376
 
        adapter_count = 0;
377
 
 
378
 
        mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>Initing DirectDraw\n" );
379
 
 
380
 
        //load direct draw DLL: based on videolans code
381
 
        hddraw_dll = LoadLibrary("DDRAW.DLL");
382
 
        if( hddraw_dll == NULL )
383
 
    {
384
 
        mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed loading ddraw.dll\n" );
385
 
                return 1;
 
367
    HRESULT (WINAPI *OurDirectDrawCreateEx)(GUID *, LPVOID *, REFIID, IUnknown FAR *);
 
368
    DDSURFACEDESC2 ddsd = {
 
369
        .dwSize  = sizeof(ddsd),
 
370
        .dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT,
 
371
    };
 
372
    LPDIRECTDRAWENUMERATEEX OurDirectDrawEnumerateEx;
 
373
 
 
374
    adapter_count = 0;
 
375
 
 
376
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>Initing DirectDraw\n");
 
377
 
 
378
    //load direct draw DLL: based on videolans code
 
379
    hddraw_dll = LoadLibrary("DDRAW.DLL");
 
380
    if (!hddraw_dll) {
 
381
        mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>failed loading ddraw.dll\n");
 
382
        return 1;
386
383
    }
387
384
 
388
 
        if(vo_adapter_num){ //display other than default
389
 
        OurDirectDrawEnumerateEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(hddraw_dll,"DirectDrawEnumerateExA");
390
 
        if (!OurDirectDrawEnumerateEx){
391
 
            FreeLibrary( hddraw_dll );
 
385
    if (vo_adapter_num) {   //display other than default
 
386
        OurDirectDrawEnumerateEx = (LPDIRECTDRAWENUMERATEEX)GetProcAddress(hddraw_dll, "DirectDrawEnumerateExA");
 
387
        if (!OurDirectDrawEnumerateEx) {
 
388
            FreeLibrary(hddraw_dll);
392
389
            hddraw_dll = NULL;
393
 
            mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed geting proc address: DirectDrawEnumerateEx\n");
394
 
            mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>no directx 7 or higher installed\n");
 
390
            mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>failed geting proc address: DirectDrawEnumerateEx\n");
 
391
            mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>no directx 7 or higher installed\n");
395
392
            return 1;
396
393
        }
397
394
 
398
395
        // enumerate all display devices attached to the desktop
399
 
        OurDirectDrawEnumerateEx(EnumCallbackEx, NULL, DDENUM_ATTACHEDSECONDARYDEVICES );
400
 
 
401
 
        if(vo_adapter_num >= adapter_count)
402
 
            mp_msg(MSGT_VO, MSGL_ERR,"Selected adapter (%d) doesn't exist: Default Display Adapter selected\n",vo_adapter_num);
403
 
    }
404
 
 
405
 
        OurDirectDrawCreateEx = (void *)GetProcAddress(hddraw_dll, "DirectDrawCreateEx");
406
 
    if ( OurDirectDrawCreateEx == NULL )
407
 
     {
408
 
         FreeLibrary( hddraw_dll );
409
 
         hddraw_dll = NULL;
410
 
        mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed geting proc address: DirectDrawCreateEx\n");
411
 
                return 1;
412
 
     }
413
 
 
414
 
        // initialize DirectDraw and create directx v7 object
415
 
    if (OurDirectDrawCreateEx(selected_guid_ptr, (VOID**)&g_lpdd, &IID_IDirectDraw7, NULL ) != DD_OK )
416
 
    {
417
 
        FreeLibrary( hddraw_dll );
418
 
        hddraw_dll = NULL;
419
 
        mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't initialize ddraw\n");
420
 
                return 1;
421
 
    }
422
 
 
423
 
        //get current screen siz for selected monitor ...
424
 
        ddsd.dwSize=sizeof(ddsd);
425
 
        ddsd.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
426
 
        g_lpdd->lpVtbl->GetDisplayMode(g_lpdd, &ddsd);
427
 
        if(vo_screenwidth && vo_screenheight)
428
 
        {
429
 
            vm_height=vo_screenheight;
430
 
            vm_width=vo_screenwidth;
431
 
        }
 
396
        OurDirectDrawEnumerateEx(EnumCallbackEx, NULL, DDENUM_ATTACHEDSECONDARYDEVICES);
 
397
 
 
398
        if (vo_adapter_num >= adapter_count)
 
399
            mp_msg(MSGT_VO, MSGL_ERR, "Selected adapter (%d) doesn't exist: Default Display Adapter selected\n", vo_adapter_num);
 
400
    }
 
401
 
 
402
    OurDirectDrawCreateEx = (void *)GetProcAddress(hddraw_dll, "DirectDrawCreateEx");
 
403
    if (!OurDirectDrawCreateEx) {
 
404
        FreeLibrary(hddraw_dll);
 
405
        hddraw_dll = NULL;
 
406
        mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>failed geting proc address: DirectDrawCreateEx\n");
 
407
        return 1;
 
408
    }
 
409
 
 
410
    // initialize DirectDraw and create directx v7 object
 
411
    if (OurDirectDrawCreateEx(selected_guid_ptr, (VOID **)&g_lpdd, &IID_IDirectDraw7, NULL) != DD_OK) {
 
412
        FreeLibrary(hddraw_dll);
 
413
        hddraw_dll = NULL;
 
414
        mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>can't initialize ddraw\n");
 
415
        return 1;
 
416
    }
 
417
 
 
418
    //get current screen siz for selected monitor ...
 
419
    g_lpdd->lpVtbl->GetDisplayMode(g_lpdd, &ddsd);
 
420
    if (vo_screenwidth && vo_screenheight) {
 
421
        vm_height = vo_screenheight;
 
422
        vm_width  = vo_screenwidth;
 
423
    } else {
 
424
        vm_height = ddsd.dwHeight;
 
425
        vm_width  = ddsd.dwWidth;
 
426
    }
 
427
 
 
428
    if (vo_dbpp)
 
429
        vm_bpp = vo_dbpp;
432
430
    else
433
 
    {
434
 
            vm_height=ddsd.dwHeight;
435
 
            vm_width=ddsd.dwWidth;
436
 
        }
437
 
 
438
 
 
439
 
        if(vo_dbpp)vm_bpp=vo_dbpp;
440
 
        else vm_bpp=ddsd.ddpfPixelFormat.dwRGBBitCount;
441
 
 
442
 
        if(vidmode){
443
 
                if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, vo_w32_window, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK)
444
 
                {
445
 
                mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set cooperativelevel for exclusive mode\n");
446
 
            return 1;
447
 
                }
448
 
                /*SetDisplayMode(ddobject,width,height,bpp,refreshrate,aditionalflags)*/
449
 
                if(g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,vm_width, vm_height, vm_bpp,0,0) != DD_OK)
450
 
                {
451
 
                mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set displaymode\n");
452
 
                return 1;
453
 
                }
454
 
            mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>Initialized adapter %i for %i x %i @ %i \n",vo_adapter_num,vm_width,vm_height,vm_bpp);
455
 
            return 0;
456
 
        }
457
 
        if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, vo_w32_window, DDSCL_NORMAL) != DD_OK) // or DDSCL_SETFOCUSWINDOW
458
 
     {
459
 
        mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>could not set cooperativelevel for hardwarecheck\n");
460
 
                return 1;
461
 
    }
462
 
    mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>DirectDraw Initialized\n");
463
 
        return 0;
 
431
        vm_bpp = ddsd.ddpfPixelFormat.dwRGBBitCount;
 
432
 
 
433
    if (vidmode) {
 
434
        if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, vo_w32_window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN) != DD_OK) {
 
435
            mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>can't set cooperativelevel for exclusive mode\n");
 
436
            return 1;
 
437
        }
 
438
        /*SetDisplayMode(ddobject,width,height,bpp,refreshrate,aditionalflags)*/
 
439
        if (g_lpdd->lpVtbl->SetDisplayMode(g_lpdd, vm_width, vm_height, vm_bpp, 0, 0) != DD_OK) {
 
440
            mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>can't set displaymode\n");
 
441
            return 1;
 
442
        }
 
443
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>Initialized adapter %i for %i x %i @ %i \n", vo_adapter_num, vm_width, vm_height, vm_bpp);
 
444
        return 0;
 
445
    }
 
446
    if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, vo_w32_window, DDSCL_NORMAL) != DD_OK) {   // or DDSCL_SETFOCUSWINDOW
 
447
        mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>could not set cooperativelevel for hardwarecheck\n");
 
448
        return 1;
 
449
    }
 
450
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>DirectDraw Initialized\n");
 
451
    return 0;
464
452
}
465
453
 
466
454
static uint32_t Directx_ManageDisplay(void)
467
455
{
468
 
    HRESULT         ddrval;
469
 
    DDCAPS          capsDrv;
470
 
    DDOVERLAYFX     ovfx;
471
 
    DWORD           dwUpdateFlags=0;
472
 
    int width,height;
 
456
    HRESULT ddrval;
 
457
    DDCAPS capsDrv = { .dwSize = sizeof(capsDrv) };
 
458
    DDOVERLAYFX ovfx = { .dwSize = sizeof(ovfx) };
 
459
    DWORD dwUpdateFlags = 0;
 
460
    int width, height;
473
461
 
474
462
    rd.left = vo_dx - xinerama_x;
475
463
    rd.top  = vo_dy - xinerama_y;
476
 
    width  = vo_dwidth;
477
 
    height = vo_dheight;
 
464
    width   = vo_dwidth;
 
465
    height  = vo_dheight;
478
466
 
479
467
    aspect(&width, &height, A_WINZOOM);
480
468
    panscan_calc_windowed();
481
 
    width  += vo_panscan_x;
482
 
    height += vo_panscan_y;
483
 
    width  = FFMIN(width,  vo_screenwidth);
484
 
    height = FFMIN(height, vo_screenheight);
485
 
    rd.left += (vo_dwidth  - width ) / 2;
 
469
    width   += vo_panscan_x;
 
470
    height  += vo_panscan_y;
 
471
    width    = FFMIN(width, vo_screenwidth);
 
472
    height   = FFMIN(height, vo_screenheight);
 
473
    rd.left += (vo_dwidth - width) / 2;
486
474
    rd.top  += (vo_dheight - height) / 2;
487
475
 
488
 
    rd.right=rd.left+width;
489
 
    rd.bottom=rd.top+height;
490
 
 
491
 
        /*ok, let's workaround some overlay limitations*/
492
 
        if(!nooverlay)
493
 
        {
494
 
                uint32_t        uStretchFactor1000;  //minimum stretch
495
 
        uint32_t        xstretch1000,ystretch1000;
496
 
                /*get driver capabilities*/
497
 
        ZeroMemory(&capsDrv, sizeof(capsDrv));
498
 
        capsDrv.dwSize = sizeof(capsDrv);
499
 
        if(g_lpdd->lpVtbl->GetCaps(g_lpdd,&capsDrv, NULL) != DD_OK)return 1;
500
 
                /*get minimum stretch, depends on display adaptor and mode (refresh rate!) */
501
 
        uStretchFactor1000 = capsDrv.dwMinOverlayStretch>1000 ? capsDrv.dwMinOverlayStretch : 1000;
502
 
        rd.right = ((width+rd.left)*uStretchFactor1000+999)/1000;
503
 
        rd.bottom = (height+rd.top)*uStretchFactor1000/1000;
 
476
    rd.right  = rd.left + width;
 
477
    rd.bottom = rd.top + height;
 
478
 
 
479
    /*ok, let's workaround some overlay limitations*/
 
480
    if (!nooverlay) {
 
481
        uint32_t uStretchFactor1000;                 //minimum stretch
 
482
        uint32_t xstretch1000, ystretch1000;
 
483
 
 
484
        if (!width || !height) {
 
485
            // window is minimized, so we should hide the overlay in case
 
486
            // colorkeying is not used or working.
 
487
            // In addition trying to set width/height to 0 would crash
 
488
            g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay, NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL);
 
489
            return 0;
 
490
        }
 
491
 
 
492
        /*get driver capabilities*/
 
493
        if (g_lpdd->lpVtbl->GetCaps(g_lpdd, &capsDrv, NULL) != DD_OK)
 
494
            return 1;
 
495
        /*get minimum stretch, depends on display adaptor and mode (refresh rate!) */
 
496
        uStretchFactor1000 = capsDrv.dwMinOverlayStretch > 1000 ? capsDrv.dwMinOverlayStretch : 1000;
 
497
        rd.right  = ((width + rd.left) * uStretchFactor1000 + 999) / 1000;
 
498
        rd.bottom = (height + rd.top) * uStretchFactor1000 / 1000;
504
499
        /*calculate xstretch1000 and ystretch1000*/
505
 
        xstretch1000 = ((rd.right - rd.left)* 1000)/image_width ;
506
 
        ystretch1000 = ((rd.bottom - rd.top)* 1000)/image_height;
507
 
                rs.left=0;
508
 
                rs.right=image_width;
509
 
                rs.top=0;
510
 
                rs.bottom=image_height;
511
 
        if(rd.left < 0)rs.left=(-rd.left*1000)/xstretch1000;
512
 
        if(rd.top < 0)rs.top=(-rd.top*1000)/ystretch1000;
513
 
        if(rd.right > vo_screenwidth)rs.right=((vo_screenwidth-rd.left)*1000)/xstretch1000;
514
 
        if(rd.bottom > vo_screenheight)rs.bottom=((vo_screenheight-rd.top)*1000)/ystretch1000;
515
 
                /*do not allow to zoom or shrink if hardware isn't able to do so*/
516
 
                if((width < image_width)&& !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKX))
517
 
                {
518
 
                        if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKXN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only shrinkN\n");
519
 
                else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't shrink x\n");
520
 
                rd.right=rd.left+image_width;
521
 
                }
522
 
                else if((width > image_width)&& !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHX))
523
 
                {
524
 
                        if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHXN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only stretchN\n");
525
 
                else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't stretch x\n");
526
 
                rd.right = rd.left+image_width;
527
 
                }
528
 
                if((height < image_height) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKY))
529
 
                {
530
 
                        if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKYN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only shrinkN\n");
531
 
                else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't shrink y\n");
532
 
                rd.bottom = rd.top + image_height;
533
 
                }
534
 
                else if((height > image_height ) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHY))
535
 
                {
536
 
                        if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHYN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only stretchN\n");
537
 
                else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't stretch y\n");
538
 
                rd.bottom = rd.top + image_height;
539
 
                }
540
 
                /*the last thing to check are alignment restrictions
541
 
          these expressions (x & -y) just do alignment by dropping low order bits...
542
 
          so to round up, we add first, then truncate*/
543
 
                if((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYSRC) && capsDrv.dwAlignBoundarySrc)
544
 
                  rs.left = (rs.left + capsDrv.dwAlignBoundarySrc / 2) & -(signed)(capsDrv.dwAlignBoundarySrc);
545
 
        if((capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC) && capsDrv.dwAlignSizeSrc)
546
 
                  rs.right = rs.left + ((rs.right - rs.left + capsDrv.dwAlignSizeSrc / 2) & -(signed) (capsDrv.dwAlignSizeSrc));
547
 
        if((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYDEST) && capsDrv.dwAlignBoundaryDest)
548
 
                  rd.left = (rd.left + capsDrv.dwAlignBoundaryDest / 2) & -(signed)(capsDrv.dwAlignBoundaryDest);
549
 
        if((capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST) && capsDrv.dwAlignSizeDest)
550
 
                  rd.right = rd.left + ((rd.right - rd.left) & -(signed) (capsDrv.dwAlignSizeDest));
551
 
                /*create an overlay FX structure to specify a destination color key*/
552
 
                ZeroMemory(&ovfx, sizeof(ovfx));
553
 
        ovfx.dwSize = sizeof(ovfx);
554
 
        if(vo_fs||vidmode)
555
 
                {
556
 
                        ovfx.dckDestColorkey.dwColorSpaceLowValue = 0;
 
500
        xstretch1000 = ((rd.right - rd.left) * 1000) / image_width;
 
501
        ystretch1000 = ((rd.bottom - rd.top) * 1000) / image_height;
 
502
        rs.left      = 0;
 
503
        rs.right     = image_width;
 
504
        rs.top       = 0;
 
505
        rs.bottom    = image_height;
 
506
        if (rd.left < 0)
 
507
            rs.left = (-rd.left * 1000) / xstretch1000;
 
508
        if (rd.top < 0)
 
509
            rs.top = (-rd.top * 1000) / ystretch1000;
 
510
        if (rd.right > vo_screenwidth)
 
511
            rs.right = ((vo_screenwidth - rd.left) * 1000) / xstretch1000;
 
512
        if (rd.bottom > vo_screenheight)
 
513
            rs.bottom = ((vo_screenheight - rd.top) * 1000) / ystretch1000;
 
514
        /*do not allow to zoom or shrink if hardware isn't able to do so*/
 
515
        if (width < image_width && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKX)) {
 
516
            if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKXN)
 
517
                mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>can only shrinkN\n");
 
518
            else
 
519
                mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>can't shrink x\n");
 
520
            rd.right = rd.left + image_width;
 
521
        } else if (width > image_width && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHX)) {
 
522
            if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHXN)
 
523
                mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>can only stretchN\n");
 
524
            else
 
525
                mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>can't stretch x\n");
 
526
            rd.right = rd.left + image_width;
 
527
        }
 
528
        if (height < image_height && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKY)) {
 
529
            if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKYN)
 
530
                mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>can only shrinkN\n");
 
531
            else
 
532
                mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>can't shrink y\n");
 
533
            rd.bottom = rd.top + image_height;
 
534
        } else if (height > image_height && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHY)) {
 
535
            if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHYN)
 
536
                mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>can only stretchN\n");
 
537
            else
 
538
                mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>can't stretch y\n");
 
539
            rd.bottom = rd.top + image_height;
 
540
        }
 
541
        /*the last thing to check are alignment restrictions
 
542
         * these expressions (x & -y) just do alignment by dropping low order bits...
 
543
         * so to round up, we add first, then truncate*/
 
544
        if ((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYSRC) && capsDrv.dwAlignBoundarySrc)
 
545
            rs.left = (rs.left + capsDrv.dwAlignBoundarySrc / 2) & - (signed)(capsDrv.dwAlignBoundarySrc);
 
546
        if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC) && capsDrv.dwAlignSizeSrc)
 
547
            rs.right = rs.left + ((rs.right - rs.left + capsDrv.dwAlignSizeSrc / 2) & - (signed)(capsDrv.dwAlignSizeSrc));
 
548
        if ((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYDEST) && capsDrv.dwAlignBoundaryDest)
 
549
            rd.left = (rd.left + capsDrv.dwAlignBoundaryDest / 2) & - (signed)(capsDrv.dwAlignBoundaryDest);
 
550
        if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST) && capsDrv.dwAlignSizeDest)
 
551
            rd.right = rd.left + ((rd.right - rd.left) & - (signed)(capsDrv.dwAlignSizeDest));
 
552
        /*create an overlay FX structure to specify a destination color key*/
 
553
        if (vo_fs || vidmode) {
 
554
            ovfx.dckDestColorkey.dwColorSpaceLowValue  = 0;
557
555
            ovfx.dckDestColorkey.dwColorSpaceHighValue = 0;
558
 
                }
559
 
                else
560
 
                {
561
 
                        ovfx.dckDestColorkey.dwColorSpaceLowValue = destcolorkey;
 
556
        } else {
 
557
            ovfx.dckDestColorkey.dwColorSpaceLowValue  = destcolorkey;
562
558
            ovfx.dckDestColorkey.dwColorSpaceHighValue = destcolorkey;
563
 
                }
 
559
        }
564
560
        // set the flags we'll send to UpdateOverlay      //DDOVER_AUTOFLIP|DDOVERFX_MIRRORLEFTRIGHT|DDOVERFX_MIRRORUPDOWN could be useful?;
565
561
        dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX;
566
562
        /*if hardware can't do colorkeying set the window on top*/
567
 
                if(capsDrv.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY) dwUpdateFlags |= DDOVER_KEYDESTOVERRIDE;
568
 
        else if (!tmp_image) vo_ontop = 1;
569
 
        }
570
 
    else
571
 
    {
 
563
        if (capsDrv.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY)
 
564
            dwUpdateFlags |= DDOVER_KEYDESTOVERRIDE;
 
565
        else if (!tmp_image)
 
566
            vo_ontop = 1;
 
567
    } else {
572
568
        g_lpddclipper->lpVtbl->SetHWnd(g_lpddclipper, 0, vo_w32_window);
573
569
    }
574
570
 
575
571
    /*make sure the overlay is inside the screen*/
576
 
    if(rd.left<0)rd.left=0;
577
 
    if(rd.right>vo_screenwidth)rd.right=vo_screenwidth;
578
 
    if(rd.top<0)rd.top=0;
579
 
    if(rd.bottom>vo_screenheight)rd.bottom=vo_screenheight;
 
572
    rd.top    = FFMAX(rd.top,  0);
 
573
    rd.left   = FFMAX(rd.left, 0);
 
574
    rd.bottom = FFMIN(rd.bottom, vo_screenheight);
 
575
    rd.right  = FFMIN(rd.right,  vo_screenwidth);
580
576
 
581
 
        /*for nonoverlay mode we are finished, for overlay mode we have to display the overlay first*/
582
 
        if(nooverlay)return 0;
 
577
    /*for nonoverlay mode we are finished, for overlay mode we have to display the overlay first*/
 
578
    if (nooverlay)
 
579
        return 0;
583
580
 
584
581
//    printf("overlay: %i %i %ix%i\n",rd.left,rd.top,rd.right - rd.left,rd.bottom - rd.top);
585
 
        ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,&rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
586
 
    if(FAILED(ddrval))
587
 
    {
 
582
    ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay, &rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
 
583
    if (FAILED(ddrval)) {
588
584
        // one cause might be the driver lied about minimum stretch
589
585
        // we should try upping the destination size a bit, or
590
586
        // perhaps shrinking the source size
591
 
                mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>UpdateOverlay failed\n" );
592
 
                mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>Overlay:x1:%i,y1:%i,x2:%i,y2:%i,w:%i,h:%i\n",rd.left,rd.top,rd.right,rd.bottom,rd.right - rd.left,rd.bottom - rd.top );
593
 
                mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>");
594
 
                switch (ddrval)
595
 
                {
596
 
                        case DDERR_NOSTRETCHHW:
597
 
                                {mp_msg(MSGT_VO, MSGL_ERR ,"hardware can't stretch: try to size the window back\n");break;}
598
 
            case DDERR_INVALIDRECT:
599
 
                                {mp_msg(MSGT_VO, MSGL_ERR ,"invalid rectangle\n");break;}
600
 
                        case DDERR_INVALIDPARAMS:
601
 
                                {mp_msg(MSGT_VO, MSGL_ERR ,"invalid parameters\n");break;}
602
 
                        case DDERR_HEIGHTALIGN:
603
 
                                {mp_msg(MSGT_VO, MSGL_ERR ,"height align\n");break;}
604
 
                        case DDERR_XALIGN:
605
 
                                {mp_msg(MSGT_VO, MSGL_ERR ,"x align\n");break;}
606
 
                        case DDERR_UNSUPPORTED:
607
 
                                {mp_msg(MSGT_VO, MSGL_ERR ,"unsupported\n");break;}
608
 
                        case DDERR_INVALIDSURFACETYPE:
609
 
                                {mp_msg(MSGT_VO, MSGL_ERR ,"invalid surfacetype\n");break;}
610
 
                        case DDERR_INVALIDOBJECT:
611
 
                                {mp_msg(MSGT_VO, MSGL_ERR ,"invalid object\n");break;}
612
 
                        case DDERR_SURFACELOST:
613
 
                                {
614
 
                                        mp_msg(MSGT_VO, MSGL_ERR ,"surfaces lost\n");
615
 
                                        g_lpddsOverlay->lpVtbl->Restore( g_lpddsOverlay ); //restore and try again
616
 
                                g_lpddsPrimary->lpVtbl->Restore( g_lpddsPrimary );
617
 
                                ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,&rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
618
 
                                        if(ddrval !=DD_OK)mp_msg(MSGT_VO, MSGL_FATAL ,"<vo_directx><FATAL ERROR>UpdateOverlay failed again\n" );
619
 
                                        break;
620
 
                                }
621
 
            default:
622
 
                mp_msg(MSGT_VO, MSGL_ERR ," 0x%x\n",ddrval);
623
 
                }
624
 
            /*ok we can't do anything about it -> hide overlay*/
625
 
                if(ddrval != DD_OK)
626
 
                {
627
 
                        ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL);
 
587
        mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>UpdateOverlay failed\n");
 
588
        mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>Overlay:x1:%i,y1:%i,x2:%i,y2:%i,w:%i,h:%i\n", rd.left, rd.top, rd.right, rd.bottom, rd.right - rd.left, rd.bottom - rd.top);
 
589
        mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>%s (0x%x)\n", dd_errstr(ddrval), ddrval);
 
590
        if (ddrval == DDERR_SURFACELOST) {
 
591
            g_lpddsOverlay->lpVtbl->Restore(g_lpddsOverlay);                               //restore and try again
 
592
            g_lpddsPrimary->lpVtbl->Restore(g_lpddsPrimary);
 
593
            ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay, &rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
 
594
            if (ddrval != DD_OK)
 
595
                mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>UpdateOverlay failed again\n");
 
596
        }
 
597
        /*ok we can't do anything about it -> hide overlay*/
 
598
        if (ddrval != DD_OK) {
 
599
            ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay, NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL);
628
600
            return 1;
629
 
                }
630
 
        }
 
601
        }
 
602
    }
631
603
    return 0;
632
604
}
633
605
 
648
620
//find out supported overlay pixelformats
649
621
static uint32_t Directx_CheckOverlayPixelformats(void)
650
622
{
651
 
    DDCAPS          capsDrv;
652
 
    HRESULT         ddrval;
653
 
    DDSURFACEDESC2   ddsdOverlay;
654
 
        uint32_t        i;
655
 
    uint32_t        formatcount = 0;
656
 
        //get driver caps to determine overlay support
657
 
    ZeroMemory(&capsDrv, sizeof(capsDrv));
658
 
    capsDrv.dwSize = sizeof(capsDrv);
659
 
        ddrval = g_lpdd->lpVtbl->GetCaps(g_lpdd,&capsDrv, NULL);
660
 
    if (FAILED(ddrval))
661
 
        {
662
 
        mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>failed getting ddrawcaps\n");
663
 
                return 1;
664
 
        }
665
 
    if (!(capsDrv.dwCaps & DDCAPS_OVERLAY))
666
 
    {
667
 
                mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>Your card doesn't support overlay\n");
668
 
                return 1;
669
 
        }
670
 
    mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>testing supported overlay pixelformats\n");
 
623
    DDCAPS capsDrv = { .dwSize = sizeof(capsDrv) };
 
624
    HRESULT ddrval;
 
625
    DDSURFACEDESC2 ddsdOverlay = {
 
626
        .dwSize = sizeof(ddsdOverlay),
 
627
        .ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY,
 
628
        .dwFlags  = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT,
 
629
        .dwWidth  = 300,
 
630
        .dwHeight = 280,
 
631
    };
 
632
    uint32_t i;
 
633
    uint32_t formatcount = 0;
 
634
    ddsdOverlay.dwBackBufferCount = 0;
 
635
    //get driver caps to determine overlay support
 
636
    ddrval = g_lpdd->lpVtbl->GetCaps(g_lpdd, &capsDrv, NULL);
 
637
    if (FAILED(ddrval)) {
 
638
        mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>failed getting ddrawcaps\n");
 
639
        return 1;
 
640
    }
 
641
    if (!(capsDrv.dwCaps & DDCAPS_OVERLAY)) {
 
642
        mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>Your card doesn't support overlay\n");
 
643
        return 1;
 
644
    }
 
645
    mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>testing supported overlay pixelformats\n");
671
646
    //it is not possible to query for pixel formats supported by the
672
647
    //overlay hardware: try out various formats till one works
673
 
    ZeroMemory(&ddsdOverlay, sizeof(ddsdOverlay));
674
 
    ddsdOverlay.dwSize = sizeof(ddsdOverlay);
675
 
    ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
676
 
    ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH| DDSD_PIXELFORMAT;
677
 
    ddsdOverlay.dwWidth=300;
678
 
    ddsdOverlay.dwHeight=280;
679
 
    ddsdOverlay.dwBackBufferCount=0;
680
648
    //try to create an overlay surface using one of the pixel formats in our global list
681
 
        i=0;
682
 
    do
683
 
    {
684
 
                ddsdOverlay.ddpfPixelFormat=g_ddpf[i].g_ddpfOverlay;
685
 
        ddrval = g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsdOverlay, &g_lpddsOverlay, NULL);
686
 
        if (ddrval == DD_OK)
687
 
                {
688
 
                         mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT OVERLAY>%i %s supported\n",i,g_ddpf[i].img_format_name);
689
 
                         g_ddpf[i].drv_caps = VFCAP_CSP_SUPPORTED |VFCAP_OSD |VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP;
690
 
                         formatcount++;}
691
 
            else mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT OVERLAY>%i %s not supported\n",i,g_ddpf[i].img_format_name);
692
 
                if (g_lpddsOverlay != NULL) {g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);g_lpddsOverlay = NULL;}
693
 
        } while( ++i < NUM_FORMATS );
694
 
    mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>Your card supports %i of %i overlayformats\n",formatcount, NUM_FORMATS);
695
 
        if (formatcount == 0)
696
 
        {
697
 
                mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><WARN>Your card supports overlay, but we couldn't create one\n");
698
 
                mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>This can have the following reasons:\n");
699
 
                mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- you are already using an overlay with another app\n");
700
 
                mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- you don't have enough videomemory\n");
701
 
                mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- vo_directx doesn't support the cards overlay pixelformat\n");
702
 
                return 1;
703
 
        }
704
 
    if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYMIRRORLEFTRIGHT)mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>can mirror left right\n"); //I don't have hardware which
705
 
    if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYMIRRORUPDOWN )mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>can mirror up down\n");      //supports those send me one and I'll implement ;)
706
 
        return 0;
 
649
    for (i = 0; i < NUM_FORMATS; i++) {
 
650
        ddsdOverlay.ddpfPixelFormat = g_ddpf[i].g_ddpfOverlay;
 
651
        ddrval = g_lpdd->lpVtbl->CreateSurface(g_lpdd, &ddsdOverlay, &g_lpddsOverlay, NULL);
 
652
        if (ddrval == DD_OK) {
 
653
            mp_msg(MSGT_VO, MSGL_V, "<vo_directx><FORMAT OVERLAY>%i %s supported\n", i, g_ddpf[i].img_format_name);
 
654
            drv_caps[i] = VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP;
 
655
            formatcount++;
 
656
        } else
 
657
            mp_msg(MSGT_VO, MSGL_V, "<vo_directx><FORMAT OVERLAY>%i %s not supported\n", i, g_ddpf[i].img_format_name);
 
658
        if (g_lpddsOverlay) {
 
659
            g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);
 
660
            g_lpddsOverlay = NULL;
 
661
        }
 
662
    }
 
663
    mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>Your card supports %i of %i overlayformats\n", formatcount, NUM_FORMATS);
 
664
    if (formatcount == 0) {
 
665
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><WARN>Your card supports overlay, but we couldn't create one\n");
 
666
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>This can have the following reasons:\n");
 
667
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>- you are already using an overlay with another app\n");
 
668
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>- you don't have enough videomemory\n");
 
669
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>- vo_directx doesn't support the cards overlay pixelformat\n");
 
670
        return 1;
 
671
    }
 
672
    if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYMIRRORLEFTRIGHT)
 
673
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>can mirror left right\n");                                                   //I don't have hardware which
 
674
    if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYMIRRORUPDOWN)
 
675
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>can mirror up down\n");                                                      //supports those send me one and I'll implement ;)
 
676
    return 0;
707
677
}
708
678
 
709
679
//find out the Pixelformat of the Primary Surface
710
680
static uint32_t Directx_CheckPrimaryPixelformat(void)
711
681
{
712
 
        uint32_t i=0;
 
682
    int i;
713
683
    uint32_t formatcount = 0;
714
 
        DDPIXELFORMAT   ddpf;
715
 
        DDSURFACEDESC2   ddsd;
716
 
    HDC             hdc;
717
 
    HRESULT         hres;
718
 
        COLORREF        rgbT=RGB(0,0,0);
719
 
        mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>checking primary surface\n");
720
 
        memset( &ddpf, 0, sizeof( DDPIXELFORMAT ));
721
 
    ddpf.dwSize = sizeof( DDPIXELFORMAT );
 
684
    DDPIXELFORMAT ddpf = { .dwSize = sizeof(ddpf) };
 
685
    DDSURFACEDESC2 ddsd;
 
686
    HDC hdc;
 
687
    HRESULT hres;
 
688
    COLORREF rgbT = RGB(0, 0, 0);
 
689
    mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>checking primary surface\n");
722
690
    //we have to create a primary surface first
723
 
        if(Directx_CreatePrimarySurface()!=0)return 1;
724
 
        if(g_lpddsPrimary->lpVtbl->GetPixelFormat( g_lpddsPrimary, &ddpf ) != DD_OK )
725
 
        {
726
 
                mp_msg(MSGT_VO, MSGL_FATAL ,"<vo_directx><FATAL ERROR>can't get pixelformat\n");
727
 
                return 1;
728
 
        }
729
 
    while ( i < NUM_FORMATS )
730
 
    {
731
 
           if (g_ddpf[i].g_ddpfOverlay.dwRGBBitCount == ddpf.dwRGBBitCount)
732
 
           {
733
 
           if (g_ddpf[i].g_ddpfOverlay.dwRBitMask == ddpf.dwRBitMask)
734
 
                   {
735
 
                           mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT PRIMARY>%i %s supported\n",i,g_ddpf[i].img_format_name);
736
 
                           g_ddpf[i].drv_caps = VFCAP_CSP_SUPPORTED |VFCAP_OSD;
737
 
                           formatcount++;
738
 
               primary_image_format=g_ddpf[i].img_format;
739
 
                   }
740
 
           }
741
 
           i++;
 
691
    if (Directx_CreatePrimarySurface() != 0)
 
692
        return 1;
 
693
    if (g_lpddsPrimary->lpVtbl->GetPixelFormat(g_lpddsPrimary, &ddpf) != DD_OK) {
 
694
        mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>can't get pixelformat\n");
 
695
        return 1;
 
696
    }
 
697
    for (i = 0; i < NUM_FORMATS; i++) {
 
698
        if (g_ddpf[i].g_ddpfOverlay.dwRGBBitCount == ddpf.dwRGBBitCount) {
 
699
            if (g_ddpf[i].g_ddpfOverlay.dwRBitMask == ddpf.dwRBitMask) {
 
700
                mp_msg(MSGT_VO, MSGL_V, "<vo_directx><FORMAT PRIMARY>%i %s supported\n", i, g_ddpf[i].img_format_name);
 
701
                drv_caps[i] = VFCAP_CSP_SUPPORTED | VFCAP_OSD;
 
702
                formatcount++;
 
703
                primary_image_format = g_ddpf[i].img_format;
 
704
            }
 
705
        }
742
706
    }
743
707
    //get the colorkey for overlay mode
744
 
        destcolorkey = CLR_INVALID;
745
 
    if (windowcolor != CLR_INVALID && g_lpddsPrimary->lpVtbl->GetDC(g_lpddsPrimary,&hdc) == DD_OK)
746
 
    {
 
708
    destcolorkey = CLR_INVALID;
 
709
    if (windowcolor != CLR_INVALID && g_lpddsPrimary->lpVtbl->GetDC(g_lpddsPrimary, &hdc) == DD_OK) {
747
710
        rgbT = GetPixel(hdc, 0, 0);
748
711
        SetPixel(hdc, 0, 0, windowcolor);
749
 
        g_lpddsPrimary->lpVtbl->ReleaseDC(g_lpddsPrimary,hdc);
 
712
        g_lpddsPrimary->lpVtbl->ReleaseDC(g_lpddsPrimary, hdc);
750
713
    }
751
714
    // read back the converted color
752
715
    ddsd.dwSize = sizeof(ddsd);
753
 
    while ((hres = g_lpddsPrimary->lpVtbl->Lock(g_lpddsPrimary,NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
 
716
    while ((hres = g_lpddsPrimary->lpVtbl->Lock(g_lpddsPrimary, NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
754
717
        ;
755
 
    if (hres == DD_OK)
756
 
    {
757
 
        destcolorkey = *(DWORD *) ddsd.lpSurface;
 
718
    if (hres == DD_OK) {
 
719
        destcolorkey = *(DWORD *)ddsd.lpSurface;
758
720
        if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
759
721
            destcolorkey &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1;
760
 
        g_lpddsPrimary->lpVtbl->Unlock(g_lpddsPrimary,NULL);
 
722
        g_lpddsPrimary->lpVtbl->Unlock(g_lpddsPrimary, NULL);
761
723
    }
762
 
    if (windowcolor != CLR_INVALID && g_lpddsPrimary->lpVtbl->GetDC(g_lpddsPrimary,&hdc) == DD_OK)
763
 
    {
 
724
    if (windowcolor != CLR_INVALID && g_lpddsPrimary->lpVtbl->GetDC(g_lpddsPrimary, &hdc) == DD_OK) {
764
725
        SetPixel(hdc, 0, 0, rgbT);
765
 
        g_lpddsPrimary->lpVtbl->ReleaseDC(g_lpddsPrimary,hdc);
766
 
    }
767
 
        //release primary
768
 
        g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
769
 
        g_lpddsPrimary = NULL;
770
 
        if(formatcount==0)
771
 
        {
772
 
                mp_msg(MSGT_VO, MSGL_FATAL ,"<vo_directx><FATAL ERROR>Unknown Pixelformat\n");
773
 
                return 1;
774
 
        }
775
 
        return 0;
 
726
        g_lpddsPrimary->lpVtbl->ReleaseDC(g_lpddsPrimary, hdc);
 
727
    }
 
728
    //release primary
 
729
    g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
 
730
    g_lpddsPrimary = NULL;
 
731
    if (formatcount == 0) {
 
732
        mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>Unknown Pixelformat\n");
 
733
        return 1;
 
734
    }
 
735
    return 0;
776
736
}
777
737
 
778
738
static int preinit(const char *arg)
779
739
{
780
 
        if(arg)
781
 
        {
782
 
                if(strstr(arg,"noaccel"))
783
 
                {
784
 
                        mp_msg(MSGT_VO,MSGL_V,"<vo_directx><INFO>disabled overlay\n");
785
 
                    nooverlay = 1;
786
 
                }
787
 
        }
 
740
    if (arg) {
 
741
        if (strstr(arg, "noaccel")) {
 
742
            mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>disabled overlay\n");
 
743
            nooverlay = 1;
 
744
        }
 
745
    }
788
746
 
789
747
    windowcolor = vo_colorkey;
790
 
    colorbrush = CreateSolidBrush(windowcolor);
791
 
    blackbrush = (HBRUSH)GetStockObject(BLACK_BRUSH);
792
 
        if (!vo_w32_init())
793
 
            return 1;
794
 
        if (!vo_w32_config(100, 100, VOFLAG_HIDDEN))
795
 
            return 1;
796
 
 
797
 
        if (Directx_InitDirectDraw()!= 0)return 1;          //init DirectDraw
798
 
 
799
 
    if (Directx_CheckPrimaryPixelformat()!=0)return 1;
800
 
        if (!nooverlay && Directx_CheckOverlayPixelformats() == 0)        //check for supported hardware
801
 
        {
802
 
                mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>hardware supports overlay\n");
803
 
                nooverlay = 0;
804
 
        }
805
 
        else   //if we can't have overlay we create a backpuffer with the same imageformat as the primary surface
806
 
        {
807
 
        mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>using backpuffer\n");
808
 
                nooverlay = 1;
809
 
        }
810
 
        mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>preinit succesfully finished\n");
811
 
        return 0;
 
748
    colorbrush  = CreateSolidBrush(windowcolor);
 
749
    blackbrush  = (HBRUSH)GetStockObject(BLACK_BRUSH);
 
750
    if (!vo_w32_init())
 
751
        return 1;
 
752
    if (!vo_w32_config(100, 100, VOFLAG_HIDDEN))
 
753
        return 1;
 
754
 
 
755
    if (Directx_InitDirectDraw() != 0)
 
756
        return 1;                                           //init DirectDraw
 
757
 
 
758
    if (Directx_CheckPrimaryPixelformat() != 0)
 
759
        return 1;
 
760
    if (!nooverlay && Directx_CheckOverlayPixelformats() == 0) {          //check for supported hardware
 
761
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>hardware supports overlay\n");
 
762
        nooverlay = 0;
 
763
    } else {   //if we can't have overlay we create a backpuffer with the same imageformat as the primary surface
 
764
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>using backpuffer\n");
 
765
        nooverlay = 1;
 
766
    }
 
767
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>preinit succesfully finished\n");
 
768
    return 0;
812
769
}
813
770
 
814
 
static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y )
 
771
static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y)
815
772
{
816
 
        uint8_t *s;
 
773
    uint8_t *s;
817
774
    uint8_t *d;
818
 
    uint32_t uvstride=dstride/2;
819
 
        // copy Y
820
 
    d=image+dstride*y+x;
821
 
    s=src[0];
822
 
    mem2agpcpy_pic(d,s,w,h,dstride,stride[0]);
823
 
 
824
 
        w/=2;h/=2;x/=2;y/=2;
825
 
 
826
 
        // copy U
827
 
    d=image+dstride*image_height + uvstride*y+x;
828
 
    if(image_format == IMGFMT_YV12)s=src[2];
829
 
        else s=src[1];
830
 
    mem2agpcpy_pic(d,s,w,h,uvstride,stride[1]);
831
 
 
832
 
        // copy V
833
 
    d=image+dstride*image_height +uvstride*(image_height/2) + uvstride*y+x;
834
 
    if(image_format == IMGFMT_YV12)s=src[1];
835
 
        else s=src[2];
836
 
    mem2agpcpy_pic(d,s,w,h,uvstride,stride[2]);
 
775
    uint32_t uvstride = dstride / 2;
 
776
    // copy Y
 
777
    d = image + dstride * y + x;
 
778
    s = src[0];
 
779
    mem2agpcpy_pic(d, s, w, h, dstride, stride[0]);
 
780
 
 
781
    w /= 2;
 
782
    h /= 2;
 
783
    x /= 2;
 
784
    y /= 2;
 
785
 
 
786
    // copy U
 
787
    d = image + dstride * image_height + uvstride * y + x;
 
788
    if (image_format == IMGFMT_YV12)
 
789
        s = src[2];
 
790
    else
 
791
        s = src[1];
 
792
    mem2agpcpy_pic(d, s, w, h, uvstride, stride[1]);
 
793
 
 
794
    // copy V
 
795
    d = image + dstride * image_height + uvstride * (image_height / 2) + uvstride * y + x;
 
796
    if (image_format == IMGFMT_YV12)
 
797
        s = src[1];
 
798
    else
 
799
        s = src[2];
 
800
    mem2agpcpy_pic(d, s, w, h, uvstride, stride[2]);
837
801
    return 0;
838
802
}
839
803
 
840
804
static void flip_page(void)
841
805
{
842
 
        HRESULT dxresult;
843
 
        g_lpddsBack->lpVtbl->Unlock (g_lpddsBack,NULL);
844
 
        if (vo_doublebuffering)
845
 
    {
846
 
                // flip to the next image in the sequence
847
 
                dxresult = g_lpddsOverlay->lpVtbl->Flip( g_lpddsOverlay,NULL, DDFLIP_WAIT);
848
 
                if(dxresult == DDERR_SURFACELOST)
849
 
                {
850
 
                        mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR><vo_directx><INFO>Restoring Surface\n");
851
 
                        g_lpddsBack->lpVtbl->Restore( g_lpddsBack );
852
 
                        // restore overlay and primary before calling
853
 
                        // Directx_ManageDisplay() to avoid error messages
854
 
                        g_lpddsOverlay->lpVtbl->Restore( g_lpddsOverlay );
855
 
                        g_lpddsPrimary->lpVtbl->Restore( g_lpddsPrimary );
856
 
                        // update overlay in case we return from screensaver
857
 
                        Directx_ManageDisplay();
858
 
                    dxresult = g_lpddsOverlay->lpVtbl->Flip( g_lpddsOverlay,NULL, DDFLIP_WAIT);
859
 
                }
860
 
                if(dxresult != DD_OK)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't flip page\n");
 
806
    HRESULT dxresult;
 
807
    g_lpddsBack->lpVtbl->Unlock(g_lpddsBack, NULL);
 
808
    if (vo_doublebuffering) {
 
809
        // flip to the next image in the sequence
 
810
        dxresult = g_lpddsOverlay->lpVtbl->Flip(g_lpddsOverlay, NULL, DDFLIP_WAIT);
 
811
        if (dxresult == DDERR_SURFACELOST) {
 
812
            mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR><vo_directx><INFO>Restoring Surface\n");
 
813
            g_lpddsBack->lpVtbl->Restore(g_lpddsBack);
 
814
            // restore overlay and primary before calling
 
815
            // Directx_ManageDisplay() to avoid error messages
 
816
            g_lpddsOverlay->lpVtbl->Restore(g_lpddsOverlay);
 
817
            g_lpddsPrimary->lpVtbl->Restore(g_lpddsPrimary);
 
818
            // update overlay in case we return from screensaver
 
819
            Directx_ManageDisplay();
 
820
            dxresult = g_lpddsOverlay->lpVtbl->Flip(g_lpddsOverlay, NULL, DDFLIP_WAIT);
 
821
        }
 
822
        if (dxresult != DD_OK)
 
823
            mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>can't flip page\n");
861
824
    }
862
 
        if(nooverlay)
863
 
        {
864
 
                DDBLTFX  ddbltfx;
 
825
    if (nooverlay) {
865
826
        // ask for the "NOTEARING" option
866
 
            memset( &ddbltfx, 0, sizeof(DDBLTFX) );
867
 
        ddbltfx.dwSize = sizeof(DDBLTFX);
868
 
        ddbltfx.dwDDFX = DDBLTFX_NOTEARING;
 
827
        DDBLTFX ddbltfx = {
 
828
            .dwSize = sizeof(ddbltfx),
 
829
            .dwDDFX = DDBLTFX_NOTEARING,
 
830
        };
869
831
        g_lpddsPrimary->lpVtbl->Blt(g_lpddsPrimary, &rd, g_lpddsBack, NULL, DDBLT_WAIT, &ddbltfx);
870
 
        }
871
 
        if (g_lpddsBack->lpVtbl->Lock(g_lpddsBack,NULL,&ddsdsf, DDLOCK_NOSYSLOCK | DDLOCK_WAIT , NULL) == DD_OK) {
872
 
            if(vo_directrendering && (dstride != ddsdsf.lPitch)){
873
 
                mp_msg(MSGT_VO,MSGL_WARN,"<vo_directx><WARN>stride changed !!!! disabling direct rendering\n");
874
 
                vo_directrendering=0;
875
 
            }
876
 
            free(tmp_image);
877
 
            tmp_image = NULL;
878
 
            dstride = ddsdsf.lPitch;
879
 
            image = ddsdsf.lpSurface;
880
 
        } else if (!tmp_image) {
881
 
                mp_msg(MSGT_VO, MSGL_WARN, "<vo_directx><WARN>Locking the surface failed, rendering to a hidden surface!\n");
882
 
                tmp_image = image = calloc(1, image_height * dstride * 2);
883
 
        }
 
832
    }
 
833
    if (g_lpddsBack->lpVtbl->Lock(g_lpddsBack, NULL, &ddsdsf, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL) == DD_OK) {
 
834
        if (vo_directrendering && (dstride != ddsdsf.lPitch)) {
 
835
            mp_msg(MSGT_VO, MSGL_WARN, "<vo_directx><WARN>stride changed !!!! disabling direct rendering\n");
 
836
            vo_directrendering = 0;
 
837
        }
 
838
        free(tmp_image);
 
839
        tmp_image = NULL;
 
840
        dstride   = ddsdsf.lPitch;
 
841
        image     = ddsdsf.lpSurface;
 
842
    } else if (!tmp_image) {
 
843
        mp_msg(MSGT_VO, MSGL_WARN, "<vo_directx><WARN>Locking the surface failed, rendering to a hidden surface!\n");
 
844
        tmp_image = image = calloc(1, image_height * dstride * 2);
 
845
    }
884
846
}
885
847
 
886
848
static int draw_frame(uint8_t *src[])
887
849
{
888
 
        fast_memcpy( image, *src, dstride * image_height );
889
 
        return 0;
 
850
    fast_memcpy(image, *src, dstride * image_height);
 
851
    return 0;
890
852
}
891
853
 
892
854
static uint32_t get_image(mp_image_t *mpi)
893
855
{
894
 
    if(mpi->flags&MP_IMGFLAG_READABLE) {mp_msg(MSGT_VO, MSGL_V,"<vo_directx><ERROR>slow video ram\n");return VO_FALSE;}
895
 
    if(mpi->type==MP_IMGTYPE_STATIC) {mp_msg(MSGT_VO, MSGL_V,"<vo_directx><ERROR>not static\n");return VO_FALSE;}
896
 
    if((mpi->width==dstride) || (mpi->flags&(MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ACCEPT_WIDTH)))
897
 
        {
898
 
                if(mpi->flags&MP_IMGFLAG_PLANAR)
899
 
                {
900
 
                    if(image_format == IMGFMT_YV12)
901
 
                        {
902
 
                                mpi->planes[2]= image + dstride*image_height;
903
 
                    mpi->planes[1]= image + dstride*image_height+ dstride*image_height/4;
904
 
                mpi->stride[1]=mpi->stride[2]=dstride/2;
905
 
                        }
906
 
                        else if(image_format == IMGFMT_IYUV || image_format == IMGFMT_I420)
907
 
                        {
908
 
                                mpi->planes[1]= image + dstride*image_height;
909
 
                    mpi->planes[2]= image + dstride*image_height+ dstride*image_height/4;
910
 
                            mpi->stride[1]=mpi->stride[2]=dstride/2;
911
 
                        }
912
 
                        else if(image_format == IMGFMT_YVU9)
913
 
                        {
914
 
                                mpi->planes[2] = image + dstride*image_height;
915
 
                                mpi->planes[1] = image + dstride*image_height+ dstride*image_height/16;
916
 
                            mpi->stride[1]=mpi->stride[2]=dstride/4;
917
 
                        }
918
 
                }
919
 
                mpi->planes[0]=image;
920
 
        mpi->stride[0]=dstride;
921
 
                mpi->width=image_width;
922
 
                mpi->height=image_height;
923
 
        mpi->flags|=MP_IMGFLAG_DIRECT;
 
856
    if (mpi->flags & MP_IMGFLAG_READABLE) {
 
857
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><ERROR>slow video ram\n");
 
858
        return VO_FALSE;
 
859
    }
 
860
    if (mpi->type == MP_IMGTYPE_STATIC) {
 
861
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><ERROR>not static\n");
 
862
        return VO_FALSE;
 
863
    }
 
864
    if (mpi->width == dstride || (mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH))) {
 
865
        if (mpi->flags & MP_IMGFLAG_PLANAR) {
 
866
            if (image_format == IMGFMT_YV12) {
 
867
                mpi->planes[2] = image + dstride * image_height;
 
868
                mpi->planes[1] = image + dstride * image_height + dstride * image_height / 4;
 
869
                mpi->stride[1] = mpi->stride[2] = dstride / 2;
 
870
            } else if (image_format == IMGFMT_IYUV || image_format == IMGFMT_I420) {
 
871
                mpi->planes[1] = image + dstride * image_height;
 
872
                mpi->planes[2] = image + dstride * image_height + dstride * image_height / 4;
 
873
                mpi->stride[1] = mpi->stride[2] = dstride / 2;
 
874
            } else if (image_format == IMGFMT_YVU9) {
 
875
                mpi->planes[2] = image + dstride * image_height;
 
876
                mpi->planes[1] = image + dstride * image_height + dstride * image_height / 16;
 
877
                mpi->stride[1] = mpi->stride[2] = dstride / 4;
 
878
            }
 
879
        }
 
880
        mpi->planes[0] = image;
 
881
        mpi->stride[0] = dstride;
 
882
        mpi->width     = image_width;
 
883
        mpi->height    = image_height;
 
884
        mpi->flags    |= MP_IMGFLAG_DIRECT;
924
885
        mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>Direct Rendering ENABLED\n");
925
886
        return VO_TRUE;
926
887
    }
927
888
    return VO_FALSE;
928
889
}
929
890
 
930
 
static uint32_t put_image(mp_image_t *mpi){
931
 
 
932
 
    uint8_t   *d;
933
 
        uint8_t   *s;
 
891
static uint32_t put_image(mp_image_t *mpi)
 
892
{
 
893
    uint8_t *d;
 
894
    uint8_t *s;
934
895
    uint32_t x = mpi->x;
935
 
        uint32_t y = mpi->y;
936
 
        uint32_t w = mpi->w;
937
 
        uint32_t h = mpi->h;
938
 
 
939
 
    if((mpi->flags&MP_IMGFLAG_DIRECT)||(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK))
940
 
        {
941
 
                mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>put_image: nothing to do: drawslices\n");
942
 
                return VO_TRUE;
943
 
    }
944
 
 
945
 
    if (mpi->flags&MP_IMGFLAG_PLANAR)
946
 
        {
947
 
 
948
 
                if(image_format!=IMGFMT_YVU9)draw_slice(mpi->planes,mpi->stride,mpi->w,mpi->h,0,0);
949
 
                else
950
 
                {
951
 
                        // copy Y
952
 
            d=image+dstride*y+x;
953
 
            s=mpi->planes[0];
954
 
            mem2agpcpy_pic(d,s,w,h,dstride,mpi->stride[0]);
955
 
            w/=4;h/=4;x/=4;y/=4;
956
 
            // copy V
957
 
            d=image+dstride*image_height + dstride*y/4+x;
958
 
                s=mpi->planes[2];
959
 
            mem2agpcpy_pic(d,s,w,h,dstride/4,mpi->stride[1]);
960
 
                // copy U
961
 
            d=image+dstride*image_height + dstride*image_height/16 + dstride/4*y+x;
962
 
                    s=mpi->planes[1];
963
 
            mem2agpcpy_pic(d,s,w,h,dstride/4,mpi->stride[2]);
964
 
                }
965
 
        }
966
 
        else //packed
967
 
        {
968
 
                mem2agpcpy_pic(image, mpi->planes[0], w * (mpi->bpp / 8), h, dstride, mpi->stride[0]);
969
 
        }
970
 
        return VO_TRUE;
 
896
    uint32_t y = mpi->y;
 
897
    uint32_t w = mpi->w;
 
898
    uint32_t h = mpi->h;
 
899
 
 
900
    if ((mpi->flags & MP_IMGFLAG_DIRECT) || (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)) {
 
901
        mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>put_image: nothing to do: drawslices\n");
 
902
        return VO_TRUE;
 
903
    }
 
904
 
 
905
    if (mpi->flags & MP_IMGFLAG_PLANAR) {
 
906
        if (image_format != IMGFMT_YVU9)
 
907
            draw_slice(mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
 
908
        else {
 
909
            // copy Y
 
910
            d = image + dstride * y + x;
 
911
            s = mpi->planes[0];
 
912
            mem2agpcpy_pic(d, s, w, h, dstride, mpi->stride[0]);
 
913
            w /= 4;
 
914
            h /= 4;
 
915
            x /= 4;
 
916
            y /= 4;
 
917
            // copy V
 
918
            d = image + dstride * image_height + dstride * y / 4 + x;
 
919
            s = mpi->planes[2];
 
920
            mem2agpcpy_pic(d, s, w, h, dstride / 4, mpi->stride[1]);
 
921
            // copy U
 
922
            d = image + dstride * image_height + dstride * image_height / 16 + dstride / 4 * y + x;
 
923
            s = mpi->planes[1];
 
924
            mem2agpcpy_pic(d, s, w, h, dstride / 4, mpi->stride[2]);
 
925
        }
 
926
    } else { //packed
 
927
        mem2agpcpy_pic(image, mpi->planes[0], w * (mpi->bpp / 8), h, dstride, mpi->stride[0]);
 
928
    }
 
929
    return VO_TRUE;
971
930
}
972
931
 
973
 
static int
974
 
config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t options, char *title, uint32_t format)
 
932
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t options, char *title, uint32_t format)
975
933
{
976
 
        image_format =  format;
977
 
        image_width = width;
978
 
        image_height = height;
979
 
    if(format != primary_image_format)nooverlay = 0;
 
934
    image_format = format;
 
935
    image_width  = width;
 
936
    image_height = height;
 
937
    if (format != primary_image_format)
 
938
        nooverlay = 0;
980
939
 
981
940
    /*release all directx objects*/
982
 
    if (g_cc != NULL)g_cc->lpVtbl->Release(g_cc);
983
 
    g_cc=NULL;
984
 
    if(g_lpddclipper)g_lpddclipper->lpVtbl->Release(g_lpddclipper);
985
 
        g_lpddclipper=NULL;
986
 
    if (g_lpddsBack != NULL) g_lpddsBack->lpVtbl->Release(g_lpddsBack);
 
941
    if (g_cc)
 
942
        g_cc->lpVtbl->Release(g_cc);
 
943
    g_cc = NULL;
 
944
    if (g_lpddclipper)
 
945
        g_lpddclipper->lpVtbl->Release(g_lpddclipper);
 
946
    g_lpddclipper = NULL;
 
947
    if (g_lpddsBack)
 
948
        g_lpddsBack->lpVtbl->Release(g_lpddsBack);
987
949
    g_lpddsBack = NULL;
988
 
    if(vo_doublebuffering)
989
 
        if (g_lpddsOverlay != NULL)g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);
 
950
    if (vo_doublebuffering)
 
951
        if (g_lpddsOverlay)
 
952
            g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);
990
953
    g_lpddsOverlay = NULL;
991
 
    if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
 
954
    if (g_lpddsPrimary)
 
955
        g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
992
956
    g_lpddsPrimary = NULL;
993
 
    mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surfaces released\n");
994
 
 
995
 
        if (!vo_w32_config(d_width, d_height, options))
996
 
                return 1;
997
 
 
998
 
        if (WinID == -1)
999
 
        SetWindowText(vo_w32_window,title);
1000
 
 
1001
 
 
1002
 
        /*create the surfaces*/
1003
 
    if(Directx_CreatePrimarySurface())return 1;
1004
 
 
1005
 
        //create palette for 256 color mode
1006
 
        if(image_format==IMGFMT_BGR8){
1007
 
                LPDIRECTDRAWPALETTE ddpalette=NULL;
1008
 
                LPPALETTEENTRY palette=calloc(256, sizeof(*palette));
1009
 
                int i;
1010
 
                for(i=0; i<256; i++){
1011
 
                        palette[i].peRed   = ((i >> 5) & 0x07) * 255 / 7;
1012
 
                        palette[i].peGreen = ((i >> 2) & 0x07) * 255 / 7;
1013
 
                        palette[i].peBlue  = ((i >> 0) & 0x03) * 255 / 3;
1014
 
                        palette[i].peFlags = PC_NOCOLLAPSE;
1015
 
                }
1016
 
                g_lpdd->lpVtbl->CreatePalette(g_lpdd,DDPCAPS_8BIT|DDPCAPS_INITIALIZE,palette,&ddpalette,NULL);
1017
 
                g_lpddsPrimary->lpVtbl->SetPalette(g_lpddsPrimary,ddpalette);
1018
 
                free(palette);
1019
 
                ddpalette->lpVtbl->Release(ddpalette);
1020
 
        }
1021
 
 
1022
 
        if (!nooverlay && Directx_CreateOverlay(image_format))
1023
 
        {
1024
 
                        if(format == primary_image_format)nooverlay=1; /*overlay creation failed*/
1025
 
                        else {
1026
 
              mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't use overlay mode: please use -vo directx:noaccel\n");
1027
 
                          return 1;
1028
 
            }
1029
 
        }
1030
 
        if(nooverlay)
1031
 
        {
1032
 
                if(Directx_CreateBackpuffer())
1033
 
                {
1034
 
                        mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't get the driver to work on your system :(\n");
1035
 
                        return 1;
1036
 
                }
1037
 
                mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>back surface created\n");
1038
 
                vo_doublebuffering = 0;
1039
 
                /*create clipper for nonoverlay mode*/
1040
 
            if(g_lpdd->lpVtbl->CreateClipper(g_lpdd, 0, &g_lpddclipper,NULL)!= DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't create clipper\n");return 1;}
1041
 
        if(g_lpddclipper->lpVtbl->SetHWnd (g_lpddclipper, 0, vo_w32_window)!= DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't associate clipper with window\n");return 1;}
1042
 
        if(g_lpddsPrimary->lpVtbl->SetClipper (g_lpddsPrimary,g_lpddclipper)!=DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't associate primary surface with clipper\n");return 1;}
1043
 
            mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>clipper succesfully created\n");
1044
 
        }else{
1045
 
                if(DD_OK != g_lpddsOverlay->lpVtbl->QueryInterface(g_lpddsOverlay,&IID_IDirectDrawColorControl,(void**)&g_cc))
1046
 
                        mp_msg(MSGT_VO, MSGL_V,"<vo_directx><WARN>unable to get DirectDraw ColorControl interface\n");
1047
 
        }
1048
 
        Directx_ManageDisplay();
1049
 
        memset(&ddsdsf, 0,sizeof(DDSURFACEDESC2));
1050
 
        ddsdsf.dwSize = sizeof (DDSURFACEDESC2);
1051
 
        if (g_lpddsBack->lpVtbl->Lock(g_lpddsBack,NULL,&ddsdsf, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL) == DD_OK) {
 
957
    mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>overlay surfaces released\n");
 
958
 
 
959
    if (!vo_w32_config(d_width, d_height, options))
 
960
        return 1;
 
961
 
 
962
    /*create the surfaces*/
 
963
    if (Directx_CreatePrimarySurface())
 
964
        return 1;
 
965
 
 
966
    //create palette for 256 color mode
 
967
    if (image_format == IMGFMT_BGR8) {
 
968
        LPDIRECTDRAWPALETTE ddpalette = NULL;
 
969
        LPPALETTEENTRY palette = calloc(256, sizeof(*palette));
 
970
        int i;
 
971
        for (i = 0; i < 256; i++) {
 
972
            palette[i].peRed   = ((i >> 5) & 0x07) * 255 / 7;
 
973
            palette[i].peGreen = ((i >> 2) & 0x07) * 255 / 7;
 
974
            palette[i].peBlue  = ((i >> 0) & 0x03) * 255 / 3;
 
975
            palette[i].peFlags = PC_NOCOLLAPSE;
 
976
        }
 
977
        g_lpdd->lpVtbl->CreatePalette(g_lpdd, DDPCAPS_8BIT | DDPCAPS_INITIALIZE, palette, &ddpalette, NULL);
 
978
        g_lpddsPrimary->lpVtbl->SetPalette(g_lpddsPrimary, ddpalette);
 
979
        free(palette);
 
980
        ddpalette->lpVtbl->Release(ddpalette);
 
981
    }
 
982
 
 
983
    if (!nooverlay && Directx_CreateOverlay(image_format)) {
 
984
        if (format == primary_image_format)
 
985
            nooverlay = 1;                                             /*overlay creation failed*/
 
986
        else {
 
987
            mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>can't use overlay mode: please use -vo directx:noaccel\n");
 
988
            return 1;
 
989
        }
 
990
    }
 
991
    if (nooverlay) {
 
992
        if (Directx_CreateBackpuffer()) {
 
993
            mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>can't get the driver to work on your system :(\n");
 
994
            return 1;
 
995
        }
 
996
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><INFO>back surface created\n");
 
997
        vo_doublebuffering = 0;
 
998
        /*create clipper for nonoverlay mode*/
 
999
        if (g_lpdd->lpVtbl->CreateClipper(g_lpdd, 0, &g_lpddclipper, NULL) != DD_OK) {
 
1000
            mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>can't create clipper\n");
 
1001
            return 1;
 
1002
        }
 
1003
        if (g_lpddclipper->lpVtbl->SetHWnd(g_lpddclipper, 0, vo_w32_window) != DD_OK) {
 
1004
            mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>can't associate clipper with window\n");
 
1005
            return 1;
 
1006
        }
 
1007
        if (g_lpddsPrimary->lpVtbl->SetClipper(g_lpddsPrimary, g_lpddclipper) != DD_OK) {
 
1008
            mp_msg(MSGT_VO, MSGL_FATAL, "<vo_directx><FATAL ERROR>can't associate primary surface with clipper\n");
 
1009
            return 1;
 
1010
        }
 
1011
        mp_msg(MSGT_VO, MSGL_DBG3, "<vo_directx><INFO>clipper succesfully created\n");
 
1012
    } else {
 
1013
        if (DD_OK != g_lpddsOverlay->lpVtbl->QueryInterface(g_lpddsOverlay, &IID_IDirectDrawColorControl, (void **)&g_cc))
 
1014
            mp_msg(MSGT_VO, MSGL_V, "<vo_directx><WARN>unable to get DirectDraw ColorControl interface\n");
 
1015
    }
 
1016
    Directx_ManageDisplay();
 
1017
    memset(&ddsdsf, 0, sizeof(DDSURFACEDESC2));
 
1018
    ddsdsf.dwSize = sizeof(DDSURFACEDESC2);
 
1019
    if (g_lpddsBack->lpVtbl->Lock(g_lpddsBack, NULL, &ddsdsf, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL) == DD_OK) {
1052
1020
        dstride = ddsdsf.lPitch;
1053
 
        image = ddsdsf.lpSurface;
 
1021
        image   = ddsdsf.lpSurface;
1054
1022
        return 0;
1055
 
        }
1056
 
        mp_msg(MSGT_VO, MSGL_V, "<vo_directx><ERROR>Initial Lock on the Surface failed.\n");
1057
 
        return 1;
 
1023
    }
 
1024
    mp_msg(MSGT_VO, MSGL_V, "<vo_directx><ERROR>Initial Lock on the Surface failed.\n");
 
1025
    return 1;
1058
1026
}
1059
1027
 
1060
1028
//function to set color controls
1064
1032
//  saturation  [0, 20000]
1065
1033
static uint32_t color_ctrl_set(const char *what, int value)
1066
1034
{
1067
 
        uint32_t        r = VO_NOTIMPL;
1068
 
        DDCOLORCONTROL  dcc;
1069
 
        //printf("\n*** %s = %d\n", what, value);
1070
 
        if (!g_cc) {
1071
 
                //printf("\n *** could not get color control interface!!!\n");
1072
 
                return VO_NOTIMPL;
1073
 
        }
1074
 
        ZeroMemory(&dcc, sizeof(dcc));
1075
 
        dcc.dwSize = sizeof(dcc);
1076
 
 
1077
 
        if (!strcmp(what, "brightness")) {
1078
 
                dcc.dwFlags = DDCOLOR_BRIGHTNESS;
1079
 
                dcc.lBrightness = (value + 100) * 10000 / 200;
1080
 
                r = VO_TRUE;
1081
 
        } else if (!strcmp(what, "contrast")) {
1082
 
                dcc.dwFlags = DDCOLOR_CONTRAST;
1083
 
                dcc.lContrast = (value + 100) * 20000 / 200;
1084
 
                r = VO_TRUE;
1085
 
        } else if (!strcmp(what, "hue")) {
1086
 
                dcc.dwFlags = DDCOLOR_HUE;
1087
 
                dcc.lHue = value * 180 / 100;
1088
 
                r = VO_TRUE;
1089
 
        } else if (!strcmp(what, "saturation")) {
1090
 
                dcc.dwFlags = DDCOLOR_SATURATION;
1091
 
                dcc.lSaturation = (value + 100) * 20000 / 200;
1092
 
                r = VO_TRUE;
1093
 
        }
1094
 
 
1095
 
        if (r == VO_TRUE) {
1096
 
                g_cc->lpVtbl->SetColorControls(g_cc, &dcc);
1097
 
        }
1098
 
        return r;
 
1035
    uint32_t r = VO_NOTIMPL;
 
1036
    DDCOLORCONTROL dcc = { .dwSize = sizeof(dcc) };
 
1037
    //printf("\n*** %s = %d\n", what, value);
 
1038
    if (!g_cc) {
 
1039
        //printf("\n *** could not get color control interface!!!\n");
 
1040
        return VO_NOTIMPL;
 
1041
    }
 
1042
 
 
1043
    if (!strcmp(what, "brightness")) {
 
1044
        dcc.dwFlags     = DDCOLOR_BRIGHTNESS;
 
1045
        dcc.lBrightness = (value + 100) * 10000 / 200;
 
1046
        r = VO_TRUE;
 
1047
    } else if (!strcmp(what, "contrast")) {
 
1048
        dcc.dwFlags   = DDCOLOR_CONTRAST;
 
1049
        dcc.lContrast = (value + 100) * 20000 / 200;
 
1050
        r = VO_TRUE;
 
1051
    } else if (!strcmp(what, "hue")) {
 
1052
        dcc.dwFlags = DDCOLOR_HUE;
 
1053
        dcc.lHue    = value * 180 / 100;
 
1054
        r = VO_TRUE;
 
1055
    } else if (!strcmp(what, "saturation")) {
 
1056
        dcc.dwFlags     = DDCOLOR_SATURATION;
 
1057
        dcc.lSaturation = (value + 100) * 20000 / 200;
 
1058
        r = VO_TRUE;
 
1059
    }
 
1060
 
 
1061
    if (r == VO_TRUE) {
 
1062
        g_cc->lpVtbl->SetColorControls(g_cc, &dcc);
 
1063
    }
 
1064
    return r;
1099
1065
}
1100
1066
 
1101
1067
//analoguous to color_ctrl_set
1102
1068
static uint32_t color_ctrl_get(const char *what, int *value)
1103
1069
{
1104
 
        uint32_t        r = VO_NOTIMPL;
1105
 
        DDCOLORCONTROL  dcc;
1106
 
        if (!g_cc) {
1107
 
                //printf("\n *** could not get color control interface!!!\n");
1108
 
                return VO_NOTIMPL;
1109
 
        }
1110
 
        ZeroMemory(&dcc, sizeof(dcc));
1111
 
        dcc.dwSize = sizeof(dcc);
1112
 
 
1113
 
        if (g_cc->lpVtbl->GetColorControls(g_cc, &dcc) != DD_OK) {
1114
 
                return r;
1115
 
        }
1116
 
 
1117
 
        if (!strcmp(what, "brightness") && (dcc.dwFlags & DDCOLOR_BRIGHTNESS)) {
1118
 
                *value = dcc.lBrightness * 200 / 10000 - 100;
1119
 
                r = VO_TRUE;
1120
 
        } else if (!strcmp(what, "contrast") && (dcc.dwFlags & DDCOLOR_CONTRAST)) {
1121
 
                *value = dcc.lContrast * 200 / 20000 - 100;
1122
 
                r = VO_TRUE;
1123
 
        } else if (!strcmp(what, "hue") && (dcc.dwFlags & DDCOLOR_HUE)) {
1124
 
                *value = dcc.lHue * 100 / 180;
1125
 
                r = VO_TRUE;
1126
 
        } else if (!strcmp(what, "saturation") && (dcc.dwFlags & DDCOLOR_SATURATION)) {
1127
 
                *value = dcc.lSaturation * 200 / 20000 - 100;
1128
 
                r = VO_TRUE;
1129
 
        }
 
1070
    uint32_t r = VO_NOTIMPL;
 
1071
    DDCOLORCONTROL dcc = { .dwSize = sizeof(dcc) };
 
1072
    if (!g_cc) {
 
1073
        //printf("\n *** could not get color control interface!!!\n");
 
1074
        return VO_NOTIMPL;
 
1075
    }
 
1076
 
 
1077
    if (g_cc->lpVtbl->GetColorControls(g_cc, &dcc) != DD_OK) {
 
1078
        return r;
 
1079
    }
 
1080
 
 
1081
    if (!strcmp(what, "brightness") && (dcc.dwFlags & DDCOLOR_BRIGHTNESS)) {
 
1082
        *value = dcc.lBrightness * 200 / 10000 - 100;
 
1083
        r      = VO_TRUE;
 
1084
    } else if (!strcmp(what, "contrast") && (dcc.dwFlags & DDCOLOR_CONTRAST)) {
 
1085
        *value = dcc.lContrast * 200 / 20000 - 100;
 
1086
        r      = VO_TRUE;
 
1087
    } else if (!strcmp(what, "hue") && (dcc.dwFlags & DDCOLOR_HUE)) {
 
1088
        *value = dcc.lHue * 100 / 180;
 
1089
        r      = VO_TRUE;
 
1090
    } else if (!strcmp(what, "saturation") && (dcc.dwFlags & DDCOLOR_SATURATION)) {
 
1091
        *value = dcc.lSaturation * 200 / 20000 - 100;
 
1092
        r      = VO_TRUE;
 
1093
    }
1130
1094
//      printf("\n*** %s = %d\n", what, *value);
1131
1095
 
1132
 
        return r;
 
1096
    return r;
1133
1097
}
1134
1098
 
1135
1099
static int control(uint32_t request, void *data)
1136
1100
{
1137
1101
    switch (request) {
1138
 
 
1139
 
        case VOCTRL_GET_IMAGE:
1140
 
        return get_image(data);
 
1102
    case VOCTRL_GET_IMAGE:
 
1103
        return get_image(data);
1141
1104
    case VOCTRL_QUERY_FORMAT:
1142
 
        return query_format(*((uint32_t*)data));
1143
 
        case VOCTRL_DRAW_IMAGE:
 
1105
        return query_format(*(uint32_t *)data);
 
1106
    case VOCTRL_DRAW_IMAGE:
1144
1107
        return put_image(data);
1145
1108
    case VOCTRL_BORDER:
1146
1109
        vo_w32_border();
1147
1110
        Directx_ManageDisplay();
1148
 
                return VO_TRUE;
 
1111
        return VO_TRUE;
1149
1112
    case VOCTRL_ONTOP:
1150
1113
        vo_w32_ontop();
1151
 
                return VO_TRUE;
 
1114
        return VO_TRUE;
1152
1115
    case VOCTRL_ROOTWIN:
1153
 
                        if(WinID != -1) return VO_TRUE;
1154
 
                if(vidmode)
1155
 
                        {
1156
 
                                mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>rootwin has no meaning in exclusive mode\n");
1157
 
                        }
1158
 
                else
1159
 
                        {
1160
 
                                if(vo_rootwin) vo_rootwin = 0;
1161
 
                                else vo_rootwin = 1;
1162
 
                                Directx_ManageDisplay();
1163
 
                        }
1164
 
                return VO_TRUE;
 
1116
        if (WinID != -1)
 
1117
            return VO_TRUE;
 
1118
        if (vidmode) {
 
1119
            mp_msg(MSGT_VO, MSGL_ERR, "<vo_directx><ERROR>rootwin has no meaning in exclusive mode\n");
 
1120
        } else {
 
1121
            if (vo_rootwin)
 
1122
                vo_rootwin = 0;
 
1123
            else
 
1124
                vo_rootwin = 1;
 
1125
            Directx_ManageDisplay();
 
1126
        }
 
1127
        return VO_TRUE;
1165
1128
    case VOCTRL_FULLSCREEN:
1166
 
                {
1167
 
            vo_w32_fullscreen();
1168
 
            Directx_ManageDisplay();
1169
 
                    return VO_TRUE;
1170
 
                }
1171
 
        case VOCTRL_SET_EQUALIZER: {
1172
 
        vf_equalizer_t *eq=data;
1173
 
                return color_ctrl_set(eq->item, eq->value);
1174
 
        }
1175
 
        case VOCTRL_GET_EQUALIZER: {
1176
 
        vf_equalizer_t *eq=data;
1177
 
                return color_ctrl_get(eq->item, &eq->value);
1178
 
        }
 
1129
        vo_w32_fullscreen();
 
1130
        Directx_ManageDisplay();
 
1131
        return VO_TRUE;
 
1132
    case VOCTRL_SET_EQUALIZER: {
 
1133
        vf_equalizer_t *eq = data;
 
1134
        return color_ctrl_set(eq->item, eq->value);
 
1135
    }
 
1136
    case VOCTRL_GET_EQUALIZER: {
 
1137
        vf_equalizer_t *eq = data;
 
1138
        return color_ctrl_get(eq->item, &eq->value);
 
1139
    }
1179
1140
    case VOCTRL_UPDATE_SCREENINFO:
1180
1141
        w32_update_xinerama_info();
1181
1142
        return VO_TRUE;
1182
 
    };
 
1143
    }
1183
1144
    return VO_NOTIMPL;
1184
1145
}