qt: playlist: use item title if available
[vlc.git] / src / video_output / vout_wrapper.c
1 /*****************************************************************************
2  * vout_wrapper.c: "vout display" -> "video output" wrapper
3  *****************************************************************************
4  * Copyright (C) 2009 Laurent Aimar
5  *
6  * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <vlc_common.h>
31 #include <vlc_plugin.h>
32 #include <vlc_vout.h>
33 #include <assert.h>
34 #include "vout_internal.h"
35 #include "display.h"
36
37 /*****************************************************************************
38  * Local prototypes
39  *****************************************************************************/
40 #ifdef _WIN32
41 static int  Forward(vlc_object_t *, char const *,
42                     vlc_value_t, vlc_value_t, void *);
43 #endif
44
45 static void VoutDisplayEvent(vout_display_t *vd, int event, va_list args)
46 {
47     vout_thread_t *vout = vd->owner.sys;
48
49     switch (event) {
50     case VOUT_DISPLAY_EVENT_VIEWPOINT_MOVED:
51         var_SetAddress(vout, "viewpoint-moved",
52                        (void *)va_arg(args, const vlc_viewpoint_t *));
53         break;
54     default:
55         msg_Err(vd, "VoutDisplayEvent received event %d", event);
56         /* TODO add an assert when all event are handled */
57         break;
58     }
59 }
60
61 /* Minimum number of display picture */
62 #define DISPLAY_PICTURE_COUNT (1)
63
64 /*****************************************************************************
65  *
66  *****************************************************************************/
67 vout_display_t *vout_OpenWrapper(vout_thread_t *vout,
68                      const char *splitter_name, const vout_display_cfg_t *cfg)
69 {
70     vout_thread_sys_t *sys = vout->p;
71     vout_display_t *vd;
72     vout_display_owner_t owner = {
73         .event = VoutDisplayEvent, .sys = vout,
74     };
75     const char *modlist;
76     char *modlistbuf = NULL;
77
78     msg_Dbg(vout, "Opening vout display wrapper");
79
80     if (splitter_name == NULL)
81         modlist = modlistbuf = var_InheritString(vout, "vout");
82     else
83         modlist = "splitter,none";
84
85     vd = vout_display_New(VLC_OBJECT(vout), &sys->original, cfg, modlist,
86                           &owner);
87     free(modlistbuf);
88
89     if (vd == NULL)
90         return NULL;
91
92     sys->decoder_pool = NULL;
93     sys->display_pool = NULL;
94
95     const bool use_dr = !vout_IsDisplayFiltered(vd);
96     const bool allow_dr = !vd->info.has_pictures_invalid && !vd->info.is_slow && use_dr;
97     const unsigned private_picture  = 4; /* XXX 3 for filter, 1 for SPU */
98     const unsigned decoder_picture  = 1 + sys->dpb_size;
99     const unsigned kept_picture     = 1; /* last displayed picture */
100     const unsigned reserved_picture = DISPLAY_PICTURE_COUNT +
101                                       private_picture +
102                                       kept_picture;
103     const unsigned display_pool_size = allow_dr ? __MAX(VOUT_MAX_PICTURES,
104                                                         reserved_picture + decoder_picture) : 3;
105     picture_pool_t *display_pool = vout_GetPool(vd, display_pool_size);
106     if (display_pool == NULL)
107         goto error;
108
109     picture_pool_t *decoder_pool = NULL;
110
111 #ifndef NDEBUG
112     if ( picture_pool_GetSize(display_pool) < display_pool_size )
113         msg_Warn(vout, "Not enough display buffers in the pool, requested %u got %u",
114                  display_pool_size, picture_pool_GetSize(display_pool));
115 #endif
116
117     if (allow_dr &&
118         picture_pool_GetSize(display_pool) >= reserved_picture + decoder_picture) {
119         sys->dpb_size     = picture_pool_GetSize(display_pool) - reserved_picture;
120         sys->decoder_pool = display_pool;
121     } else {
122         sys->decoder_pool = decoder_pool =
123             picture_pool_NewFromFormat(&vd->source,
124                                        __MAX(VOUT_MAX_PICTURES,
125                                              reserved_picture + decoder_picture - DISPLAY_PICTURE_COUNT));
126         if (!sys->decoder_pool)
127             goto error;
128         if (allow_dr) {
129             msg_Warn(vout, "Not enough direct buffers, using system memory");
130             sys->dpb_size = 0;
131         } else {
132             sys->dpb_size = picture_pool_GetSize(sys->decoder_pool) - reserved_picture;
133         }
134         if (use_dr)
135             sys->display_pool = vout_GetPool(vd, 3);
136     }
137     sys->private_pool = picture_pool_Reserve(sys->decoder_pool, private_picture);
138     if (sys->private_pool == NULL) {
139         if (decoder_pool != NULL)
140             picture_pool_Release(decoder_pool);
141         sys->decoder_pool = NULL;
142         goto error;
143     }
144
145 #ifdef _WIN32
146     var_Create(vout, "video-wallpaper", VLC_VAR_BOOL|VLC_VAR_DOINHERIT);
147     var_AddCallback(vout, "video-wallpaper", Forward, vd);
148 #endif
149     var_SetBool(VLC_OBJECT(vout), "viewpoint-changeable",
150                 vd->fmt.projection_mode != PROJECTION_MODE_RECTANGULAR);
151     return vd;
152
153 error:
154     vout_display_Delete(vd);
155     return NULL;
156 }
157
158 /*****************************************************************************
159  *
160  *****************************************************************************/
161 void vout_CloseWrapper(vout_thread_t *vout, vout_display_t *vd)
162 {
163     vout_thread_sys_t *sys = vout->p;
164
165     assert(vout->p->decoder_pool && vout->p->private_pool);
166
167     picture_pool_Release(sys->private_pool);
168
169     if (sys->display_pool != NULL || vout_IsDisplayFiltered(vd))
170         picture_pool_Release(sys->decoder_pool);
171
172 #ifdef _WIN32
173     var_DelCallback(vout, "video-wallpaper", Forward, vd);
174 #endif
175     sys->decoder_pool = NULL; /* FIXME remove */
176
177     vout_display_Delete(vd);
178 }
179
180 #ifdef _WIN32
181 static int Forward(vlc_object_t *object, char const *var,
182                    vlc_value_t oldval, vlc_value_t newval, void *data)
183 {
184     vout_thread_t *vout = (vout_thread_t*)object;
185     vout_display_t *vd = data;
186
187     VLC_UNUSED(oldval);
188     return var_Set(vd, var, newval);
189 }
190 #endif
191