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
43 void (*pf_release)( picture_t * );
44 picture_release_sys_t *p_release_sys;
47 int (*pf_lock)( picture_t * );
48 void (*pf_unlock)( picture_t * );
59 picture_t **pp_picture;
62 static void PicturePoolPictureRelease( picture_t * );
64 picture_pool_t *picture_pool_NewExtended( const picture_pool_configuration_t *cfg )
66 picture_pool_t *p_pool = calloc( 1, sizeof(*p_pool) );
71 p_pool->i_picture = cfg->picture_count;
72 p_pool->pp_picture = calloc( p_pool->i_picture, sizeof(*p_pool->pp_picture) );
73 if( !p_pool->pp_picture )
79 for( int i = 0; i < cfg->picture_count; i++ )
81 picture_t *p_picture = cfg->picture[i];
83 /* The pool must be the only owner of the picture */
84 assert( p_picture->i_refcount == 1 );
86 /* Install the new release callback */
87 picture_release_sys_t *p_release_sys = malloc( sizeof(*p_release_sys) );
90 p_release_sys->pf_release = p_picture->pf_release;
91 p_release_sys->p_release_sys = p_picture->p_release_sys;
92 p_release_sys->pf_lock = cfg->lock;
93 p_release_sys->pf_unlock = cfg->unlock;
94 p_release_sys->i_tick = 0;
96 p_picture->i_refcount = 0;
97 p_picture->pf_release = PicturePoolPictureRelease;
98 p_picture->p_release_sys = p_release_sys;
101 p_pool->pp_picture[i] = p_picture;
107 picture_pool_t *picture_pool_New( int i_picture, picture_t *pp_picture[] )
109 picture_pool_configuration_t cfg;
111 memset( &cfg, 0, sizeof(cfg) );
112 cfg.picture_count = i_picture;
113 cfg.picture = pp_picture;
115 return picture_pool_NewExtended( &cfg );
118 picture_pool_t *picture_pool_NewFromFormat( const video_format_t *p_fmt, int i_picture )
120 picture_t *pp_picture[i_picture];
122 for( int i = 0; i < i_picture; i++ )
124 pp_picture[i] = picture_New( p_fmt->i_chroma,
125 p_fmt->i_width, p_fmt->i_height,
130 picture_pool_t *p_pool = picture_pool_New( i_picture, pp_picture );
137 for( int i = 0; i < i_picture; i++ )
141 picture_Release( pp_picture[i] );
146 void picture_pool_Delete( picture_pool_t *p_pool )
148 for( int i = 0; i < p_pool->i_picture; i++ )
150 picture_t *p_picture = p_pool->pp_picture[i];
151 picture_release_sys_t *p_release_sys = p_picture->p_release_sys;
153 assert( p_picture->i_refcount == 0 );
155 /* Restore old release callback */
156 p_picture->i_refcount = 1;
157 p_picture->pf_release = p_release_sys->pf_release;
158 p_picture->p_release_sys = p_release_sys->p_release_sys;
160 picture_Release( p_picture );
162 free( p_release_sys );
164 free( p_pool->pp_picture );
168 picture_t *picture_pool_Get( picture_pool_t *p_pool )
170 for( int i = 0; i < p_pool->i_picture; i++ )
172 picture_t *p_picture = p_pool->pp_picture[i];
173 if( p_picture->i_refcount > 0 )
176 picture_release_sys_t *p_release_sys = p_picture->p_release_sys;
177 if( p_release_sys->pf_lock && p_release_sys->pf_lock(p_picture) )
181 p_picture->p_release_sys->i_tick = p_pool->i_tick++;
182 picture_Hold( p_picture );
188 void picture_pool_NonEmpty( picture_pool_t *p_pool, bool b_reset )
190 picture_t *p_old = NULL;
192 for( int i = 0; i < p_pool->i_picture; i++ )
194 picture_t *p_picture = p_pool->pp_picture[i];
197 p_picture->i_refcount = 0;
198 else if( p_picture->i_refcount == 0 )
200 else if( !p_old || p_picture->p_release_sys->i_tick < p_old->p_release_sys->i_tick )
203 if( !b_reset && p_old )
204 p_old->i_refcount = 0;
207 static void PicturePoolPictureRelease( picture_t *p_picture )
209 assert( p_picture->i_refcount > 0 );
211 if( --p_picture->i_refcount > 0 )
214 picture_release_sys_t *p_release_sys = p_picture->p_release_sys;
215 if( p_release_sys->pf_unlock )
216 p_release_sys->pf_unlock( p_picture );