src/video/windx5/SDL_dx5yuv.c
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
equal deleted inserted replaced
1667:1fddae038bc8 1668:4da1ee79c9af
    46     Uint8 *planes[3];
    46     Uint8 *planes[3];
    47 };
    47 };
    48 
    48 
    49 
    49 
    50 static LPDIRECTDRAWSURFACE3
    50 static LPDIRECTDRAWSURFACE3
    51 CreateYUVSurface (_THIS, int width, int height, Uint32 format)
    51 CreateYUVSurface(_THIS, int width, int height, Uint32 format)
    52 {
    52 {
    53     HRESULT result;
    53     HRESULT result;
    54     LPDIRECTDRAWSURFACE dd_surface1;
    54     LPDIRECTDRAWSURFACE dd_surface1;
    55     LPDIRECTDRAWSURFACE3 dd_surface3;
    55     LPDIRECTDRAWSURFACE3 dd_surface3;
    56     DDSURFACEDESC ddsd;
    56     DDSURFACEDESC ddsd;
    57 
    57 
    58     /* Set up the surface description */
    58     /* Set up the surface description */
    59     SDL_memset (&ddsd, 0, sizeof (ddsd));
    59     SDL_memset(&ddsd, 0, sizeof(ddsd));
    60     ddsd.dwSize = sizeof (ddsd);
    60     ddsd.dwSize = sizeof(ddsd);
    61     ddsd.dwFlags = (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT);
    61     ddsd.dwFlags = (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT);
    62     ddsd.dwWidth = width;
    62     ddsd.dwWidth = width;
    63     ddsd.dwHeight = height;
    63     ddsd.dwHeight = height;
    64 #ifdef USE_DIRECTX_OVERLAY
    64 #ifdef USE_DIRECTX_OVERLAY
    65     ddsd.ddsCaps.dwCaps = (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY);
    65     ddsd.ddsCaps.dwCaps = (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY);
    66 #else
    66 #else
    67     ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY);
    67     ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY);
    68 #endif
    68 #endif
    69     ddsd.ddpfPixelFormat.dwSize = sizeof (ddsd.ddpfPixelFormat);
    69     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
    70     ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
    70     ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
    71     ddsd.ddpfPixelFormat.dwFourCC = format;
    71     ddsd.ddpfPixelFormat.dwFourCC = format;
    72 
    72 
    73     /* Create the DirectDraw video surface */
    73     /* Create the DirectDraw video surface */
    74     result = IDirectDraw2_CreateSurface (ddraw2, &ddsd, &dd_surface1, NULL);
    74     result = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &dd_surface1, NULL);
    75     if (result != DD_OK) {
    75     if (result != DD_OK) {
    76         SetDDerror ("DirectDraw2::CreateSurface", result);
    76         SetDDerror("DirectDraw2::CreateSurface", result);
    77         return (NULL);
    77         return (NULL);
    78     }
    78     }
    79     result = IDirectDrawSurface_QueryInterface (dd_surface1,
    79     result = IDirectDrawSurface_QueryInterface(dd_surface1,
    80                                                 &IID_IDirectDrawSurface3,
    80                                                &IID_IDirectDrawSurface3,
    81                                                 (LPVOID *) & dd_surface3);
    81                                                (LPVOID *) & dd_surface3);
    82     IDirectDrawSurface_Release (dd_surface1);
    82     IDirectDrawSurface_Release(dd_surface1);
    83     if (result != DD_OK) {
    83     if (result != DD_OK) {
    84         SetDDerror ("DirectDrawSurface::QueryInterface", result);
    84         SetDDerror("DirectDrawSurface::QueryInterface", result);
    85         return (NULL);
    85         return (NULL);
    86     }
    86     }
    87 
    87 
    88     /* Make sure the surface format was set properly */
    88     /* Make sure the surface format was set properly */
    89     SDL_memset (&ddsd, 0, sizeof (ddsd));
    89     SDL_memset(&ddsd, 0, sizeof(ddsd));
    90     ddsd.dwSize = sizeof (ddsd);
    90     ddsd.dwSize = sizeof(ddsd);
    91     result = IDirectDrawSurface3_Lock (dd_surface3, NULL,
    91     result = IDirectDrawSurface3_Lock(dd_surface3, NULL,
    92                                        &ddsd, DDLOCK_NOSYSLOCK, NULL);
    92                                       &ddsd, DDLOCK_NOSYSLOCK, NULL);
    93     if (result != DD_OK) {
    93     if (result != DD_OK) {
    94         SetDDerror ("DirectDrawSurface3::Lock", result);
    94         SetDDerror("DirectDrawSurface3::Lock", result);
    95         IDirectDrawSurface_Release (dd_surface3);
    95         IDirectDrawSurface_Release(dd_surface3);
    96         return (NULL);
    96         return (NULL);
    97     }
    97     }
    98     IDirectDrawSurface3_Unlock (dd_surface3, NULL);
    98     IDirectDrawSurface3_Unlock(dd_surface3, NULL);
    99 
    99 
   100     if (!(ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC) ||
   100     if (!(ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC) ||
   101         (ddsd.ddpfPixelFormat.dwFourCC != format)) {
   101         (ddsd.ddpfPixelFormat.dwFourCC != format)) {
   102         SDL_SetError ("DDraw didn't use requested FourCC format");
   102         SDL_SetError("DDraw didn't use requested FourCC format");
   103         IDirectDrawSurface_Release (dd_surface3);
   103         IDirectDrawSurface_Release(dd_surface3);
   104         return (NULL);
   104         return (NULL);
   105     }
   105     }
   106 
   106 
   107     /* We're ready to go! */
   107     /* We're ready to go! */
   108     return (dd_surface3);
   108     return (dd_surface3);
   109 }
   109 }
   110 
   110 
   111 #ifdef DEBUG_YUV
   111 #ifdef DEBUG_YUV
   112 static char *
   112 static char *
   113 PrintFOURCC (Uint32 code)
   113 PrintFOURCC(Uint32 code)
   114 {
   114 {
   115     static char buf[5];
   115     static char buf[5];
   116 
   116 
   117     buf[3] = code >> 24;
   117     buf[3] = code >> 24;
   118     buf[2] = (code >> 16) & 0xFF;
   118     buf[2] = (code >> 16) & 0xFF;
   121     return (buf);
   121     return (buf);
   122 }
   122 }
   123 #endif
   123 #endif
   124 
   124 
   125 SDL_Overlay *
   125 SDL_Overlay *
   126 DX5_CreateYUVOverlay (_THIS, int width, int height, Uint32 format,
   126 DX5_CreateYUVOverlay(_THIS, int width, int height, Uint32 format,
   127                       SDL_Surface * display)
   127                      SDL_Surface * display)
   128 {
   128 {
   129     SDL_Overlay *overlay;
   129     SDL_Overlay *overlay;
   130     struct private_yuvhwdata *hwdata;
   130     struct private_yuvhwdata *hwdata;
   131 
   131 
   132 #ifdef DEBUG_YUV
   132 #ifdef DEBUG_YUV
   133     DWORD numcodes;
   133     DWORD numcodes;
   134     DWORD *codes;
   134     DWORD *codes;
   135 
   135 
   136     printf ("FOURCC format requested: 0x%x\n", PrintFOURCC (format));
   136     printf("FOURCC format requested: 0x%x\n", PrintFOURCC(format));
   137     IDirectDraw2_GetFourCCCodes (ddraw2, &numcodes, NULL);
   137     IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, NULL);
   138     if (numcodes) {
   138     if (numcodes) {
   139         DWORD i;
   139         DWORD i;
   140         codes = SDL_malloc (numcodes * sizeof (*codes));
   140         codes = SDL_malloc(numcodes * sizeof(*codes));
   141         if (codes) {
   141         if (codes) {
   142             IDirectDraw2_GetFourCCCodes (ddraw2, &numcodes, codes);
   142             IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, codes);
   143             for (i = 0; i < numcodes; ++i) {
   143             for (i = 0; i < numcodes; ++i) {
   144                 fprintf (stderr, "Code %d: 0x%x\n", i,
   144                 fprintf(stderr, "Code %d: 0x%x\n", i, PrintFOURCC(codes[i]));
   145                          PrintFOURCC (codes[i]));
       
   146             }
   145             }
   147             SDL_free (codes);
   146             SDL_free(codes);
   148         }
   147         }
   149     } else {
   148     } else {
   150         fprintf (stderr, "No FOURCC codes supported\n");
   149         fprintf(stderr, "No FOURCC codes supported\n");
   151     }
   150     }
   152 #endif
   151 #endif
   153 
   152 
   154     /* Create the overlay structure */
   153     /* Create the overlay structure */
   155     overlay = (SDL_Overlay *) SDL_malloc (sizeof *overlay);
   154     overlay = (SDL_Overlay *) SDL_malloc(sizeof *overlay);
   156     if (overlay == NULL) {
   155     if (overlay == NULL) {
   157         SDL_OutOfMemory ();
   156         SDL_OutOfMemory();
   158         return (NULL);
   157         return (NULL);
   159     }
   158     }
   160     SDL_memset (overlay, 0, (sizeof *overlay));
   159     SDL_memset(overlay, 0, (sizeof *overlay));
   161 
   160 
   162     /* Fill in the basic members */
   161     /* Fill in the basic members */
   163     overlay->format = format;
   162     overlay->format = format;
   164     overlay->w = width;
   163     overlay->w = width;
   165     overlay->h = height;
   164     overlay->h = height;
   166 
   165 
   167     /* Set up the YUV surface function structure */
   166     /* Set up the YUV surface function structure */
   168     overlay->hwfuncs = &dx5_yuvfuncs;
   167     overlay->hwfuncs = &dx5_yuvfuncs;
   169 
   168 
   170     /* Create the pixel data and lookup tables */
   169     /* Create the pixel data and lookup tables */
   171     hwdata = (struct private_yuvhwdata *) SDL_malloc (sizeof *hwdata);
   170     hwdata = (struct private_yuvhwdata *) SDL_malloc(sizeof *hwdata);
   172     overlay->hwdata = hwdata;
   171     overlay->hwdata = hwdata;
   173     if (hwdata == NULL) {
   172     if (hwdata == NULL) {
   174         SDL_OutOfMemory ();
   173         SDL_OutOfMemory();
   175         SDL_FreeYUVOverlay (overlay);
   174         SDL_FreeYUVOverlay(overlay);
   176         return (NULL);
   175         return (NULL);
   177     }
   176     }
   178     hwdata->surface = CreateYUVSurface (this, width, height, format);
   177     hwdata->surface = CreateYUVSurface(this, width, height, format);
   179     if (hwdata->surface == NULL) {
   178     if (hwdata->surface == NULL) {
   180         SDL_FreeYUVOverlay (overlay);
   179         SDL_FreeYUVOverlay(overlay);
   181         return (NULL);
   180         return (NULL);
   182     }
   181     }
   183     overlay->hw_overlay = 1;
   182     overlay->hw_overlay = 1;
   184 
   183 
   185     /* Set up the plane pointers */
   184     /* Set up the plane pointers */
   198     /* We're all done.. */
   197     /* We're all done.. */
   199     return (overlay);
   198     return (overlay);
   200 }
   199 }
   201 
   200 
   202 int
   201 int
   203 DX5_LockYUVOverlay (_THIS, SDL_Overlay * overlay)
   202 DX5_LockYUVOverlay(_THIS, SDL_Overlay * overlay)
   204 {
   203 {
   205     HRESULT result;
   204     HRESULT result;
   206     LPDIRECTDRAWSURFACE3 surface;
   205     LPDIRECTDRAWSURFACE3 surface;
   207     DDSURFACEDESC ddsd;
   206     DDSURFACEDESC ddsd;
   208 
   207 
   209     surface = overlay->hwdata->surface;
   208     surface = overlay->hwdata->surface;
   210     SDL_memset (&ddsd, 0, sizeof (ddsd));
   209     SDL_memset(&ddsd, 0, sizeof(ddsd));
   211     ddsd.dwSize = sizeof (ddsd);
   210     ddsd.dwSize = sizeof(ddsd);
   212     result = IDirectDrawSurface3_Lock (surface, NULL,
   211     result = IDirectDrawSurface3_Lock(surface, NULL,
   213                                        &ddsd, DDLOCK_NOSYSLOCK, NULL);
   212                                       &ddsd, DDLOCK_NOSYSLOCK, NULL);
   214     if (result == DDERR_SURFACELOST) {
   213     if (result == DDERR_SURFACELOST) {
   215         result = IDirectDrawSurface3_Restore (surface);
   214         result = IDirectDrawSurface3_Restore(surface);
   216         result = IDirectDrawSurface3_Lock (surface, NULL, &ddsd,
   215         result = IDirectDrawSurface3_Lock(surface, NULL, &ddsd,
   217                                            (DDLOCK_NOSYSLOCK | DDLOCK_WAIT),
   216                                           (DDLOCK_NOSYSLOCK | DDLOCK_WAIT),
   218                                            NULL);
   217                                           NULL);
   219     }
   218     }
   220     if (result != DD_OK) {
   219     if (result != DD_OK) {
   221         SetDDerror ("DirectDrawSurface3::Lock", result);
   220         SetDDerror("DirectDrawSurface3::Lock", result);
   222         return (-1);
   221         return (-1);
   223     }
   222     }
   224 
   223 
   225     /* Find the pitch and offset values for the overlay */
   224     /* Find the pitch and offset values for the overlay */
   226 #if defined(NONAMELESSUNION)
   225 #if defined(NONAMELESSUNION)
   246     }
   245     }
   247     return (0);
   246     return (0);
   248 }
   247 }
   249 
   248 
   250 void
   249 void
   251 DX5_UnlockYUVOverlay (_THIS, SDL_Overlay * overlay)
   250 DX5_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay)
   252 {
   251 {
   253     LPDIRECTDRAWSURFACE3 surface;
   252     LPDIRECTDRAWSURFACE3 surface;
   254 
   253 
   255     surface = overlay->hwdata->surface;
   254     surface = overlay->hwdata->surface;
   256     IDirectDrawSurface3_Unlock (surface, NULL);
   255     IDirectDrawSurface3_Unlock(surface, NULL);
   257 }
   256 }
   258 
   257 
   259 int
   258 int
   260 DX5_DisplayYUVOverlay (_THIS, SDL_Overlay * overlay, SDL_Rect * src,
   259 DX5_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src,
   261                        SDL_Rect * dst)
   260                       SDL_Rect * dst)
   262 {
   261 {
   263     HRESULT result;
   262     HRESULT result;
   264     LPDIRECTDRAWSURFACE3 surface;
   263     LPDIRECTDRAWSURFACE3 surface;
   265     RECT srcrect, dstrect;
   264     RECT srcrect, dstrect;
   266 
   265 
   272     dstrect.top = SDL_bounds.top + dst->y;
   271     dstrect.top = SDL_bounds.top + dst->y;
   273     dstrect.left = SDL_bounds.left + dst->x;
   272     dstrect.left = SDL_bounds.left + dst->x;
   274     dstrect.bottom = dstrect.top + dst->h;
   273     dstrect.bottom = dstrect.top + dst->h;
   275     dstrect.right = dstrect.left + dst->w;
   274     dstrect.right = dstrect.left + dst->w;
   276 #ifdef USE_DIRECTX_OVERLAY
   275 #ifdef USE_DIRECTX_OVERLAY
   277     result = IDirectDrawSurface3_UpdateOverlay (surface, &srcrect,
   276     result = IDirectDrawSurface3_UpdateOverlay(surface, &srcrect,
   278                                                 SDL_primary, &dstrect,
   277                                                SDL_primary, &dstrect,
   279                                                 DDOVER_SHOW, NULL);
   278                                                DDOVER_SHOW, NULL);
   280     if (result != DD_OK) {
   279     if (result != DD_OK) {
   281         SetDDerror ("DirectDrawSurface3::UpdateOverlay", result);
   280         SetDDerror("DirectDrawSurface3::UpdateOverlay", result);
   282         return (-1);
   281         return (-1);
   283     }
   282     }
   284 #else
   283 #else
   285     result =
   284     result =
   286         IDirectDrawSurface3_Blt (SDL_primary, &dstrect, surface, &srcrect,
   285         IDirectDrawSurface3_Blt(SDL_primary, &dstrect, surface, &srcrect,
   287                                  DDBLT_WAIT, NULL);
   286                                 DDBLT_WAIT, NULL);
   288     if (result != DD_OK) {
   287     if (result != DD_OK) {
   289         SetDDerror ("DirectDrawSurface3::Blt", result);
   288         SetDDerror("DirectDrawSurface3::Blt", result);
   290         return (-1);
   289         return (-1);
   291     }
   290     }
   292 #endif
   291 #endif
   293     return (0);
   292     return (0);
   294 }
   293 }
   295 
   294 
   296 void
   295 void
   297 DX5_FreeYUVOverlay (_THIS, SDL_Overlay * overlay)
   296 DX5_FreeYUVOverlay(_THIS, SDL_Overlay * overlay)
   298 {
   297 {
   299     struct private_yuvhwdata *hwdata;
   298     struct private_yuvhwdata *hwdata;
   300 
   299 
   301     hwdata = overlay->hwdata;
   300     hwdata = overlay->hwdata;
   302     if (hwdata) {
   301     if (hwdata) {
   303         if (hwdata->surface) {
   302         if (hwdata->surface) {
   304             IDirectDrawSurface_Release (hwdata->surface);
   303             IDirectDrawSurface_Release(hwdata->surface);
   305         }
   304         }
   306         SDL_free (hwdata);
   305         SDL_free(hwdata);
   307     }
   306     }
   308 }
   307 }
   309 
   308 
   310 /* vi: set ts=4 sw=4 expandtab: */
   309 /* vi: set ts=4 sw=4 expandtab: */