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 it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser 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);
64 struct vout_display_sys_t {
66 IDirectFBSurface *primary;
74 static int Open(vlc_object_t *object)
76 vout_display_t *vd = (vout_display_t *)object;
77 vout_display_sys_t *sys;
79 if (vout_display_IsWindowed(vd))
82 vd->sys = sys = calloc(1, sizeof(*sys));
86 if (DirectFBInit(NULL,NULL) != DFB_OK) {
87 msg_Err(vd, "Cannot init DirectFB");
92 DFBSurfaceDescription dsc;
93 dsc.flags = DSDESC_CAPS;
94 dsc.caps = DSCAPS_PRIMARY | DSCAPS_TRIPLE;
96 dsc.flags |= DSDESC_HEIGHT | DSDESC_WIDTH;
101 IDirectFB *directfb = NULL;
102 if (DirectFBCreate(&directfb) != DFB_OK || !directfb)
104 sys->directfb = directfb;
106 IDirectFBSurface *primary = NULL;
107 if (directfb->CreateSurface(directfb, &dsc, &primary) || !primary)
109 sys->primary = primary;
115 primary->GetSize(primary, &width, &height);
119 video_format_ApplyRotation(&fmt, &vd->fmt);
121 DFBSurfacePixelFormat pixel_format;
122 sys->primary->GetPixelFormat(sys->primary, &pixel_format);
123 switch (pixel_format) {
125 fmt.i_chroma = VLC_CODEC_RGB8;
126 fmt.i_rmask = 0x7 << 5;
127 fmt.i_gmask = 0x7 << 2;
128 fmt.i_bmask = 0x3 << 0;
130 case DSPF_RGB16: fmt.i_chroma = VLC_CODEC_RGB16; break;
131 case DSPF_RGB24: fmt.i_chroma = VLC_CODEC_RGB24; break;
132 case DSPF_RGB32: fmt.i_chroma = VLC_CODEC_RGB32; break;
134 msg_Err(vd, "unknown screen depth %i", pixel_format);
135 Close(VLC_OBJECT(vd));
139 video_format_FixRgb(&fmt);
142 fmt.i_height = height;
143 fmt.i_visible_width = width;
144 fmt.i_visible_height = height;
147 vout_display_info_t info = vd->info;
148 info.has_hide_mouse = true;
155 vd->display = Display;
156 vd->control = Control;
160 vout_display_SendEventFullscreen(vd, true);
161 vout_display_SendEventDisplaySize(vd, fmt.i_width, fmt.i_height);
165 msg_Err(vd, "Cannot create primary surface");
166 Close(VLC_OBJECT(vd));
170 static void Close(vlc_object_t *object)
172 vout_display_t *vd = (vout_display_t *)object;
173 vout_display_sys_t *sys = vd->sys;
176 picture_pool_Release(sys->pool);
178 IDirectFBSurface *primary = sys->primary;
180 primary->Release(primary);
182 IDirectFB *directfb = sys->directfb;
184 directfb->Release(directfb);
189 struct picture_sys_t {
190 vout_display_sys_t *sys;
193 static int Lock(picture_t *pic)
195 vout_display_sys_t *sys = pic->p_sys->sys;
196 return sys->pics[sys->idx] == pic ? VLC_SUCCESS : VLC_EGENERIC;
200 static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
203 vout_display_sys_t *sys = vd->sys;
204 IDirectFBSurface *primary = sys->primary;
207 picture_resource_t rsc;
208 memset(&rsc, 0, sizeof(rsc));
209 rsc.p[0].i_lines = vd->fmt.i_height;
211 for (int i = 0; i < 3; i++) {
212 rsc.p_sys = malloc(sizeof(*rsc.p_sys));
215 rsc.p_sys->sys = sys;
218 if (primary->Lock(primary, DSLF_WRITE, &pixels, &pitch) != DFB_OK)
221 rsc.p[0].i_pitch = pitch;
222 rsc.p[0].p_pixels = pixels;
223 primary->Unlock(primary);
224 primary->Flip(primary, NULL, 0);
226 sys->pics[i] = picture_NewFromResource(&vd->fmt, &rsc);
233 picture_pool_configuration_t cfg = {
235 .picture = sys->pics,
240 sys->pool = picture_pool_NewExtended(&cfg);
245 for (int i = 0; i < 2; i++) {
247 free(sys->pics[i]->p_sys);
248 picture_Release(sys->pics[i]);
255 static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
257 vout_display_sys_t *sys = vd->sys;
259 IDirectFBSurface *primary = sys->primary;
260 primary->Flip(primary, NULL, 0);
263 picture_Release(picture);
265 VLC_UNUSED(subpicture);
268 static int Control(vout_display_t *vd, int query, va_list args)
270 (void) vd; (void) query; (void) args;