[vlc-commits] commit: Added picture_pool_Reserve helper. (Laurent Aimar )

git at videolan.org git at videolan.org
Fri Apr 23 21:17:04 CEST 2010


vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Tue Apr 20 00:17:56 2010 +0200| [0a3c6b714f774a403081858f978e71f0f5ccec28] | committer: Laurent Aimar 

Added picture_pool_Reserve helper.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=0a3c6b714f774a403081858f978e71f0f5ccec28
---

 include/vlc_picture_pool.h |   11 ++++++
 src/libvlccore.sym         |    1 +
 src/misc/picture_pool.c    |   86 +++++++++++++++++++++++++++++++++++--------
 3 files changed, 82 insertions(+), 16 deletions(-)

diff --git a/include/vlc_picture_pool.h b/include/vlc_picture_pool.h
index 2a01d52..1f22e32 100644
--- a/include/vlc_picture_pool.h
+++ b/include/vlc_picture_pool.h
@@ -106,5 +106,16 @@ VLC_EXPORT( picture_t *, picture_pool_Get, ( picture_pool_t * ) );
  */
 VLC_EXPORT( void, picture_pool_NonEmpty, ( picture_pool_t *, bool reset ) );
 
+/**
+ * It reserves picture_count pictures from the given pool and returns
+ * a new pool with thoses pictures.
+ *
+ * The master pool must be full.
+ * The returned pool must be deleted before the master pool.
+ * When deleted, all pictures return to the master pool.
+ */
+VLC_EXPORT( picture_pool_t *, picture_pool_Reserve, (picture_pool_t *, int picture_count) );
+
+
 #endif /* VLC_PICTURE_POOL_H */
 
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index f07ec4b..afcf654 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -314,6 +314,7 @@ picture_pool_New
 picture_pool_NewExtended
 picture_pool_NewFromFormat
 picture_pool_NonEmpty
+picture_pool_Reserve
 picture_Reset
 picture_Setup
 plane_CopyPixels
diff --git a/src/misc/picture_pool.c b/src/misc/picture_pool.c
index 5b8b322..9264122 100644
--- a/src/misc/picture_pool.c
+++ b/src/misc/picture_pool.c
@@ -52,29 +52,43 @@ struct picture_release_sys_t {
 
 struct picture_pool_t {
     /* */
-    int64_t   tick;
+    picture_pool_t *master;
+    int64_t        tick;
     /* */
-    int       picture_count;
-    picture_t **picture;
+    int            picture_count;
+    picture_t      **picture;
+    bool           *picture_reserved;
 };
 
 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 *pool = calloc(1, sizeof(*pool));
     if (!pool)
         return NULL;
 
-    pool->tick = 1;
-    pool->picture_count = cfg->picture_count;
+    pool->master = master;
+    pool->tick = master ? master->tick : 1;
+    pool->picture_count = picture_count;
     pool->picture = calloc(pool->picture_count, sizeof(*pool->picture));
-    if (!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 *picture = cfg->picture[i];
@@ -99,6 +113,7 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg
 
         /* */
         pool->picture[i] = picture;
+        pool->picture_reserved[i] = false;
     }
     return pool;
 
@@ -139,23 +154,57 @@ error:
     return NULL;
 }
 
+picture_pool_t *picture_pool_Reserve(picture_pool_t *master, int count)
+{
+    picture_pool_t *pool = Create(master, count);
+    if (!pool)
+        return NULL;
+
+    int found = 0;
+    for (int i = 0; i < master->picture_count && found < count; i++) {
+        if (master->picture_reserved[i])
+            continue;
+
+        assert(master->picture[i]->i_refcount == 0);
+        master->picture_reserved[i] = true;
+
+        pool->picture[found]          = master->picture[i];
+        pool->picture_reserved[found] = false;
+        found++;
+    }
+    if (found < count) {
+        picture_pool_Delete(pool);
+        return NULL;
+    }
+    return pool;
+}
+
 void picture_pool_Delete(picture_pool_t *pool)
 {
     for (int i = 0; i < pool->picture_count; i++) {
         picture_t *picture = pool->picture[i];
-        picture_release_sys_t *release_sys = picture->p_release_sys;
+        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(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;
+            /* 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);
+            picture_Release(picture);
 
-        free(release_sys);
+            free(release_sys);
+        }
     }
+    free(pool->picture_reserved);
     free(pool->picture);
     free(pool);
 }
@@ -163,6 +212,9 @@ void picture_pool_Delete(picture_pool_t *pool)
 picture_t *picture_pool_Get(picture_pool_t *pool)
 {
     for (int i = 0; i < pool->picture_count; i++) {
+        if (pool->picture_reserved[i])
+            continue;
+
         picture_t *picture = pool->picture[i];
         if (picture->i_refcount > 0)
             continue;
@@ -183,8 +235,10 @@ void picture_pool_NonEmpty(picture_pool_t *pool, bool reset)
     picture_t *old = NULL;
 
     for (int i = 0; i < pool->picture_count; i++) {
-        picture_t *picture = pool->picture[i];
+        if (pool->picture_reserved[i])
+            continue;
 
+        picture_t *picture = pool->picture[i];
         if (reset) {
             if (picture->i_refcount > 0)
                 Unlock(picture);



More information about the vlc-commits mailing list