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 /*****************************************************************************
27 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_vout_display.h>
35 #include <vlc_picture_pool.h>
39 /*****************************************************************************
41 *****************************************************************************/
42 static int Open (vlc_object_t
*);
43 static void Close(vlc_object_t
*);
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
)
55 /*****************************************************************************
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
*);
64 static int OpenDisplay (vout_display_t
*);
65 static void CloseDisplay(vout_display_t
*);
68 struct vout_display_sys_t
{
71 IDirectFBSurface
*primary
;
72 DFBSurfacePixelFormat pixel_format
;
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
));
100 if (DirectFBInit(NULL
,NULL
) != DFB_OK
) {
101 msg_Err(vd
, "Cannot init DirectFB");
106 if (OpenDisplay(vd
)) {
107 msg_Err(vd
, "Cannot create primary surface");
108 Close(VLC_OBJECT(vd
));
111 vout_display_DeleteWindow(vd
, NULL
);
114 video_format_t fmt
= vd
->fmt
;
116 switch (sys
->pixel_format
) {
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;
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;
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;
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;
146 msg_Err(vd
, "unknown screen depth %i", sys
->pixel_format
);
147 Close(VLC_OBJECT(vd
));
151 fmt
.i_width
= sys
->width
;
152 fmt
.i_height
= sys
->height
;
155 vout_display_info_t info
= vd
->info
;
156 info
.has_hide_mouse
= true;
163 vd
->display
= Display
;
164 vd
->control
= Control
;
168 vout_display_SendEventFullscreen(vd
, true);
169 vout_display_SendEventDisplaySize(vd
, fmt
.i_width
, fmt
.i_height
, true);
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
;
179 picture_pool_Delete(sys
->pool
);
186 static picture_pool_t
*Pool(vout_display_t
*vd
, unsigned count
)
188 vout_display_sys_t
*sys
= vd
->sys
;
191 sys
->pool
= picture_pool_NewFromFormat(&vd
->fmt
, count
);
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
;
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
);
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
)
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
)
235 msg_Err(vd
, "Unsupported query in vout display directfb");
240 static void Manage (vout_display_t
*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
;
254 /*dsc.height = 240;*/
256 IDirectFB
*directfb
= NULL
;
257 if (DirectFBCreate(&directfb
) != DFB_OK
|| !directfb
)
259 sys
->directfb
= directfb
;
261 IDirectFBSurface
*primary
= NULL
;
262 if (directfb
->CreateSurface(directfb
, &dsc
, &primary
) || !primary
)
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);
274 static void CloseDisplay(vout_display_t
*vd
)
276 vout_display_sys_t
*sys
= vd
->sys
;
278 IDirectFBSurface
*primary
= sys
->primary
;
280 primary
->Release(primary
);
282 IDirectFB
*directfb
= sys
->directfb
;
284 directfb
->Release(directfb
);