If http-use-IE-proxy is enable, use Internet Explorer entered HTTP proxy server confi...
[vlc.git] / src / misc / picture_pool.c
blob5b8b322974e3ff7cba59b92e7ab52f2fc56bb53c
1 /*****************************************************************************
2 * picture_pool.c : picture pool functions
3 *****************************************************************************
4 * Copyright (C) 2009 the VideoLAN team
5 * Copyright (C) 2009 Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
6 * $Id$
8 * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
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 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32 #include <assert.h>
34 #include <vlc_common.h>
35 #include <vlc_picture_pool.h>
37 /*****************************************************************************
39 *****************************************************************************/
40 struct picture_release_sys_t {
41 /* Saved release */
42 void (*release)(picture_t *);
43 picture_release_sys_t *release_sys;
45 /* */
46 int (*lock)(picture_t *);
47 void (*unlock)(picture_t *);
49 /* */
50 int64_t tick;
53 struct picture_pool_t {
54 /* */
55 int64_t tick;
56 /* */
57 int picture_count;
58 picture_t **picture;
61 static void Release(picture_t *);
62 static int Lock(picture_t *);
63 static void Unlock(picture_t *);
65 picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg)
67 picture_pool_t *pool = calloc(1, sizeof(*pool));
68 if (!pool)
69 return NULL;
71 pool->tick = 1;
72 pool->picture_count = cfg->picture_count;
73 pool->picture = calloc(pool->picture_count, sizeof(*pool->picture));
74 if (!pool->picture) {
75 free(pool);
76 return NULL;
79 for (int i = 0; i < cfg->picture_count; i++) {
80 picture_t *picture = cfg->picture[i];
82 /* The pool must be the only owner of the picture */
83 assert(picture->i_refcount == 1);
85 /* Install the new release callback */
86 picture_release_sys_t *release_sys = malloc(sizeof(*release_sys));
87 if (!release_sys)
88 abort();
89 release_sys->release = picture->pf_release;
90 release_sys->release_sys = picture->p_release_sys;
91 release_sys->lock = cfg->lock;
92 release_sys->unlock = cfg->unlock;
93 release_sys->tick = 0;
95 /* */
96 picture->i_refcount = 0;
97 picture->pf_release = Release;
98 picture->p_release_sys = release_sys;
100 /* */
101 pool->picture[i] = picture;
103 return pool;
107 picture_pool_t *picture_pool_New(int picture_count, picture_t *picture[])
109 picture_pool_configuration_t cfg;
111 memset(&cfg, 0, sizeof(cfg));
112 cfg.picture_count = picture_count;
113 cfg.picture = picture;
115 return picture_pool_NewExtended(&cfg);
118 picture_pool_t *picture_pool_NewFromFormat(const video_format_t *fmt, int picture_count)
120 picture_t *picture[picture_count];
122 for (int i = 0; i < picture_count; i++) {
123 picture[i] = picture_NewFromFormat(fmt);
124 if (!picture[i])
125 goto error;
127 picture_pool_t *pool = picture_pool_New(picture_count, picture);
128 if (!pool)
129 goto error;
131 return pool;
133 error:
134 for (int i = 0; i < picture_count; i++) {
135 if (!picture[i])
136 break;
137 picture_Release(picture[i]);
139 return NULL;
142 void picture_pool_Delete(picture_pool_t *pool)
144 for (int i = 0; i < pool->picture_count; i++) {
145 picture_t *picture = pool->picture[i];
146 picture_release_sys_t *release_sys = picture->p_release_sys;
148 assert(picture->i_refcount == 0);
150 /* Restore old release callback */
151 picture->i_refcount = 1;
152 picture->pf_release = release_sys->release;
153 picture->p_release_sys = release_sys->release_sys;
155 picture_Release(picture);
157 free(release_sys);
159 free(pool->picture);
160 free(pool);
163 picture_t *picture_pool_Get(picture_pool_t *pool)
165 for (int i = 0; i < pool->picture_count; i++) {
166 picture_t *picture = pool->picture[i];
167 if (picture->i_refcount > 0)
168 continue;
170 if (Lock(picture))
171 continue;
173 /* */
174 picture->p_release_sys->tick = pool->tick++;
175 picture_Hold(picture);
176 return picture;
178 return NULL;
181 void picture_pool_NonEmpty(picture_pool_t *pool, bool reset)
183 picture_t *old = NULL;
185 for (int i = 0; i < pool->picture_count; i++) {
186 picture_t *picture = pool->picture[i];
188 if (reset) {
189 if (picture->i_refcount > 0)
190 Unlock(picture);
191 picture->i_refcount = 0;
192 } else if (picture->i_refcount == 0) {
193 return;
194 } else if (!old || picture->p_release_sys->tick < old->p_release_sys->tick) {
195 old = picture;
198 if (!reset && old) {
199 if (old->i_refcount > 0)
200 Unlock(old);
201 old->i_refcount = 0;
205 static void Release(picture_t *picture)
207 assert(picture->i_refcount > 0);
209 if (--picture->i_refcount > 0)
210 return;
211 Unlock(picture);
214 static int Lock(picture_t *picture)
216 picture_release_sys_t *release_sys = picture->p_release_sys;
217 if (release_sys->lock)
218 return release_sys->lock(picture);
219 return VLC_SUCCESS;
221 static void Unlock(picture_t *picture)
223 picture_release_sys_t *release_sys = picture->p_release_sys;
224 if (release_sys->unlock)
225 release_sys->unlock(picture);