]> git.sesse.net Git - vlc/blob - modules/video_output/directfb.c
DirectFB: Copyright update
[vlc] / modules / video_output / directfb.c
1 /*****************************************************************************
2  * directfb.c: DirectFB video output display method
3  *****************************************************************************
4  * Copyright © 2005-2009 VLC authors and VideoLAN
5  *
6  * Authors: Iuri Diniz <iuridiniz@gmail.com>
7  *          Laurent Aimar <fenrir@videolan.org>
8  *
9  * This code is based in sdl.c and fb.c, thanks for VideoLAN team.
10  *
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.
15  *
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.
20  *
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  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_vout_display.h>
36 #include <vlc_picture_pool.h>
37
38 #include <directfb.h>
39
40 /*****************************************************************************
41  * Module descriptor
42  *****************************************************************************/
43 static int  Open (vlc_object_t *);
44 static void Close(vlc_object_t *);
45
46 vlc_module_begin()
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)
54 vlc_module_end()
55
56 /*****************************************************************************
57  * Local prototypes
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 *);
63
64 /* */
65 static int  OpenDisplay (vout_display_t *);
66 static void CloseDisplay(vout_display_t *);
67
68 /* */
69 struct vout_display_sys_t {
70     /* */
71     IDirectFB             *directfb;
72     IDirectFBSurface      *primary;
73     DFBSurfacePixelFormat pixel_format;
74
75     /* */
76     int width;
77     int height;
78
79     /* */
80     picture_pool_t *pool;
81 };
82
83 /* */
84 static int Open(vlc_object_t *object)
85 {
86     vout_display_t *vd = (vout_display_t *)object;
87     vout_display_sys_t *sys;
88
89     /* Allocate structure */
90     vd->sys = sys = malloc(sizeof(*sys));
91     if (!sys)
92         return VLC_ENOMEM;
93
94     sys->directfb = NULL;
95     sys->primary  = NULL;
96     sys->width    = 0;
97     sys->height   = 0;
98     sys->pool     = NULL;
99
100     /* Init DirectFB */
101     if (DirectFBInit(NULL,NULL) != DFB_OK) {
102         msg_Err(vd, "Cannot init DirectFB");
103         free(sys);
104         return VLC_EGENERIC;
105     }
106
107     if (OpenDisplay(vd)) {
108         msg_Err(vd, "Cannot create primary surface");
109         Close(VLC_OBJECT(vd));
110         return VLC_EGENERIC;
111     }
112     vout_display_DeleteWindow(vd, NULL);
113
114     /* */
115     video_format_t fmt = vd->fmt;
116
117     switch (sys->pixel_format) {
118     case DSPF_RGB332:
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;
124         break;
125     case DSPF_RGB16:
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;
131         break;
132     case DSPF_RGB24:
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;
138         break;
139     case DSPF_RGB32:
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;
145         break;
146     default:
147         msg_Err(vd, "unknown screen depth %i", sys->pixel_format);
148         Close(VLC_OBJECT(vd));
149         return VLC_EGENERIC;
150     }
151
152     fmt.i_width  = sys->width;
153     fmt.i_height = sys->height;
154
155     /* */
156     vout_display_info_t info = vd->info;
157     info.has_hide_mouse = true;
158
159     /* */
160     vd->fmt     = fmt;
161     vd->info    = info;
162     vd->pool    = Pool;
163     vd->prepare = NULL;
164     vd->display = Display;
165     vd->control = Control;
166     vd->manage  = Manage;
167
168     /* */
169     vout_display_SendEventFullscreen(vd, true);
170     vout_display_SendEventDisplaySize(vd, fmt.i_width, fmt.i_height, true);
171     return VLC_SUCCESS;
172 }
173
174 static void Close(vlc_object_t *object)
175 {
176     vout_display_t *vd = (vout_display_t *)object;
177     vout_display_sys_t *sys = vd->sys;
178
179     if (sys->pool)
180         picture_pool_Delete(sys->pool);
181
182     CloseDisplay(vd);
183     free(sys);
184 }
185
186 /* */
187 static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
188 {
189     vout_display_sys_t *sys = vd->sys;
190
191     if (!sys->pool)
192         sys->pool = picture_pool_NewFromFormat(&vd->fmt, count);
193     return sys->pool;
194 }
195
196 static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
197 {
198     vout_display_sys_t *sys = vd->sys;
199
200     IDirectFBSurface *primary = sys->primary;
201
202     void *pixels;
203     int  pitch;
204     if (primary->Lock(primary, DSLF_WRITE, &pixels, &pitch) == DFB_OK) {
205         picture_resource_t rsc;
206
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;
211
212         picture_t *direct = picture_NewFromResource(&vd->fmt, &rsc);
213         if (direct) {
214             picture_Copy(direct, picture);
215             picture_Release(direct);
216         }
217
218         if (primary->Unlock(primary) == DFB_OK)
219             primary->Flip(primary, NULL, 0);
220     }
221     picture_Release(picture);
222     VLC_UNUSED(subpicture);
223 }
224
225 static int Control(vout_display_t *vd, int query, va_list args)
226 {
227     switch (query) {
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)
232             return VLC_EGENERIC;
233         return VLC_SUCCESS;
234     }
235     default:
236         msg_Err(vd, "Unsupported query in vout display directfb");
237         return VLC_EGENERIC;
238     }
239 }
240
241 static void Manage (vout_display_t *vd)
242 {
243     VLC_UNUSED(vd);
244 }
245
246 static int OpenDisplay(vout_display_t *vd)
247 {
248     vout_display_sys_t *sys = vd->sys;
249
250     DFBSurfaceDescription dsc;
251     /*dsc.flags = DSDESC_CAPS | DSDESC_HEIGHT | DSDESC_WIDTH;*/
252     dsc.flags = DSDESC_CAPS;
253     dsc.caps  = DSCAPS_PRIMARY | DSCAPS_FLIPPING;
254     /*dsc.width = 352;*/
255     /*dsc.height = 240;*/
256
257     IDirectFB *directfb = NULL;
258     if (DirectFBCreate(&directfb) != DFB_OK || !directfb)
259         return VLC_EGENERIC;
260     sys->directfb = directfb;
261
262     IDirectFBSurface *primary = NULL;
263     if (directfb->CreateSurface(directfb, &dsc, &primary) || !primary)
264         return VLC_EGENERIC;
265     sys->primary = primary;
266
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);
271
272     return VLC_SUCCESS;
273 }
274
275 static void CloseDisplay(vout_display_t *vd)
276 {
277     vout_display_sys_t *sys = vd->sys;
278
279     IDirectFBSurface *primary = sys->primary;
280     if (primary)
281         primary->Release(primary);
282
283     IDirectFB *directfb = sys->directfb;
284     if (directfb)
285         directfb->Release(directfb);
286 }
287