medialibrary: Fix and update the playlist 'Convert' function
[vlc.git] / src / misc / medialibrary.c
blobf83fc8584b191c58344098443ec8c373108f1a2d
1 /*****************************************************************************
2 * medialib.cpp: medialibrary module
3 *****************************************************************************
4 * Copyright © 2015-2016 VLC authors, VideoLAN and VideoLabs
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
25 #include <vlc_common.h>
26 #include <vlc_media_library.h>
27 #include <vlc_modules.h>
28 #include <vlc_list.h>
29 #include <vlc_threads.h>
30 #include <libvlc.h>
32 #include <assert.h>
34 struct vlc_ml_event_callback_t
36 vlc_ml_callback_t pf_cb;
37 void* p_data;
38 struct vlc_list node;
41 struct vlc_medialibrary_t
43 vlc_medialibrary_module_t m;
45 vlc_mutex_t lock;
46 struct vlc_list cbs;
49 static vlc_medialibrary_t* ml_priv( vlc_medialibrary_module_t* p_ml )
51 return container_of( p_ml, struct vlc_medialibrary_t, m );
54 static void vlc_ml_event_send( vlc_medialibrary_module_t* p_ml, const vlc_ml_event_t* p_event )
56 vlc_medialibrary_t* p_priv = ml_priv( p_ml );
57 vlc_mutex_lock( &p_priv->lock );
58 struct vlc_ml_event_callback_t* p_cb;
59 vlc_list_foreach( p_cb, &p_priv->cbs, node )
61 p_cb->pf_cb( p_cb->p_data, p_event );
63 vlc_mutex_unlock( &p_priv->lock );
66 vlc_ml_event_callback_t*
67 vlc_ml_event_register_callback( vlc_medialibrary_t* p_ml, vlc_ml_callback_t cb,
68 void* p_data )
70 struct vlc_ml_event_callback_t* p_cb = malloc( sizeof( *p_cb ) );
71 if ( unlikely( p_cb == NULL ) )
72 return NULL;
73 p_cb->pf_cb = cb;
74 p_cb->p_data = p_data;
75 vlc_mutex_lock( &p_ml->lock );
76 vlc_list_append( &p_cb->node, &p_ml->cbs );
77 vlc_mutex_unlock( &p_ml->lock );
78 return p_cb;
81 void vlc_ml_event_unregister_callback( vlc_medialibrary_t* p_ml,
82 vlc_ml_event_callback_t* p_cb )
84 vlc_mutex_lock( &p_ml->lock );
85 vlc_list_remove( &p_cb->node );
86 vlc_mutex_unlock( &p_ml->lock );
87 free( p_cb );
90 void vlc_ml_event_unregister_from_callback( vlc_medialibrary_t* p_ml,
91 vlc_ml_event_callback_t* p_cb )
93 vlc_mutex_assert( &p_ml->lock );
94 vlc_list_remove( &p_cb->node );
95 free( p_cb );
98 static const vlc_medialibrary_callbacks_t callbacks = {
99 .pf_send_event = &vlc_ml_event_send
102 vlc_medialibrary_t* libvlc_MlCreate( libvlc_int_t* p_libvlc )
104 vlc_medialibrary_t *p_ml = vlc_custom_create( VLC_OBJECT( p_libvlc ),
105 sizeof( *p_ml ), "medialibrary" );
106 if ( unlikely( p_ml == NULL ) )
107 return NULL;
108 vlc_mutex_init( &p_ml->lock );
109 vlc_list_init( &p_ml->cbs );
110 p_ml->m.cbs = &callbacks;
111 p_ml->m.p_module = module_need( &p_ml->m, "medialibrary", NULL, false );
112 if ( p_ml->m.p_module == NULL )
114 vlc_object_delete(&p_ml->m);
115 return NULL;
117 return p_ml;
120 void libvlc_MlRelease( vlc_medialibrary_t* p_ml )
122 assert( p_ml != NULL );
123 module_unneed( &p_ml->m, p_ml->m.p_module );
124 assert( vlc_list_is_empty( &p_ml->cbs ) );
125 vlc_object_delete(&p_ml->m);
128 #undef vlc_ml_instance_get
129 vlc_medialibrary_t* vlc_ml_instance_get( vlc_object_t* p_obj )
131 libvlc_priv_t* p_priv = libvlc_priv( vlc_object_instance(p_obj) );
132 return p_priv->p_media_library;
135 static void vlc_ml_thumbnails_release( vlc_ml_thumbnail_t *p_thumbnails )
137 for ( int i = 0; i < VLC_ML_THUMBNAIL_SIZE_COUNT; ++i )
138 free( p_thumbnails[i].psz_mrl );
141 static void vlc_ml_show_release_inner( vlc_ml_show_t* p_show )
143 free( p_show->psz_artwork_mrl );
144 free( p_show->psz_name );
145 free( p_show->psz_summary );
146 free( p_show->psz_tvdb_id );
149 void vlc_ml_show_release( vlc_ml_show_t* p_show )
151 if ( p_show == NULL )
152 return;
153 vlc_ml_show_release_inner( p_show );
154 free( p_show );
157 static void vlc_ml_media_release_tracks_inner( vlc_ml_media_track_list_t* p_tracks )
159 if ( p_tracks == NULL )
160 return;
161 for ( size_t i = 0; i < p_tracks->i_nb_items; ++i )
163 vlc_ml_media_track_t* p_track = &p_tracks->p_items[i];
164 free( p_track->psz_codec );
165 free( p_track->psz_language );
166 free( p_track->psz_description );
168 free( p_tracks );
171 static void vlc_ml_media_release_inner( vlc_ml_media_t* p_media )
173 vlc_ml_file_list_release( p_media->p_files );
174 vlc_ml_media_release_tracks_inner( p_media->p_tracks );
175 free( p_media->psz_title );
176 vlc_ml_thumbnails_release( p_media->thumbnails );
177 switch( p_media->i_subtype )
179 case VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK:
180 break;
181 case VLC_ML_MEDIA_SUBTYPE_SHOW_EPISODE:
182 free( p_media->show_episode.psz_summary );
183 free( p_media->show_episode.psz_tvdb_id );
184 break;
185 case VLC_ML_MEDIA_SUBTYPE_MOVIE:
186 free( p_media->movie.psz_summary );
187 free( p_media->movie.psz_imdb_id );
188 break;
189 default:
190 break;
194 static void vlc_ml_artist_release_inner( vlc_ml_artist_t* p_artist )
196 vlc_ml_thumbnails_release( p_artist->thumbnails );
197 free( p_artist->psz_name );
198 free( p_artist->psz_shortbio );
199 free( p_artist->psz_mb_id );
202 void vlc_ml_artist_release( vlc_ml_artist_t* p_artist )
204 if ( p_artist == NULL )
205 return;
206 vlc_ml_artist_release_inner( p_artist );
207 free( p_artist );
210 static void vlc_ml_album_release_inner( vlc_ml_album_t* p_album )
212 vlc_ml_thumbnails_release( p_album->thumbnails );
213 free( p_album->psz_artist );
214 free( p_album->psz_summary );
215 free( p_album->psz_title );
218 void vlc_ml_album_release( vlc_ml_album_t* p_album )
220 if ( p_album == NULL )
221 return;
222 vlc_ml_album_release_inner( p_album );
223 free( p_album );
226 void vlc_ml_genre_release( vlc_ml_genre_t* p_genre )
228 if ( p_genre == NULL )
229 return;
230 free( p_genre->psz_name );
231 free( p_genre );
234 static void vlc_ml_playlist_release_inner( vlc_ml_playlist_t* p_playlist )
236 free( p_playlist->psz_name );
237 free( p_playlist->psz_mrl );
238 free( p_playlist->psz_artwork_mrl );
241 void vlc_ml_playlist_release( vlc_ml_playlist_t* p_playlist )
243 if ( p_playlist == NULL )
244 return;
245 vlc_ml_playlist_release_inner( p_playlist );
246 free( p_playlist );
249 /* Lists release */
251 void vlc_ml_media_release( vlc_ml_media_t* p_media )
253 if ( p_media == NULL )
254 return;
255 vlc_ml_media_release_inner( p_media );
256 free( p_media );
259 void vlc_ml_label_list_release( vlc_ml_label_list_t* p_list )
261 if ( p_list == NULL )
262 return;
263 for ( size_t i = 0; i < p_list->i_nb_items; ++i )
264 free( p_list->p_items[i].psz_name );
265 free( p_list );
268 void vlc_ml_file_list_release( vlc_ml_file_list_t* p_list )
270 if ( p_list == NULL )
271 return;
272 for ( size_t i = 0; i < p_list->i_nb_items; ++i )
273 free( p_list->p_items[i].psz_mrl );
274 free( p_list );
277 void vlc_ml_artist_list_release( vlc_ml_artist_list_t* p_list )
279 if ( p_list == NULL )
280 return;
281 for ( size_t i = 0; i < p_list->i_nb_items; ++i )
282 vlc_ml_artist_release_inner( &p_list->p_items[i] );
283 free( p_list );
287 void vlc_ml_media_list_release( vlc_ml_media_list_t* p_list )
289 if ( p_list == NULL )
290 return;
291 for ( size_t i = 0; i < p_list->i_nb_items; ++i )
292 vlc_ml_media_release_inner( &p_list->p_items[i] );
293 free( p_list );
296 void vlc_ml_album_list_release( vlc_ml_album_list_t* p_list )
298 if ( p_list == NULL )
299 return;
300 for ( size_t i = 0; i < p_list->i_nb_items; ++i )
301 vlc_ml_album_release_inner( &p_list->p_items[i] );
302 free( p_list );
305 void vlc_ml_show_list_release( vlc_ml_show_list_t* p_list )
307 if ( p_list == NULL )
308 return;
309 for ( size_t i = 0; i < p_list->i_nb_items; ++i )
310 vlc_ml_show_release_inner( &p_list->p_items[i] );
311 free( p_list );
314 void vlc_ml_genre_list_release( vlc_ml_genre_list_t* p_list )
316 if ( p_list == NULL )
317 return;
318 for ( size_t i = 0; i < p_list->i_nb_items; ++i )
319 free( p_list->p_items[i].psz_name );
320 free( p_list );
323 void vlc_ml_playlist_list_release( vlc_ml_playlist_list_t* p_list )
325 if ( p_list == NULL )
326 return;
327 for ( size_t i = 0; i < p_list->i_nb_items; ++i )
328 vlc_ml_playlist_release_inner( &p_list->p_items[i] );
329 free( p_list );
332 void vlc_ml_entry_point_list_release( vlc_ml_entry_point_list_t* p_list )
334 if ( p_list == NULL )
335 return;
336 for ( size_t i = 0; i < p_list->i_nb_items; ++i )
337 free( p_list->p_items[i].psz_mrl );
338 free( p_list );
341 void vlc_ml_playback_states_all_release( vlc_ml_playback_states_all* prefs )
343 free( prefs->current_video_track );
344 free( prefs->current_audio_track );
345 free( prefs->current_subtitle_track );
346 free( prefs->aspect_ratio );
347 free( prefs->crop );
348 free( prefs->deinterlace );
349 free( prefs->video_filter );
352 static void vlc_ml_bookmark_release_inner( vlc_ml_bookmark_t* bookmark )
354 free( bookmark->psz_name );
355 free( bookmark->psz_description );
358 void vlc_ml_bookmark_release( vlc_ml_bookmark_t* bookmark )
360 if ( bookmark == NULL )
361 return;
362 vlc_ml_bookmark_release_inner( bookmark );
363 free( bookmark );
366 void vlc_ml_bookmark_list_release( vlc_ml_bookmark_list_t* list )
368 if ( list == NULL )
369 return;
370 for ( size_t i = 0; i < list->i_nb_items; ++i )
371 vlc_ml_bookmark_release_inner( &list->p_items[i] );
372 free( list );
375 void* vlc_ml_get( vlc_medialibrary_t* p_ml, int i_query, ... )
377 assert( p_ml != NULL );
378 va_list args;
379 va_start( args, i_query );
380 void* res = p_ml->m.pf_get( &p_ml->m, i_query, args );
381 va_end( args );
382 return res;
385 int vlc_ml_control( vlc_medialibrary_t* p_ml, int i_query, ... )
387 va_list args;
388 va_start( args, i_query );
389 int i_res = p_ml->m.pf_control( &p_ml->m, i_query, args );
390 va_end( args );
391 return i_res;
394 int vlc_ml_list( vlc_medialibrary_t* p_ml, int i_query,
395 const vlc_ml_query_params_t* p_params, ... )
397 va_list args;
398 va_start( args, p_params );
399 int i_res = p_ml->m.pf_list( &p_ml->m, i_query, p_params, args );
400 va_end( args );
401 return i_res;