]> git.sesse.net Git - vlc/blob - modules/media_library/item_list.c
I422_YUY2: clobber lists for MMX and SSE2
[vlc] / modules / media_library / item_list.c
1 /*****************************************************************************
2  * item_list.c: An input_item_t+media_id couple list for the media library
3  *****************************************************************************
4  * Copyright (C) 2008-2010 the VideoLAN Team and AUTHORS
5  * $Id$
6  *
7  * Authors: Antoine Lejeune <phytos@videolan.org>
8  *          Jean-Philippe André <jpeg@videolan.org>
9  *          Rémi Duraffort <ivoire@videolan.org>
10  *          Adrien Maglo <magsoft@videolan.org>
11  *          Srikanth Raju <srikiraju at gmail dot com>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28 #include "sql_media_library.h"
29 #include "item_list.h"
30
31 /**
32  * @short item hash list for the media library monitoring system
33  */
34
35 /**
36  * @brief Add an item to the head of the list
37  * @param p_ml
38  * @param p_media media object. ID must be non zero and valid
39  * @param p_item input item to add, MUST NOT be NULL
40  * @param locked flag set if the list is locked. do not use
41  * @return VLC_SUCCESS or VLC_EGENERIC
42  */
43 int __item_list_add( watch_thread_t *p_wt, ml_media_t* p_media, input_item_t *p_item,
44                      bool locked )
45 {
46     if( !locked )
47         vlc_mutex_lock( &p_wt->list_mutex );
48     ml_LockMedia( p_media );
49     assert( p_media->i_id );
50     /* Ensure duplication does not occur */
51     il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
52     {
53         if( p_elt->p_item->i_id == p_item->i_id )
54         {
55             ml_UnlockMedia( p_media );
56             if( !locked )
57                 vlc_mutex_unlock( &p_wt->list_mutex );
58             return VLC_EGENERIC;
59         }
60     }
61
62     item_list_t *p_new = ( item_list_t* ) calloc( 1, sizeof( item_list_t ) );
63     if( !p_new )
64     {
65         ml_UnlockMedia( p_media );
66         if( !locked )
67             vlc_mutex_unlock( &p_wt->list_mutex );
68         return VLC_ENOMEM;
69     }
70     p_new->p_next = p_wt->p_hlist[ item_hash( p_item ) ];
71     p_new->i_refs = 1;
72     p_new->i_media_id = p_media->i_id;
73     p_new->p_media = p_media;
74     p_new->p_item = p_item;
75     p_wt->p_hlist[ item_hash( p_item ) ] = p_new;
76     ml_UnlockMedia( p_media );
77     if( !locked )
78         vlc_mutex_unlock( &p_wt->list_mutex );
79     return VLC_SUCCESS;
80 }
81
82 /**
83  * @brief Delete an item from the list
84  * @param p_ml this media library
85  * @param i_media_id media library's media ID
86  */
87 item_list_t* item_list_delMedia( watch_thread_t *p_wt, int i_media_id )
88 {
89     vlc_mutex_lock( &p_wt->list_mutex );
90     item_list_t *p_prev = NULL;
91     il_foreachhashlist( p_wt->p_hlist, p_elt, ixx )
92     {
93         if( p_elt->i_media_id == i_media_id )
94         {
95             if( p_prev )
96                 p_prev->p_next = p_elt->p_next;
97             else
98                 p_wt->p_hlist[ixx] = p_elt->p_next;
99             p_elt->p_next = NULL;
100             vlc_mutex_unlock( &p_wt->list_mutex );
101             return p_elt;
102         }
103         else
104         {
105             p_prev = p_elt;
106         }
107     }
108     vlc_mutex_unlock( &p_wt->list_mutex );
109     return NULL;
110 }
111
112 /**
113  * @brief Delete an item from the list and return the single element
114  * @param p_ml this media library
115  * @param p_item item to delete
116  * @return The element from the list containing p_item
117  */
118 item_list_t* item_list_delItem( watch_thread_t *p_wt, input_item_t *p_item, bool locked )
119 {
120     if( !locked )
121         vlc_mutex_lock( &p_wt->list_mutex );
122     item_list_t *p_prev = NULL;
123     il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
124     {
125         if( p_elt->p_item == p_item )
126         {
127             if( p_prev )
128                 p_prev->p_next = p_elt->p_next;
129             else
130                 p_wt->p_hlist[ item_hash( p_item ) ] = p_elt->p_next;
131             p_elt->p_next = NULL;
132             if( !locked )
133                 vlc_mutex_unlock( &p_wt->list_mutex );
134             return p_elt;
135         }
136         else
137         {
138             p_prev = p_elt;
139         }
140     }
141     if( !locked )
142         vlc_mutex_unlock( &p_wt->list_mutex );
143     return NULL;
144 }
145
146 /**
147  * @brief Find an input item
148  * @param p_ml this media library
149  * @param i_media_id item to find and gc_incref
150  * @return input item if found, NULL if not found
151  */
152 input_item_t* item_list_itemOfMediaId( watch_thread_t *p_wt, int i_media_id )
153 {
154     item_list_t* p_tmp = item_list_listitemOfMediaId( p_wt, i_media_id );
155     if( p_tmp )
156         return p_tmp->p_item;
157     else
158         return NULL;
159 }
160
161 /**
162  * @brief Find an item list item
163  * @param p_ml this media library
164  * @param i_media_id item to find and gc_incref
165  * @return input item if found, NULL if not found
166  */
167 item_list_t* item_list_listitemOfMediaId( watch_thread_t *p_wt, int i_media_id )
168 {
169     vlc_mutex_lock( &p_wt->list_mutex );
170     il_foreachhashlist( p_wt->p_hlist, p_elt, ixx )
171     {
172         if( p_elt->i_media_id == i_media_id )
173         {
174             p_elt->i_age = 0;
175             vlc_mutex_unlock( &p_wt->list_mutex );
176             return p_elt;
177         }
178     }
179     vlc_mutex_unlock( &p_wt->list_mutex );
180     return NULL;
181 }
182
183 /**
184  * @brief Find a media
185  * @param p_ml this media library
186  * @param i_media_id item to find and gc_incref
187  * @return media if found. NULL otherwise
188  */
189 ml_media_t* item_list_mediaOfMediaId( watch_thread_t *p_wt, int i_media_id )
190 {
191     item_list_t* p_tmp = item_list_listitemOfMediaId( p_wt, i_media_id );
192     if( p_tmp )
193         return p_tmp->p_media;
194     else
195         return NULL;
196 }
197
198 /**
199  * @brief Find a media ID by its input_item
200  * @param p_ml this media library
201  * @param p_item item to find
202  * @return media_id found, or VLC_EGENERIC
203  */
204 int item_list_mediaIdOfItem( watch_thread_t *p_wt, input_item_t *p_item )
205 {
206     vlc_mutex_lock( &p_wt->list_mutex );
207     il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
208     {
209         if( p_elt->p_item == p_item )
210         {
211             if( p_elt->i_media_id <= 0 )
212                 /* TODO! */
213             p_elt->i_age = 0;
214             vlc_mutex_unlock( &p_wt->list_mutex );
215             return p_elt->i_media_id;
216         }
217     }
218     vlc_mutex_unlock( &p_wt->list_mutex );
219     return VLC_EGENERIC;
220 }
221
222 /**
223  * @brief Find a media by its input_item
224  * @param p_ml this media library
225  * @param p_item item to find
226  * @return media found, or VLC_EGENERIC
227  */
228 ml_media_t* item_list_mediaOfItem( watch_thread_t *p_wt, input_item_t* p_item,
229         bool locked )
230 {
231     if( !locked )
232         vlc_mutex_lock( &p_wt->list_mutex );
233     il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
234     {
235         if( p_elt->p_item == p_item )
236         {
237             p_wt->p_hlist[ item_hash( p_item ) ] = p_elt->p_next;
238             p_elt->p_next = NULL;
239             if( !locked )
240                 vlc_mutex_unlock( &p_wt->list_mutex );
241             return p_elt->p_media;
242         }
243     }
244     if( !locked )
245         vlc_mutex_unlock( &p_wt->list_mutex );
246     return NULL;
247 }
248 /**
249  * @brief Flag an item as updated
250  * @param p_ml this media library
251  * @param p_item item to find and flag
252  * @param b_played raise play count or not, update last play
253  * @return media_id found, or VLC_EGENERIC
254  */
255 int item_list_updateInput( watch_thread_t *p_wt, input_item_t *p_item,
256                            bool b_played )
257 {
258     vlc_mutex_lock( &p_wt->list_mutex );
259     il_foreachlist( p_wt->p_hlist[ item_hash( p_item ) ], p_elt )
260     {
261         if( p_elt->p_item == p_item )
262         {
263             /* Item found, flag and return */
264             p_elt->i_age = 0;
265             p_elt->i_update |= b_played ? 3 : 1;
266             vlc_mutex_unlock( &p_wt->list_mutex );
267             return p_elt->i_media_id;
268         }
269     }
270     vlc_mutex_unlock( &p_wt->list_mutex );
271     return VLC_EGENERIC;
272 }
273
274 /**
275  * @brief Free every item in the item list.
276  * @param p_wt Watch thread
277  * @note All decref of objects must be handled by watch system
278  */
279 void item_list_destroy( watch_thread_t* p_wt )
280 {
281     vlc_mutex_lock( &p_wt->list_mutex );
282     for( int i = 0; i < ML_ITEMLIST_HASH_LENGTH ; i++ )
283     {
284         for( item_list_t* p_elt = p_wt->p_hlist[i] ; p_elt; p_elt = p_wt->p_hlist[i] )
285         {
286             p_wt->p_hlist[i] = p_elt->p_next;
287             free( p_elt );
288         }
289     }
290     vlc_mutex_unlock( &p_wt->list_mutex );
291 }