Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
281 lines (228 loc) · 7.29 KB

SDL_DirectFB_yuv.c

File metadata and controls

281 lines (228 loc) · 7.29 KB
 
1
2
/*
SDL - Simple DirectMedia Layer
Feb 1, 2006
Feb 1, 2006
3
Copyright (C) 1997-2006 Sam Lantinga
4
5
This library is free software; you can redistribute it and/or
Feb 1, 2006
Feb 1, 2006
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
Feb 1, 2006
Feb 1, 2006
8
version 2.1 of the License, or (at your option) any later version.
9
10
11
12
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Feb 1, 2006
Feb 1, 2006
13
Lesser General Public License for more details.
14
Feb 1, 2006
Feb 1, 2006
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19
20
21
Sam Lantinga
slouken@libsdl.org
*/
Feb 21, 2006
Feb 21, 2006
22
#include "SDL_config.h"
23
24
25
26
27
/* This is the DirectFB implementation of YUV video overlays */
#include "SDL_video.h"
#include "SDL_DirectFB_yuv.h"
Feb 16, 2006
Feb 16, 2006
28
#include "../SDL_yuvfuncs.h"
29
30
31
32
/* The functions used to manipulate software video overlays */
static struct private_yuvhwfuncs directfb_yuvfuncs = {
May 28, 2006
May 28, 2006
33
34
35
36
DirectFB_LockYUVOverlay,
DirectFB_UnlockYUVOverlay,
DirectFB_DisplayYUVOverlay,
DirectFB_FreeYUVOverlay
37
38
};
May 28, 2006
May 28, 2006
39
40
41
struct private_yuvhwdata
{
DFBDisplayLayerID layer_id;
42
May 28, 2006
May 28, 2006
43
44
IDirectFBDisplayLayer *layer;
IDirectFBSurface *surface;
45
May 28, 2006
May 28, 2006
46
47
48
/* These are just so we don't have to allocate them separately */
Uint16 pitches[3];
Uint8 *planes[3];
49
50
51
};
static DFBEnumerationResult
May 29, 2006
May 29, 2006
52
53
enum_layers_callback(DFBDisplayLayerID id,
DFBDisplayLayerDescription desc, void *data)
54
{
May 28, 2006
May 28, 2006
55
struct private_yuvhwdata *hwdata = (struct private_yuvhwdata *) data;
56
May 28, 2006
May 28, 2006
57
58
59
/* we don't want the primary */
if (id == DLID_PRIMARY)
return DFENUM_OK;
60
May 28, 2006
May 28, 2006
61
62
63
/* take the one with a surface for video */
if ((desc.caps & DLCAPS_SURFACE) && (desc.type & DLTF_VIDEO)) {
hwdata->layer_id = id;
64
May 28, 2006
May 28, 2006
65
return DFENUM_CANCEL;
66
67
}
May 28, 2006
May 28, 2006
68
return DFENUM_OK;
69
70
71
}
May 28, 2006
May 28, 2006
72
static DFBResult
May 29, 2006
May 29, 2006
73
74
CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata,
int width, int height, Uint32 format)
75
{
May 28, 2006
May 28, 2006
76
77
78
79
80
DFBResult ret;
IDirectFB *dfb = HIDDEN->dfb;
IDirectFBDisplayLayer *layer;
DFBDisplayLayerConfig conf;
May 29, 2006
May 29, 2006
81
ret = dfb->EnumDisplayLayers(dfb, enum_layers_callback, hwdata);
May 28, 2006
May 28, 2006
82
if (ret) {
May 29, 2006
May 29, 2006
83
SetDirectFBerror("IDirectFB::EnumDisplayLayers", ret);
May 28, 2006
May 28, 2006
84
return ret;
85
86
}
May 28, 2006
May 28, 2006
87
88
if (!hwdata->layer_id)
return DFB_UNSUPPORTED;
89
May 29, 2006
May 29, 2006
90
ret = dfb->GetDisplayLayer(dfb, hwdata->layer_id, &layer);
May 28, 2006
May 28, 2006
91
if (ret) {
May 29, 2006
May 29, 2006
92
SetDirectFBerror("IDirectFB::GetDisplayLayer", ret);
May 28, 2006
May 28, 2006
93
return ret;
94
95
}
May 28, 2006
May 28, 2006
96
97
98
conf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
conf.width = width;
conf.height = height;
99
May 28, 2006
May 28, 2006
100
switch (format) {
101
case SDL_YV12_OVERLAY:
May 28, 2006
May 28, 2006
102
103
conf.pixelformat = DSPF_YV12;
break;
104
case SDL_IYUV_OVERLAY:
May 28, 2006
May 28, 2006
105
106
conf.pixelformat = DSPF_I420;
break;
107
case SDL_YUY2_OVERLAY:
May 28, 2006
May 28, 2006
108
109
conf.pixelformat = DSPF_YUY2;
break;
110
case SDL_UYVY_OVERLAY:
May 28, 2006
May 28, 2006
111
112
conf.pixelformat = DSPF_UYVY;
break;
113
default:
May 29, 2006
May 29, 2006
114
115
fprintf(stderr, "SDL_DirectFB: Unsupported YUV format (0x%08x)!\n",
format);
May 28, 2006
May 28, 2006
116
break;
117
118
}
May 29, 2006
May 29, 2006
119
ret = layer->SetConfiguration(layer, &conf);
May 28, 2006
May 28, 2006
120
if (ret) {
May 29, 2006
May 29, 2006
121
122
SetDirectFBerror("IDirectFBDisplayLayer::SetConfiguration", ret);
layer->Release(layer);
May 28, 2006
May 28, 2006
123
return ret;
124
125
}
May 29, 2006
May 29, 2006
126
ret = layer->GetSurface(layer, &hwdata->surface);
May 28, 2006
May 28, 2006
127
if (ret) {
May 29, 2006
May 29, 2006
128
129
SetDirectFBerror("IDirectFBDisplayLayer::GetSurface", ret);
layer->Release(layer);
May 28, 2006
May 28, 2006
130
return ret;
131
132
}
May 28, 2006
May 28, 2006
133
hwdata->layer = layer;
134
May 28, 2006
May 28, 2006
135
return DFB_OK;
136
137
}
May 28, 2006
May 28, 2006
138
SDL_Overlay *
May 29, 2006
May 29, 2006
139
140
DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format,
SDL_Surface * display)
141
{
May 28, 2006
May 28, 2006
142
143
144
145
SDL_Overlay *overlay;
struct private_yuvhwdata *hwdata;
/* Create the overlay structure */
May 29, 2006
May 29, 2006
146
overlay = SDL_calloc(1, sizeof(SDL_Overlay));
May 28, 2006
May 28, 2006
147
if (!overlay) {
May 29, 2006
May 29, 2006
148
SDL_OutOfMemory();
May 28, 2006
May 28, 2006
149
return NULL;
150
}
May 28, 2006
May 28, 2006
151
152
153
154
155
156
157
158
159
160
/* Fill in the basic members */
overlay->format = format;
overlay->w = width;
overlay->h = height;
/* Set up the YUV surface function structure */
overlay->hwfuncs = &directfb_yuvfuncs;
/* Create the pixel data and lookup tables */
May 29, 2006
May 29, 2006
161
hwdata = SDL_calloc(1, sizeof(struct private_yuvhwdata));
May 28, 2006
May 28, 2006
162
163
overlay->hwdata = hwdata;
if (!hwdata) {
May 29, 2006
May 29, 2006
164
165
SDL_OutOfMemory();
SDL_FreeYUVOverlay(overlay);
May 28, 2006
May 28, 2006
166
return NULL;
167
168
}
May 29, 2006
May 29, 2006
169
170
if (CreateYUVSurface(this, hwdata, width, height, format)) {
SDL_FreeYUVOverlay(overlay);
May 28, 2006
May 28, 2006
171
return NULL;
172
173
}
May 28, 2006
May 28, 2006
174
overlay->hw_overlay = 1;
175
May 28, 2006
May 28, 2006
176
177
178
179
/* Set up the plane pointers */
overlay->pitches = hwdata->pitches;
overlay->pixels = hwdata->planes;
switch (format) {
180
181
case SDL_YV12_OVERLAY:
case SDL_IYUV_OVERLAY:
May 28, 2006
May 28, 2006
182
183
overlay->planes = 3;
break;
184
default:
May 28, 2006
May 28, 2006
185
186
overlay->planes = 1;
break;
187
188
}
May 28, 2006
May 28, 2006
189
190
/* We're all done.. */
return overlay;
191
192
}
May 28, 2006
May 28, 2006
193
int
May 29, 2006
May 29, 2006
194
DirectFB_LockYUVOverlay(_THIS, SDL_Overlay * overlay)
195
{
May 28, 2006
May 28, 2006
196
197
198
199
200
DFBResult ret;
void *data;
int pitch;
IDirectFBSurface *surface = overlay->hwdata->surface;
May 29, 2006
May 29, 2006
201
ret = surface->Lock(surface, DSLF_READ | DSLF_WRITE, &data, &pitch);
May 28, 2006
May 28, 2006
202
if (ret) {
May 29, 2006
May 29, 2006
203
SetDirectFBerror("IDirectFBSurface::Lock", ret);
May 28, 2006
May 28, 2006
204
return -1;
205
206
}
May 28, 2006
May 28, 2006
207
208
209
/* Find the pitch and offset values for the overlay */
overlay->pitches[0] = (Uint16) pitch;
overlay->pixels[0] = (Uint8 *) data;
210
May 28, 2006
May 28, 2006
211
switch (overlay->format) {
212
213
case SDL_YV12_OVERLAY:
case SDL_IYUV_OVERLAY:
May 28, 2006
May 28, 2006
214
215
216
217
218
219
220
221
/* Add the two extra planes */
overlay->pitches[1] = overlay->pitches[0] / 2;
overlay->pitches[2] = overlay->pitches[0] / 2;
overlay->pixels[1] =
overlay->pixels[0] + overlay->pitches[0] * overlay->h;
overlay->pixels[2] =
overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2;
break;
222
default:
May 28, 2006
May 28, 2006
223
224
/* Only one plane, no worries */
break;
225
226
}
May 28, 2006
May 28, 2006
227
return 0;
228
229
}
May 28, 2006
May 28, 2006
230
void
May 29, 2006
May 29, 2006
231
DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay)
232
{
May 28, 2006
May 28, 2006
233
IDirectFBSurface *surface = overlay->hwdata->surface;
234
May 28, 2006
May 28, 2006
235
overlay->pixels[0] = overlay->pixels[1] = overlay->pixels[2] = NULL;
236
May 29, 2006
May 29, 2006
237
surface->Unlock(surface);
238
239
}
May 28, 2006
May 28, 2006
240
int
May 29, 2006
May 29, 2006
241
242
DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src,
SDL_Rect * dst)
243
{
May 28, 2006
May 28, 2006
244
245
246
247
248
DFBResult ret;
DFBDisplayLayerConfig conf;
IDirectFBDisplayLayer *primary = HIDDEN->layer;
IDirectFBDisplayLayer *layer = overlay->hwdata->layer;
May 29, 2006
May 29, 2006
249
primary->GetConfiguration(primary, &conf);
May 28, 2006
May 28, 2006
250
May 29, 2006
May 29, 2006
251
252
253
254
255
ret = layer->SetScreenLocation(layer,
dst->x / (float) conf.width,
dst->y / (float) conf.height,
dst->w / (float) conf.width,
dst->h / (float) conf.height);
May 28, 2006
May 28, 2006
256
if (ret) {
May 29, 2006
May 29, 2006
257
SetDirectFBerror("IDirectFBDisplayLayer::SetScreenLocation", ret);
May 28, 2006
May 28, 2006
258
return -1;
259
260
}
May 28, 2006
May 28, 2006
261
return 0;
262
263
}
May 28, 2006
May 28, 2006
264
void
May 29, 2006
May 29, 2006
265
DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay * overlay)
266
{
May 28, 2006
May 28, 2006
267
struct private_yuvhwdata *hwdata;
268
May 28, 2006
May 28, 2006
269
270
271
hwdata = overlay->hwdata;
if (hwdata) {
if (hwdata->surface)
May 29, 2006
May 29, 2006
272
hwdata->surface->Release(hwdata->surface);
273
May 28, 2006
May 28, 2006
274
if (hwdata->layer)
May 29, 2006
May 29, 2006
275
hwdata->layer->Release(hwdata->layer);
276
May 29, 2006
May 29, 2006
277
free(hwdata);
278
279
280
}
}
May 28, 2006
May 28, 2006
281
/* vi: set ts=4 sw=4 expandtab: */