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 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
));
72 pool
->picture_count
= cfg
->picture_count
;
73 pool
->picture
= calloc(pool
->picture_count
, sizeof(*pool
->picture
));
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
));
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;
96 picture
->i_refcount
= 0;
97 picture
->pf_release
= Release
;
98 picture
->p_release_sys
= release_sys
;
101 pool
->picture
[i
] = picture
;
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
);
127 picture_pool_t
*pool
= picture_pool_New(picture_count
, picture
);
134 for (int i
= 0; i
< picture_count
; i
++) {
137 picture_Release(picture
[i
]);
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
);
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)
174 picture
->p_release_sys
->tick
= pool
->tick
++;
175 picture_Hold(picture
);
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
];
189 if (picture
->i_refcount
> 0)
191 picture
->i_refcount
= 0;
192 } else if (picture
->i_refcount
== 0) {
194 } else if (!old
|| picture
->p_release_sys
->tick
< old
->p_release_sys
->tick
) {
199 if (old
->i_refcount
> 0)
205 static void Release(picture_t
*picture
)
207 assert(picture
->i_refcount
> 0);
209 if (--picture
->i_refcount
> 0)
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
);
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
);