Unexported vlc_thread_set_priority().
[vlc/vlc-skelet.git] / modules / video_output / directfb.c
blobe2f23491723d283129de980dfca3082aeae62b2f
1 /*****************************************************************************
2 * directfb.c: DirectFB video output display method
3 *****************************************************************************
4 * Copyright (C) 2005-2009 the VideoLAN team
6 * Authors: Iuri Diniz <iuri@digizap.com.br>
8 * This code is based in sdl.c and fb.c, thanks for VideoLAN team.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_vout_display.h>
35 #include <vlc_picture_pool.h>
37 #include <directfb.h>
39 /*****************************************************************************
40 * Module descriptor
41 *****************************************************************************/
42 static int Open (vlc_object_t *);
43 static void Close(vlc_object_t *);
45 vlc_module_begin()
46 set_shortname("DirectFB")
47 set_category(CAT_VIDEO)
48 set_subcategory(SUBCAT_VIDEO_VOUT)
49 set_description(N_("DirectFB video output http://www.directfb.org/"))
50 set_capability("vout display", 35)
51 add_shortcut("directfb")
52 set_callbacks(Open, Close)
53 vlc_module_end()
55 /*****************************************************************************
56 * Local prototypes
57 *****************************************************************************/
58 static picture_pool_t *Pool (vout_display_t *, unsigned);
59 static void Display(vout_display_t *, picture_t *, subpicture_t *);
60 static int Control(vout_display_t *, int, va_list);
61 static void Manage (vout_display_t *);
63 /* */
64 static int OpenDisplay (vout_display_t *);
65 static void CloseDisplay(vout_display_t *);
67 /* */
68 struct vout_display_sys_t {
69 /* */
70 IDirectFB *directfb;
71 IDirectFBSurface *primary;
72 DFBSurfacePixelFormat pixel_format;
74 /* */
75 int width;
76 int height;
78 /* */
79 picture_pool_t *pool;
82 /* */
83 static int Open(vlc_object_t *object)
85 vout_display_t *vd = (vout_display_t *)object;
86 vout_display_sys_t *sys;
88 /* Allocate structure */
89 vd->sys = sys = malloc(sizeof(*sys));
90 if (!sys)
91 return VLC_ENOMEM;
93 sys->directfb = NULL;
94 sys->primary = NULL;
95 sys->width = 0;
96 sys->height = 0;
97 sys->pool = NULL;
99 /* Init DirectFB */
100 if (DirectFBInit(NULL,NULL) != DFB_OK) {
101 msg_Err(vd, "Cannot init DirectFB");
102 free(sys);
103 return VLC_EGENERIC;
106 if (OpenDisplay(vd)) {
107 msg_Err(vd, "Cannot create primary surface");
108 Close(VLC_OBJECT(vd));
109 return VLC_EGENERIC;
111 vout_display_DeleteWindow(vd, NULL);
113 /* */
114 video_format_t fmt = vd->fmt;
116 switch (sys->pixel_format) {
117 case DSPF_RGB332:
118 /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */
119 fmt.i_chroma = VLC_CODEC_RGB8;
120 fmt.i_rmask = 0x7 << 5;
121 fmt.i_gmask = 0x7 << 2;
122 fmt.i_bmask = 0x3 << 0;
123 break;
124 case DSPF_RGB16:
125 /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */
126 fmt.i_chroma = VLC_CODEC_RGB16;
127 fmt.i_rmask = 0x1f << 11;
128 fmt.i_gmask = 0x3f << 5;
129 fmt.i_bmask = 0x1f << 0;
130 break;
131 case DSPF_RGB24:
132 /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */
133 fmt.i_chroma = VLC_CODEC_RGB24;
134 fmt.i_rmask = 0xff << 16;
135 fmt.i_gmask = 0xff << 8;
136 fmt.i_bmask = 0xff << 0;
137 break;
138 case DSPF_RGB32:
139 /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */
140 fmt.i_chroma = VLC_CODEC_RGB32;
141 fmt.i_rmask = 0xff << 16;
142 fmt.i_gmask = 0xff << 8;
143 fmt.i_bmask = 0xff << 0;
144 break;
145 default:
146 msg_Err(vd, "unknown screen depth %i", sys->pixel_format);
147 Close(VLC_OBJECT(vd));
148 return VLC_EGENERIC;
151 fmt.i_width = sys->width;
152 fmt.i_height = sys->height;
154 /* */
155 vout_display_info_t info = vd->info;
156 info.has_hide_mouse = true;
158 /* */
159 vd->fmt = fmt;
160 vd->info = info;
161 vd->pool = Pool;
162 vd->prepare = NULL;
163 vd->display = Display;
164 vd->control = Control;
165 vd->manage = Manage;
167 /* */
168 vout_display_SendEventFullscreen(vd, true);
169 vout_display_SendEventDisplaySize(vd, fmt.i_width, fmt.i_height, true);
170 return VLC_SUCCESS;
173 static void Close(vlc_object_t *object)
175 vout_display_t *vd = (vout_display_t *)object;
176 vout_display_sys_t *sys = vd->sys;
178 if (sys->pool)
179 picture_pool_Delete(sys->pool);
181 CloseDisplay(vd);
182 free(sys);
185 /* */
186 static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
188 vout_display_sys_t *sys = vd->sys;
190 if (!sys->pool)
191 sys->pool = picture_pool_NewFromFormat(&vd->fmt, count);
192 return sys->pool;
195 static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
197 vout_display_sys_t *sys = vd->sys;
199 IDirectFBSurface *primary = sys->primary;
201 void *pixels;
202 int pitch;
203 if (primary->Lock(primary, DSLF_WRITE, &pixels, &pitch) == DFB_OK) {
204 picture_resource_t rsc;
206 memset(&rsc, 0, sizeof(rsc));
207 rsc.p[0].p_pixels = pixels;
208 rsc.p[0].i_lines = sys->height;
209 rsc.p[0].i_pitch = pitch;
211 picture_t *direct = picture_NewFromResource(&vd->fmt, &rsc);
212 if (direct) {
213 picture_Copy(direct, picture);
214 picture_Release(direct);
217 if (primary->Unlock(primary) == DFB_OK)
218 primary->Flip(primary, NULL, 0);
220 picture_Release(picture);
221 VLC_UNUSED(subpicture);
224 static int Control(vout_display_t *vd, int query, va_list args)
226 switch (query) {
227 case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: {
228 const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *);
229 if (cfg->display.width != vd->fmt.i_width ||
230 cfg->display.height != vd->fmt.i_height)
231 return VLC_EGENERIC;
232 return VLC_SUCCESS;
234 default:
235 msg_Err(vd, "Unsupported query in vout display directfb");
236 return VLC_EGENERIC;
240 static void Manage (vout_display_t *vd)
242 VLC_UNUSED(vd);
245 static int OpenDisplay(vout_display_t *vd)
247 vout_display_sys_t *sys = vd->sys;
249 DFBSurfaceDescription dsc;
250 /*dsc.flags = DSDESC_CAPS | DSDESC_HEIGHT | DSDESC_WIDTH;*/
251 dsc.flags = DSDESC_CAPS;
252 dsc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING;
253 /*dsc.width = 352;*/
254 /*dsc.height = 240;*/
256 IDirectFB *directfb = NULL;
257 if (DirectFBCreate(&directfb) != DFB_OK || !directfb)
258 return VLC_EGENERIC;
259 sys->directfb = directfb;
261 IDirectFBSurface *primary = NULL;
262 if (directfb->CreateSurface(directfb, &dsc, &primary) || !primary)
263 return VLC_EGENERIC;
264 sys->primary = primary;
266 primary->GetSize(primary, &sys->width, &sys->height);
267 primary->GetPixelFormat(primary, &sys->pixel_format);
268 primary->FillRectangle(primary, 0, 0, sys->width, sys->height);
269 primary->Flip(primary, NULL, 0);
271 return VLC_SUCCESS;
274 static void CloseDisplay(vout_display_t *vd)
276 vout_display_sys_t *sys = vd->sys;
278 IDirectFBSurface *primary = sys->primary;
279 if (primary)
280 primary->Release(primary);
282 IDirectFB *directfb = sys->directfb;
283 if (directfb)
284 directfb->Release(directfb);