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 vd
->sys
= sys
= calloc(1, sizeof(*sys
));
83 if (DirectFBInit(NULL
,NULL
) != DFB_OK
) {
84 msg_Err(vd
, "Cannot init DirectFB");
89 DFBSurfaceDescription dsc
;
90 dsc
.flags
= DSDESC_CAPS
;
91 dsc
.caps
= DSCAPS_PRIMARY
| DSCAPS_TRIPLE
;
93 dsc
.flags
|= DSDESC_HEIGHT
| DSDESC_WIDTH
;
98 IDirectFB
*directfb
= NULL
;
99 if (DirectFBCreate(&directfb
) != DFB_OK
|| !directfb
)
101 sys
->directfb
= directfb
;
103 IDirectFBSurface
*primary
= NULL
;
104 if (directfb
->CreateSurface(directfb
, &dsc
, &primary
) || !primary
)
106 sys
->primary
= primary
;
112 primary
->GetSize(primary
, &width
, &height
);
114 vout_display_DeleteWindow(vd
, NULL
);
118 video_format_ApplyRotation(&fmt
, &vd
->fmt
);
120 DFBSurfacePixelFormat pixel_format
;
121 sys
->primary
->GetPixelFormat(sys
->primary
, &pixel_format
);
122 switch (pixel_format
) {
124 fmt
.i_chroma
= VLC_CODEC_RGB8
;
125 fmt
.i_rmask
= 0x7 << 5;
126 fmt
.i_gmask
= 0x7 << 2;
127 fmt
.i_bmask
= 0x3 << 0;
129 case DSPF_RGB16
: fmt
.i_chroma
= VLC_CODEC_RGB16
; break;
130 case DSPF_RGB24
: fmt
.i_chroma
= VLC_CODEC_RGB24
; break;
131 case DSPF_RGB32
: fmt
.i_chroma
= VLC_CODEC_RGB32
; break;
133 msg_Err(vd
, "unknown screen depth %i", pixel_format
);
134 Close(VLC_OBJECT(vd
));
138 video_format_FixRgb(&fmt
);
141 fmt
.i_height
= height
;
142 fmt
.i_visible_width
= width
;
143 fmt
.i_visible_height
= height
;
146 vout_display_info_t info
= vd
->info
;
147 info
.has_hide_mouse
= true;
154 vd
->display
= Display
;
155 vd
->control
= Control
;
159 vout_display_SendEventFullscreen(vd
, true);
160 vout_display_SendEventDisplaySize(vd
, fmt
.i_width
, fmt
.i_height
, true);
164 msg_Err(vd
, "Cannot create primary surface");
165 Close(VLC_OBJECT(vd
));
169 static void Close(vlc_object_t
*object
)
171 vout_display_t
*vd
= (vout_display_t
*)object
;
172 vout_display_sys_t
*sys
= vd
->sys
;
175 picture_pool_Delete(sys
->pool
);
177 IDirectFBSurface
*primary
= sys
->primary
;
179 primary
->Release(primary
);
181 IDirectFB
*directfb
= sys
->directfb
;
183 directfb
->Release(directfb
);
188 struct picture_sys_t
{
189 vout_display_sys_t
*sys
;
192 static int Lock(picture_t
*pic
)
194 vout_display_sys_t
*sys
= pic
->p_sys
->sys
;
195 return sys
->pics
[sys
->idx
] == pic
? VLC_SUCCESS
: VLC_EGENERIC
;
199 static picture_pool_t
*Pool(vout_display_t
*vd
, unsigned count
)
202 vout_display_sys_t
*sys
= vd
->sys
;
203 IDirectFBSurface
*primary
= sys
->primary
;
206 picture_resource_t rsc
;
207 memset(&rsc
, 0, sizeof(rsc
));
208 rsc
.p
[0].i_lines
= vd
->fmt
.i_height
;
210 for (int i
= 0; i
< 3; i
++) {
211 rsc
.p_sys
= malloc(sizeof(*rsc
.p_sys
));
214 rsc
.p_sys
->sys
= sys
;
217 if (primary
->Lock(primary
, DSLF_WRITE
, &pixels
, &pitch
) != DFB_OK
)
220 rsc
.p
[0].i_pitch
= pitch
;
221 rsc
.p
[0].p_pixels
= pixels
;
222 primary
->Unlock(primary
);
223 primary
->Flip(primary
, NULL
, 0);
225 sys
->pics
[i
] = picture_NewFromResource(&vd
->fmt
, &rsc
);
232 picture_pool_configuration_t cfg
= {
234 .picture
= sys
->pics
,
239 sys
->pool
= picture_pool_NewExtended(&cfg
);
244 for (int i
= 0; i
< 2; i
++) {
246 free(sys
->pics
[i
]->p_sys
);
247 picture_Release(sys
->pics
[i
]);
254 static void Display(vout_display_t
*vd
, picture_t
*picture
, subpicture_t
*subpicture
)
256 vout_display_sys_t
*sys
= vd
->sys
;
258 IDirectFBSurface
*primary
= sys
->primary
;
259 primary
->Flip(primary
, NULL
, 0);
262 picture_Release(picture
);
264 VLC_UNUSED(subpicture
);
267 static int Control(vout_display_t
*vd
, int query
, va_list args
)
270 case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE
: {
271 const vout_display_cfg_t
*cfg
= va_arg(args
, const vout_display_cfg_t
*);
272 if (cfg
->display
.width
!= vd
->fmt
.i_width
||
273 cfg
->display
.height
!= vd
->fmt
.i_height
)
278 msg_Err(vd
, "Unsupported query in vout display directfb");