/*****************************************************************************
*
*****************************************************************************/
-struct picture_release_sys_t
-{
+struct picture_release_sys_t {
/* Saved release */
- void (*pf_release)( picture_t * );
- picture_release_sys_t *p_release_sys;
+ void (*release)(picture_t *);
+ picture_release_sys_t *release_sys;
/* */
- int (*pf_lock)( picture_t * );
- void (*pf_unlock)( picture_t * );
+ int (*lock)(picture_t *);
+ void (*unlock)(picture_t *);
/* */
- int64_t i_tick;
+ int64_t tick;
};
-struct picture_pool_t
-{
- int64_t i_tick;
-
- int i_picture;
- picture_t **pp_picture;
+struct picture_pool_t {
+ /* */
+ picture_pool_t *master;
+ int64_t tick;
+ /* */
+ int picture_count;
+ picture_t **picture;
+ bool *picture_reserved;
};
-static void PicturePoolPictureRelease( picture_t * );
+static void Release(picture_t *);
+static int Lock(picture_t *);
+static void Unlock(picture_t *);
-picture_pool_t *picture_pool_NewExtended( const picture_pool_configuration_t *cfg )
+static picture_pool_t *Create(picture_pool_t *master, int picture_count)
{
- picture_pool_t *p_pool = calloc( 1, sizeof(*p_pool) );
- if( !p_pool )
+ picture_pool_t *pool = calloc(1, sizeof(*pool));
+ if (!pool)
return NULL;
- p_pool->i_tick = 1;
- p_pool->i_picture = cfg->picture_count;
- p_pool->pp_picture = calloc( p_pool->i_picture, sizeof(*p_pool->pp_picture) );
- if( !p_pool->pp_picture )
- {
- free( p_pool );
+ pool->master = master;
+ pool->tick = master ? master->tick : 1;
+ pool->picture_count = picture_count;
+ pool->picture = calloc(pool->picture_count, sizeof(*pool->picture));
+ pool->picture_reserved = calloc(pool->picture_count, sizeof(*pool->picture_reserved));
+ if (!pool->picture || !pool->picture_reserved) {
+ free(pool->picture);
+ free(pool->picture_reserved);
+ free(pool);
return NULL;
}
+ return pool;
+}
+
+picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg)
+{
+ picture_pool_t *pool = Create(NULL, cfg->picture_count);
+ if (!pool)
+ return NULL;
- for( int i = 0; i < cfg->picture_count; i++ )
- {
- picture_t *p_picture = cfg->picture[i];
+ for (int i = 0; i < cfg->picture_count; i++) {
+ picture_t *picture = cfg->picture[i];
/* The pool must be the only owner of the picture */
- assert( p_picture->i_refcount == 1 );
+ assert(picture->i_refcount == 1);
/* Install the new release callback */
- picture_release_sys_t *p_release_sys = malloc( sizeof(*p_release_sys) );
- if( !p_release_sys )
+ picture_release_sys_t *release_sys = malloc(sizeof(*release_sys));
+ if (!release_sys)
abort();
- p_release_sys->pf_release = p_picture->pf_release;
- p_release_sys->p_release_sys = p_picture->p_release_sys;
- p_release_sys->pf_lock = cfg->lock;
- p_release_sys->pf_unlock = cfg->unlock;
- p_release_sys->i_tick = 0;
+ release_sys->release = picture->pf_release;
+ release_sys->release_sys = picture->p_release_sys;
+ release_sys->lock = cfg->lock;
+ release_sys->unlock = cfg->unlock;
+ release_sys->tick = 0;
- p_picture->i_refcount = 0;
- p_picture->pf_release = PicturePoolPictureRelease;
- p_picture->p_release_sys = p_release_sys;
+ /* */
+ picture->i_refcount = 0;
+ picture->pf_release = Release;
+ picture->p_release_sys = release_sys;
/* */
- p_pool->pp_picture[i] = p_picture;
+ pool->picture[i] = picture;
+ pool->picture_reserved[i] = false;
}
- return p_pool;
+ return pool;
}
-picture_pool_t *picture_pool_New( int i_picture, picture_t *pp_picture[] )
+picture_pool_t *picture_pool_New(int picture_count, picture_t *picture[])
{
picture_pool_configuration_t cfg;
- memset( &cfg, 0, sizeof(cfg) );
- cfg.picture_count = i_picture;
- cfg.picture = pp_picture;
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.picture_count = picture_count;
+ cfg.picture = picture;
- return picture_pool_NewExtended( &cfg );
+ return picture_pool_NewExtended(&cfg);
}
-picture_pool_t *picture_pool_NewFromFormat( const video_format_t *p_fmt, int i_picture )
+picture_pool_t *picture_pool_NewFromFormat(const video_format_t *fmt, int picture_count)
{
- picture_t *pp_picture[i_picture];
-
- for( int i = 0; i < i_picture; i++ )
- {
- pp_picture[i] = picture_New( p_fmt->i_chroma,
- p_fmt->i_width, p_fmt->i_height,
- p_fmt->i_aspect );
- if( !pp_picture[i] )
+ picture_t *picture[picture_count];
+
+ for (int i = 0; i < picture_count; i++) {
+ picture[i] = picture_NewFromFormat(fmt);
+ if (!picture[i])
goto error;
}
- picture_pool_t *p_pool = picture_pool_New( i_picture, pp_picture );
- if( !p_pool )
+ picture_pool_t *pool = picture_pool_New(picture_count, picture);
+ if (!pool)
goto error;
- return p_pool;
+ return pool;
error:
- for( int i = 0; i < i_picture; i++ )
- {
- if( !pp_picture[i] )
+ for (int i = 0; i < picture_count; i++) {
+ if (!picture[i])
break;
- picture_Release( pp_picture[i] );
+ picture_Release(picture[i]);
}
return NULL;
}
-void picture_pool_Delete( picture_pool_t *p_pool )
+picture_pool_t *picture_pool_Reserve(picture_pool_t *master, int count)
{
- for( int i = 0; i < p_pool->i_picture; i++ )
- {
- picture_t *p_picture = p_pool->pp_picture[i];
- picture_release_sys_t *p_release_sys = p_picture->p_release_sys;
+ picture_pool_t *pool = Create(master, count);
+ if (!pool)
+ return NULL;
- assert( p_picture->i_refcount == 0 );
+ int found = 0;
+ for (int i = 0; i < master->picture_count && found < count; i++) {
+ if (master->picture_reserved[i])
+ continue;
- /* Restore old release callback */
- p_picture->i_refcount = 1;
- p_picture->pf_release = p_release_sys->pf_release;
- p_picture->p_release_sys = p_release_sys->p_release_sys;
+ assert(master->picture[i]->i_refcount == 0);
+ master->picture_reserved[i] = true;
- picture_Release( p_picture );
+ pool->picture[found] = master->picture[i];
+ pool->picture_reserved[found] = false;
+ found++;
+ }
+ if (found < count) {
+ picture_pool_Delete(pool);
+ return NULL;
+ }
+ return pool;
+}
- free( p_release_sys );
+void picture_pool_Delete(picture_pool_t *pool)
+{
+ for (int i = 0; i < pool->picture_count; i++) {
+ picture_t *picture = pool->picture[i];
+ if (pool->master) {
+ for (int j = 0; j < pool->master->picture_count; j++) {
+ if (pool->master->picture[j] == picture)
+ pool->master->picture_reserved[j] = false;
+ }
+ } else {
+ picture_release_sys_t *release_sys = picture->p_release_sys;
+
+ assert(picture->i_refcount == 0);
+ assert(!pool->picture_reserved[i]);
+
+ /* Restore old release callback */
+ picture->i_refcount = 1;
+ picture->pf_release = release_sys->release;
+ picture->p_release_sys = release_sys->release_sys;
+
+ picture_Release(picture);
+
+ free(release_sys);
+ }
}
- free( p_pool->pp_picture );
- free( p_pool );
+ free(pool->picture_reserved);
+ free(pool->picture);
+ free(pool);
}
-picture_t *picture_pool_Get( picture_pool_t *p_pool )
+picture_t *picture_pool_Get(picture_pool_t *pool)
{
- for( int i = 0; i < p_pool->i_picture; i++ )
- {
- picture_t *p_picture = p_pool->pp_picture[i];
- if( p_picture->i_refcount > 0 )
+ for (int i = 0; i < pool->picture_count; i++) {
+ if (pool->picture_reserved[i])
continue;
- picture_release_sys_t *p_release_sys = p_picture->p_release_sys;
- if( p_release_sys->pf_lock && p_release_sys->pf_lock(p_picture) )
+ picture_t *picture = pool->picture[i];
+ if (picture->i_refcount > 0)
+ continue;
+
+ if (Lock(picture))
continue;
/* */
- p_picture->p_release_sys->i_tick = p_pool->i_tick++;
- picture_Hold( p_picture );
- return p_picture;
+ picture->p_release_sys->tick = pool->tick++;
+ picture_Hold(picture);
+ return picture;
}
return NULL;
}
-void picture_pool_NonEmpty( picture_pool_t *p_pool, bool b_reset )
+void picture_pool_NonEmpty(picture_pool_t *pool, bool reset)
{
- picture_t *p_old = NULL;
+ picture_t *old = NULL;
- for( int i = 0; i < p_pool->i_picture; i++ )
- {
- picture_t *p_picture = p_pool->pp_picture[i];
+ for (int i = 0; i < pool->picture_count; i++) {
+ if (pool->picture_reserved[i])
+ continue;
- if( b_reset )
- p_picture->i_refcount = 0;
- else if( p_picture->i_refcount == 0 )
+ picture_t *picture = pool->picture[i];
+ if (reset) {
+ if (picture->i_refcount > 0)
+ Unlock(picture);
+ picture->i_refcount = 0;
+ } else if (picture->i_refcount == 0) {
return;
- else if( !p_old || p_picture->p_release_sys->i_tick < p_old->p_release_sys->i_tick )
- p_old = p_picture;
+ } else if (!old || picture->p_release_sys->tick < old->p_release_sys->tick) {
+ old = picture;
+ }
}
- if( !b_reset && p_old )
- p_old->i_refcount = 0;
+ if (!reset && old) {
+ if (old->i_refcount > 0)
+ Unlock(old);
+ old->i_refcount = 0;
+ }
+}
+int picture_pool_GetSize(picture_pool_t *pool)
+{
+ return pool->picture_count;
}
-static void PicturePoolPictureRelease( picture_t *p_picture )
+static void Release(picture_t *picture)
{
- assert( p_picture->i_refcount > 0 );
+ assert(picture->i_refcount > 0);
- if( --p_picture->i_refcount > 0 )
+ if (--picture->i_refcount > 0)
return;
+ Unlock(picture);
+}
- picture_release_sys_t *p_release_sys = p_picture->p_release_sys;
- if( p_release_sys->pf_unlock )
- p_release_sys->pf_unlock( p_picture );
+static int Lock(picture_t *picture)
+{
+ picture_release_sys_t *release_sys = picture->p_release_sys;
+ if (release_sys->lock)
+ return release_sys->lock(picture);
+ return VLC_SUCCESS;
+}
+static void Unlock(picture_t *picture)
+{
+ picture_release_sys_t *release_sys = picture->p_release_sys;
+ if (release_sys->unlock)
+ release_sys->unlock(picture);
}