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

Latest commit

 

History

History
289 lines (235 loc) · 7.59 KB

SDL_DirectFB_yuv.c

File metadata and controls

289 lines (235 loc) · 7.59 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 = {
Jul 10, 2006
Jul 10, 2006
33
34
35
36
DirectFB_LockYUVOverlay,
DirectFB_UnlockYUVOverlay,
DirectFB_DisplayYUVOverlay,
DirectFB_FreeYUVOverlay
37
38
};
Jul 10, 2006
Jul 10, 2006
39
40
41
struct private_yuvhwdata
{
DFBDisplayLayerID layer_id;
42
Jul 10, 2006
Jul 10, 2006
43
44
IDirectFBDisplayLayer *layer;
IDirectFBSurface *surface;
45
Jul 10, 2006
Jul 10, 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
Jul 10, 2006
Jul 10, 2006
52
53
enum_layers_callback(DFBDisplayLayerID id,
DFBDisplayLayerDescription desc, void *data)
54
{
Jul 10, 2006
Jul 10, 2006
55
struct private_yuvhwdata *hwdata = (struct private_yuvhwdata *) data;
56
Jul 10, 2006
Jul 10, 2006
57
58
59
/* we don't want the primary */
if (id == DLID_PRIMARY)
return DFENUM_OK;
60
Jul 10, 2006
Jul 10, 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
Jul 10, 2006
Jul 10, 2006
65
return DFENUM_CANCEL;
66
67
}
Jul 10, 2006
Jul 10, 2006
68
return DFENUM_OK;
69
70
71
}
Jul 10, 2006
Jul 10, 2006
72
73
74
static DFBResult
CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata,
int width, int height, Uint32 format)
75
{
Jul 10, 2006
Jul 10, 2006
76
77
78
79
80
81
82
83
84
DFBResult ret;
IDirectFB *dfb = HIDDEN->dfb;
IDirectFBDisplayLayer *layer;
DFBDisplayLayerConfig conf;
ret = dfb->EnumDisplayLayers(dfb, enum_layers_callback, hwdata);
if (ret) {
SetDirectFBerror("IDirectFB::EnumDisplayLayers", ret);
return ret;
85
86
}
Jul 10, 2006
Jul 10, 2006
87
88
if (!hwdata->layer_id)
return DFB_UNSUPPORTED;
89
Jul 10, 2006
Jul 10, 2006
90
91
92
93
ret = dfb->GetDisplayLayer(dfb, hwdata->layer_id, &layer);
if (ret) {
SetDirectFBerror("IDirectFB::GetDisplayLayer", ret);
return ret;
94
95
}
Jul 10, 2006
Jul 10, 2006
96
97
98
conf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
conf.width = width;
conf.height = height;
99
Jul 10, 2006
Jul 10, 2006
100
switch (format) {
101
case SDL_YV12_OVERLAY:
Jul 10, 2006
Jul 10, 2006
102
103
conf.pixelformat = DSPF_YV12;
break;
104
case SDL_IYUV_OVERLAY:
Jul 10, 2006
Jul 10, 2006
105
106
conf.pixelformat = DSPF_I420;
break;
107
case SDL_YUY2_OVERLAY:
Jul 10, 2006
Jul 10, 2006
108
109
conf.pixelformat = DSPF_YUY2;
break;
110
case SDL_UYVY_OVERLAY:
Jul 10, 2006
Jul 10, 2006
111
112
conf.pixelformat = DSPF_UYVY;
break;
113
default:
Jul 10, 2006
Jul 10, 2006
114
115
116
fprintf(stderr, "SDL_DirectFB: Unsupported YUV format (0x%08x)!\n",
format);
break;
117
118
}
Feb 20, 2007
Feb 20, 2007
119
120
121
122
123
124
125
126
/* Need to set coop level or newer DirectFB versions will fail here. */
ret = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
if (ret) {
SetDirectFBError("IDirectFBDisplayLayer::SetCooperativeLevel() failed", ret);
layer->Release(layer);
return ret;
}
Jul 10, 2006
Jul 10, 2006
127
128
129
130
131
ret = layer->SetConfiguration(layer, &conf);
if (ret) {
SetDirectFBerror("IDirectFBDisplayLayer::SetConfiguration", ret);
layer->Release(layer);
return ret;
132
133
}
Jul 10, 2006
Jul 10, 2006
134
135
136
137
138
ret = layer->GetSurface(layer, &hwdata->surface);
if (ret) {
SetDirectFBerror("IDirectFBDisplayLayer::GetSurface", ret);
layer->Release(layer);
return ret;
139
140
}
Jul 10, 2006
Jul 10, 2006
141
hwdata->layer = layer;
142
Jul 10, 2006
Jul 10, 2006
143
return DFB_OK;
144
145
}
Jul 10, 2006
Jul 10, 2006
146
147
148
SDL_Overlay *
DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format,
SDL_Surface * display)
149
{
Jul 10, 2006
Jul 10, 2006
150
151
152
153
154
155
156
157
SDL_Overlay *overlay;
struct private_yuvhwdata *hwdata;
/* Create the overlay structure */
overlay = SDL_calloc(1, sizeof(SDL_Overlay));
if (!overlay) {
SDL_OutOfMemory();
return NULL;
158
}
Jul 10, 2006
Jul 10, 2006
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* 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 */
hwdata = SDL_calloc(1, sizeof(struct private_yuvhwdata));
overlay->hwdata = hwdata;
if (!hwdata) {
SDL_OutOfMemory();
SDL_FreeYUVOverlay(overlay);
return NULL;
175
176
}
Jul 10, 2006
Jul 10, 2006
177
178
179
if (CreateYUVSurface(this, hwdata, width, height, format)) {
SDL_FreeYUVOverlay(overlay);
return NULL;
180
181
}
Jul 10, 2006
Jul 10, 2006
182
overlay->hw_overlay = 1;
183
Jul 10, 2006
Jul 10, 2006
184
185
186
187
/* Set up the plane pointers */
overlay->pitches = hwdata->pitches;
overlay->pixels = hwdata->planes;
switch (format) {
188
189
case SDL_YV12_OVERLAY:
case SDL_IYUV_OVERLAY:
Jul 10, 2006
Jul 10, 2006
190
191
overlay->planes = 3;
break;
192
default:
Jul 10, 2006
Jul 10, 2006
193
194
overlay->planes = 1;
break;
195
196
}
Jul 10, 2006
Jul 10, 2006
197
198
/* We're all done.. */
return overlay;
199
200
}
Jul 10, 2006
Jul 10, 2006
201
202
int
DirectFB_LockYUVOverlay(_THIS, SDL_Overlay * overlay)
203
{
Jul 10, 2006
Jul 10, 2006
204
205
206
207
208
209
210
211
212
DFBResult ret;
void *data;
int pitch;
IDirectFBSurface *surface = overlay->hwdata->surface;
ret = surface->Lock(surface, DSLF_READ | DSLF_WRITE, &data, &pitch);
if (ret) {
SetDirectFBerror("IDirectFBSurface::Lock", ret);
return -1;
213
214
}
Jul 10, 2006
Jul 10, 2006
215
216
217
/* Find the pitch and offset values for the overlay */
overlay->pitches[0] = (Uint16) pitch;
overlay->pixels[0] = (Uint8 *) data;
218
Jul 10, 2006
Jul 10, 2006
219
switch (overlay->format) {
220
221
case SDL_YV12_OVERLAY:
case SDL_IYUV_OVERLAY:
Jul 10, 2006
Jul 10, 2006
222
223
224
225
226
227
228
229
/* 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;
230
default:
Jul 10, 2006
Jul 10, 2006
231
232
/* Only one plane, no worries */
break;
233
234
}
Jul 10, 2006
Jul 10, 2006
235
return 0;
236
237
}
Jul 10, 2006
Jul 10, 2006
238
239
void
DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay)
240
{
Jul 10, 2006
Jul 10, 2006
241
IDirectFBSurface *surface = overlay->hwdata->surface;
242
Jul 10, 2006
Jul 10, 2006
243
overlay->pixels[0] = overlay->pixels[1] = overlay->pixels[2] = NULL;
244
Jul 10, 2006
Jul 10, 2006
245
surface->Unlock(surface);
246
247
}
Jul 10, 2006
Jul 10, 2006
248
249
250
int
DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src,
SDL_Rect * dst)
251
{
Jul 10, 2006
Jul 10, 2006
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
DFBResult ret;
DFBDisplayLayerConfig conf;
IDirectFBDisplayLayer *primary = HIDDEN->layer;
IDirectFBDisplayLayer *layer = overlay->hwdata->layer;
primary->GetConfiguration(primary, &conf);
ret = layer->SetScreenLocation(layer,
dst->x / (float) conf.width,
dst->y / (float) conf.height,
dst->w / (float) conf.width,
dst->h / (float) conf.height);
if (ret) {
SetDirectFBerror("IDirectFBDisplayLayer::SetScreenLocation", ret);
return -1;
267
268
}
Jul 10, 2006
Jul 10, 2006
269
return 0;
270
271
}
Jul 10, 2006
Jul 10, 2006
272
273
void
DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay * overlay)
274
{
Jul 10, 2006
Jul 10, 2006
275
struct private_yuvhwdata *hwdata;
276
Jul 10, 2006
Jul 10, 2006
277
278
279
280
hwdata = overlay->hwdata;
if (hwdata) {
if (hwdata->surface)
hwdata->surface->Release(hwdata->surface);
281
Jul 10, 2006
Jul 10, 2006
282
283
if (hwdata->layer)
hwdata->layer->Release(hwdata->layer);
284
Jul 10, 2006
Jul 10, 2006
285
free(hwdata);
286
287
288
}
}
Jul 10, 2006
Jul 10, 2006
289
/* vi: set ts=4 sw=4 expandtab: */