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>
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 /*****************************************************************************
27 *****************************************************************************/
34 #include <vlc_common.h>
35 #include <vlc_picture_pool.h>
37 /*****************************************************************************
39 *****************************************************************************/
40 struct picture_release_sys_t {
42 void (*release)(picture_t *);
43 picture_release_sys_t *release_sys;
46 int (*lock)(picture_t *);
47 void (*unlock)(picture_t *);
53 struct picture_pool_t {
61 static void PicturePoolPictureRelease(picture_t *);
63 picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg)
65 picture_pool_t *pool = calloc(1, sizeof(*pool));
70 pool->picture_count = cfg->picture_count;
71 pool->picture = calloc(pool->picture_count, sizeof(*pool->picture));
77 for (int i = 0; i < cfg->picture_count; i++) {
78 picture_t *picture = cfg->picture[i];
80 /* The pool must be the only owner of the picture */
81 assert(picture->i_refcount == 1);
83 /* Install the new release callback */
84 picture_release_sys_t *release_sys = malloc(sizeof(*release_sys));
87 release_sys->release = picture->pf_release;
88 release_sys->release_sys = picture->p_release_sys;
89 release_sys->lock = cfg->lock;
90 release_sys->unlock = cfg->unlock;
91 release_sys->tick = 0;
94 picture->i_refcount = 0;
95 picture->pf_release = PicturePoolPictureRelease;
96 picture->p_release_sys = release_sys;
99 pool->picture[i] = picture;
105 picture_pool_t *picture_pool_New(int picture_count, picture_t *picture[])
107 picture_pool_configuration_t cfg;
109 memset(&cfg, 0, sizeof(cfg));
110 cfg.picture_count = picture_count;
111 cfg.picture = picture;
113 return picture_pool_NewExtended(&cfg);
116 picture_pool_t *picture_pool_NewFromFormat(const video_format_t *fmt, int picture_count)
118 picture_t *picture[picture_count];
120 for (int i = 0; i < picture_count; i++) {
121 picture[i] = picture_NewFromFormat(fmt);
125 picture_pool_t *pool = picture_pool_New(picture_count, picture);
132 for (int i = 0; i < picture_count; i++) {
135 picture_Release(picture[i]);
140 void picture_pool_Delete(picture_pool_t *pool)
142 for (int i = 0; i < pool->picture_count; i++) {
143 picture_t *picture = pool->picture[i];
144 picture_release_sys_t *release_sys = picture->p_release_sys;
146 assert(picture->i_refcount == 0);
148 /* Restore old release callback */
149 picture->i_refcount = 1;
150 picture->pf_release = release_sys->release;
151 picture->p_release_sys = release_sys->release_sys;
153 picture_Release(picture);
161 picture_t *picture_pool_Get(picture_pool_t *pool)
163 for (int i = 0; i < pool->picture_count; i++) {
164 picture_t *picture = pool->picture[i];
165 if (picture->i_refcount > 0)
168 picture_release_sys_t *release_sys = picture->p_release_sys;
169 if (release_sys->lock && release_sys->lock(picture))
173 picture->p_release_sys->tick = pool->tick++;
174 picture_Hold(picture);
180 void picture_pool_NonEmpty(picture_pool_t *pool, bool reset)
182 picture_t *old = NULL;
184 for (int i = 0; i < pool->picture_count; i++) {
185 picture_t *picture = pool->picture[i];
189 picture->i_refcount = 0;
190 } else if (picture->i_refcount == 0) {
192 } else if (!old || picture->p_release_sys->tick < old->p_release_sys->tick) {
202 static void PicturePoolPictureRelease(picture_t *picture)
204 assert(picture->i_refcount > 0);
206 if (--picture->i_refcount > 0)
209 picture_release_sys_t *release_sys = picture->p_release_sys;
210 if (release_sys->unlock)
211 release_sys->unlock(picture);