]> git.sesse.net Git - vlc/blob - modules/media_library/media_pool.c
macosx: video effects panel: only allow to activate clone XOR wall
[vlc] / modules / media_library / media_pool.c
1 /*****************************************************************************
2  * media_pool.c : Media pool for watching system
3  *****************************************************************************
4  * Copyright (C) 2009-2010 the VideoLAN team and AUTHORS
5  * $Id$
6  *
7  * Authors: Srikanth Raju <srikiraju at gmail dot com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #include "sql_media_library.h"
25
26 #define mp_foreachlist( a, b ) for( ml_poolobject_t* b = a; b; b = b->p_next )
27
28 static inline int mediapool_hash( int media_id )
29 {
30     return media_id % ML_MEDIAPOOL_HASH_LENGTH;
31 }
32
33 /**
34  * @brief Get a media from the pool
35  * @param p_ml ML object
36  * @param media_id The media id of the object to get
37  * @return the found media or NULL if not found
38  */
39 ml_media_t* pool_GetMedia( media_library_t* p_ml, int media_id )
40 {
41     vlc_mutex_lock( &p_ml->p_sys->pool_mutex );
42     ml_media_t* p_media = NULL;
43     mp_foreachlist( p_ml->p_sys->p_mediapool[ mediapool_hash( media_id ) ], p_item )
44     {
45         if( p_item->p_media->i_id == media_id )
46         {
47             p_media = p_item->p_media;
48             break;
49         }
50     }
51     if( p_media )
52         ml_gc_incref( p_media );
53     vlc_mutex_unlock( &p_ml->p_sys->pool_mutex );
54     return p_media;
55 }
56
57 /**
58  * @brief Insert a media into the media pool
59  * @param p_ml ML object
60  * @param p_media Media object to insert
61  * @return VLC_SUCCESS or VLC_EGENERIC
62  */
63 int pool_InsertMedia( media_library_t* p_ml, ml_media_t* p_media, bool locked )
64 {
65     if( !locked )
66         ml_LockMedia( p_media );
67     assert( p_media );
68     assert( p_media->i_id > 0 );
69     if( p_media->ml_gc_data.pool )
70     {
71         msg_Dbg( p_ml, "Already in pool! %s %d", p_media->psz_uri, p_media->i_id );
72         ml_UnlockMedia( p_media );
73         return VLC_EGENERIC;
74     }
75     p_media->ml_gc_data.pool = true;
76     int i_ret = VLC_SUCCESS;
77     vlc_mutex_lock( &p_ml->p_sys->pool_mutex );
78     mp_foreachlist( p_ml->p_sys->p_mediapool[ (mediapool_hash(p_media->i_id)) ], p_item )
79     {
80         if( p_media == p_item->p_media )
81         {
82             i_ret = VLC_EGENERIC;
83             break;
84         }
85         else if( p_media->i_id == p_item->p_media->i_id )
86         {
87             i_ret = VLC_EGENERIC;
88             msg_Warn( p_ml, "A media of the same id was found, but in different objects!" );
89             break;
90         }
91     }
92     if( i_ret == VLC_SUCCESS )
93     {
94         ml_poolobject_t* p_new = ( ml_poolobject_t * ) calloc( 1, sizeof( ml_poolobject_t* ) );
95         if( !p_new )
96             i_ret = VLC_EGENERIC;
97         else
98         {
99             ml_gc_incref( p_media );
100             p_new->p_media = p_media;
101             p_new->p_next = p_ml->p_sys->p_mediapool[ ( mediapool_hash( p_media->i_id ) ) ];
102             p_ml->p_sys->p_mediapool[ ( mediapool_hash( p_media->i_id ) ) ] = p_new;
103         }
104     }
105     vlc_mutex_unlock( &p_ml->p_sys->pool_mutex );
106     if( !locked )
107         ml_UnlockMedia( p_media );
108     return i_ret;
109 }
110
111 /**
112  * @brief Perform a single garbage collection scan on the media pool
113  * @param p_ml The ML object
114  * @note Scans all media and removes any medias not held by any other objects.
115  */
116 void pool_GC( media_library_t* p_ml )
117 {
118     vlc_mutex_lock( &p_ml->p_sys->pool_mutex );
119     ml_poolobject_t* p_prev = NULL;
120     ml_media_t* p_media = NULL;
121     for( int i_idx = 0; i_idx < ML_MEDIAPOOL_HASH_LENGTH; i_idx++ )
122     {
123         p_prev = NULL;
124         for( ml_poolobject_t* p_item = p_ml->p_sys->p_mediapool[ i_idx ];
125                 p_item != NULL; p_item = p_item->p_next )
126         {
127             p_media = p_item->p_media;
128             int refs;
129             refs = p_media->ml_gc_data.refs;
130             if( refs == 1 )
131             {
132                 if( p_prev == NULL )
133                     p_ml->p_sys->p_mediapool[i_idx] = p_item->p_next;
134                 else
135                     p_prev->p_next = p_item->p_next;
136                 p_media->ml_gc_data.pool = false;
137                 ml_gc_decref( p_item->p_media );//This should destroy the object
138                 free( p_item );
139             }
140             p_prev = p_item;
141         }
142     }
143     vlc_mutex_unlock( &p_ml->p_sys->pool_mutex );
144 }