1 /*****************************************************************************
2 * directfb.c: DirectFB video output display method
3 *****************************************************************************
4 * Copyright © 2005-2009 VLC authors and VideoLAN
6 * Authors: Iuri Diniz <iuridiniz@gmail.com>
7 * Laurent Aimar <fenrir@videolan.org>
9 * This code is based in sdl.c and fb.c, thanks for VideoLAN team.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_vout_display.h>
36 #include <vlc_picture_pool.h>
40 /*****************************************************************************
42 *****************************************************************************/
43 static int Open (vlc_object_t *);
44 static void Close(vlc_object_t *);
47 set_shortname("DirectFB")
48 set_category(CAT_VIDEO)
49 set_subcategory(SUBCAT_VIDEO_VOUT)
50 set_description(N_("DirectFB video output http://www.directfb.org/"))
51 set_capability("vout display", 35)
52 add_shortcut("directfb")
53 set_callbacks(Open, Close)
56 /*****************************************************************************
58 *****************************************************************************/
59 static picture_pool_t *Pool (vout_display_t *, unsigned);
60 static void Display(vout_display_t *, picture_t *, subpicture_t *);
61 static int Control(vout_display_t *, int, va_list);
62 static void Manage (vout_display_t *);
65 static int OpenDisplay (vout_display_t *);
66 static void CloseDisplay(vout_display_t *);
69 struct vout_display_sys_t {
72 IDirectFBSurface *primary;
73 DFBSurfacePixelFormat pixel_format;
84 static int Open(vlc_object_t *object)
86 vout_display_t *vd = (vout_display_t *)object;
87 vout_display_sys_t *sys;
89 /* Allocate structure */
90 vd->sys = sys = malloc(sizeof(*sys));
101 if (DirectFBInit(NULL,NULL) != DFB_OK) {
102 msg_Err(vd, "Cannot init DirectFB");
107 if (OpenDisplay(vd)) {
108 msg_Err(vd, "Cannot create primary surface");
109 Close(VLC_OBJECT(vd));
112 vout_display_DeleteWindow(vd, NULL);
115 video_format_t fmt = vd->fmt;
117 switch (sys->pixel_format) {
119 /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */
120 fmt.i_chroma = VLC_CODEC_RGB8;
121 fmt.i_rmask = 0x7 << 5;
122 fmt.i_gmask = 0x7 << 2;
123 fmt.i_bmask = 0x3 << 0;
126 /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */
127 fmt.i_chroma = VLC_CODEC_RGB16;
128 fmt.i_rmask = 0x1f << 11;
129 fmt.i_gmask = 0x3f << 5;
130 fmt.i_bmask = 0x1f << 0;
133 /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */
134 fmt.i_chroma = VLC_CODEC_RGB24;
135 fmt.i_rmask = 0xff << 16;
136 fmt.i_gmask = 0xff << 8;
137 fmt.i_bmask = 0xff << 0;
140 /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */
141 fmt.i_chroma = VLC_CODEC_RGB32;
142 fmt.i_rmask = 0xff << 16;
143 fmt.i_gmask = 0xff << 8;
144 fmt.i_bmask = 0xff << 0;
147 msg_Err(vd, "unknown screen depth %i", sys->pixel_format);
148 Close(VLC_OBJECT(vd));
152 fmt.i_width = sys->width;
153 fmt.i_height = sys->height;
156 vout_display_info_t info = vd->info;
157 info.has_hide_mouse = true;
164 vd->display = Display;
165 vd->control = Control;
169 vout_display_SendEventFullscreen(vd, true);
170 vout_display_SendEventDisplaySize(vd, fmt.i_width, fmt.i_height, true);
174 static void Close(vlc_object_t *object)
176 vout_display_t *vd = (vout_display_t *)object;
177 vout_display_sys_t *sys = vd->sys;
180 picture_pool_Delete(sys->pool);
187 static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
189 vout_display_sys_t *sys = vd->sys;
192 sys->pool = picture_pool_NewFromFormat(&vd->fmt, count);
196 static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
198 vout_display_sys_t *sys = vd->sys;
200 IDirectFBSurface *primary = sys->primary;
204 if (primary->Lock(primary, DSLF_WRITE, &pixels, &pitch) == DFB_OK) {
205 picture_resource_t rsc;
207 memset(&rsc, 0, sizeof(rsc));
208 rsc.p[0].p_pixels = pixels;
209 rsc.p[0].i_lines = sys->height;
210 rsc.p[0].i_pitch = pitch;
212 picture_t *direct = picture_NewFromResource(&vd->fmt, &rsc);
214 picture_Copy(direct, picture);
215 picture_Release(direct);
218 if (primary->Unlock(primary) == DFB_OK)
219 primary->Flip(primary, NULL, 0);
221 picture_Release(picture);
222 VLC_UNUSED(subpicture);
225 static int Control(vout_display_t *vd, int query, va_list args)
228 case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: {
229 const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *);
230 if (cfg->display.width != vd->fmt.i_width ||
231 cfg->display.height != vd->fmt.i_height)
236 msg_Err(vd, "Unsupported query in vout display directfb");
241 static void Manage (vout_display_t *vd)
246 static int OpenDisplay(vout_display_t *vd)
248 vout_display_sys_t *sys = vd->sys;
250 DFBSurfaceDescription dsc;
251 /*dsc.flags = DSDESC_CAPS | DSDESC_HEIGHT | DSDESC_WIDTH;*/
252 dsc.flags = DSDESC_CAPS;
253 dsc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING;
255 /*dsc.height = 240;*/
257 IDirectFB *directfb = NULL;
258 if (DirectFBCreate(&directfb) != DFB_OK || !directfb)
260 sys->directfb = directfb;
262 IDirectFBSurface *primary = NULL;
263 if (directfb->CreateSurface(directfb, &dsc, &primary) || !primary)
265 sys->primary = primary;
267 primary->GetSize(primary, &sys->width, &sys->height);
268 primary->GetPixelFormat(primary, &sys->pixel_format);
269 primary->FillRectangle(primary, 0, 0, sys->width, sys->height);
270 primary->Flip(primary, NULL, 0);
275 static void CloseDisplay(vout_display_t *vd)
277 vout_display_sys_t *sys = vd->sys;
279 IDirectFBSurface *primary = sys->primary;
281 primary->Release(primary);
283 IDirectFB *directfb = sys->directfb;
285 directfb->Release(directfb);