VLC_ADD_PLUGINS([fixed32tos16 s16tofixed32 u8tofixed32])
VLC_ADD_PLUGINS([trivial_resampler ugly_resampler])
VLC_ADD_PLUGINS([trivial_channel_mixer trivial_mixer])
-VLC_ADD_PLUGINS([playlist export sgimb m3u nsc xtag])
+VLC_ADD_PLUGINS([playlist export sgimb nsc xtag])
VLC_ADD_PLUGINS([i420_rgb rawvideo blend scale image logo magnify])
VLC_ADD_PLUGINS([wav araw subtitle vobsub adpcm a52sys dtssys au ty voc xa nuv])
VLC_ADD_PLUGINS([access_directory access_file access_udp access_tcp])
/* Used by VLC_AddTarget() */
#define PLAYLIST_INSERT 0x0001
-#define PLAYLIST_REPLACE 0x0002
-#define PLAYLIST_APPEND 0x0004
-#define PLAYLIST_GO 0x0008
-#define PLAYLIST_CHECK_INSERT 0x0010
-#define PLAYLIST_PREPARSE 0x0020
+#define PLAYLIST_APPEND 0x0002
+#define PLAYLIST_GO 0x0004
+#define PLAYLIST_PREPARSE 0x0008
#define PLAYLIST_END -666
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
+
/**
* \file
* This file is a collection of common definitions and types
typedef struct variable_t variable_t;
typedef struct date_t date_t;
typedef struct hashtable_entry_t hashtable_entry_t;
+typedef struct gc_object_t gc_object_t ;
/* Messages */
typedef struct msg_bank_t msg_bank_t;
#define VLC_OBJECT( x ) \
((vlc_object_t *)(x))+0*(x)->be_sure_to_add_VLC_COMMON_MEMBERS_to_struct
+#define VLC_GC_MEMBERS \
+/** \name VLC_GC_MEMBERS \
+ * these members are common to all objects that wish to be garbage-collected \
+ */ \
+/**@{*/ \
+ int i_gc_refcount; \
+ void (*pf_destructor) ( gc_object_t * ); \
+ void *p_destructor_arg; \
+/**@}*/
+
+struct gc_object_t
+{
+ VLC_GC_MEMBERS
+};
+
+static inline void __vlc_gc_incref( gc_object_t * p_gc )
+{
+ p_gc->i_gc_refcount ++;
+};
+
+static inline void __vlc_gc_decref( gc_object_t *p_gc )
+{
+ p_gc->i_gc_refcount -- ;
+
+ if( p_gc->i_gc_refcount == 0 )
+ {
+ p_gc->pf_destructor( p_gc );
+ /* Do not use the p_gc pointer from now on ! */
+ }
+}
+
+#define vlc_gc_incref( a ) __vlc_gc_incref( (gc_object_t *)a )
+#define vlc_gc_decref( a ) __vlc_gc_decref( (gc_object_t *)a )
+#define vlc_gc_init( a,b,c ) { ((gc_object_t *)a)->i_gc_refcount = 0; \
+ ((gc_object_t *)a)->pf_destructor = b; \
+ ((gc_object_t *)a)->p_destructor_arg = c; }
+
+
/*****************************************************************************
* Macros and inline functions
*****************************************************************************/
* Input thread configuration
*****************************************************************************/
+#define DEFAULT_INPUT_ACTIVITY 1
+#define DIRECTORY_ACTIVITY 100
+#define TRANSCODE_ACTIVITY 10
+
/* Used in ErrorThread */
#define INPUT_IDLE_SLEEP ((mtime_t)(0.100*CLOCK_FREQ))
#ifndef _VLC__INPUT_H
#define _VLC__INPUT_H 1
+#include <vlc_playlist.h>
+#include <vlc_meta.h>
+
+struct vlc_meta_t;
+
/*****************************************************************************
* input_item_t: Describes an input and is used to spawn input_thread_t objects
*****************************************************************************/
struct input_item_t
{
+ VLC_GC_MEMBERS
+ int i_id; /**< Identifier of the item */
+
char *psz_name; /**< text describing this item */
char *psz_uri; /**< mrl of this item */
+ vlc_bool_t b_fixed_name; /**< Can the interface change the name ?*/
int i_options; /**< Number of input options */
char **ppsz_options; /**< Array of input options */
- mtime_t i_duration; /**< A hint about the duration of this
- * item, in milliseconds*/
+ mtime_t i_duration; /**< Duration in milliseconds*/
- int i_id; /**< Identifier of the item */
uint8_t i_type; /**< Type (file, disc, ...) */
int i_categories; /**< Number of info categories */
info_category_t **pp_categories; /**< Pointer to the first info category */
int i_es; /**< Number of es format descriptions */
- es_format_t **es; /**< Pointer to an array of es formats */
-
- vlc_bool_t b_fixed_name; /**< Can the interface change the name ?*/
+ es_format_t **es; /**< Es formats */
input_stats_t *p_stats; /**< Statistics */
+ int i_nb_played; /**< Number of times played */
+
+ vlc_meta_t *p_meta;
- vlc_mutex_t lock; /**< Item cannot be changed without this lock */
+ vlc_mutex_t lock; /**< Lock for the item */
};
#define ITEM_TYPE_UNKNOWN 0
static inline void vlc_input_item_Init( vlc_object_t *p_o, input_item_t *p_i )
{
memset( p_i, 0, sizeof(input_item_t) );
- p_i->i_options = 0;
- p_i->i_es = 0;
- p_i->i_categories = 0 ;
p_i->psz_name = 0;
p_i->psz_uri = 0;
+ p_i->i_es = 0;
+ p_i->es = 0;
+ p_i->i_options = 0;
p_i->ppsz_options = 0;
+ p_i->i_categories = 0 ;
p_i->pp_categories = 0;
- p_i->es = 0;
p_i->i_type = ITEM_TYPE_UNKNOWN;
p_i->b_fixed_name = VLC_TRUE;
p_i->p_stats = (input_stats_t*) malloc( sizeof( input_stats_t ) );
+ p_i->p_meta = NULL;
vlc_mutex_init( p_o, &p_i->p_stats->lock );
vlc_mutex_init( p_o, &p_i->lock );
}
}
+VLC_EXPORT( void, vlc_input_item_AddOption, ( input_item_t *p_input, const char *psz_option ) );
+
static inline void vlc_input_item_Clean( input_item_t *p_i )
{
if( p_i->psz_name ) free( p_i->psz_name );
p_i->psz_name = 0;
p_i->psz_uri = 0;
+ if( p_i->p_meta ) vlc_meta_Delete( p_i->p_meta );
+
while( p_i->i_options )
{
p_i->i_options--;
VLC_EXPORT( char *, vlc_input_item_GetInfo, ( input_item_t *p_i, const char *psz_cat,const char *psz_name ) );
VLC_EXPORT(int, vlc_input_item_AddInfo, ( input_item_t *p_i, const char *psz_cat, const char *psz_name, const char *psz_format, ... ) );
+#define input_ItemNew( a,b,c ) input_ItemNewExt( a, b, c, 0, NULL, -1 )
+#define input_ItemNewExt(a,b,c,d,e,f) __input_ItemNewExt( VLC_OBJECT(a),b,c,d,e,f)
+VLC_EXPORT( input_item_t *, __input_ItemNewExt, (vlc_object_t *, const char *, const char*, int, const char **, int) );
+VLC_EXPORT( input_item_t *, input_ItemNewWithType, ( vlc_object_t *, const char *, const char *e, int, const char **, int, int ) );
+
+VLC_EXPORT( input_item_t *, input_ItemGetById, (playlist_t *, int ) );
+
+
/*****************************************************************************
* Seek point: (generalisation of chapters)
*****************************************************************************/
static inline int __stats_GetFloat( vlc_object_t *p_obj, int i_id,
unsigned int i_counter, float *value )
{
- int i_ret;
vlc_value_t val;val.f_float = 0.0;
- i_ret = __stats_Get( p_obj, i_id, i_counter, &val );
+ int i_ret = __stats_Get( p_obj, i_id, i_counter, &val );
*value = val.f_float;
return i_ret;
}
#define VLC_META_NOW_PLAYING N_("Now Playing")
#define VLC_META_PUBLISHER N_("Publisher")
-#define VLC_META_CDDB_ARTIST N_("CDDB Artist")
-#define VLC_META_CDDB_CATEGORY N_("CDDB Category")
-#define VLC_META_CDDB_DISCID N_("CDDB Disc ID")
-#define VLC_META_CDDB_EXT_DATA N_("CDDB Extended Data")
-#define VLC_META_CDDB_GENRE N_("CDDB Genre")
-#define VLC_META_CDDB_YEAR N_("CDDB Year")
-#define VLC_META_CDDB_TITLE N_("CDDB Title")
-
-#define VLC_META_CDTEXT_ARRANGER N_("CD-Text Arranger")
-#define VLC_META_CDTEXT_COMPOSER N_("CD-Text Composer")
-#define VLC_META_CDTEXT_DISCID N_("CD-Text Disc ID")
-#define VLC_META_CDTEXT_GENRE N_("CD-Text Genre")
-#define VLC_META_CDTEXT_MESSAGE N_("CD-Text Message")
-#define VLC_META_CDTEXT_SONGWRITER N_("CD-Text Songwriter")
-#define VLC_META_CDTEXT_PERFORMER N_("CD-Text Performer")
-#define VLC_META_CDTEXT_TITLE N_("CD-Text Title")
-
-#define VLC_META_ISO_APPLICATION_ID N_("ISO-9660 Application ID")
-#define VLC_META_ISO_PREPARER N_("ISO-9660 Preparer")
-#define VLC_META_ISO_PUBLISHER N_("ISO-9660 Publisher")
-#define VLC_META_ISO_VOLUME N_("ISO-9660 Volume")
-#define VLC_META_ISO_VOLUMESET N_("ISO-9660 Volume Set")
-
#define VLC_META_CODEC_NAME N_("Codec Name")
#define VLC_META_CODEC_DESCRIPTION N_("Codec Description")
struct vlc_meta_t
{
- /* meta name/value pairs */
- int i_meta;
- char **name;
- char **value;
-
+ char *psz_title;
+ char *psz_author;
+ char *psz_artist;
+ char *psz_genre;
+ char *psz_copyright;
+ char *psz_album;
+ char *psz_tracknum;
+ char *psz_description;
+ char *psz_rating;
+ char *psz_date;
+ char *psz_setting;
+ char *psz_url;
+ char *psz_language;
+ char *psz_nowplaying;
+ char *psz_publisher;
+#if 0
/* track meta information */
int i_track;
vlc_meta_t **track;
+#endif
};
+#define vlc_meta_Set( meta,var,val ) { \
+ if( meta->psz_##var ) free( meta->psz_##var ); \
+ meta->psz_##var = strdup( val ); }
+
+#define vlc_meta_SetTitle( meta, b ) vlc_meta_Set( meta, title, b );
+#define vlc_meta_SetArtist( meta, b ) vlc_meta_Set( meta, artist, b );
+#define vlc_meta_SetAuthor( meta, b ) vlc_meta_Set( meta, author, b );
+#define vlc_meta_SetGenre( meta, b ) vlc_meta_Set( meta, genre, b );
+#define vlc_meta_SetCopyright( meta, b ) vlc_meta_Set( meta, copyright, b );
+#define vlc_meta_SetAlbum( meta, b ) vlc_meta_Set( meta, album, b );
+#define vlc_meta_SetTracknum( meta, b ) vlc_meta_Set( meta, tracknum, b );
+#define vlc_meta_SetDescription( meta, b ) vlc_meta_Set( meta, description, b );
+#define vlc_meta_SetRating( meta, b ) vlc_meta_Set( meta, rating, b );
+#define vlc_meta_SetDate( meta, b ) vlc_meta_Set( meta, date, b );
+#define vlc_meta_SetSetting( meta, b ) vlc_meta_Set( meta, setting, b );
+#define vlc_meta_SetURL( meta, b ) vlc_meta_Set( meta, url, b );
+#define vlc_meta_SetLanguage( meta, b ) vlc_meta_Set( meta, language, b );
+#define vlc_meta_SetNowPlaying( meta, b ) vlc_meta_Set( meta, nowplaying, b );
+#define vlc_meta_SetPublisher( meta, b ) vlc_meta_Set( meta, publisher, b );
+
static inline vlc_meta_t *vlc_meta_New( void )
{
vlc_meta_t *m = (vlc_meta_t*)malloc( sizeof( vlc_meta_t ) );
-
- m->i_meta = 0;
- m->name = NULL;
- m->value = NULL;
-
- m->i_track= 0;
- m->track = NULL;
-
+ if( !m ) return NULL;
+ m->psz_title = NULL;
+ m->psz_author = NULL;
+ m->psz_artist = NULL;
+ m->psz_genre = NULL;
+ m->psz_copyright = NULL;
+ m->psz_album = NULL;
+ m->psz_tracknum = NULL;
+ m->psz_description = NULL;
+ m->psz_rating = NULL;
+ m->psz_date = NULL;
+ m->psz_setting = NULL;
+ m->psz_url = NULL;
+ m->psz_language = NULL;
+ m->psz_nowplaying = NULL;
+ m->psz_publisher = NULL;
return m;
}
static inline void vlc_meta_Delete( vlc_meta_t *m )
{
- int i;
- for( i = 0; i < m->i_meta; i++ )
- {
- free( m->name[i] );
- free( m->value[i] );
- }
- if( m->name ) free( m->name );
- if( m->value ) free( m->value );
+ free( m->psz_title );
+ free( m->psz_author );
+ free( m->psz_artist );
+ free( m->psz_genre );
+ free( m->psz_copyright );
+ free( m->psz_album );
+ free( m->psz_tracknum );
+ free( m->psz_description );
+ free( m->psz_rating );
+ free( m->psz_date );
+ free( m->psz_setting );
+ free( m->psz_url );
+ free( m->psz_language );
+ free( m->psz_nowplaying );
+ free( m->psz_publisher );
- for( i = 0; i < m->i_track; i++ )
- {
- vlc_meta_Delete( m->track[i] );
- }
- if( m->track ) free( m->track );
free( m );
}
-static inline void vlc_meta_Add( vlc_meta_t *m,
- const char *name, const char *value )
-{
- m->name = (char**)realloc( m->name, sizeof(char*) * ( m->i_meta + 1 ) );
- m->name[m->i_meta] = strdup( name );
-
- m->value = (char**)realloc( m->value, sizeof(char*) * ( m->i_meta + 1 ) );
- m->value[m->i_meta] = strdup( value );
-
- m->i_meta++;
-}
-
-static inline vlc_meta_t *vlc_meta_Duplicate( vlc_meta_t *src )
-{
- vlc_meta_t *dst = vlc_meta_New();
- int i;
- for( i = 0; i < src->i_meta; i++ )
- {
- vlc_meta_Add( dst, src->name[i], src->value[i] );
- }
- for( i = 0; i < src->i_track; i++ )
- {
- vlc_meta_t *tk = vlc_meta_Duplicate( src->track[i] );
-
- dst->track = (vlc_meta_t**)realloc( dst->track, sizeof( vlc_meta_t* ) * (dst->i_track+1) );
- dst->track[dst->i_track++] = tk;
- }
- return dst;
-}
-
static inline void vlc_meta_Merge( vlc_meta_t *dst, vlc_meta_t *src )
{
- int i, j;
- for( i = 0; i < src->i_meta; i++ )
- {
- /* Check if dst contains the entry */
- for( j = 0; j < dst->i_meta; j++ )
- {
- if( !strcmp( src->name[i], dst->name[j] ) ) break;
- }
- if( j < dst->i_meta )
- {
- if( dst->value[j] ) free( dst->value[j] );
- dst->value[j] = strdup( src->value[i] );
- }
- else vlc_meta_Add( dst, src->name[i], src->value[i] );
- }
-}
-
-static inline char *vlc_meta_GetValue( vlc_meta_t *m, const char *name )
-{
- int i;
-
- for( i = 0; i < m->i_meta; i++ )
- {
- if( !strcmp( m->name[i], name ) )
- {
- char *value = NULL;
- if( m->value[i] ) value = strdup( m->value[i] );
- return value;
- }
+ if( !dst || !src ) return;
+#define COPY_FIELD( a ) \
+ if( src->psz_ ## a ) { \
+ if( dst->psz_ ## a ) free( dst->psz_## a ); \
+ dst->psz_##a = strdup( src->psz_##a ); \
}
- return NULL;
+ COPY_FIELD( title );
+ COPY_FIELD( author );
+ COPY_FIELD( artist );
+ COPY_FIELD( genre );
+ COPY_FIELD( copyright );
+ COPY_FIELD( album );
+ COPY_FIELD( tracknum );
+ COPY_FIELD( description );
+ COPY_FIELD( rating );
+ COPY_FIELD( date );
+ COPY_FIELD( setting );
+ COPY_FIELD( url );
+ COPY_FIELD( language );
+ COPY_FIELD( nowplaying );
+ COPY_FIELD( publisher );
}
+ /** \todo Track meta */
#endif
/**
* \file
- * This file defines the vlc_object_t structure and object types
+ * This file defines the vlc_object_t structure and object types.
*/
/**
VLC_EXPORT( vlc_list_t *, __vlc_list_find, ( vlc_object_t *, int, int ) );
VLC_EXPORT( void, vlc_list_release, ( vlc_list_t * ) );
VLC_EXPORT( vlc_t *, vlc_current_object, ( int ) );
+
/*}@*/
#define vlc_object_create(a,b) \
#define vlc_list_find(a,b,c) \
__vlc_list_find( VLC_OBJECT(a),b,c)
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
+#ifndef _VLC_PLAYLIST_H_
+#define _VLC_PLAYLIST_H_
+
/**
* \file
* This file contain structures and function prototypes related
{
char *psz_filename;
FILE *p_file;
-};
-
-struct item_parent_t
-{
- int i_view;
- playlist_item_t *p_parent;
+ playlist_item_t *p_root;
};
/**
*/
struct playlist_item_t
{
- input_item_t input; /**< input item descriptor */
+ input_item_t *p_input; /**< input item descriptor */
/* Tree specific fields */
int i_children; /**< Number of children
-1 if not a node */
playlist_item_t **pp_children; /**< Children nodes/items */
- int i_parents; /**< Number of parents */
- struct item_parent_t **pp_parents; /**< Parents */
- int i_serial; /**< Has this node been updated ? */
-
- uint8_t i_flags; /**< Flags */
-
+ playlist_item_t *p_parent; /**< Item parent */
- int i_nb_played; /**< How many times was this item played ? */
+ int i_id; /**< Playlist item specific id */
- /* LEGACY FIELDS */
- vlc_bool_t b_autodeletion; /**< Indicates whther this item is to
- * be deleted after playback. True mean
- * that this item is to be deleted
- * after playback, false otherwise */
- vlc_bool_t b_enabled; /**< Indicates whether this item is to be
- * played or skipped */
- /* END LEGACY FIELDS */
+ uint8_t i_flags; /**< Flags */
};
-#define PLAYLIST_SAVE_FLAG 0x01 /**< Must it be saved */
-#define PLAYLIST_SKIP_FLAG 0x02 /**< Must playlist skip after it ? */
-#define PLAYLIST_ENA_FLAG 0x04 /**< Is it enabled ? */
-#define PLAYLIST_DEL_FLAG 0x08 /**< Autodelete ? */
+#define PLAYLIST_SAVE_FLAG 0x01 /**< Must it be saved */
+#define PLAYLIST_SKIP_FLAG 0x02 /**< Must playlist skip after it ? */
+#define PLAYLIST_DBL_FLAG 0x04 /**< Is it disabled ? */
#define PLAYLIST_RO_FLAG 0x10 /**< Write-enabled ? */
#define PLAYLIST_REMOVE_FLAG 0x20 /**< Remove this item at the end */
-
-/**
- * playlist view
- * \see playlist_t
-*/
-struct playlist_view_t
-{
- char * psz_name; /**< View name */
- int i_id; /**< Identifier for the view */
- playlist_item_t * p_root; /**< Root node */
-};
-
-
-/**
- * predefined views
- *
- */
-#define VIEW_CATEGORY 1
-#define VIEW_SIMPLE 2
-#define VIEW_ALL 3
-#define VIEW_FIRST_SORTED 4
-#define VIEW_S_AUTHOR 4
-#define VIEW_S_GENRE 5
-#define VIEW_S_ALBUM 6
-
-#define VIEW_LAST_SORTED 10
-
-#define VIEW_FIRST_CUSTOM 100
+#define PLAYLIST_EXPANDED_FLAG 0x40 /**< Expanded node */
/**
* Playlist status
*/
-typedef enum { PLAYLIST_STOPPED,PLAYLIST_RUNNING,PLAYLIST_PAUSED } playlist_status_t;
+typedef enum
+{ PLAYLIST_STOPPED,PLAYLIST_RUNNING,PLAYLIST_PAUSED } playlist_status_t;
struct services_discovery_t
VLC_COMMON_MEMBERS
vlc_mutex_t lock;
int i_waiting;
- int *pi_waiting;
+ input_item_t **pp_waiting;
};
These members are uniq to playlist_t
*/
/*@{*/
- int i_index; /**< current index into the playlist */
int i_enabled; /**< How many items are enabled ? */
int i_size; /**< total size of the list */
int i_all_size; /**< size of list of items and nodes */
playlist_item_t ** pp_all_items; /**< array of pointers to the
* playlist items and nodes */
+ int i_last_playlist_id; /**< Last id to an item */
- int i_views; /**< Number of views */
- playlist_view_t ** pp_views; /**< array of pointers to the
- * playlist views */
+ int i_input_items;
+ input_item_t ** pp_input_items;
- input_thread_t * p_input; /**< the input thread ascosiated
- * with the current item */
+ int i_last_input_id ;
- mtime_t request_date; /**< Used for profiling */
+ input_thread_t * p_input; /**< the input thread associated
+ * with the current item */
- int i_last_id; /**< Last id to an item */
int i_sort; /**< Last sorting applied to the playlist */
int i_order; /**< Last ordering applied to the playlist */
- playlist_item_t * p_general; /**< Keep a pointer on the "general"
- category */
+ playlist_item_t * p_root_category;
+ playlist_item_t * p_root_onelevel;
+
+ playlist_item_t * p_local_category; /** < "Playlist" in CATEGORY view */
+ playlist_item_t * p_ml_category; /** < "Library" in CATEGORY view */
+ playlist_item_t * p_local_onelevel; /** < "Playlist" in ONELEVEL view */
+ playlist_item_t * p_ml_onelevel; /** < "Library" in ONELEVEL iew */
services_discovery_t **pp_sds;
int i_sds;
- vlc_bool_t b_go_next; /*< Go further than the parent node ? */
-
struct {
- /* Current status */
+ /* Current status. These fields are readonly, only the playlist
+ * main loop can touch it*/
playlist_status_t i_status; /**< Current status of playlist */
-
- /* R/O fields, don't touch if you aren't the playlist thread */
- /* Use a request */
playlist_item_t * p_item; /**< Currently playing/active item */
- playlist_item_t * p_node; /**< Current node to play from */
- int i_view; /**< Current view */
+ playlist_item_t * p_node; /**< Current node to play from */
} status;
struct {
- /* Request */
- /* Playlist thread uses this info to calculate the next position */
- int i_view; /**< requested view id */
+ /* Request. Use this to give orders to the playlist main loop */
+ int i_status; /**< requested playlist status */
playlist_item_t * p_node; /**< requested node to play from */
playlist_item_t * p_item; /**< requested item to play in the node */
int i_skip; /**< Number of items to skip */
- int i_goto; /**< Direct index to go to (non-view)*/
- vlc_bool_t b_request; /**< Set to true by the requester
- The playlist sets it back to false
- when processing the request */
- vlc_mutex_t lock; /**< Lock to protect request */
+ vlc_bool_t b_request;/**< Set to true by the requester
+ The playlist sets it back to false
+ when processing the request */
+ vlc_mutex_t lock; /**< Lock to protect request */
} request;
- playlist_preparse_t *p_preparse;
+ playlist_preparse_t *p_preparse; /**< Preparser object */
vlc_mutex_t gc_lock; /**< Lock to protect the garbage collection */
- // The following members are about user interaction
- // The playlist manages the user interaction to avoid creating another
- // thread
- interaction_t *p_interaction;
-
- global_stats_t *p_stats;
+ // Playlist-unrelated fields
+ interaction_t *p_interaction; /**< Interaction manager */
+ global_stats_t *p_stats; /**< Global statistics */
/*@}*/
};
* Prototypes
*****************************************************************************/
+/* Global thread */
+#define playlist_ThreadCreate(a) __playlist_ThreadCreate(VLC_OBJECT(a))
+playlist_t *__playlist_ThreadCreate ( vlc_object_t * );
+int playlist_ThreadDestroy ( playlist_t * );
+
+/* Helpers */
+#define PL_LOCK vlc_mutex_lock( &p_playlist->object_lock );
+#define PL_UNLOCK vlc_mutex_unlock( &p_playlist->object_lock );
+
/* Creation/Deletion */
-#define playlist_Create(a) __playlist_Create(VLC_OBJECT(a))
-playlist_t * __playlist_Create ( vlc_object_t * );
-int playlist_Destroy ( playlist_t * );
+playlist_t *playlist_Create ( vlc_object_t * );
+void playlist_Destroy ( playlist_t * );
+
+/* Engine */
+void playlist_MainLoop( playlist_t * );
+void playlist_LastLoop( playlist_t * );
+void playlist_PreparseLoop( playlist_preparse_t * );
+
+/* Control */
+playlist_item_t * playlist_NextItem ( playlist_t * );
+int playlist_PlayItem ( playlist_t *, playlist_item_t * );
/* Playlist control */
#define playlist_Play(p) playlist_LockControl(p,PLAYLIST_PLAY )
#define playlist_Next(p) playlist_LockControl(p,PLAYLIST_SKIP, 1)
#define playlist_Prev(p) playlist_LockControl(p,PLAYLIST_SKIP, -1)
#define playlist_Skip(p,i) playlist_LockControl(p,PLAYLIST_SKIP, i)
-#define playlist_Goto(p,i) playlist_LockControl(p,PLAYLIST_GOTO, i)
VLC_EXPORT( int, playlist_Control, ( playlist_t *, int, ... ) );
VLC_EXPORT( int, playlist_LockControl, ( playlist_t *, int, ... ) );
-VLC_EXPORT( int, playlist_Clear, ( playlist_t * ) );
-VLC_EXPORT( int, playlist_LockClear, ( playlist_t * ) );
+VLC_EXPORT( void, playlist_Clear, ( playlist_t * ) );
+VLC_EXPORT( void, playlist_LockClear, ( playlist_t * ) );
VLC_EXPORT( int, playlist_PreparseEnqueue, (playlist_t *, input_item_t *) );
VLC_EXPORT( int, playlist_PreparseEnqueueItem, (playlist_t *, playlist_item_t *) );
/* Item management functions (act on items) */
-#define playlist_AddItem(p,pi,i1,i2) playlist_ItemAdd(p,pi,i1,i2)
#define playlist_ItemNew( a , b, c ) __playlist_ItemNew(VLC_OBJECT(a) , b , c )
#define playlist_ItemCopy( a, b ) __playlist_ItemCopy(VLC_OBJECT(a), b )
VLC_EXPORT( playlist_item_t* , __playlist_ItemNew, ( vlc_object_t *,const char *,const char * ) );
VLC_EXPORT( playlist_item_t* , __playlist_ItemCopy, ( vlc_object_t *,playlist_item_t* ) );
-VLC_EXPORT( playlist_item_t* , playlist_ItemNewWithType, ( vlc_object_t *,const char *,const char *, int ) );
+VLC_EXPORT( playlist_item_t* , playlist_ItemNewWithType, ( vlc_object_t *,const char *,const char *, int , const char **, int, int) );
+#define playlist_ItemNewFromInput(a,b) __playlist_ItemNewFromInput(VLC_OBJECT(a),b)
+VLC_EXPORT( playlist_item_t *, __playlist_ItemNewFromInput, ( vlc_object_t *p_obj,input_item_t *p_input ) );
+
+
VLC_EXPORT( int, playlist_ItemDelete, ( playlist_item_t * ) );
-VLC_EXPORT( int, playlist_ItemAddParent, ( playlist_item_t *, int,playlist_item_t *) );
-VLC_EXPORT( int, playlist_CopyParents, ( playlist_item_t *,playlist_item_t *) );
+
/* Item informations accessors */
VLC_EXPORT( int, playlist_ItemSetName, (playlist_item_t *, char * ) );
VLC_EXPORT( int, playlist_ItemSetDuration, (playlist_item_t *, mtime_t ) );
+VLC_EXPORT( void, playlist_ItemAddOption, (playlist_item_t *, const char *) );
-/* View management functions */
-VLC_EXPORT( int, playlist_ViewInsert, (playlist_t *, int, char * ) );
-VLC_EXPORT( int, playlist_ViewDelete, (playlist_t *,playlist_view_t* ) );
-VLC_EXPORT( playlist_view_t *, playlist_ViewFind, (playlist_t *, int ) );
-VLC_EXPORT( int, playlist_ViewUpdate, (playlist_t *, int ) );
-VLC_EXPORT( int, playlist_ViewDump, (playlist_t *, playlist_view_t * ) );
-VLC_EXPORT( int, playlist_ViewEmpty, (playlist_t *, int, vlc_bool_t ) );
+VLC_EXPORT(void, playlist_NodeDump, ( playlist_t *p_playlist, playlist_item_t *p_item, int i_level ) );
+
+/** Counts the items of a view */
+VLC_EXPORT( int, playlist_NodeChildrenCount, (playlist_t *,playlist_item_t* ) );
/* Node management */
-VLC_EXPORT( playlist_item_t *, playlist_NodeCreate, ( playlist_t *,int,char *, playlist_item_t * p_parent ) );
-VLC_EXPORT( int, playlist_NodeAppend, (playlist_t *,int,playlist_item_t*,playlist_item_t *) );
-VLC_EXPORT( int, playlist_NodeInsert, (playlist_t *,int,playlist_item_t*,playlist_item_t *, int) );
+VLC_EXPORT( playlist_item_t *, playlist_NodeCreate, ( playlist_t *, char *, playlist_item_t * p_parent ) );
+VLC_EXPORT( int, playlist_NodeAppend, (playlist_t *,playlist_item_t*,playlist_item_t *) );
+VLC_EXPORT( int, playlist_NodeInsert, (playlist_t *,playlist_item_t*,playlist_item_t *, int) );
VLC_EXPORT( int, playlist_NodeRemoveItem, (playlist_t *,playlist_item_t*,playlist_item_t *) );
-VLC_EXPORT( int, playlist_NodeRemoveParent, (playlist_t *,playlist_item_t*,playlist_item_t *) );
-VLC_EXPORT( int, playlist_NodeChildrenCount, (playlist_t *,playlist_item_t* ) );
VLC_EXPORT( playlist_item_t *, playlist_ChildSearchName, (playlist_item_t*, const char* ) );
VLC_EXPORT( int, playlist_NodeDelete, ( playlist_t *, playlist_item_t *, vlc_bool_t , vlc_bool_t ) );
VLC_EXPORT( int, playlist_NodeEmpty, ( playlist_t *, playlist_item_t *, vlc_bool_t ) );
-/* Tree walking */
-playlist_item_t *playlist_FindNextFromParent( playlist_t *p_playlist,
- int i_view,
- playlist_item_t *p_root,
- playlist_item_t *p_node,
- playlist_item_t *p_item );
-playlist_item_t *playlist_FindPrevFromParent( playlist_t *p_playlist,
- int i_view,
- playlist_item_t *p_root,
- playlist_item_t *p_node,
- playlist_item_t *p_item );
+/* Tree walking - These functions are only for playlist, not plugins */
+playlist_item_t *playlist_GetNextLeaf( playlist_t *p_playlist,
+ playlist_item_t *p_root,
+ playlist_item_t *p_item );
+playlist_item_t *playlist_GetNextEnabledLeaf( playlist_t *p_playlist,
+ playlist_item_t *p_root,
+ playlist_item_t *p_item );
+playlist_item_t *playlist_GetPrevLeaf( playlist_t *p_playlist,
+ playlist_item_t *p_root,
+ playlist_item_t *p_item );
+playlist_item_t *playlist_GetLastLeaf( playlist_t *p_playlist,
+ playlist_item_t *p_root );
/* Simple add/remove functions */
-/* These functions add the item to the "simple" view (+all & category )*/
-VLC_EXPORT( int, playlist_Add, ( playlist_t *, const char *, const char *, int, int ) );
-VLC_EXPORT( int, playlist_AddExt, ( playlist_t *, const char *, const char *, int, int, mtime_t, const char **,int ) );
-VLC_EXPORT( int, playlist_ItemAdd, ( playlist_t *, playlist_item_t *, int, int ) );
-VLC_EXPORT(int, playlist_NodeAddItem, ( playlist_t *, playlist_item_t *,int,playlist_item_t *,int , int ) );
+VLC_EXPORT( int, playlist_PlaylistAdd, ( playlist_t *, const char *, const char *, int, int ) );
+VLC_EXPORT( int, playlist_PlaylistAddExt, ( playlist_t *, const char *, const char *, int, int, mtime_t, const char **,int ) );
+VLC_EXPORT( int, playlist_PlaylistAddInput, ( playlist_t *, input_item_t *,int , int ) );
+VLC_EXPORT( playlist_item_t *, playlist_NodeAddInput, ( playlist_t *, input_item_t *,playlist_item_t *,int , int ) );
+VLC_EXPORT( void, playlist_NodeAddItem, ( playlist_t *, playlist_item_t *, playlist_item_t *,int , int ) );
+VLC_EXPORT( int, playlist_BothAddInput, ( playlist_t *, input_item_t *,playlist_item_t *,int , int ) );
+VLC_EXPORT( void, playlist_AddWhereverNeeded, (playlist_t* , input_item_t*, playlist_item_t*,playlist_item_t*,vlc_bool_t, int ) );
+
+void playlist_SendAddNotify( playlist_t *p_playlist, int i_item_id, int i_node_id );
/* Misc item operations (act on item+playlist) */
-VLC_EXPORT( int, playlist_Delete, ( playlist_t *, int ) );
+VLC_EXPORT( int, playlist_DeleteAllFromInput, ( playlist_t *, int ) );
+VLC_EXPORT( int, playlist_DeleteFromInput, ( playlist_t *, int, playlist_item_t *, vlc_bool_t ) );
+VLC_EXPORT( int, playlist_DeleteFromItemId, ( playlist_t *, int ) );
VLC_EXPORT( int, playlist_LockDelete, ( playlist_t *, int ) );
-VLC_EXPORT( int, playlist_Disable, ( playlist_t *, playlist_item_t * ) );
-VLC_EXPORT( int, playlist_Enable, ( playlist_t *, playlist_item_t * ) );
-VLC_EXPORT( int, playlist_ItemToNode, (playlist_t *,playlist_item_t *) );
-VLC_EXPORT( int, playlist_LockItemToNode, (playlist_t *,playlist_item_t *) );
-VLC_EXPORT( int, playlist_Replace, (playlist_t *,playlist_item_t *, input_item_t*) );
-VLC_EXPORT( int, playlist_LockReplace, (playlist_t *,playlist_item_t *, input_item_t*) );
+VLC_EXPORT( int, playlist_LockDeleteAllFromInput, ( playlist_t *, int ) );
+VLC_EXPORT( playlist_item_t*, playlist_ItemToNode, (playlist_t *,playlist_item_t *) );
+VLC_EXPORT( playlist_item_t*, playlist_LockItemToNode, (playlist_t *,playlist_item_t *) );
+playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist,
+ int i_input_id, playlist_item_t *p_root );
/* Item search functions */
VLC_EXPORT( playlist_item_t *, playlist_ItemGetById, (playlist_t *, int) );
-VLC_EXPORT( playlist_item_t *, playlist_LockItemGetById, (playlist_t *, int) );
-VLC_EXPORT( playlist_item_t *, playlist_ItemGetByPos, (playlist_t *, int) );
-VLC_EXPORT( playlist_item_t *, playlist_LockItemGetByPos, (playlist_t *, int) );
VLC_EXPORT( playlist_item_t *, playlist_ItemGetByInput, (playlist_t *,input_item_t * ) );
-VLC_EXPORT( playlist_item_t *, playlist_LockItemGetByInput, (playlist_t *,input_item_t * ) );
-VLC_EXPORT( int, playlist_GetPositionById, (playlist_t *,int ) );
-VLC_EXPORT( int, playlist_ItemAddOption, (playlist_item_t *, const char *) );
+static inline playlist_item_t *playlist_LockItemGetById( playlist_t *p_playlist,
+ int i_id)
+{
+ playlist_item_t *p_ret;
+ vlc_mutex_lock( &p_playlist->object_lock );
+ p_ret = playlist_ItemGetById( p_playlist, i_id );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ return p_ret;
+}
+
+static inline playlist_item_t *playlist_LockItemGetByInput(
+ playlist_t *p_playlist, input_item_t *p_item )
+{
+ playlist_item_t *p_ret;
+ vlc_mutex_lock( &p_playlist->object_lock );
+ p_ret = playlist_ItemGetByInput( p_playlist, p_item );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ return p_ret;
+}
+
+VLC_EXPORT( int, playlist_LiveSearchUpdate, (playlist_t *, playlist_item_t *, const char *) );
/* Playlist sorting */
#define playlist_SortID(p, i) playlist_Sort( p, SORT_ID, i)
#define playlist_SortAuthor(p, i) playlist_Sort( p, SORT_AUTHOR, i)
#define playlist_SortAlbum(p, i) playlist_Sort( p, SORT_ALBUM, i)
#define playlist_SortGroup(p, i) playlist_Sort( p, SORT_GROUP, i)
-VLC_EXPORT( int, playlist_Sort, ( playlist_t *, int, int) );
-VLC_EXPORT( int, playlist_Move, ( playlist_t *, int, int ) );
-VLC_EXPORT( int, playlist_TreeMove, ( playlist_t *, playlist_item_t *, playlist_item_t *, int, int ) );
-VLC_EXPORT( int, playlist_NodeGroup, ( playlist_t *, int,playlist_item_t *,playlist_item_t **,int, int, int ) );
+VLC_EXPORT( int, playlist_TreeMove, ( playlist_t *, playlist_item_t *, playlist_item_t *, int ) );
+VLC_EXPORT( int, playlist_NodeGroup, ( playlist_t *, playlist_item_t *,playlist_item_t **,int, int, int ) );
VLC_EXPORT( int, playlist_NodeSort, ( playlist_t *, playlist_item_t *,int, int ) );
VLC_EXPORT( int, playlist_RecursiveNodeSort, ( playlist_t *, playlist_item_t *,int, int ) );
/* Load/Save */
VLC_EXPORT( int, playlist_Import, ( playlist_t *, const char * ) );
-VLC_EXPORT( int, playlist_Export, ( playlist_t *, const char *, const char * ) );
+VLC_EXPORT( int, playlist_Export, ( playlist_t *, const char *, playlist_item_t *, const char * ) );
/***********************************************************************
* Inline functions
***********************************************************************/
-
-/**
- * tell if a playlist is currently playing.
- * \param p_playlist the playlist to check
- * \return true if playlist is playing, false otherwise
- */
+/** Tell if the playlist is currently running */
static inline vlc_bool_t playlist_IsPlaying( playlist_t * p_playlist )
{
vlc_bool_t b_playing;
-
vlc_mutex_lock( &p_playlist->object_lock );
b_playing = p_playlist->status.i_status == PLAYLIST_RUNNING;
vlc_mutex_unlock( &p_playlist->object_lock );
-
return( b_playing );
}
-/**
- * tell if a playlist is currently empty
- * \param p_playlist the playlist to check
- * \return true if the playlist is empty, false otherwise
- */
+/** Tell if the playlist is empty */
static inline vlc_bool_t playlist_IsEmpty( playlist_t * p_playlist )
{
vlc_bool_t b_empty;
-
vlc_mutex_lock( &p_playlist->object_lock );
b_empty = p_playlist->i_size == 0;
vlc_mutex_unlock( &p_playlist->object_lock );
-
return( b_empty );
}
-
-
/**
* @}
*/
+
+#endif
void (*vlc_list_release_inner) (vlc_list_t *);
int (*playlist_Control_inner) (playlist_t *, int, ...);
int (*playlist_LockControl_inner) (playlist_t *, int, ...);
- int (*playlist_Clear_inner) (playlist_t *);
- int (*playlist_LockClear_inner) (playlist_t *);
+ void (*playlist_Clear_inner) (playlist_t *);
+ void (*playlist_LockClear_inner) (playlist_t *);
int (*playlist_PreparseEnqueue_inner) (playlist_t *, input_item_t *);
int (*playlist_ServicesDiscoveryAdd_inner) (playlist_t *, const char *);
int (*playlist_ServicesDiscoveryRemove_inner) (playlist_t *, const char *);
vlc_bool_t (*playlist_IsServicesDiscoveryLoaded_inner) (playlist_t *,const char *);
playlist_item_t* (*__playlist_ItemNew_inner) (vlc_object_t *,const char *,const char *);
playlist_item_t* (*__playlist_ItemCopy_inner) (vlc_object_t *,playlist_item_t*);
- playlist_item_t* (*playlist_ItemNewWithType_inner) (vlc_object_t *,const char *,const char *, int);
+ playlist_item_t* (*playlist_ItemNewWithType_inner) (vlc_object_t *,const char *,const char *, int , const char **, int, int);
int (*playlist_ItemDelete_inner) (playlist_item_t *);
- int (*playlist_ItemAddParent_inner) (playlist_item_t *, int,playlist_item_t *);
- int (*playlist_CopyParents_inner) (playlist_item_t *,playlist_item_t *);
+ void *playlist_ItemAddParent_deprecated;
+ void *playlist_CopyParents_deprecated;
int (*playlist_ItemSetName_inner) (playlist_item_t *, char *);
int (*playlist_ItemSetDuration_inner) (playlist_item_t *, mtime_t);
- int (*playlist_ViewInsert_inner) (playlist_t *, int, char *);
- int (*playlist_ViewDelete_inner) (playlist_t *,playlist_view_t*);
- playlist_view_t * (*playlist_ViewFind_inner) (playlist_t *, int);
- int (*playlist_ViewUpdate_inner) (playlist_t *, int);
- int (*playlist_ViewDump_inner) (playlist_t *, playlist_view_t *);
- int (*playlist_ViewEmpty_inner) (playlist_t *, int, vlc_bool_t);
- playlist_item_t * (*playlist_NodeCreate_inner) (playlist_t *,int,char *, playlist_item_t * p_parent);
- int (*playlist_NodeAppend_inner) (playlist_t *,int,playlist_item_t*,playlist_item_t *);
- int (*playlist_NodeInsert_inner) (playlist_t *,int,playlist_item_t*,playlist_item_t *, int);
+ void *playlist_ViewInsert_deprecated;
+ void *playlist_ViewDelete_deprecated;
+ void *playlist_ViewFind_deprecated;
+ void *playlist_ViewUpdate_deprecated;
+ void *playlist_ViewDump_deprecated;
+ void *playlist_ViewEmpty_deprecated;
+ playlist_item_t * (*playlist_NodeCreate_inner) (playlist_t *, char *, playlist_item_t * p_parent);
+ int (*playlist_NodeAppend_inner) (playlist_t *,playlist_item_t*,playlist_item_t *);
+ int (*playlist_NodeInsert_inner) (playlist_t *,playlist_item_t*,playlist_item_t *, int);
int (*playlist_NodeRemoveItem_inner) (playlist_t *,playlist_item_t*,playlist_item_t *);
int (*playlist_NodeChildrenCount_inner) (playlist_t *,playlist_item_t*);
playlist_item_t * (*playlist_ChildSearchName_inner) (playlist_item_t*, const char*);
int (*playlist_NodeDelete_inner) (playlist_t *, playlist_item_t *, vlc_bool_t , vlc_bool_t);
int (*playlist_NodeEmpty_inner) (playlist_t *, playlist_item_t *, vlc_bool_t);
- int (*playlist_Add_inner) (playlist_t *, const char *, const char *, int, int);
- int (*playlist_AddExt_inner) (playlist_t *, const char *, const char *, int, int, mtime_t, const char **,int);
- int (*playlist_ItemAdd_inner) (playlist_t *, playlist_item_t *, int, int);
- int (*playlist_NodeAddItem_inner) (playlist_t *, playlist_item_t *,int,playlist_item_t *,int , int);
- int (*playlist_Delete_inner) (playlist_t *, int);
+ void *playlist_Add_deprecated;
+ void *playlist_AddExt_deprecated;
+ void *playlist_ItemAdd_deprecated;
+ void (*playlist_NodeAddItem_inner) (playlist_t *, playlist_item_t *, playlist_item_t *,int , int);
+ void *playlist_Delete_deprecated;
int (*playlist_LockDelete_inner) (playlist_t *, int);
- int (*playlist_Disable_inner) (playlist_t *, playlist_item_t *);
- int (*playlist_Enable_inner) (playlist_t *, playlist_item_t *);
- int (*playlist_ItemToNode_inner) (playlist_t *,playlist_item_t *);
- int (*playlist_LockItemToNode_inner) (playlist_t *,playlist_item_t *);
- int (*playlist_Replace_inner) (playlist_t *,playlist_item_t *, input_item_t*);
- int (*playlist_LockReplace_inner) (playlist_t *,playlist_item_t *, input_item_t*);
+ void *playlist_Disable_deprecated;
+ void *playlist_Enable_deprecated;
+ playlist_item_t* (*playlist_ItemToNode_inner) (playlist_t *,playlist_item_t *);
+ playlist_item_t* (*playlist_LockItemToNode_inner) (playlist_t *,playlist_item_t *);
+ void *playlist_Replace_deprecated;
+ void *playlist_LockReplace_deprecated;
playlist_item_t * (*playlist_ItemGetById_inner) (playlist_t *, int);
- playlist_item_t * (*playlist_LockItemGetById_inner) (playlist_t *, int);
- playlist_item_t * (*playlist_ItemGetByPos_inner) (playlist_t *, int);
- playlist_item_t * (*playlist_LockItemGetByPos_inner) (playlist_t *, int);
+ void *playlist_LockItemGetById_deprecated;
+ void *playlist_ItemGetByPos_deprecated;
+ void *playlist_LockItemGetByPos_deprecated;
playlist_item_t * (*playlist_ItemGetByInput_inner) (playlist_t *,input_item_t *);
- playlist_item_t * (*playlist_LockItemGetByInput_inner) (playlist_t *,input_item_t *);
- int (*playlist_GetPositionById_inner) (playlist_t *,int);
- int (*playlist_ItemAddOption_inner) (playlist_item_t *, const char *);
- int (*playlist_Sort_inner) (playlist_t *, int, int);
- int (*playlist_Move_inner) (playlist_t *, int, int);
- int (*playlist_NodeGroup_inner) (playlist_t *, int,playlist_item_t *,playlist_item_t **,int, int, int);
+ void *playlist_LockItemGetByInput_deprecated;
+ void *playlist_GetPositionById_deprecated;
+ void (*playlist_ItemAddOption_inner) (playlist_item_t *, const char *);
+ void *playlist_Sort_deprecated;
+ void *playlist_Move_deprecated;
+ int (*playlist_NodeGroup_inner) (playlist_t *, playlist_item_t *,playlist_item_t **,int, int, int);
int (*playlist_NodeSort_inner) (playlist_t *, playlist_item_t *,int, int);
int (*playlist_RecursiveNodeSort_inner) (playlist_t *, playlist_item_t *,int, int);
int (*playlist_Import_inner) (playlist_t *, const char *);
- int (*playlist_Export_inner) (playlist_t *, const char *, const char *);
+ int (*playlist_Export_inner) (playlist_t *, const char *, playlist_item_t *, const char *);
spu_t * (*__spu_Create_inner) (vlc_object_t *);
int (*spu_Init_inner) (spu_t *);
void (*spu_Destroy_inner) (spu_t *);
void (*net_ListenClose_inner) (int *fd);
void (*DigestMD5_inner) (struct md5_s *, uint32_t *);
int (*ACL_Check_inner) (vlc_acl_t *p_acl, const char *psz_ip);
- int (*playlist_NodeRemoveParent_inner) (playlist_t *,playlist_item_t*,playlist_item_t *);
+ void *playlist_NodeRemoveParent_deprecated;
vlc_acl_t * (*__ACL_Duplicate_inner) (vlc_object_t *p_this, const vlc_acl_t *p_acl);
vlc_acl_t * (*__ACL_Create_inner) (vlc_object_t *p_this, vlc_bool_t b_allow);
int (*ACL_LoadFile_inner) (vlc_acl_t *p_acl, const char *path);
char * (*FromLocaleDup_inner) (const char *);
int (*utf8_mkdir_inner) (const char *filename);
vlm_media_t* (*vlm_MediaSearch_inner) (vlm_t *, const char *);
- int (*playlist_TreeMove_inner) (playlist_t *, playlist_item_t *, playlist_item_t *, int, int);
+ int (*playlist_TreeMove_inner) (playlist_t *, playlist_item_t *, playlist_item_t *, int);
const char * (*config_GetDataDir_inner) (const vlc_object_t *);
double (*us_atof_inner) (const char *);
double (*us_strtod_inner) (const char *, char **);
void (*decode_URI_inner) (char *psz);
char * (*encode_URI_component_inner) (const char *psz);
size_t (*vlc_strlcpy_inner) (char *, const char *, size_t);
+ void *playlist_ItemNewFromInput_deprecated;
+ input_item_t * (*__input_ItemNewExt_inner) (vlc_object_t *, const char *, const char*, int, const char **, int);
+ input_item_t * (*input_ItemNewWithType_inner) (vlc_object_t *, const char *, const char *e, int, const char **, int, int);
+ playlist_item_t * (*playlist_NodeAddInput_inner) (playlist_t *, input_item_t *,playlist_item_t *,int , int);
+ int (*playlist_PlaylistAdd_inner) (playlist_t *, const char *, const char *, int, int);
+ int (*playlist_PlaylistAddExt_inner) (playlist_t *, const char *, const char *, int, int, mtime_t, const char **,int);
+ int (*playlist_PlaylistAddInput_inner) (playlist_t *, input_item_t *,int , int);
+ int (*playlist_BothAddInput_inner) (playlist_t *, input_item_t *,playlist_item_t *,int , int);
+ playlist_item_t * (*__playlist_ItemNewFromInput_inner) (vlc_object_t *p_obj,input_item_t *p_input);
+ input_item_t * (*input_ItemGetById_inner) (playlist_t *, int);
+ int (*playlist_LiveSearchUpdate_inner) (playlist_t *, playlist_item_t *, const char *);
+ void (*vlc_input_item_AddOption_inner) (input_item_t *p_input, const char *psz_option);
+ int (*playlist_DeleteFromInput_inner) (playlist_t *, int, playlist_item_t *, vlc_bool_t);
+ int (*playlist_DeleteAllFromInput_inner) (playlist_t *, int);
+ int (*playlist_LockDeleteAllFromInput_inner) (playlist_t *, int);
+ void (*playlist_AddWhereverNeeded_inner) (playlist_t* , input_item_t*, playlist_item_t*,playlist_item_t*,vlc_bool_t, int);
+ int (*playlist_DeleteFromItemId_inner) (playlist_t *, int);
+ void (*playlist_NodeDump_inner) (playlist_t *p_playlist, playlist_item_t *p_item, int i_level);
+ int (*__intf_UserOkayCancel_inner) (vlc_object_t*, const char*, const char*);
+ int (*__intf_UserStringInput_inner) (vlc_object_t*, const char*, const char*, char **);
};
# if defined (__PLUGIN__)
# define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner
# define __playlist_ItemCopy (p_symbols)->__playlist_ItemCopy_inner
# define playlist_ItemNewWithType (p_symbols)->playlist_ItemNewWithType_inner
# define playlist_ItemDelete (p_symbols)->playlist_ItemDelete_inner
-# define playlist_ItemAddParent (p_symbols)->playlist_ItemAddParent_inner
-# define playlist_CopyParents (p_symbols)->playlist_CopyParents_inner
# define playlist_ItemSetName (p_symbols)->playlist_ItemSetName_inner
# define playlist_ItemSetDuration (p_symbols)->playlist_ItemSetDuration_inner
-# define playlist_ViewInsert (p_symbols)->playlist_ViewInsert_inner
-# define playlist_ViewDelete (p_symbols)->playlist_ViewDelete_inner
-# define playlist_ViewFind (p_symbols)->playlist_ViewFind_inner
-# define playlist_ViewUpdate (p_symbols)->playlist_ViewUpdate_inner
-# define playlist_ViewDump (p_symbols)->playlist_ViewDump_inner
-# define playlist_ViewEmpty (p_symbols)->playlist_ViewEmpty_inner
# define playlist_NodeCreate (p_symbols)->playlist_NodeCreate_inner
# define playlist_NodeAppend (p_symbols)->playlist_NodeAppend_inner
# define playlist_NodeInsert (p_symbols)->playlist_NodeInsert_inner
# define playlist_ChildSearchName (p_symbols)->playlist_ChildSearchName_inner
# define playlist_NodeDelete (p_symbols)->playlist_NodeDelete_inner
# define playlist_NodeEmpty (p_symbols)->playlist_NodeEmpty_inner
-# define playlist_Add (p_symbols)->playlist_Add_inner
-# define playlist_AddExt (p_symbols)->playlist_AddExt_inner
-# define playlist_ItemAdd (p_symbols)->playlist_ItemAdd_inner
# define playlist_NodeAddItem (p_symbols)->playlist_NodeAddItem_inner
-# define playlist_Delete (p_symbols)->playlist_Delete_inner
# define playlist_LockDelete (p_symbols)->playlist_LockDelete_inner
-# define playlist_Disable (p_symbols)->playlist_Disable_inner
-# define playlist_Enable (p_symbols)->playlist_Enable_inner
# define playlist_ItemToNode (p_symbols)->playlist_ItemToNode_inner
# define playlist_LockItemToNode (p_symbols)->playlist_LockItemToNode_inner
-# define playlist_Replace (p_symbols)->playlist_Replace_inner
-# define playlist_LockReplace (p_symbols)->playlist_LockReplace_inner
# define playlist_ItemGetById (p_symbols)->playlist_ItemGetById_inner
-# define playlist_LockItemGetById (p_symbols)->playlist_LockItemGetById_inner
-# define playlist_ItemGetByPos (p_symbols)->playlist_ItemGetByPos_inner
-# define playlist_LockItemGetByPos (p_symbols)->playlist_LockItemGetByPos_inner
# define playlist_ItemGetByInput (p_symbols)->playlist_ItemGetByInput_inner
-# define playlist_LockItemGetByInput (p_symbols)->playlist_LockItemGetByInput_inner
-# define playlist_GetPositionById (p_symbols)->playlist_GetPositionById_inner
# define playlist_ItemAddOption (p_symbols)->playlist_ItemAddOption_inner
-# define playlist_Sort (p_symbols)->playlist_Sort_inner
-# define playlist_Move (p_symbols)->playlist_Move_inner
# define playlist_NodeGroup (p_symbols)->playlist_NodeGroup_inner
# define playlist_NodeSort (p_symbols)->playlist_NodeSort_inner
# define playlist_RecursiveNodeSort (p_symbols)->playlist_RecursiveNodeSort_inner
# define net_ListenClose (p_symbols)->net_ListenClose_inner
# define DigestMD5 (p_symbols)->DigestMD5_inner
# define ACL_Check (p_symbols)->ACL_Check_inner
-# define playlist_NodeRemoveParent (p_symbols)->playlist_NodeRemoveParent_inner
# define __ACL_Duplicate (p_symbols)->__ACL_Duplicate_inner
# define __ACL_Create (p_symbols)->__ACL_Create_inner
# define ACL_LoadFile (p_symbols)->ACL_LoadFile_inner
# define decode_URI (p_symbols)->decode_URI_inner
# define encode_URI_component (p_symbols)->encode_URI_component_inner
# define vlc_strlcpy (p_symbols)->vlc_strlcpy_inner
+# define __input_ItemNewExt (p_symbols)->__input_ItemNewExt_inner
+# define input_ItemNewWithType (p_symbols)->input_ItemNewWithType_inner
+# define playlist_NodeAddInput (p_symbols)->playlist_NodeAddInput_inner
+# define playlist_PlaylistAdd (p_symbols)->playlist_PlaylistAdd_inner
+# define playlist_PlaylistAddExt (p_symbols)->playlist_PlaylistAddExt_inner
+# define playlist_PlaylistAddInput (p_symbols)->playlist_PlaylistAddInput_inner
+# define playlist_BothAddInput (p_symbols)->playlist_BothAddInput_inner
+# define __playlist_ItemNewFromInput (p_symbols)->__playlist_ItemNewFromInput_inner
+# define input_ItemGetById (p_symbols)->input_ItemGetById_inner
+# define playlist_LiveSearchUpdate (p_symbols)->playlist_LiveSearchUpdate_inner
+# define vlc_input_item_AddOption (p_symbols)->vlc_input_item_AddOption_inner
+# define playlist_DeleteFromInput (p_symbols)->playlist_DeleteFromInput_inner
+# define playlist_DeleteAllFromInput (p_symbols)->playlist_DeleteAllFromInput_inner
+# define playlist_LockDeleteAllFromInput (p_symbols)->playlist_LockDeleteAllFromInput_inner
+# define playlist_AddWhereverNeeded (p_symbols)->playlist_AddWhereverNeeded_inner
+# define playlist_DeleteFromItemId (p_symbols)->playlist_DeleteFromItemId_inner
+# define playlist_NodeDump (p_symbols)->playlist_NodeDump_inner
+# define __intf_UserOkayCancel (p_symbols)->__intf_UserOkayCancel_inner
+# define __intf_UserStringInput (p_symbols)->__intf_UserStringInput_inner
# elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__)
/******************************************************************
* STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access.
((p_symbols)->__playlist_ItemCopy_inner) = __playlist_ItemCopy; \
((p_symbols)->playlist_ItemNewWithType_inner) = playlist_ItemNewWithType; \
((p_symbols)->playlist_ItemDelete_inner) = playlist_ItemDelete; \
- ((p_symbols)->playlist_ItemAddParent_inner) = playlist_ItemAddParent; \
- ((p_symbols)->playlist_CopyParents_inner) = playlist_CopyParents; \
((p_symbols)->playlist_ItemSetName_inner) = playlist_ItemSetName; \
((p_symbols)->playlist_ItemSetDuration_inner) = playlist_ItemSetDuration; \
- ((p_symbols)->playlist_ViewInsert_inner) = playlist_ViewInsert; \
- ((p_symbols)->playlist_ViewDelete_inner) = playlist_ViewDelete; \
- ((p_symbols)->playlist_ViewFind_inner) = playlist_ViewFind; \
- ((p_symbols)->playlist_ViewUpdate_inner) = playlist_ViewUpdate; \
- ((p_symbols)->playlist_ViewDump_inner) = playlist_ViewDump; \
- ((p_symbols)->playlist_ViewEmpty_inner) = playlist_ViewEmpty; \
((p_symbols)->playlist_NodeCreate_inner) = playlist_NodeCreate; \
((p_symbols)->playlist_NodeAppend_inner) = playlist_NodeAppend; \
((p_symbols)->playlist_NodeInsert_inner) = playlist_NodeInsert; \
((p_symbols)->playlist_ChildSearchName_inner) = playlist_ChildSearchName; \
((p_symbols)->playlist_NodeDelete_inner) = playlist_NodeDelete; \
((p_symbols)->playlist_NodeEmpty_inner) = playlist_NodeEmpty; \
- ((p_symbols)->playlist_Add_inner) = playlist_Add; \
- ((p_symbols)->playlist_AddExt_inner) = playlist_AddExt; \
- ((p_symbols)->playlist_ItemAdd_inner) = playlist_ItemAdd; \
((p_symbols)->playlist_NodeAddItem_inner) = playlist_NodeAddItem; \
- ((p_symbols)->playlist_Delete_inner) = playlist_Delete; \
((p_symbols)->playlist_LockDelete_inner) = playlist_LockDelete; \
- ((p_symbols)->playlist_Disable_inner) = playlist_Disable; \
- ((p_symbols)->playlist_Enable_inner) = playlist_Enable; \
((p_symbols)->playlist_ItemToNode_inner) = playlist_ItemToNode; \
((p_symbols)->playlist_LockItemToNode_inner) = playlist_LockItemToNode; \
- ((p_symbols)->playlist_Replace_inner) = playlist_Replace; \
- ((p_symbols)->playlist_LockReplace_inner) = playlist_LockReplace; \
((p_symbols)->playlist_ItemGetById_inner) = playlist_ItemGetById; \
- ((p_symbols)->playlist_LockItemGetById_inner) = playlist_LockItemGetById; \
- ((p_symbols)->playlist_ItemGetByPos_inner) = playlist_ItemGetByPos; \
- ((p_symbols)->playlist_LockItemGetByPos_inner) = playlist_LockItemGetByPos; \
((p_symbols)->playlist_ItemGetByInput_inner) = playlist_ItemGetByInput; \
- ((p_symbols)->playlist_LockItemGetByInput_inner) = playlist_LockItemGetByInput; \
- ((p_symbols)->playlist_GetPositionById_inner) = playlist_GetPositionById; \
((p_symbols)->playlist_ItemAddOption_inner) = playlist_ItemAddOption; \
- ((p_symbols)->playlist_Sort_inner) = playlist_Sort; \
- ((p_symbols)->playlist_Move_inner) = playlist_Move; \
((p_symbols)->playlist_NodeGroup_inner) = playlist_NodeGroup; \
((p_symbols)->playlist_NodeSort_inner) = playlist_NodeSort; \
((p_symbols)->playlist_RecursiveNodeSort_inner) = playlist_RecursiveNodeSort; \
((p_symbols)->net_ListenClose_inner) = net_ListenClose; \
((p_symbols)->DigestMD5_inner) = DigestMD5; \
((p_symbols)->ACL_Check_inner) = ACL_Check; \
- ((p_symbols)->playlist_NodeRemoveParent_inner) = playlist_NodeRemoveParent; \
((p_symbols)->__ACL_Duplicate_inner) = __ACL_Duplicate; \
((p_symbols)->__ACL_Create_inner) = __ACL_Create; \
((p_symbols)->ACL_LoadFile_inner) = ACL_LoadFile; \
((p_symbols)->decode_URI_inner) = decode_URI; \
((p_symbols)->encode_URI_component_inner) = encode_URI_component; \
((p_symbols)->vlc_strlcpy_inner) = vlc_strlcpy; \
+ ((p_symbols)->__input_ItemNewExt_inner) = __input_ItemNewExt; \
+ ((p_symbols)->input_ItemNewWithType_inner) = input_ItemNewWithType; \
+ ((p_symbols)->playlist_NodeAddInput_inner) = playlist_NodeAddInput; \
+ ((p_symbols)->playlist_PlaylistAdd_inner) = playlist_PlaylistAdd; \
+ ((p_symbols)->playlist_PlaylistAddExt_inner) = playlist_PlaylistAddExt; \
+ ((p_symbols)->playlist_PlaylistAddInput_inner) = playlist_PlaylistAddInput; \
+ ((p_symbols)->playlist_BothAddInput_inner) = playlist_BothAddInput; \
+ ((p_symbols)->__playlist_ItemNewFromInput_inner) = __playlist_ItemNewFromInput; \
+ ((p_symbols)->input_ItemGetById_inner) = input_ItemGetById; \
+ ((p_symbols)->playlist_LiveSearchUpdate_inner) = playlist_LiveSearchUpdate; \
+ ((p_symbols)->vlc_input_item_AddOption_inner) = vlc_input_item_AddOption; \
+ ((p_symbols)->playlist_DeleteFromInput_inner) = playlist_DeleteFromInput; \
+ ((p_symbols)->playlist_DeleteAllFromInput_inner) = playlist_DeleteAllFromInput; \
+ ((p_symbols)->playlist_LockDeleteAllFromInput_inner) = playlist_LockDeleteAllFromInput; \
+ ((p_symbols)->playlist_AddWhereverNeeded_inner) = playlist_AddWhereverNeeded; \
+ ((p_symbols)->playlist_DeleteFromItemId_inner) = playlist_DeleteFromItemId; \
+ ((p_symbols)->playlist_NodeDump_inner) = playlist_NodeDump; \
+ ((p_symbols)->__intf_UserOkayCancel_inner) = __intf_UserOkayCancel; \
+ ((p_symbols)->__intf_UserStringInput_inner) = __intf_UserStringInput; \
(p_symbols)->net_ConvertIPv4_deprecated = NULL; \
+ (p_symbols)->playlist_ItemAddParent_deprecated = NULL; \
+ (p_symbols)->playlist_CopyParents_deprecated = NULL; \
+ (p_symbols)->playlist_ViewInsert_deprecated = NULL; \
+ (p_symbols)->playlist_ViewDelete_deprecated = NULL; \
+ (p_symbols)->playlist_ViewFind_deprecated = NULL; \
+ (p_symbols)->playlist_ViewUpdate_deprecated = NULL; \
+ (p_symbols)->playlist_ViewDump_deprecated = NULL; \
+ (p_symbols)->playlist_ViewEmpty_deprecated = NULL; \
+ (p_symbols)->playlist_Add_deprecated = NULL; \
+ (p_symbols)->playlist_AddExt_deprecated = NULL; \
+ (p_symbols)->playlist_ItemAdd_deprecated = NULL; \
+ (p_symbols)->playlist_Delete_deprecated = NULL; \
+ (p_symbols)->playlist_Disable_deprecated = NULL; \
+ (p_symbols)->playlist_Enable_deprecated = NULL; \
+ (p_symbols)->playlist_Replace_deprecated = NULL; \
+ (p_symbols)->playlist_LockReplace_deprecated = NULL; \
+ (p_symbols)->playlist_LockItemGetById_deprecated = NULL; \
+ (p_symbols)->playlist_ItemGetByPos_deprecated = NULL; \
+ (p_symbols)->playlist_LockItemGetByPos_deprecated = NULL; \
+ (p_symbols)->playlist_LockItemGetByInput_deprecated = NULL; \
+ (p_symbols)->playlist_GetPositionById_deprecated = NULL; \
+ (p_symbols)->playlist_Sort_deprecated = NULL; \
+ (p_symbols)->playlist_Move_deprecated = NULL; \
+ (p_symbols)->playlist_NodeRemoveParent_deprecated = NULL; \
(p_symbols)->__stats_CounterGet_deprecated = NULL; \
(p_symbols)->__stats_TimerDumpAll_deprecated = NULL; \
+ (p_symbols)->playlist_ItemNewFromInput_deprecated = NULL; \
# endif /* __PLUGIN__ */
#endif /* __VLC_SYMBOLS_H */
if( !p_playlist ) return VLC_EGENERIC;
/* Let's check if we need to play */
- if( &p_playlist->status.p_item->input ==
+ if( p_playlist->status.p_item->p_input ==
((input_thread_t *)p_access->p_parent)->input.p_item )
{
p_item = p_playlist->status.p_item;
if( b_play )
{
playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- p_playlist->status.i_view, p_playlist->status.p_item,
- NULL );
+ p_playlist->status.p_item, NULL );
}
if( p_playlist ) vlc_object_release( p_playlist );
input_title_t ***ppp_title;
int i;
char *psz_title;
- vlc_meta_t **pp_meta;
+ vlc_meta_t *p_meta;
switch( i_query )
{
psz_title = malloc( strlen( _("Audio CD - Track ") ) + 5 );
snprintf( psz_title, 100, _("Audio CD - Track %i" ),
p_access->info.i_title+1 );
- pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
- *pp_meta = vlc_meta_New();
- vlc_meta_Add( *pp_meta, _(VLC_META_TITLE), psz_title );
+ p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
+ vlc_meta_SetTitle( p_meta, psz_title );
free( psz_title );
break;
{
access_sys_t *p_sys = p_access->p_sys;
int i;
- playlist_item_t *p_item;
+ input_item_t *p_input_item;
char *psz_name;
p_sys->i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access),
p_sys->vcddev, &p_sys->p_sectors );
playlist_ItemSetName( p_parent, psz_name );
vlc_mutex_unlock( &p_playlist->object_lock );
var_SetInteger( p_playlist, "item-change",
- p_parent->input.i_id );
+ p_parent->p_input->i_id );
free( psz_name );
#ifdef HAVE_LIBCDDB
playlist_ItemSetName( p_parent, psz_name );
vlc_mutex_unlock( &p_playlist->object_lock );
var_SetInteger( p_playlist, "item-change",
- p_parent->input.i_id );
+ p_parent->p_input->i_id );
free( psz_name );
}
}
sprintf( psz_name, _("Audio CD - Track %i"), (i+1) );
/* Create playlist items */
- p_item = playlist_ItemNewWithType( VLC_OBJECT( p_playlist ),
- psz_uri, psz_name, ITEM_TYPE_DISC );
- playlist_ItemAddOption( p_item, psz_opt );
+ p_input_item = input_ItemNewWithType( VLC_OBJECT( p_playlist ),
+ psz_uri, psz_name, 0, NULL, -1,
+ ITEM_TYPE_DISC );
+ vlc_input_item_AddOption( p_input_item, psz_opt );
#ifdef HAVE_LIBCDDB
/* If we have CDDB info, change the name */
if( p_sys->p_disc )
{
if( cddb_track_get_title( t ) != NULL )
{
- vlc_input_item_AddInfo( &p_item->input,
+ vlc_input_item_AddInfo( p_input_item,
_(VLC_META_INFO_CAT),
_(VLC_META_TITLE),
cddb_track_get_title( t ) );
- if( p_item->input.psz_name )
- free( p_item->input.psz_name );
- asprintf( &p_item->input.psz_name, "%s",
+ if( p_input_item->psz_name )
+ free( p_input_item->psz_name );
+ asprintf( &p_input_item->psz_name, "%s",
cddb_track_get_title( t ) );
}
psz_result = cddb_track_get_artist( t );
if( psz_result )
{
- vlc_input_item_AddInfo( &p_item->input,
+ vlc_input_item_AddInfo( p_input_item,
_(VLC_META_INFO_CAT),
_(VLC_META_ARTIST), psz_result );
}
}
}
#endif
- playlist_NodeAddItem( p_playlist, p_item,
- p_parent->pp_parents[0]->i_view,
- p_parent, PLAYLIST_APPEND, PLAYLIST_END );
+ playlist_BothAddInput( p_playlist, p_input_item, p_parent,
+ PLAYLIST_APPEND, PLAYLIST_END );
free( psz_uri ); free( psz_opt ); free( psz_name );
}
}
#if LIBCDIO_VERSION_NUM >= 72
static char *psz_paranoia_list[] = { "none", "overlap", "full" };
static char *psz_paranoia_list_text[] = { N_("none"), N_("overlap"),
- N_("full") };
+ N_("full") };
#endif
#define DEBUG_LONGTEXT N_( \
static int ReadDir( playlist_t *, const char *psz_name, int i_mode,
- playlist_item_t * );
+ playlist_item_t *, playlist_item_t * );
/*****************************************************************************
* Open: open the directory
{
char *psz_name = NULL;
char *psz;
- int i_mode, i_pos;
+ int i_mode, i_activity;
- playlist_item_t *p_item;
+ playlist_item_t *p_item, *p_root_category;
vlc_bool_t b_play = VLC_FALSE;
playlist_t *p_playlist =
msg_Err( p_access, "can't find playlist" );
goto end;
}
- else
- {
- char *ptr;
- psz_name = ToLocale( p_access->psz_path );
- ptr = strdup( psz_name );
- LocaleFree( psz_name );
- if( ptr == NULL )
- goto end;
+ char *ptr;
+ psz_name = ToLocale( p_access->psz_path );
+ ptr = strdup( psz_name );
+ LocaleFree( psz_name );
+ if( ptr == NULL )
+ goto end;
- psz_name = ptr;
+ psz_name = ptr;
- /* Remove the ending '/' char */
- ptr += strlen( ptr );
- if( ( ptr > psz_name ) )
+ /* Remove the ending '/' char */
+ ptr += strlen( ptr );
+ if( ( ptr > psz_name ) )
+ {
+ switch( *--ptr )
{
- switch( *--ptr )
- {
- case '/':
- case '\\':
- *ptr = '\0';
- }
+ case '/':
+ case '\\':
+ *ptr = '\0';
}
}
- /* Initialize structure */
+ /* Handle mode */
psz = var_CreateGetString( p_access, "recursive" );
if( *psz == '\0' || !strncmp( psz, "none" , 4 ) )
- {
i_mode = MODE_NONE;
- }
else if( !strncmp( psz, "collapse", 8 ) )
- {
i_mode = MODE_COLLAPSE;
- }
else
- {
i_mode = MODE_EXPAND;
- }
free( psz );
- /* Make sure we are deleted when we are done */
- /* The playlist position we will use for the add */
- i_pos = p_playlist->i_index + 1;
-
msg_Dbg( p_access, "opening directory `%s'", p_access->psz_path );
- if( &p_playlist->status.p_item->input ==
+ if( p_playlist->status.p_item->p_input ==
((input_thread_t *)p_access->p_parent)->input.p_item )
{
p_item = p_playlist->status.p_item;
}
b_play = VLC_FALSE;
}
+ p_item->p_input->i_type = ITEM_TYPE_DIRECTORY;
- p_item->input.i_type = ITEM_TYPE_DIRECTORY;
- if( ReadDir( p_playlist, psz_name , i_mode, p_item ) != VLC_SUCCESS )
- {
- }
+ p_root_category = playlist_LockItemToNode( p_playlist, p_item );
+
+ i_activity = var_GetInteger( p_playlist, "activity" );
+ var_SetInteger( p_playlist, "activity", i_activity +
+ DIRECTORY_ACTIVITY );
+
+ ReadDir( p_playlist, psz_name , i_mode, p_item, p_root_category );
+
+ i_activity = var_GetInteger( p_playlist, "activity" );
+ var_SetInteger( p_playlist, "activity", i_activity -
+ DIRECTORY_ACTIVITY );
end:
/* Begin to read the directory */
if( b_play )
{
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- p_playlist->status.i_view,
+#if 0
+ /// \bug we can start playing an already deleted item. Fix ?*/
+ playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, 1242,
p_playlist->status.p_item, NULL );
+#endif
}
if( psz_name ) free( psz_name );
vlc_object_release( p_playlist );
* ReadDir: read a directory and add its content to the list
*****************************************************************************/
static int ReadDir( playlist_t *p_playlist, const char *psz_name,
- int i_mode, playlist_item_t *p_parent )
+ int i_mode, playlist_item_t *p_parent,
+ playlist_item_t *p_parent_category )
{
struct dirent **pp_dir_content;
int i_dir_content, i;
}
}
- /* Change the item to a node */
- if( p_parent->i_children == -1 )
- {
- playlist_LockItemToNode( p_playlist,p_parent );
- }
-
/* get the first directory entry */
i_dir_content = scandir( psz_name, &pp_dir_content, Filter, alphasort );
if( i_dir_content == -1 )
p_playlist, psz_tmp );
LocaleFree( psz_tmp );
- p_node = playlist_NodeCreate( p_playlist,
- p_parent->pp_parents[0]->i_view,
- psz_newname, p_parent );
-
- playlist_CopyParents( p_parent, p_node );
-
- p_node->input.i_type = ITEM_TYPE_DIRECTORY;
+ if( p_parent_category )
+ {
+ p_node = playlist_NodeCreate( p_playlist, psz_newname,
+ p_parent_category );
+ }
+ else
+ {
+ p_node = playlist_NodeCreate( p_playlist, psz_newname,
+ p_parent_category );
+ }
+ /* If we had the parent in category, the it is now node.
+ * Else, we still don't have */
if( ReadDir( p_playlist, psz_uri , MODE_EXPAND,
- p_node ) != VLC_SUCCESS )
+ p_node, p_parent_category ? p_node : NULL )
+ != VLC_SUCCESS )
{
return VLC_EGENERIC;
}
}
else
{
- playlist_item_t *p_item;
+ input_item_t *p_input;
char *psz_tmp1, *psz_tmp2, *psz_loc;
if( i_extensions > 0 )
psz_loc );
LocaleFree( psz_loc );
- p_item = playlist_ItemNewWithType( VLC_OBJECT(p_playlist),
- psz_tmp1, psz_tmp2, ITEM_TYPE_VFILE );
- playlist_NodeAddItem( p_playlist,p_item,
- p_parent->pp_parents[0]->i_view,
- p_parent,
- PLAYLIST_APPEND | PLAYLIST_PREPARSE,
- PLAYLIST_END );
+ p_input = input_ItemNewWithType( VLC_OBJECT(p_playlist),
+ psz_tmp1, psz_tmp2, 0, NULL,
+ -1, ITEM_TYPE_VFILE );
- playlist_CopyParents( p_parent, p_item );
+ playlist_AddWhereverNeeded( p_playlist, p_input, p_parent,
+ p_parent_category, VLC_FALSE,
+ PLAYLIST_APPEND|PLAYLIST_PREPARSE);
}
}
free( psz_uri );
dvdnav_get_title_string(p_sys->dvdnav, &title_name);
if( (NULL != title_name) && ('\0' != title_name[0]) )
{
- vlc_meta_t **pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
- vlc_meta_t *meta;
- *pp_meta = meta = vlc_meta_New();
- vlc_meta_Add( meta, VLC_META_TITLE, title_name );
+ vlc_meta_t *p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
+ vlc_meta_SetTitle( p_meta, title_name );
return VLC_SUCCESS;
}
return VLC_EGENERIC;
goto error;
}
- /* Change the uri */
+ /* Change the URI */
vlc_mutex_lock( &p_playlist->object_lock );
- p_input_item = &p_playlist->status.p_item->input;
+ p_input_item = p_playlist->status.p_item->p_input;
vlc_mutex_lock( &p_input_item->lock );
free( p_input_item->psz_uri );
free( p_access->psz_path );
vlc_bool_t *pb_bool;
int *pi_int;
int64_t *pi_64;
- vlc_meta_t **pp_meta;
+ vlc_meta_t *p_meta;
switch( i_query )
{
break;
case ACCESS_GET_META:
- pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
- *pp_meta = vlc_meta_New();
+ p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
if( p_sys->psz_icy_name )
- vlc_meta_Add( *pp_meta, VLC_META_TITLE,
- p_sys->psz_icy_name );
+ vlc_meta_SetTitle( p_meta, p_sys->psz_icy_name );
if( p_sys->psz_icy_genre )
- vlc_meta_Add( *pp_meta, VLC_META_GENRE,
- p_sys->psz_icy_genre );
+ vlc_meta_SetGenre( p_meta, p_sys->psz_icy_genre );
if( p_sys->psz_icy_title )
- vlc_meta_Add( *pp_meta, VLC_META_NOW_PLAYING,
- p_sys->psz_icy_title );
+ vlc_meta_SetNowPlaying( p_meta, p_sys->psz_icy_title );
break;
case ACCESS_GET_TITLE_INFO:
free( psz_location );
return VLC_EGENERIC;
}
- p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
- playlist_Add( p_playlist, psz_location, psz_location,
- PLAYLIST_INSERT | PLAYLIST_GO,
- p_playlist->i_index + 1 );
+ /** \bug we do not autodelete here */
+ playlist_PlaylistAdd( p_playlist, psz_location, psz_location,
+ PLAYLIST_INSERT | PLAYLIST_GO, PLAYLIST_END );
vlc_object_release( p_playlist );
free( psz_location );
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/* Main loop */
while( !p_intf->b_die )
{
-
+
/* find a video output if we currently don't have one */
if( p_vout == NULL )
{
vlc_mutex_lock( &p_intf->change_lock );
p_intf->p_sys->b_key_pressed = VLC_TRUE;
-
+
vlc_mutex_unlock( &p_intf->change_lock );
return VLC_SUCCESS;
mtime_t i_seconds;
vlc_value_t time;
- p_playlist = (playlist_t *) vlc_object_find( p_intf,
+ p_playlist = (playlist_t *) vlc_object_find( p_intf,
VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if ( !p_playlist )
{
}
/* Get new URL */
- p_current_item = p_playlist->pp_items[p_playlist->i_index];
+ p_current_item = p_playlist->status.p_item;
#ifdef CMML_INTF_DEBUG
msg_Dbg( p_intf, "Current playlist item URL is \"%s\"",
p_current_item->input.psz_uri );
#endif
- psz_uri_to_load = XURL_Concat( p_current_item->input.psz_uri,
+ psz_uri_to_load = XURL_Concat( p_current_item->p_input->psz_uri,
psz_url );
#ifdef CMML_INTF_DEBUG
char *psz_return_value = NULL;
char *psz_seconds = NULL;
int i_seconds;
-
+
psz_url = XURL_GetWithoutFragment( p_current_item->input->psz_uri );
/* Get current time as a string */
p = GetTimedURIFragmentForTime; /* unused */
p = GetCurrentTimeInSeconds; /* unused */
- return strdup( p_current_item->input.psz_uri );
+ return strdup( p_current_item->p_input->psz_uri );
#endif
}
#endif
/* Find the playlist */
- p_playlist = (playlist_t *) vlc_object_find( p_intf,
+ p_playlist = (playlist_t *) vlc_object_find( p_intf,
VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if ( !p_playlist )
{
return;
}
- p_current_item = p_playlist->pp_items[p_playlist->i_index];
+ p_current_item = p_playlist->status.p_item;
/* Save the currently-playing media in a new history item */
psz_timed_url = GetTimedURLFromPlaylistItem( p_intf, p_current_item );
#endif
/* Find the playlist */
- p_playlist = (playlist_t *) vlc_object_find( p_intf,
+ p_playlist = (playlist_t *) vlc_object_find( p_intf,
VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if ( !p_playlist )
{
vlc_object_release( p_playlist );
return;
}
- p_current_item = p_playlist->pp_items[p_playlist->i_index];
- p_new_history_item->psz_uri = GetTimedURLFromPlaylistItem( p_intf,
+ p_current_item = p_playlist->status.p_item;
+ p_new_history_item->psz_uri = GetTimedURLFromPlaylistItem( p_intf,
p_current_item );
p_new_history_item->psz_name = p_new_history_item->psz_uri;
static void ReplacePlaylistItem( playlist_t *p_playlist, char *psz_uri )
{
playlist_Stop( p_playlist );
- (void) playlist_Add( p_playlist, psz_uri, psz_uri,
- PLAYLIST_REPLACE, p_playlist->i_index );
- playlist_Goto( p_playlist, p_playlist->i_index );
+ (void) playlist_PlaylistAdd( p_playlist, psz_uri, psz_uri,
+ PLAYLIST_INSERT /* FIXME: used to be PLAYLIST_REPLACE */, PLAYLIST_END|PLAYLIST_GO /* FIXME: p_playlist->status.i_index */ );
}
/****************************************************************************
static void PlayBookmark( intf_thread_t *p_intf, int i_num )
{
vlc_value_t val;
- int i_position;
+ int i;
char psz_bookmark_name[11];
playlist_t *p_playlist =
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist )
{
char *psz_bookmark = strdup( val.psz_string );
- for( i_position = 0; i_position < p_playlist->i_size; i_position++)
+ for( i = 0; i < p_playlist->pp_all_items; i++)
{
if( !strcmp( psz_bookmark,
- p_playlist->pp_items[i_position]->input.psz_uri ) )
+ p_playlist->pp_items[i]->p_input->psz_uri ) )
{
- playlist_Goto( p_playlist, i_position );
+ playlist_LockControl( p_playlist, PLAYLIST_ITEMPLAY,
+ p_playlist->pp_items[i] );
break;
}
}
if( p_playlist->status.p_item )
{
config_PutPsz( p_intf, psz_bookmark_name,
- p_playlist->status.p_item->input.psz_uri);
+ p_playlist->status.p_item->p_input->psz_uri);
msg_Info( p_intf, "setting playlist bookmark %i to %s", i_num,
- p_playlist->status.p_item->input.psz_uri);
+ p_playlist->status.p_item->p_input->psz_uri);
config_SaveConfigFile( p_intf, "hotkeys" );
}
vlc_object_release( p_playlist );
int E_(TestURIParam)( char *psz_uri, const char *psz_name );
/** This function parses a MRL */
-playlist_item_t *E_(MRLParse)( intf_thread_t *, char *psz, char *psz_name );
+input_item_t *E_(MRLParse)( intf_thread_t *, char *psz, char *psz_name );
/** Return the first word from a string (works in-place) */
char *E_(FirstWord)( char *psz, char *new );
{
char mrl[1024], psz_name[1024], tmp[1024];
char *p, *str;
- playlist_item_t *p_item;
+ input_item_t *p_input;
E_(ExtractURIValue)( p_request, "mrl", tmp, 1024 );
decode_URI( tmp );
}
*p = '\0';
- p_item = E_(MRLParse)( p_intf, mrl, psz_name );
+ p_input = E_(MRLParse)( p_intf, mrl, psz_name );
- if( !p_item || !p_item->input.psz_uri ||
- !*p_item->input.psz_uri )
+ if( !p_input || p_input->psz_uri ||
+ !*p_input->psz_uri )
{
msg_Dbg( p_intf, "invalid requested mrl: %s", mrl );
}
else
{
- playlist_AddItem( p_sys->p_playlist, p_item,
+ playlist_PlaylistAddInput( p_sys->p_playlist, p_input,
PLAYLIST_APPEND, PLAYLIST_END );
msg_Dbg( p_intf, "requested mrl add: %s", mrl );
}
for( j = 0 ; j < i_nb_items ; j++ )
{
if( p_items[j] ==
- p_sys->p_playlist->pp_items[i]->input.i_id ) break;
+ p_sys->p_playlist->pp_items[i]->p_input->i_id )
+ break;
}
if( j == i_nb_items )
{
- playlist_LockDelete( p_sys->p_playlist, p_sys->p_playlist->pp_items[i]->input.i_id );
+ playlist_LockDelete( p_sys->p_playlist,
+ p_sys->p_playlist->pp_items[i]->p_input->i_id );
msg_Dbg( p_intf, "requested playlist delete: %d",
i );
}
if( !strcmp( type , "title" ) )
{
playlist_RecursiveNodeSort( p_sys->p_playlist, /*playlist_ItemGetById( p_sys->p_playlist, i_item ),*/
- p_sys->p_playlist->pp_views[0]->p_root,
+ /* Ugly hack,but not worse than before ... */
+ p_sys->p_playlist->p_root_onelevel,
SORT_TITLE_NODES_FIRST,
( i_order == 0 ) ? ORDER_NORMAL : ORDER_REVERSE );
msg_Dbg( p_intf, "requested playlist sort by title (%d)" , i_order );
else if( !strcmp( type , "author" ) )
{
playlist_RecursiveNodeSort( p_sys->p_playlist, /*playlist_ItemGetById( p_sys->p_playlist, i_item ),*/
- p_sys->p_playlist->pp_views[0]->p_root,
+ p_sys->p_playlist->p_root_onelevel,
SORT_AUTHOR,
( i_order == 0 ) ? ORDER_NORMAL : ORDER_REVERSE );
msg_Dbg( p_intf, "requested playlist sort by author (%d)" , i_order );
else if( !strcmp( type , "shuffle" ) )
{
playlist_RecursiveNodeSort( p_sys->p_playlist, /*playlist_ItemGetById( p_sys->p_playlist, i_item ),*/
- p_sys->p_playlist->pp_views[0]->p_root,
+ p_sys->p_playlist->p_root_onelevel,
SORT_RANDOM,
( i_order == 0 ) ? ORDER_NORMAL : ORDER_REVERSE );
msg_Dbg( p_intf, "requested playlist shuffle");
E_(ExtractURIValue)( p_request, "psz_newpos", psz_newpos, 6 );
i_pos = atoi( psz_pos );
i_newpos = atoi( psz_newpos );
+ /* FIXME FIXME TODO TODO XXX XXX
+ ( duplicate from rpn.c )
if ( i_pos < i_newpos )
{
playlist_Move( p_sys->p_playlist, i_pos, i_newpos + 1 );
playlist_Move( p_sys->p_playlist, i_pos, i_newpos );
}
msg_Dbg( p_intf, "requested move playlist item %d to %d", i_pos, i_newpos);
+ FIXME FIXME TODO TODO XXX XXX */
break;
}
mvar_t *E_(mvar_PlaylistSetNew)( intf_thread_t *p_intf, char *name,
playlist_t *p_pl )
{
- playlist_view_t *p_view;
mvar_t *s = E_(mvar_New)( name, "set" );
-
-
vlc_mutex_lock( &p_pl->object_lock );
-
- p_view = playlist_ViewFind( p_pl, VIEW_CATEGORY ); /* FIXME */
-
- if( p_view != NULL )
- E_(PlaylistListNode)( p_intf, p_pl, p_view->p_root, name, s, 0 );
-
+ E_(PlaylistListNode)( p_intf, p_pl, p_pl->p_root_category , name, s, 0 );
vlc_mutex_unlock( &p_pl->object_lock );
-
return s;
}
char *psz_name = E_(SSPop)( st );
char *mrl = E_(SSPop)( st );
char *tmp;
- playlist_item_t *p_item;
+ input_item_t *p_input;
int i_id;
tmp = E_(ToUTF8)( p_intf, psz_name );
if( !*psz_name )
{
- p_item = E_(MRLParse)( p_intf, mrl, mrl );
+ p_input = E_(MRLParse)( p_intf, mrl, mrl );
}
else
{
- p_item = E_(MRLParse)( p_intf, mrl, psz_name );
+ p_input = E_(MRLParse)( p_intf, mrl, psz_name );
}
- if( p_item == NULL || p_item->input.psz_uri == NULL ||
- !*p_item->input.psz_uri )
+ if( !p_input || !p_input->psz_uri || !*p_input->psz_uri )
{
i_id = VLC_EGENERIC;
msg_Dbg( p_intf, "invalid requested mrl: %s", mrl );
}
else
{
- i_id = playlist_AddItem( p_sys->p_playlist, p_item,
+ i_id = playlist_PlaylistAddInput( p_sys->p_playlist, p_input,
PLAYLIST_APPEND, PLAYLIST_END );
msg_Dbg( p_intf, "requested mrl add: %s", mrl );
}
}
else if( !strcmp( s, "playlist_move" ) )
{
- int i_newpos = E_(SSPopN)( st, vars );
- int i_pos = E_(SSPopN)( st, vars );
+ /*int i_newpos =*/ E_(SSPopN)( st, vars );
+ /*int i_pos =*/ E_(SSPopN)( st, vars );
+ /* FIXME FIXME TODO TODO XXX XXX
+ do not release before fixing this
if ( i_pos < i_newpos )
{
playlist_Move( p_sys->p_playlist, i_pos, i_newpos + 1 );
}
msg_Dbg( p_intf, "requested to move playlist item %d to %d",
i_pos, i_newpos);
+ FIXME FIXME TODO TODO XXX XXX */
+ msg_Err( p_intf, "moving using indexes is obsolete. We need to update this function" );
}
else if( !strcmp( s, "playlist_sort" ) )
{
int i_sort = E_(SSPopN)( st, vars );
i_order = i_order % 2;
i_sort = i_sort % 9;
+ /* FIXME FIXME TODO TODO XXX XXX
+ do not release before fixing this
playlist_RecursiveNodeSort( p_sys->p_playlist,
p_sys->p_playlist->p_general,
i_sort, i_order );
msg_Dbg( p_intf, "requested sort playlist by : %d in order : %d",
i_sort, i_order );
+ FIXME FIXME TODO TODO XXX XXX */
+ msg_Err( p_intf, "this needs to be fixed to use the new playlist framework" );
}
else if( !strcmp( s, "services_discovery_add" ) )
{
sprintf( value, "%d", ( p_pl->status.p_item == p_node )? 1 : 0 );
E_(mvar_AppendNewVar)( itm, "current", value );
- sprintf( value, "%d", p_node->input.i_id );
+ sprintf( value, "%d", p_node->p_input->i_id );
E_(mvar_AppendNewVar)( itm, "index", value );
- psz = E_(FromUTF8)( p_intf, p_node->input.psz_name );
+ psz = E_(FromUTF8)( p_intf, p_node->p_input->psz_name );
E_(mvar_AppendNewVar)( itm, "name", psz );
free( psz );
- psz = E_(FromUTF8)( p_intf, p_node->input.psz_uri );
+ psz = E_(FromUTF8)( p_intf, p_node->p_input->psz_uri );
E_(mvar_AppendNewVar)( itm, "uri", psz );
free( psz );
E_(mvar_AppendNewVar)( itm, "ro", "rw" );
}
- sprintf( value, "%ld", (long)p_node->input.i_duration );
+ sprintf( value, "%ld", (long)p_node->p_input->i_duration );
E_(mvar_AppendNewVar)( itm, "duration", value );
E_(mvar_AppendVar)( s, itm );
int i_child;
mvar_t *itm = E_(mvar_New)( name, "set" );
- psz = E_(FromUTF8)( p_intf, p_node->input.psz_name );
+ psz = E_(FromUTF8)( p_intf, p_node->p_input->psz_name );
E_(mvar_AppendNewVar)( itm, "name", psz );
E_(mvar_AppendNewVar)( itm, "uri", psz );
free( psz );
sprintf( value, "Node" );
E_(mvar_AppendNewVar)( itm, "type", value );
- sprintf( value, "%d", p_node->input.i_id );
+ sprintf( value, "%d", p_node->p_input->i_id );
E_(mvar_AppendNewVar)( itm, "index", value );
sprintf( value, "%d", p_node->i_children);
return NULL;
}
-playlist_item_t *E_(MRLParse)( intf_thread_t *p_intf, char *_psz,
- char *psz_name )
+input_item_t *E_(MRLParse)( intf_thread_t *p_intf, char *_psz,
+ char *psz_name )
{
char *psz = strdup( _psz );
char *s_mrl = psz;
char *s_temp;
- playlist_item_t * p_item = NULL;
+ input_item_t * p_input = NULL;
/* extract the mrl */
s_temp = FirstOption( s_mrl, s_mrl );
s_temp = s_mrl + strlen( s_mrl );
}
- p_item = playlist_ItemNew( p_intf, s_mrl, psz_name );
+ p_input = input_ItemNew( p_intf, s_mrl, psz_name );
s_mrl = s_temp;
/* now we can take care of the options */
{
s_temp = s_mrl + strlen( s_mrl );
}
- playlist_ItemAddOption( p_item, s_mrl );
+ vlc_input_item_AddOption( p_input, s_mrl );
s_mrl = s_temp;
}
free( psz );
-
- return p_item;
+ return p_input;
}
/**********************************************************************
static int Activate( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t*)p_this;
- playlist_t *p_playlist;
char *psz_host, *psz_unix_path;
int *pi_socket = NULL;
CONSOLE_INTRO_MSG;
#endif
- /* Force "no-view" mode */
- p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
- FIND_ANYWHERE );
- if( p_playlist )
- {
- vlc_mutex_lock( &p_playlist->object_lock );
- p_playlist->status.i_view = -1;
- vlc_mutex_unlock( &p_playlist->object_lock );
- vlc_object_release( p_playlist );
- }
-
msg_rc( _("Remote control interface initialized. Type `help' for help.") );
return VLC_SUCCESS;
}
FIND_ANYWHERE );
if( !p_playlist )
{
+ msg_Err( p_this, "no playlist" );
return VLC_ENOOBJ;
}
{
vlc_value_t val;
var_Get( p_playlist->p_input, "state", &val );
- if( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) ) {
+ if( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) )
+ {
msg_rc( _("Type 'menu select' or 'pause' to continue.") );
vlc_object_release( p_playlist );
return VLC_EGENERIC;
}
else if( !strcmp( psz_cmd, "play" ) )
{
- if( p_playlist->p_input )
- {
- vlc_value_t val;
-
- var_Get( p_playlist->p_input, "rate", &val );
- if( val.i_int != INPUT_RATE_DEFAULT )
- {
- val.i_int = INPUT_RATE_DEFAULT;
- var_Set( p_playlist->p_input, "rate", val );
- }
- else
- {
- playlist_Play( p_playlist );
- }
- }
+ msg_Warn( p_playlist, "play" );
+ playlist_Play( p_playlist );
}
else if (!strcmp( psz_cmd, "goto" ) )
{
- if( strlen( newval.psz_string ) > 0)
- {
- val.i_int = atoi( newval.psz_string );
- playlist_Goto( p_playlist, val.i_int);
- }
+ msg_Err( p_playlist, "goto is deprecated" );
}
else if( !strcmp( psz_cmd, "stop" ) )
{
if( p_item )
{
msg_rc( "Trying to add %s to playlist.", newval.psz_string );
- playlist_AddItem( p_playlist, p_item,
- PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END );
+// playlist_AddItem( p_playlist, p_item,
+// PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END );
}
}
else if( !strcmp( psz_cmd, "playlist" ) )
{
int i;
-
- for ( i = 0; i < p_playlist->i_size; i++ )
- {
- msg_rc( "|%s%s %s|%s|", i == p_playlist->i_index ? "*" : " ",
- p_playlist->pp_items[i]->input.psz_name,
- p_playlist->pp_items[i]->input.psz_uri,
- p_playlist->pp_items[i]->i_parents > 0 ?
- p_playlist->pp_items[i]->pp_parents[0]->p_parent->input.psz_name : "" );
- }
- if ( i == 0 )
- {
- msg_rc( "| no entries" );
- }
+ playlist_view_t *p_view;
+ playlist_NodeDump( p_playlist, p_playlist->p_root_category, 0 );
+ playlist_NodeDump( p_playlist, p_playlist->p_root_onelevel, 0 );
}
else if( !strcmp( psz_cmd, "status" ) )
{
demux_sys_t *p_sys = p_demux->p_sys;
int64_t *pi64;
int i;
- vlc_meta_t **pp_meta;
+ vlc_meta_t *p_meta;
switch( i_query )
{
return VLC_SUCCESS;
case DEMUX_GET_META:
- pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
- *pp_meta = vlc_meta_Duplicate( p_sys->meta );
+ p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
+ vlc_meta_Merge( p_meta, p_sys->meta );
return VLC_SUCCESS;
case DEMUX_SET_POSITION:
{
if( p_cd->psz_title && *p_cd->psz_title )
{
- vlc_meta_Add( p_sys->meta, VLC_META_TITLE, p_cd->psz_title );
+ vlc_meta_SetTitle( p_sys->meta, p_cd->psz_title );
}
if( p_cd->psz_author && *p_cd->psz_author )
{
- vlc_meta_Add( p_sys->meta, VLC_META_AUTHOR, p_cd->psz_author );
+ vlc_meta_SetAuthor( p_sys->meta, p_cd->psz_author );
}
if( p_cd->psz_copyright && *p_cd->psz_copyright )
{
- vlc_meta_Add( p_sys->meta, VLC_META_COPYRIGHT, p_cd->psz_copyright );
+ vlc_meta_SetCopyright( p_sys->meta, p_cd->psz_copyright );
}
if( p_cd->psz_description && *p_cd->psz_description )
{
- vlc_meta_Add( p_sys->meta, VLC_META_DESCRIPTION, p_cd->psz_description );
+ vlc_meta_SetDescription( p_sys->meta, p_cd->psz_description );
}
if( p_cd->psz_rating && *p_cd->psz_rating )
{
- vlc_meta_Add( p_sys->meta, VLC_META_RATING, p_cd->psz_rating );
+ vlc_meta_SetRating( p_sys->meta, p_cd->psz_rating );
}
}
+ fprintf( stderr, "*********** Unhandled child meta\n" );
+#if 0
for( i_stream = 0, i = 0; i < 128; i++ )
{
asf_object_codec_list_t *p_cl = ASF_FindObject( p_sys->p_root->p_hdr,
i_stream++;
}
}
+#endif
es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
return VLC_SUCCESS;
p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
- vlc_meta_Add( p_sys->meta, VLC_META_SETTING, buffer );
+ vlc_meta_SetSetting( p_sys->meta, buffer );
}
/* now read info on each stream and create ES */
int i;
double f, *pf;
int64_t i64, *pi64;
- vlc_meta_t **pp_meta;
+ vlc_meta_t *p_meta;
switch( i_query )
{
}
return VLC_SUCCESS;
case DEMUX_GET_META:
- pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
- *pp_meta = vlc_meta_Duplicate( p_sys->meta );
+ p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
+ vlc_meta_Merge( p_meta, p_sys->meta );
return VLC_SUCCESS;
default:
p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'f', 'l', 'a', 'c' ) );
p_sys->b_start = VLC_TRUE;
- p_sys->p_meta = 0;
+ p_sys->p_meta = NULL;
/* We need to read and store the STREAMINFO metadata */
i_peek = stream_Peek( p_demux->s, &p_peek, 8 );
if( i_query == DEMUX_SET_TIME ) return VLC_EGENERIC;
else if( i_query == DEMUX_GET_META )
{
- vlc_meta_t **pp_meta = (vlc_meta_t **)va_arg( args, vlc_meta_t** );
+ vlc_meta_t *p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
if( p_demux->p_sys->p_meta )
- *pp_meta = vlc_meta_Duplicate( p_demux->p_sys->p_meta );
- else *pp_meta = NULL;
+ vlc_meta_Merge( p_meta, p_demux->p_sys->p_meta );
return VLC_SUCCESS;
}
else return demux2_vaControlHelper( p_demux->s, 0, -1,
set_description( _("Playlist metademux") );
set_capability( "demux2", 5 );
set_callbacks( Activate, Deactivate );
- add_shortcut( "m3u" );
add_shortcut( "asx" );
add_shortcut( "html" );
- add_shortcut( "pls" );
add_shortcut( "b4s" );
vlc_module_end();
/* Check for m3u/asx file extension or if the demux has been forced */
psz_ext = strrchr ( p_demux->psz_path, '.' );
- if( ( psz_ext && !strcasecmp( psz_ext, ".m3u") ) ||
- /* a .ram file can contain a single rtsp link */
- ( psz_ext && !strcasecmp( psz_ext, ".ram") ) ||
- ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "m3u") ) )
+ if(( psz_ext && !strcasecmp( psz_ext, ".ram") ) )
{
i_type = TYPE_M3U;
}
{
i_type = TYPE_HTML;
}
- else if( ( psz_ext && !strcasecmp( psz_ext, ".pls") ) ||
- ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "pls") ) )
- {
- i_type = TYPE_PLS;
- }
else if( ( psz_ext && !strcasecmp( psz_ext, ".b4s") ) ||
( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "b4s") ) )
{
int i_skp;
size_t i_idx;
- vlc_meta_t **pp_meta;
+ vlc_meta_t *p_meta;
switch( i_query )
{
case DEMUX_GET_META:
- pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
- *pp_meta = vlc_meta_Duplicate( p_sys->meta );
+ p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
+ vlc_meta_Merge( p_meta, p_sys->meta );
return VLC_SUCCESS;
case DEMUX_GET_LENGTH:
if( psz_title )
{
- vlc_meta_Add( sys.meta, VLC_META_TITLE, psz_title );
+ vlc_meta_SetTitle( sys.meta, psz_title );
}
if( psz_date_utc )
{
- vlc_meta_Add( sys.meta, VLC_META_DATE, psz_date_utc );
+ vlc_meta_SetDate( sys.meta, psz_date_utc );
}
if( psz_segment_filename )
{
- vlc_meta_Add( sys.meta, _("Segment filename"), psz_segment_filename );
+ fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
}
if( psz_muxing_application )
{
- vlc_meta_Add( sys.meta, _("Muxing application"), psz_muxing_application );
+ fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
}
if( psz_writing_application )
{
- vlc_meta_Add( sys.meta, _("Writing application"), psz_writing_application );
+ fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
}
for( i_track = 0; i_track < tracks.size(); i_track++ )
{
- mkv_track_t *tk = tracks[i_track];
- vlc_meta_t *mtk = vlc_meta_New();
-
- sys.meta->track = (vlc_meta_t**)realloc( sys.meta->track,
- sizeof( vlc_meta_t * ) * ( sys.meta->i_track + 1 ) );
- sys.meta->track[sys.meta->i_track++] = mtk;
-
- if( tk->fmt.psz_description )
- {
- vlc_meta_Add( sys.meta, VLC_META_DESCRIPTION, tk->fmt.psz_description );
- }
- if( tk->psz_codec_name )
- {
- vlc_meta_Add( sys.meta, VLC_META_CODEC_NAME, tk->psz_codec_name );
- }
- if( tk->psz_codec_settings )
- {
- vlc_meta_Add( sys.meta, VLC_META_SETTING, tk->psz_codec_settings );
- }
- if( tk->psz_codec_info_url )
- {
- vlc_meta_Add( sys.meta, VLC_META_CODEC_DESCRIPTION, tk->psz_codec_info_url );
- }
- if( tk->psz_codec_download_url )
- {
- vlc_meta_Add( sys.meta, VLC_META_URL, tk->psz_codec_download_url );
- }
+// mkv_track_t *tk = tracks[i_track];
+// vlc_meta_t *mtk = vlc_meta_New();
+ fprintf( stderr, "***** WARNING: Unhandled child meta\n");
}
if( i_tags_position >= 0 )
!strncmp( psz_ref, "rtsp://", 7 ) )
{
msg_Dbg( p_demux, "adding ref = `%s'", psz_ref );
+ msg_Err( p_demux, "REF is broken (fix playlist") ;
+#if 0
if( p_item )
{
playlist_item_t *p_child =
b_play = VLC_TRUE;
}
}
+#endif
}
else
{
}
strcat( psz_absolute, psz_ref );
msg_Dbg( p_demux, "adding ref = `%s'", psz_absolute );
+ msg_Err( p_demux, "Ref broken (fix playlist" );
+#if 0
if( p_item )
{
playlist_item_t *p_child =
b_play = VLC_TRUE;
}
}
+#endif
}
}
else
if( b_play == VLC_TRUE )
{
playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- p_playlist->status.i_view,
p_playlist->status.p_item, NULL );
}
vlc_object_release( p_playlist );
case DEMUX_GET_META:
{
- vlc_meta_t **pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
- vlc_meta_t *meta;
+ vlc_meta_t *p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t*);
MP4_Box_t *p_udta = MP4_BoxGet( p_sys->p_root, "/moov/udta" );
MP4_Box_t *p_0xa9xxx;
if( p_udta == NULL )
{
return VLC_EGENERIC;
}
- *pp_meta = meta = vlc_meta_New();
for( p_0xa9xxx = p_udta->p_first; p_0xa9xxx != NULL;
p_0xa9xxx = p_0xa9xxx->p_next )
{
switch( p_0xa9xxx->i_type )
{
case FOURCC_0xa9nam: /* Full name */
- vlc_meta_Add( meta, VLC_META_TITLE, psz_utf );
+ vlc_meta_SetArtist( p_meta, psz_utf );
break;
case FOURCC_0xa9aut:
- vlc_meta_Add( meta, VLC_META_AUTHOR, psz_utf );
+ vlc_meta_SetAuthor( p_meta, psz_utf );
break;
case FOURCC_0xa9ART:
- vlc_meta_Add( meta, VLC_META_ARTIST, psz_utf );
+ vlc_meta_SetArtist( p_meta, psz_utf );
break;
case FOURCC_0xa9cpy:
- vlc_meta_Add( meta, VLC_META_COPYRIGHT, psz_utf );
+ vlc_meta_SetCopyright( p_meta, psz_utf );
break;
case FOURCC_0xa9day: /* Creation Date */
- vlc_meta_Add( meta, VLC_META_DATE, psz_utf );
+ vlc_meta_SetDate( p_meta, psz_utf );
break;
case FOURCC_0xa9des: /* Description */
- vlc_meta_Add( meta, VLC_META_DESCRIPTION, psz_utf );
+ vlc_meta_SetDescription( p_meta, psz_utf );
break;
case FOURCC_0xa9gen: /* Genre */
- vlc_meta_Add( meta, VLC_META_GENRE, psz_utf );
+ vlc_meta_SetGenre( p_meta, psz_utf );
break;
case FOURCC_0xa9swr:
{
demux_sys_t *p_sys = p_demux->p_sys;
int64_t *pi64;
- vlc_meta_t **pp_meta;
+ vlc_meta_t *p_meta;
int i_ret;
switch( i_query )
{
case DEMUX_GET_META:
- pp_meta = (vlc_meta_t **)va_arg( args, vlc_meta_t** );
- if( p_sys->meta ) *pp_meta = vlc_meta_Duplicate( p_sys->meta );
- else *pp_meta = NULL;
+ p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
+ vlc_meta_Merge( p_meta, p_sys->meta );
return VLC_SUCCESS;
case DEMUX_GET_TIME:
struct demux_sys_t
{
char *psz_prefix;
- playlist_t *p_playlist;
xml_t *p_xml;
xml_reader_t *p_xml_reader;
- int b_shout;
};
/*****************************************************************************
static int Control( demux_t *p_demux, int i_query, va_list args );
static char *GetNextToken(char *psz_cur_string);
static int IsWhitespace( char *psz_string );
-static void ShoutcastAdd( playlist_t *p_playlist, playlist_item_t* p_genre,
- playlist_item_t *p_bitrate, playlist_item_t *p_item,
- char *psz_genre, char *psz_bitrate );
/*****************************************************************************
* Import_B4S: main import function
psz_ext = strrchr ( p_demux->psz_path, '.' );
if( ( psz_ext && !strcasecmp( psz_ext, ".b4s") ) ||
- ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "b4s-open") ) ||
- ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "shout-b4s") ) )
+ ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "b4s-open") ) )
{
;
}
msg_Err( p_demux, "out of memory" );
return VLC_ENOMEM;
}
- p_sys->b_shout = p_demux->psz_demux &&
- !strcmp(p_demux->psz_demux, "shout-b4s");
p_sys->psz_prefix = E_(FindPrefix)( p_demux );
- p_sys->p_playlist = NULL;
p_sys->p_xml = NULL;
p_sys->p_xml_reader = NULL;
demux_sys_t *p_sys = p_demux->p_sys;
if( p_sys->psz_prefix ) free( p_sys->psz_prefix );
- if( p_sys->p_playlist ) vlc_object_release( p_sys->p_playlist );
if( p_sys->p_xml_reader ) xml_ReaderDelete( p_sys->p_xml, p_sys->p_xml_reader );
if( p_sys->p_xml ) xml_Delete( p_sys->p_xml );
free( p_sys );
static int Demux( demux_t *p_demux )
{
demux_sys_t *p_sys = p_demux->p_sys;
- playlist_t *p_playlist;
- playlist_item_t *p_item, *p_current;
+ playlist_item_t *p_item;
playlist_item_t *p_bitrate = NULL, *p_genre = NULL;
- vlc_bool_t b_play;
- int i_ret;
+ int i_ret, i_parent_id;
xml_t *p_xml;
xml_reader_t *p_xml_reader;
char *psz_elname = NULL;
- int i_type, b_shoutcast;
+ int i_type;
char *psz_mrl = NULL, *psz_name = NULL, *psz_genre = NULL;
char *psz_now = NULL, *psz_listeners = NULL, *psz_bitrate = NULL;
-
- b_shoutcast = p_sys->b_shout;
-
- p_playlist = (playlist_t *) vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
- FIND_ANYWHERE );
- if( !p_playlist )
- {
- msg_Err( p_demux, "can't find playlist" );
- return -1;
- }
- p_sys->p_playlist = p_playlist;
-
- b_play = E_(FindItem)( p_demux, p_playlist, &p_current );
-
- playlist_ItemToNode( p_playlist, p_current );
- p_current->input.i_type = ITEM_TYPE_PLAYLIST;
- if( b_shoutcast )
- {
- p_genre = playlist_NodeCreate( p_playlist, p_current->pp_parents[0]->i_view, "Genre", p_current );
- playlist_CopyParents( p_current, p_genre );
-
- p_bitrate = playlist_NodeCreate( p_playlist, p_current->pp_parents[0]->i_view, "Bitrate", p_current );
- playlist_CopyParents( p_current, p_bitrate );
- }
+ INIT_PLAYLIST_STUFF;
p_xml = p_sys->p_xml = xml_Create( p_demux );
if( !p_xml ) return -1;
if( xml_ReaderRead( p_xml_reader ) != 1 )
{
msg_Err( p_demux, "invalid file (no root node)" );
+ vlc_object_release( p_playlist );
return -1;
}
msg_Err( p_demux, "invalid root node %i, %s",
xml_ReaderNodeType( p_xml_reader ), psz_elname );
if( psz_elname ) free( psz_elname );
+ vlc_object_release( p_playlist );
return -1;
}
free( psz_elname );
if( !psz_elname ) return -1;
if( !strcmp( psz_elname, "entry" ) )
{
- p_item = playlist_ItemNew( p_playlist, psz_mrl, psz_name );
+ p_input = input_ItemNewExt( p_playlist, psz_mrl, psz_name,
+ 0, NULL, -1 );
if( psz_now )
- {
- vlc_input_item_AddInfo( &(p_item->input),
- _(VLC_META_INFO_CAT),
- _( VLC_META_NOW_PLAYING ),
- "%s",
- psz_now );
- }
+ vlc_meta_SetNowPlaying( p_input->p_meta, psz_now );
if( psz_genre )
- {
- vlc_input_item_AddInfo( &p_item->input,
- _(VLC_META_INFO_CAT),
- _( VLC_META_GENRE ),
- "%s",
- psz_genre );
- }
+ vlc_meta_SetGenre( p_input->p_meta, psz_genre );
if( psz_listeners )
- {
- vlc_input_item_AddInfo( &p_item->input,
- _(VLC_META_INFO_CAT),
- _( "Listeners" ),
- "%s",
- psz_listeners );
- }
+ msg_Err( p_playlist, "Unsupported meta listeners" );
if( psz_bitrate )
- {
- vlc_input_item_AddInfo( &p_item->input,
- _(VLC_META_INFO_CAT),
- _( "Bitrate" ),
- "%s",
- psz_bitrate );
- }
- playlist_NodeAddItem( p_playlist, p_item,
- p_current->pp_parents[0]->i_view,
- p_current, PLAYLIST_APPEND,
- PLAYLIST_END );
-
- /* We need to declare the parents of the node as the
- * * same of the parent's ones */
- playlist_CopyParents( p_current, p_item );
-
- vlc_input_item_CopyOptions( &p_current->input,
- &p_item->input );
- if( b_shoutcast )
- {
- char *psz_genreToken;
- char *psz_otherToken;
- int i = 0;
-
- psz_genreToken = psz_genre;
-
- /* split up the combined genre string form
- shoutcast and add the individual genres */
- while ( psz_genreToken &&
- ( psz_otherToken = GetNextToken(psz_genreToken )))
- {
- if( strlen(psz_genreToken)>2 )
- /* We dont want genres below 2 letters,
- this gets rid of alot of junk*/
- {
- /* lowercase everything */
- for( i=0; psz_genreToken[i]!=0; i++ )
- psz_genreToken[i] =
- tolower(psz_genreToken[i]);
- /* Make first letter uppercase, purely cosmetical */
- psz_genreToken[0] =
- toupper( psz_genreToken[0] );
- ShoutcastAdd( p_playlist, p_genre,
- p_bitrate, p_item,
- psz_genreToken, psz_bitrate );
-
- psz_genreToken = psz_otherToken;
- }
- }
- }
+ msg_Err( p_playlist, "Unsupported meta bitrate" );
+
+ playlist_AddWhereverNeeded( p_playlist, p_input, p_current,
+ p_item_in_category, (i_parent_id > 0 ) ? VLC_TRUE:
+ VLC_FALSE, PLAYLIST_APPEND );
#define FREE(a) if( a ) free( a ); a = NULL;
FREE( psz_name );
{
msg_Warn( p_demux, "error while parsing data" );
}
- if( b_shoutcast )
- {
- vlc_mutex_lock( &p_playlist->object_lock );
- playlist_NodeSort( p_playlist, p_bitrate, SORT_TITLE_NUMERIC, ORDER_NORMAL );
- vlc_mutex_unlock( &p_playlist->object_lock );
- }
- /* Go back and play the playlist */
- if( b_play && p_playlist->status.p_item &&
- p_playlist->status.p_item->i_children > 0 )
- {
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- p_playlist->status.i_view,
- p_playlist->status.p_item,
- p_playlist->status.p_item->pp_children[0] );
- }
-
- vlc_object_release( p_playlist );
- p_sys->p_playlist = NULL;
+ HANDLE_PLAY_AND_RELEASE;
return VLC_SUCCESS;
}
}
return VLC_TRUE;
}
-
-static void ShoutcastAdd( playlist_t *p_playlist, playlist_item_t* p_genre,
- playlist_item_t *p_bitrate, playlist_item_t *p_item,
- char *psz_genre, char *psz_bitrate )
-{
- playlist_item_t *p_parent;
- if( psz_bitrate )
- {
- playlist_item_t *p_copy = playlist_ItemCopy(p_playlist,p_item);
- p_parent = playlist_ChildSearchName( p_bitrate, psz_bitrate );
- if( !p_parent )
- {
- p_parent = playlist_NodeCreate( p_playlist, p_genre->pp_parents[0]->i_view, psz_bitrate,
- p_bitrate );
- playlist_CopyParents( p_bitrate, p_parent );
- }
- playlist_NodeAddItem( p_playlist, p_copy, p_parent->pp_parents[0]->i_view, p_parent, PLAYLIST_APPEND, PLAYLIST_END );
- playlist_CopyParents( p_parent, p_copy );
-
- }
-
- if( psz_genre )
- {
- playlist_item_t *p_copy = playlist_ItemCopy(p_playlist,p_item);
- p_parent = playlist_ChildSearchName( p_genre, psz_genre );
- if( !p_parent )
- {
- p_parent = playlist_NodeCreate( p_playlist, p_genre->pp_parents[0]->i_view, psz_genre,
- p_genre );
- playlist_CopyParents( p_genre, p_parent );
- }
- playlist_NodeAddItem( p_playlist, p_copy, p_parent->pp_parents[0]->i_view, p_parent, PLAYLIST_APPEND, PLAYLIST_END );
- playlist_CopyParents( p_parent, p_copy );
- }
-}
*****************************************************************************/
static int Demux( demux_t *p_demux )
{
+#if 0
playlist_t *p_playlist;
char *psz_line;
playlist_item_t *p_current;
b_play = E_(FindItem)( p_demux, p_playlist, &p_current );
playlist_ItemToNode( p_playlist, p_current );
- p_current->input.i_type = ITEM_TYPE_PLAYLIST;
+ p_current->p_input->i_type = ITEM_TYPE_PLAYLIST;
while( (psz_line = stream_ReadLine( p_demux->s )) )
{
vlc_object_release( p_playlist );
return VLC_SUCCESS;
+#endif
}
static struct
static int Demux( demux_t *p_demux )
{
- playlist_t *p_playlist;
char *psz_line;
-
char *psz_name = NULL;
char *psz_artist = NULL;
int i_parsed_duration = 0;
mtime_t i_duration = -1;
- char **ppsz_options = NULL;
- int i_options = 0, i;
-
- playlist_item_t *p_item, *p_current;
-
- vlc_bool_t b_play;
-
+ const char**ppsz_options = NULL;
+ int i_options = 0, i, i_parent_id;
vlc_bool_t b_cleanup = VLC_FALSE;
- p_playlist = (playlist_t *) vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
- FIND_ANYWHERE );
- if( !p_playlist )
- {
- msg_Err( p_demux, "can't find playlist" );
- return -1;
- }
-
- b_play = E_(FindItem)( p_demux, p_playlist, &p_current );
-
- playlist_ItemToNode( p_playlist, p_current );
- p_current->input.i_type = ITEM_TYPE_PLAYLIST;
+ INIT_PLAYLIST_STUFF;
psz_line = stream_ReadLine( p_demux->s );
while( psz_line )
sizeof("EXTVLCOPT:") -1 ) )
{
/* VLC Option */
- char *psz_option;
+ const char *psz_option;
psz_parse += sizeof("EXTVLCOPT:") -1;
if( !*psz_parse ) goto error;
EnsureUTF8( psz_name );
EnsureUTF8( psz_mrl );
- p_item = playlist_ItemNew( p_playlist, psz_mrl, psz_name );
for( i = 0; i< i_options; i++ )
- {
- EnsureUTF8( ppsz_options[i] );
- playlist_ItemAddOption( p_item, ppsz_options[i] );
- }
- p_item->input.i_duration = i_duration;
+ EnsureUTF8( (char*)ppsz_options[i] );
+
+ p_input = input_ItemNewExt( p_playlist, psz_mrl, psz_name,
+ i_options, ppsz_options, i_duration );
if ( psz_artist && *psz_artist )
- vlc_input_item_AddInfo( &p_item->input, _(VLC_META_INFO_CAT),
+ vlc_input_item_AddInfo( p_input, _(VLC_META_INFO_CAT),
_(VLC_META_ARTIST), "%s", psz_artist );
- playlist_NodeAddItem( p_playlist, p_item,
- p_current->pp_parents[0]->i_view,
- p_current, PLAYLIST_APPEND,
- PLAYLIST_END );
-
- /* We need to declare the parents of the node as the
- * * same of the parent's ones */
- playlist_CopyParents( p_current, p_item );
-
- vlc_input_item_CopyOptions( &p_current->input,
- &p_item->input );
-
+ fprintf( stderr, "Adding %s\n", p_input->psz_uri );
+ playlist_AddWhereverNeeded( p_playlist, p_input, p_current,
+ p_item_in_category, (i_parent_id > 0 )? VLC_TRUE : VLC_FALSE,
+ PLAYLIST_APPEND );
free( psz_mrl );
}
if( b_cleanup )
{
/* Cleanup state */
- while( i_options-- ) free( ppsz_options[i_options] );
+ while( i_options-- ) free( (char*)ppsz_options[i_options] );
if( ppsz_options ) free( ppsz_options );
ppsz_options = NULL; i_options = 0;
if( psz_name ) free( psz_name );
b_cleanup = VLC_FALSE;
}
}
-
- /* Go back and play the playlist */
- if( b_play && p_playlist->status.p_item &&
- p_playlist->status.p_item->i_children > 0 )
- {
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- p_playlist->status.i_view,
- p_playlist->status.p_item,
- p_playlist->status.p_item->pp_children[0] );
- }
-
- vlc_object_release( p_playlist );
+ HANDLE_PLAY_AND_RELEASE;
return VLC_SUCCESS;
}
return VLC_EGENERIC;
}
-static void parseEXTINF(char *psz_string, char **ppsz_artist,
+static void parseEXTINF(char *psz_string, char **ppsz_artist,
char **ppsz_name, int *pi_duration)
{
char *end = NULL;
*ppsz_artist = psz_string;
*ppsz_name = psz_item + 3; /* points directly after ' - ' */
return;
- }
+ }
/* reaching this point means: 0.8.1- with artist or something without artist */
if ( *psz_string == ',' )
psz_string++;
*ppsz_name = psz_string;
return;
- }
+ }
psz_item = psz_string;
psz_string = strchr( psz_string, ',' );
return VLC_EGENERIC;
}
- p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
while( ( psz_line = stream_ReadLine( p_demux->s) ) != NULL )
{
char *psz_unicode;
}
psz_unicode = FromLocale( psz_line );
- playlist_Add( p_playlist, psz_unicode, psz_unicode, PLAYLIST_APPEND,
- PLAYLIST_END );
+// playlist_Add( p_playlist, psz_unicode, psz_unicode, PLAYLIST_APPEND,
+// PLAYLIST_END );
free( psz_line );
LocaleFree( psz_line );
add_bool( "playlist-autostart", 1, NULL,
AUTOSTART_TEXT, AUTOSTART_LONGTEXT, VLC_FALSE );
+ add_integer( "parent-item", 0, NULL, NULL, NULL, VLC_TRUE );
+
set_shortname( _("Playlist") );
set_description( _("Playlist") );
add_shortcut( "old-open" );
return psz_mrl;
}
+void E_(AddToPlaylist)( demux_t *p_demux, playlist_t *p_playlist,
+ input_item_t *p_input,
+ playlist_item_t *p_item, int i_parent_id )
+{
+ // Only add to parent if specific parent requested or not current
+ // playlist item
+ if( i_parent_id > 0 || ! (
+ p_playlist->status.p_item &&
+ p_playlist->status.p_item->p_input ==
+ ((input_thread_t *)p_demux->p_parent)->input.p_item ) )
+ {
+ playlist_NodeAddInput( p_playlist, p_input, p_item,
+ PLAYLIST_APPEND, PLAYLIST_END );
+ }
+ // Else, add to both
+ else
+ {
+ playlist_BothAddInput( p_playlist, p_input, p_item,
+ PLAYLIST_APPEND, PLAYLIST_END );
+ }
+ vlc_input_item_CopyOptions( p_item->p_input, p_input );
+}
+
+
vlc_bool_t E_(FindItem)( demux_t *p_demux, playlist_t *p_playlist,
playlist_item_t **pp_item )
{
vlc_bool_t b_play = var_CreateGetBool( p_demux, "playlist-autostart" );
if( b_play && p_playlist->status.p_item &&
- &p_playlist->status.p_item->input ==
+ p_playlist->status.p_item->p_input ==
((input_thread_t *)p_demux->p_parent)->input.p_item )
{
msg_Dbg( p_playlist, "starting playlist playback" );
vlc_bool_t E_(FindItem)( demux_t *, playlist_t *, playlist_item_t **);
+void E_(AddToPlaylist)( demux_t *, playlist_t*,input_item_t*,playlist_item_t*,int );
+
int E_(Import_Old) ( vlc_object_t * );
int E_(Import_Native) ( vlc_object_t * );
int E_(Import_Shoutcast) ( vlc_object_t * );
void E_(Close_Shoutcast) ( vlc_object_t * );
+
+#define INIT_PLAYLIST_STUFF \
+ vlc_bool_t b_play; \
+ playlist_item_t *p_current, *p_item_in_category = NULL; \
+ input_item_t *p_input; \
+ playlist_t *p_playlist = (playlist_t *) vlc_object_find( p_demux, \
+ VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); \
+ if( !p_playlist ) \
+ { \
+ msg_Err( p_demux, "can't find playlist" ); \
+ return VLC_EGENERIC; \
+ } \
+ i_parent_id = var_CreateGetInteger( p_demux, "parent-item" ); \
+ if( i_parent_id > 0 ) \
+ { \
+ b_play = VLC_FALSE; \
+ p_current = playlist_ItemGetById( p_playlist, i_parent_id ); \
+ } \
+ else \
+ { \
+ b_play = E_(FindItem)( p_demux, p_playlist, &p_current ); \
+ p_item_in_category = playlist_ItemToNode( p_playlist, p_current ); \
+ p_current->p_input->i_type = ITEM_TYPE_PLAYLIST; \
+ }
+
+#define HANDLE_PLAY_AND_RELEASE \
+ /* Go back and play the playlist */ \
+ if( b_play && p_playlist->status.p_item && \
+ p_playlist->status.p_item->i_children > 0 ) \
+ { \
+ playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, 1242, \
+ p_playlist->status.p_item, NULL ); \
+ } \
+ vlc_object_release( p_playlist );
+
static int Demux( demux_t *p_demux )
{
+#if 0
mtime_t i_duration = -1;
char *psz_name = NULL;
char *psz_line;
}
vlc_object_release( p_playlist );
return VLC_SUCCESS;
+#endif
}
static int Control( demux_t *p_demux, int i_query, va_list args )
static int Demux( demux_t *p_demux )
{
demux_sys_t *p_sys = p_demux->p_sys;
- playlist_t *p_playlist;
- playlist_item_t *p_item, *p_current;
- vlc_bool_t b_play;
vlc_bool_t b_item = VLC_FALSE;
vlc_bool_t b_image = VLC_FALSE;
- int i_ret;
+ int i_ret, i_parent_id;
xml_t *p_xml;
xml_reader_t *p_xml_reader;
char *psz_item_summary = NULL;
int i_type;
- p_playlist = (playlist_t *) vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
- FIND_ANYWHERE );
- if( !p_playlist )
- {
- msg_Err( p_demux, "can't find playlist" );
- return -1;
- }
- p_sys->p_playlist = p_playlist;
-
- b_play = E_(FindItem)( p_demux, p_playlist, &p_current );
-
- playlist_ItemToNode( p_playlist, p_current );
- p_current->input.i_type = ITEM_TYPE_PLAYLIST;
+ INIT_PLAYLIST_STUFF;
p_xml = p_sys->p_xml = xml_Create( p_demux );
if( !p_xml ) return -1;
else if( b_item == VLC_FALSE && b_image == VLC_FALSE
&& !strcmp( psz_elname, "link" ) )
{
- vlc_input_item_AddInfo( &(p_current->input),
+ vlc_input_item_AddInfo( p_current->p_input,
_( "Podcast Info" ),
_( "Podcast Link" ),
"%s",
else if( b_item == VLC_FALSE && b_image == VLC_FALSE
&& !strcmp( psz_elname, "copyright" ) )
{
- vlc_input_item_AddInfo( &(p_current->input),
+ vlc_input_item_AddInfo( p_current->p_input,
_( "Podcast Info" ),
_( "Podcast Copyright" ),
"%s",
else if( b_item == VLC_FALSE && b_image == VLC_FALSE
&& !strcmp( psz_elname, "itunes:category" ) )
{
- vlc_input_item_AddInfo( &(p_current->input),
+ vlc_input_item_AddInfo( p_current->p_input,
_( "Podcast Info" ),
_( "Podcast Category" ),
"%s",
else if( b_item == VLC_FALSE && b_image == VLC_FALSE
&& !strcmp( psz_elname, "itunes:keywords" ) )
{
- vlc_input_item_AddInfo( &(p_current->input),
+ vlc_input_item_AddInfo( p_current->p_input,
_( "Podcast Info" ),
_( "Podcast Keywords" ),
"%s",
else if( b_item == VLC_FALSE && b_image == VLC_FALSE
&& !strcmp( psz_elname, "itunes:subtitle" ) )
{
- vlc_input_item_AddInfo( &(p_current->input),
+ vlc_input_item_AddInfo( p_current->p_input,
_( "Podcast Info" ),
_( "Podcast Subtitle" ),
"%s",
&& ( !strcmp( psz_elname, "itunes:summary" )
||!strcmp( psz_elname, "description" ) ) )
{ /* <description> isn't standard iTunes podcast stuff */
- vlc_input_item_AddInfo( &(p_current->input),
+ vlc_input_item_AddInfo( p_current->p_input,
_( "Podcast Info" ),
_( "Podcast Summary" ),
"%s",
if( !psz_elname ) return -1;
if( !strcmp( psz_elname, "item" ) )
{
- p_item = playlist_ItemNew( p_playlist, psz_item_mrl,
- psz_item_name );
- if( p_item == NULL ) break;
- playlist_NodeAddItem( p_playlist, p_item,
- p_current->pp_parents[0]->i_view,
- p_current, PLAYLIST_APPEND,
- PLAYLIST_END );
-
- /* We need to declare the parents of the node as the
- * * same of the parent's ones */
- playlist_CopyParents( p_current, p_item );
-
+ p_input = input_ItemNewExt( p_playlist, psz_item_mrl,
+ psz_item_name, 0, NULL, -1 );
+ if( p_input == NULL ) break;
if( psz_item_date )
{
- vlc_input_item_AddInfo( &p_item->input,
+ vlc_input_item_AddInfo( p_input,
_( "Podcast Info" ),
_( "Podcast Publication Date" ),
"%s",
}
if( psz_item_author )
{
- vlc_input_item_AddInfo( &p_item->input,
+ vlc_input_item_AddInfo( p_input,
_( "Podcast Info" ),
_( "Podcast Author" ),
"%s",
}
if( psz_item_category )
{
- vlc_input_item_AddInfo( &p_item->input,
+ vlc_input_item_AddInfo( p_input,
_( "Podcast Info" ),
_( "Podcast Subcategory" ),
"%s",
}
if( psz_item_duration )
{
- vlc_input_item_AddInfo( &p_item->input,
+ vlc_input_item_AddInfo( p_input,
_( "Podcast Info" ),
_( "Podcast Duration" ),
"%s",
}
if( psz_item_keywords )
{
- vlc_input_item_AddInfo( &p_item->input,
+ vlc_input_item_AddInfo( p_input,
_( "Podcast Info" ),
_( "Podcast Keywords" ),
"%s",
}
if( psz_item_subtitle )
{
- vlc_input_item_AddInfo( &p_item->input,
+ vlc_input_item_AddInfo( p_input,
_( "Podcast Info" ),
_( "Podcast Subtitle" ),
"%s",
}
if( psz_item_summary )
{
- vlc_input_item_AddInfo( &p_item->input,
+ vlc_input_item_AddInfo( p_input,
_( "Podcast Info" ),
_( "Podcast Summary" ),
"%s",
}
if( psz_item_size )
{
- vlc_input_item_AddInfo( &p_item->input,
+ vlc_input_item_AddInfo( p_input,
_( "Podcast Info" ),
_( "Podcast Size" ),
"%s bytes",
}
if( psz_item_type )
{
- vlc_input_item_AddInfo( &p_item->input,
+ vlc_input_item_AddInfo( p_input,
_( "Podcast Info" ),
_( "Podcast Type" ),
"%s",
psz_item_type );
}
+ fprintf( stderr, "Adding WHEREVER\n");
+ playlist_AddWhereverNeeded( p_playlist, p_input, p_current,
+ p_item_in_category, (i_parent_id > 0 ) ? VLC_TRUE:
+ VLC_FALSE, PLAYLIST_APPEND );
#define FREE(a) if( a ) free( a ); a = NULL;
FREE( psz_item_name );
FREE( psz_item_mrl );
msg_Warn( p_demux, "error while parsing data" );
}
- /* Go back and play the playlist */
- if( b_play && p_playlist->status.p_item &&
- p_playlist->status.p_item->i_children > 0 )
- {
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- p_playlist->status.i_view,
- p_playlist->status.p_item,
- p_playlist->status.p_item->pp_children[0] );
- }
-
- vlc_object_release( p_playlist );
- p_sys->p_playlist = NULL;
+ HANDLE_PLAY_AND_RELEASE;
return VLC_SUCCESS;
}
static int Demux( demux_t *p_demux )
{
+#if 0
demux_sys_t *p_sys = p_demux->p_sys;
playlist_t *p_playlist;
vlc_object_release( p_playlist );
p_sys->p_playlist = NULL;
+#endif
return VLC_SUCCESS;
}
**/
static int DemuxGenre( demux_t *p_demux )
{
+#if 0
demux_sys_t *p_sys = p_demux->p_sys;
char *psz_name = NULL; /* genre name */
char *psz_eltname = NULL; /* tag name */
break;
}
}
+#endif
return 0;
}
**/
static int DemuxStation( demux_t *p_demux )
{
+#if 0
demux_sys_t *p_sys = p_demux->p_sys;
char *psz_base = NULL; /* */
break;
}
}
+#endif
return 0;
}
#undef FREE
*/
int xspf_import_Demux( demux_t *p_demux )
{
+#if 0
playlist_t *p_playlist = NULL;
playlist_item_t *p_current = NULL;
xml_Delete( p_xml );
return i_ret;
+#endif
}
/** \brief dummy function for demux callback interface */
{
return VLC_EGENERIC;
}
-
+#if 0
/**
* \brief parse the root node of a XSPF playlist
* \param p_demux demuxer instance
return VLC_TRUE;
}
+#endif
free( temp );
}
+ msg_Err( p_playlist, "SGIMB playlist handling is broken" );
+#if 0
p_child = playlist_ItemNew( p_playlist, p_sys->psz_uri,
p_sys->psz_name ? p_sys->psz_name : p_sys->psz_uri );
playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
p_playlist->status.i_view,
p_playlist->status.p_item, NULL );
-
+#endif
vlc_object_release( p_playlist );
return VLC_SUCCESS;
}
* - ...
*/
+#define vlc_meta_Add(a,b,c) fprintf(stderr, "FIXME: TS demuxer meta is broken\n" )
/*****************************************************************************
* Module descriptor
*****************************************************************************/
while( i_strings > 0 )
{
+ vlc_meta_t *p_meta = (vlc_meta_t *)(p_demux->p_private);
+
char *psz_temp = id3_ucs4_utf8duplicate(
id3_field_getstrings( &p_frame->fields[1], --i_strings ) );
if( psz_temp != psz_endptr &&
i_genre >= 0 && i_genre < NUM_GENRES )
{
- vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
- VLC_META_GENRE, ppsz_genres[atoi(psz_temp)]);
+ vlc_meta_SetGenre( p_meta, ppsz_genres[atoi(psz_temp)]);
}
else
{
/* Unknown genre */
- vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
- VLC_META_GENRE, psz_temp );
+ vlc_meta_SetGenre( p_meta,psz_temp );
}
}
else if( !strcmp(p_frame->id, ID3_FRAME_TITLE ) )
{
- vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
- VLC_META_TITLE, psz_temp );
+ vlc_meta_SetTitle( p_meta, psz_temp );
}
else if( !strcmp(p_frame->id, ID3_FRAME_ARTIST ) )
{
- vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
- VLC_META_ARTIST, psz_temp );
+ vlc_meta_SetArtist( p_meta, psz_temp );
}
else if( !strcmp(p_frame->id, ID3_FRAME_YEAR ) )
{
- vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
- VLC_META_DATE, psz_temp );
+ vlc_meta_SetDate( p_meta, psz_temp );
}
else if( !strcmp(p_frame->id, ID3_FRAME_COMMENT ) )
{
- vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
- VLC_META_DESCRIPTION, psz_temp );
+ vlc_meta_SetDescription( p_meta, psz_temp );
}
else if( strstr( (char*)p_frame->description, "Copyright" ) )
{
- vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
- VLC_META_COPYRIGHT, psz_temp );
+ vlc_meta_SetCopyright( p_meta, psz_temp );
}
else if( strstr( (char*)p_frame->description, "Publisher" ) )
{
- vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
- VLC_META_PUBLISHER, psz_temp );
+ vlc_meta_SetPublisher( p_meta, psz_temp );
}
else
{
- /* Unknown meta info */
- vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
- (char *)p_frame->description, psz_temp );
+ msg_Err(p_demux, "Fixme: unhandled meta" );
}
free( psz_temp );
}
if ( o_urlString )
{
NSURL * o_url;
-
- playlist_Add( p_playlist, [o_urlString fileSystemRepresentation],
- [[[NSFileManager defaultManager] displayNameAtPath: o_urlString] UTF8String],
- PLAYLIST_INSERT, PLAYLIST_END );
+ input_item_t *p_input;
+
+ p_input = input_ItemNew( p_playlist,
+ [o_urlString fileSystemRepresentation],
+ [[[NSFileManager defaultManager]
+ displayNameAtPath: o_urlString] UTF8String] );
+ playlist_PlaylistAddInput( p_playlist, p_input, PLAYLIST_INSERT,
+ PLAYLIST_END );
+
o_url = [NSURL fileURLWithPath: o_urlString];
if( o_url != nil )
- {
+ {
[[NSDocumentController sharedDocumentController]
- noteNewRecentDocumentURL: o_url];
+ noteNewRecentDocumentURL: o_url];
}
}
vlc_object_release( p_playlist );
return;
}
-#define p_input p_intf->p_sys->p_input
if( p_intf->p_sys->b_input_update )
{
/* Called when new input is opened */
vlc_object_release( p_playlist );
- if( ( b_input = ( p_input != NULL ) ) )
+ if( ( b_input = ( p_intf->p_sys->p_input != NULL ) ) )
{
- vlc_object_yield( p_input );
+ vlc_object_yield( p_intf->p_sys->p_input );
/* seekable streams */
- b_seekable = var_GetBool( p_input, "seekable" );
+ b_seekable = var_GetBool( p_intf->p_sys->p_input, "seekable" );
/* check wether slow/fast motion is possible*/
- b_control = p_input->input.b_can_pace_control;
+ b_control = p_intf->p_sys->p_input->input.b_can_pace_control;
/* chapters & titles */
- //b_chapters = p_input->stream.i_area_nb > 1;
+ //b_chapters = p_intf->p_sys->p_input->stream.i_area_nb > 1;
vlc_object_release( p_input );
}
return;
}
o_temp = [NSString stringWithUTF8String:
- p_playlist->status.p_item->input.psz_name];
+ p_playlist->status.p_item->p_input->psz_name];
if( o_temp == NULL )
o_temp = [NSString stringWithCString:
- p_playlist->status.p_item->input.psz_name];
+ p_playlist->status.p_item->p_input->psz_name];
[self setScrollField: o_temp stopAfter:-1];
- p_vout = vlc_object_find( p_input, VLC_OBJECT_VOUT,
+ p_vout = vlc_object_find( p_intf->p_sys->p_input, VLC_OBJECT_VOUT,
FIND_PARENT );
if( p_vout != NULL )
{
p_intf->p_sys->b_current_title_update = FALSE;
}
- if( p_input && [o_timeslider isEnabled] )
+ if( p_intf->p_sys->p_input && [o_timeslider isEnabled] )
{
/* Update the slider */
vlc_value_t time;
vlc_value_t pos;
float f_updated;
- var_Get( p_input, "position", &pos );
+ var_Get( p_intf->p_sys->p_input, "position", &pos );
f_updated = 10000. * pos.f_float;
[o_timeslider setFloatValue: f_updated];
- var_Get( p_input, "time", &time );
+ var_Get( p_intf->p_sys->p_input, "time", &time );
i_seconds = time.i_time / 1000000;
o_time = [NSString stringWithFormat: @"%d:%02d:%02d",
}
/* Manage Playing status */
- var_Get( p_input, "state", &val );
+ var_Get( p_intf->p_sys->p_input, "state", &val );
if( p_intf->p_sys->i_play_status != val.i_int )
{
p_intf->p_sys->i_play_status = val.i_int;
[self setSubmenusEnabled: FALSE];
}
-#undef p_input
[self updateMessageArray];
- (void)resetScrollField
{
i_end_scroll = -1;
-#define p_input p_intf->p_sys->p_input
- if( p_input && !p_input->b_die )
+ if( p_intf->p_sys->p_input && !p_intf->p_sys->p_input->b_die )
{
NSString *o_temp;
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
return;
}
o_temp = [NSString stringWithUTF8String:
- p_playlist->status.p_item->input.psz_name];
+ p_playlist->status.p_item->p_input->psz_name];
if( o_temp == NULL )
o_temp = [NSString stringWithCString:
- p_playlist->status.p_item->input.psz_name];
+ p_playlist->status.p_item->p_input->psz_name];
[self setScrollField: o_temp stopAfter:-1];
vlc_object_release( p_playlist );
return;
}
-#undef p_input
[self setScrollField: _NS("VLC media player") stopAfter:-1];
}
IBOutlet id o_outline_view;
NSMutableDictionary *o_outline_dict;
- int i_current_view;
}
- (void)initStrings;
- (IBAction)addNode:(id)sender;
- (void)appendArray:(NSArray*)o_array atPos:(int)i_position enqueue:(BOOL)b_enqueue;
-- (void)appendNodeArray:(NSArray*)o_array inNode:(playlist_item_t *)p_node atPos:(int)i_position inView:(int)i_view enqueue:(BOOL)b_enqueue;
+- (void)appendNodeArray:(NSArray*)o_array inNode:(playlist_item_t *)p_node atPos:(int)i_position enqueue:(BOOL)b_enqueue;
@end
{
playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
- i_current_view = VIEW_CATEGORY;
- playlist_ViewUpdate( p_playlist, i_current_view );
-
[o_outline_view setTarget: self];
[o_outline_view setDelegate: self];
[o_outline_view setDataSource: self];
if( item == nil )
{
/* root object */
- playlist_view_t *p_view;
- p_view = playlist_ViewFind( p_playlist, i_current_view );
- if( p_view && p_view->p_root )
+ if( p_playlist->p_root_category )
{
- i_return = p_view->p_root->i_children;
-
- if( i_current_view == VIEW_CATEGORY )
- {
- i_return--; /* remove the GENERAL item from the list */
- i_return += p_playlist->p_general->i_children; /* add the items of the general node */
- }
+ i_return = p_playlist->p_root_category->i_children;
}
}
else
i_return = p_item->i_children;
}
vlc_object_release( p_playlist );
-
+
if( i_return <= 0 )
i_return = 0;
-
+
return i_return;
}
if( item == nil )
{
/* root object */
- playlist_view_t *p_view;
- p_view = playlist_ViewFind( p_playlist, i_current_view );
- if( p_view && p_view->p_root ) p_return = p_view->p_root->pp_children[index];
-
- if( i_current_view == VIEW_CATEGORY )
+ if( p_playlist->p_root_category )
{
- if( p_playlist->p_general->i_children && index >= 0 && index < p_playlist->p_general->i_children )
- {
- p_return = p_playlist->p_general->pp_children[index];
- }
- else if( p_view && p_view->p_root && index >= 0 && index - p_playlist->p_general->i_children < p_view->p_root->i_children )
- {
- p_return = p_view->p_root->pp_children[index - p_playlist->p_general->i_children + 1];
- }
+ p_return = p_playlist->p_root_category->pp_children[index];
}
}
else
if( p_item && index < p_item->i_children && index >= 0 )
p_return = p_item->pp_children[index];
}
-
vlc_object_release( p_playlist );
if( item == nil )
{
/* root object */
- playlist_view_t *p_view;
- p_view = playlist_ViewFind( p_playlist, i_current_view );
- if( p_view && p_view->p_root ) i_return = p_view->p_root->i_children;
-
- if( i_current_view == VIEW_CATEGORY )
+ if( p_playlist->p_root_category )
{
- i_return--;
- i_return += p_playlist->p_general->i_children;
+ i_return = p_playlist->p_root_category->i_children;
}
}
else
if( [[o_tc identifier] isEqualToString:@"1"] )
{
o_value = [NSString stringWithUTF8String:
- p_item->input.psz_name];
+ p_item->p_input->psz_name];
if( o_value == NULL )
o_value = [NSString stringWithCString:
- p_item->input.psz_name];
+ p_item->p_input->psz_name];
}
else if( [[o_tc identifier] isEqualToString:@"2"] )
{
char *psz_temp;
- psz_temp = vlc_input_item_GetInfo( &p_item->input ,_("Meta-information"),_("Artist") );
+ psz_temp = vlc_input_item_GetInfo( p_item->p_input ,_("Meta-information"),_("Artist") );
if( psz_temp == NULL )
o_value = @"";
else if( [[o_tc identifier] isEqualToString:@"3"] )
{
char psz_duration[MSTRTIME_MAX_SIZE];
- mtime_t dur = p_item->input.i_duration;
+ mtime_t dur = p_item->p_input->i_duration;
if( dur != -1 )
{
secstotimestr( psz_duration, dur/1000000 );
vlc_object_release( p_playlist );
}
-- (playlist_item_t *)parentOfItem:(playlist_item_t *)p_item
-{
- int i;
- for( i = 0 ; i < p_item->i_parents; i++ )
- {
- if( p_item->pp_parents[i]->i_view == i_current_view )
- {
- return p_item->pp_parents[i]->p_parent;
- }
- }
- return NULL;
-}
-
- (void)updateRowSelection
{
int i_row;
}
p_temp_item = p_item;
- while( p_temp_item->i_parents > 0 )
+ while( p_temp_item->p_parent )
{
[o_array insertObject: [NSValue valueWithPointer: p_temp_item] atIndex: 0];
-
- p_temp_item = [self parentOfItem: p_temp_item];
+ p_temp_item = p_temp_item->p_parent;
/*for (i = 0 ; i < p_temp_item->i_parents ; i++)
{
if( p_temp_item->pp_parents[i]->i_view == i_current_view )
}*/
}
- for (j = 0 ; j < [o_array count] - 1 ; j++)
+ for( j = 0; j < [o_array count] - 1; j++ )
{
id o_item;
if( ( o_item = [o_outline_dict objectForKey:
[NSString stringWithFormat: @"%p",
[[o_array objectAtIndex:j] pointerValue]]] ) != nil )
+ {
+ msg_Err( p_playlist, "o_item: %p", o_item );
[o_outline_view expandItem: o_item];
+ }
}
}
}
- while( p_temp_item->i_parents > 0 )
+ while( p_temp_item )
{
- p_temp_item = [self parentOfItem: p_temp_item];
+ p_temp_item = p_temp_item->p_parent;
if( p_temp_item == p_node )
{
vlc_mutex_unlock( &p_playlist->object_lock );
vlc_object_release( p_playlist );
return YES;
}
-
-/* for( i = 0; i < p_temp_item->i_parents ; i++ )
- {
- if( p_temp_item->pp_parents[i]->i_view == i_current_view )
- {
- if( p_temp_item->pp_parents[i]->p_parent == p_node )
- {
- vlc_mutex_unlock( &p_playlist->object_lock );
- vlc_object_release( p_playlist );
- return YES;
- }
- else
- {
- p_temp_item = p_temp_item->pp_parents[i]->p_parent;
- break;
- }
- }
- }*/
}
vlc_mutex_unlock( &p_playlist->object_lock );
}
{
o_real_filename = o_filename;
}
- playlist_Export( p_playlist, [o_real_filename fileSystemRepresentation], "export-m3u" );
+ playlist_Export( p_playlist, [o_real_filename fileSystemRepresentation], p_playlist->p_local_category, "export-m3u" );
}
}
vlc_object_release( p_playlist );
{
if( p_item->i_children == -1 )
{
- p_node = [self parentOfItem: p_item];
+ p_node = p_item->p_parent;
-/* for( i = 0 ; i < p_item->i_parents ; i++ )
- {
- if( p_item->pp_parents[i]->i_view == i_current_view )
- {
- p_node = p_item->pp_parents[i]->p_parent;
- }
- }*/
}
else
{
p_item = NULL;
}
}
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, i_current_view, p_node, p_item );
+ playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, 0, p_node, p_item );
}
vlc_object_release( p_playlist );
}
{
if( p_item->i_children == -1 )
{
- playlist_PreparseEnqueue( p_playlist, &p_item->input );
+ playlist_PreparseEnqueue( p_playlist, p_item->p_input );
}
else
{
[o_mi setState: playlist_IsServicesDiscoveryLoaded( p_playlist,
[o_string cString] ) ? YES : NO];
- i_current_view = VIEW_CATEGORY;
- playlist_ViewUpdate( p_playlist, i_current_view );
vlc_object_release( p_playlist );
[self playlistUpdated];
return;
}
else
{
- if( p_playlist->status.i_status != PLAYLIST_STOPPED &&
- p_playlist->status.p_item == [[o_outline_view itemAtRow: i_row] pointerValue] )
- {
- playlist_Stop( p_playlist );
- }
- vlc_mutex_lock( &p_playlist->object_lock );
- playlist_Delete( p_playlist, p_item->input.i_id );
- vlc_mutex_unlock( &p_playlist->object_lock );
+ playlist_LockDelete( p_playlist, p_item->i_id );
}
}
[self playlistUpdated];
else
/*If no item is selected, sort the whole playlist*/
{
- playlist_view_t * p_view = playlist_ViewFind( p_playlist, i_current_view );
- p_item = p_view->p_root;
+ p_item = p_playlist->p_root_category;
}
if( p_item->i_children > -1 ) // the item is a node
}
else
{
- int i;
-
- for( i = 0 ; i < p_item->i_parents ; i++ )
- {
- if( p_item->pp_parents[i]->i_view == i_current_view )
- {
- vlc_mutex_lock( &p_playlist->object_lock );
- playlist_RecursiveNodeSort( p_playlist,
- p_item->pp_parents[i]->p_parent, i_mode, ORDER_NORMAL );
- vlc_mutex_unlock( &p_playlist->object_lock );
- break;
- }
- }
+ vlc_mutex_lock( &p_playlist->object_lock );
+ playlist_RecursiveNodeSort( p_playlist,
+ p_item->p_parent, i_mode, ORDER_NORMAL );
+ vlc_mutex_unlock( &p_playlist->object_lock );
}
vlc_object_release( p_playlist );
[self playlistUpdated];
}
-- (playlist_item_t *)createItem:(NSDictionary *)o_one_item
+- (input_item_t *)createItem:(NSDictionary *)o_one_item
{
intf_thread_t * p_intf = VLCIntf;
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
{
return NULL;
}
- playlist_item_t *p_item;
+ input_item_t *p_input;
int i;
BOOL b_rem = FALSE, b_dir = FALSE;
NSString *o_uri, *o_name;
o_uri = o_temp;
}
- p_item = playlist_ItemNew( p_intf, [o_uri fileSystemRepresentation], [o_name UTF8String] );
- if( !p_item )
+ p_input = input_ItemNew( p_playlist, [o_uri fileSystemRepresentation], [o_name UTF8String] );
+ if( !p_input )
return NULL;
if( o_options )
{
for( i = 0; i < (int)[o_options count]; i++ )
{
- playlist_ItemAddOption( p_item, strdup( [[o_options objectAtIndex:i] UTF8String] ) );
+ vlc_input_item_AddOption( p_input, strdup( [[o_options objectAtIndex:i] UTF8String] ) );
}
}
}
vlc_object_release( p_playlist );
- return p_item;
+ return p_input;
}
- (void)appendArray:(NSArray*)o_array atPos:(int)i_position enqueue:(BOOL)b_enqueue
for( i_item = 0; i_item < (int)[o_array count]; i_item++ )
{
- playlist_item_t *p_item;
+ input_item_t *p_input;
NSDictionary *o_one_item;
/* Get the item */
o_one_item = [o_array objectAtIndex: i_item];
- p_item = [self createItem: o_one_item];
- if( !p_item )
+ p_input = [self createItem: o_one_item];
+ if( !p_input )
{
continue;
}
/* Add the item */
- playlist_AddItem( p_playlist, p_item, PLAYLIST_INSERT, i_position == -1 ? PLAYLIST_END : i_position + i_item );
+ playlist_PlaylistAddInput( p_playlist, p_input, PLAYLIST_INSERT,
+ i_position == -1 ? PLAYLIST_END : i_position + i_item );
if( i_item == 0 && !b_enqueue )
{
+ playlist_item_t *p_item;
+ p_item = playlist_ItemGetByInput( p_playlist, p_input );
playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
}
+ else
+ {
+ playlist_item_t *p_item;
+ p_item = playlist_ItemGetByInput( p_playlist, p_input );
+ playlist_Control( p_playlist, PLAYLIST_PREPARSE, p_item );
+ }
}
+ [self playlistUpdated];
vlc_object_release( p_playlist );
}
-- (void)appendNodeArray:(NSArray*)o_array inNode:(playlist_item_t *)p_node atPos:(int)i_position inView:(int)i_view enqueue:(BOOL)b_enqueue
+- (void)appendNodeArray:(NSArray*)o_array inNode:(playlist_item_t *)p_node atPos:(int)i_position enqueue:(BOOL)b_enqueue
{
int i_item;
playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
for( i_item = 0; i_item < (int)[o_array count]; i_item++ )
{
- playlist_item_t *p_item;
+ input_item_t *p_input;
NSDictionary *o_one_item;
/* Get the item */
o_one_item = [o_array objectAtIndex: i_item];
- p_item = [self createItem: o_one_item];
- if( !p_item )
+ p_input = [self createItem: o_one_item];
+ if( !p_input )
{
continue;
}
/* Add the item */
- playlist_NodeAddItem( p_playlist, p_item, i_view, p_node, PLAYLIST_INSERT, i_position + i_item );
+ playlist_NodeAddInput( p_playlist, p_input, p_node,
+ PLAYLIST_INSERT,
+ i_position == -1 ?
+ PLAYLIST_END : i_position + i_item );
+
if( i_item == 0 && !b_enqueue )
{
+ playlist_item_t *p_item;
+ p_item = playlist_ItemGetByInput( p_playlist, p_input );
playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
}
+ else
+ {
+ playlist_item_t *p_item;
+ p_item = playlist_ItemGetByInput( p_playlist, p_input );
+ playlist_Control( p_playlist, PLAYLIST_PREPARSE, p_item );
+ }
}
+ [self playlistUpdated];
vlc_object_release( p_playlist );
-
}
- (IBAction)handlePopUp:(id)sender
vlc_mutex_lock( &p_playlist->object_lock );
o_current_name = [NSString stringWithUTF8String:
- p_item->pp_children[i_current]->input.psz_name];
- psz_temp = vlc_input_item_GetInfo( &p_item->input ,
+ p_item->pp_children[i_current]->p_input->psz_name];
+ psz_temp = vlc_input_item_GetInfo( p_item->p_input ,
_("Meta-information"),_("Artist") );
o_current_author = [NSString stringWithUTF8String: psz_temp];
free( psz_temp);
{
playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
- playlist_view_t * p_view;
id o_result;
unsigned int i;
if( p_playlist == NULL )
return;
- p_view = playlist_ViewFind( p_playlist, i_current_view );
- if( p_view )
- {
/*First, only search after the selected item:*
*(b_selected_item_met = NO) */
- o_result = [self subSearchItem:p_view->p_root];
- if( o_result == NULL )
- {
- /* If the first search failed, search again from the beginning */
- o_result = [self subSearchItem:p_view->p_root];
- }
- if( o_result != NULL )
- {
- int i_start;
- if( [[o_result objectAtIndex: 0] pointerValue] ==
- p_playlist->p_general )
- i_start = 1;
- else
- i_start = 0;
+ o_result = [self subSearchItem:p_playlist->p_root_category];
+ if( o_result == NULL )
+ {
+ /* If the first search failed, search again from the beginning */
+ o_result = [self subSearchItem:p_playlist->p_root_category];
+ }
+ if( o_result != NULL )
+ {
+ int i_start;
+ if( [[o_result objectAtIndex: 0] pointerValue] ==
+ p_playlist->p_local_category )
+ i_start = 1;
+ else
+ i_start = 0;
- for( i = i_start ; i < [o_result count] - 1 ; i++ )
- {
- [o_outline_view expandItem: [o_outline_dict objectForKey:
- [NSString stringWithFormat: @"%p",
- [[o_result objectAtIndex: i] pointerValue]]]];
- }
- i_row = [o_outline_view rowForItem: [o_outline_dict objectForKey:
- [NSString stringWithFormat: @"%p",
- [[o_result objectAtIndex: [o_result count] - 1 ]
- pointerValue]]]];
- }
- if( i_row > -1 )
+ for( i = i_start ; i < [o_result count] - 1 ; i++ )
{
- [o_outline_view selectRow:i_row byExtendingSelection: NO];
- [o_outline_view scrollRowToVisible: i_row];
+ [o_outline_view expandItem: [o_outline_dict objectForKey:
+ [NSString stringWithFormat: @"%p",
+ [[o_result objectAtIndex: i] pointerValue]]]];
}
+ i_row = [o_outline_view rowForItem: [o_outline_dict objectForKey:
+ [NSString stringWithFormat: @"%p",
+ [[o_result objectAtIndex: [o_result count] - 1 ]
+ pointerValue]]]];
+ }
+ if( i_row > -1 )
+ {
+ [o_outline_view selectRow:i_row byExtendingSelection: NO];
+ [o_outline_view scrollRowToVisible: i_row];
}
vlc_object_release( p_playlist );
}
- (IBAction)recursiveExpandNode:(id)sender
{
- int i;
id o_item = [o_outline_view itemAtRow: [o_outline_view selectedRow]];
playlist_item_t *p_item = (playlist_item_t *)[o_item pointerValue];
if( ![[o_outline_view dataSource] outlineView: o_outline_view
isItemExpandable: o_item] )
{
- for( i = 0 ; i < p_item->i_parents ; i++ )
- {
- if( p_item->pp_parents[i]->i_view == i_current_view )
- {
- o_item = [o_outline_dict objectForKey: [NSString
- stringWithFormat: @"%p", p_item->pp_parents[i]->p_parent]];
- break;
- }
- }
+ o_item = [o_outline_dict objectForKey: [NSString
+ stringWithFormat: @"%p", p_item->p_parent]];
}
/* We need to collapse the node first, since OSX refuses to recursively
{
int i_mode = 0, i_type;
intf_thread_t *p_intf = VLCIntf;
- playlist_view_t *p_view;
playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
return;
}
- p_view = playlist_ViewFind( p_playlist, i_current_view );
-
if( o_tc_sortColumn == o_tc )
{
b_isSortDescending = !b_isSortDescending;
}
vlc_mutex_lock( &p_playlist->object_lock );
- playlist_RecursiveNodeSort( p_playlist, p_view->p_root, i_mode, i_type );
+ playlist_RecursiveNodeSort( p_playlist, p_playlist->p_root_category, i_mode, i_type );
vlc_mutex_unlock( &p_playlist->object_lock );
vlc_object_release( p_playlist );
return;
}
- playlist_item_t * p_item = playlist_NodeCreate( p_playlist, VIEW_CATEGORY,
- _("Empty Folder"), p_playlist->p_general );
+ playlist_item_t * p_item = playlist_NodeCreate( p_playlist,
+ _("Empty Folder"), p_playlist->p_local_category );
if(! p_item )
msg_Warn( VLCIntf, "node creation failed" );
-
- playlist_ViewUpdate( p_playlist, VIEW_CATEGORY );
-
+
vlc_object_release( p_playlist );
+ [self playlistUpdated];
}
@end
/* Refuse to move items that are not in the General Node
(Service Discovery) */
if( ![self isItem: [o_item pointerValue] inNode:
- p_playlist->p_general checkItemExistence: NO])
+ p_playlist->p_local_category checkItemExistence: NO])
{
vlc_object_release(p_playlist);
return NO;
/* We refuse to drop an item in anything else than a child of the General
Node. We still accept items that would be root nodes of the outlineview
however, to allow drop in an empty playlist. */
- if( !([self isItem: [item pointerValue] inNode: p_playlist->p_general
+ if( !([self isItem: [item pointerValue] inNode: p_playlist->p_local_category
checkItemExistence: NO] || item == nil) )
{
vlc_object_release( p_playlist );
/* If the item is to be dropped as root item of the outline, make it a
child of the General node.
Else, choose the proposed parent as parent. */
- if( item == nil ) p_new_parent = p_playlist->p_general;
+ if( item == nil ) p_new_parent = p_playlist->p_local_category;
else p_new_parent = [item pointerValue];
/* Make sure the proposed parent is a node.
int i_old_index = 0;
p_item = [[o_all_items objectAtIndex:i] pointerValue];
- p_old_parent = [self parentOfItem: p_item];
+ p_old_parent = p_item->p_parent;
if( !p_old_parent )
continue;
/* We may need the old index later */
vlc_mutex_lock( &p_playlist->object_lock );
// Acually detach the item from the old position
if( playlist_NodeRemoveItem( p_playlist, p_item, p_old_parent ) ==
- VLC_SUCCESS &&
- playlist_NodeRemoveParent( p_playlist, p_item, p_old_parent ) ==
VLC_SUCCESS )
{
int i_new_index;
i_new_index = index + i - i_removed_from_node;
}
// Reattach the item to the new position
- playlist_NodeInsert( p_playlist, i_current_view, p_item,
- p_new_parent, i_new_index );
+ playlist_NodeInsert( p_playlist, p_item, p_new_parent, i_new_index );
}
vlc_mutex_unlock( &p_playlist->object_lock );
}
else
{
[self appendNodeArray: o_array inNode: p_node
- atPos: index inView: i_current_view enqueue: YES];
+ atPos: index enqueue: YES];
}
vlc_object_release( p_playlist );
return YES;
if(! [self isItemInPlaylist: p_item] ) return;
char *psz_temp;
- vlc_mutex_lock( &p_item->input.lock );
+ vlc_mutex_lock( &p_item->p_input->lock );
/* fill uri / title / author info */
- if( p_item->input.psz_uri )
+ if( p_item->p_input->psz_uri )
{
[o_uri_txt setStringValue:
- ([NSString stringWithUTF8String:p_item->input.psz_uri] == nil ) ?
- [NSString stringWithCString:p_item->input.psz_uri] :
- [NSString stringWithUTF8String:p_item->input.psz_uri]];
+ ([NSString stringWithUTF8String:p_item->p_input->psz_uri] == nil ) ?
+ [NSString stringWithCString:p_item->p_input->psz_uri] :
+ [NSString stringWithUTF8String:p_item->p_input->psz_uri]];
}
- if( p_item->input.psz_name )
+ if( p_item->p_input->psz_name )
{
[o_title_txt setStringValue:
- ([NSString stringWithUTF8String:p_item->input.psz_name] == nil ) ?
- [NSString stringWithCString:p_item->input.psz_name] :
- [NSString stringWithUTF8String:p_item->input.psz_name]];
+ ([NSString stringWithUTF8String:p_item->p_input->psz_name] == nil ) ?
+ [NSString stringWithCString:p_item->p_input->psz_name] :
+ [NSString stringWithUTF8String:p_item->p_input->psz_name]];
}
- vlc_mutex_unlock( &p_item->input.lock );
+ vlc_mutex_unlock( &p_item->p_input->lock );
- psz_temp = vlc_input_item_GetInfo( &p_item->input, _("Meta-information"), _("Artist") );
+ psz_temp = vlc_input_item_GetInfo( p_item->p_input, _("Meta-information"), _("Artist") );
if( psz_temp )
{
- (void)setMeta: (char *)meta forLabel: (id)theItem
{
- char *psz_meta = vlc_input_item_GetInfo( &p_item->input, \
+ char *psz_meta = vlc_input_item_GetInfo( p_item->p_input, \
_(VLC_META_INFO_CAT), _(meta) );
if( psz_meta != NULL && *psz_meta)
[theItem setStringValue: [NSString stringWithUTF8String: psz_meta]];
{
/* we can only do that if there's a valid input around */
- vlc_mutex_lock( &p_item->input.p_stats->lock );
+ vlc_mutex_lock( &p_item->p_input->p_stats->lock );
/* input */
[o_read_bytes_txt setStringValue: [NSString stringWithFormat: \
- @"%8.0f kB", (float)(p_item->input.p_stats->i_read_bytes)/1000]];
+ @"%8.0f kB", (float)(p_item->p_input->p_stats->i_read_bytes)/1000]];
[o_input_bitrate_txt setStringValue: [NSString stringWithFormat: \
- @"%6.0f kb/s", (float)(p_item->input.p_stats->f_input_bitrate)*8000]];
+ @"%6.0f kb/s", (float)(p_item->p_input->p_stats->f_input_bitrate)*8000]];
[o_demux_bytes_txt setStringValue: [NSString stringWithFormat: \
- @"%8.0f kB", (float)(p_item->input.p_stats->i_demux_read_bytes)/1000]];
+ @"%8.0f kB", (float)(p_item->p_input->p_stats->i_demux_read_bytes)/1000]];
[o_demux_bitrate_txt setStringValue: [NSString stringWithFormat: \
- @"%6.0f kb/s", (float)(p_item->input.p_stats->f_demux_bitrate)*8000]];
+ @"%6.0f kb/s", (float)(p_item->p_input->p_stats->f_demux_bitrate)*8000]];
/* Video */
[o_video_decoded_txt setStringValue: [NSString stringWithFormat: @"%5i", \
- p_item->input.p_stats->i_decoded_video]];
+ p_item->p_input->p_stats->i_decoded_video]];
[o_displayed_txt setStringValue: [NSString stringWithFormat: @"%5i", \
- p_item->input.p_stats->i_displayed_pictures]];
+ p_item->p_input->p_stats->i_displayed_pictures]];
[o_lost_frames_txt setStringValue: [NSString stringWithFormat: @"%5i", \
- p_item->input.p_stats->i_lost_pictures]];
+ p_item->p_input->p_stats->i_lost_pictures]];
/* Sout */
[o_sent_packets_txt setStringValue: [NSString stringWithFormat: @"%5i", \
- p_item->input.p_stats->i_sent_packets]];
+ p_item->p_input->p_stats->i_sent_packets]];
[o_sent_bytes_txt setStringValue: [NSString stringWithFormat: @"%8.0f kB", \
- (float)(p_item->input.p_stats->i_sent_bytes)/1000]];
+ (float)(p_item->p_input->p_stats->i_sent_bytes)/1000]];
[o_sent_bitrate_txt setStringValue: [NSString stringWithFormat: \
- @"%6.0f kb/s", (float)(p_item->input.p_stats->f_send_bitrate*8)*1000]];
+ @"%6.0f kb/s", (float)(p_item->p_input->p_stats->f_send_bitrate*8)*1000]];
/* Audio */
[o_audio_decoded_txt setStringValue: [NSString stringWithFormat: @"%5i", \
- p_item->input.p_stats->i_decoded_audio]];
+ p_item->p_input->p_stats->i_decoded_audio]];
[o_played_abuffers_txt setStringValue: [NSString stringWithFormat: @"%5i", \
- p_item->input.p_stats->i_played_abuffers]];
+ p_item->p_input->p_stats->i_played_abuffers]];
[o_lost_abuffers_txt setStringValue: [NSString stringWithFormat: @"%5i", \
- p_item->input.p_stats->i_lost_abuffers]];
+ p_item->p_input->p_stats->i_lost_abuffers]];
- vlc_mutex_unlock( &p_item->input.p_stats->lock );
+ vlc_mutex_unlock( &p_item->p_input->p_stats->lock );
}
}
if( [self isItemInPlaylist: p_item] )
{
- vlc_mutex_lock( &p_item->input.lock );
+ vlc_mutex_lock( &p_item->p_input->lock );
- p_item->input.psz_uri = strdup( [[o_uri_txt stringValue] UTF8String] );
- p_item->input.psz_name = strdup( [[o_title_txt stringValue] UTF8String] );
- vlc_mutex_unlock( &p_item->input.lock );
- vlc_input_item_AddInfo( &p_item->input, _("Meta-information"), _("Artist"), [[o_author_txt stringValue] UTF8String]);
+ p_item->p_input->psz_uri = strdup( [[o_uri_txt stringValue] UTF8String] );
+ p_item->p_input->psz_name = strdup( [[o_title_txt stringValue] UTF8String] );
+ vlc_mutex_unlock( &p_item->p_input->lock );
+ vlc_input_item_AddInfo( p_item->p_input, _("Meta-information"), _("Artist"), [[o_author_txt stringValue] UTF8String]);
val.b_bool = VLC_TRUE;
var_Set( p_playlist, "intf-change", val );
{
if( self == o_root_item )
{
- vlc_mutex_lock( &p_item->input.lock );
+ vlc_mutex_lock( &p_item->p_input->lock );
o_children = [[NSMutableArray alloc] initWithCapacity:
- p_item->input.i_categories];
- for (i = 0 ; i < p_item->input.i_categories ; i++)
+ p_item->p_input->i_categories];
+ for (i = 0 ; i < p_item->p_input->i_categories ; i++)
{
[o_children addObject:[[VLCInfoTreeItem alloc]
initWithName: [NSString stringWithUTF8String:
- p_item->input.pp_categories[i]->psz_name]
+ p_item->p_input->pp_categories[i]->psz_name]
value: @""
ID: i
parent: self]];
}
- vlc_mutex_unlock( &p_item->input.lock );
+ vlc_mutex_unlock( &p_item->p_input->lock );
}
else if( o_parent == o_root_item )
{
- vlc_mutex_lock( &p_item->input.lock );
+ vlc_mutex_lock( &p_item->p_input->lock );
o_children = [[NSMutableArray alloc] initWithCapacity:
- p_item->input.pp_categories[i_object_id]->i_infos];
+ p_item->p_input->pp_categories[i_object_id]->i_infos];
- for (i = 0 ; i < p_item->input.pp_categories[i_object_id]->i_infos ; i++)
+ for (i = 0 ; i < p_item->p_input->pp_categories[i_object_id]->i_infos ; i++)
{
[o_children addObject:[[VLCInfoTreeItem alloc]
initWithName: [NSString stringWithUTF8String:
- p_item->input.pp_categories[i_object_id]->pp_infos[i]->psz_name]
+ p_item->p_input->pp_categories[i_object_id]->pp_infos[i]->psz_name]
value: [NSString stringWithUTF8String:
- p_item->input.pp_categories[i_object_id]->pp_infos[i]->psz_value]
+ p_item->p_input->pp_categories[i_object_id]->pp_infos[i]->psz_value]
ID: i
parent: self]];
}
- vlc_mutex_unlock( &p_item->input.lock );
+ vlc_mutex_unlock( &p_item->p_input->lock );
}
else
{
NSMutableArray * tempArray = [[NSMutableArray alloc] init];
while( x != y )
{
- playlist_item_t *p_item =
+ playlist_item_t *p_item =
[[o_t2_tbl_plst itemAtRow:
[[o_t2_tbl_plst selectedRowIndexes]
indexGreaterThanOrEqualToIndex: x]] pointerValue];
if( p_item->i_children <= 0 )
{
[tempArray addObject: [NSString stringWithUTF8String:
- p_item->input.psz_uri]];
+ p_item->p_input->psz_uri]];
stop = NO;
}
else
NSString *tempString = [NSString stringWithFormat: \
@"%@ (%i/%i)", _NS("Streaming/Transcoding Wizard"), \
( x + 1 ), y];
- playlist_item_t *p_item = playlist_ItemNew( p_playlist, \
+ input_item_t *p_input = input_ItemNew( p_playlist, \
[[[o_userSelections objectForKey:@"pathToStrm"] \
objectAtIndex:x] UTF8String], \
[tempString UTF8String] );
- playlist_ItemAddOption( p_item, [[[o_userSelections \
+ vlc_input_item_AddOption( p_input, [[[o_userSelections \
objectForKey:@"opts"] objectAtIndex: x] UTF8String]);
if(! [[o_userSelections objectForKey:@"partExtractFrom"] \
isEqualToString:@""] )
{
- playlist_ItemAddOption( p_item, [[NSString \
+ vlc_input_item_AddOption( p_input, [[NSString \
stringWithFormat: @"start-time=%@", [o_userSelections \
objectForKey: @"partExtractFrom"]] UTF8String] );
}
if(! [[o_userSelections objectForKey:@"partExtractTo"] \
isEqualToString:@""] )
{
- playlist_ItemAddOption( p_item, [[NSString \
+ vlc_input_item_AddOption( p_input, [[NSString \
stringWithFormat: @"stop-time=%@", [o_userSelections \
objectForKey: @"partExtractTo"]] UTF8String] );
}
- playlist_ItemAddOption( p_item, [[NSString stringWithFormat: \
+ vlc_input_item_AddOption( p_input, [[NSString stringWithFormat: \
@"ttl=%@", [o_userSelections objectForKey:@"ttl"]] \
UTF8String] );
- playlist_AddItem( p_playlist, p_item, PLAYLIST_STOP, PLAYLIST_END );
-
+ playlist_PlaylistAddInput( p_playlist, p_input, PLAYLIST_STOP, PLAYLIST_END );
+
if( x == 0 )
- /* play the first item and add the others afterwards */
+ {
+ /* play the first item and add the others afterwards */
+ playlist_item_t *p_item = playlist_ItemGetByInput( p_playlist, p_input );
playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
+ }
x += 1;
}
- playlist_ViewUpdate( p_playlist, VIEW_CATEGORY );
-
vlc_object_release(p_playlist);
} else {
msg_Err( p_intf, "unable to find playlist" );
\
vars/equalizer.cpp \
vars/equalizer.hpp \
- vars/playlist.cpp \
- vars/playlist.hpp \
vars/playtree.cpp \
vars/playtree.hpp \
vars/time.cpp \
if( m_playNow )
{
// Enqueue and play the item
- playlist_Add( pPlaylist, m_name.c_str(),m_name.c_str(),
- PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
+ playlist_PlaylistAdd( pPlaylist, m_name.c_str(),m_name.c_str(),
+ PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
}
else
{
// Enqueue the item only
- playlist_Add( pPlaylist, m_name.c_str(), m_name.c_str(),
- PLAYLIST_APPEND, PLAYLIST_END );
+ playlist_PlaylistAdd( pPlaylist, m_name.c_str(), m_name.c_str(),
+ PLAYLIST_APPEND, PLAYLIST_END );
}
}
}
-void CmdPlaylistSort::execute()
-{
- // XXX add the mode and type
- playlist_t *pPlaylist = getIntf()->p_sys->p_playlist;
- if( pPlaylist != NULL )
- {
- playlist_Sort( pPlaylist, SORT_TITLE, ORDER_NORMAL );
- }
-
-}
-
-
void CmdPlaylistNext::execute()
{
playlist_t *pPlaylist = getIntf()->p_sys->p_playlist;
{
// FIXME: when the PLS export will be working, we'll need to remove
// this hardcoding...
- playlist_Export( pPlaylist, m_file.c_str(), "export-m3u" );
+ msg_Err( getIntf(), "need to fix playlist save" );
+// playlist_Export( pPlaylist, m_file.c_str(), "export-m3u" );
}
}
void CmdPlaytreeSort::execute()
{
/// \todo Choose sort method/order - Need more commands
+ /// \todo Choose the correct view
playlist_t *p_playlist = getIntf()->p_sys->p_playlist;
vlc_mutex_lock( &p_playlist->object_lock );
- playlist_view_t* p_view = playlist_ViewFind( p_playlist, p_playlist->status.i_view );
- playlist_RecursiveNodeSort( p_playlist, p_view->p_root , SORT_TITLE, ORDER_NORMAL );
+ playlist_RecursiveNodeSort( p_playlist, p_playlist->p_root_onelevel,
+ SORT_TITLE, ORDER_NORMAL );
vlc_mutex_unlock( &p_playlist->object_lock );
// Ask for rebuild
#include "../src/vlcproc.hpp"
#include "../utils/var_text.hpp"
#include "../vars/equalizer.hpp"
-#include "../vars/playlist.hpp"
#include "../vars/playtree.hpp"
-void CmdNotifyPlaylist::execute()
-{
- // Notify the playlist variable
- Playlist &rVar = VlcProc::instance( getIntf() )->getPlaylistVar();
- rVar.onChange();
-}
-
void CmdPlaytreeChanged::execute()
{
// Notify the playtree variable
rVar.onChange();
}
-
void CmdPlaytreeUpdate::execute()
{
// Notify the playtree variable
bool CmdPlaytreeUpdate::checkRemove( CmdGeneric *pQueuedCommand ) const
{
-
+ // We don't use RTTI - Use C-style cast
CmdPlaytreeUpdate *pUpdateCommand = (CmdPlaytreeUpdate *)(pQueuedCommand);
- //CmdPlaytreeUpdate *pUpdateCommand = dynamic_cast<CmdPlaytreeUpdate *>(pQueuedCommand);
if( m_id == pUpdateCommand->m_id )
{
return true;
REGISTER_CMD( "playlist.load()", CmdDlgPlaylistLoad )
REGISTER_CMD( "playlist.save()", CmdDlgPlaylistSave )
REGISTER_CMD( "playlist.add()", CmdDlgAdd )
- VarList &rVar = VlcProc::instance( getIntf() )->getPlaylistVar();
- m_commandMap["playlist.del()"] =
- CmdGenericPtr( new CmdPlaylistDel( getIntf(), rVar ) );
REGISTER_CMD( "playlist.next()", CmdPlaylistNext )
REGISTER_CMD( "playlist.previous()", CmdPlaylistPrevious )
- REGISTER_CMD( "playlist.sort()", CmdPlaylistSort )
m_commandMap["playlist.setRandom(true)"] =
CmdGenericPtr( new CmdPlaylistRandom( getIntf(), true ) );
m_commandMap["playlist.setRandom(false)"] =
m_pData->m_listLayout.push_back( layout );
m_curLayer = 0;
}
-
else if( rName == "Playlist" )
{
RequireDefault( "id" );
RequireDefault( "font" );
CheckDefault( "visible", "true" );
+ CheckDefault( "flat", "true" ); // Only difference here
CheckDefault( "x", "0" );
CheckDefault( "y", "0" );
CheckDefault( "width", "0" );
CheckDefault( "lefttop", "lefttop" );
CheckDefault( "rightbottom", "lefttop" );
CheckDefault( "bgimage", "none" );
+ CheckDefault( "itemimage", "none" );
+ CheckDefault( "openimage", "none" );
+ CheckDefault( "closedimage", "none" );
CheckDefault( "fgcolor", "#000000" );
CheckDefault( "playcolor", "#FF0000" );
CheckDefault( "bgcolor1", "#FFFFFF" );
CheckDefault( "bgcolor2", "#FFFFFF" );
CheckDefault( "selcolor", "#0000FF" );
CheckDefault( "help", "" );
-
- m_curListId = uniqueId( attr["id"] );
- const BuilderData::List listData( m_curListId, atoi( attr["x"] ) +
+ m_curTreeId = uniqueId( attr["id"] );
+ const BuilderData::Tree treeData( m_curTreeId, atoi( attr["x"] ) +
m_xOffset, atoi( attr["y"] ) + m_yOffset, attr["visible"],
+ attr["flat"],
atoi( attr["width"]), atoi( attr["height"] ),
- attr["lefttop"], attr["rightbottom"], attr["font"],
- "playlist", attr["bgimage"], attr["fgcolor"],
- attr["playcolor"], attr["bgcolor1"], attr["bgcolor2"],
+ attr["lefttop"], attr["rightbottom"],
+ attr["font"], "playtree",
+ attr["bgimage"], attr["itemimage"],
+ attr["openimage"], attr["closedimage"],
+ attr["fgcolor"],
+ attr["playcolor"],
+ attr["bgcolor1"],
+ attr["bgcolor2"],
attr["selcolor"], attr["help"],
m_curLayer, m_curWindowId, m_curLayoutId );
m_curLayer++;
- m_pData->m_listList.push_back( listData );
+ m_pData->m_listTree.push_back( treeData );
}
-
else if( rName == "Playtree" )
{
RequireDefault( "id" );
CheckDefault( "help", "" );
string newValue = attr["value"];
- if( m_curListId != "" )
- {
- // Slider associated to a list
- newValue = "playlist.slider";
- }
- else if( m_curTreeId != "" )
+ if( m_curTreeId != "" )
{
// Slider associated to a tree
newValue = "playtree.slider";
m_xOffsetList.pop_back();
m_yOffsetList.pop_back();
}
- else if( rName == "Playlist" )
- {
- m_curListId = "";
- }
- else if( rName == "Playtree" )
+ else if( rName == "Playtree" || rName == "Playlist" )
{
m_curTreeId = "";
}
if( p_playlist != NULL )
{
// Make sure the item is deleted afterwards
- p_playlist->pp_items[p_playlist->i_index]->b_autodeletion =
- VLC_TRUE;
+ /// \bug does not always work
+ p_playlist->status.p_item->i_flags |= PLAYLIST_REMOVE_FLAG;
vlc_object_release( p_playlist );
}
#define REGISTER_VAR( var, type, name ) \
var = VariablePtr( new type( getIntf() ) ); \
pVarManager->registerVar( var, name );
-
- /* Playlist variables */
- REGISTER_VAR( m_cPlaylist, Playlist, "playlist" )
- pVarManager->registerVar( getPlaylistVar().getPositionVarPtr(),
- "playlist.slider" );
REGISTER_VAR( m_cVarRandom, VarBoolImpl, "playlist.isRandom" )
REGISTER_VAR( m_cVarLoop, VarBoolImpl, "playlist.isLoop" )
REGISTER_VAR( m_cVarRepeat, VarBoolImpl, "playlist.isRepeat" )
playlist_t *p_playlist = (playlist_t*)pObj;
pThis->updateStreamName(p_playlist);
- // Create a playlist notify command (for old style playlist)
- CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
// Create a playtree notify command (for new style playtree)
CmdPlaytreeChanged *pCmdTree = new CmdPlaytreeChanged( pThis->getIntf() );
// Push the command in the asynchronous command queue
AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
- pQueue->push( CmdGenericPtr( pCmd ) );
pQueue->push( CmdGenericPtr( pCmdTree ) );
return VLC_SUCCESS;
playlist_t *p_playlist = (playlist_t*)pObj;
pThis->updateStreamName(p_playlist);
- // Create a playlist notify command
- // TODO: selective update
- CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
// Create a playtree notify command
CmdPlaytreeUpdate *pCmdTree = new CmdPlaytreeUpdate( pThis->getIntf(),
newVal.i_int );
// Push the command in the asynchronous command queue
AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
- pQueue->push( CmdGenericPtr( pCmd ) );
pQueue->push( CmdGenericPtr( pCmdTree ), true );
return VLC_SUCCESS;
p_add );
ptrTree = CmdGenericPtr( pCmdTree );
- // Create a playlist notify command (for old style playlist)
- CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
-
// Push the command in the asynchronous command queue
AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
- pQueue->push( CmdGenericPtr( pCmd ) );
pQueue->push( ptrTree , false );
return VLC_SUCCESS;
i_id);
ptrTree = CmdGenericPtr( pCmdTree );
- // Create a playlist notify command (for old style playlist)
- CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
-
// Push the command in the asynchronous command queue
AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
- pQueue->push( CmdGenericPtr( pCmd ) );
pQueue->push( ptrTree , false );
return VLC_SUCCESS;
}
-
-
int VlcProc::onPlaylistChange( vlc_object_t *pObj, const char *pVariable,
vlc_value_t oldVal, vlc_value_t newVal,
void *pParam )
playlist_t *p_playlist = (playlist_t*)pObj;
pThis->updateStreamName(p_playlist);
- // Create a playlist notify command (old style playlist)
- // TODO: selective update
- CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
- pQueue->push( CmdGenericPtr( pCmd ) );
// Create two playtree notify commands: one for old item, one for new
CmdPlaytreeUpdate *pCmdTree = new CmdPlaytreeUpdate( pThis->getIntf(),
oldVal.i_int );
#include <set>
#include "../vars/equalizer.hpp"
-#include "../vars/playlist.hpp"
#include "../vars/playtree.hpp"
#include "../vars/time.hpp"
#include "../vars/volume.hpp"
/// Delete the instance of VlcProc
static void destroy( intf_thread_t *pIntf );
- /// Getter for the playlist variable
- Playlist &getPlaylistVar() { return *((Playlist*)m_cPlaylist.get()); }
-
/// Getter for the playtree variable
Playtree &getPlaytreeVar() { return *((Playtree*)m_cPlaytree.get()); }
private:
/// Timer to call manage() regularly (via doManage())
OSTimer *m_pTimer;
- /// Playlist variable
- VariablePtr m_cPlaylist;
- /// Playtree variable FIXME
+ /// Playtree variable
VariablePtr m_cPlaytree;
VariablePtr m_cVarRandom;
VariablePtr m_cVarLoop;
+++ /dev/null
-/*****************************************************************************
- * playlist.cpp
- *****************************************************************************
- * Copyright (C) 2003 the VideoLAN team
- * $Id$
- *
- * Authors: Cyril Deguet <asmax@via.ecp.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#include <vlc/vlc.h>
-
-#include "playlist.hpp"
-#include "../utils/ustring.hpp"
-
-Playlist::Playlist( intf_thread_t *pIntf ): VarList( pIntf )
-{
- // Get the playlist VLC object
- m_pPlaylist = pIntf->p_sys->p_playlist;
-
- buildList();
-}
-
-
-Playlist::~Playlist()
-{
-}
-
-
-void Playlist::delSelected()
-{
- // Remove the items from the VLC playlist
- int index = 0;
- ConstIterator it;
- for( it = begin(); it != end(); it++ )
- {
- if( (*it).m_selected )
- {
- playlist_item_t *p_item = playlist_LockItemGetByPos( m_pPlaylist,
- index );
- playlist_LockDelete( m_pPlaylist, p_item->input.i_id );
- }
- else
- {
- index++;
- }
- }
-
- notify();
-}
-
-
-void Playlist::action( Elem_t *pItem )
-{
- // Find the index of the item
- int index = 0;
- ConstIterator it;
- for( it = begin(); it != end(); it++ )
- {
- if( &*it == pItem ) break;
- index++;
- }
- // Item found ?
- if( index < size() )
- {
- playlist_Goto( m_pPlaylist, index );
- }
-}
-
-
-void Playlist::onChange()
-{
- buildList();
- notify();
-}
-
-
-void Playlist::buildList()
-{
- clear();
-
- vlc_mutex_lock( &m_pPlaylist->object_lock );
- for( int i = 0; i < m_pPlaylist->i_size; i++ )
- {
- // Get the name of the playlist item
- UString *pName =
- new UString( getIntf(), m_pPlaylist->pp_items[i]->input.psz_name );
- // Is it the played stream ?
- bool playing = (i == m_pPlaylist->i_index );
- // Add the item in the list
- m_list.push_back( Elem_t( UStringPtr( pName ), false, playing ) );
- }
- vlc_mutex_unlock( &m_pPlaylist->object_lock );
-}
-
+++ /dev/null
-/*****************************************************************************
- * playlist.hpp
- *****************************************************************************
- * Copyright (C) 2003 the VideoLAN team
- * $Id$
- *
- * Authors: Cyril Deguet <asmax@via.ecp.fr>
- * Olivier Teulière <ipkiss@via.ecp.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef PLAYLIST_HPP
-#define PLAYLIST_HPP
-
-#include "../utils/var_list.hpp"
-
-/// Variable for VLC playlist
-class Playlist: public VarList
-{
- public:
- Playlist( intf_thread_t *pIntf );
- virtual ~Playlist();
-
- /// Remove the selected elements from the list
- virtual void delSelected();
-
- /// Execute the action associated to this item
- virtual void action( Elem_t *pItem );
-
- /// Function called to notify playlist changes
- void onChange();
-
- private:
- /// VLC playlist object
- playlist_t *m_pPlaylist;
-
- /// Build the list from the VLC playlist
- void buildList();
-};
-
-
-#endif
playlist_item_t *p_item = (playlist_item_t *)(it->m_pData);
if( p_item->i_children == -1 )
{
- playlist_Delete( getIntf()->p_sys->p_playlist,
- p_item->input.i_id );
+ playlist_DeleteFromItemId( getIntf()->p_sys->p_playlist,
+ p_item->i_id );
it2 = getNextVisibleItem( it ) ;
it->parent()->removeChild( it );
it = it2;
{
vlc_mutex_lock( &m_pPlaylist->object_lock );
VarTree::Iterator it;
- if( pItem->size() )
+
+ playlist_item_t *p_item = (playlist_item_t *)pItem->m_pData;
+ playlist_item_t *p_parent = p_item;
+ while( p_parent )
+ {
+ if( p_parent == m_pPlaylist->p_root_category )
+ break;
+ p_parent = p_parent->p_parent;
+ }
+
+ if( p_parent )
{
- it = pItem->begin();
- while( it->size() ) it = it->begin();
+ playlist_Control( m_pPlaylist, PLAYLIST_VIEWPLAY, 1242,
+ p_parent, p_item );
}
- playlist_Control( m_pPlaylist,
- PLAYLIST_VIEWPLAY,
- m_pPlaylist->status.i_view,
- pItem->size()
- ? (playlist_item_t *)pItem->m_pData
- : (playlist_item_t *)pItem->parent()->m_pData,
- pItem->size()
- ? (playlist_item_t *)it->m_pData
- : (playlist_item_t *)pItem->m_pData
- );
vlc_mutex_unlock( &m_pPlaylist->object_lock );
}
{
// Update the item
playlist_item_t* pNode = (playlist_item_t*)(it->m_pData);
- UString *pName = new UString( getIntf(), pNode->input.psz_name );
+ UString *pName = new UString( getIntf(), pNode->p_input->psz_name );
it->m_cString = UStringPtr( pName );
it->m_playing = m_pPlaylist->status.p_item == pNode;
if( it->m_playing ) descr.b_active_item = true;
playlist_item_t *p_item = playlist_ItemGetById(
m_pPlaylist, p_add->i_item );
if( !p_item ) return;
- UString *pName = new UString( getIntf(), p_item->input.psz_name );
+ UString *pName = new UString( getIntf(),
+ p_item->p_input->psz_name );
node->add( p_add->i_item, UStringPtr( pName ),
false,false, false, p_item->i_flags & PLAYLIST_RO_FLAG,
p_item );
for( int i = 0; i < pNode->i_children; i++ )
{
UString *pName = new UString( getIntf(),
- pNode->pp_children[i]->input.psz_name );
- rTree.add( pNode->pp_children[i]->input.i_id, UStringPtr( pName ),
+ pNode->pp_children[i]->p_input->psz_name );
+ rTree.add( pNode->pp_children[i]->p_input->i_id, UStringPtr( pName ),
false,
m_pPlaylist->status.p_item == pNode->pp_children[i],
false, pNode->pp_children[i]->i_flags & PLAYLIST_RO_FLAG,
i_items_to_append = 0;
- playlist_view_t *p_view;
- p_view = playlist_ViewFind( m_pPlaylist, VIEW_CATEGORY );
- /// \todo let the user chose the view
-
clear();
+ /* TODO: Let user choose view - Stick with category ATM */
+
/* Set the root's name */
- UString *pName = new UString( getIntf(), p_view->p_root->input.psz_name );
+ UString *pName = new UString( getIntf(),
+ m_pPlaylist->p_root_category->p_input->psz_name );
m_cString = UStringPtr( pName );
- buildNode( p_view->p_root, *this );
+ buildNode( m_pPlaylist->p_root_category, *this );
vlc_mutex_unlock( &m_pPlaylist->object_lock );
// What is it ?
{
char *psz_utf8 = wxFromLocale( paths[i] );
if( event.GetInt() )
- playlist_Add( p_playlist, psz_utf8, psz_utf8,
+ playlist_PlaylistAdd( p_playlist, psz_utf8, psz_utf8,
PLAYLIST_APPEND | (i ? 0 : PLAYLIST_GO) |
(i ? PLAYLIST_PREPARSE : 0 ),
PLAYLIST_END );
else
- playlist_Add( p_playlist, psz_utf8, psz_utf8,
+ playlist_PlaylistAdd( p_playlist, psz_utf8, psz_utf8,
PLAYLIST_APPEND | PLAYLIST_PREPARSE , PLAYLIST_END );
wxLocaleFree( psz_utf8 );
}
{
wxString path = p_dir_dialog->GetPath();
char *psz_utf8 = wxFromLocale( path );
- playlist_Add( p_playlist, psz_utf8, psz_utf8,
+ playlist_PlaylistAdd( p_playlist, psz_utf8, psz_utf8,
PLAYLIST_APPEND | (event.GetInt() ? PLAYLIST_GO : 0),
PLAYLIST_END );
wxLocaleFree( psz_utf8 );
ADD_META( VLC_META_LANGUAGE, language_text );
ADD_META( VLC_META_NOW_PLAYING, nowplaying_text );
ADD_META( VLC_META_PUBLISHER, publisher_text );
+ ADD_META( VLC_META_SETTING, setting_text );
meta_sizer->Layout();
name_text->SetValue( wxU( p_item->psz_name ) );
#define UPDATE_META( meta, widget ) { \
- char *psz_meta = vlc_input_item_GetInfo( p_item, _(VLC_META_INFO_CAT), \
- _(meta) ); \
+ char *psz_meta = p_item->p_meta->psz_##meta; \
if( psz_meta != NULL && *psz_meta) \
{ \
widget->SetLabel( wxU( psz_meta ) ); \
else { widget->SetLabel( wxU( "-" ) ); } \
}
- UPDATE_META( VLC_META_ARTIST, artist_text );
- UPDATE_META( VLC_META_GENRE, genre_text );
- UPDATE_META( VLC_META_COPYRIGHT, copyright_text );
- UPDATE_META( VLC_META_COLLECTION, collection_text );
- UPDATE_META( VLC_META_SEQ_NUM, seqnum_text );
- UPDATE_META( VLC_META_DESCRIPTION, description_text );
- UPDATE_META( VLC_META_RATING, rating_text );
- UPDATE_META( VLC_META_DATE, date_text );
- UPDATE_META( VLC_META_LANGUAGE, language_text );
- UPDATE_META( VLC_META_NOW_PLAYING, nowplaying_text );
- UPDATE_META( VLC_META_PUBLISHER, publisher_text );
+ UPDATE_META( artist, artist_text );
+ UPDATE_META( genre, genre_text );
+ UPDATE_META( copyright, copyright_text );
+ UPDATE_META( album, collection_text );
+ UPDATE_META( tracknum, seqnum_text );
+ UPDATE_META( description, description_text );
+ UPDATE_META( rating, rating_text );
+ UPDATE_META( date, date_text );
+ UPDATE_META( language, language_text );
+ UPDATE_META( nowplaying, nowplaying_text );
+ UPDATE_META( publisher, publisher_text );
+ UPDATE_META( setting, setting_text );
#undef UPDATE_META
}
/* Create the standard info panel */
info_panel = new MetaDataPanel(p_intf, panel, true );
- info_panel->Update( &(p_item->input) );
+ info_panel->Update( p_item->p_input );
/* Separation */
wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
*****************************************************************************/
void ItemInfoDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
{
- vlc_mutex_lock( &p_item->input.lock );
- p_item->input.psz_name = info_panel->GetName();
- p_item->input.psz_uri = info_panel->GetURI();
- vlc_mutex_unlock( &p_item->input.lock );
+ vlc_mutex_lock( &p_item->p_input->lock );
+ p_item->p_input->psz_name = info_panel->GetName();
+ p_item->p_input->psz_uri = info_panel->GetURI();
+ vlc_mutex_unlock( &p_item->p_input->lock );
EndModal( wxID_OK );
}
for( int i = 0; i < (int)mrl.GetCount(); i++ )
{
vlc_bool_t b_start = !i && i_open_arg;
- playlist_item_t *p_item;
+ input_item_t *p_input;
char *psz_utf8;
psz_utf8 = wxFromLocale( mrl[i] );
- p_item = playlist_ItemNew( p_intf, psz_utf8, psz_utf8 );
+ p_input = input_ItemNew( p_intf, psz_utf8, psz_utf8 );
wxLocaleFree( psz_utf8 );
/* Insert options */
((const char *)mrl[i + 1].mb_str())[0] == ':' )
{
psz_utf8 = wxFromLocale( mrl[i + 1] );
- playlist_ItemAddOption( p_item, psz_utf8 );
+ vlc_input_item_AddOption( p_input, psz_utf8 );
wxLocaleFree( psz_utf8 );
i++;
}
for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
{
psz_utf8 = wxFromLocale( subsfile_mrl[j] );
- playlist_ItemAddOption( p_item, psz_utf8 );
+ vlc_input_item_AddOption( p_input, psz_utf8 );
wxLocaleFree( psz_utf8 );
}
}
for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
{
psz_utf8 = wxFromLocale( sout_mrl[j] );
- playlist_ItemAddOption( p_item, psz_utf8 );
+ vlc_input_item_AddOption( p_input, psz_utf8 );
wxLocaleFree( psz_utf8 );
}
}
-
if( b_start )
{
- playlist_AddItem( p_playlist, p_item,
- PLAYLIST_APPEND,
- PLAYLIST_END );
- playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
+ playlist_PlaylistAddInput( p_playlist, p_input, PLAYLIST_APPEND,
+ PLAYLIST_END );
+ msg_Err( p_playlist, "Item start not implemented" );
+ // FIXME: Play only within the playlist node
+ //playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
}
else
{
- playlist_AddItem( p_playlist, p_item,
- PLAYLIST_APPEND|PLAYLIST_PREPARSE,
- PLAYLIST_END );
+ playlist_PlaylistAddInput( p_playlist, p_input,
+ PLAYLIST_APPEND|PLAYLIST_PREPARSE,
+ PLAYLIST_END );
}
}
Search_Event,
/* controls */
+ Source_Event,
TreeCtrl_Event,
Browse_Event, /* For export playlist */
MenuDummy_Event = wxID_HIGHEST + 999,
FirstView_Event = wxID_HIGHEST + 1000,
+ CategoryView_Event, OneLevelView_Event,
LastView_Event = wxID_HIGHEST + 1100,
FirstSD_Event = wxID_HIGHEST + 2000,
EVT_MENU( PopupInfo_Event, Playlist::OnPopupInfo)
EVT_MENU( PopupAddNode_Event, Playlist::OnPopupAddNode)
+ /* Source selector */
+ EVT_LIST_ITEM_SELECTED( Source_Event, Playlist::OnSourceSelected )
/* Tree control events */
EVT_TREE_ITEM_ACTIVATED( TreeCtrl_Event, Playlist::OnActivateItem )
EVT_TREE_KEY_DOWN( -1, Playlist::OnKeyDown )
public:
PlaylistItem( playlist_item_t *p_item ) : wxTreeItemData()
{
- i_id = p_item->input.i_id;
+ i_id = p_item->i_id;
+ i_input_id = p_item->p_input->i_id;
}
protected:
+ int i_input_id;
int i_id;
friend class Playlist;
friend class PlaylistFileDropTarget;
p_view_menu = NULL;
p_sd_menu = SDMenu();
- i_current_view = VIEW_CATEGORY;
- b_changed_view = VLC_FALSE;
+// i_current_view = VIEW_ONELEVEL;
+ p_current_viewroot = p_playlist->p_root_onelevel;
+ p_current_treeroot = p_playlist->p_local_onelevel;
i_title_sorted = 0;
i_group_sorted = 0;
search_button->SetDefault();
toolbar->Realize();
+ /* Create teh source selector */
+ source_sel = new wxListCtrl( playlist_panel, Source_Event,
+ wxDefaultPosition, wxDefaultSize,
+ wxLC_AUTOARRANGE|wxLC_SINGLE_SEL );
+
/* Create the tree */
treectrl = new wxTreeCtrl( playlist_panel, TreeCtrl_Event,
wxDefaultPosition, wxDefaultSize,
font.SetPointSize(9);
treectrl->SetFont( font );
- wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
+ wxBoxSizer *panel_sizer = new wxBoxSizer( wxHORIZONTAL );
+ panel_sizer->Add( source_sel, 0, wxALL | wxEXPAND, 5 );
panel_sizer->Add( treectrl, 1, wxEXPAND | wxALL, 5 );
panel_sizer->Layout();
#endif
i_saved_id = -1;
-
-
- /* We want to be noticed of playlist changes */
+ i_saved_input_id = -1;
/* Some global changes happened -> Rebuild all */
var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this );
child = treectrl->GetNextChild( node, cookie );
}
}
- treectrl->SetItemImage( node, p_node->input.i_type );
+ treectrl->SetItemImage( node, p_node->p_input->i_type );
}
void Playlist::CreateNode( playlist_item_t *p_node, wxTreeItemId parent )
{
wxTreeItemId node =
- treectrl->AppendItem( parent, wxL2U( p_node->input.psz_name ),
+ treectrl->AppendItem( parent, wxL2U( p_node->p_input->psz_name ),
-1,-1, new PlaylistItem( p_node ) );
- treectrl->SetItemImage( node, p_node->input.i_type );
+ treectrl->SetItemImage( node, p_node->p_input->i_type );
UpdateNodeChildren( p_node, node );
}
void Playlist::UpdateNodeChildren( playlist_item_t *p_node,
wxTreeItemId node )
{
-
for( int i = 0; i< p_node->i_children ; i++ )
{
/* Append the item */
if( p_node->pp_children[i]->i_children == -1 )
{
- wxTreeItemId item =
- treectrl->AppendItem( node,
- wxL2U( p_node->pp_children[i]->input.psz_name ), -1,-1,
+ if( !(p_node->pp_children[i]->i_flags & PLAYLIST_DBL_FLAG) )
+ {
+ wxTreeItemId item =
+ treectrl->AppendItem( node,
+ wxL2U( p_node->pp_children[i]->p_input->psz_name ), -1,-1,
new PlaylistItem( p_node->pp_children[i]) );
- UpdateTreeItem( item );
+ UpdateTreeItem( item );
+ }
}
else
{
/* Update an item in the tree */
void Playlist::UpdateTreeItem( wxTreeItemId item )
{
+ LockPlaylist( p_intf->p_sys, p_playlist );
if( ! item.IsOk() ) return;
wxTreeItemData *p_data = treectrl->GetItemData( item );
if( !p_data ) return;
- LockPlaylist( p_intf->p_sys, p_playlist );
playlist_item_t *p_item = playlist_ItemGetById( p_playlist,
((PlaylistItem *)p_data)->i_id );
if( !p_item )
wxString msg;
wxString duration = wxU( "" );
- char *psz_author = vlc_input_item_GetInfo( &p_item->input,
- _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
- if( !psz_author )
+
+ char *psz_author;
+ if( p_item->p_input->p_meta )
{
- UnlockPlaylist( p_intf->p_sys, p_playlist );
- return;
+ psz_author= p_item->p_input->p_meta->psz_artist ?
+ strdup( p_item->p_input->p_meta->psz_artist ) :
+ strdup("");
}
+ else
+ psz_author = strdup( "" );
char psz_duration[MSTRTIME_MAX_SIZE];
- mtime_t dur = p_item->input.i_duration;
+ mtime_t dur = p_item->p_input->i_duration;
if( dur != -1 )
{
wxU( " )" ) );
}
- if( !strcmp( psz_author, "" ) || p_item->input.b_fixed_name == VLC_TRUE )
+ if( !strcmp( psz_author, "" ) || p_item->p_input->b_fixed_name == VLC_TRUE )
{
- msg = wxString( wxU( p_item->input.psz_name ) ) + duration;
+ msg = wxString( wxU( p_item->p_input->psz_name ) ) + duration;
}
else
{
msg = wxString(wxU( psz_author )) + wxT(" - ") +
- wxString(wxU(p_item->input.psz_name)) + duration;
+ wxString(wxU(p_item->p_input->psz_name)) + duration;
}
free( psz_author );
treectrl->SetItemText( item , msg );
- treectrl->SetItemImage( item, p_item->input.i_type );
+ treectrl->SetItemImage( item, p_item->p_input->i_type );
if( p_playlist->status.p_item == p_item )
{
/* No need to do anything if the playlist is going to be rebuilt */
if( b_need_update ) return;
- if( p_add->i_view != i_current_view ) goto update;
-
node = FindItem( treectrl->GetRootItem(), p_add->i_node );
if( !node.IsOk() ) goto update;
p_item = playlist_ItemGetById( p_playlist, p_add->i_item );
if( !p_item ) goto update;
+ if( (p_item->i_flags & PLAYLIST_DBL_FLAG ) ) goto update;
item = FindItem( treectrl->GetRootItem(), p_add->i_item );
if( item.IsOk() ) goto update;
item = treectrl->AppendItem( node,
- wxL2U( p_item->input.psz_name ), -1,-1,
+ wxL2U( p_item->p_input->psz_name ), -1,-1,
new PlaylistItem( p_item ) );
- treectrl->SetItemImage( item, p_item->input.i_type );
+ treectrl->SetItemImage( item, p_item->p_input->i_type );
if( item.IsOk() && p_item->i_children == -1 )
{
update:
int i_count = CountItems( treectrl->GetRootItem());
- if( i_count != p_playlist->i_size )
- {
- statusbar->SetStatusText( wxString::Format( wxU(_(
- "%i items in playlist (%i not shown)")),
- p_playlist->i_size,
- p_playlist->i_size - i_count ) );
- if( !b_changed_view )
- {
- i_current_view = VIEW_CATEGORY;
- b_changed_view = VLC_TRUE;
- b_need_update = VLC_TRUE;
- }
- }
- else
- {
- statusbar->SetStatusText( wxString::Format( wxU(_(
- "%i items in playlist")),
- p_playlist->i_size ), 0 );
- }
-
+ statusbar->SetStatusText( wxString::Format( wxU(_(
+ "%i items in playlist" ) ), i_count ) );
return;
}
void Playlist::UpdateItem( int i )
{
if( i < 0 ) return; /* Sanity check */
-
- wxTreeItemId item = FindItem( treectrl->GetRootItem(), i );
-
+ wxTreeItemId item = FindItemByInput( treectrl->GetRootItem(), i );
if( item.IsOk() )
{
UpdateTreeItem( item );
if( i <= 0 ) return; /* Sanity check */
if( i == i_saved_id ) i_saved_id = -1;
+ /* Hack: always invalidate input item cache */
+ i_saved_input_id = -1;
+
+ /// \todo Check if it is in the source selector */
+
wxTreeItemId item = FindItem( treectrl->GetRootItem(), i );
if( item.IsOk() )
/* Find a wxItem from a playlist id */
wxTreeItemId Playlist::FindItem( wxTreeItemId root, int i_id )
+{
+ return FindItemInner( root, i_id, false );
+}
+
+wxTreeItemId Playlist::FindItemByInput( wxTreeItemId root, int i_input_id )
+{
+ return FindItemInner( root, i_input_id, true );
+}
+
+wxTreeItemId Playlist::FindItemInner( wxTreeItemId root, int i_id, bool b_byinput )
{
wxTreeItemIdValue cookie;
PlaylistItem *p_wxcurrent;
if( i_id < 0 )
{
- wxTreeItemId dummy;
- return dummy;
+ wxTreeItemId dummy; dummy.Unset(); return dummy;
}
- if( i_saved_id == i_id )
- {
+ if( b_byinput && i_saved_input_id == i_id )
+ return saved_input_tree_item;
+ if( !b_byinput && i_saved_id == i_id)
return saved_tree_item;
- }
if( !p_wxcurrent )
{
- wxTreeItemId dummy;
- return dummy;
+ wxTreeItemId dummy; dummy.Unset(); return dummy;
}
- if( p_wxcurrent->i_id == i_id )
+ if( !b_byinput && p_wxcurrent->i_id == i_id )
{
i_saved_id = i_id;
saved_tree_item = root;
return root;
}
+ if( b_byinput && p_wxcurrent->i_input_id == i_id )
+ {
+ i_saved_input_id = i_id;
+ saved_input_tree_item = root;
+ return root;
+ }
while( item.IsOk() )
{
p_wxcurrent = (PlaylistItem *)treectrl->GetItemData( item );
- if( p_wxcurrent->i_id == i_id )
+ if( !b_byinput && p_wxcurrent->i_id == i_id )
{
i_saved_id = i_id;
saved_tree_item = item;
return item;
}
+ else if( b_byinput && p_wxcurrent->i_input_id == i_id )
+ {
+ i_saved_input_id = i_id;
+ saved_input_tree_item = item;
+ return item;
+ }
if( treectrl->ItemHasChildren( item ) )
{
- wxTreeItemId search = FindItem( item, i_id );
+ wxTreeItemId search = FindItemInner( item, i_id, b_byinput );
if( search.IsOk() )
{
- i_saved_id = i_id;
- saved_tree_item = search;
- return search;
+ if( !b_byinput )
+ {
+ i_saved_id = i_id;
+ saved_tree_item = search;
+ return search;
+ }
+ else
+ {
+ i_saved_input_id = i_id;
+ saved_input_tree_item = search;
+ return search;
+
+ }
}
}
item = treectrl->GetNextChild( root, cookie );
}
/* Not found */
- wxTreeItemId dummy;
- return dummy;
+ wxTreeItemId dummy; dummy.Unset(); return dummy;
}
int Playlist::CountItems( wxTreeItemId root )
item = treectrl->GetNextChild( root, cookie);
}
/* Not found */
- wxTreeItemId dummy;
+ wxTreeItemId dummy; dummy.Unset();
return dummy;
}
**********************************************************************/
void Playlist::Rebuild( vlc_bool_t b_root )
{
- playlist_view_t *p_view;
-
i_items_to_append = 0;
/* We can remove the callbacks before locking, anyway, we won't
/* ...and rebuild it */
LockPlaylist( p_intf->p_sys, p_playlist );
}
+ /* Invalidate cache */
i_saved_id = -1;
+ i_saved_input_id = -1;
- p_view = playlist_ViewFind( p_playlist, i_current_view ); /* FIXME */
+ /* Rebuild the list */
+ source_sel->ClearAll();
+ for( int i = 0 ; i< p_current_viewroot->i_children ; i++ )
+ {
+ source_sel->InsertItem( i,
+ wxL2U( p_current_viewroot->pp_children[i]->p_input->psz_name) );
+ source_sel->SetItemData( i,
+ p_current_viewroot->pp_children[i]->i_id );
+ if( p_current_viewroot->pp_children[i] == p_current_treeroot )
+ source_sel->Select( i );
+ }
/* HACK we should really get new*/
treectrl->DeleteAllItems();
treectrl->AddRoot( wxU(_("root" )), -1, -1,
- new PlaylistItem( p_view->p_root) );
+ new PlaylistItem( p_current_treeroot ) );
wxTreeItemId root = treectrl->GetRootItem();
- UpdateNode( p_view->p_root, root );
+ //UpdateNode( p_current_treeroot, root );
+ //CreateNode( p_current_treeroot, root );
+ UpdateNodeChildren( p_current_treeroot, root );
int i_count = CountItems( treectrl->GetRootItem() );
- if( i_count < p_playlist->i_size && !b_changed_view )
- {
- i_current_view = VIEW_CATEGORY;
- b_changed_view = VLC_TRUE;
- Rebuild( VLC_FALSE );
- }
- else if( i_count != p_playlist->i_size )
- {
- statusbar->SetStatusText( wxString::Format( wxU(_(
- "%i items in playlist (%i not shown)")),
- p_playlist->i_size,
- p_playlist->i_size - i_count ) );
- }
- else
- {
- statusbar->SetStatusText( wxString::Format( wxU(_(
- "%i items in playlist")),
- p_playlist->i_size ), 0 );
- }
+ statusbar->SetStatusText( wxString::Format( wxU(_(
+ "%i items in playlist")), i_count ), 0 );
if( b_root )
{
}
}
-
-
void Playlist::ShowPlaylist( bool show )
{
if( show ) Rebuild( VLC_TRUE );
return;
}
- if( p_item->i_children == -1 ) DeleteItem( p_item->input.i_id );
+ if( p_item->i_children == -1 ) DeleteItem( p_item->i_id );
else DeleteNode( p_item );
- RemoveItem( p_item->input.i_id );
+ RemoveItem( p_item->i_id );
UnlockPlaylist( p_intf->p_sys, p_playlist );
}
void Playlist::DeleteItem( int item_id )
{
- playlist_Delete( p_playlist, item_id );
+ playlist_DeleteFromItemId( p_playlist, item_id );
}
void Playlist::DeleteNode( playlist_item_t *p_item )
{
if( dialog.GetPath().mb_str() )
{
- playlist_Export( p_playlist, dialog.GetPath().mb_str(),
- formats[dialog.GetFilterIndex()].psz_module );
+ abort();
+// playlist_Export( p_playlist, dialog.GetPath().mb_str(),
+// /* ROOT */
+// formats[dialog.GetFilterIndex()].psz_module );
}
}
void Playlist::OnSearch( wxCommandEvent& WXUNUSED(event) )
{
wxString search_string = search_text->GetValue();
+ PlaylistItem *p_wxroot;
+ p_wxroot = (PlaylistItem *)treectrl->GetItemData( treectrl->GetRootItem() );
+ playlist_item_t *p_root = playlist_ItemGetById( p_playlist, p_wxroot->i_id );
- vlc_bool_t pb_found = VLC_FALSE;
-
- wxTreeItemId found =
- FindItemByName( treectrl->GetRootItem(), search_string,
- search_current, &pb_found );
-
- if( !found.IsOk() )
- {
- wxTreeItemId dummy;
- search_current = dummy;
- found = FindItemByName( treectrl->GetRootItem(), search_string,
- search_current, &pb_found );
- }
+ if( !p_root ) abort();
+ char *psz_name = wxFromLocale( search_string );
+ playlist_LiveSearchUpdate( p_playlist, p_root, psz_name );
+ Rebuild( VLC_TRUE );
- if( found.IsOk() )
- {
- search_current = found;
- treectrl->EnsureVisible( found );
- treectrl->UnselectAll();
- treectrl->SelectItem( found, true );
- }
+ wxLocaleFree( psz_name );
}
/**********************************************************************
********************************************************************/
void Playlist::OnActivateItem( wxTreeEvent& event )
{
- playlist_item_t *p_item,*p_node,*p_item2,*p_node2;
+ playlist_item_t *p_item, *p_parent;
PlaylistItem *p_wxitem = (PlaylistItem *)treectrl->GetItemData(
event.GetItem() );
- wxTreeItemId parent = treectrl->GetItemParent( event.GetItem() );
-
- PlaylistItem *p_wxparent = (PlaylistItem *)treectrl->GetItemData( parent );
LockPlaylist( p_intf->p_sys, p_playlist );
- if( !( p_wxitem && p_wxparent ) )
+ if( !( p_wxitem ) )
{
UnlockPlaylist( p_intf->p_sys, p_playlist );
return;
}
+ p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id );
- p_item2 = playlist_ItemGetById(p_playlist, p_wxitem->i_id);
- p_node2 = playlist_ItemGetById(p_playlist, p_wxparent->i_id);
- if( p_item2 && p_item2->i_children == -1 )
+ p_parent = p_item;
+ while( p_parent )
{
- p_node = p_node2;
- p_item = p_item2;
+ if( p_parent == p_current_treeroot )
+ break;
+ p_parent = p_parent->p_parent;
}
- else
+
+ if( p_parent )
{
- p_node = p_item2;
- p_item = NULL;
-/* if( p_node && p_node->i_children > 0 &&
- p_node->pp_children[0]->i_children == -1)
- {
- p_item = p_node->pp_children[0];
- }
- else
- {
- p_item = NULL;
- }*/
+ playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, 1242,
+ p_parent, p_item );
}
-
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, i_current_view,
- p_node, p_item );
UnlockPlaylist( p_intf->p_sys, p_playlist );
}
}
}
-void Playlist::OnEnDis( wxCommandEvent& event )
-{
- msg_Warn( p_intf, "not implemented" );
-}
-
void Playlist::OnDragItemBegin( wxTreeEvent& event )
{
event.Allow();
{
if( p_destitem2->pp_children[i] == p_destitem ) break;
}
- playlist_TreeMove( p_playlist, p_drageditem, p_destitem2,
- i, i_current_view );
+ playlist_TreeMove( p_playlist, p_drageditem, p_destitem2, i );
}
else
/* this is a node */
{
- playlist_TreeMove( p_playlist, p_drageditem, p_destitem,
- 0, i_current_view );
+ playlist_TreeMove( p_playlist, p_drageditem, p_destitem, 0 );
}
UnlockPlaylist( p_intf->p_sys, p_playlist );
{
/* We were droped below the last item so we append to the
* general node */
- p_dest = p->p_playlist->p_general;
+ msg_Err( p->p_playlist, "USE OF P_GENERAL" );
+ p_dest = p->p_playlist->p_local_category;
i_pos = PLAYLIST_END;
}
else
for( size_t i = 0; i < filenames.GetCount(); i++ )
{
const char *psz_utf8 = wxDnDFromLocale( filenames[i] );
- playlist_item_t *p_item =
- playlist_ItemNew( p->p_playlist, psz_utf8, psz_utf8 );
- playlist_NodeAddItem( p->p_playlist, p_item, p->i_current_view,
- p_dest, PLAYLIST_PREPARSE, i_pos );
+ input_item_t *p_input = input_ItemNew( p->p_playlist,
+ psz_utf8, psz_utf8 );
+ playlist_NodeAddInput( p->p_playlist, p_input,
+ p_dest, PLAYLIST_PREPARSE, i_pos );
wxDnDLocaleFree( psz_utf8 );
}
}
else if( event.GetId() < LastView_Event )
{
-
- int i_new_view = event.GetId() - FirstView_Event;
-
- playlist_view_t *p_view = playlist_ViewFind( p_playlist, i_new_view );
-
- if( p_view != NULL )
+ if( event.GetId() == CategoryView_Event )
{
- b_changed_view = VLC_TRUE;
- i_current_view = i_new_view;
- playlist_ViewUpdate( p_playlist, i_new_view );
- Rebuild( VLC_TRUE );
- return;
+ p_current_viewroot = p_playlist->p_root_category;
+ if( p_current_treeroot == p_playlist->p_local_category ||
+ p_current_treeroot == p_playlist->p_local_onelevel )
+ {
+ p_current_treeroot = p_playlist->p_local_category;
+ }
+ else if( p_current_treeroot == p_playlist->p_ml_category ||
+ p_current_treeroot == p_playlist->p_ml_onelevel )
+ {
+ p_current_treeroot = p_playlist->p_ml_category;
+ }
}
- else if( i_new_view >= VIEW_FIRST_SORTED &&
- i_new_view <= VIEW_LAST_SORTED )
+ else if( event.GetId() == OneLevelView_Event )
{
- b_changed_view = VLC_TRUE;
- playlist_ViewInsert( p_playlist, i_new_view, "View" );
- playlist_ViewUpdate( p_playlist, i_new_view );
-
- i_current_view = i_new_view;
-
- Rebuild( VLC_TRUE );
+ p_current_viewroot = p_playlist->p_root_onelevel;
+ if( p_current_treeroot == p_playlist->p_local_category ||
+ p_current_treeroot == p_playlist->p_local_onelevel )
+ {
+ p_current_treeroot = p_playlist->p_local_onelevel;
+ }
+ else if( p_current_treeroot == p_playlist->p_ml_category ||
+ p_current_treeroot == p_playlist->p_ml_onelevel )
+ {
+ p_current_treeroot = p_playlist->p_ml_onelevel;
+ }
}
+ wxCommandEvent event;
+ OnSearch( event );
+ return;
}
else if( event.GetId() >= FirstSD_Event && event.GetId() < LastSD_Event )
{
}
}
- /* FIXME : have a list of "should have" views */
- p_view_menu->Append( FirstView_Event + VIEW_CATEGORY,
- wxU(_("Normal") ) );
- p_view_menu->Append( FirstView_Event + VIEW_S_AUTHOR,
- wxU(_("Sorted by Artist") ) );
- p_view_menu->Append( FirstView_Event + VIEW_S_ALBUM,
- wxU(_("Sorted by Album") ) );
-
+ p_view_menu->Append( CategoryView_Event, wxU(_("Normal") ) );
+ p_view_menu->Append( OneLevelView_Event, wxU(_("One level") ) );
return p_view_menu;
}
void Playlist::OnPopupPlay( wxCommandEvent& event )
{
playlist_item_t *p_popup_item, *p_popup_parent;
+
+
+
+ abort();
+
+
LockPlaylist( p_intf->p_sys, p_playlist );
p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item );
p_popup_parent = playlist_ItemGetById( p_playlist, i_popup_parent );
p_popup_item->i_children > 0 )
{
playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- i_current_view, p_popup_item,
+ 1242, p_popup_item,
p_popup_item->pp_children[0] );
}
else
{
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- i_current_view, p_popup_item, NULL );
+ playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, 1242,
+ p_popup_item, NULL );
}
}
else
if( event.GetId() == PopupPlay_Event )
{
playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- i_current_view, p_popup_parent,
- p_popup_item );
+ 1242, p_popup_parent, p_popup_item );
}
}
}
{
if( p_popup_item->i_children == -1 )
{
- playlist_PreparseEnqueue( p_playlist, &p_popup_item->input );
+ playlist_PreparseEnqueue( p_playlist, p_popup_item->p_input );
}
else
{
{
wxMenuEvent dummy;
i_wx_popup_item = FindItem( treectrl->GetRootItem(),
- p_parent->pp_children[i]->input.i_id );
- i_popup_item = p_parent->pp_children[i]->input.i_id;
+ p_parent->pp_children[i]->i_id );
+ i_popup_item = p_parent->pp_children[i]->i_id;
Preparse();
}
}
SORT_TITLE_NODES_FIRST, ORDER_NORMAL );
treectrl->DeleteChildren( i_wx_popup_item );
- i_saved_id = -1;
+ i_saved_id = -1; i_saved_input_id = -1;
UpdateNodeChildren( p_item, i_wx_popup_item );
}
p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id );
- playlist_NodeCreate( p_playlist, i_current_view, psz_name, p_item );
+ playlist_NodeCreate( p_playlist, psz_name, p_item );
UnlockPlaylist( p_intf->p_sys, p_playlist );
Rebuild( VLC_TRUE );
wxLocaleFree( psz_name );
}
+void Playlist::OnSourceSelected( wxListEvent &event )
+{
+ int i_id = event.GetData();
+
+ if( p_current_treeroot && i_id != p_current_treeroot->i_id )
+ {
+ playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id );
+ if( p_item ) p_current_treeroot = p_item;
+ Rebuild( VLC_TRUE );
+ }
+}
/*****************************************************************************
* Custom events management
switch( event.GetId() )
{
case UpdateItem_Event:
+ fprintf( stderr,"Update input item id %i\n", event.GetInt() );
UpdateItem( event.GetInt() );
break;
case AppendItem_Event:
+ fprintf( stderr,"Append item id %i\n",
+ ((playlist_add_t*)event.GetClientData())->i_item );
AppendItem( event );
break;
case RemoveItem_Event:
+ fprintf( stderr,"Remove item id %i\n", event.GetInt() );
RemoveItem( event.GetInt() );
break;
}
wxButton *search_button;
wxTreeItemId search_current;
- void OnEnDis( wxCommandEvent& event );
-
/* Sort */
int i_sort_mode;
void OnSort( wxCommandEvent& event );
void OnPopupEna( wxCommandEvent& event );
void OnPopupInfo( wxCommandEvent& event );
void OnPopupAddNode( wxCommandEvent& event );
+
+ /* List */
+ void OnSourceSelected( wxListEvent &event );
protected:
void Rebuild( vlc_bool_t );
private:
/* Search (internal) */
int CountItems( wxTreeItemId);
wxTreeItemId FindItem( wxTreeItemId, int );
+ wxTreeItemId FindItemByInput( wxTreeItemId, int );
+ wxTreeItemId FindItemInner( wxTreeItemId, int , bool );
wxTreeItemId FindItemByName( wxTreeItemId, wxString,
wxTreeItemId, vlc_bool_t *);
wxTreeItemId saved_tree_item;
+ wxTreeItemId saved_input_tree_item;
int i_saved_id;
+ int i_saved_input_id;
protected:
playlist_t *p_playlist;
protected:
intf_thread_t *p_intf;
wxTreeCtrl *treectrl;
+ wxListView *source_sel;
int i_current_view;
+ playlist_item_t *p_current_treeroot;
+ playlist_item_t *p_current_viewroot;
friend class PlaylistFileDropTarget;
};
listview->InsertColumn( 1, wxU(_("URI")) );
listview->SetColumnWidth( 0, 250 );
listview->SetColumnWidth( 1, 100 );
+#if 0
for( int i=0 ; i < p_playlist->i_size ; i++ )
{
wxString filename = wxL2U( p_playlist->pp_items[i]->input.
(long)p_playlist->pp_items[i]->input.i_id );
}
listview->Select( p_playlist->i_index , TRUE);
+#endif
mainSizer->Add( listview, 1, wxALL|wxEXPAND, 5 );
listview->Hide();
i = listview->GetNextItem( i , wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if( i != -1 )
{
- long data = listview->GetItemData( i );
+ long data = listview->GetItemData( i );
playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
VLC_OBJECT_PLAYLIST, FIND_ANYWHERE);
if( p_playlist )
p_playlist, (int)data );
if( p_item )
{
- p_parent->SetMrl( (const char*)p_item->input.psz_uri );
+ p_parent->SetMrl( (const char*)p_item->p_input->psz_uri );
}
else
event.Veto();
VLC_OBJECT_PLAYLIST, FIND_ANYWHERE);
if( p_playlist )
{
- playlist_item_t *p_item = playlist_ItemNew( p_playlist, mrl,
- ITEM_NAME );
- playlist_ItemAddOption( p_item, psz_opt);
+ input_item_t *p_input = input_ItemNew( p_playlist, mrl,
+ ITEM_NAME );
+ vlc_input_item_AddOption( p_input, psz_opt );
if( i_from != 0)
{
char psz_from[20];
snprintf( psz_from, 20, "start-time=%i", i_from);
- playlist_ItemAddOption( p_item, psz_from);
+ vlc_input_item_AddOption( p_input, psz_from );
}
if( i_to != 0)
{
char psz_to[20];
snprintf( psz_to, 20, "stop-time=%i", i_to);
- playlist_ItemAddOption( p_item, psz_to);
+ vlc_input_item_AddOption( p_input, psz_to );
}
char psz_ttl[20];
snprintf( psz_ttl, 20, "ttl=%i",i_ttl );
- playlist_ItemAddOption( p_item, psz_ttl );
+ vlc_input_item_AddOption( p_input, psz_ttl );
- playlist_AddItem( p_playlist, p_item, PLAYLIST_GO, PLAYLIST_END );
+ playlist_PlaylistAddInput( p_playlist, p_input,
+ PLAYLIST_GO, PLAYLIST_END );
vlc_object_release(p_playlist);
}
else
void InputManager::UpdateNowPlaying()
{
- char *psz_now_playing = vlc_input_item_GetInfo( p_input->input.p_item,
- _(VLC_META_INFO_CAT), _(VLC_META_NOW_PLAYING) );
+ char *psz_now_playing = p_input->input.p_item->p_meta->psz_nowplaying ?
+ strdup( p_input->input.p_item->p_meta->psz_nowplaying ):
+ strdup( "" );
if( psz_now_playing && *psz_now_playing )
{
p_main_intf->statusbar->SetStatusText(
{
char *psz_utf8 = wxDnDFromLocale( filenames[i] );
- playlist_Add( p_playlist, psz_utf8, psz_utf8,
+ playlist_PlaylistAdd( p_playlist, psz_utf8, psz_utf8,
PLAYLIST_APPEND | ((i | b_enqueue) ? 0 : PLAYLIST_GO),
PLAYLIST_END );
class PlaylistItem : public wxTreeItemData
{
public:
- PlaylistItem( playlist_item_t *p_item ) : i_id(p_item->input.i_id) {}
+ PlaylistItem( playlist_item_t *p_item ) : i_id(p_item->p_input->i_id) {}
int i_id;
};
void PlaylistManager::CreateNode( playlist_item_t *p_node, wxTreeItemId parent)
{
wxTreeItemId node =
- treectrl->AppendItem( parent, wxL2U( p_node->input.psz_name ), -1, -1,
+ treectrl->AppendItem( parent, wxL2U( p_node->p_input->psz_name ), -1, -1,
new PlaylistItem( p_node ) );
- treectrl->SetItemImage( node, p_node->input.i_type );
+ treectrl->SetItemImage( node, p_node->p_input->i_type );
UpdateNodeChildren( p_node, node );
}
}
}
- treectrl->SetItemImage( node, p_node->input.i_type );
+ treectrl->SetItemImage( node, p_node->p_input->i_type );
}
{
wxTreeItemId item =
treectrl->AppendItem( node,
- wxL2U( p_node->pp_children[i]->input.psz_name ), -1,-1,
+ wxL2U( p_node->pp_children[i]->p_input->psz_name ), -1,-1,
new PlaylistItem( p_node->pp_children[i]) );
UpdateTreeItem( item );
wxString msg;
wxString duration = wxU( "" );
- char *psz_author =
- vlc_input_item_GetInfo( &p_item->input,
- _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
+ char *psz_author = p_item->p_input->p_meta->psz_artist ?
+ strdup( p_item->p_input->p_meta->psz_artist ) :
+ strdup( "" );
if( !psz_author )
{
UnlockPlaylist( p_intf->p_sys, p_playlist );
}
char psz_duration[MSTRTIME_MAX_SIZE];
- mtime_t dur = p_item->input.i_duration;
+ mtime_t dur = p_item->p_input->i_duration;
if( dur != -1 )
{
wxU( " )" ) );
}
- if( !strcmp( psz_author, "" ) || p_item->input.b_fixed_name == VLC_TRUE )
+ if( !strcmp( psz_author, "" ) || p_item->p_input->b_fixed_name == VLC_TRUE )
{
- msg = wxString( wxU( p_item->input.psz_name ) ) + duration;
+ msg = wxString( wxU( p_item->p_input->psz_name ) ) + duration;
}
else
{
msg = wxString(wxU( psz_author )) + wxT(" - ") +
- wxString(wxU(p_item->input.psz_name)) + duration;
+ wxString(wxU(p_item->p_input->psz_name)) + duration;
}
free( psz_author );
treectrl->SetItemText( item , msg );
- treectrl->SetItemImage( item, p_item->input.i_type );
+ treectrl->SetItemImage( item, p_item->p_input->i_type );
if( p_playlist->status.p_item == p_item )
{
item = FindItem( treectrl->GetRootItem(), p_add->i_item );
if( item.IsOk() ) goto update;
- item = treectrl->AppendItem( node, wxL2U( p_item->input.psz_name ), -1,-1,
+ item = treectrl->AppendItem( node, wxL2U( p_item->p_input->psz_name ), -1,-1,
new PlaylistItem( p_item ) );
- treectrl->SetItemImage( item, p_item->input.i_type );
+ treectrl->SetItemImage( item, p_item->p_input->i_type );
if( item.IsOk() && p_item->i_children == -1 ) UpdateTreeItem( item );
**********************************************************************/
void PlaylistManager::Rebuild( vlc_bool_t b_root )
{
- playlist_view_t *p_view;
-
i_items_to_append = 0;
i_cached_item_id = -1;
- p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
-
treectrl->DeleteAllItems();
treectrl->AddRoot( wxU(_("root" )), -1, -1,
- new PlaylistItem( p_view->p_root ) );
+ new PlaylistItem( p_playlist->p_root_category ) );
wxTreeItemId root = treectrl->GetRootItem();
- UpdateNode( p_view->p_root, root );
+ UpdateNode( p_playlist->p_root_category, root );
}
/**********************************************************************
p_node = p_item;
p_item = NULL;
}
-
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VIEW_CATEGORY,
- p_node, p_item );
+ playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, p_node, p_item );
UnlockPlaylist( p_intf->p_sys, p_playlist );
}
}
/* Playing something ... */
- psz_artist = vlc_input_item_GetInfo( p_input->input.p_item,
- _("Meta-information"),
- _(VLC_META_ARTIST) );
- psz_album = vlc_input_item_GetInfo( p_input->input.p_item,
- _("Meta-information"),
- _("Album/movie/show title" ) );
+ psz_artist = p_input->input.p_item->p_meta->psz_artist ?
+ strdup( p_input->input.p_item->p_meta->psz_artist ) :
+ strdup( "" );
+ psz_album = p_input->input.p_item->p_meta->psz_album ?
+ strdup( p_input->input.p_item->p_meta->psz_album ) :
+ strdup( "" );
psz_title = strdup( p_input->input.p_item->psz_name );
if( psz_title == NULL ) psz_title = strdup( N_("(no title)") );
if( psz_artist == NULL ) psz_artist = strdup( N_("(no artist)") );
}
/* Playing something ... */
- psz_artist = vlc_input_item_GetInfo( p_input->input.p_item,
- _(VLC_META_INFO_CAT),
- _(VLC_META_ARTIST) );
- psz_album = vlc_input_item_GetInfo( p_input->input.p_item,
- _(VLC_META_INFO_CAT),
- _(VLC_META_COLLECTION) );
+ psz_artist = p_input->input.p_item->p_meta->psz_artist ?
+ strdup( p_input->input.p_item->p_meta->psz_artist ) :
+ strdup( "" );
+ psz_album = p_input->input.p_item->p_meta->psz_album ?
+ strdup( p_input->input.p_item->p_meta->psz_album ) :
+ strdup( "" );
psz_title = strdup( p_input->input.p_item->psz_name );
if( psz_title == NULL ) psz_title = strdup( N_("(no title)") );
if( psz_artist == NULL ) psz_artist = strdup( N_("(no artist)") );
fprintf( p_export->p_file, "#EXTM3U\n" );
/* Go through the playlist and add items */
- for( i = 0; i< p_playlist->i_size ; i++)
+ for( i = 0; i< p_export->p_root->i_children ; i++)
{
- if( (p_playlist->pp_items[i]->i_flags & PLAYLIST_SAVE_FLAG) == 0 )
- {
+ playlist_item_t *p_current = p_export->p_root->pp_children[i];
+ if( p_current->i_flags & PLAYLIST_SAVE_FLAG )
continue;
- }
/* General info */
- if( p_playlist->pp_items[i]->input.psz_name &&
- strcmp( p_playlist->pp_items[i]->input.psz_name,
- p_playlist->pp_items[i]->input.psz_uri ) )
+ if( p_current->p_input->psz_name &&
+ strcmp( p_current->p_input->psz_uri,
+ p_current->p_input->psz_name ) )
{
- char *psz_artist =
- vlc_input_item_GetInfo( &p_playlist->pp_items[i]->input,
- _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
+ char *psz_artist = p_current->p_input->p_meta->psz_artist ?
+ strdup( p_current->p_input->p_meta->psz_artist ):
+ strdup( "" );
if( psz_artist && *psz_artist )
{
/* write EXTINF with artist */
fprintf( p_export->p_file, "#EXTINF:%i,%s - %s\n",
- (int)(p_playlist->pp_items[i]->input.i_duration/1000000),
- psz_artist,
- p_playlist->pp_items[i]->input.psz_name );
+ (int)( p_current->p_input->i_duration/1000000 ),
+ psz_artist,
+ p_current->p_input->psz_name);
}
else
{
/* write EXTINF without artist */
fprintf( p_export->p_file, "#EXTINF:%i,%s\n",
- (int)(p_playlist->pp_items[i]->input.i_duration/1000000),
- p_playlist->pp_items[i]->input.psz_name );
+ (int)( p_current->p_input->i_duration/1000000 ),
+ p_current->p_input->psz_name);
}
if( psz_artist )
free( psz_artist );
}
/* VLC specific options */
- for( j = 0; j < p_playlist->pp_items[i]->input.i_options; j++ )
+ for( j = 0; j < p_current->p_input->i_options; j++ )
{
fprintf( p_export->p_file, "#EXTVLCOPT:%s\n",
- p_playlist->pp_items[i]->input.ppsz_options[j][0] == ':' ?
- p_playlist->pp_items[i]->input.ppsz_options[j] + 1 :
- p_playlist->pp_items[i]->input.ppsz_options[j] );
+ p_current->p_input->ppsz_options[j][0] == ':' ?
+ p_current->p_input->ppsz_options[j] + 1 :
+ p_current->p_input->ppsz_options[j] );
}
fprintf( p_export->p_file, "%s\n",
- p_playlist->pp_items[i]->input.psz_uri );
+ p_current->p_input->psz_uri );
}
return VLC_SUCCESS;
}
/* Write header */
fprintf( p_export->p_file , PLAYLIST_FILE_HEADER "\n" );
- for ( i = 0 ; i < p_playlist->i_size ; i++ )
+ for ( i = 0 ; i < p_export->p_root->i_children ; i++ )
{
char *psz_uri;
- psz_uri = ToLocale( p_playlist->pp_items[i]->input.psz_uri );
+ psz_uri =
+ ToLocale( p_export->p_root->pp_children[i]->p_input->psz_name );
fprintf( p_export->p_file , "%s\n" , psz_uri );
LocaleFree( psz_uri );
}
#define p_item p_playlist->status.p_item
if ( p_item )
{
- for (i = 0; i < p_item->i_parents; i++ )
+ if ( p_item->p_parent->p_input->i_type == ITEM_TYPE_PLAYLIST )
{
- if ( p_item->pp_parents[i]->p_parent->input.i_type
- == ITEM_TYPE_PLAYLIST )
- {
- /* set the current node and its children */
- p_node = p_item->pp_parents[i]->p_parent;
- pp_items = p_node->pp_children;
- i_size = p_node->i_children;
+ /* set the current node and its children */
+ p_node = p_item->p_parent;
+ pp_items = p_node->pp_children;
+ i_size = p_node->i_children;
#undef p_item
- /* save name of the playlist node */
- psz_temp = convert_xml_special_chars( p_node->input.psz_name );
- if ( *psz_temp )
- fprintf( p_export->p_file, "\t<title>%s</title>\n",
- psz_temp );
- free( psz_temp );
-
- /* save the creator of the playlist node */
- psz = vlc_input_item_GetInfo( &p_node->input,
- _(VLC_META_INFO_CAT),
- _(VLC_META_ARTIST) );
- if ( psz && !*psz )
- {
- free ( psz );
- psz = NULL;
- }
-
- if ( !psz )
- psz = vlc_input_item_GetInfo( &p_node->input,
- _(VLC_META_INFO_CAT),
- _(VLC_META_AUTHOR) );
-
- psz_temp = convert_xml_special_chars( psz );
-
- if ( psz ) free( psz );
- if ( *psz_temp )
- fprintf( p_export->p_file, "\t<creator>%s</creator>\n",
- psz_temp );
- free( psz_temp );
-
- /* save location of the playlist node */
- psz = assertUTF8URI( p_export->psz_filename );
- if ( psz && *psz )
- {
- fprintf( p_export->p_file, "\t<location>%s</location>\n",
- psz );
- free( psz );
- }
- break;
+ /* save name of the playlist node */
+ psz_temp = convert_xml_special_chars( p_node->p_input->psz_name );
+ if ( *psz_temp )
+ fprintf( p_export->p_file, "\t<title>%s</title>\n",
+ psz_temp );
+ free( psz_temp );
+
+ /* save the creator of the playlist node */
+ psz = p_node->p_input->p_meta->psz_artist ?
+ strdup( p_node->p_input->p_meta->psz_artist ):
+ strdup( "" );
+ if ( psz && !*psz )
+ {
+ free ( psz );
+ psz = NULL;
+ }
+
+ if ( !psz )
+ psz = p_node->p_input->p_meta->psz_author ?
+ strdup( p_node->p_input->p_meta->psz_author ):
+ strdup( "" );
+
+ psz_temp = convert_xml_special_chars( psz );
+
+ if ( psz ) free( psz );
+ if ( *psz_temp )
+ fprintf( p_export->p_file, "\t<creator>%s</creator>\n",
+ psz_temp );
+ free( psz_temp );
+
+ /* save location of the playlist node */
+ psz = assertUTF8URI( p_export->psz_filename );
+ if ( psz && *psz )
+ {
+ fprintf( p_export->p_file, "\t<location>%s</location>\n",
+ psz );
+ free( psz );
}
}
}
fprintf( p_file, "\t\t<track>\n" );
/* -> the location */
- if ( p_item->input.psz_uri && *p_item->input.psz_uri )
+ if ( p_item->p_input->psz_uri && *p_item->p_input->psz_uri )
{
- psz = assertUTF8URI( p_item->input.psz_uri );
+ psz = assertUTF8URI( p_item->p_input->psz_uri );
fprintf( p_file, "\t\t\t<location>%s</location>\n", psz );
free( psz );
}
/* -> the name/title (only if different from uri)*/
- if ( p_item->input.psz_name &&
- p_item->input.psz_uri &&
- strcmp( p_item->input.psz_uri, p_item->input.psz_name ) )
+ if ( p_item->p_input->psz_name &&
+ p_item->p_input->psz_uri &&
+ strcmp( p_item->p_input->psz_uri, p_item->p_input->psz_name ) )
{
- psz_temp = convert_xml_special_chars( p_item->input.psz_name );
+ psz_temp = convert_xml_special_chars( p_item->p_input->psz_name );
if ( *psz_temp )
fprintf( p_file, "\t\t\t<title>%s</title>\n", psz_temp );
free( psz_temp );
}
/* -> the artist/creator */
- psz = vlc_input_item_GetInfo( &p_item->input,
- _(VLC_META_INFO_CAT),
- _(VLC_META_ARTIST) );
+ psz = p_item->p_input->p_meta->psz_artist ?
+ strdup( p_item->p_input->p_meta->psz_artist ):
+ strdup( "" );
if ( psz && !*psz )
{
free ( psz );
psz = NULL;
}
if ( !psz )
- psz = vlc_input_item_GetInfo( &p_item->input,
- _(VLC_META_INFO_CAT),
- _(VLC_META_AUTHOR) );
+ psz = p_item->p_input->p_meta->psz_author ?
+ strdup( p_item->p_input->p_meta->psz_author ):
+ strdup( "" );
psz_temp = convert_xml_special_chars( psz );
if ( psz ) free( psz );
if ( *psz_temp )
free( psz_temp );
/* -> the album */
- psz = vlc_input_item_GetInfo( &p_item->input,
- _(VLC_META_INFO_CAT),
- _(VLC_META_COLLECTION) );
+ psz = p_item->p_input->p_meta->psz_album ?
+ strdup( p_item->p_input->p_meta->psz_album ):
+ strdup( "" );
psz_temp = convert_xml_special_chars( psz );
if ( psz ) free( psz );
if ( *psz_temp )
free( psz_temp );
/* -> the track number */
- psz = vlc_input_item_GetInfo( &p_item->input,
- _(VLC_META_INFO_CAT),
- _(VLC_META_SEQ_NUM) );
+ psz = p_item->p_input->p_meta->psz_tracknum ?
+ strdup( p_item->p_input->p_meta->psz_tracknum ):
+ strdup( "" );
if ( psz )
{
if ( *psz )
}
/* -> the duration */
- if ( p_item->input.i_duration > 0 )
+ if ( p_item->p_input->i_duration > 0 )
{
fprintf( p_file, "\t\t\t<duration>%ld</duration>\n",
- (long)(p_item->input.i_duration / 1000) );
+ (long)(p_item->p_input->i_duration / 1000) );
}
fprintf( p_file, "\t\t</track>\n" );
/* Misc atoms */
if( p_meta )
{
- int i;
- for( i = 0; i < p_meta->i_meta; i++ )
- {
- bo_t *box = NULL;
-
- if( !strcmp( p_meta->name[i], VLC_META_TITLE ) )
- box = box_new( "\251nam" );
- else if( !strcmp( p_meta->name[i], VLC_META_AUTHOR ) )
- box = box_new( "\251aut" );
- else if( !strcmp( p_meta->name[i], VLC_META_ARTIST ) )
- box = box_new( "\251ART" );
- else if( !strcmp( p_meta->name[i], VLC_META_GENRE ) )
- box = box_new( "\251gen" );
- else if( !strcmp( p_meta->name[i], VLC_META_COPYRIGHT ) )
- box = box_new( "\251cpy" );
- else if( !strcmp( p_meta->name[i], VLC_META_DESCRIPTION ) )
- box = box_new( "\251des" );
- else if( !strcmp( p_meta->name[i], VLC_META_DATE ) )
- box = box_new( "\251day" );
- else if( !strcmp( p_meta->name[i], VLC_META_URL ) )
- box = box_new( "\251url" );
-
- if( box )
- {
- bo_add_16be( box, strlen( p_meta->value[i] ) );
- bo_add_16be( box, 0 );
- bo_add_mem( box, strlen( p_meta->value[i] ),
- (uint8_t*)(p_meta->value[i]) );
- box_fix( box );
- box_gather( udta, box );
- }
- }
+#define ADD_META_BOX( type, box_string ) { \
+ bo_t *box = NULL; \
+ if( p_meta->psz_##type ) box = box_new( "\251" box_string ); \
+ if( box ) \
+ { \
+ bo_add_16be( box, strlen( p_meta->psz_##type ) ); \
+ bo_add_16be( box, 0 ); \
+ bo_add_mem( box, strlen( p_meta->psz_##type ), \
+ (uint8_t*)(p_meta->psz_##type ) ); \
+ box_fix( box ); \
+ box_gather( udta, box ); \
+ } }
+
+ ADD_META_BOX( title, "nam" );
+ ADD_META_BOX( author, "aut" );
+ ADD_META_BOX( artist, "ART" );
+ ADD_META_BOX( genre, "gen" );
+ ADD_META_BOX( copyright, "cpy" );
+ ADD_META_BOX( description, "des" );
+ ADD_META_BOX( date, "day" );
+ ADD_META_BOX( url, "url" );
+#undef ADD_META_BOX
}
box_fix( udta );
msg_Warn( p_sd, "unable to find playlist, cancelling DAAP" );
return VLC_EGENERIC;
}
+ msg_Err( p_sd, "DAAP IS BROKEN !! Fix it if you want it !" );
+ return VLC_EGENERIC;
- p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
+#if 0
p_sys->p_node = playlist_NodeCreate( p_playlist, VIEW_CATEGORY,
_("DAAP shares"), p_view->p_root );
p_sys->p_node->i_flags |= PLAYLIST_RO_FLAG;
vlc_object_release( p_playlist );
return VLC_SUCCESS;
+#endif
}
static int OpenAccess( vlc_object_t *p_this )
{
+#if 0
access_t *p_access = (access_t*)p_this;
access_sys_t *p_sys;
vlc_value_t val;
if( i_ret != 0 )
return VLC_EGENERIC;
-
+#endif
return VLC_SUCCESS;
}
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
+#if 0
services_discovery_t *p_sd = ( services_discovery_t* )p_this;
services_discovery_sys_t *p_sys = p_sd->p_sys;
}
free( p_sys );
+#endif
}
static void CloseAccess( vlc_object_t *p_this )
static void ProcessHost( services_discovery_t *p_sd, dhost_t *p_host )
{
+#if 0
int i_dbsize, i_db, i, i_songsize, i_ret;
int i_size = DAAP_ClientHost_GetSharename( p_host->p_host, NULL, 0 );
DAAP_ClientHost_AsyncWaitUpdate( p_host->p_host );
vlc_object_release( p_playlist );
+#endif
}
static void FreeHost( services_discovery_t *p_sd, dhost_t *p_host )
/*****************************************************************************
- * sap.c : SAP interface module
+ * hal.c : HAL interface module
*****************************************************************************
* Copyright (C) 2004 the VideoLAN team
* $Id$
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
-/*****************************************************************************
- * Includes
- *****************************************************************************/
-#include <stdlib.h> /* malloc(), free() */
-
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <hal/libhal.h>
-/************************************************************************
- * Macros and definitions
- ************************************************************************/
-
#define MAX_LINE_LENGTH 256
-
/*****************************************************************************
- * Module descriptor
+ * Local prototypes
*****************************************************************************/
+struct services_discovery_sys_t
+{
+ LibHalContext *p_ctx;
+ playlist_item_t *p_node_cat;
+ playlist_item_t *p_node_one;
+};
+static void AddItem( services_discovery_t *p_sd, input_item_t * p_input );
+static void Run ( services_discovery_t *p_intf );
-/* Callbacks */
- static int Open ( vlc_object_t * );
- static void Close( vlc_object_t * );
+static int Open ( vlc_object_t * );
+static void Close( vlc_object_t * );
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
vlc_module_begin();
set_description( _("HAL devices detection") );
set_category( CAT_PLAYLIST );
vlc_module_end();
-/*****************************************************************************
- * Local structures
- *****************************************************************************/
-
-struct services_discovery_sys_t
-{
- LibHalContext *p_ctx;
-
- /* playlist node */
- playlist_item_t *p_node;
-
-};
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-
-/* Main functions */
- static void Run ( services_discovery_t *p_intf );
-
/*****************************************************************************
* Open: initialize and create stuff
*****************************************************************************/
vlc_value_t val;
playlist_t *p_playlist;
- playlist_view_t *p_view;
DBusError dbus_error;
DBusConnection *p_connection;
return VLC_EGENERIC;
}
- p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
- p_sys->p_node = playlist_NodeCreate( p_playlist, VIEW_CATEGORY,
- _("Devices"), p_view->p_root );
+ p_sys->p_node_cat = playlist_NodeCreate( p_playlist, _("Devices"),
+ p_playlist->p_root_category );
+ p_sys->p_node_cat->i_flags |= PLAYLIST_RO_FLAG;
+ p_sys->p_node_one = playlist_NodeCreate( p_playlist, _("Devices"),
+ p_playlist->p_root_onelevel );
+ p_sys->p_node_one->i_flags |= PLAYLIST_RO_FLAG;
- p_sys->p_node->i_flags |= PLAYLIST_RO_FLAG;
val.b_bool = VLC_TRUE;
var_Set( p_playlist, "intf-change", val );
VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist )
{
- playlist_NodeDelete( p_playlist, p_sys->p_node, VLC_TRUE, VLC_TRUE );
+ playlist_NodeDelete( p_playlist, p_sys->p_node_cat, VLC_TRUE,VLC_TRUE );
+ playlist_NodeDelete( p_playlist, p_sys->p_node_one, VLC_TRUE,VLC_TRUE );
vlc_object_release( p_playlist );
}
free( p_sys );
char *psz_name;
char *psz_uri;
char *psz_blockdevice;
- services_discovery_sys_t *p_sys = p_sd->p_sys;
- playlist_t *p_playlist;
- playlist_item_t *p_item;
+ input_item_t *p_input;
#ifdef HAVE_HAL_1
psz_name = libhal_device_get_property_string( p_sd->p_sys->p_ctx,
psz_device, "volume.label", NULL );
#endif
asprintf( &psz_uri, "dvd://%s", psz_blockdevice );
/* Create the playlist item here */
- p_item = playlist_ItemNew( p_sd, psz_uri,
- psz_name );
+ p_input = input_ItemNew( p_sd, psz_uri, psz_name );
free( psz_uri );
#ifdef HAVE_HAL_1
libhal_free_string( psz_device );
#else
hal_free_string( psz_device );
#endif
- if( !p_item )
+ if( !p_input )
{
return;
}
- p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
- p_playlist = (playlist_t *)vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST,
- FIND_ANYWHERE );
+ AddItem( p_sd, p_input );
+}
+
+static void AddItem( services_discovery_t *p_sd, input_item_t * p_input )
+{
+ playlist_item_t *p_item;
+ playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_sd,
+ VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( !p_playlist )
{
msg_Err( p_sd, "playlist not found" );
return;
}
-
- playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY, p_sys->p_node,
- PLAYLIST_APPEND, PLAYLIST_END );
+ p_item = playlist_NodeAddInput( p_playlist, p_input,p_sd->p_sys->p_node_cat,
+ PLAYLIST_APPEND, PLAYLIST_END );
+ p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
+ p_item = playlist_NodeAddInput( p_playlist, p_input,p_sd->p_sys->p_node_one,
+ PLAYLIST_APPEND, PLAYLIST_END );
+ p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
vlc_object_release( p_playlist );
}
char *psz_name = "Audio CD";
char *psz_uri;
char *psz_blockdevice;
- services_discovery_sys_t *p_sys = p_sd->p_sys;
- playlist_t *p_playlist;
- playlist_item_t *p_item;
+ input_item_t *p_input;
#ifdef HAVE_HAL_1
psz_blockdevice = libhal_device_get_property_string( p_sd->p_sys->p_ctx,
psz_device, "block.device", NULL );
#endif
asprintf( &psz_uri, "cdda://%s", psz_blockdevice );
/* Create the playlist item here */
- p_item = playlist_ItemNew( p_sd, psz_uri,
- psz_name );
+ p_input = input_ItemNew( p_sd, psz_uri, psz_name );
free( psz_uri );
#ifdef HAVE_HAL_1
libhal_free_string( psz_device );
#else
hal_free_string( psz_device );
#endif
- if( !p_item )
- {
- return;
- }
- p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
- p_playlist = (playlist_t *)vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST,
- FIND_ANYWHERE );
- if( !p_playlist )
- {
- msg_Err( p_sd, "playlist not found" );
+ if( !p_input )
return;
- }
-
- playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY, p_sys->p_node,
- PLAYLIST_APPEND, PLAYLIST_END );
-
- vlc_object_release( p_playlist );
-
+ AddItem( p_sd, p_input );
}
static void ParseDevice( services_discovery_t *p_sd, char *psz_device )
struct services_discovery_sys_t
{
/* playlist node */
- playlist_item_t *p_node;
+ playlist_item_t *p_node_cat;
+ playlist_item_t *p_node_one;
input_thread_t **pp_input;
char **ppsz_urls;
return VLC_EGENERIC;
}
- p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
- p_sys->p_node = playlist_NodeCreate( p_playlist, VIEW_CATEGORY,
- _("Podcast"), p_view->p_root );
+ p_sys->p_node_cat = playlist_NodeCreate( p_playlist, _("Podcast"),
+ p_playlist->p_root_category );
+ p_sys->p_node_one = playlist_NodeCreate( p_playlist, _("Podcast"),
+ p_playlist->p_root_onelevel );
+ p_sys->p_node_one->p_input->i_id = p_sys->p_node_cat->p_input->i_id;
+
+ p_sys->p_node_one->i_flags |= PLAYLIST_RO_FLAG;
+ p_sys->p_node_cat->i_flags |= PLAYLIST_RO_FLAG;
+ p_sys->p_node_one->i_flags |= PLAYLIST_SKIP_FLAG;
+ p_sys->p_node_cat->i_flags |= PLAYLIST_SKIP_FLAG;
p_sys->pp_input = malloc( p_sys->i_urls * sizeof( input_thread_t * ) );
for( i = 0; i < p_sys->i_urls; i++ )
{
+ input_item_t *p_input;
asprintf( &psz_buf, "%s", p_sys->ppsz_urls[i] );
- p_item = playlist_ItemNew( p_playlist, psz_buf,
- p_sys->ppsz_urls[i] );
+ p_input = input_ItemNewExt( p_playlist, psz_buf,
+ p_sys->ppsz_urls[i], 0, NULL, -1 );
+ vlc_input_item_AddOption( p_input, "demux=podcast" );
+ p_item = playlist_NodeAddInput( p_playlist, p_input, p_sys->p_node_cat,
+ PLAYLIST_APPEND, PLAYLIST_END );
+ p_item = playlist_NodeAddInput( p_playlist, p_input, p_sys->p_node_one,
+ PLAYLIST_APPEND, PLAYLIST_END );
free( psz_buf );
- playlist_ItemAddOption( p_item, "demux=podcast" );
- playlist_NodeAddItem( p_playlist, p_item,
- p_sys->p_node->pp_parents[0]->i_view,
- p_sys->p_node, PLAYLIST_APPEND,
- PLAYLIST_END );
-
- /* We need to declare the parents of the node as the same of the
- * parent's ones */
- playlist_CopyParents( p_sys->p_node, p_item );
- p_sys->pp_input[i] = input_CreateThread( p_playlist, &p_item->input );
+ p_sys->pp_input[i] = input_CreateThread( p_playlist, p_input );
}
- p_sys->p_node->i_flags |= PLAYLIST_RO_FLAG;
val.b_bool = VLC_TRUE;
var_Set( p_playlist, "intf-change", val );
free( p_sd->p_sys->pp_input );
if( p_playlist )
{
- playlist_NodeDelete( p_playlist, p_sys->p_node, VLC_TRUE, VLC_TRUE );
+ playlist_NodeDelete( p_playlist, p_sys->p_node_cat, VLC_TRUE, VLC_TRUE );
+ playlist_NodeDelete( p_playlist, p_sys->p_node_one, VLC_TRUE, VLC_TRUE );
vlc_object_release( p_playlist );
}
for( i = 0; i < p_sys->i_urls; i++ ) free( p_sys->ppsz_urls[i] );
/* SAP annnounces must only contain one SDP */
sdp_t *p_sdp;
- int i_item_id;
-// playlist_item_t *p_item;
+ int i_input_id;
+ int i_item_id_cat;
+ int i_item_id_one;
};
struct services_discovery_sys_t
int *pi_fd;
/* playlist node */
- playlist_item_t *p_node;
+ playlist_item_t *p_node_cat;
+ playlist_item_t *p_node_one;
playlist_t *p_playlist;
/* Table of announces */
msg_Warn( p_sd, "unable to find playlist, cancelling SAP listening");
return VLC_EGENERIC;
}
+ p_sys->p_node_cat = playlist_NodeCreate( p_sys->p_playlist,
+ _("SAP sessions"),
+ p_sys->p_playlist->p_root_category );
+ p_sys->p_node_cat->i_flags |= PLAYLIST_RO_FLAG;
+ p_sys->p_node_cat->i_flags |= PLAYLIST_SKIP_FLAG;
+
+ p_sys->p_node_one = playlist_NodeCreate( p_sys->p_playlist,
+ _("SAP sessions"),
+ p_sys->p_playlist->p_root_onelevel );
+ p_sys->p_node_one->i_flags |= PLAYLIST_RO_FLAG;
+ p_sys->p_node_one->i_flags |= PLAYLIST_SKIP_FLAG;
- p_view = playlist_ViewFind( p_sys->p_playlist, VIEW_CATEGORY );
- p_sys->p_node = playlist_NodeCreate( p_sys->p_playlist, VIEW_CATEGORY,
- _("Session Announcements (SAP)"), p_view->p_root );
- p_sys->p_node->i_flags |= PLAYLIST_RO_FLAG;
- p_sys->p_node->i_flags &= ~PLAYLIST_SKIP_FLAG;
val.b_bool = VLC_TRUE;
var_Set( p_sys->p_playlist, "intf-change", val );
if( p_sys->p_playlist )
{
- playlist_NodeDelete( p_sys->p_playlist, p_sys->p_node, VLC_TRUE,
+ playlist_NodeDelete( p_sys->p_playlist, p_sys->p_node_cat, VLC_TRUE,
+ VLC_TRUE );
+ playlist_NodeDelete( p_sys->p_playlist, p_sys->p_node_one, VLC_TRUE,
VLC_TRUE );
vlc_object_release( p_sys->p_playlist );
}
p_announce = p_sd->p_sys->pp_announces[i];
/* Remove the playlist item */
- playlist_LockDelete( p_sd->p_sys->p_playlist,
- p_announce->i_item_id );
+ playlist_LockDeleteAllFromInput( p_sd->p_sys->p_playlist,
+ p_announce->i_input_id );
/* Remove the sap_announce from the array */
REMOVE_ELEM( p_sd->p_sys->pp_announces,
p_playlist = (playlist_t *)vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
- p_playlist->status.p_item->i_flags |= PLAYLIST_DEL_FLAG;
-
- playlist_Add( p_playlist, p_sdp->psz_uri, p_sdp->psz_sessionname,
- PLAYLIST_APPEND, PLAYLIST_END );
+ /* TODO FIXME !! Add at the correct place */
+ playlist_PlaylistAdd( p_playlist, p_sdp->psz_uri, p_sdp->psz_sessionname,
+ PLAYLIST_APPEND, PLAYLIST_END );
vlc_object_release( p_playlist );
if( p_sdp ) FreeSDP( p_sdp );
sap_announce_t *CreateAnnounce( services_discovery_t *p_sd, uint16_t i_hash,
sdp_t *p_sdp )
{
+ input_item_t *p_input;
playlist_item_t *p_item, *p_child;
char *psz_value;
sap_announce_t *p_sap = (sap_announce_t *)malloc(
p_sap->i_last = mdate();
p_sap->i_hash = i_hash;
p_sap->p_sdp = p_sdp;
- p_sap->i_item_id = -1;
/* Create the actual playlist item here */
- p_item = playlist_ItemNew( p_sd, p_sap->p_sdp->psz_uri, p_sdp->psz_sessionname );
-
- if( !p_item )
+ p_input = input_ItemNewWithType( VLC_OBJECT(p_sd),
+ p_sap->p_sdp->psz_uri,
+ p_sdp->psz_sessionname,
+ 0, NULL, -1, ITEM_TYPE_NET );
+ p_sap->i_input_id = p_input->i_id;
+ if( !p_input )
{
free( p_sap );
return NULL;
}
if( p_sys->b_timeshift )
- playlist_ItemAddOption( p_item, ":access-filter=timeshift" );
+ vlc_input_item_AddOption( p_input, ":access-filter=timeshift" );
psz_value = GetAttribute( p_sap->p_sdp, "tool" );
if( psz_value != NULL )
{
- vlc_input_item_AddInfo( &p_item->input, _("Session"),
- _("Tool"), psz_value );
+ vlc_input_item_AddInfo( p_input, _("Session"),_("Tool"), psz_value );
}
if( strcmp( p_sdp->psz_username, "-" ) )
{
- vlc_input_item_AddInfo( &p_item->input, _("Session"),
+ vlc_input_item_AddInfo( p_input, _("Session"),
_("User"), p_sdp->psz_username );
}
+ /* Handle group */
psz_value = GetAttribute( p_sap->p_sdp, "x-plgroup" );
-
if( psz_value == NULL )
- {
psz_value = GetAttribute( p_sap->p_sdp, "plgroup" );
- }
- /* Find or Create the group playlist non-playable item */
if( psz_value != NULL )
{
EnsureUTF8( psz_value );
- p_child = playlist_ChildSearchName( p_sys->p_node, psz_value );
+ p_child = playlist_ChildSearchName( p_sys->p_node_cat, psz_value );
if( p_child == NULL )
{
- p_child = playlist_NodeCreate( p_sys->p_playlist,
- VIEW_CATEGORY, psz_value,
- p_sys->p_node );
+ p_child = playlist_NodeCreate( p_sys->p_playlist, psz_value,
+ p_sys->p_node_cat );
p_child->i_flags &= ~PLAYLIST_SKIP_FLAG;
}
}
else
{
- p_child = p_sys->p_node;
+ p_child = p_sys->p_node_cat;
}
+ p_item = playlist_NodeAddInput( p_sys->p_playlist, p_input, p_child,
+ PLAYLIST_APPEND, PLAYLIST_END );
p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
p_item->i_flags &= ~PLAYLIST_SAVE_FLAG;
+ p_sap->i_item_id_cat = p_item->i_id;
- playlist_NodeAddItem( p_sys->p_playlist, p_item, VIEW_CATEGORY, p_child,
- PLAYLIST_APPEND, PLAYLIST_END );
-
- p_sap->i_item_id = p_item->input.i_id;
+ p_item = playlist_NodeAddInput( p_sys->p_playlist, p_input,
+ p_sys->p_node_one, PLAYLIST_APPEND, PLAYLIST_END );
+ p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
+ p_item->i_flags &= ~PLAYLIST_SAVE_FLAG;
+ p_sap->i_item_id_one = p_item->i_id;
TAB_APPEND( p_sys->i_announces, p_sys->pp_announces, p_sap );
printf( "inflateInit() failed. Result: %d\n", i_result );
return( -1 );
}
-#if 0
- p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
- i_position = p_playlist->i_index;
-
- /* Gather the complete sdp file */
- for( ;; )
- {
- int i_read = stream_Read( p_demux->s, &p_sdp[i_sdp], i_sdp_max - i_sdp - 1 );
-#endif
d_stream.next_in = (Bytef *)psz_src;
d_stream.avail_in = i_len;
n = 0;
if( p_announce->p_sdp ) FreeSDP( p_announce->p_sdp );
- if( p_announce->i_item_id > -1 )
+ if( p_announce->i_input_id > -1 )
{
- playlist_LockDelete( p_sd->p_sys->p_playlist, p_announce->i_item_id );
+ playlist_LockDeleteAllFromInput(
+ p_sd->p_sys->p_playlist, p_announce->i_input_id );
}
for( i = 0; i< p_sd->p_sys->i_announces; i++)
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
- int i_size,i_index;
playlist_t *p_playlist;
playlist_item_t *p_item = NULL;
input_item_t item;
continue;
}
- if( p_playlist->i_size < 0 || p_playlist->i_index < 0 )
+ if( p_playlist->i_size < 0 )
{
vlc_object_release( p_playlist );
continue;
}
else
{
- // vlc_mutex_lock(&p_playlist->object_lock );
p_item = p_playlist->status.p_item;
item = p_item->input;
if( !p_item )
{
vlc_object_release( p_playlist );
- // vlc_mutex_unlock(&p_playlist->object_lock );
continue;
}
- i_size = p_playlist->i_size;
- i_index = p_playlist->i_index+1;
- // vlc_mutex_unlock(&p_playlist->object_lock );
vlc_object_release( p_playlist );
psz_display = (char *)malloc( sizeof(char )*
(strlen( item.psz_name ) +
MSTRTIME_MAX_SIZE + 2+6 + 10 +10 ));
- sprintf( psz_display," %i/%i - %s %s",
- i_index,i_size, item.psz_name, psz_duration);
+ sprintf( psz_display,"%s %s",
+ item.psz_name, psz_duration);
}
/* Display */
interface/interface.c \
interface/intf_eject.c \
interface/interaction.c \
- playlist/playlist.c \
+ playlist/thread.c \
+ playlist/control.c \
+ playlist/engine.c \
playlist/sort.c \
playlist/loadsave.c \
- playlist/view.c \
+ playlist/tree.c \
playlist/item.c \
- playlist/item-ext.c \
+ playlist/search.c \
playlist/services_discovery.c \
+ input/item.c \
input/access.c \
input/clock.c \
input/control.c \
vlc_mutex_lock( &p_playlist->object_lock );
if( p_playlist->i_size )
{
- int i_index;
int i_from;
char *psz_from = NULL;
psz_from = ( char * )malloc( 20 * sizeof( char ) );
- if( psz_from )
+ if( psz_from && p_playlist->status.p_item )
{
i_from = mediacontrol_position2microsecond( p_playlist->p_input, a_position ) / 1000000;
- i_index = p_playlist->i_index;
- if( i_index < 0 )
- {
- /* We know that there is at least 1 element, since i_size != 0 */
- i_index = 0;
- }
-
/* Set start time */
snprintf( psz_from, 20, "start-time=%i", i_from );
- playlist_ItemAddOption( p_playlist->pp_items[i_index], psz_from );
+ playlist_ItemAddOption( p_playlist->status.p_item, psz_from );
free( psz_from );
}
for( i_index = 0 ; i_index < i_playlist_size ; i_index++ )
{
- retval->data[i_index] = strdup( p_playlist->pp_items[i_index]->input.psz_uri );
+ retval->data[i_index] = strdup( p_playlist->pp_items[i_index]->p_input->psz_uri );
}
vlc_mutex_unlock( &p_playlist->object_lock );
}
if( i_id > 0 )
{
- /* Always use the current view when using libvlc */
- playlist_view_t *p_view;
- playlist_item_t *p_item;
-
- if( p_instance->p_playlist->status.i_view == -1 )
- {
- playlist_Control( p_instance->p_playlist, PLAYLIST_GOTO,
- i_id );
- }
- p_view = playlist_ViewFind( p_instance->p_playlist,
- p_instance->p_playlist->status.i_view );
- if( !p_view )
- {
- libvlc_exception_raise( p_exception,
- "Unable to find current playlist view ");
- return;
- }
-
- p_item = playlist_ItemGetById( p_instance->p_playlist, i_id );
+ playlist_item_t *p_item = playlist_ItemGetById( p_instance->p_playlist, i_id );
if( !p_item )
{
libvlc_exception_raise( p_exception, "Unable to find item " );
return;
}
-
playlist_Control( p_instance->p_playlist, PLAYLIST_VIEWPLAY,
- p_instance->p_playlist->status.i_view,
- p_view->p_root, p_item );
+ p_instance->p_playlist->status.p_node, p_item );
}
else
{
msg_Dbg( p_input, "EsOutProgramMeta: number=%d", i_group );
sprintf( psz_cat, "%s %d", _("Program"), i_group );
- for( i = 0; i < p_meta->i_meta; i++ )
- {
- msg_Dbg( p_input, " - %s = %s", p_meta->name[i], p_meta->value[i] );
-
- input_Control( p_input, INPUT_ADD_INFO, psz_cat,
- _(p_meta->name[i]), "%s", p_meta->value[i] );
- if( !strcasecmp( p_meta->name[i], "Name" ) )
- psz_name = p_meta->value[i];
- else if( !strcasecmp( p_meta->name[i], "Provider" ) )
- psz_provider = p_meta->value[i];
- else if( !strcasecmp( p_meta->name[i], VLC_META_NOW_PLAYING ) )
- psz_now_playing = p_meta->value[i];
- }
+// if( p_meta->psz_provider) psz_provider = p_meta->psz_provider;
+ if( p_meta->psz_nowplaying ) psz_now_playing = p_meta->psz_nowplaying;
if( !psz_name && !psz_now_playing )
{
static void ControlReduce( input_thread_t * );
static vlc_bool_t Control( input_thread_t *, int, vlc_value_t );
-
static int UpdateFromAccess( input_thread_t * );
static int UpdateFromDemux( input_thread_t * );
static int UpdateMeta( input_thread_t *, vlc_bool_t );
static void SlaveDemux( input_thread_t *p_input );
static void SlaveSeek( input_thread_t *p_input );
-static vlc_meta_t *InputMetaUser( input_thread_t *p_input );
+static void InputMetaUser( input_thread_t *p_input );
/*****************************************************************************
* This function creates a new input, and returns a pointer
p_input->input.b_eof = VLC_FALSE;
p_input->input.i_cr_average = 0;
+ p_input->input.p_item->p_meta = vlc_meta_New();
stats_ReinitInputStats( p_item->p_stats );
/* No slave */
/* Unload all modules */
if( p_input->p_es_out ) input_EsOutDelete( p_input->p_es_out );
- /* Delete meta */
- if( p_input->p_meta ) vlc_meta_Delete( p_input->p_meta );
-
vlc_object_detach( p_input );
vlc_object_destroy( p_input );
char *psz_subtitle;
vlc_value_t val;
double f_fps;
- vlc_meta_t *p_meta, *p_meta_tmp;
+ vlc_meta_t *p_meta;
int i_es_out_mode;
int i, i_delay;
}
}
+ p_meta = p_input->input.p_item->p_meta;
/* Get meta data from users */
- p_meta_tmp = InputMetaUser( p_input );
-
+ InputMetaUser( p_input );
/* Get meta data from master input */
- if( demux2_Control( p_input->input.p_demux, DEMUX_GET_META, &p_meta ) )
- p_meta = NULL;
-
- /* Merge them */
- if( p_meta == NULL )
- {
- p_meta = p_meta_tmp;
- }
- else if( p_meta_tmp )
- {
- vlc_meta_Merge( p_meta, p_meta_tmp );
- vlc_meta_Delete( p_meta_tmp );
- }
+ demux2_Control( p_input->input.p_demux, DEMUX_GET_META, p_meta );
/* Access_file does not give any meta, and there are no slave */
if( !b_quick )
{
- if( !p_input->input.p_access ||
+ if( p_input->input.p_access )
access2_Control( p_input->input.p_access, ACCESS_GET_META,
- &p_meta_tmp))
- p_meta_tmp = NULL;
-
- if( p_meta == NULL )
- {
- p_meta = p_meta_tmp;
- }
- else if( p_meta_tmp )
- {
- vlc_meta_Merge( p_meta, p_meta_tmp );
- vlc_meta_Delete( p_meta_tmp );
- }
+ p_meta );
/* Get meta data from slave input */
for( i = 0; i < p_input->i_slave; i++ )
{
- vlc_meta_t *p_meta_slave;
-
- if( !demux2_Control( p_input->slave[i]->p_demux,
- DEMUX_GET_META, &p_meta_slave ) )
+ demux2_Control( p_input->slave[i]->p_demux,
+ DEMUX_GET_META, p_meta );
+ if( p_input->slave[i]->p_access )
{
- if( p_meta == NULL )
- {
- p_meta = p_meta_slave;
- }
- else if( p_meta_slave )
- {
- vlc_meta_Merge( p_meta, p_meta_slave );
- vlc_meta_Delete( p_meta_slave );
- }
- }
-
- if( p_input->slave[i]->p_access &&
- !access2_Control( p_input->slave[i]->p_access,
- ACCESS_GET_META, &p_meta_slave ) )
- {
- if( p_meta == NULL )
- {
- p_meta = p_meta_slave;
- }
- else if( p_meta_slave )
- {
- vlc_meta_Merge( p_meta, p_meta_slave );
- vlc_meta_Delete( p_meta_slave );
- }
+ access2_Control( p_input->slave[i]->p_access,
+ ACCESS_GET_META, p_meta );
}
}
}
- p_input->p_meta = p_meta;
UpdateMeta( p_input, b_quick );
if( !b_quick )
vlc_object_release( p_pl );
}
- /* Delete meta */
- if( p_input->p_meta )
- vlc_meta_Delete( p_input->p_meta );
-
/* Tell we're dead */
p_input->b_dead = VLC_TRUE;
}
if( !InputSourceInit( p_input, slave, val.psz_string, NULL,
VLC_FALSE ) )
{
- vlc_meta_t *p_meta_new = NULL;
- vlc_meta_t *p_meta;
+ vlc_meta_t *p_meta = p_input->input.p_item->p_meta;
int64_t i_time;
/* Add the slave */
break;
}
-
/* Get meta (access and demux) */
- if( access2_Control( slave->p_access,
- ACCESS_GET_META, &p_meta_new ) )
- p_meta_new = NULL;
- if( !demux2_Control( slave->p_demux,
- DEMUX_GET_META, &p_meta ) )
- {
- if( p_meta_new )
- {
- vlc_meta_Merge( p_meta_new, p_meta );
- vlc_meta_Delete( p_meta );
- }
- else
- {
- p_meta_new = p_meta;
- }
- }
- /* Update meta */
- if( p_meta_new )
- {
- if( p_input->p_meta )
- {
- vlc_meta_Merge( p_input->p_meta, p_meta_new );
- vlc_meta_Delete( p_meta_new );
- }
- else
- {
- p_input->p_meta = p_meta_new;
- }
- UpdateMeta( p_input, VLC_FALSE );
- }
+ access2_Control( slave->p_access, ACCESS_GET_META,
+ p_meta );
+ demux2_Control( slave->p_demux, DEMUX_GET_META, p_meta );
+ UpdateMeta( p_input, VLC_FALSE );
TAB_APPEND( p_input->i_slave, p_input->slave, slave );
}
{
v.i_int = p_access->info.i_seekpoint;
var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &v, NULL);
-
p_access->info.i_update &= ~INPUT_UPDATE_SEEKPOINT;
}
if( p_access->info.i_update & INPUT_UPDATE_META )
{
/* TODO maybe multi - access ? */
- vlc_meta_t *p_meta;
- if( !access2_Control( p_input->input.p_access,ACCESS_GET_META,&p_meta))
- {
- if( p_input->p_meta )
- {
- vlc_meta_Merge( p_input->p_meta, p_meta );
- vlc_meta_Delete( p_meta );
- }
- else
- {
- p_input->p_meta = p_meta;
- }
-
- UpdateMeta( p_input, VLC_FALSE );
- var_SetBool( p_input, "item-change", p_input->input.p_item->i_id );
- }
+ vlc_meta_t *p_meta = p_input->input.p_item->p_meta;
+ access2_Control( p_input->input.p_access,ACCESS_GET_META, p_meta );
+ UpdateMeta( p_input, VLC_FALSE );
+ var_SetBool( p_input, "item-change", p_input->input.p_item->i_id );
p_access->info.i_update &= ~INPUT_UPDATE_META;
}
*****************************************************************************/
static int UpdateMeta( input_thread_t *p_input, vlc_bool_t b_quick )
{
- vlc_meta_t *p_meta = p_input->p_meta;
- int i;
-
- if( !p_meta || p_meta->i_meta == 0 )
+ vlc_meta_t *p_meta = p_input->input.p_item->p_meta;
+ if( !p_meta )
return VLC_SUCCESS;
- if( !b_quick ) msg_Dbg( p_input, "meta information:" );
- for( i = 0; i < p_meta->i_meta; i++ )
- {
- if( !b_quick )
- msg_Dbg( p_input, " - '%s' = '%s'",
- _(p_meta->name[i]), p_meta->value[i] );
-
- if( !strcmp(p_meta->name[i], _(VLC_META_TITLE)) && p_meta->value[i] &&
- !p_input->input.p_item->b_fixed_name )
- input_Control( p_input, INPUT_SET_NAME, p_meta->value[i] );
-
- if( !strcmp( p_meta->name[i], _(VLC_META_AUTHOR) ) )
- input_Control( p_input, INPUT_ADD_INFO, _("General"),
- _(VLC_META_AUTHOR), p_meta->value[i] );
-
- input_Control( p_input, INPUT_ADD_INFO, _(VLC_META_INFO_CAT),
- _(p_meta->name[i]), "%s", p_meta->value[i] );
- }
-
- for( i = 0; i < p_meta->i_track; i++ )
- {
- vlc_meta_t *tk = p_meta->track[i];
- int j;
-
- if( tk->i_meta > 0 )
- {
- char *psz_cat = malloc( strlen(_("Stream")) + 10 );
+ if( p_meta->psz_title && !p_input->input.p_item->b_fixed_name )
+ input_Control( p_input, INPUT_SET_NAME, p_meta->psz_title );
- msg_Dbg( p_input, " - track[%d]:", i );
-
- sprintf( psz_cat, "%s %d", _("Stream"), i );
- for( j = 0; j < tk->i_meta; j++ )
- {
- msg_Dbg( p_input, " - '%s' = '%s'", _(tk->name[j]),
- tk->value[j] );
-
- input_Control( p_input, INPUT_ADD_INFO, psz_cat,
- _(tk->name[j]), "%s", tk->value[j] );
- }
- }
- }
-
- if( p_input->p_sout && p_input->p_sout->p_meta == NULL )
- {
- p_input->p_sout->p_meta = vlc_meta_Duplicate( p_meta );
- }
+ /** \todo handle sout meta */
return VLC_SUCCESS;
}
/*****************************************************************************
* InputMetaUser:
*****************************************************************************/
-static vlc_meta_t *InputMetaUser( input_thread_t *p_input )
+static void InputMetaUser( input_thread_t *p_input )
{
- vlc_meta_t *p_meta;
+ vlc_meta_t *p_meta = p_input->input.p_item->p_meta;
vlc_value_t val;
- if( ( p_meta = vlc_meta_New() ) == NULL )
- return NULL;
+ if( !p_meta ) return;
/* Get meta information from user */
-#define GET_META( c, s ) \
+#define GET_META( field, s ) \
var_Get( p_input, (s), &val ); \
- if( *val.psz_string ) \
- vlc_meta_Add( p_meta, _(c), val.psz_string ); \
+ if( *val.psz_string ) { \
+ if( p_meta->psz_ ## field ) free ( p_meta->psz_ ## field ); \
+ p_meta->psz_ ## field = strdup( val.psz_string ); \
+ } \
free( val.psz_string )
- GET_META( VLC_META_TITLE, "meta-title" );
- GET_META( VLC_META_AUTHOR, "meta-author" );
- GET_META( VLC_META_ARTIST, "meta-artist" );
- GET_META( VLC_META_GENRE, "meta-genre" );
- GET_META( VLC_META_COPYRIGHT, "meta-copyright" );
- GET_META( VLC_META_DESCRIPTION, "meta-description" );
- GET_META( VLC_META_DATE, "meta-date" );
- GET_META( VLC_META_URL, "meta-url" );
+ GET_META( title, "meta-title" );
+ GET_META( author, "meta-author" );
+ GET_META( artist, "meta-artist" );
+ GET_META( genre, "meta-genre" );
+ GET_META( copyright, "meta-copyright" );
+ GET_META( description, "meta-description" );
+ GET_META( date, "meta-date" );
+ GET_META( url, "meta-url" );
#undef GET_META
-
- return p_meta;
}
/*****************************************************************************
psz_source, *pi_title_start, *pi_chapter_start,
*pi_title_end, *pi_chapter_end );
}
-
-
-/***********************************************************************
- * Info management functions
- ***********************************************************************/
-/**
- * Get a info item from a given category in a given input item.
- *
- * \param p_i The input item to get info from
- * \param psz_cat String representing the category for the info
- * \param psz_name String representing the name of the desired info
- * \return A pointer to the string with the given info if found, or an
- * empty string otherwise. The caller should free the returned
- * pointer.
- */
-char *vlc_input_item_GetInfo( input_item_t *p_i,
- const char *psz_cat,
- const char *psz_name )
-{
- int i,j;
-
- vlc_mutex_lock( &p_i->lock );
-
- for( i = 0 ; i< p_i->i_categories ; i++ )
- {
- info_category_t *p_cat = p_i->pp_categories[i];
-
- if( !psz_cat || strcmp( p_cat->psz_name, psz_cat ) )
- continue;
-
- for( j = 0; j < p_cat->i_infos ; j++ )
- {
- if( !strcmp( p_cat->pp_infos[j]->psz_name, psz_name ) )
- {
- char *psz_ret = strdup( p_cat->pp_infos[j]->psz_value );
- vlc_mutex_unlock( &p_i->lock );
- return psz_ret;
- }
- }
- }
- vlc_mutex_unlock( &p_i->lock );
- return strdup( "" );
-}
-
-int vlc_input_item_AddInfo( input_item_t *p_i,
- const char *psz_cat,
- const char *psz_name,
- const char *psz_format, ... )
-{
- va_list args;
- int i;
- info_t *p_info = NULL;
- info_category_t *p_cat = NULL ;
-
- vlc_mutex_lock( &p_i->lock );
-
- for( i = 0 ; i < p_i->i_categories ; i ++ )
- {
- if( !strcmp( p_i->pp_categories[i]->psz_name, psz_cat ) )
- {
- p_cat = p_i->pp_categories[i];
- break;
- }
- }
- if( !p_cat )
- {
- if( !(p_cat = (info_category_t *)malloc( sizeof(info_category_t) )) )
- {
- vlc_mutex_unlock( &p_i->lock );
- return VLC_EGENERIC;
- }
- p_cat->psz_name = strdup( psz_cat );
- p_cat->i_infos = 0;
- p_cat->pp_infos = 0;
- INSERT_ELEM( p_i->pp_categories, p_i->i_categories, p_i->i_categories,
- p_cat );
- }
-
- for( i = 0; i< p_cat->i_infos; i++ )
- {
- if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
- {
- p_info = p_cat->pp_infos[i];
- break;
- }
- }
-
- if( !p_info )
- {
- if( ( p_info = (info_t *)malloc( sizeof( info_t ) ) ) == NULL )
- {
- vlc_mutex_unlock( &p_i->lock );
- return VLC_EGENERIC;
- }
- INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );
- p_info->psz_name = strdup( psz_name );
- }
- else
- {
- if( p_info->psz_value ) free( p_info->psz_value );
- }
-
- va_start( args, psz_format );
- vasprintf( &p_info->psz_value, psz_format, args);
- va_end( args );
-
- vlc_mutex_unlock( &p_i->lock );
-
- return VLC_SUCCESS;
-}
-
--- /dev/null
+/*****************************************************************************
+ * item.c: input_item management
+ *****************************************************************************
+ * Copyright (C) 1998-2004 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+#include "vlc_playlist.h"
+#include "vlc_interface.h"
+
+static void GuessType( input_item_t *p_item );
+
+/**
+ * Get a info item from a given category in a given input item.
+ *
+ * \param p_i The input item to get info from
+ * \param psz_cat String representing the category for the info
+ * \param psz_name String representing the name of the desired info
+ * \return A pointer to the string with the given info if found, or an
+ * empty string otherwise. The caller should free the returned
+ * pointer.
+ */
+char *vlc_input_item_GetInfo( input_item_t *p_i,
+ const char *psz_cat,
+ const char *psz_name )
+{
+ int i,j;
+
+ vlc_mutex_lock( &p_i->lock );
+
+ for( i = 0 ; i< p_i->i_categories ; i++ )
+ {
+ info_category_t *p_cat = p_i->pp_categories[i];
+
+ if( !psz_cat || strcmp( p_cat->psz_name, psz_cat ) )
+ continue;
+
+ for( j = 0; j < p_cat->i_infos ; j++ )
+ {
+ if( !strcmp( p_cat->pp_infos[j]->psz_name, psz_name ) )
+ {
+ char *psz_ret = strdup( p_cat->pp_infos[j]->psz_value );
+ vlc_mutex_unlock( &p_i->lock );
+ return psz_ret;
+ }
+ }
+ }
+ vlc_mutex_unlock( &p_i->lock );
+ return strdup( "" );
+}
+
+static void vlc_input_item_Destroy ( gc_object_t *p_this )
+{
+ vlc_object_t *p_obj = (vlc_object_t *)p_this->p_destructor_arg;
+ int i, i_top, i_bottom;
+ input_item_t *p_input = (input_item_t *) p_this;
+
+ playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_obj,
+ VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+
+ fprintf( stderr, "Destroying item %s\n", p_input->psz_name );
+
+
+ vlc_input_item_Clean( p_input );
+
+ if( p_playlist )
+ {
+ i_bottom = 0; i_top = p_playlist->i_input_items - 1;
+ i = i_top / 2;
+ while( p_playlist->pp_input_items[i]->i_id != p_input->i_id &&
+ i_top > i_bottom )
+ {
+ if( p_playlist->pp_input_items[i]->i_id < p_input->i_id )
+ i_bottom = i + 1;
+ else
+ i_top = i -1;
+
+ i = i_bottom + ( i_top - i_bottom ) / 2;
+
+ }
+ if( p_playlist->pp_input_items[i]->i_id == p_input->i_id )
+ {
+ REMOVE_ELEM( p_playlist->pp_input_items,
+ p_playlist->i_input_items, i );
+ }
+ vlc_object_release( p_playlist );
+ }
+ free( p_input );
+}
+
+int vlc_input_item_AddInfo( input_item_t *p_i,
+ const char *psz_cat,
+ const char *psz_name,
+ const char *psz_format, ... )
+{
+ va_list args;
+ int i;
+ info_t *p_info = NULL;
+ info_category_t *p_cat = NULL ;
+
+ vlc_mutex_lock( &p_i->lock );
+
+ for( i = 0 ; i < p_i->i_categories ; i ++ )
+ {
+ if( !strcmp( p_i->pp_categories[i]->psz_name, psz_cat ) )
+ {
+ p_cat = p_i->pp_categories[i];
+ break;
+ }
+ }
+ if( !p_cat )
+ {
+ if( !(p_cat = (info_category_t *)malloc( sizeof(info_category_t) )) )
+ {
+ vlc_mutex_unlock( &p_i->lock );
+ return VLC_EGENERIC;
+ }
+ p_cat->psz_name = strdup( psz_cat );
+ p_cat->i_infos = 0;
+ p_cat->pp_infos = 0;
+ INSERT_ELEM( p_i->pp_categories, p_i->i_categories, p_i->i_categories,
+ p_cat );
+ }
+
+ for( i = 0; i< p_cat->i_infos; i++ )
+ {
+ if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
+ {
+ p_info = p_cat->pp_infos[i];
+ break;
+ }
+ }
+
+ if( !p_info )
+ {
+ if( ( p_info = (info_t *)malloc( sizeof( info_t ) ) ) == NULL )
+ {
+ vlc_mutex_unlock( &p_i->lock );
+ return VLC_EGENERIC;
+ }
+ INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );
+ p_info->psz_name = strdup( psz_name );
+ }
+ else
+ {
+ if( p_info->psz_value ) free( p_info->psz_value );
+ }
+
+ va_start( args, psz_format );
+ vasprintf( &p_info->psz_value, psz_format, args);
+ va_end( args );
+
+ vlc_mutex_unlock( &p_i->lock );
+
+ return VLC_SUCCESS;
+}
+
+void vlc_input_item_AddOption( input_item_t *p_input,
+ const char *psz_option )
+{
+ if( !psz_option ) return;
+ vlc_mutex_lock( &p_input->lock );
+ INSERT_ELEM( p_input->ppsz_options, p_input->i_options,
+ p_input->i_options, strdup( psz_option ) );
+ vlc_mutex_unlock( &p_input->lock );
+};
+
+
+input_item_t *input_ItemGetById( playlist_t *p_playlist, int i_id )
+{
+ int i, i_top, i_bottom;
+ i_bottom = 0; i_top = p_playlist->i_input_items -1;
+ i = i_top /2 ;
+ while( p_playlist->pp_input_items[i]->i_id != i_id &&
+ i_top > i_bottom )
+ {
+ if( p_playlist->pp_input_items[i]->i_id < i_id )
+ i_bottom = i + 1;
+ else
+ i_top = i - 1;
+ i = i_bottom + ( i_top - i_bottom ) / 2;
+ }
+ if( p_playlist->pp_input_items[i]->i_id == i_id )
+ {
+ return p_playlist->pp_input_items[i];
+ }
+ return NULL;
+}
+
+input_item_t *__input_ItemNewExt( vlc_object_t *p_obj, const char *psz_uri,
+ const char *psz_name, int i_options,
+ const char **ppsz_options, int i_duration )
+{
+ return input_ItemNewWithType( p_obj, psz_uri, psz_name,
+ i_options, ppsz_options,
+ i_duration, ITEM_TYPE_UNKNOWN );
+}
+
+
+input_item_t *input_ItemNewWithType( vlc_object_t *p_obj, const char *psz_uri,
+ const char *psz_name, int i_options,
+ const char **ppsz_options, int i_duration,
+ int i_type )
+{
+ /* FIXME DON'T SEARCH PLAYLIST */
+ /* FIXME SHOULD LOCK */
+ input_item_t *p_input = (input_item_t *)malloc( sizeof( input_item_t ) );
+ playlist_t *p_playlist = (playlist_t *) vlc_object_find( p_obj,
+ VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+
+ vlc_input_item_Init( p_obj, p_input );
+ vlc_gc_init( p_input, vlc_input_item_Destroy, (void *)p_obj );
+
+ p_input->i_id = ++p_playlist->i_last_input_id;
+
+ INSERT_ELEM( p_playlist->pp_input_items, p_playlist->i_input_items,
+ p_playlist->i_input_items, p_input );
+ vlc_object_release( p_playlist );
+
+ p_input->b_fixed_name = VLC_FALSE;
+
+ if( psz_uri )
+ p_input->psz_uri = strdup( psz_uri );
+ else
+ p_input->psz_uri = NULL;
+
+ if( psz_name != NULL )
+ p_input->psz_name = strdup( psz_name );
+ else
+ p_input->psz_name = strdup ( p_input->psz_uri );
+
+ p_input->i_type = i_type;
+
+ if( p_input->i_type == ITEM_TYPE_UNKNOWN )
+ GuessType( p_input );
+
+ p_input->i_duration = i_duration;
+ p_input->ppsz_options = NULL;
+
+ for( p_input->i_options = 0; p_input->i_options < i_options;
+ p_input->i_options++ )
+ {
+ if( !p_input->i_options )
+ {
+ p_input->ppsz_options = malloc( i_options * sizeof(char *) );
+ if( !p_input->ppsz_options ) break;
+ }
+ p_input->ppsz_options[p_input->i_options] =
+ strdup( ppsz_options[p_input->i_options] );
+ }
+ return p_input;
+}
+
+/* Guess the type of the item using the beginning of the mrl */
+static void GuessType( input_item_t *p_item)
+{
+ int i;
+ static struct { char *psz_search; int i_type; } types_array[] =
+ {
+ { "http", ITEM_TYPE_NET },
+ { "dvd", ITEM_TYPE_DISC },
+ { "cdda", ITEM_TYPE_CDDA },
+ { "mms", ITEM_TYPE_NET },
+ { "rtsp", ITEM_TYPE_NET },
+ { "udp", ITEM_TYPE_NET },
+ { "rtp", ITEM_TYPE_NET },
+ { "vcd", ITEM_TYPE_DISC },
+ { "v4l", ITEM_TYPE_CARD },
+ { "dshow", ITEM_TYPE_CARD },
+ { "pvr", ITEM_TYPE_CARD },
+ { "dvb", ITEM_TYPE_CARD },
+ { "qpsk", ITEM_TYPE_CARD },
+ { "sdp", ITEM_TYPE_NET },
+ { NULL, 0 }
+ };
+
+#if 0 /* Unused */
+ static struct { char *psz_search; int i_type; } exts_array[] =
+ {
+ { "mp3", ITEM_TYPE_AFILE },
+ { NULL, 0 }
+ };
+#endif
+
+ for( i = 0; types_array[i].psz_search != NULL; i++ )
+ {
+ if( !strncmp( p_item->psz_uri, types_array[i].psz_search,
+ strlen( types_array[i].psz_search ) ) )
+ {
+ p_item->i_type = types_array[i].i_type;
+ return;
+ }
+ }
+ p_item->i_type = ITEM_TYPE_VFILE;
+}
/*
* Initialize playlist and get commandline files
*/
- p_playlist = playlist_Create( p_vlc );
+ p_playlist = playlist_ThreadCreate( p_vlc );
if( !p_playlist )
{
msg_Err( p_vlc, "playlist initialization failed" );
{
vlc_object_detach( p_playlist );
vlc_object_release( p_playlist );
- playlist_Destroy( p_playlist );
+ playlist_ThreadDestroy( p_playlist );
}
/*
if( p_playlist == NULL )
{
msg_Dbg( p_vlc, "no playlist present, creating one" );
- p_playlist = playlist_Create( p_vlc );
+ p_playlist = playlist_ThreadCreate( p_vlc );
if( p_playlist == NULL )
{
vlc_object_yield( p_playlist );
}
- i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
+ i_err = playlist_PlaylistAddExt( p_playlist, psz_target, psz_target,
i_mode, i_pos, -1, ppsz_options, i_options);
vlc_object_release( p_playlist );
*/
int VLC_PlaylistIndex( int i_object )
{
- int i_index;
- playlist_t * p_playlist;
- vlc_t *p_vlc = vlc_current_object( i_object );
-
- /* Check that the handle is valid */
- if( !p_vlc )
- {
- return VLC_ENOOBJ;
- }
-
- p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
-
- if( !p_playlist )
- {
- if( i_object ) vlc_object_release( p_vlc );
- return VLC_ENOOBJ;
- }
-
- i_index = p_playlist->i_index;
- vlc_object_release( p_playlist );
-
- if( i_object ) vlc_object_release( p_vlc );
- return i_index;
+ printf( "This function is deprecated and should not be used anymore" );
+ return -1;
}
/**
*****************************************************************************/
int VLC_PlaylistClear( int i_object )
{
- int i_err;
playlist_t * p_playlist;
vlc_t *p_vlc = vlc_current_object( i_object );
return VLC_ENOOBJ;
}
- i_err = playlist_Clear( p_playlist );
+ playlist_Clear( p_playlist );
vlc_object_release( p_playlist );
if( i_object ) vlc_object_release( p_vlc );
- return i_err;
+ return VLC_SUCCESS;
}
/**
--- /dev/null
+/*****************************************************************************
+ * control.c : Hanle control of the playlist & running through it
+ *****************************************************************************
+ * Copyright (C) 1999-2004 the VideoLAN team
+ * $Id: /local/vlc/0.8.6-playlist-vlm/src/playlist/playlist.c 13741 2006-03-21T19:29:39.792444Z zorglub $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ * Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+#include "vlc_playlist.h"
+
+#define PLAYLIST_DEBUG 1
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+int PlaylistVAControl( playlist_t * p_playlist, int i_query, va_list args );
+
+void PreparseEnqueueItemSub( playlist_t *, playlist_item_t * );
+
+playlist_item_t *playlist_RecursiveFindLast(playlist_t *p_playlist,
+ playlist_item_t *p_node );
+
+/*****************************************************************************
+ * Playlist control
+ *****************************************************************************/
+
+/**
+ * Do a playlist action. Should be entered without playlist lock
+ * \see playlist_Control
+ */
+int playlist_LockControl( playlist_t * p_playlist, int i_query, ... )
+{
+ va_list args;
+ int i_result;
+ va_start( args, i_query );
+ vlc_mutex_lock( &p_playlist->object_lock );
+ i_result = PlaylistVAControl( p_playlist, i_query, args );
+ va_end( args );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ return i_result;
+}
+
+/**
+ * Do a playlist action.
+ * If there is something in the playlist then you can do playlist actions.
+ * Should be entered with playlist lock. See include/vlc_playlist.h for
+ * possible queries
+ *
+ * \param p_playlist the playlist to do the command on
+ * \param i_query the command to do
+ * \param variable number of arguments
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_Control( playlist_t * p_playlist, int i_query, ... )
+{
+ va_list args;
+ int i_result;
+ va_start( args, i_query );
+ i_result = PlaylistVAControl( p_playlist, i_query, args );
+ va_end( args );
+
+ return i_result;
+}
+
+int PlaylistVAControl( playlist_t * p_playlist, int i_query, va_list args )
+{
+ int i_view;
+ playlist_item_t *p_item, *p_node;
+ vlc_value_t val;
+
+ if( p_playlist->i_size <= 0 )
+ {
+ return VLC_EGENERIC;
+ }
+
+ switch( i_query )
+ {
+ case PLAYLIST_STOP:
+ p_playlist->request.i_status = PLAYLIST_STOPPED;
+ p_playlist->request.b_request = VLC_TRUE;
+ p_playlist->request.p_item = NULL;
+ break;
+
+ case PLAYLIST_ITEMPLAY:
+ p_item = (playlist_item_t *)va_arg( args, playlist_item_t * );
+ if ( p_item == NULL || p_item->p_input->psz_uri == NULL )
+ return VLC_EGENERIC;
+ p_playlist->request.i_status = PLAYLIST_RUNNING;
+ p_playlist->request.i_skip = 0;
+ p_playlist->request.b_request = VLC_TRUE;
+ p_playlist->request.p_item = p_item;
+ p_playlist->request.p_node = p_playlist->status.p_node;
+ break;
+
+ case PLAYLIST_VIEWPLAY:
+ i_view = (int) va_arg( args, playlist_item_t *);
+ p_node = (playlist_item_t *)va_arg( args, playlist_item_t * );
+ p_item = (playlist_item_t *)va_arg( args, playlist_item_t * );
+ if ( p_node == NULL )
+ {
+ p_playlist->status.i_status = PLAYLIST_STOPPED;
+ p_playlist->request.b_request = VLC_TRUE;
+ msg_Err( p_playlist, "null node" );
+ return VLC_SUCCESS;
+ }
+ p_playlist->request.i_status = PLAYLIST_RUNNING;
+ p_playlist->request.i_skip = 0;
+ p_playlist->request.b_request = VLC_TRUE;
+ p_playlist->request.p_node = p_node;
+ p_playlist->request.p_item = p_item;
+ break;
+
+ case PLAYLIST_PLAY:
+ p_playlist->request.i_status = PLAYLIST_RUNNING;
+ p_playlist->request.b_request = VLC_TRUE;
+
+ if( p_playlist->p_input )
+ {
+ val.i_int = PLAYING_S;
+ var_Set( p_playlist->p_input, "state", val );
+ break;
+ }
+ p_playlist->request.p_node = p_playlist->status.p_node;
+ p_playlist->request.p_item = p_playlist->status.p_item;
+ p_playlist->request.i_skip = 0;
+ break;
+
+ case PLAYLIST_AUTOPLAY:
+ p_playlist->status.i_status = PLAYLIST_RUNNING;
+ p_playlist->status.p_node = p_playlist->p_local_category;
+ p_playlist->request.b_request = VLC_FALSE;
+ break;
+
+ case PLAYLIST_PAUSE:
+ val.i_int = 0;
+ if( p_playlist->p_input )
+ var_Get( p_playlist->p_input, "state", &val );
+
+ if( val.i_int == PAUSE_S )
+ {
+ p_playlist->status.i_status = PLAYLIST_RUNNING;
+ if( p_playlist->p_input )
+ {
+ val.i_int = PLAYING_S;
+ var_Set( p_playlist->p_input, "state", val );
+ }
+ }
+ else
+ {
+ p_playlist->status.i_status = PLAYLIST_PAUSED;
+ if( p_playlist->p_input )
+ {
+ val.i_int = PAUSE_S;
+ var_Set( p_playlist->p_input, "state", val );
+ }
+ }
+ break;
+
+ case PLAYLIST_SKIP:
+ p_playlist->request.p_node = p_playlist->status.p_node;
+ p_playlist->request.p_item = p_playlist->status.p_item;
+ p_playlist->request.i_skip = (int) va_arg( args, int );
+ p_playlist->request.b_request = VLC_TRUE;
+ break;
+
+ default:
+ msg_Err( p_playlist, "unknown playlist query" );
+ return VLC_EBADVAR;
+ break;
+ }
+
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Preparse control
+ *****************************************************************************/
+/** Enqueue an item for preparsing */
+int playlist_PreparseEnqueue( playlist_t *p_playlist,
+ input_item_t *p_item )
+{
+ vlc_mutex_lock( &p_playlist->p_preparse->object_lock );
+ vlc_gc_incref( p_item );
+ INSERT_ELEM( p_playlist->p_preparse->pp_waiting,
+ p_playlist->p_preparse->i_waiting,
+ p_playlist->p_preparse->i_waiting,
+ p_item );
+ vlc_mutex_unlock( &p_playlist->p_preparse->object_lock );
+ return VLC_SUCCESS;
+}
+
+/** Enqueue a playlist item or a node for peparsing.
+ * This function should be entered without playlist and preparser locks */
+int playlist_PreparseEnqueueItem( playlist_t *p_playlist,
+ playlist_item_t *p_item )
+{
+ vlc_mutex_lock( &p_playlist->object_lock );
+ vlc_mutex_lock( &p_playlist->p_preparse->object_lock );
+ PreparseEnqueueItemSub( p_playlist, p_item );
+ vlc_mutex_unlock( &p_playlist->p_preparse->object_lock );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ return VLC_SUCCESS;
+}
+
+void PreparseEnqueueItemSub( playlist_t *p_playlist,
+ playlist_item_t *p_item )
+{
+ int i;
+ if( p_item->i_children == -1 )
+ {
+ vlc_gc_incref( p_item );
+ INSERT_ELEM( p_playlist->p_preparse->pp_waiting,
+ p_playlist->p_preparse->i_waiting,
+ p_playlist->p_preparse->i_waiting,
+ p_item->p_input );
+ }
+ else
+ {
+ for( i = 0; i < p_item->i_children; i++)
+ {
+ PreparseEnqueueItemSub( p_playlist,
+ p_item->pp_children[i] );
+ }
+ }
+}
+
+/*****************************************************************************
+ * Playback logic
+ *****************************************************************************/
+
+/** This function calculates the next playlist item, depending
+ * on the playlist course mode (forward, backward, random, view,...). */
+playlist_item_t * playlist_NextItem( playlist_t *p_playlist )
+{
+ playlist_item_t *p_new = NULL;
+ int i_skip,i;
+
+ vlc_bool_t b_loop = var_GetBool( p_playlist, "loop" );
+ vlc_bool_t b_random = var_GetBool( p_playlist, "random" );
+ vlc_bool_t b_repeat = var_GetBool( p_playlist, "repeat" );
+ vlc_bool_t b_playstop = var_GetBool( p_playlist, "play-and-stop" );
+
+ /* Handle quickly a few special cases */
+
+ /* No items to play */
+ if( p_playlist->i_size == 0 )
+ {
+ msg_Info( p_playlist, "playlist is empty" );
+ return NULL;
+ }
+
+ /* Repeat and play/stop */
+ if( !p_playlist->request.b_request && b_repeat == VLC_TRUE &&
+ p_playlist->status.p_item )
+ {
+ msg_Dbg( p_playlist,"repeating item" );
+ return p_playlist->status.p_item;
+ }
+ if( !p_playlist->request.b_request && b_playstop == VLC_TRUE )
+ {
+ msg_Dbg( p_playlist,"stopping (play and stop)");
+ return NULL;
+ }
+
+ if( !p_playlist->request.b_request && p_playlist->status.p_item &&
+ p_playlist->status.p_item->i_flags & PLAYLIST_SKIP_FLAG )
+ {
+ msg_Dbg( p_playlist, "blocking item, stopping") ;
+ return NULL;
+ }
+
+ /* Random case. This is an exception: if request, but request is skip +- 1
+ * we don't go to next item but select a new random one. */
+ if( b_random )
+ msg_Err( p_playlist, "random unsupported" );
+#if 0
+ &&
+ ( !p_playlist->request.b_request ||
+ ( p_playlist->request.b_request && ( p_playlist->request.p_item == NULL ||
+ p_playlist->request.i_skip == 1 || p_playlist->request.i_skip == -1 ) ) ) )
+ {
+ /* how many items to choose from ? */
+ i_count = 0;
+ for ( i = 0; i < p_playlist->i_size; i++ )
+ {
+ if ( p_playlist->pp_items[i]->p_input->i_nb_played == 0 )
+ i_count++;
+ }
+ /* Nothing left? */
+ if ( i_count == 0 )
+ {
+ /* Don't loop? Exit! */
+ if( !b_loop )
+ return NULL;
+ /* Otherwise reset the counter */
+ for ( i = 0; i < p_playlist->i_size; i++ )
+ {
+ p_playlist->pp_items[i]->p_input->i_nb_played = 0;
+ }
+ i_count = p_playlist->i_size;
+ }
+ srand( (unsigned int)mdate() );
+ i = rand() % i_count + 1 ;
+ /* loop thru the list and count down the unplayed items to the selected one */
+ for ( i_new = 0; i_new < p_playlist->i_size && i > 0; i_new++ )
+ {
+ if ( p_playlist->pp_items[i_new]->p_input->i_nb_played == 0 )
+ i--;
+ }
+ i_new--;
+
+ p_playlist->request.i_skip = 0;
+ p_playlist->request.b_request = VLC_FALSE;
+ return p_playlist->pp_items[i_new];
+ }
+#endif
+
+ /* Start the real work */
+ if( p_playlist->request.b_request )
+ {
+#ifdef PLAYLIST_DEBUG
+ msg_Dbg( p_playlist,"processing request" );
+#endif
+ p_new = p_playlist->request.p_item;
+ i_skip = p_playlist->request.i_skip;
+
+ p_playlist->status.p_node = p_playlist->request.p_node;
+
+ /* If we are asked for a node, take its first item */
+ if( i_skip == 0 &&
+ ( p_new == NULL || p_new->i_children != -1 ) )
+ {
+ i_skip++;
+ }
+
+ if( i_skip > 0 )
+ {
+ for( i = i_skip; i > 0 ; i-- )
+ {
+ p_new = playlist_GetNextEnabledLeaf( p_playlist,
+ p_playlist->request.p_node,
+ p_new );
+ if( p_new == NULL )
+ {
+#ifdef PLAYLIST_DEBUG
+ msg_Dbg( p_playlist, "looping - restarting at beginning "
+ "of node" );
+#endif
+ p_new = playlist_GetNextLeaf( p_playlist,
+ p_playlist->request.p_node,
+ NULL );
+ if( p_new == NULL ) break;
+ }
+ }
+ }
+ else if( i_skip < 0 )
+ {
+ for( i = i_skip; i < 0 ; i++ )
+ {
+ p_new = playlist_GetPrevLeaf( p_playlist,
+ p_playlist->request.p_node,
+ p_new );
+ if( p_new == NULL )
+ {
+#ifdef PLAYLIST_DEBUG
+ msg_Dbg( p_playlist, "looping - restarting at end "
+ "of node" );
+#endif
+ /** \bug This is needed because GetPrevLeaf does not loop
+ * by itself */
+ p_new = playlist_GetLastLeaf( p_playlist,
+ p_playlist->request.p_node );
+ }
+ if( p_new == NULL ) break;
+ }
+ }
+ /* Clear the request */
+ p_playlist->request.b_request = VLC_FALSE;
+ }
+ /* "Automatic" item change ( next ) */
+ else
+ {
+#ifdef PLAYLIST_DEBUG
+ msg_Dbg( p_playlist,"changing item without a request" );
+#endif
+ /* Cant go to next from current item */
+ if( p_playlist->status.p_item &&
+ p_playlist->status.p_item->i_flags & PLAYLIST_SKIP_FLAG )
+ return NULL;
+
+ p_new = playlist_GetNextLeaf( p_playlist,
+ p_playlist->status.p_node,
+ p_playlist->status.p_item );
+ if( p_new == NULL && b_loop )
+ {
+#ifdef PLAYLIST_DEBUG
+ msg_Dbg( p_playlist, "looping" );
+#endif
+ p_new = playlist_GetNextLeaf( p_playlist,
+ p_playlist->status.p_node,
+ NULL );
+ }
+ /* The new item can't be autoselected */
+ if( p_new != NULL && p_new->i_flags & PLAYLIST_SKIP_FLAG )
+ return NULL;
+ }
+ if( p_new == NULL )
+ {
+ msg_Dbg( p_playlist, "did not find something to play" );
+ }
+ return p_new;
+}
+
+/** Start the input for an item */
+int playlist_PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
+{
+ vlc_value_t val;
+ int i_activity = var_GetInteger( p_playlist, "activity") ;
+
+ msg_Dbg( p_playlist, "creating new input thread" );
+
+ p_item->p_input->i_nb_played++;
+ p_playlist->status.p_item = p_item;
+
+ p_playlist->status.i_status = PLAYLIST_RUNNING;
+
+ var_SetInteger( p_playlist, "activity", i_activity +
+ DEFAULT_INPUT_ACTIVITY );
+ p_playlist->p_input = input_CreateThread( p_playlist, p_item->p_input );
+
+ val.i_int = p_item->p_input->i_id;
+ /* unlock the playlist to set the var...mmm */
+ vlc_mutex_unlock( &p_playlist->object_lock);
+ var_Set( p_playlist, "playlist-current", val);
+ vlc_mutex_lock( &p_playlist->object_lock);
+
+ return VLC_SUCCESS;
+}
--- /dev/null
+/*****************************************************************************
+ * engine.c : Run the playlist and handle its control
+ *****************************************************************************
+ * Copyright (C) 1999-2004 the VideoLAN team
+ * $Id: /local/vlc/0.8.6-playlist-vlm/src/playlist/playlist.c 13741 2006-03-21T19:29:39.792444Z zorglub $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ * Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/sout.h>
+#include <vlc/input.h>
+#include "vlc_playlist.h"
+#include "vlc_interaction.h"
+
+#undef PLAYLIST_DEBUG
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void VariablesInit( playlist_t *p_playlist );
+
+/**
+ * Create playlist
+ *
+ * Create a playlist structure.
+ * \param p_parent the vlc object that is to be the parent of this playlist
+ * \return a pointer to the created playlist, or NULL on error
+ */
+playlist_t * playlist_Create( vlc_object_t *p_parent )
+{
+ playlist_t *p_playlist;
+
+ /* Allocate structure */
+ p_playlist = vlc_object_create( p_parent, VLC_OBJECT_PLAYLIST );
+ if( !p_playlist )
+ {
+ msg_Err( p_parent, "out of memory" );
+ return NULL;
+ }
+
+ VariablesInit( p_playlist );
+
+ /* Initialise data structures */
+ vlc_mutex_init( p_playlist, &p_playlist->gc_lock );
+ p_playlist->i_last_playlist_id = 0;
+ p_playlist->i_last_input_id = 0;
+ p_playlist->p_input = NULL;
+
+ p_playlist->i_size = 0;
+ p_playlist->pp_items = NULL;
+ p_playlist->i_all_size = 0;
+ p_playlist->pp_all_items = NULL;
+
+ p_playlist->i_input_items = 0;
+ p_playlist->pp_input_items = NULL;
+
+ p_playlist->p_root_category = playlist_NodeCreate( p_playlist, NULL, NULL);
+ p_playlist->p_root_onelevel = playlist_NodeCreate( p_playlist, NULL, NULL);
+
+ /* Create playlist and media library */
+ p_playlist->p_local_category = playlist_NodeCreate( p_playlist,
+ _( "Playlist" ),p_playlist->p_root_category );
+ p_playlist->p_ml_category = playlist_NodeCreate( p_playlist,
+ _( "Media Library" ), p_playlist->p_root_category );
+ p_playlist->p_local_onelevel = playlist_NodeCreate( p_playlist,
+ _( "Playlist" ), p_playlist->p_root_onelevel );
+ p_playlist->p_ml_onelevel = playlist_NodeCreate( p_playlist,
+ _( "Media Library" ), p_playlist->p_root_onelevel );
+
+ /* This is a hack to find it later. Quite ugly, but I haven't found a
+ * better way */
+ p_playlist->p_local_onelevel->p_input->i_id =
+ p_playlist->p_local_category->p_input->i_id;
+ p_playlist->p_ml_onelevel->p_input->i_id =
+ p_playlist->p_ml_category->p_input->i_id;
+
+ /* Initial status */
+ p_playlist->status.p_item = NULL;
+ p_playlist->status.p_node = p_playlist->p_root_onelevel;
+ p_playlist->request.b_request = VLC_FALSE;
+ p_playlist->status.i_status = PLAYLIST_STOPPED;
+
+ p_playlist->i_sort = SORT_ID;
+ p_playlist->i_order = ORDER_NORMAL;
+
+ vlc_object_attach( p_playlist, p_parent );
+ return p_playlist;
+}
+
+void playlist_Destroy( playlist_t *p_playlist )
+{
+ while( p_playlist->i_sds )
+ {
+ playlist_ServicesDiscoveryRemove( p_playlist,
+ p_playlist->pp_sds[0]->psz_module );
+ }
+ vlc_thread_join( p_playlist->p_preparse );
+ vlc_thread_join( p_playlist );
+
+ vlc_object_detach( p_playlist->p_preparse );
+
+ var_Destroy( p_playlist, "intf-change" );
+ var_Destroy( p_playlist, "item-change" );
+ var_Destroy( p_playlist, "playlist-current" );
+ var_Destroy( p_playlist, "intf-popmenu" );
+ var_Destroy( p_playlist, "intf-show" );
+ var_Destroy( p_playlist, "play-and-stop" );
+ var_Destroy( p_playlist, "random" );
+ var_Destroy( p_playlist, "repeat" );
+ var_Destroy( p_playlist, "loop" );
+ var_Destroy( p_playlist, "activity" );
+
+ playlist_LockClear( p_playlist );
+
+ if( p_playlist->p_stats )
+ free( p_playlist->p_stats );
+
+ vlc_mutex_destroy( &p_playlist->gc_lock );
+ vlc_object_destroy( p_playlist->p_preparse );
+ vlc_object_destroy( p_playlist );
+
+}
+/* Destroy remaining objects */
+static mtime_t ObjectGarbageCollector( playlist_t *p_playlist, int i_type,
+ mtime_t destroy_date )
+{
+ vlc_object_t *p_obj;
+
+ if( destroy_date > mdate() ) return destroy_date;
+
+ if( destroy_date == 0 )
+ {
+ /* give a little time */
+ return mdate() + I64C(1000000);
+ }
+ else
+ {
+ vlc_mutex_lock( &p_playlist->gc_lock );
+ while( ( p_obj = vlc_object_find( p_playlist, i_type, FIND_CHILD ) ) )
+ {
+ if( p_obj->p_parent != (vlc_object_t*)p_playlist )
+ {
+ /* only first child (ie unused) */
+ vlc_object_release( p_obj );
+ break;
+ }
+ if( i_type == VLC_OBJECT_VOUT )
+ {
+ msg_Dbg( p_playlist, "garbage collector destroying 1 vout" );
+ vlc_object_detach( p_obj );
+ vlc_object_release( p_obj );
+ vout_Destroy( (vout_thread_t *)p_obj );
+ }
+ else if( i_type == VLC_OBJECT_SOUT )
+ {
+ vlc_object_release( p_obj );
+ sout_DeleteInstance( (sout_instance_t*)p_obj );
+ }
+ }
+ vlc_mutex_unlock( &p_playlist->gc_lock );
+ return 0;
+ }
+}
+
+/** Main loop for the playlist */
+void playlist_MainLoop( playlist_t *p_playlist )
+{
+ playlist_item_t *p_item = NULL;
+
+ mtime_t i_vout_destroyed_date = 0;
+ mtime_t i_sout_destroyed_date = 0;
+
+ PL_LOCK
+
+ /* First, check if we have something to do */
+ /* FIXME : this can be called several times */
+ if( p_playlist->request.b_request )
+ {
+#ifdef PLAYLIST_DEBUG
+ msg_Dbg(p_playlist, "incoming request - stopping current input" );
+#endif
+ /* Stop the existing input */
+ if( p_playlist->p_input )
+ {
+ input_StopThread( p_playlist->p_input );
+ }
+ }
+
+ /* If there is an input, check that it doesn't need to die. */
+ if( p_playlist->p_input )
+ {
+ /* This input is dead. Remove it ! */
+ if( p_playlist->p_input->b_dead )
+ {
+ int i_activity;
+ input_thread_t *p_input;
+
+ p_input = p_playlist->p_input;
+ p_playlist->p_input = NULL;
+
+ /* Release the playlist lock, because we may get stuck
+ * in input_DestroyThread() for some time. */
+ PL_UNLOCK
+
+ /* Destroy input */
+ input_DestroyThread( p_input );
+
+ /* Unlink current input
+ * (_after_ input_DestroyThread for vout garbage collector) */
+ vlc_object_detach( p_input );
+
+ /* Destroy object */
+ vlc_object_destroy( p_input );
+
+ i_vout_destroyed_date = 0;
+ i_sout_destroyed_date = 0;
+
+ if( p_playlist->status.p_item->i_flags
+ & PLAYLIST_REMOVE_FLAG )
+ {
+ playlist_ItemDelete( p_playlist->status.p_item );
+ p_playlist->status.p_item = NULL;
+ }
+
+ i_activity= var_GetInteger( p_playlist, "activity") ;
+ var_SetInteger( p_playlist, "activity", i_activity -
+ DEFAULT_INPUT_ACTIVITY );
+
+ return;
+ }
+ /* This input is dying, let it do */
+ else if( p_playlist->p_input->b_die )
+ {
+ ;
+ }
+ /* This input has finished, ask it to die ! */
+ else if( p_playlist->p_input->b_error
+ || p_playlist->p_input->b_eof )
+ {
+ input_StopThread( p_playlist->p_input );
+ /* Select the next playlist item */
+ PL_UNLOCK
+ return;
+ }
+ else if( p_playlist->p_input->i_state != INIT_S )
+ {
+ PL_UNLOCK
+ i_vout_destroyed_date =
+ ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT,
+ i_vout_destroyed_date );
+ i_sout_destroyed_date =
+ ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT,
+ i_sout_destroyed_date );
+ PL_LOCK
+ }
+ }
+ else
+ {
+ /* No input. Several cases
+ * - No request, running status -> start new item
+ * - No request, stopped status -> collect garbage
+ * - Request, running requested -> start new item
+ * - Request, stopped requested -> collect garbage
+ */
+ if( (!p_playlist->request.b_request &&
+ p_playlist->status.i_status != PLAYLIST_STOPPED) ||
+ ( p_playlist->request.b_request &&
+ p_playlist->request.i_status != PLAYLIST_STOPPED ) )
+ {
+ msg_Dbg( p_playlist, "Starting new item" );
+ stats_TimerStart( p_playlist, "Playlist walk",
+ STATS_TIMER_PLAYLIST_WALK );
+ p_item = playlist_NextItem( p_playlist );
+ stats_TimerStop( p_playlist, STATS_TIMER_PLAYLIST_WALK );
+
+ if( p_item == NULL )
+ {
+ msg_Dbg( p_playlist, "nothing to play" );
+ p_playlist->status.i_status = PLAYLIST_STOPPED;
+ PL_UNLOCK
+ return;
+ }
+ playlist_PlayItem( p_playlist, p_item );
+ }
+ else
+ {
+ if( p_item && p_playlist->status.p_item &&
+ p_playlist->status.p_item->i_flags & PLAYLIST_REMOVE_FLAG )
+ {
+ playlist_ItemDelete( p_item );
+ p_playlist->status.p_item = NULL;
+ }
+
+ /* Collect garbage */
+ PL_UNLOCK
+ i_sout_destroyed_date =
+ ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT, mdate() );
+ i_vout_destroyed_date =
+ ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT, mdate() );
+ PL_LOCK
+ }
+ }
+ PL_UNLOCK
+}
+
+/** Playlist dying last loop */
+void playlist_LastLoop( playlist_t *p_playlist )
+{
+ vlc_object_t *p_obj;
+
+ /* If there is an input, kill it */
+ while( 1 )
+ {
+ PL_LOCK
+
+ if( p_playlist->p_input == NULL )
+ {
+ PL_UNLOCK
+ break;
+ }
+
+ if( p_playlist->p_input->b_dead )
+ {
+ input_thread_t *p_input;
+
+ /* Unlink current input */
+ p_input = p_playlist->p_input;
+ p_playlist->p_input = NULL;
+ PL_UNLOCK
+
+ /* Destroy input */
+ input_DestroyThread( p_input );
+ /* Unlink current input (_after_ input_DestroyThread for vout
+ * garbage collector)*/
+ vlc_object_detach( p_input );
+
+ /* Destroy object */
+ vlc_object_destroy( p_input );
+ continue;
+ }
+ else if( p_playlist->p_input->b_die )
+ {
+ /* This input is dying, leave it alone */
+ ;
+ }
+ else if( p_playlist->p_input->b_error || p_playlist->p_input->b_eof )
+ {
+ input_StopThread( p_playlist->p_input );
+ PL_UNLOCK
+ continue;
+ }
+ else
+ {
+ p_playlist->p_input->b_eof = 1;
+ }
+
+ PL_UNLOCK
+
+ msleep( INTF_IDLE_SLEEP );
+ }
+
+ /* close all remaining sout */
+ while( ( p_obj = vlc_object_find( p_playlist,
+ VLC_OBJECT_SOUT, FIND_CHILD ) ) )
+ {
+ vlc_object_release( p_obj );
+ sout_DeleteInstance( (sout_instance_t*)p_obj );
+ }
+
+ /* close all remaining vout */
+ while( ( p_obj = vlc_object_find( p_playlist,
+ VLC_OBJECT_VOUT, FIND_CHILD ) ) )
+ {
+ vlc_object_detach( p_obj );
+ vlc_object_release( p_obj );
+ vout_Destroy( (vout_thread_t *)p_obj );
+ }
+}
+
+/** Main loop for preparser queue */
+void playlist_PreparseLoop( playlist_preparse_t *p_obj )
+{
+ playlist_t *p_playlist = (playlist_t *)p_obj->p_parent;
+ int i_activity;
+
+ vlc_mutex_lock( &p_obj->object_lock );
+
+ if( p_obj->i_waiting > 0 )
+ {
+ input_item_t *p_current = p_playlist->p_preparse->pp_waiting[0];
+ REMOVE_ELEM( p_obj->pp_waiting, p_obj->i_waiting, 0 );
+ vlc_mutex_unlock( &p_obj->object_lock );
+ vlc_mutex_lock( &p_playlist->object_lock );
+ if( p_current )
+ {
+ vlc_bool_t b_preparsed = VLC_FALSE;
+ if( strncmp( p_current->psz_uri, "http:", 5 ) &&
+ strncmp( p_current->psz_uri, "rtsp:", 5 ) &&
+ strncmp( p_current->psz_uri, "udp:", 4 ) &&
+ strncmp( p_current->psz_uri, "mms:", 4 ) &&
+ strncmp( p_current->psz_uri, "cdda:", 4 ) &&
+ strncmp( p_current->psz_uri, "dvd:", 4 ) &&
+ strncmp( p_current->psz_uri, "v4l:", 4 ) &&
+ strncmp( p_current->psz_uri, "dshow:", 6 ) )
+ {
+ b_preparsed = VLC_TRUE;
+ stats_TimerStart( p_playlist, "Preparse run",
+ STATS_TIMER_PREPARSE );
+ input_Preparse( p_playlist, p_current );
+ stats_TimerStop( p_playlist, STATS_TIMER_PREPARSE );
+ }
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ if( b_preparsed )
+ {
+ var_SetInteger( p_playlist, "item-change",
+ p_current->i_id );
+ }
+ vlc_gc_decref( p_current );
+ }
+ else
+ {
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ }
+ vlc_mutex_lock( &p_obj->object_lock );
+ i_activity= var_GetInteger( p_playlist, "activity" );
+ if( i_activity < 0 ) i_activity = 0;
+ msleep( (i_activity+1) * 1000 );
+ }
+
+ vlc_mutex_unlock( &p_obj->object_lock );
+}
+
+static void VariablesInit( playlist_t *p_playlist )
+{
+ vlc_value_t val;
+ /* These variables control updates */
+ var_Create( p_playlist, "intf-change", VLC_VAR_BOOL );
+ val.b_bool = VLC_TRUE;
+ var_Set( p_playlist, "intf-change", val );
+
+ var_Create( p_playlist, "item-change", VLC_VAR_INTEGER );
+ val.i_int = -1;
+ var_Set( p_playlist, "item-change", val );
+
+ var_Create( p_playlist, "item-deleted", VLC_VAR_INTEGER );
+ val.i_int = -1;
+ var_Set( p_playlist, "item-deleted", val );
+
+ var_Create( p_playlist, "item-append", VLC_VAR_ADDRESS );
+
+ var_Create( p_playlist, "playlist-current", VLC_VAR_INTEGER );
+ val.i_int = -1;
+ var_Set( p_playlist, "playlist-current", val );
+
+ var_Create( p_playlist, "intf-popupmenu", VLC_VAR_BOOL );
+
+ var_Create( p_playlist, "intf-show", VLC_VAR_BOOL );
+ val.b_bool = VLC_TRUE;
+ var_Set( p_playlist, "intf-show", val );
+
+ var_Create( p_playlist, "activity", VLC_VAR_INTEGER );
+ var_SetInteger( p_playlist, "activity", 0 );
+
+ /* Variables to control playback */
+ var_CreateGetBool( p_playlist, "play-and-stop" );
+ var_CreateGetBool( p_playlist, "random" );
+ var_CreateGetBool( p_playlist, "repeat" );
+ var_CreateGetBool( p_playlist, "loop" );
+}
+++ /dev/null
-/*****************************************************************************
- * item-ext.c : Playlist item management functions (act on the playlist)
- *****************************************************************************
- * Copyright (C) 1999-2004 the VideoLAN team
- * $Id$
- *
- * Authors: Samuel Hocevar <sam@zoy.org>
- * Clément Stenac <zorglub@videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#include <stdlib.h> /* free(), strtol() */
-#include <stdio.h> /* sprintf() */
-#include <string.h> /* strerror() */
-
-#include <vlc/vlc.h>
-#include <vlc/input.h>
-
-#include "vlc_playlist.h"
-
-/***************************************************************************
- * Item creation/addition functions
- ***************************************************************************/
-
-/**
- * Add a MRL into the playlist, duration and options given
- *
- * \param p_playlist the playlist to add into
- * \param psz_uri the mrl to add to the playlist
- * \param psz_name a text giving a name or description of this item
- * \param i_mode the mode used when adding
- * \param i_pos the position in the playlist where to add. If this is
- * PLAYLIST_END the item will be added at the end of the playlist
- * regardless of it's size
- * \param i_duration length of the item in milliseconds.
- * \param ppsz_options an array of options
- * \param i_options the number of options
- * \return The id of the playlist item
-*/
-int playlist_AddExt( playlist_t *p_playlist, const char * psz_uri,
- const char *psz_name, int i_mode, int i_pos,
- mtime_t i_duration, const char **ppsz_options,
- int i_options )
-{
- playlist_item_t *p_item;
- p_item = playlist_ItemNew( p_playlist , psz_uri, psz_name );
-
- if( p_item == NULL )
- {
- msg_Err( p_playlist, "unable to add item to playlist" );
- return -1;
- }
-
- p_item->input.i_duration = i_duration;
- p_item->input.i_options = i_options;
- p_item->input.ppsz_options = NULL;
-
- for( p_item->input.i_options = 0; p_item->input.i_options < i_options;
- p_item->input.i_options++ )
- {
- if( !p_item->input.i_options )
- {
- p_item->input.ppsz_options = malloc( i_options * sizeof(char *) );
- if( !p_item->input.ppsz_options ) break;
- }
-
- p_item->input.ppsz_options[p_item->input.i_options] =
- strdup( ppsz_options[p_item->input.i_options] );
- }
-
- return playlist_AddItem( p_playlist, p_item, i_mode, i_pos );
-}
-
-/**
- * Add a MRL into the playlist.
- *
- * \param p_playlist the playlist to add into
- * \param psz_uri the mrl to add to the playlist
- * \param psz_name a text giving a name or description of this item
- * \param i_mode the mode used when adding
- * \param i_pos the position in the playlist where to add. If this is
- * PLAYLIST_END the item will be added at the end of the playlist
- * regardless of it's size
- * \return The id of the playlist item
-*/
-int playlist_Add( playlist_t *p_playlist, const char *psz_uri,
- const char *psz_name, int i_mode, int i_pos )
-{
- return playlist_AddExt( p_playlist, psz_uri, psz_name, i_mode, i_pos,
- -1, NULL, 0 );
-}
-
-/**
- * Add a playlist item into a playlist
- *
- * \param p_playlist the playlist to insert into
- * \param p_item the playlist item to insert
- * \param i_mode the mode used when adding
- * \param i_pos the possition in the playlist where to add. If this is
- * PLAYLIST_END the item will be added at the end of the playlist
- * regardless of it's size
- * \return The id of the playlist item
- */
-int playlist_AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
- int i_mode, int i_pos)
-{
- vlc_value_t val;
- vlc_bool_t b_end = VLC_FALSE;
- playlist_view_t *p_view = NULL;
-
- playlist_add_t *p_add = (playlist_add_t *)malloc(sizeof( playlist_add_t));
-
- vlc_mutex_lock( &p_playlist->object_lock );
-
- /*
- * CHECK_INSERT : checks if the item is already enqued before
- * enqueing it
- */
-
- /* That should not change */
- if ( i_mode & PLAYLIST_CHECK_INSERT )
- {
- int j;
-
- if ( p_playlist->pp_items )
- {
- for ( j = 0; j < p_playlist->i_size; j++ )
- {
- if ( !strcmp( p_playlist->pp_items[j]->input.psz_uri,
- p_item->input.psz_uri ) )
- {
- playlist_ItemDelete( p_item );
- vlc_mutex_unlock( &p_playlist->object_lock );
- return -1;
- }
- }
- }
- i_mode &= ~PLAYLIST_CHECK_INSERT;
- i_mode |= PLAYLIST_APPEND;
- }
-
- msg_Dbg( p_playlist, "adding playlist item `%s' ( %s )",
- p_item->input.psz_name, p_item->input.psz_uri );
-
- p_item->input.i_id = ++p_playlist->i_last_id;
-
- /* Do a few boundary checks and allocate space for the item */
- if( i_pos == PLAYLIST_END )
- {
- b_end = VLC_TRUE;
- if( i_mode & PLAYLIST_INSERT )
- {
- i_mode &= ~PLAYLIST_INSERT;
- i_mode |= PLAYLIST_APPEND;
- }
-
- i_pos = p_playlist->i_size - 1;
- }
-
- if( !(i_mode & PLAYLIST_REPLACE)
- || i_pos < 0 || i_pos >= p_playlist->i_size )
- {
- /* Additional boundary checks */
- if( i_mode & PLAYLIST_APPEND )
- {
- i_pos++;
- }
-
- if( i_pos < 0 )
- {
- i_pos = 0;
- }
- else if( i_pos > p_playlist->i_size )
- {
- i_pos = p_playlist->i_size;
- }
-
- INSERT_ELEM( p_playlist->pp_items, p_playlist->i_size, i_pos, p_item );
- INSERT_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size,
- p_playlist->i_all_size, p_item );
- p_playlist->i_enabled ++;
-
- /* We update the ALL view directly */
- playlist_ViewUpdate( p_playlist, VIEW_ALL );
-
- /* Add the item to the General category */
- if( b_end == VLC_TRUE )
- {
- playlist_NodeAppend( p_playlist, VIEW_CATEGORY, p_item,
- p_playlist->p_general );
- p_add->i_item = p_item->input.i_id;
- p_add->i_node = p_playlist->p_general->input.i_id;
- p_add->i_view = VIEW_CATEGORY;
- val.p_address = p_add;
- var_Set( p_playlist, "item-append", val );
- }
- else
- {
- playlist_NodeInsert( p_playlist, VIEW_CATEGORY, p_item,
- p_playlist->p_general, i_pos );
- }
-
-
- p_view = playlist_ViewFind( p_playlist, VIEW_ALL );
- playlist_ItemAddParent( p_item, VIEW_ALL, p_view->p_root );
-
- /* FIXME : Update sorted views */
-
- if( p_playlist->i_index >= i_pos )
- {
- p_playlist->i_index++;
- }
- }
- else
- {
- msg_Err( p_playlist, "Insert mode not implemented" );
- }
-
- if( (i_mode & PLAYLIST_GO ) && p_view )
- {
- p_playlist->request.b_request = VLC_TRUE;
- /* FIXME ... */
- p_playlist->request.i_view = VIEW_CATEGORY;
- p_playlist->request.p_node = p_view->p_root;
- p_playlist->request.p_item = p_item;
-
- if( p_playlist->p_input )
- {
- input_StopThread( p_playlist->p_input );
- }
- p_playlist->status.i_status = PLAYLIST_RUNNING;
- }
-
- if( i_mode & PLAYLIST_PREPARSE &&
- var_CreateGetBool( p_playlist, "auto-preparse" ) )
- {
- playlist_PreparseEnqueue( p_playlist, &p_item->input );
- }
-
- vlc_mutex_unlock( &p_playlist->object_lock );
-
- if( b_end == VLC_FALSE )
- {
- val.b_bool = VLC_TRUE;
- var_Set( p_playlist, "intf-change", val );
- }
-
- free( p_add );
-
- return p_item->input.i_id;
-}
-
-
-/**
- * Add a playlist item to a given node (in the category view )
- *
- * \param p_playlist the playlist to insert into
- * \param p_item the playlist item to insert
- * \param i_view the view for which to add or TODO: ALL_VIEWS
- * \param p_parent the parent node
- * \param i_mode the mode used when adding
- * \param i_pos the possition in the node where to add. If this is
- * PLAYLIST_END the item will be added at the end of the node
- ** \return The id of the playlist item
- */
-int playlist_NodeAddItem( playlist_t *p_playlist, playlist_item_t *p_item,
- int i_view,playlist_item_t *p_parent,
- int i_mode, int i_pos)
-{
- vlc_value_t val;
- int i_position;
- playlist_view_t *p_view;
-
- playlist_add_t *p_add = (playlist_add_t *)malloc(sizeof( playlist_add_t));
-
- vlc_mutex_lock( &p_playlist->object_lock );
-
- if ( i_pos == PLAYLIST_END ) i_pos = -1;
-
- /* Sanity checks */
- if( !p_parent || p_parent->i_children == -1 )
- {
- msg_Err( p_playlist, "invalid node" );
- }
-
- /*
- * CHECK_INSERT : checks if the item is already enqued before
- * enqueing it
- */
- if ( i_mode & PLAYLIST_CHECK_INSERT )
- {
- int j;
-
- if ( p_playlist->pp_items )
- {
- for ( j = 0; j < p_playlist->i_size; j++ )
- {
- if ( !strcmp( p_playlist->pp_items[j]->input.psz_uri,
- p_item->input.psz_uri ) )
- {
- playlist_ItemDelete( p_item );
- vlc_mutex_unlock( &p_playlist->object_lock );
- free( p_add );
- return -1;
- }
- }
- }
- i_mode &= ~PLAYLIST_CHECK_INSERT;
- i_mode |= PLAYLIST_APPEND;
- }
-
- msg_Dbg( p_playlist, "adding playlist item `%s' ( %s )",
- p_item->input.psz_name, p_item->input.psz_uri );
-
- p_item->input.i_id = ++p_playlist->i_last_id;
-
- /* First, add the item at the right position in the item bank */
- /* WHY THAT ? */
- //i_position = p_playlist->i_index == -1 ? 0 : p_playlist->i_index;
- i_position = p_playlist->i_size ;
-
- INSERT_ELEM( p_playlist->pp_items,
- p_playlist->i_size,
- i_position,
- p_item );
- INSERT_ELEM( p_playlist->pp_all_items,
- p_playlist->i_all_size,
- p_playlist->i_all_size,
- p_item );
- p_playlist->i_enabled ++;
-
- /* TODO: Handle modes */
- playlist_NodeInsert( p_playlist, i_view, p_item, p_parent, i_pos );
-
- p_add->i_item = p_item->input.i_id;
- p_add->i_node = p_parent->input.i_id;
- p_add->i_view = i_view;
- val.p_address = p_add;
- var_Set( p_playlist, "item-append", val );
-
- /* We update the ALL view directly */
- p_view = playlist_ViewFind( p_playlist, VIEW_ALL );
- playlist_ItemAddParent( p_item, VIEW_ALL, p_view->p_root );
- playlist_ViewUpdate( p_playlist, VIEW_ALL );
-
- /* TODO : Update sorted views*/
-
- if( i_mode & PLAYLIST_GO )
- {
- p_playlist->request.b_request = VLC_TRUE;
- p_playlist->request.i_view = VIEW_CATEGORY;
- p_playlist->request.p_node = p_parent;
- p_playlist->request.p_item = p_item;
- if( p_playlist->p_input )
- {
- input_StopThread( p_playlist->p_input );
- }
- p_playlist->status.i_status = PLAYLIST_RUNNING;
- }
- if( i_mode & PLAYLIST_PREPARSE &&
- var_CreateGetBool( p_playlist, "auto-preparse" ) )
- {
- playlist_PreparseEnqueue( p_playlist, &p_item->input );
- }
-
- vlc_mutex_unlock( &p_playlist->object_lock );
-
- val.b_bool = VLC_TRUE;
-// var_Set( p_playlist, "intf-change", val );
-//
- free( p_add );
-
- return p_item->input.i_id;
-}
-
-/***************************************************************************
- * Item search functions
- ***************************************************************************/
-
-/**
- * Search the position of an item by its id
- * This function must be entered with the playlist lock
- *
- * \param p_playlist the playlist
- * \param i_id the id to find
- * \return the position, or VLC_EGENERIC on failure
- */
-int playlist_GetPositionById( playlist_t * p_playlist , int i_id )
-{
- int i;
- for( i = 0 ; i < p_playlist->i_size ; i++ )
- {
- if( p_playlist->pp_items[i]->input.i_id == i_id )
- {
- return i;
- }
- }
- return VLC_EGENERIC;
-}
-
-
-/**
- * Search an item by its position
- * This function must be entered with the playlist lock
- *
- * \param p_playlist the playlist
- * \param i_pos the position of the item to find
- * \return the item, or NULL on failure
- */
-playlist_item_t * playlist_ItemGetByPos( playlist_t * p_playlist , int i_pos )
-{
- if( i_pos >= 0 && i_pos < p_playlist->i_size)
- {
- return p_playlist->pp_items[i_pos];
- }
- else if( p_playlist->i_size > 0)
- {
- return p_playlist->pp_items[p_playlist->i_index];
- }
- else
- {
- return NULL;
- }
-}
-
-playlist_item_t *playlist_LockItemGetByPos( playlist_t *p_playlist, int i_pos )
-{
- playlist_item_t *p_ret;
- vlc_mutex_lock( &p_playlist->object_lock );
- p_ret = playlist_ItemGetByPos( p_playlist, i_pos );
- vlc_mutex_unlock( &p_playlist->object_lock );
- return p_ret;
-}
-
-/**
- * Search an item by its id
- *
- * \param p_playlist the playlist
- * \param i_id the id to find
- * \return the item, or NULL on failure
- */
-playlist_item_t * playlist_ItemGetById( playlist_t * p_playlist , int i_id )
-{
- int i, i_top, i_bottom;
- i_bottom = 0; i_top = p_playlist->i_all_size - 1;
- i = i_top / 2;
- while( p_playlist->pp_all_items[i]->input.i_id != i_id &&
- i_top > i_bottom )
- {
- if( p_playlist->pp_all_items[i]->input.i_id < i_id )
- {
- i_bottom = i + 1;
- }
- else
- {
- i_top = i - 1;
- }
- i = i_bottom + ( i_top - i_bottom ) / 2;
- }
- if( p_playlist->pp_all_items[i]->input.i_id == i_id )
- {
- return p_playlist->pp_all_items[i];
- }
- return NULL;
-}
-
-playlist_item_t *playlist_LockItemGetById( playlist_t *p_playlist, int i_id)
-{
- playlist_item_t *p_ret;
- vlc_mutex_lock( &p_playlist->object_lock );
- p_ret = playlist_ItemGetById( p_playlist, i_id );
- vlc_mutex_unlock( &p_playlist->object_lock );
- return p_ret;
-}
-
-/**
- * Search an item by its input_item_t
- *
- * \param p_playlist the playlist
- * \param p_item the input_item_t to find
- * \return the item, or NULL on failure
- */
-playlist_item_t * playlist_ItemGetByInput( playlist_t * p_playlist ,
- input_item_t *p_item )
-{
- int i;
- if( &p_playlist->status.p_item->input == p_item )
- {
- return p_playlist->status.p_item;
- }
-
- for( i = 0 ; i < p_playlist->i_size ; i++ )
- {
- if( &p_playlist->pp_items[i]->input == p_item )
- {
- return p_playlist->pp_items[i];
- }
- }
- return NULL;
-}
-
-playlist_item_t *playlist_LockItemGetByInput( playlist_t *p_playlist,
- input_item_t *p_item )
-{
- playlist_item_t *p_ret;
- vlc_mutex_lock( &p_playlist->object_lock );
- p_ret = playlist_ItemGetByInput( p_playlist, p_item );
- vlc_mutex_unlock( &p_playlist->object_lock );
- return p_ret;
-}
-
-
-/***********************************************************************
- * Misc functions
- ***********************************************************************/
-
-/**
- * Transform an item to a node
- *
- * This function must be entered without the playlist lock
- *
- * \param p_playlist the playlist object
- * \param p_item the item to transform
- * \return nothing
- */
-int playlist_ItemToNode( playlist_t *p_playlist,playlist_item_t *p_item )
-{
- int i = 0;
- if( p_item->i_children == -1 )
- {
- p_item->i_children = 0;
- }
-
- /* Remove it from the array of available items */
- for( i = 0 ; i < p_playlist->i_size ; i++ )
- {
- if( p_item == p_playlist->pp_items[i] )
- {
- REMOVE_ELEM( p_playlist->pp_items, p_playlist->i_size, i );
- }
- }
- var_SetInteger( p_playlist, "item-change", p_item->input.i_id );
-
- return VLC_SUCCESS;
-}
-
-int playlist_LockItemToNode( playlist_t *p_playlist, playlist_item_t *p_item )
-{
- int i_ret;
- vlc_mutex_lock( &p_playlist->object_lock );
- i_ret = playlist_ItemToNode( p_playlist, p_item );
- vlc_mutex_unlock( &p_playlist->object_lock );
- return i_ret;
-}
-
-/**
- * Replaces an item with another one
- * This function must be entered without the playlist lock
- *
- * \see playlist_Replace
- */
-int playlist_LockReplace( playlist_t *p_playlist,
- playlist_item_t *p_olditem,
- input_item_t *p_new )
-{
- int i_ret;
- vlc_mutex_lock( &p_playlist->object_lock );
- i_ret = playlist_Replace( p_playlist, p_olditem, p_new );
- vlc_mutex_unlock( &p_playlist->object_lock );
- return i_ret;
-}
-
-/**
- * Replaces an item with another one
- * This function must be entered with the playlist lock:
- *
- * \param p_playlist the playlist
- * \param p_olditem the item to replace
- * \param p_new the new input_item
- * \return VLC_SUCCESS or an error
- */
-int playlist_Replace( playlist_t *p_playlist, playlist_item_t *p_olditem,
- input_item_t *p_new )
-{
- int i;
- int j;
-
- if( p_olditem->i_children != -1 )
- {
- msg_Err( p_playlist, "playlist_Replace can only be used on leafs");
- return VLC_EGENERIC;
- }
-
- p_olditem->i_nb_played = 0;
- memcpy( &p_olditem->input, p_new, sizeof( input_item_t ) );
-
- p_olditem->i_nb_played = 0;
-
- for( i = 0 ; i< p_olditem->i_parents ; i++ )
- {
- playlist_item_t *p_parent = p_olditem->pp_parents[i]->p_parent;
-
- for( j = 0 ; j< p_parent->i_children ; i++ )
- {
- if( p_parent->pp_children[j] == p_olditem )
- {
- p_parent->i_serial++;
- }
- }
- }
- return VLC_SUCCESS;
-}
-
-/**
- * Deletes an item from a playlist.
- *
- * This function must be entered without the playlist lock
- *
- * \param p_playlist the playlist to remove from.
- * \param i_id the identifier of the item to delete
- * \return returns VLC_SUCCESS or an error
- */
-int playlist_Delete( playlist_t * p_playlist, int i_id )
-{
- int i, i_top, i_bottom;
- int i_pos;
- vlc_bool_t b_flag = VLC_FALSE;
-
- playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id );
-
- if( p_item == NULL )
- {
- return VLC_EGENERIC;
- }
- if( p_item->i_children > -1 )
- {
- return playlist_NodeDelete( p_playlist, p_item, VLC_TRUE, VLC_FALSE );
- }
-
- var_SetInteger( p_playlist, "item-deleted", i_id );
-
- i_bottom = 0; i_top = p_playlist->i_all_size - 1;
- i = i_top / 2;
- while( p_playlist->pp_all_items[i]->input.i_id != i_id &&
- i_top > i_bottom )
- {
- if( p_playlist->pp_all_items[i]->input.i_id < i_id )
- {
- i_bottom = i + 1;
- }
- else
- {
- i_top = i - 1;
- }
- i = i_bottom + ( i_top - i_bottom ) / 2;
- }
- if( p_playlist->pp_all_items[i]->input.i_id == i_id )
- {
- REMOVE_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size, i );
- }
-
- /* Check if it is the current item */
- if( p_playlist->status.p_item == p_item )
- {
- /* Hack we don't call playlist_Control for lock reasons */
- p_playlist->status.i_status = PLAYLIST_STOPPED;
- p_playlist->request.b_request = VLC_TRUE;
- p_playlist->request.p_item = NULL;
- msg_Info( p_playlist, "stopping playback" );
- b_flag = VLC_TRUE;
- }
-
- /* Get position and update index if needed */
- i_pos = playlist_GetPositionById( p_playlist, i_id );
-
- if( i_pos >= 0 && i_pos <= p_playlist->i_index )
- {
- p_playlist->i_index--;
- }
-
- msg_Dbg( p_playlist, "deleting playlist item `%s'",
- p_item->input.psz_name );
-
- /* Remove the item from all its parent nodes */
- for ( i= 0 ; i < p_item->i_parents ; i++ )
- {
- playlist_NodeRemoveItem( p_playlist, p_item,
- p_item->pp_parents[i]->p_parent );
- if( p_item->pp_parents[i]->i_view == VIEW_ALL )
- {
- p_playlist->i_size--;
- }
- }
-
- /* TODO : Update views */
-
- if( b_flag == VLC_FALSE )
- playlist_ItemDelete( p_item );
- else
- p_item->i_flags |= PLAYLIST_REMOVE_FLAG;
-
- return VLC_SUCCESS;
-}
-
-int playlist_LockDelete( playlist_t * p_playlist, int i_id )
-{
- int i_ret;
- vlc_mutex_lock( &p_playlist->object_lock );
- i_ret = playlist_Delete( p_playlist, i_id );
- vlc_mutex_unlock( &p_playlist->object_lock );
- return i_ret;
-}
-
-/**
- * Clear all playlist items
- *
- * \param p_playlist the playlist to be cleared.
- * \return returns 0
- */
-int playlist_Clear( playlist_t * p_playlist )
-{
- int i;
- for( i = p_playlist->i_size; i > 0 ; i-- )
- {
- playlist_Delete( p_playlist, p_playlist->pp_items[0]->input.i_id );
- }
- for( i = 0 ; i< p_playlist->i_views; i++ )
- {
- playlist_ViewEmpty( p_playlist, i, VLC_TRUE );
- }
- return VLC_SUCCESS;
-}
-
-int playlist_LockClear( playlist_t *p_playlist )
-{
- int i_ret;
- vlc_mutex_lock( &p_playlist->object_lock );
- i_ret = playlist_Clear( p_playlist );
- vlc_mutex_unlock( &p_playlist->object_lock );
- return i_ret;
-}
-
-
-/**
- * Disables a playlist item
- *
- * \param p_playlist the playlist to disable from.
- * \param i_pos the position of the item to disable
- * \return returns 0
- */
-int playlist_Disable( playlist_t * p_playlist, playlist_item_t *p_item )
-{
- if( !p_item ) return VLC_EGENERIC;
-
- msg_Dbg( p_playlist, "disabling playlist item `%s'",
- p_item->input.psz_name );
-
- if( p_item->i_flags & PLAYLIST_ENA_FLAG )
- {
- p_playlist->i_enabled--;
- }
- p_item->i_flags &= ~PLAYLIST_ENA_FLAG;
-
- var_SetInteger( p_playlist, "item-change", p_item->input.i_id );
- return VLC_SUCCESS;
-}
-
-/**
- * Enables a playlist item
- *
- * \param p_playlist the playlist to enable from.
- * \param i_pos the position of the item to enable
- * \return returns 0
- */
-int playlist_Enable( playlist_t * p_playlist, playlist_item_t *p_item )
-{
- if( !p_item ) return VLC_EGENERIC;
-
- msg_Dbg( p_playlist, "enabling playlist item `%s'",
- p_item->input.psz_name );
-
- if( p_item->i_flags & ~PLAYLIST_ENA_FLAG )
- {
- p_playlist->i_enabled++;
- }
- p_item->i_flags |= PLAYLIST_ENA_FLAG;
-
- var_SetInteger( p_playlist, "item-change", p_item->input.i_id );
- return VLC_SUCCESS;
-}
-
-/**
- * Move an item in a playlist
- *
- * This function must be entered without the playlist lock
- *
- * Move the item in the playlist with position i_pos before the current item
- * at position i_newpos.
- * \param p_playlist the playlist to move items in
- * \param i_pos the position of the item to move
- * \param i_newpos the position of the item that will be behind the moved item
- * after the move
- * \return returns VLC_SUCCESS
- */
-int playlist_Move( playlist_t * p_playlist, int i_pos, int i_newpos )
-{
- vlc_value_t val;
- vlc_mutex_lock( &p_playlist->object_lock );
-
- /* take into account that our own row disappears. */
- if( i_pos < i_newpos ) i_newpos--;
-
- if( i_pos >= 0 && i_newpos >=0 && i_pos <= p_playlist->i_size &&
- i_newpos <= p_playlist->i_size )
- {
- playlist_item_t * temp;
-
- msg_Dbg( p_playlist, "moving playlist item `%s' (%i -> %i)",
- p_playlist->pp_items[i_pos]->input.psz_name, i_pos, i_newpos);
-
- if( i_pos == p_playlist->i_index )
- {
- p_playlist->i_index = i_newpos;
- }
- else if( i_pos > p_playlist->i_index &&
- i_newpos <= p_playlist->i_index )
- {
- p_playlist->i_index++;
- }
- else if( i_pos < p_playlist->i_index &&
- i_newpos >= p_playlist->i_index )
- {
- p_playlist->i_index--;
- }
-
- if ( i_pos < i_newpos )
- {
- temp = p_playlist->pp_items[i_pos];
- while ( i_pos < i_newpos )
- {
- p_playlist->pp_items[i_pos] = p_playlist->pp_items[i_pos+1];
- i_pos++;
- }
- p_playlist->pp_items[i_newpos] = temp;
- }
- else if ( i_pos > i_newpos )
- {
- temp = p_playlist->pp_items[i_pos];
- while ( i_pos > i_newpos )
- {
- p_playlist->pp_items[i_pos] = p_playlist->pp_items[i_pos-1];
- i_pos--;
- }
- p_playlist->pp_items[i_newpos] = temp;
- }
- }
-
- vlc_mutex_unlock( &p_playlist->object_lock );
-
- val.b_bool = VLC_TRUE;
- var_Set( p_playlist, "intf-change", val );
-
- return VLC_SUCCESS;
-}
-
-/**
- * Moves an item
- *
- * This function must be entered with the playlist lock
- *
- * \param p_playlist the playlist
- * \param p_item the item to move
- * \param p_node the new parent of the item
- * \param i_newpos the new position under this new parent
- * \param i_view the view in which the move must be done or ALL_VIEWS
- * \return VLC_SUCCESS or an error
- */
-int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item,
- playlist_item_t *p_node, int i_newpos, int i_view )
-{
- int i;
- playlist_item_t *p_detach = NULL;
- struct item_parent_t *p_parent;
-
- if( p_node->i_children == -1 ) return VLC_EGENERIC;
-
- /* Detach from the parent */
- for( i = 0 ; i< p_item->i_parents; i++ )
- {
- if( p_item->pp_parents[i]->i_view == i_view )
- {
- int j;
- p_detach = p_item->pp_parents[i]->p_parent;
- for( j = 0; j < p_detach->i_children; j++ )
- {
- if( p_detach->pp_children[j] == p_item ) break;
- }
- REMOVE_ELEM( p_detach->pp_children, p_detach->i_children, j );
- p_detach->i_serial++;
- free( p_item->pp_parents[i] );
- REMOVE_ELEM( p_item->pp_parents, p_item->i_parents, i );
- i--;
- }
- }
-
- /* Attach to new parent */
- INSERT_ELEM( p_node->pp_children, p_node->i_children, i_newpos, p_item );
-
- p_parent = malloc( sizeof( struct item_parent_t ) );
- p_parent->p_parent = p_node;
- p_parent->i_view = i_view;
-
- INSERT_ELEM( p_item->pp_parents, p_item->i_parents, p_item->i_parents,
- p_parent );
- p_node->i_serial++;
- p_item->i_serial++;
-
- return VLC_SUCCESS;
-}
/*****************************************************************************
- * item.c : Playlist item functions
+ * item.c : Playlist item creation/deletion/add/removal functions
*****************************************************************************
* Copyright (C) 1999-2004 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
+ * Clément Stenac <zorglub@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
-#include <stdlib.h> /* free(), strtol() */
-#include <stdio.h> /* sprintf() */
-#include <string.h> /* strerror() */
-
#include <vlc/vlc.h>
#include <vlc/input.h>
-#include "vlc_input.h"
#include "vlc_playlist.h"
-static void GuessType( input_item_t *p_item);
+void AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
+ playlist_item_t *p_node, int i_pos );
+void GoAndPreparse( playlist_t *p_playlist, int i_mode,
+ playlist_item_t *p_item );
+void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item );
+int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item,
+ vlc_bool_t b_stop );
+/*****************************************************************************
+ * Playlist item creation
+ *****************************************************************************/
/**
* Create a new item, without adding it to the playlist
*
* \param psz_name a text giving a name or description of the item
* \return the new item or NULL on failure
*/
-
playlist_item_t * __playlist_ItemNew( vlc_object_t *p_obj,
const char *psz_uri,
const char *psz_name )
{
return playlist_ItemNewWithType( p_obj, psz_uri,
- psz_name, ITEM_TYPE_UNKNOWN );
+ psz_name, 0, NULL, -1,
+ ITEM_TYPE_UNKNOWN );
}
playlist_item_t * playlist_ItemNewWithType( vlc_object_t *p_obj,
const char *psz_uri,
const char *psz_name,
+ int i_options,
+ const char **ppsz_options,
+ int i_duration,
int i_type )
{
- playlist_item_t * p_item;
-
- if( psz_uri == NULL) return NULL;
+ if( psz_uri == NULL ) return NULL;
+ input_item_t *p_input = input_ItemNewWithType( p_obj, psz_uri,
+ psz_name, i_options, ppsz_options,
+ i_duration, i_type );
+ return playlist_ItemNewFromInput( p_obj, p_input );
+}
+playlist_item_t *__playlist_ItemNewFromInput( vlc_object_t *p_obj,
+ input_item_t *p_input )
+{
+ /** FIXME !!!!! don't find playlist each time */
+ playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_obj, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+ playlist_item_t * p_item;
p_item = malloc( sizeof( playlist_item_t ) );
if( p_item == NULL ) return NULL;
- memset( p_item, 0, sizeof( playlist_item_t ) );
-
- vlc_input_item_Init( p_obj, &p_item->input );
- p_item->input.b_fixed_name = VLC_FALSE;
-
- p_item->input.psz_uri = strdup( psz_uri );
-
- if( psz_name != NULL ) p_item->input.psz_name = strdup( psz_name );
- else p_item->input.psz_name = strdup ( psz_uri );
-
- p_item->input.i_type = i_type;
+ p_item->p_input = p_input;
+ vlc_gc_incref( p_item->p_input );
- p_item->b_enabled = VLC_TRUE;
- p_item->i_nb_played = 0;
+ p_item->i_id = ++p_playlist->i_last_playlist_id;
+ p_item->p_parent = NULL;
p_item->i_children = -1;
p_item->pp_children = NULL;
-
p_item->i_flags = 0;
- p_item->i_flags |= PLAYLIST_SKIP_FLAG;
- p_item->i_flags |= PLAYLIST_SAVE_FLAG;
-
- p_item->input.i_duration = -1;
- p_item->input.ppsz_options = NULL;
- p_item->input.i_options = 0;
-
- vlc_mutex_init( p_obj, &p_item->input.lock );
- if( p_item->input.i_type == ITEM_TYPE_UNKNOWN )
- GuessType( &p_item->input );
+ vlc_object_release( p_playlist );
return p_item;
}
/**
- * Copy a playlist item
+ * Copy a playlist item - FIXME: Rewrite FIXME
*
* Creates a new item with name, mrl and meta infor like the
* source. Does not copy children for node type items.
{
playlist_item_t *p_res;
int i;
- vlc_mutex_lock( &p_item->input.lock );
+ vlc_mutex_lock( &p_item->p_input->lock );
p_res = malloc( sizeof( playlist_item_t ) );
if( p_res == NULL )
{
- vlc_mutex_unlock( &p_item->input.lock );
+ vlc_mutex_unlock( &p_item->p_input->lock );
return NULL;
}
*p_res = *p_item;
- vlc_mutex_init( p_obj, &p_res->input.lock );
+ vlc_mutex_init( p_obj, &p_res->p_input->lock );
- if( p_item->input.i_options )
- p_res->input.ppsz_options =
- malloc( p_item->input.i_options * sizeof(char*) );
- for( i = 0; i < p_item->input.i_options; i++ )
+ if( p_item->p_input->i_options )
+ p_res->p_input->ppsz_options =
+ malloc( p_item->p_input->i_options * sizeof(char*) );
+ for( i = 0; i < p_item->p_input->i_options; i++ )
{
- p_res->input.ppsz_options[i] = strdup( p_item->input.ppsz_options[i] );
+ p_res->p_input->ppsz_options[i] = strdup( p_item->p_input->ppsz_options[i] );
}
if( p_item->i_children != -1 )
p_res->i_children = -1;
p_res->pp_children = NULL;
}
- p_res->i_parents = 0;
- p_res->pp_parents = NULL;
-
- if( p_item->input.psz_name )
- p_res->input.psz_name = strdup( p_item->input.psz_name );
- if( p_item->input.psz_uri )
- p_res->input.psz_uri = strdup( p_item->input.psz_uri );
-
- if( p_item->input.i_es )
+ p_res->p_parent = NULL;
+
+ if( p_item->p_input->psz_name )
+ p_res->p_input->psz_name = strdup( p_item->p_input->psz_name );
+ if( p_item->p_input->psz_uri )
+ p_res->p_input->psz_uri = strdup( p_item->p_input->psz_uri );
+
+ if( p_item->p_input->i_es )
{
- p_res->input.es =
- (es_format_t**)malloc( p_item->input.i_es * sizeof(es_format_t*));
- for( i = 0; i < p_item->input.i_es; i++ )
+ p_res->p_input->es =
+ (es_format_t**)malloc( p_item->p_input->i_es * sizeof(es_format_t*));
+ for( i = 0; i < p_item->p_input->i_es; i++ )
{
- p_res->input.es[ i ] = (es_format_t*)malloc(sizeof(es_format_t*));
- es_format_Copy( p_res->input.es[ i ],
- p_item->input.es[ i ] );
+ p_res->p_input->es[ i ] = (es_format_t*)malloc(sizeof(es_format_t*));
+ es_format_Copy( p_res->p_input->es[ i ],
+ p_item->p_input->es[ i ] );
}
}
- if( p_item->input.i_categories )
+ if( p_item->p_input->i_categories )
{
- p_res->input.pp_categories = NULL;
- p_res->input.i_categories = 0;
- for( i = 0; i < p_item->input.i_categories; i++ )
+ p_res->p_input->pp_categories = NULL;
+ p_res->p_input->i_categories = 0;
+ for( i = 0; i < p_item->p_input->i_categories; i++ )
{
info_category_t *p_incat;
- p_incat = p_item->input.pp_categories[i];
+ p_incat = p_item->p_input->pp_categories[i];
if( p_incat->i_infos )
{
int j;
for( j = 0; j < p_incat->i_infos; j++ )
{
- vlc_input_item_AddInfo( &p_res->input, p_incat->psz_name,
+ vlc_input_item_AddInfo( p_res->p_input, p_incat->psz_name,
p_incat->pp_infos[j]->psz_name,
- "%s", /* to be safe */
+ "%s",
p_incat->pp_infos[j]->psz_value );
}
}
}
}
- vlc_mutex_unlock( &p_item->input.lock );
+ vlc_mutex_unlock( &p_item->p_input->lock );
return p_res;
}
+/***************************************************************************
+ * Playlist item destruction
+ ***************************************************************************/
+
+/** Delete a playlist item and detach its input item */
+int playlist_ItemDelete( playlist_item_t *p_item )
+{
+ vlc_gc_decref( p_item->p_input );
+ free( p_item );
+ return VLC_SUCCESS;
+}
+
+/** Remove an input item from ONELEVEL and CATEGORY */
+int playlist_DeleteAllFromInput( playlist_t *p_playlist, int i_input_id )
+{
+ playlist_DeleteFromInput( p_playlist, i_input_id,
+ p_playlist->p_root_category, VLC_TRUE );
+ playlist_DeleteFromInput( p_playlist, i_input_id,
+ p_playlist->p_root_onelevel, VLC_TRUE );
+ return VLC_SUCCESS;
+}
+
+/** Remove an input item from ONELEVEL and CATEGORY.
+ * This function must be entered without the playlist lock */
+int playlist_LockDeleteAllFromInput( playlist_t * p_playlist, int i_id )
+{
+ int i_ret;
+ vlc_mutex_lock( &p_playlist->object_lock );
+ i_ret = playlist_DeleteAllFromInput( p_playlist, i_id );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ return i_ret;
+}
+
+/** Remove an input item when it appears from a root playlist item */
+int playlist_DeleteFromInput( playlist_t *p_playlist, int i_input_id,
+ playlist_item_t *p_root, vlc_bool_t b_do_stop )
+{
+ int i;
+ for( i = 0 ; i< p_root->i_children ; i++ )
+ {
+ if( p_root->pp_children[i]->i_children == -1 &&
+ p_root->pp_children[i]->p_input->i_id == i_input_id )
+ {
+ DeleteInner( p_playlist, p_root->pp_children[i], b_do_stop );
+ }
+ else if( p_root->pp_children[i]->i_children >= 0 )
+ {
+ return playlist_DeleteFromInput( p_playlist, i_input_id,
+ p_root->pp_children[i], b_do_stop );
+ }
+ }
+}
+
+/** Remove a playlist item from the playlist, given its id */
+int playlist_DeleteFromItemId( playlist_t *p_playlist, int i_id )
+{
+ playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id );
+ if( !p_item ) return VLC_EGENERIC;
+ return DeleteInner( p_playlist, p_item, VLC_TRUE );
+}
+
+/** Remove a playlist item from the playlist, given its id
+ * This function should be entered without the playlist lock */
+int playlist_LockDelete( playlist_t * p_playlist, int i_id )
+{
+ int i_ret;
+ vlc_mutex_lock( &p_playlist->object_lock );
+ i_ret = playlist_DeleteFromItemId( p_playlist, i_id );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ return i_ret;
+}
+
+/** Clear the playlist */
+void playlist_Clear( playlist_t * p_playlist )
+{
+ playlist_NodeEmpty( p_playlist, p_playlist->p_root_category, VLC_TRUE );
+ playlist_NodeEmpty( p_playlist, p_playlist->p_root_onelevel, VLC_TRUE );
+}
+/** Clear the playlist. This function must be entered without the lock */
+void playlist_LockClear( playlist_t *p_playlist )
+{
+ vlc_mutex_lock( &p_playlist->object_lock );
+ playlist_Clear( p_playlist );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+}
+
+/***************************************************************************
+ * Playlist item addition
+ ***************************************************************************/
+
/**
- * Deletes a playlist item
+ * Add a MRL into the playlist.
*
- * \param p_item the item to delete
- * \return nothing
+ * \param p_playlist the playlist to add into
+ * \param psz_uri the mrl to add to the playlist
+ * \param psz_name a text giving a name or description of this item
+ * \param i_mode the mode used when adding
+ * \param i_pos the position in the playlist where to add. If this is
+ * PLAYLIST_END the item will be added at the end of the playlist
+ * regardless of it's size
+ * \return The id of the playlist item
*/
-int playlist_ItemDelete( playlist_item_t *p_item )
+int playlist_PlaylistAdd( playlist_t *p_playlist, const char *psz_uri,
+ const char *psz_name, int i_mode, int i_pos )
{
- vlc_mutex_lock( &p_item->input.lock );
+ return playlist_PlaylistAddExt( p_playlist, psz_uri, psz_name,
+ i_mode, i_pos, -1, NULL, 0 );
+}
- if( p_item->input.psz_name ) free( p_item->input.psz_name );
- if( p_item->input.psz_uri ) free( p_item->input.psz_uri );
+/**
+ * Add a MRL into the playlist, duration and options given
+ *
+ * \param p_playlist the playlist to add into
+ * \param psz_uri the mrl to add to the playlist
+ * \param psz_name a text giving a name or description of this item
+ * \param i_mode the mode used when adding
+ * \param i_pos the position in the playlist where to add. If this is
+ * PLAYLIST_END the item will be added at the end of the playlist
+ * regardless of it's size
+ * \param i_duration length of the item in milliseconds.
+ * \param ppsz_options an array of options
+ * \param i_options the number of options
+ * \return The id of the playlist item
+*/
+int playlist_PlaylistAddExt( playlist_t *p_playlist, const char * psz_uri,
+ const char *psz_name, int i_mode, int i_pos,
+ mtime_t i_duration, const char **ppsz_options,
+ int i_options )
+{
+ input_item_t *p_input = input_ItemNewExt( p_playlist, psz_uri, psz_name,
+ i_options, ppsz_options,
+ i_duration );
- /* Free the info categories */
- if( p_item->input.i_categories > 0 )
- {
- int i, j;
+ return playlist_PlaylistAddInput( p_playlist, p_input, i_mode, i_pos );
+}
- for( i = 0; i < p_item->input.i_categories; i++ )
- {
- info_category_t *p_category = p_item->input.pp_categories[i];
+/** Add an input item to the playlist node */
+int playlist_PlaylistAddInput( playlist_t* p_playlist, input_item_t *p_input,
+ int i_mode, int i_pos )
+{
+ playlist_item_t *p_item;
+ p_input->i_id = ++p_playlist->i_last_input_id;
- for( j = 0; j < p_category->i_infos; j++)
- {
- if( p_category->pp_infos[j]->psz_name )
- {
- free( p_category->pp_infos[j]->psz_name);
- }
- if( p_category->pp_infos[j]->psz_value )
- {
- free( p_category->pp_infos[j]->psz_value );
- }
- free( p_category->pp_infos[j] );
- }
+ msg_Dbg( p_playlist, "adding playlist item `%s' ( %s )",
+ p_input->psz_name, p_input->psz_uri );
- if( p_category->i_infos ) free( p_category->pp_infos );
- if( p_category->psz_name ) free( p_category->psz_name );
- free( p_category );
- }
+ vlc_mutex_lock( &p_playlist->object_lock );
- free( p_item->input.pp_categories );
- }
+ /* Add to ONELEVEL */
+ p_item = playlist_ItemNewFromInput( p_playlist, p_input );
+ if( p_item == NULL ) return VLC_EGENERIC;
+ AddItem( p_playlist, p_item,p_playlist->p_local_onelevel, i_pos );
+
+ /* Add to CATEGORY */
+ p_item = playlist_ItemNewFromInput( p_playlist, p_input );
+ if( p_item == NULL ) return VLC_EGENERIC;
+ AddItem( p_playlist, p_item, p_playlist->p_local_category, i_pos );
+
+ GoAndPreparse( p_playlist, i_mode, p_item );
- for( ; p_item->input.i_options > 0; p_item->input.i_options-- )
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ return VLC_SUCCESS;
+}
+
+/** Add an input item to p_direct_parent in the category tree, and to the
+ * matching top category in onelevel **/
+int playlist_BothAddInput( playlist_t *p_playlist,
+ input_item_t *p_input,
+ playlist_item_t *p_direct_parent,
+ int i_mode, int i_pos )
+{
+ playlist_item_t *p_item, *p_up;
+ int i_top;
+ vlc_mutex_lock( & p_playlist->object_lock );
+
+ /* Add to category */
+ p_item = playlist_ItemNewFromInput( p_playlist, p_input );
+ if( p_item == NULL ) return VLC_EGENERIC;
+ fprintf( stderr, "Adding to CATEGORY\n");
+ AddItem( p_playlist, p_item, p_direct_parent, i_pos );
+
+ /* Add to onelevel */
+ p_item = playlist_ItemNewFromInput( p_playlist, p_input );
+ if( p_item == NULL ) return VLC_EGENERIC;
+ fprintf( stderr, "Adding to ONE\n");
+
+ p_up = p_direct_parent;
+ while( p_up->p_parent != p_playlist->p_root_category )
{
- free( p_item->input.ppsz_options[p_item->input.i_options - 1] );
- if( p_item->input.i_options == 1 ) free( p_item->input.ppsz_options );
+ p_up = p_up->p_parent;
}
-
- for( ; p_item->i_parents > 0 ; )
+ for( i_top = 0 ; i_top < p_playlist->p_root_onelevel->i_children; i_top++ )
{
- struct item_parent_t *p_parent = p_item->pp_parents[0];
- REMOVE_ELEM( p_item->pp_parents, p_item->i_parents, 0 );
- free( p_parent );
+ if( p_playlist->p_root_onelevel->pp_children[i_top]->p_input->i_id == p_up->p_input->i_id )
+ {
+ AddItem( p_playlist, p_item,
+ p_playlist->p_root_onelevel->pp_children[i_top], i_pos );
+ break;
+ }
}
+ GoAndPreparse( p_playlist, i_mode, p_item );
- vlc_mutex_unlock( &p_item->input.lock );
- vlc_mutex_destroy( &p_item->input.lock );
-
- free( p_item );
-
+ vlc_mutex_unlock( &p_playlist->object_lock );
return VLC_SUCCESS;
}
/**
- * Add a option to one item ( no need for p_playlist )
- *
- * \param p_item the item on which we want the info
- * \param psz_option the option
- * \return 0 on success
+ * Add an item where it should be added, when adding from a node
+ * (ex: directory access, playlist demuxers, services discovery, ... )
+ * \param p_playlist the playlist
+ * \param p_input the input to add
+ * \param p_parent the direct node
+ * \param p_item_in_category the item within category root (as returned by playlist_ItemToNode)
+ * \param b_forced_parent Are we forced to add only to p_parent ?
*/
-int playlist_ItemAddOption( playlist_item_t *p_item, const char *psz_option )
+void playlist_AddWhereverNeeded( playlist_t *p_playlist, input_item_t *p_input,
+ playlist_item_t *p_parent,
+ playlist_item_t *p_item_in_category,
+ vlc_bool_t b_forced_parent, int i_mode )
+{
+ /* If we have forced a parent :
+ * - Just add the input to the forced parent (which should be p_parent)
+ * Else
+ * - If we have item in category, add to it, and to onelevel (bothadd)
+ * - If we don't, just add to p_parent
+ */
+ if( b_forced_parent == VLC_TRUE || !p_item_in_category )
+ {
+ playlist_NodeAddInput( p_playlist, p_input, p_parent, i_mode,
+ PLAYLIST_END );
+ }
+ else
+ {
+ playlist_BothAddInput( p_playlist, p_input, p_item_in_category,
+ i_mode, PLAYLIST_END );
+ }
+}
+
+
+/** Add an input item to a given node */
+playlist_item_t * playlist_NodeAddInput( playlist_t *p_playlist,
+ input_item_t *p_input,
+ playlist_item_t *p_parent,
+ int i_mode, int i_pos )
{
- if( !psz_option ) return VLC_EGENERIC;
+ playlist_item_t *p_item;
+
+ /* Sanity checks */
+ if( !p_parent || p_parent->i_children == -1 )
+ {
+ msg_Err( p_playlist, "invalid node" );
+ }
- vlc_mutex_lock( &p_item->input.lock );
- INSERT_ELEM( p_item->input.ppsz_options, p_item->input.i_options,
- p_item->input.i_options, strdup( psz_option ) );
- vlc_mutex_unlock( &p_item->input.lock );
+ vlc_mutex_lock( &p_playlist->object_lock );
- return VLC_SUCCESS;
+ p_item = playlist_ItemNewFromInput( p_playlist, p_input );
+ if( p_item == NULL ) return NULL;
+ AddItem( p_playlist, p_item, p_parent, i_pos );
+
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ return p_item;
}
-/**
- * Add a parent to an item
- *
- * \param p_item the item
- * \param i_view the view in which the parent is
- * \param p_parent the parent to add
- * \return nothing
- */
-int playlist_ItemAddParent( playlist_item_t *p_item, int i_view,
- playlist_item_t *p_parent )
+/** Add a playlist item to a given node */
+void playlist_NodeAddItem( playlist_t *p_playlist, playlist_item_t *p_item,
+ playlist_item_t *p_parent, int i_mode, int i_pos )
{
- vlc_bool_t b_found = VLC_FALSE;
- int i;
-
- for( i= 0; i< p_item->i_parents ; i++ )
- {
- if( p_item->pp_parents[i]->i_view == i_view )
-
- {
- b_found = VLC_TRUE;
- break;
- }
- }
- if( b_found == VLC_FALSE )
- {
-
- struct item_parent_t *p_ip = (struct item_parent_t *)
- malloc(sizeof(struct item_parent_t) );
- p_ip->i_view = i_view;
- p_ip->p_parent = p_parent;
-
- INSERT_ELEM( p_item->pp_parents,
- p_item->i_parents, p_item->i_parents,
- p_ip );
- }
- return VLC_SUCCESS;
+ vlc_mutex_lock( &p_playlist->object_lock );
+ AddItem( p_playlist, p_item, p_parent, i_pos );
+ vlc_mutex_unlock( &p_playlist->object_lock );
}
+/*****************************************************************************
+ * Playlist item misc operations
+ *****************************************************************************/
+
/**
- * Copy all parents from parent to child
+ * Transform an item to a node. Return the node in the category tree, or NULL
+ * if not found there
+ * This function must be entered without the playlist lock
*/
-int playlist_CopyParents( playlist_item_t *p_parent,
- playlist_item_t *p_child )
+playlist_item_t *playlist_ItemToNode( playlist_t *p_playlist,
+ playlist_item_t *p_item )
{
- int i=0;
- for( i= 0 ; i< p_parent->i_parents; i ++ )
+ /* What we do
+ * Find the input in CATEGORY.
+ * - If we find it
+ * - change it to node
+ * - we'll return it at the end
+ * - Delete the input from ONELEVEL
+ * - If we don't find it, just change to node (we are probably in VLM)
+ * and return NULL
+ *
+ * If we were in ONELEVEL, we thus retrieve the node in CATEGORY (will be
+ * useful for later BothAddInput )
+ */
+
+ /** \todo First look if we don't already have it */
+ playlist_item_t *p_item_in_category = playlist_ItemFindFromInputAndRoot(
+ p_playlist, p_item->p_input->i_id,
+ p_playlist->p_root_category );
+
+ if( p_item_in_category )
{
- playlist_ItemAddParent( p_child,
- p_parent->pp_parents[i]->i_view,
- p_parent );
+ ChangeToNode( p_playlist, p_item_in_category );
+ playlist_DeleteFromInput( p_playlist, p_item->p_input->i_id,
+ p_playlist->p_root_onelevel, VLC_FALSE );
+ var_SetInteger( p_playlist, "item-change", p_item->p_input->i_id );
+ return p_item_in_category;
+ }
+ else
+ {
+ ChangeToNode( p_playlist, p_item );
+ return NULL;
}
- return VLC_SUCCESS;
}
+/** Transform an item to a node
+ * This function must be entered without the playlist lock
+ * \see playlist_ItemToNode
+ */
+playlist_item_t * playlist_LockItemToNode( playlist_t *p_playlist,
+ playlist_item_t *p_item )
+{
+ playlist_item_t *p_ret;
+ vlc_mutex_lock( &p_playlist->object_lock );
+ p_ret = playlist_ItemToNode( p_playlist, p_item );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ return p_ret;
+}
-/**********************************************************************
- * playlist_item_t structure accessors
- * These functions give access to the fields of the playlist_item_t
- * structure
- **********************************************************************/
+/** Find an item within a root, given its input id.
+ * \return the first found item, or NULL if not found
+ */
+playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist,
+ int i_input_id,
+ playlist_item_t *p_root )
+{
+ int i;
+ for( i = 0 ; i< p_root->i_children ; i++ )
+ {
+ if( p_root->pp_children[i]->i_children == -1 &&
+ p_root->pp_children[i]->p_input->i_id == i_input_id )
+ {
+ return p_root->pp_children[i];
+ }
+ else if( p_root->pp_children[i]->i_children >= 0 )
+ {
+ playlist_item_t *p_search =
+ playlist_ItemFindFromInputAndRoot( p_playlist, i_input_id,
+ p_root->pp_children[i] );
+ if( p_search ) return p_search;
+ }
+ }
+ return NULL;
+}
/**
- * Set the name of a playlist item
+ * Moves an item
+ *
+ * This function must be entered with the playlist lock
*
- * \param p_item the item
- * \param psz_name the new name
- * \return VLC_SUCCESS on success, VLC_EGENERIC on failure
+ * \param p_playlist the playlist
+ * \param p_item the item to move
+ * \param p_node the new parent of the item
+ * \param i_newpos the new position under this new parent
+ * \return VLC_SUCCESS or an error
*/
+int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item,
+ playlist_item_t *p_node, int i_newpos )
+{
+ int j;
+ playlist_item_t *p_detach = NULL;
+
+ if( p_node->i_children == -1 ) return VLC_EGENERIC;
+
+ p_detach = p_item->p_parent;
+ for( j = 0; j < p_detach->i_children; j++ )
+ {
+ if( p_detach->pp_children[j] == p_item ) break;
+ }
+ REMOVE_ELEM( p_detach->pp_children, p_detach->i_children, j );
+
+ /* Attach to new parent */
+ INSERT_ELEM( p_node->pp_children, p_node->i_children, i_newpos, p_item );
+
+ return VLC_SUCCESS;
+}
+
+/** Send a notification that an item has been added to a node */
+void playlist_SendAddNotify( playlist_t *p_playlist, int i_item_id,
+ int i_node_id )
+{
+ vlc_value_t val;
+ playlist_add_t *p_add = (playlist_add_t *)malloc(sizeof( playlist_add_t));
+ p_add->i_item = i_item_id;
+ p_add->i_node = i_node_id;
+ val.p_address = p_add;
+ var_Set( p_playlist, "item-append", val );
+ free( p_add );
+}
+
+/*****************************************************************************
+ * Playlist item accessors
+ *****************************************************************************/
+
+/** Set the name of a playlist item */
int playlist_ItemSetName( playlist_item_t *p_item, char *psz_name )
{
if( psz_name && p_item )
{
- if( p_item->input.psz_name ) free( p_item->input.psz_name );
- p_item->input.psz_name = strdup( psz_name );
+ if( p_item->p_input->psz_name ) free( p_item->p_input->psz_name );
+ p_item->p_input->psz_name = strdup( psz_name );
return VLC_SUCCESS;
}
return VLC_EGENERIC;
}
-/**
- * Set the duration of a playlist item
- * This function must be entered with the item lock
- *
- * \param p_item the item
- * \param i_duration the new duration
- * \return VLC_SUCCESS on success, VLC_EGENERIC on failure
+/** Set the duration of a playlist item
+ * \param i_duration the new duration in microseconds
*/
int playlist_ItemSetDuration( playlist_item_t *p_item, mtime_t i_duration )
{
char psz_buffer[MSTRTIME_MAX_SIZE];
if( p_item )
{
- p_item->input.i_duration = i_duration;
+ p_item->p_input->i_duration = i_duration;
if( i_duration != -1 )
{
secstotimestr( psz_buffer, (int)(i_duration/1000000) );
{
memcpy( psz_buffer, "--:--:--", sizeof("--:--:--") );
}
- vlc_input_item_AddInfo( &p_item->input, _("General") , _("Duration"),
+ vlc_input_item_AddInfo( p_item->p_input, _("General") , _("Duration"),
"%s", psz_buffer );
return VLC_SUCCESS;
return VLC_EGENERIC;
}
-/*
- * Guess the type of the item using the beginning of the mrl */
-static void GuessType( input_item_t *p_item)
+/** Add an option to a playlist item */
+void playlist_ItemAddOption( playlist_item_t *p_item,
+ const char *psz_option)
{
- int i;
- static struct { char *psz_search; int i_type; } types_array[] =
+ vlc_input_item_AddOption( p_item->p_input, psz_option );
+}
+
+/***************************************************************************
+ * The following functions are local
+ ***************************************************************************/
+
+/* Enqueue an item for preparsing, and play it, if needed */
+void GoAndPreparse( playlist_t *p_playlist, int i_mode,
+ playlist_item_t *p_item )
+{
+#if 0
+ if( (i_mode & PLAYLIST_GO ) && p_view )
{
- { "http", ITEM_TYPE_NET },
- { "dvd", ITEM_TYPE_DISC },
- { "cdda", ITEM_TYPE_CDDA },
- { "mms", ITEM_TYPE_NET },
- { "rtsp", ITEM_TYPE_NET },
- { "udp", ITEM_TYPE_NET },
- { "rtp", ITEM_TYPE_NET },
- { "vcd", ITEM_TYPE_DISC },
- { "v4l", ITEM_TYPE_CARD },
- { "dshow", ITEM_TYPE_CARD },
- { "pvr", ITEM_TYPE_CARD },
- { "dvb", ITEM_TYPE_CARD },
- { "qpsk", ITEM_TYPE_CARD },
- { "sdp", ITEM_TYPE_NET },
- { NULL, 0 }
- };
-
-#if 0 /* Unused */
- static struct { char *psz_search; int i_type; } exts_array[] =
+ p_playlist->request.b_request = VLC_TRUE;
+ /* FIXME ... */
+ p_playlist->request.i_view = VIEW_CATEGORY;
+ p_playlist->request.p_node = p_view->p_root;
+ p_playlist->request.p_item = p_item;
+
+ if( p_playlist->p_input )
+ {
+ input_StopThread( p_playlist->p_input );
+ }
+ p_playlist->status.i_status = PLAYLIST_RUNNING;
+ }
+#endif
+ if( i_mode & PLAYLIST_PREPARSE &&
+ var_CreateGetBool( p_playlist, "auto-preparse" ) )
{
- { "mp3", ITEM_TYPE_AFILE },
- { NULL, 0 }
- };
+ playlist_PreparseEnqueue( p_playlist, p_item->p_input );
+ }
+}
+
+/* Add the playlist item to the requested node and fire a notification */
+void AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
+ playlist_item_t *p_node, int i_pos )
+{
+ INSERT_ELEM( p_playlist->pp_items, p_playlist->i_size,
+ p_playlist->i_size, p_item );
+#if 0
+ fprintf( stderr, "Adding input %s (id %i) - playlist item id %i "
+ "to node %s (id %i)\n",
+ p_item->p_input->psz_name, p_item->p_input->i_id,
+ p_item->i_id, p_node->p_input->psz_name,
+ p_node->i_id );
#endif
+ INSERT_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size,
+ p_playlist->i_all_size, p_item );
+ p_playlist->i_enabled ++;
+
+ if( i_pos == PLAYLIST_END )
+ {
+ playlist_NodeAppend( p_playlist, p_item, p_node );
+ }
+ else
+ {
+ playlist_NodeInsert( p_playlist, p_item, p_node, i_pos );
+ }
+
+ playlist_SendAddNotify( p_playlist, p_item->i_id, p_node->i_id );
+}
+
+/* Actually convert an item to a node */
+void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item )
+{
+ int i;
+ if( p_item->i_children == -1 )
+ p_item->i_children = 0;
+
+ /* Remove it from the array of available items */
+ for( i = 0 ; i < p_playlist->i_size ; i++ )
+ {
+ if( p_item == p_playlist->pp_items[i] )
+ {
+ REMOVE_ELEM( p_playlist->pp_items, p_playlist->i_size, i );
+ }
+ }
+}
+
+/* Do the actual removal */
+int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item,
+ vlc_bool_t b_stop )
+{
+ int i, i_top, i_bottom;
+ int i_id = p_item->i_id;
+ vlc_bool_t b_flag = VLC_FALSE;
+
+ //fprintf( stderr, "Deleting item %i - %s\n", i_id,
+ // p_item->p_input->psz_name );
+
+ if( p_item->i_children > -1 )
+ {
+ return playlist_NodeDelete( p_playlist, p_item, VLC_TRUE, VLC_FALSE );
+ }
+ var_SetInteger( p_playlist, "item-deleted", i_id );
+
+ /* Remove the item from the bank */
+ i_bottom = 0; i_top = p_playlist->i_all_size - 1;
+ i = i_top / 2;
+ while( p_playlist->pp_all_items[i]->i_id != i_id &&
+ i_top > i_bottom )
+ {
+ if( p_playlist->pp_all_items[i]->i_id < i_id )
+ {
+ i_bottom = i + 1;
+ }
+ else
+ {
+ i_top = i - 1;
+ }
+ i = i_bottom + ( i_top - i_bottom ) / 2;
+ }
+ if( p_playlist->pp_all_items[i]->i_id == i_id )
+ {
+ REMOVE_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size, i );
+ }
- for( i = 0; types_array[i].psz_search != NULL; i++ )
+ /* Check if it is the current item */
+ if( p_playlist->status.p_item == p_item )
{
- if( !strncmp( p_item->psz_uri, types_array[i].psz_search,
- strlen( types_array[i].psz_search ) ) )
+ /* Hack we don't call playlist_Control for lock reasons */
+ if( b_stop )
{
- p_item->i_type = types_array[i].i_type;
- return;
+ p_playlist->status.i_status = PLAYLIST_STOPPED;
+ p_playlist->request.b_request = VLC_TRUE;
+ p_playlist->request.p_item = NULL;
+ msg_Info( p_playlist, "stopping playback" );
}
+ b_flag = VLC_TRUE;
}
- p_item->i_type = ITEM_TYPE_VFILE;
+
+ msg_Dbg( p_playlist, "deleting playlist item `%s'",
+ p_item->p_input->psz_name );
+
+ /* Remove the item from its parent */
+ playlist_NodeRemoveItem( p_playlist, p_item, p_item->p_parent );
+
+ if( b_flag == VLC_FALSE )
+ playlist_ItemDelete( p_item );
+ else
+ p_item->i_flags |= PLAYLIST_REMOVE_FLAG;
+
+ return VLC_SUCCESS;
}
psz_uri = (char *)malloc(sizeof(char)*strlen(psz_filename) + 17 );
sprintf( psz_uri, "file/playlist://%s", psz_filename);
- i_id = playlist_Add( p_playlist, psz_uri, psz_uri,
+ i_id = playlist_PlaylistAdd( p_playlist, psz_uri, psz_uri,
PLAYLIST_INSERT , PLAYLIST_END);
vlc_mutex_lock( &p_playlist->object_lock );
p_item = playlist_ItemGetById( p_playlist, i_id );
- p_item->b_autodeletion = VLC_TRUE;
vlc_mutex_unlock( &p_playlist->object_lock );
playlist_Play(p_playlist);
psz_uri = (char *)malloc(sizeof(char)*strlen(psz_filename) + 17 );
sprintf( psz_uri, "file/playlist://%s", psz_filename);
- i_id = playlist_Add( p_playlist, psz_uri, psz_uri,
+ i_id = playlist_PlaylistAdd( p_playlist, psz_uri, psz_uri,
PLAYLIST_INSERT , PLAYLIST_END);
vlc_mutex_lock( &p_playlist->object_lock );
p_item = playlist_ItemGetById( p_playlist, i_id );
- p_item->b_autodeletion = VLC_TRUE;
vlc_mutex_unlock( &p_playlist->object_lock );
playlist_Play(p_playlist);
}
/**
- * Export a playlist to a certain type of playlistfile
+ * Export a node of the playlist to a certain type of playlistfile
*
* \param p_playlist the playlist to export
* \param psz_filename the location where the exported file will be saved
+ * \param p_export_root the root node to export
* \param psz_type the type of playlist file to create.
* \return VLC_SUCCESS on success
*/
int playlist_Export( playlist_t * p_playlist, const char *psz_filename ,
- const char *psz_type)
+ playlist_item_t *p_export_root,const char *psz_type )
{
module_t *p_module;
playlist_export_t *p_export;
- msg_Info( p_playlist, "saving playlist to file %s", psz_filename );
+ if( p_export_root == NULL ) return VLC_EGENERIC;
+
+ msg_Info( p_playlist, "saving %s to file %s",
+ p_export_root->p_input->psz_name, psz_filename );
/* Prepare the playlist_export_t structure */
p_export = (playlist_export_t *)malloc( sizeof(playlist_export_t) );
if( !p_export)
{
- msg_Err( p_playlist, "out of memory");
+ msg_Err( p_playlist, "out of memory" );
return VLC_ENOMEM;
}
p_export->psz_filename = NULL;
return VLC_EGENERIC;
}
- p_playlist->p_private = (void *)p_export;
+ p_export->p_root = p_export_root;
+
/* Lock the playlist */
vlc_mutex_lock( &p_playlist->object_lock );
+ p_playlist->p_private = (void *)p_export;
/* And call the module ! All work is done now */
p_module = module_Need( p_playlist, "playlist export", psz_type, VLC_TRUE);
+++ /dev/null
-/*****************************************************************************
- * playlist.c : Playlist management functions
- *****************************************************************************
- * Copyright (C) 1999-2004 the VideoLAN team
- * $Id$
- *
- * Authors: Samuel Hocevar <sam@zoy.org>
- * Clément Stenac <zorglub@videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#include <stdlib.h> /* free(), strtol() */
-#include <stdio.h> /* sprintf() */
-#include <string.h> /* strerror() */
-
-#include <vlc/vlc.h>
-#include <vlc/vout.h>
-#include <vlc/sout.h>
-#include <vlc/input.h>
-
-#include "vlc_playlist.h"
-
-#include "vlc_interaction.h"
-
-#define TITLE_CATEGORY N_( "By category" )
-#define TITLE_SIMPLE N_( "Manually added" )
-#define TITLE_ALL N_( "All items, unsorted" )
-
-#undef PLAYLIST_PROFILE
-#undef PLAYLIST_DEBUG
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static void RunThread ( playlist_t * );
-static void RunPreparse( playlist_preparse_t * );
-static playlist_item_t * NextItem ( playlist_t * );
-static int PlayItem ( playlist_t *, playlist_item_t * );
-
-int playlist_vaControl( playlist_t * p_playlist, int i_query, va_list args );
-
-void playlist_PreparseEnqueueItemSub( playlist_t *, playlist_item_t * );
-
-playlist_item_t *playlist_RecursiveFindLast(playlist_t *p_playlist,
- playlist_item_t *p_node );
-
-/*****************************************************************************
- * Helper Function for NextItem
- *****************************************************************************/
-
-playlist_item_t *playlist_RecursiveFindLast(playlist_t *p_playlist,
- playlist_item_t *p_node )
-{
- int i;
- playlist_item_t *p_item;
- for ( i = p_node->i_children - 1; i >= 0; i-- )
- {
- if( p_node->pp_children[i]->i_children == -1 )
- return p_node->pp_children[i];
- else if(p_node->pp_children[i]->i_children > 0)
- {
- p_item = playlist_RecursiveFindLast( p_playlist,
- p_node->pp_children[i] );
- if ( p_item != NULL )
- return p_item;
- }
- else if( i == 0 )
- return NULL;
- }
- return NULL;
-}
-
-
-/**
- * Create playlist
- *
- * Create a playlist structure.
- * \param p_parent the vlc object that is to be the parent of this playlist
- * \return a pointer to the created playlist, or NULL on error
- */
-playlist_t * __playlist_Create ( vlc_object_t *p_parent )
-{
- playlist_t *p_playlist;
- playlist_view_t *p_view;
- vlc_value_t val;
-
- /* Allocate structure */
- p_playlist = vlc_object_create( p_parent, VLC_OBJECT_PLAYLIST );
- if( !p_playlist )
- {
- msg_Err( p_parent, "out of memory" );
- return NULL;
- }
-
- /* These variables control updates */
- var_Create( p_playlist, "intf-change", VLC_VAR_BOOL );
- val.b_bool = VLC_TRUE;
- var_Set( p_playlist, "intf-change", val );
-
- var_Create( p_playlist, "item-change", VLC_VAR_INTEGER );
- val.i_int = -1;
- var_Set( p_playlist, "item-change", val );
-
- var_Create( p_playlist, "item-deleted", VLC_VAR_INTEGER );
- val.i_int = -1;
- var_Set( p_playlist, "item-deleted", val );
-
- var_Create( p_playlist, "item-append", VLC_VAR_ADDRESS );
-
- var_Create( p_playlist, "playlist-current", VLC_VAR_INTEGER );
- val.i_int = -1;
- var_Set( p_playlist, "playlist-current", val );
-
- var_Create( p_playlist, "intf-popupmenu", VLC_VAR_BOOL );
-
- var_Create( p_playlist, "intf-show", VLC_VAR_BOOL );
- val.b_bool = VLC_TRUE;
- var_Set( p_playlist, "intf-show", val );
-
-
- /* Variables to control playback */
- var_CreateGetBool( p_playlist, "play-and-stop" );
- var_CreateGetBool( p_playlist, "random" );
- var_CreateGetBool( p_playlist, "repeat" );
- var_CreateGetBool( p_playlist, "loop" );
-
- /* Initialise data structures */
- vlc_mutex_init( p_playlist, &p_playlist->gc_lock );
- p_playlist->i_last_id = 0;
- p_playlist->b_go_next = VLC_TRUE;
- p_playlist->p_input = NULL;
-
- p_playlist->request_date = 0;
-
- p_playlist->i_views = 0;
- p_playlist->pp_views = NULL;
-
- p_playlist->i_index = -1;
- p_playlist->i_size = 0;
- p_playlist->pp_items = NULL;
- p_playlist->i_all_size = 0;
- p_playlist->pp_all_items = 0;
-
- playlist_ViewInsert( p_playlist, VIEW_CATEGORY, TITLE_CATEGORY );
- playlist_ViewInsert( p_playlist, VIEW_ALL, TITLE_ALL );
-
- p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
-
- p_playlist->p_general =
- playlist_NodeCreate( p_playlist, VIEW_CATEGORY,
- _( "General" ), p_view->p_root );
- p_playlist->p_general->i_flags |= PLAYLIST_RO_FLAG;
-
- /* Set startup status
- * We set to simple view on startup for interfaces that don't do
- * anything */
- p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
- p_playlist->status.i_view = VIEW_CATEGORY;
- p_playlist->status.p_item = NULL;
- p_playlist->status.p_node = p_view->p_root;
- p_playlist->request.b_request = VLC_FALSE;
- p_playlist->status.i_status = PLAYLIST_STOPPED;
-
- p_playlist->i_sort = SORT_ID;
- p_playlist->i_order = ORDER_NORMAL;
-
- p_playlist->p_stats = (global_stats_t *)malloc( sizeof( global_stats_t ) );
- vlc_mutex_init( p_playlist, &p_playlist->p_stats->lock );
-
- /* Finally, launch the thread ! */
- if( vlc_thread_create( p_playlist, "playlist", RunThread,
- VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
- {
- msg_Err( p_playlist, "cannot spawn playlist thread" );
- vlc_object_destroy( p_playlist );
- return NULL;
- }
-
- /* Preparsing stuff */
- p_playlist->p_preparse = vlc_object_create( p_playlist,
- sizeof( playlist_preparse_t ) );
- if( !p_playlist->p_preparse )
- {
- msg_Err( p_playlist, "unable to create preparser" );
- vlc_object_destroy( p_playlist );
- return NULL;
- }
-
- // Preparse
- p_playlist->p_preparse->i_waiting = 0;
- p_playlist->p_preparse->pi_waiting = NULL;
-
- // Interaction
- p_playlist->p_interaction = NULL;
-
- vlc_object_attach( p_playlist->p_preparse, p_playlist );
- if( vlc_thread_create( p_playlist->p_preparse, "preparser",
- RunPreparse, VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
- {
- msg_Err( p_playlist, "cannot spawn preparse thread" );
- vlc_object_detach( p_playlist->p_preparse );
- vlc_object_destroy( p_playlist->p_preparse );
- return NULL;
- }
-
- /* The object has been initialized, now attach it */
- vlc_object_attach( p_playlist, p_parent );
-
- return p_playlist;
-}
-
-/**
- * Destroy the playlist.
- *
- * Delete all items in the playlist and free the playlist structure.
- * \param p_playlist the playlist structure to destroy
- * \return VLC_SUCCESS or an error
- */
-int playlist_Destroy( playlist_t * p_playlist )
-{
- int i;
- p_playlist->b_die = 1;
-
- while( p_playlist->i_sds )
- {
- playlist_ServicesDiscoveryRemove( p_playlist,
- p_playlist->pp_sds[0]->psz_module );
- }
-
- if( p_playlist->p_interaction )
- {
- intf_InteractionDestroy( p_playlist->p_interaction );
- }
-
- vlc_thread_join( p_playlist->p_preparse );
- vlc_thread_join( p_playlist );
-
- vlc_object_detach( p_playlist->p_preparse );
-
- var_Destroy( p_playlist, "intf-change" );
- var_Destroy( p_playlist, "item-change" );
- var_Destroy( p_playlist, "playlist-current" );
- var_Destroy( p_playlist, "intf-popmenu" );
- var_Destroy( p_playlist, "intf-show" );
- var_Destroy( p_playlist, "play-and-stop" );
- var_Destroy( p_playlist, "random" );
- var_Destroy( p_playlist, "repeat" );
- var_Destroy( p_playlist, "loop" );
-
- playlist_Clear( p_playlist );
-
- for( i = p_playlist->i_views - 1; i >= 0 ; i-- )
- {
- playlist_view_t *p_view = p_playlist->pp_views[i];
- if( p_view->psz_name )
- free( p_view->psz_name );
- playlist_ItemDelete( p_view->p_root );
- REMOVE_ELEM( p_playlist->pp_views, p_playlist->i_views, i );
- free( p_view );
- }
-
- if( p_playlist->p_stats )
- free( p_playlist->p_stats );
-
- vlc_mutex_destroy( &p_playlist->gc_lock );
- vlc_object_destroy( p_playlist->p_preparse );
- vlc_object_destroy( p_playlist );
-
- return VLC_SUCCESS;
-}
-
-
-/**
- * Do a playlist action.
- *
- * If there is something in the playlist then you can do playlist actions.
- *
- * Playlist lock must not be taken when calling this function
- *
- * \param p_playlist the playlist to do the command on
- * \param i_query the command to do
- * \param variable number of arguments
- * \return VLC_SUCCESS or an error
- */
-int playlist_LockControl( playlist_t * p_playlist, int i_query, ... )
-{
- va_list args;
- int i_result;
- va_start( args, i_query );
- vlc_mutex_lock( &p_playlist->object_lock );
- i_result = playlist_vaControl( p_playlist, i_query, args );
- va_end( args );
- vlc_mutex_unlock( &p_playlist->object_lock );
- return i_result;
-}
-
-/**
- * Do a playlist action.
- *
- * If there is something in the playlist then you can do playlist actions.
- *
- * Playlist lock must be taken when calling this function
- *
- * \param p_playlist the playlist to do the command on
- * \param i_query the command to do
- * \param variable number of arguments
- * \return VLC_SUCCESS or an error
- */
-int playlist_Control( playlist_t * p_playlist, int i_query, ... )
-{
- va_list args;
- int i_result;
- va_start( args, i_query );
- i_result = playlist_vaControl( p_playlist, i_query, args );
- va_end( args );
-
- return i_result;
-}
-
-int playlist_vaControl( playlist_t * p_playlist, int i_query, va_list args )
-{
- playlist_view_t *p_view;
- playlist_item_t *p_item, *p_node;
- int i_view;
- vlc_value_t val;
-
-#ifdef PLAYLIST_PROFILE
- p_playlist->request_date = mdate();
-#endif
-
- if( p_playlist->i_size <= 0 )
- {
- return VLC_EGENERIC;
- }
-
- switch( i_query )
- {
- case PLAYLIST_STOP:
- p_playlist->status.i_status = PLAYLIST_STOPPED;
- p_playlist->request.b_request = VLC_TRUE;
- p_playlist->request.p_item = NULL;
- break;
-
- case PLAYLIST_ITEMPLAY:
- p_item = (playlist_item_t *)va_arg( args, playlist_item_t * );
- if ( p_item == NULL || p_item->input.psz_uri == NULL )
- return VLC_EGENERIC;
- p_playlist->status.i_status = PLAYLIST_RUNNING;
- p_playlist->request.i_skip = 0;
- p_playlist->request.b_request = VLC_TRUE;
- p_playlist->request.p_item = p_item;
- p_playlist->request.i_view = p_playlist->status.i_view;
- p_view = playlist_ViewFind( p_playlist, p_playlist->status.i_view );
- if( p_view )
- {
- p_playlist->request.p_node = p_view->p_root;
- }
- else
- {
- p_playlist->request.p_node = NULL;
- }
- break;
-
- case PLAYLIST_VIEWPLAY:
- i_view = (int)va_arg( args,int );
- p_node = (playlist_item_t *)va_arg( args, playlist_item_t * );
- p_item = (playlist_item_t *)va_arg( args, playlist_item_t * );
- if ( p_node == NULL ) //|| (p_item != NULL && p_item->input.psz_uri
- // == NULL ))
- {
- p_playlist->status.i_status = PLAYLIST_STOPPED;
- p_playlist->request.b_request = VLC_TRUE;
- return VLC_SUCCESS;
- }
- p_playlist->status.i_status = PLAYLIST_RUNNING;
- p_playlist->request.i_skip = 0;
- p_playlist->request.b_request = VLC_TRUE;
- p_playlist->request.i_view = i_view;
- p_playlist->request.p_node = p_node;
- p_playlist->request.p_item = p_item;
-
- /* Don't go further if the node doesn't want to */
- if( ! p_playlist->request.p_node->i_flags & PLAYLIST_SKIP_FLAG )
- {
- p_playlist->b_go_next = VLC_FALSE;
- }
- else
- {
- p_playlist->b_go_next = VLC_TRUE;
- }
- break;
-
- case PLAYLIST_PLAY:
- p_playlist->status.i_status = PLAYLIST_RUNNING;
-
- if( p_playlist->p_input )
- {
- val.i_int = PLAYING_S;
- var_Set( p_playlist->p_input, "state", val );
- break;
- }
-
- /* FIXME : needed ? */
- p_playlist->request.b_request = VLC_TRUE;
- p_playlist->request.i_view = p_playlist->status.i_view;
- p_playlist->request.p_node = p_playlist->status.p_node;
- p_playlist->request.p_item = p_playlist->status.p_item;
- p_playlist->request.i_skip = 0;
- p_playlist->request.i_goto = -1;
- break;
-
- case PLAYLIST_AUTOPLAY:
- p_playlist->status.i_status = PLAYLIST_RUNNING;
- p_playlist->status.p_node = p_playlist->p_general;
-
- p_playlist->request.b_request = VLC_FALSE;
- break;
-
- case PLAYLIST_PAUSE:
- val.i_int = 0;
- if( p_playlist->p_input )
- var_Get( p_playlist->p_input, "state", &val );
-
- if( val.i_int == PAUSE_S )
- {
- p_playlist->status.i_status = PLAYLIST_RUNNING;
- if( p_playlist->p_input )
- {
- val.i_int = PLAYING_S;
- var_Set( p_playlist->p_input, "state", val );
- }
- }
- else
- {
- p_playlist->status.i_status = PLAYLIST_PAUSED;
- if( p_playlist->p_input )
- {
- val.i_int = PAUSE_S;
- var_Set( p_playlist->p_input, "state", val );
- }
- }
- break;
-
- case PLAYLIST_SKIP:
- p_playlist->request.i_view = p_playlist->status.i_view;
- if( p_playlist->status.i_view > -1 )
- {
- p_playlist->request.p_node = p_playlist->status.p_node;
- p_playlist->request.p_item = p_playlist->status.p_item;
- }
- else
- {
- p_playlist->request.p_node = NULL;
- p_playlist->request.p_item = NULL;
- }
- p_playlist->request.i_skip = (int) va_arg( args, int );
- p_playlist->request.b_request = VLC_TRUE;
- break;
-
- case PLAYLIST_GOTO:
- p_playlist->status.i_status = PLAYLIST_RUNNING;
- p_playlist->request.p_node = NULL;
- p_playlist->request.p_item = NULL;
- p_playlist->request.i_view = -1;
- p_playlist->request.i_goto = (int) va_arg( args, int );
- p_playlist->request.b_request = VLC_TRUE;
- break;
-
- default:
- msg_Err( p_playlist, "unknown playlist query" );
- return VLC_EBADVAR;
- break;
- }
-
- return VLC_SUCCESS;
-}
-
-int playlist_PreparseEnqueue( playlist_t *p_playlist,
- input_item_t *p_item )
-{
- vlc_mutex_lock( &p_playlist->p_preparse->object_lock );
- INSERT_ELEM( p_playlist->p_preparse->pi_waiting,
- p_playlist->p_preparse->i_waiting,
- p_playlist->p_preparse->i_waiting,
- p_item->i_id );
- vlc_mutex_unlock( &p_playlist->p_preparse->object_lock );
- return VLC_SUCCESS;
-}
-
-/* Should only be called if playlist and preparser are locked */
-void playlist_PreparseEnqueueItemSub( playlist_t *p_playlist,
- playlist_item_t *p_item )
-{
- int i;
- if( p_item->i_children == -1 )
- {
- INSERT_ELEM( p_playlist->p_preparse->pi_waiting,
- p_playlist->p_preparse->i_waiting,
- p_playlist->p_preparse->i_waiting,
- (p_item->input.i_id) );
- }
- else
- {
- for( i = 0; i < p_item->i_children; i++)
- {
- playlist_PreparseEnqueueItemSub( p_playlist,
- p_item->pp_children[i] );
- }
- }
-}
-
-int playlist_PreparseEnqueueItem( playlist_t *p_playlist,
- playlist_item_t *p_item )
-{
- vlc_mutex_lock( &p_playlist->object_lock );
- vlc_mutex_lock( &p_playlist->p_preparse->object_lock );
- playlist_PreparseEnqueueItemSub( p_playlist, p_item );
- vlc_mutex_unlock( &p_playlist->p_preparse->object_lock );
- vlc_mutex_unlock( &p_playlist->object_lock );
- return VLC_SUCCESS;
-}
-
-
-/* Destroy remaining objects */
-static mtime_t ObjectGarbageCollector( playlist_t *p_playlist, int i_type,
- mtime_t destroy_date )
-{
- vlc_object_t *p_obj;
-
- if( destroy_date > mdate() ) return destroy_date;
-
- if( destroy_date == 0 )
- {
- /* give a little time */
- return mdate() + I64C(1000000);
- }
- else
- {
- vlc_mutex_lock( &p_playlist->gc_lock );
- while( ( p_obj = vlc_object_find( p_playlist, i_type, FIND_CHILD ) ) )
- {
- if( p_obj->p_parent != (vlc_object_t*)p_playlist )
- {
- /* only first child (ie unused) */
- vlc_object_release( p_obj );
- break;
- }
- if( i_type == VLC_OBJECT_VOUT )
- {
- msg_Dbg( p_playlist, "garbage collector destroys 1 vout" );
- vlc_object_detach( p_obj );
- vlc_object_release( p_obj );
- vout_Destroy( (vout_thread_t *)p_obj );
- }
- else if( i_type == VLC_OBJECT_SOUT )
- {
- vlc_object_release( p_obj );
- sout_DeleteInstance( (sout_instance_t*)p_obj );
- }
- }
- vlc_mutex_unlock( &p_playlist->gc_lock );
- return 0;
- }
-}
-
-/*****************************************************************************
- * RunThread: main playlist thread
- *****************************************************************************/
-static void RunThread ( playlist_t *p_playlist )
-{
- vlc_object_t *p_obj;
- playlist_item_t *p_item = NULL;
-
- mtime_t i_vout_destroyed_date = 0;
- mtime_t i_sout_destroyed_date = 0;
-
- int i_loops = 0;
-
- playlist_item_t *p_autodelete_item = NULL;
-
- /* Tell above that we're ready */
- vlc_thread_ready( p_playlist );
-
- while( !p_playlist->b_die )
- {
- i_loops++;
- if( p_playlist->p_interaction )
- {
- stats_TimerStart( p_playlist, "Interaction thread",
- STATS_TIMER_INTERACTION );
- intf_InteractionManage( p_playlist );
- stats_TimerStop( p_playlist, STATS_TIMER_INTERACTION );
- }
-
- if( i_loops %5 == 0 && p_playlist->p_stats )
- {
- stats_ComputeGlobalStats( p_playlist, p_playlist->p_stats );
- }
-
- vlc_mutex_lock( &p_playlist->object_lock );
-
- /* First, check if we have something to do */
- /* FIXME : this can be called several times */
- if( p_playlist->request.b_request )
- {
-#ifdef PLAYLIST_PROFILE
- msg_Dbg(p_playlist, "beginning processing of request, "
- I64Fi" us ", mdate() - p_playlist->request_date );
-#endif
- /* Stop the existing input */
- if( p_playlist->p_input )
- {
- input_StopThread( p_playlist->p_input );
- }
- /* The code below will start the next input for us */
- if( p_playlist->status.i_status == PLAYLIST_STOPPED )
- {
- p_playlist->request.b_request = VLC_FALSE;
- }
- }
-
- /* If there is an input, check that it doesn't need to die. */
- if( p_playlist->p_input )
- {
- if( i_loops % 5 == 0 )
- {
- stats_ComputeInputStats( p_playlist->p_input,
- p_playlist->p_input->input.p_item->p_stats );
-// stats_DumpInputStats(
-// p_playlist->p_input->input.p_item->p_stats );
- }
-
- /* This input is dead. Remove it ! */
- if( p_playlist->p_input->b_dead )
- {
- input_thread_t *p_input;
-
- p_input = p_playlist->p_input;
- p_playlist->p_input = NULL;
-
- /* Release the playlist lock, because we may get stuck
- * in input_DestroyThread() for some time. */
- vlc_mutex_unlock( &p_playlist->object_lock );
-
- /* Destroy input */
- input_DestroyThread( p_input );
-
- /* Unlink current input
- * (_after_ input_DestroyThread for vout garbage collector) */
- vlc_object_detach( p_input );
-
- /* Destroy object */
- vlc_object_destroy( p_input );
-
- i_vout_destroyed_date = 0;
- i_sout_destroyed_date = 0;
-
- if( p_playlist->status.p_item->i_flags
- & PLAYLIST_REMOVE_FLAG )
- {
- playlist_ItemDelete( p_item );
- p_playlist->status.p_item = NULL;
- }
-
- continue;
- }
- /* This input is dying, let it do */
- else if( p_playlist->p_input->b_die )
- {
- ;
- }
- /* This input has finished, ask it to die ! */
- else if( p_playlist->p_input->b_error
- || p_playlist->p_input->b_eof )
- {
- /* TODO FIXME XXX TODO FIXME XXX */
- /* Check for autodeletion */
-
- if( p_playlist->status.p_item->i_flags & PLAYLIST_DEL_FLAG )
- {
- p_autodelete_item = p_playlist->status.p_item;
- }
- input_StopThread( p_playlist->p_input );
- /* Select the next playlist item */
- vlc_mutex_unlock( &p_playlist->object_lock );
- continue;
- }
- else if( p_playlist->p_input->i_state != INIT_S )
- {
- vlc_mutex_unlock( &p_playlist->object_lock );
- i_vout_destroyed_date =
- ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT,
- i_vout_destroyed_date );
- i_sout_destroyed_date =
- ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT,
- i_sout_destroyed_date );
- vlc_mutex_lock( &p_playlist->object_lock );
- }
- }
- else if( p_playlist->status.i_status != PLAYLIST_STOPPED )
- {
- /* Start another input.
- * Get the next item to play */
- stats_TimerStart( p_playlist, "Playlist walk",
- STATS_TIMER_PLAYLIST_WALK );
- p_item = NextItem( p_playlist );
- stats_TimerStop( p_playlist, STATS_TIMER_PLAYLIST_WALK );
-
- /* We must stop */
- if( p_item == NULL )
- {
- if( p_autodelete_item )
- {
- playlist_Delete( p_playlist,
- p_autodelete_item->input.i_id );
- p_autodelete_item = NULL;
- }
- p_playlist->status.i_status = PLAYLIST_STOPPED;
- vlc_mutex_unlock( &p_playlist->object_lock );
- continue;
- }
-
- PlayItem( p_playlist, p_item );
-
- if( p_autodelete_item )
- {
- playlist_Delete( p_playlist, p_autodelete_item->input.i_id );
- p_autodelete_item = NULL;
- }
- }
- else if( p_playlist->status.i_status == PLAYLIST_STOPPED )
- {
- if( p_item && p_playlist->status.p_item &&
- p_playlist->status.p_item->i_flags & PLAYLIST_REMOVE_FLAG )
- {
- playlist_ItemDelete( p_item );
- p_playlist->status.p_item = NULL;
- }
-
- /* Collect garbage */
- vlc_mutex_unlock( &p_playlist->object_lock );
- i_sout_destroyed_date =
- ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT, mdate() );
- i_vout_destroyed_date =
- ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT, mdate() );
- vlc_mutex_lock( &p_playlist->object_lock );
- }
- vlc_mutex_unlock( &p_playlist->object_lock );
-
- msleep( INTF_IDLE_SLEEP / 2 );
-
- /* Stop sleeping earlier if we have work */
- /* TODO : statistics about this */
- if ( p_playlist->request.b_request &&
- p_playlist->status.i_status == PLAYLIST_RUNNING )
- {
- continue;
- }
-
- msleep( INTF_IDLE_SLEEP / 2 );
- }
-
- /* Playlist dying */
-
- /* If there is an input, kill it */
- while( 1 )
- {
- vlc_mutex_lock( &p_playlist->object_lock );
-
- if( p_playlist->p_input == NULL )
- {
- vlc_mutex_unlock( &p_playlist->object_lock );
- break;
- }
-
- if( p_playlist->p_input->b_dead )
- {
- input_thread_t *p_input;
-
- /* Unlink current input */
- p_input = p_playlist->p_input;
- p_playlist->p_input = NULL;
- vlc_mutex_unlock( &p_playlist->object_lock );
-
- /* Destroy input */
- input_DestroyThread( p_input );
- /* Unlink current input (_after_ input_DestroyThread for vout
- * garbage collector)*/
- vlc_object_detach( p_input );
-
- /* Destroy object */
- vlc_object_destroy( p_input );
- continue;
- }
- else if( p_playlist->p_input->b_die )
- {
- /* This input is dying, leave it alone */
- ;
- }
- else if( p_playlist->p_input->b_error || p_playlist->p_input->b_eof )
- {
- input_StopThread( p_playlist->p_input );
- vlc_mutex_unlock( &p_playlist->object_lock );
- continue;
- }
- else
- {
- p_playlist->p_input->b_eof = 1;
- }
-
- vlc_mutex_unlock( &p_playlist->object_lock );
-
- msleep( INTF_IDLE_SLEEP );
- }
-
- /* close all remaining sout */
- while( ( p_obj = vlc_object_find( p_playlist,
- VLC_OBJECT_SOUT, FIND_CHILD ) ) )
- {
- vlc_object_release( p_obj );
- sout_DeleteInstance( (sout_instance_t*)p_obj );
- }
-
- /* close all remaining vout */
- while( ( p_obj = vlc_object_find( p_playlist,
- VLC_OBJECT_VOUT, FIND_CHILD ) ) )
- {
- vlc_object_detach( p_obj );
- vlc_object_release( p_obj );
- vout_Destroy( (vout_thread_t *)p_obj );
- }
-}
-
-/* Queue for items to preparse */
-static void RunPreparse ( playlist_preparse_t *p_obj )
-{
- playlist_t *p_playlist = (playlist_t *)p_obj->p_parent;
- vlc_bool_t b_sleep;
-
- /* Tell above that we're ready */
- vlc_thread_ready( p_obj );
-
- while( !p_playlist->b_die )
- {
- vlc_mutex_lock( &p_obj->object_lock );
-
- if( p_obj->i_waiting > 0 )
- {
- int i_current_id = p_obj->pi_waiting[0];
- playlist_item_t *p_current;
- REMOVE_ELEM( p_obj->pi_waiting, p_obj->i_waiting, 0 );
- vlc_mutex_unlock( &p_obj->object_lock );
- vlc_mutex_lock( &p_playlist->object_lock );
-
- p_current = playlist_ItemGetById( p_playlist, i_current_id );
- if( p_current )
- {
- vlc_bool_t b_preparsed = VLC_FALSE;
- if( strncmp( p_current->input.psz_uri, "http:", 5 ) &&
- strncmp( p_current->input.psz_uri, "rtsp:", 5 ) &&
- strncmp( p_current->input.psz_uri, "udp:", 4 ) &&
- strncmp( p_current->input.psz_uri, "mms:", 4 ) &&
- strncmp( p_current->input.psz_uri, "cdda:", 4 ) &&
- strncmp( p_current->input.psz_uri, "dvd:", 4 ) &&
- strncmp( p_current->input.psz_uri, "v4l:", 4 ) &&
- strncmp( p_current->input.psz_uri, "dshow:", 6 ) )
- {
- b_preparsed = VLC_TRUE;
- stats_TimerStart( p_playlist, "Preparse run",
- STATS_TIMER_PREPARSE );
- input_Preparse( p_playlist, &p_current->input );
- stats_TimerStop( p_playlist, STATS_TIMER_PREPARSE );
- }
- vlc_mutex_unlock( &p_playlist->object_lock );
- if( b_preparsed )
- {
- var_SetInteger( p_playlist, "item-change",
- p_current->input.i_id );
- }
- }
- else
- vlc_mutex_unlock( &p_playlist->object_lock );
- vlc_mutex_lock( &p_obj->object_lock );
- }
- b_sleep = ( p_obj->i_waiting == 0 );
-
- vlc_mutex_unlock( &p_obj->object_lock );
-
- if( p_obj->i_waiting == 0 )
- {
- msleep( INTF_IDLE_SLEEP );
- }
- }
-}
-
-/*****************************************************************************
- * NextItem
- *****************************************************************************
- * This function calculates the next playlist item, depending
- * on the playlist course mode (forward, backward, random, view,...).
- *****************************************************************************/
-static playlist_item_t * NextItem( playlist_t *p_playlist )
-{
- playlist_item_t *p_new = NULL;
- int i_skip,i_goto,i, i_new, i_count ;
- playlist_view_t *p_view;
-
- vlc_bool_t b_loop = var_GetBool( p_playlist, "loop" );
- vlc_bool_t b_random = var_GetBool( p_playlist, "random" );
- vlc_bool_t b_repeat = var_GetBool( p_playlist, "repeat" );
- vlc_bool_t b_playstop = var_GetBool( p_playlist, "play-and-stop" );
-
-#ifdef PLAYLIST_PROFILE
- /* Calculate time needed */
- int64_t start = mdate();
-#endif
- /* Handle quickly a few special cases */
-
- /* No items to play */
- if( p_playlist->i_size == 0 )
- {
- msg_Info( p_playlist, "playlist is empty" );
- return NULL;
- }
- /* Nothing requested */
- if( !p_playlist->request.b_request && p_playlist->status.p_item == NULL )
- {
- msg_Dbg( p_playlist,"nothing requested, starting" );
- }
-
- /* Repeat and play/stop */
- if( !p_playlist->request.b_request && b_repeat == VLC_TRUE &&
- p_playlist->status.p_item )
- {
- msg_Dbg( p_playlist,"repeating item" );
- return p_playlist->status.p_item;
- }
-
- if( !p_playlist->request.b_request && b_playstop == VLC_TRUE )
- {
- msg_Dbg( p_playlist,"stopping (play and stop)");
- return NULL;
- }
-
- if( !p_playlist->request.b_request && p_playlist->status.p_item &&
- !( p_playlist->status.p_item->i_flags & PLAYLIST_SKIP_FLAG ) )
- {
- msg_Dbg( p_playlist, "no-skip mode, stopping") ;
- return NULL;
- }
-
- /* TODO: improve this (only use current node) */
- /* TODO: use the "shuffled view" internally ? */
- /* Random case. This is an exception: if request, but request is skip +- 1
- * we don't go to next item but select a new random one. */
- if( b_random &&
- ( !p_playlist->request.b_request ||
- ( p_playlist->request.b_request && ( p_playlist->request.p_item == NULL ||
- p_playlist->request.i_skip == 1 || p_playlist->request.i_skip == -1 ) ) ) )
- {
- /* how many items to choose from ? */
- i_count = 0;
- for ( i = 0; i < p_playlist->i_size; i++ )
- {
- if ( p_playlist->pp_items[i]->i_nb_played == 0 )
- i_count++;
- }
- /* Nothing left? */
- if ( i_count == 0 )
- {
- /* Don't loop? Exit! */
- if( !b_loop )
- return NULL;
- /* Otherwise reset the counter */
- for ( i = 0; i < p_playlist->i_size; i++ )
- {
- p_playlist->pp_items[i]->i_nb_played = 0;
- }
- i_count = p_playlist->i_size;
- }
- srand( (unsigned int)mdate() );
- i = rand() % i_count + 1 ;
- /* loop thru the list and count down the unplayed items to the selected one */
- for ( i_new = 0; i_new < p_playlist->i_size && i > 0; i_new++ )
- {
- if ( p_playlist->pp_items[i_new]->i_nb_played == 0 )
- i--;
- }
- i_new--;
-
- p_playlist->request.i_skip = 0;
- p_playlist->request.b_request = VLC_FALSE;
- return p_playlist->pp_items[i_new];
- }
-
- /* Start the real work */
- if( p_playlist->request.b_request )
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist,"processing request" );
-#endif
- /* We are not playing from a view */
- if( p_playlist->request.i_view == -1 )
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "non-view mode request");
-#endif
- /* Directly select the item, just like now */
- p_new = p_playlist->request.p_item;
- i_skip = p_playlist->request.i_skip;
- i_goto = p_playlist->request.i_goto;
-
- if( p_playlist->i_index < 0 ) p_playlist->i_index = 0;
- if ( p_new == NULL )
- p_new = p_playlist->pp_items[p_playlist->i_index];
-
- if( i_goto >= 0 && i_goto < p_playlist->i_size )
- {
- p_playlist->i_index = i_goto;
- p_new = p_playlist->pp_items[p_playlist->i_index];
- p_playlist->request.i_goto = -1;
- }
-
- if( i_skip != 0 )
- {
- if( p_playlist->i_index + i_skip < p_playlist->i_size &&
- p_playlist->i_index + i_skip >= 0 )
- {
- p_playlist->i_index += i_skip;
- p_new = p_playlist->pp_items[p_playlist->i_index];
- }
- p_playlist->request.i_skip = 0;
- }
- if( !( p_new->i_flags & PLAYLIST_SKIP_FLAG ) )
- {
- return NULL;
- }
- }
- else
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "view mode request" );
-#endif
- p_new = p_playlist->request.p_item;
- i_skip = p_playlist->request.i_skip;
-
- /* If we are asked for a node, take its first item */
- if( p_playlist->request.p_item == NULL && i_skip == 0 )
- {
- i_skip++;
- }
-
- p_view = playlist_ViewFind( p_playlist,p_playlist->request.i_view );
- p_playlist->status.p_node = p_playlist->request.p_node;
- p_playlist->status.i_view = p_playlist->request.i_view;
- if( !p_view )
- {
- msg_Err( p_playlist, "p_view is NULL and should not! (requested view is %i", p_playlist->request.i_view );
- }
- else if( i_skip > 0 )
- {
- for( i = i_skip; i > 0 ; i-- )
- {
- p_new = playlist_FindNextFromParent( p_playlist,
- p_playlist->request.i_view,
- p_view->p_root,
- p_playlist->request.p_node,
- p_new );
- if( p_new == NULL )
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "looping" );
-#endif
- p_new = playlist_FindNextFromParent( p_playlist,
- p_playlist->request.i_view,
- p_view->p_root,
- p_view->p_root,
- NULL );
- if( p_new == NULL ) break;
- }
- }
- }
- else if( i_skip < 0 )
- {
- for( i = i_skip; i < 0 ; i++ )
- {
- p_new = playlist_FindPrevFromParent( p_playlist,
- p_playlist->request.i_view,
- p_view->p_root,
- p_playlist->request.p_node,
- p_new );
- if( p_new == NULL )
- {
- /* We reach the beginning of the playlist.
- Go back to the last item. */
- p_new = playlist_RecursiveFindLast( p_playlist,
- p_view->p_root );
- }
- if( p_new == NULL ) break;
- }
-
- }
- }
- /* Clear the request */
- p_playlist->request.b_request = VLC_FALSE;
- }
- /* "Automatic" item change ( next ) */
- else
- {
- p_playlist->request_date = 0;
-
- if( p_playlist->status.i_view == -1 )
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "no request - old mode" );
-#endif
- if( p_playlist->i_index + 1 < p_playlist->i_size )
- {
- p_playlist->i_index++;
- p_new = p_playlist->pp_items[p_playlist->i_index];
- if( !( p_new->i_flags & PLAYLIST_SKIP_FLAG ) )
- {
- return NULL;
- }
- }
- else
- {
- if( b_loop && p_playlist->i_size > 0)
- {
- p_playlist->i_index = 0;
- p_new = p_playlist->pp_items[0];
- }
- else
- p_new = NULL;
- }
- }
- /* We are playing with a view */
- else
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist,"no request - from a view" );
-#endif
- playlist_view_t *p_view =
- playlist_ViewFind( p_playlist,
- p_playlist->status.i_view );
- if( !p_view )
- {
- msg_Err( p_playlist, "p_view is NULL and should not! (FIXME)" );
- }
- else
- {
- p_new = playlist_FindNextFromParent( p_playlist,
- p_playlist->status.i_view,
- p_view->p_root,
- p_playlist->status.p_node,
- p_playlist->status.p_item );
- if( p_new == NULL && b_loop )
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "looping" );
-#endif
- p_new = playlist_FindNextFromParent( p_playlist,
- p_playlist->status.i_view,
- p_view->p_root,
- p_view->p_root,
- NULL );
- }
- if( p_new != NULL && !(p_new->i_flags & PLAYLIST_SKIP_FLAG) )
- return NULL;
- }
- }
- }
-
- /* Reset index */
- if( p_playlist->i_index >= 0 && p_new != NULL &&
- p_playlist->pp_items[p_playlist->i_index] != p_new )
- {
- p_playlist->i_index = playlist_GetPositionById( p_playlist,
- p_new->input.i_id );
- }
-
-#ifdef PLAYLIST_PROFILE
- msg_Dbg(p_playlist,"next item found in "I64Fi " us", mdate()-start );
-#endif
-
- if( p_new == NULL )
- {
- msg_Info( p_playlist, "nothing to play" );
- }
-
- return p_new;
-}
-
-/*****************************************************************************
- * PlayItem: start the input thread for an item
- ****************************************************************************/
-static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
-{
- vlc_value_t val;
-
- msg_Dbg( p_playlist, "creating new input thread" );
-
- p_item->i_nb_played++;
- p_playlist->status.p_item = p_item;
-
- p_playlist->i_index = playlist_GetPositionById( p_playlist,
- p_item->input.i_id );
-
-#ifdef PLAYLIST_PROFILE
- if( p_playlist->request_date != 0 )
- {
- msg_Dbg( p_playlist, "request processed after "I64Fi " us",
- mdate() - p_playlist->request_date );
- }
-#endif
-
- p_playlist->p_input = input_CreateThread( p_playlist, &p_item->input );
-
- val.i_int = p_item->input.i_id;
- /* unlock the playlist to set the var...mmm */
- vlc_mutex_unlock( &p_playlist->object_lock);
- var_Set( p_playlist, "playlist-current", val);
- vlc_mutex_lock( &p_playlist->object_lock);
-
- return VLC_SUCCESS;
-
-}
--- /dev/null
+/*****************************************************************************
+ * search.c : Search functions
+ *****************************************************************************
+ * Copyright (C) 1999-2004 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+
+#include "vlc_playlist.h"
+
+/***************************************************************************
+ * Item search functions
+ ***************************************************************************/
+
+/**
+ * Search a playlist item by its playlist_item id
+ *
+ * \param p_playlist the playlist
+ * \param i_id the id to find
+ * \return the item or NULL on failure
+ */
+playlist_item_t * playlist_ItemGetById( playlist_t * p_playlist , int i_id )
+{
+ int i, i_top, i_bottom;
+ i_bottom = 0; i_top = p_playlist->i_all_size - 1;
+ i = i_top / 2;
+ while( p_playlist->pp_all_items[i]->i_id != i_id &&
+ i_top > i_bottom )
+ {
+ if( p_playlist->pp_all_items[i]->i_id < i_id )
+ i_bottom = i + 1;
+ else
+ i_top = i - 1;
+ i = i_bottom + ( i_top - i_bottom ) / 2;
+ }
+ if( p_playlist->pp_all_items[i]->i_id == i_id )
+ {
+ return p_playlist->pp_all_items[i];
+ }
+ return NULL;
+}
+
+/**
+ * Search an item by its input_item_t
+ *
+ * \param p_playlist the playlist
+ * \param p_item the input_item_t to find
+ * \return the item, or NULL on failure
+ */
+playlist_item_t * playlist_ItemGetByInput( playlist_t * p_playlist ,
+ input_item_t *p_item )
+{
+ int i;
+ if( p_playlist->status.p_item && p_playlist->status.p_item->p_input == p_item )
+ {
+ return p_playlist->status.p_item;
+ }
+
+ for( i = 0 ; i < p_playlist->i_all_size; i++ )
+ {
+msg_Err( p_playlist, "%p, %p", p_item, p_playlist->pp_all_items[i]->p_input );
+ if( p_playlist->pp_all_items[i]->p_input == p_item )
+ {
+ return p_playlist->pp_all_items[i];
+ }
+ }
+ return NULL;
+}
+
+/***************************************************************************
+ * Live search handling
+ ***************************************************************************/
+
+int playlist_LiveSearchUpdate( playlist_t *p_playlist, playlist_item_t *p_root,
+ const char *psz_string )
+{
+ int i;
+ for( i = 0 ; i< p_root->i_children ; i ++ )
+ {
+ playlist_item_t *p_item = p_root->pp_children[i];
+ if( p_item->i_children > -1 )
+ {
+ playlist_LiveSearchUpdate( p_playlist, p_item, psz_string );
+ }
+ /* Todo: Filter on all fields */
+ if( strcasestr( p_item->p_input->psz_name, psz_string ) )
+ p_item->i_flags &= ~PLAYLIST_DBL_FLAG;
+ else
+ p_item->i_flags |= PLAYLIST_DBL_FLAG;
+ }
+ return VLC_SUCCESS;
+}
playlist_item_t **pp_items, int i_mode,
int i_type );
-
-/**
- * Sort the playlist.
- * \param p_playlist the playlist
- * \param i_mode: SORT_ID, SORT_TITLE, SORT_AUTHOR, SORT_ALBUM, SORT_RANDOM
- * \param i_type: ORDER_NORMAL or ORDER_REVERSE (reversed order)
- * \return VLC_SUCCESS on success
- */
-int playlist_Sort( playlist_t * p_playlist , int i_mode, int i_type )
-{
- int i_id = -1;
- vlc_value_t val;
- val.b_bool = VLC_TRUE;
-
- vlc_mutex_lock( &p_playlist->object_lock );
-
- p_playlist->i_sort = i_mode;
- p_playlist->i_order = i_type;
-
- if( p_playlist->i_index >= 0 )
- {
- i_id = p_playlist->pp_items[p_playlist->i_index]->input.i_id;
- }
-
- playlist_ItemArraySort( p_playlist, p_playlist->i_size,
- p_playlist->pp_items, i_mode, i_type );
-
- if( i_id != -1 )
- {
- p_playlist->i_index = playlist_GetPositionById( p_playlist, i_id );
- }
-
- /* ensure we are in no-view mode */
- p_playlist->status.i_view = -1;
-
- vlc_mutex_unlock( &p_playlist->object_lock );
-
- /* Notify the interfaces */
- var_Set( p_playlist, "intf-change", val );
-
- return VLC_SUCCESS;
-}
-
/**
* Sort a node.
*
playlist_ItemArraySort( p_playlist,p_node->i_children,
p_node->pp_children, i_mode, i_type );
- p_node->i_serial++;
-
return VLC_SUCCESS;
}
if( i_mode == SORT_TITLE )
{
- i_test = strcasecmp( pp_items[i]->input.psz_name,
- pp_items[i_small]->input.psz_name );
+ i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+ pp_items[i_small]->p_input->psz_name );
}
else if( i_mode == SORT_TITLE_NUMERIC )
{
- i_test = atoi( pp_items[i]->input.psz_name ) -
- atoi( pp_items[i_small]->input.psz_name );
+ i_test = atoi( pp_items[i]->p_input->psz_name ) -
+ atoi( pp_items[i_small]->p_input->psz_name );
}
else if( i_mode == SORT_DURATION )
{
- i_test = pp_items[i]->input.i_duration -
- pp_items[i_small]->input.i_duration;
+ i_test = pp_items[i]->p_input->i_duration -
+ pp_items[i_small]->p_input->i_duration;
}
else if( i_mode == SORT_AUTHOR )
{
- char *psz_a = vlc_input_item_GetInfo(
- &pp_items[i]->input,
- _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
- char *psz_b = vlc_input_item_GetInfo(
- &pp_items[i_small]->input,
- _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
+ char *psz_a = pp_items[i]->p_input->p_meta->psz_artist;
+ char *psz_b = pp_items[i_small]->p_input->p_meta->psz_artist;
if( pp_items[i]->i_children == -1 &&
pp_items[i_small]->i_children >= 0 )
{
else if( pp_items[i]->i_children >= 0 &&
pp_items[i_small]->i_children >= 0 )
{
- i_test = strcasecmp( pp_items[i]->input.psz_name,
- pp_items[i_small]->input.psz_name );
+ i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+ pp_items[i_small]->p_input->psz_name );
}
else if( psz_a == NULL && psz_b != NULL )
{
}
else if( psz_a == NULL && psz_b == NULL )
{
- i_test = strcasecmp( pp_items[i]->input.psz_name,
- pp_items[i_small]->input.psz_name );
+ i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+ pp_items[i_small]->p_input->psz_name );
}
else
{
}
}
else if( i_mode == SORT_ALBUM )
- {
- char *psz_a = vlc_input_item_GetInfo(
- &pp_items[i]->input,
- _(VLC_META_INFO_CAT), _(VLC_META_COLLECTION) );
- char *psz_b = vlc_input_item_GetInfo(
- &pp_items[i_small]->input,
- _(VLC_META_INFO_CAT), _(VLC_META_COLLECTION) );
+ {
+ char *psz_a = pp_items[i]->p_input->p_meta->psz_album;
+ char *psz_b = pp_items[i_small]->p_input->p_meta->psz_album;
if( pp_items[i]->i_children == -1 &&
pp_items[i_small]->i_children >= 0 )
{
else if( pp_items[i]->i_children >= 0 &&
pp_items[i_small]->i_children >= 0 )
{
- i_test = strcasecmp( pp_items[i]->input.psz_name,
- pp_items[i_small]->input.psz_name );
+ i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+ pp_items[i_small]->p_input->psz_name );
}
else if( psz_a == NULL && psz_b != NULL )
{
}
else if( psz_a == NULL && psz_b == NULL )
{
- i_test = strcasecmp( pp_items[i]->input.psz_name,
- pp_items[i_small]->input.psz_name );
+ i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+ pp_items[i_small]->p_input->psz_name );
}
else
{
i_test = strcmp( psz_b, psz_a );
}
- }
+ }
else if( i_mode == SORT_TITLE_NODES_FIRST )
{
/* Alphabetic sort, all nodes first */
}
else
{
- i_test = strcasecmp( pp_items[i]->input.psz_name,
- pp_items[i_small]->input.psz_name );
+ i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+ pp_items[i_small]->p_input->psz_name );
}
}
}
-int playlist_NodeGroup( playlist_t * p_playlist , int i_view,
- playlist_item_t *p_root,
+int playlist_NodeGroup( playlist_t * p_playlist , playlist_item_t *p_root,
playlist_item_t **pp_items,int i_item,
int i_mode, int i_type )
{
if( psz_search ) free( psz_search );
if( i_mode == SORT_TITLE )
{
- psz_search = strdup( pp_items[i]->input.psz_name );
+ psz_search = strdup( pp_items[i]->p_input->psz_name );
}
else if ( i_mode == SORT_AUTHOR )
{
- psz_search = vlc_input_item_GetInfo( &pp_items[i]->input,
- _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
+ psz_search = pp_items[i]->p_input->p_meta->psz_artist;
}
else if ( i_mode == SORT_ALBUM )
{
- psz_search = vlc_input_item_GetInfo( &pp_items[i]->input,
- _(VLC_META_INFO_CAT), _(VLC_META_COLLECTION) );
+ psz_search = pp_items[i]->p_input->p_meta->psz_album;
}
else if ( i_mode == SORT_GENRE )
{
- psz_search = vlc_input_item_GetInfo( &pp_items[i]->input,
- _(VLC_META_INFO_CAT), _(VLC_META_GENRE) );
+ psz_search = pp_items[i]->p_input->p_meta->psz_genre;
}
if( psz_search && !strcmp( psz_search, "" ) )
b_found = VLC_FALSE;
for( j = 0 ; j< i_nodes; j++ )
{
- if( !strcasecmp( psz_search, pp_nodes[j]->input.psz_name ) )
+ if( !strcasecmp( psz_search, pp_nodes[j]->p_input->psz_name ) )
{
- playlist_NodeAppend( p_playlist, i_view,
- pp_items[i], pp_nodes[j] );
+ playlist_NodeAppend( p_playlist, pp_items[i], pp_nodes[j] );
b_found = VLC_TRUE;
break;
}
}
if( !b_found )
{
- p_node = playlist_NodeCreate( p_playlist, i_view,psz_search,
- NULL );
+ p_node = playlist_NodeCreate( p_playlist, psz_search, NULL );
INSERT_ELEM( pp_nodes, i_nodes, i_nodes, p_node );
- playlist_NodeAppend( p_playlist, i_view,
- pp_items[i],p_node );
+ playlist_NodeAppend( p_playlist, pp_items[i],p_node );
}
}
playlist_ItemArraySort( p_playlist, pp_nodes[i]->i_children,
pp_nodes[i]->pp_children, SORT_TITLE, i_type );
- playlist_NodeAppend( p_playlist, i_view,
- pp_nodes[i], p_root );
+ playlist_NodeAppend( p_playlist, pp_nodes[i], p_root );
}
return VLC_SUCCESS;
}
--- /dev/null
+/*****************************************************************************
+ * playlist.c : Playlist management functions
+ *****************************************************************************
+ * Copyright (C) 1999-2004 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ * Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc_input.h>
+#include "vlc_playlist.h"
+#include "vlc_interaction.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void RunControlThread ( playlist_t * );
+static void RunPreparse( playlist_preparse_t * );
+
+static playlist_t * CreatePlaylist( vlc_object_t *p_parent );
+static void HandlePlaylist( playlist_t * );
+static void EndPlaylist( playlist_t * );
+static void DestroyPlaylist( playlist_t * );
+
+static void HandleStats( playlist_t *, int );
+
+static void HandleInteraction( playlist_t * );
+static void DestroyInteraction( playlist_t * );
+
+/*****************************************************************************
+ * Main functions for the global thread
+ *****************************************************************************/
+
+/**
+ * Create the main playlist thread
+ * Additionally to the playlist, this thread controls :
+ * - Interaction
+ * - Statistics
+ * - VLM
+ * \param p_parent
+ * \return an object with a started thread
+ */
+playlist_t * __playlist_ThreadCreate( vlc_object_t *p_parent )
+{
+ playlist_t *p_playlist;
+ p_playlist = CreatePlaylist( p_parent );
+
+ if( !p_playlist ) return NULL;
+
+ // Stats
+ p_playlist->p_stats = (global_stats_t *)malloc( sizeof( global_stats_t ) );
+ vlc_mutex_init( p_playlist, &p_playlist->p_stats->lock );
+
+ // Interaction
+ p_playlist->p_interaction = NULL;
+
+ // Preparse
+ p_playlist->p_preparse = vlc_object_create( p_playlist,
+ sizeof( playlist_preparse_t ) );
+ if( !p_playlist->p_preparse )
+ {
+ msg_Err( p_playlist, "unable to create preparser" );
+ vlc_object_destroy( p_playlist );
+ return NULL;
+ }
+ p_playlist->p_preparse->i_waiting = 0;
+ p_playlist->p_preparse->pp_waiting = NULL;
+
+ vlc_object_attach( p_playlist->p_preparse, p_playlist );
+ if( vlc_thread_create( p_playlist->p_preparse, "preparser",
+ RunPreparse, VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
+ {
+ msg_Err( p_playlist, "cannot spawn preparse thread" );
+ vlc_object_detach( p_playlist->p_preparse );
+ vlc_object_destroy( p_playlist->p_preparse );
+ return NULL;
+ }
+
+ // Start the thread
+ if( vlc_thread_create( p_playlist, "playlist", RunControlThread,
+ VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
+ {
+ msg_Err( p_playlist, "cannot spawn playlist thread" );
+ vlc_object_destroy( p_playlist );
+ return NULL;
+ }
+
+ /* The object has been initialized, now attach it */
+ vlc_object_attach( p_playlist, p_parent );
+
+ return p_playlist;
+}
+
+/**
+ * Destroy the playlist global thread.
+ *
+ * Deinits all things controlled by the playlist global thread
+ * \param p_playlist the playlist thread to destroy
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_ThreadDestroy( playlist_t * p_playlist )
+{
+ p_playlist->b_die = 1;
+
+ DestroyInteraction( p_playlist );
+ DestroyPlaylist( p_playlist );
+
+ return VLC_SUCCESS;
+}
+
+/**
+ * Run the main control thread itself
+ */
+static void RunControlThread ( playlist_t *p_playlist )
+{
+ int i_loops = 0;
+
+ /* Tell above that we're ready */
+ vlc_thread_ready( p_playlist );
+
+ while( !p_playlist->b_die )
+ {
+ i_loops++;
+
+ HandleInteraction( p_playlist );
+ HandleStats( p_playlist, i_loops );
+
+ HandlePlaylist( p_playlist );
+
+ msleep( INTF_IDLE_SLEEP / 2 );
+
+ /* Stop sleeping earlier if we have work */
+ /* TODO : statistics about this */
+ if ( p_playlist->request.b_request &&
+ p_playlist->status.i_status == PLAYLIST_RUNNING )
+ {
+ continue;
+ }
+
+ msleep( INTF_IDLE_SLEEP / 2 );
+ }
+
+ EndPlaylist( p_playlist );
+}
+
+
+/*****************************************************************************
+ * Playlist-specific functions
+ *****************************************************************************/
+static playlist_t * CreatePlaylist( vlc_object_t *p_parent )
+{
+ return playlist_Create( p_parent );
+}
+
+static void DestroyPlaylist( playlist_t *p_playlist )
+{
+ playlist_Destroy( p_playlist );
+}
+
+static void HandlePlaylist( playlist_t *p_playlist )
+{
+ playlist_MainLoop( p_playlist );
+}
+
+static void EndPlaylist( playlist_t *p_playlist )
+{
+ playlist_LastLoop( p_playlist );
+}
+
+/*****************************************************************************
+ * Preparse-specific functions
+ *****************************************************************************/
+static void RunPreparse ( playlist_preparse_t *p_obj )
+{
+ /* Tell above that we're ready */
+ vlc_thread_ready( p_obj );
+ playlist_t *p_playlist = (playlist_t *)p_obj->p_parent;
+
+ while( !p_playlist->b_die )
+ {
+ playlist_PreparseLoop( p_obj );
+ if( p_obj->i_waiting == 0 )
+ {
+ msleep( INTF_IDLE_SLEEP );
+ }
+ }
+}
+
+/*****************************************************************************
+ * Interaction functions
+ *****************************************************************************/
+static void DestroyInteraction( playlist_t *p_playlist )
+{
+ if( p_playlist->p_interaction )
+ {
+ intf_InteractionDestroy( p_playlist->p_interaction );
+ }
+}
+
+static void HandleInteraction( playlist_t *p_playlist )
+{
+ if( p_playlist->p_interaction )
+ {
+ stats_TimerStart( p_playlist, "Interaction thread",
+ STATS_TIMER_INTERACTION );
+ intf_InteractionManage( p_playlist );
+ stats_TimerStop( p_playlist, STATS_TIMER_INTERACTION );
+ }
+}
+
+
+/*****************************************************************************
+ * Stats functions
+ *****************************************************************************/
+static void HandleStats( playlist_t *p_playlist, int i_loops )
+{
+ if( i_loops %5 == 0 && p_playlist->p_stats )
+ {
+ stats_ComputeGlobalStats( p_playlist, p_playlist->p_stats );
+ if( p_playlist->p_input )
+ {
+ stats_ComputeInputStats( p_playlist->p_input,
+ p_playlist->p_input->input.p_item->p_stats );
+ }
+ }
+}
--- /dev/null
+/*****************************************************************************
+ * tree.c : Playlist tree walking functions
+ *****************************************************************************
+ * Copyright (C) 1999-2004 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+#include "vlc_playlist.h"
+
+#define PLAYLIST_DEBUG 1
+
+/************************************************************************
+ * Local prototypes
+ ************************************************************************/
+playlist_item_t *GetNextUncle( playlist_t *p_playlist, playlist_item_t *p_item,
+ playlist_item_t *p_root );
+playlist_item_t *GetPrevUncle( playlist_t *p_playlist, playlist_item_t *p_item,
+ playlist_item_t *p_root );
+
+playlist_item_t *GetNextItem( playlist_t *p_playlist,
+ playlist_item_t *p_root,
+ playlist_item_t *p_item );
+playlist_item_t *GetPrevItem( playlist_t *p_playlist,
+ playlist_item_t *p_item,
+ playlist_item_t *p_root );
+
+/**
+ * Create a playlist node
+ *
+ * \param p_playlist the playlist
+ * \paam psz_name the name of the node
+ * \param p_parent the parent node to attach to or NULL if no attach
+ * \return the new node
+ */
+playlist_item_t * playlist_NodeCreate( playlist_t *p_playlist, char *psz_name,
+ playlist_item_t *p_parent )
+{
+ input_item_t *p_input;
+ playlist_item_t *p_item;
+
+ if( !psz_name ) psz_name = strdup( _("Undefined") );
+ p_input = input_ItemNewWithType( VLC_OBJECT(p_playlist), NULL, psz_name,
+ 0, NULL, -1, ITEM_TYPE_NODE );
+ p_input->i_id = ++p_playlist->i_last_input_id;
+ p_item = playlist_ItemNewFromInput( VLC_OBJECT(p_playlist), p_input );
+ p_item->i_children = 0;
+
+ if( p_item == NULL )
+ {
+ return NULL;
+ }
+ INSERT_ELEM( p_playlist->pp_all_items,
+ p_playlist->i_all_size,
+ p_playlist->i_all_size,
+ p_item );
+
+ if( p_parent != NULL )
+ {
+ playlist_NodeAppend( p_playlist, p_item, p_parent );
+ }
+
+ playlist_SendAddNotify( p_playlist, p_item->i_id,
+ p_parent ? p_parent->i_id : -1 );
+ return p_item;
+}
+
+/**
+ * Remove all the children of a node
+ *
+ * This function must be entered with the playlist lock
+ *
+ * \param p_playlist the playlist
+ * \param p_root the node
+ * \param b_delete_items do we have to delete the children items ?
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_NodeEmpty( playlist_t *p_playlist, playlist_item_t *p_root,
+ vlc_bool_t b_delete_items )
+{
+ int i;
+ if( p_root->i_children == -1 )
+ {
+ return VLC_EGENERIC;
+ }
+
+ /* Delete the children */
+ for( i = p_root->i_children-1 ; i >= 0 ;i-- )
+ {
+ if( p_root->pp_children[i]->i_children > -1 )
+ {
+ playlist_NodeDelete( p_playlist, p_root->pp_children[i],
+ b_delete_items , VLC_FALSE );
+ }
+ else if( b_delete_items )
+ {
+ /* Delete the item here */
+ playlist_DeleteFromItemId( p_playlist,
+ p_root->pp_children[i]->i_id );
+ }
+ }
+ return VLC_SUCCESS;
+}
+
+/**
+ * Remove all the children of a node and removes the node
+ *
+ * \param p_playlist the playlist
+ * \param p_root the node
+ * \param b_delete_items do we have to delete the children items ?
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_NodeDelete( playlist_t *p_playlist, playlist_item_t *p_root,
+ vlc_bool_t b_delete_items, vlc_bool_t b_force )
+{
+ int i, i_top, i_bottom;
+ if( p_root->i_children == -1 )
+ {
+ return VLC_EGENERIC;
+ }
+
+ /* Delete the children */
+ for( i = p_root->i_children - 1 ; i >= 0; i-- )
+ {
+ if( p_root->pp_children[i]->i_children > -1 )
+ {
+ playlist_NodeDelete( p_playlist, p_root->pp_children[i],
+ b_delete_items , b_force );
+ }
+ else if( b_delete_items )
+ {
+ playlist_DeleteFromItemId( p_playlist,
+ p_root->pp_children[i]->i_id );
+ }
+ }
+ /* Delete the node */
+ if( p_root->i_flags & PLAYLIST_RO_FLAG && !b_force )
+ {
+ }
+ else
+ {
+ var_SetInteger( p_playlist, "item-deleted", p_root->p_input->i_id );
+
+ i_bottom = 0; i_top = p_playlist->i_all_size - 1;
+ i = i_top / 2;
+ while( p_playlist->pp_all_items[i]->p_input->i_id !=
+ p_root->p_input->i_id && i_top > i_bottom )
+ {
+ if( p_playlist->pp_all_items[i]->p_input->i_id <
+ p_root->p_input->i_id )
+ {
+ i_bottom = i + 1;
+ }
+ else
+ {
+ i_top = i - 1;
+ }
+ i = i_bottom + ( i_top - i_bottom ) / 2;
+ }
+ if( p_playlist->pp_all_items[i]->p_input->i_id ==
+ p_root->p_input->i_id )
+ {
+ REMOVE_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size, i );
+ }
+ playlist_ItemDelete( p_root );
+ }
+ return VLC_SUCCESS;
+}
+
+
+/**
+ * Adds an item to the children of a node
+ *
+ * \param p_playlist the playlist
+ * \param p_item the item to append
+ * \param p_parent the parent node
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_NodeAppend( playlist_t *p_playlist,
+ playlist_item_t *p_item,
+ playlist_item_t *p_parent )
+{
+ return playlist_NodeInsert( p_playlist, p_item, p_parent, -1 );
+}
+
+int playlist_NodeInsert( playlist_t *p_playlist,
+ playlist_item_t *p_item,
+ playlist_item_t *p_parent,
+ int i_position )
+{
+ if( !p_parent || p_parent->i_children == -1 )
+ {
+ msg_Err( p_playlist, "invalid node" );
+ return VLC_EGENERIC;
+ }
+ if( i_position == -1 ) i_position = p_parent->i_children ;
+
+ INSERT_ELEM( p_parent->pp_children,
+ p_parent->i_children,
+ i_position,
+ p_item );
+
+ p_item->p_parent = p_parent;
+
+ return VLC_SUCCESS;
+}
+
+/**
+ * Deletes an item from the children of a node
+ *
+ * \param p_playlist the playlist
+ * \param p_item the item to remove
+ * \param p_parent the parent node
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_NodeRemoveItem( playlist_t *p_playlist,
+ playlist_item_t *p_item,
+ playlist_item_t *p_parent )
+{
+ int i;
+ for( i= 0; i< p_parent->i_children ; i++ )
+ {
+ if( p_parent->pp_children[i] == p_item )
+ {
+ REMOVE_ELEM( p_parent->pp_children, p_parent->i_children, i );
+ }
+ }
+
+ return VLC_SUCCESS;
+}
+
+
+/**
+ * Count the children of a node
+ *
+ * \param p_playlist the playlist
+ * \param p_node the node
+ * \return the number of children
+ */
+int playlist_NodeChildrenCount( playlist_t *p_playlist, playlist_item_t*p_node)
+{
+ int i;
+ int i_nb = 0;
+ if( p_node->i_children == -1 )
+ return 0;
+
+ for( i=0 ; i< p_node->i_children;i++ )
+ {
+ if( p_node->pp_children[i]->i_children == -1 )
+ i_nb++;
+ else
+ i_nb += playlist_NodeChildrenCount( p_playlist,
+ p_node->pp_children[i] );
+ }
+ return i_nb;
+}
+
+/**
+ * Search a child of a node by its name
+ *
+ * \param p_node the node
+ * \param psz_search the name of the child to search
+ * \return the child item or NULL if not found or error
+ */
+playlist_item_t *playlist_ChildSearchName( playlist_item_t *p_node,
+ const char *psz_search )
+{
+ int i;
+
+ if( p_node->i_children < 0 )
+ {
+ return NULL;
+ }
+ for( i = 0 ; i< p_node->i_children; i++ )
+ {
+ if( !strcmp( p_node->pp_children[i]->p_input->psz_name, psz_search ) )
+ {
+ return p_node->pp_children[i];
+ }
+ }
+ return NULL;
+}
+
+/**********************************************************************
+ * Tree walking functions
+ **********************************************************************/
+
+playlist_item_t *playlist_GetLastLeaf(playlist_t *p_playlist,
+ playlist_item_t *p_root )
+{
+ int i;
+ playlist_item_t *p_item;
+ for ( i = p_root->i_children - 1; i >= 0; i-- )
+ {
+ if( p_root->pp_children[i]->i_children == -1 )
+ return p_root->pp_children[i];
+ else if( p_root->pp_children[i]->i_children > 0)
+ {
+ p_item = playlist_GetLastLeaf( p_playlist,
+ p_root->pp_children[i] );
+ if ( p_item != NULL )
+ return p_item;
+ }
+ else if( i == 0 )
+ return NULL;
+ }
+ return NULL;
+}
+
+/**
+ * Finds the next item to play
+ *
+ * \param p_playlist the playlist
+ * \param p_root the root node
+ * \param p_item the previous item (NULL if none )
+ * \return the next item to play, or NULL if none found
+ */
+playlist_item_t *playlist_GetNextLeaf( playlist_t *p_playlist,
+ playlist_item_t *p_root,
+ playlist_item_t *p_item )
+{
+ playlist_item_t *p_next;
+
+#ifdef PLAYLIST_DEBUG
+ if( p_item != NULL )
+ msg_Dbg( p_playlist, "finding next of %s within %s",
+ p_item->p_input->psz_name, p_root->p_input->psz_name );
+ else
+ msg_Dbg( p_playlist, "finding something to play within %s",
+ p_root->p_input->psz_name );
+#endif
+
+ if( !p_root || p_root->i_children == -1 )
+ {
+ msg_Err( p_playlist,"invalid arguments for GetNextLeaf" );
+ return NULL;
+ }
+
+ /* Now, walk the tree until we find a suitable next item */
+ p_next = p_item;
+ do
+ {
+ p_next = GetNextItem( p_playlist, p_root, p_next );
+ } while ( p_next && p_next != p_root && p_next->i_children != -1 );
+
+#ifdef PLAYLIST_DEBUG
+ if( p_next == NULL )
+ msg_Dbg( p_playlist, "At end of node" );
+#endif
+ return p_next;
+}
+
+playlist_item_t *playlist_GetNextEnabledLeaf( playlist_t *p_playlist,
+ playlist_item_t *p_root,
+ playlist_item_t *p_item )
+{
+ playlist_item_t *p_next;
+
+#ifdef PLAYLIST_DEBUG
+ if( p_item != NULL )
+ msg_Dbg( p_playlist, "finding next of %s within %s",
+ p_item->p_input->psz_name, p_root->p_input->psz_name );
+ else
+ msg_Dbg( p_playlist, "finding something to play within %s",
+ p_root->p_input->psz_name );
+#endif
+
+ if( !p_root || p_root->i_children == -1 )
+ {
+ msg_Err( p_playlist,"invalid arguments for GetNextEnabledLeaf" );
+ return NULL;
+ }
+
+ /* Now, walk the tree until we find a suitable next item */
+ p_next = p_item;
+ do
+ {
+ p_next = GetNextItem( p_playlist, p_root, p_next );
+ } while ( p_next && p_next != p_root &&
+ !( p_next->i_children == -1 &&
+ !(p_next->i_flags & PLAYLIST_DBL_FLAG) ) );
+
+#ifdef PLAYLIST_DEBUG
+ if( p_next == NULL )
+ msg_Dbg( p_playlist, "At end of node" );
+#endif
+ return p_next;
+}
+
+/**
+ * Finds the previous item to play
+ *
+ * \param p_playlist the playlist
+ * \param p_root the root node
+ * \param p_item the previous item (NULL if none )
+ * \return the next item to play, or NULL if none found
+ */
+playlist_item_t *playlist_GetPrevLeaf( playlist_t *p_playlist,
+ playlist_item_t *p_root,
+ playlist_item_t *p_item )
+{
+ playlist_item_t *p_prev;
+
+#ifdef PLAYLIST_DEBUG
+ if( p_item != NULL )
+ msg_Dbg( p_playlist, "finding previous of %s within %s",
+ p_item->p_input->psz_name, p_root->p_input->psz_name );
+ else
+ msg_Dbg( p_playlist, "finding previous to play within %s",
+ p_root->p_input->psz_name );
+#endif
+
+ if( !p_root || p_root->i_children == -1 )
+ {
+ msg_Err( p_playlist,"invalid arguments for GetPrevLeaf" );
+ return NULL;
+ }
+
+ /* Now, walk the tree until we find a suitable previous item */
+ p_prev = p_item;
+ do
+ {
+ p_prev = GetPrevItem( p_playlist, p_root, p_prev );
+ } while ( p_prev && p_prev != p_root && p_prev->i_children != -1 );
+
+#ifdef PLAYLIST_DEBUG
+ if( p_prev == NULL )
+ msg_Dbg( p_playlist, "At beginning of node" );
+#endif
+ return p_prev;
+}
+
+/************************************************************************
+ * Following functions are local
+ ***********************************************************************/
+
+/**
+ * Get the next item in the tree
+ * If p_item is NULL, return the first child of root
+ **/
+playlist_item_t *GetNextItem( playlist_t *p_playlist,
+ playlist_item_t *p_root,
+ playlist_item_t *p_item )
+{
+ playlist_item_t *p_parent;
+ int i;
+
+ /* Node with children, get the first one */
+ if( p_item && p_item->i_children > 0 )
+ return p_item->pp_children[0];
+
+ if( p_item != NULL )
+ p_parent = p_item->p_parent;
+ else
+ p_parent = p_root;
+
+ for( i= 0 ; i < p_parent->i_children ; i++ )
+ {
+ if( p_item == NULL || p_parent->pp_children[i] == p_item )
+ {
+ if( p_item == NULL )
+ i = -1;
+
+ if( i+1 >= p_parent->i_children )
+ {
+ /* Was already the last sibling. Look for uncles */
+#ifdef PLAYLIST_DEBUG
+ msg_Dbg( p_playlist, "Current item is the last of the node,"
+ "looking for uncle from %s",
+ p_parent->p_input->psz_name );
+#endif
+ if( p_parent == p_root )
+ {
+#ifdef PLAYLIST_DEBUG
+ msg_Dbg( p_playlist, "Already at root" );
+ return NULL;
+#endif
+ }
+ return GetNextUncle( p_playlist, p_item, p_root );
+ }
+ else
+ {
+ return p_parent->pp_children[i+1];
+ }
+ }
+ }
+ msg_Err( p_playlist, "I should not be here" );
+ return NULL;
+}
+
+playlist_item_t *GetNextUncle( playlist_t *p_playlist, playlist_item_t *p_item,
+ playlist_item_t *p_root )
+{
+ playlist_item_t *p_parent = p_item->p_parent;
+ playlist_item_t *p_grandparent;
+ vlc_bool_t b_found = VLC_FALSE;
+
+ if( p_parent != NULL )
+ {
+ p_grandparent = p_parent->p_parent;
+ while( 1 )
+ {
+ int i;
+ for( i = 0 ; i< p_grandparent->i_children ; i++ )
+ {
+ if( p_parent == p_grandparent->pp_children[i] )
+ {
+#ifdef PLAYLIST_DEBUG
+ msg_Dbg( p_playlist, "parent %s found as child %i of "
+ "grandparent %s",
+ p_parent->p_input->psz_name, i,
+ p_grandparent->p_input->psz_name );
+#endif
+ b_found = VLC_TRUE;
+ break;
+ }
+ }
+ if( b_found && i + 1 < p_grandparent->i_children )
+ {
+ return p_grandparent->pp_children[i+1];
+ }
+ /* Not found at root */
+ if( p_grandparent == p_root )
+ {
+ return NULL;
+ }
+ else
+ {
+ p_parent = p_grandparent;
+ p_grandparent = p_parent->p_parent;
+ }
+ }
+ }
+ /* We reached root */
+ return NULL;
+}
+
+playlist_item_t *GetPrevUncle( playlist_t *p_playlist, playlist_item_t *p_item,
+ playlist_item_t *p_root )
+{
+ playlist_item_t *p_parent = p_item->p_parent;
+ playlist_item_t *p_grandparent;
+ vlc_bool_t b_found = VLC_FALSE;
+
+ if( p_parent != NULL )
+ {
+ p_grandparent = p_parent->p_parent;
+ while( 1 )
+ {
+ int i;
+ for( i = p_grandparent->i_children -1 ; i >= 0; i-- )
+ {
+ if( p_parent == p_grandparent->pp_children[i] )
+ {
+ b_found = VLC_TRUE;
+ break;
+ }
+ }
+ if( b_found && i - 1 > 0 )
+ {
+ return p_grandparent->pp_children[i-1];
+ }
+ /* Not found at root */
+ if( p_grandparent == p_root )
+ {
+ return NULL;
+ }
+ else
+ {
+ p_parent = p_grandparent;
+ p_grandparent = p_parent->p_parent;
+ }
+ }
+ }
+ /* We reached root */
+ return NULL;
+}
+
+
+/* Recursively search the tree for previous item */
+playlist_item_t *GetPrevItem( playlist_t *p_playlist,
+ playlist_item_t *p_root,
+ playlist_item_t *p_item )
+{
+ playlist_item_t *p_parent;
+ int i;
+
+ /* Node with children, get the last one */
+ if( p_item && p_item->i_children > 0 )
+ return p_item->pp_children[p_item->i_children - 1];
+
+ /* Last child of its parent ? */
+ if( p_item != NULL )
+ p_parent = p_item->p_parent;
+ else
+ {
+ msg_Err( p_playlist, "Get the last one" );
+ abort();
+ };
+
+ for( i = p_parent->i_children -1 ; i >= 0 ; i-- )
+ {
+ if( p_parent->pp_children[i] == p_item )
+ {
+ if( i-1 < 0 )
+ {
+ /* Was already the first sibling. Look for uncles */
+#ifdef PLAYLIST_DEBUG
+ msg_Dbg( p_playlist, "Current item is the first of the node,"
+ "looking for uncle from %s",
+ p_parent->p_input->psz_name );
+#endif
+ return GetPrevUncle( p_playlist, p_item, p_root );
+ }
+ else
+ {
+ return p_parent->pp_children[i-1];
+ }
+ }
+ }
+ msg_Err( p_playlist, "I should not be here" );
+ return NULL;
+}
+
+/* Dump the contents of a node */
+void playlist_NodeDump( playlist_t *p_playlist, playlist_item_t *p_item,
+ int i_level )
+{
+ char str[512];
+ int i;
+
+ if( i_level == 1 )
+ {
+ msg_Dbg( p_playlist, "%s (%i)",
+ p_item->p_input->psz_name, p_item->i_children );
+ }
+
+ if( p_item->i_children == -1 )
+ {
+ return;
+ }
+
+ for( i = 0; i< p_item->i_children; i++ )
+ {
+ memset( str, 32, 512 );
+ sprintf( str + 2 * i_level , "%s (%i)",
+ p_item->pp_children[i]->p_input->psz_name,
+ p_item->pp_children[i]->i_children );
+ msg_Dbg( p_playlist, "%s",str );
+ if( p_item->pp_children[i]->i_children >= 0 )
+ {
+ playlist_NodeDump( p_playlist, p_item->pp_children[i],
+ i_level + 1 );
+ }
+ }
+ return;
+}
+++ /dev/null
-/*****************************************************************************
- * view.c : Playlist views functions
- *****************************************************************************
- * Copyright (C) 1999-2004 the VideoLAN team
- * $Id$
- *
- * Authors: Clément Stenac <zorglub@videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#include <stdlib.h> /* free(), strtol() */
-#include <stdio.h> /* sprintf() */
-#include <string.h> /* strerror() */
-
-#include <vlc/vlc.h>
-#include <vlc/input.h>
-
-#include "vlc_playlist.h"
-
-#undef PLAYLIST_DEBUG
-
-/************************************************************************
- * Local prototypes
- ************************************************************************/
-
-/* TODO: inline */
-playlist_item_t *playlist_FindDirectParent( playlist_t *p_playlist,
- playlist_item_t *, int );
-
-playlist_item_t *playlist_RecursiveFindNext( playlist_t *p_playlist,
- int i_view,
- playlist_item_t *p_root,
- playlist_item_t *p_item,
- playlist_item_t *p_parent );
-
-playlist_item_t *playlist_RecursiveFindPrev( playlist_t *p_playlist,
- int i_view,
- playlist_item_t *p_root,
- playlist_item_t *p_item,
- playlist_item_t *p_parent );
-
-void playlist_NodeDump( playlist_t *p_playlist, playlist_item_t *p_item,
- int i_level );
-
-/**********************************************************************
- * Exported View management functions
- **********************************************************************/
-
-/**
- * Create a new view
- *
- * \param p_playlist a playlist object
- * \param i_id the view identifier
- * \return the new view or NULL on failure
- */
-playlist_view_t * playlist_ViewCreate( playlist_t *p_playlist, int i_id,
- char *psz_name )
-{
- playlist_view_t * p_view;
-
- p_view = malloc( sizeof( playlist_view_t ) );
-
- memset( p_view, 0, sizeof( playlist_view_t ) );
-
- p_view->p_root = playlist_NodeCreate( p_playlist, i_id, NULL, NULL );
- p_view->i_id = i_id;
- p_view->psz_name = psz_name ? strdup( psz_name ) : strdup(_("Undefined") );
-
- return p_view;
-}
-
-/**
- * Creates a new view and add it to the list
- *
- * This function must be entered without the playlist lock
- *
- * \param p_playlist a playlist object
- * \param i_id the view identifier
- * \return VLC_SUCCESS or an error
- */
-int playlist_ViewInsert( playlist_t *p_playlist, int i_id, char *psz_name )
-{
- playlist_view_t *p_view =
- playlist_ViewCreate( p_playlist, i_id , psz_name );
- if( !p_view )
- {
- msg_Err( p_playlist, "Creation failed" );
- return VLC_EGENERIC;
- }
-
- vlc_mutex_lock( &p_playlist->object_lock );
-
- INSERT_ELEM( p_playlist->pp_views, p_playlist->i_views,
- p_playlist->i_views, p_view );
-
- vlc_mutex_unlock( &p_playlist->object_lock );
- return VLC_SUCCESS;
-}
-
-
-/**
- * Deletes a view
- *
- * This function must be entered wit the playlist lock
- *
- * \param p_view the view to delete
- * \return nothing
- */
-int playlist_ViewDelete( playlist_t *p_playlist,playlist_view_t *p_view )
-{
- playlist_NodeDelete( p_playlist, p_view->p_root, VLC_TRUE, VLC_TRUE );
- REMOVE_ELEM( p_playlist->pp_views, p_playlist->i_views, 0 );
- return VLC_SUCCESS;
-}
-
-
-/**
- * Dumps the content of a view
- *
- * \param p_playlist the playlist
- * \param p_view the view to dump
- * \return nothing
- */
-int playlist_ViewDump( playlist_t *p_playlist, playlist_view_t *p_view )
-{
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "dumping view %i",p_view->i_id );
- playlist_NodeDump( p_playlist,p_view->p_root, 1 );
-#endif
- return VLC_SUCCESS;
-}
-
-/**
- * Counts the items of a view
- *
- * \param p_playlist the playlist
- * \param p_view the view to count
- * \return the number of items
- */
-int playlist_ViewItemCount( playlist_t *p_playlist,
- playlist_view_t *p_view )
-{
- return playlist_NodeChildrenCount( p_playlist, p_view->p_root );
-}
-
-
-/**
- * Updates a view. Only make sense for "sorted" and "ALL" views
- *
- * \param p_playlist the playlist
- * \param i_view the view to update
- * \return nothing
- */
-int playlist_ViewUpdate( playlist_t *p_playlist, int i_view)
-{
- playlist_view_t *p_view = playlist_ViewFind( p_playlist, i_view );
-
- if( p_view == NULL )
- {
- return VLC_EGENERIC;
- }
-
- if( i_view == VIEW_ALL )
- {
- p_view->p_root->i_children = p_playlist->i_size;
- p_view->p_root->pp_children = p_playlist->pp_items;
- }
-
- /* Handle update of sorted views here */
- if( i_view >= VIEW_FIRST_SORTED )
- {
- int i_sort_type;
- playlist_ViewEmpty( p_playlist, i_view, VLC_FALSE );
-
- switch( i_view )
- {
- case VIEW_S_AUTHOR: i_sort_type = SORT_AUTHOR;break;
- case VIEW_S_ALBUM: i_sort_type = SORT_ALBUM;break;
- case VIEW_S_GENRE: i_sort_type = SORT_GENRE;break;
- default: i_sort_type = SORT_AUTHOR;
- }
- playlist_NodeGroup( p_playlist, i_view, p_view->p_root,
- p_playlist->pp_items,p_playlist->i_size,
- i_sort_type, ORDER_NORMAL );
- }
-
-
- return VLC_SUCCESS;
-}
-
-
-/**
- * Find a view
- *
- * \param p_playlist the playlist
- * \param i_id the id to find
- * \return the found view or NULL if not found
- */
-playlist_view_t *playlist_ViewFind( playlist_t *p_playlist, int i_id )
-{
- int i;
- for( i=0 ; i< p_playlist->i_views ; i++ )
- {
- if( p_playlist->pp_views[i]->i_id == i_id )
- {
- return p_playlist->pp_views[i];
- }
- }
- return NULL;
-}
-
-
-int playlist_ViewEmpty( playlist_t *p_playlist, int i_view,
- vlc_bool_t b_delete_items )
-{
- playlist_view_t *p_view = playlist_ViewFind( p_playlist, i_view );
-
- if( p_view == NULL )
- {
- return VLC_EGENERIC;
- }
-
- return playlist_NodeEmpty( p_playlist, p_view->p_root, b_delete_items );
-}
-
-/**********************************************************************
- * Exported Nodes management functions
- **********************************************************************/
-
-
-
-/**
- * Create a playlist node
- *
- * \param p_playlist the playlist
- * \paam psz_name the name of the node
- * \param p_parent the parent node to attach to or NULL if no attach
- * \return the new node
- */
-playlist_item_t * playlist_NodeCreate( playlist_t *p_playlist, int i_view,
- char *psz_name,
- playlist_item_t *p_parent )
-{
- /* Create the item */
- playlist_item_t *p_item = (playlist_item_t *)malloc(
- sizeof( playlist_item_t ) );
- vlc_value_t val;
- playlist_add_t *p_add;
-
- if( p_item == NULL )
- {
- return NULL;
- }
- p_add = (playlist_add_t*)malloc( sizeof(playlist_add_t) );
- if( p_add == NULL )
- {
- free( p_item );
- return NULL;
- }
- vlc_input_item_Init( VLC_OBJECT(p_playlist), &p_item->input );
-
- if( psz_name != NULL )
- {
- p_item->input.psz_name = strdup( psz_name );
- }
- else
- {
- p_item->input.psz_name = strdup( _("Undefined") );
- }
-
- p_item->input.psz_uri = NULL;
-
- p_item->b_enabled = VLC_TRUE;
- p_item->i_nb_played = 0;
-
- p_item->i_flags = 0;
-
- p_item->i_children = 0;
- p_item->pp_children = NULL;
-
- p_item->input.i_duration = -1;
- p_item->input.ppsz_options = NULL;
- p_item->input.i_options = 0;
- p_item->input.i_categories = 0;
- p_item->input.pp_categories = NULL;
- p_item->input.i_id = ++p_playlist->i_last_id;
-
- p_item->input.i_type = ITEM_TYPE_NODE;
-
- p_item->pp_parents = NULL;
- p_item->i_parents = 0;
- p_item->i_serial = 0;
-
- p_item->i_flags |= PLAYLIST_SKIP_FLAG; /* Default behaviour */
-
- vlc_mutex_init( p_playlist, &p_item->input.lock );
-
- INSERT_ELEM( p_playlist->pp_all_items,
- p_playlist->i_all_size,
- p_playlist->i_all_size,
- p_item );
-
- if( p_parent != NULL )
- {
- playlist_NodeAppend( p_playlist, i_view, p_item, p_parent );
- }
-
- p_add->i_node = p_parent ? p_parent->input.i_id : -1;
- p_add->i_item = p_item->input.i_id;
- p_add->i_view = i_view;
- val.p_address = p_add;
- var_Set( p_playlist, "item-append", val);
-
- free( p_add );
-
- return p_item;
-}
-
-/**
- * Remove all the children of a node
- *
- * This function must be entered with the playlist lock
- *
- * \param p_playlist the playlist
- * \param p_root the node
- * \param b_delete_items do we have to delete the children items ?
- * \return VLC_SUCCESS or an error
- */
-int playlist_NodeEmpty( playlist_t *p_playlist, playlist_item_t *p_root,
- vlc_bool_t b_delete_items )
-{
- int i;
- if( p_root->i_children == -1 )
- {
- return VLC_EGENERIC;
- }
-
- /* Delete the children */
- for( i = p_root->i_children-1 ; i >= 0 ;i-- )
- {
- if( p_root->pp_children[i]->i_children > -1 )
- {
- playlist_NodeDelete( p_playlist, p_root->pp_children[i],
- b_delete_items , VLC_FALSE );
- }
- else if( b_delete_items )
- {
- /* Delete the item here */
- playlist_Delete( p_playlist, p_root->pp_children[i]->input.i_id );
- }
- }
- return VLC_SUCCESS;
-}
-
-/**
- * Remove all the children of a node and removes the node
- *
- * \param p_playlist the playlist
- * \param p_root the node
- * \param b_delete_items do we have to delete the children items ?
- * \return VLC_SUCCESS or an error
- */
-int playlist_NodeDelete( playlist_t *p_playlist, playlist_item_t *p_root,
- vlc_bool_t b_delete_items, vlc_bool_t b_force )
-{
- int i, i_top, i_bottom;
- if( p_root->i_children == -1 )
- {
- return VLC_EGENERIC;
- }
-
- /* Delete the children */
- for( i = p_root->i_children - 1 ; i >= 0; i-- )
- {
- if( p_root->pp_children[i]->i_children > -1 )
- {
- playlist_NodeDelete( p_playlist, p_root->pp_children[i],
- b_delete_items , b_force );
- }
- else if( b_delete_items )
- {
- /* Delete the item here */
- playlist_Delete( p_playlist, p_root->pp_children[i]->input.i_id );
- }
- }
- /* Delete the node */
- if( p_root->i_flags & PLAYLIST_RO_FLAG && !b_force )
- {
- }
- else
- {
- for( i = 0 ; i< p_root->i_parents; i++ )
- {
- playlist_NodeRemoveItem( p_playlist, p_root,
- p_root->pp_parents[i]->p_parent );
- }
- var_SetInteger( p_playlist, "item-deleted", p_root->input.i_id );
-
- i_bottom = 0; i_top = p_playlist->i_all_size - 1;
- i = i_top / 2;
- while( p_playlist->pp_all_items[i]->input.i_id != p_root->input.i_id &&
- i_top > i_bottom )
- {
- if( p_playlist->pp_all_items[i]->input.i_id < p_root->input.i_id )
- {
- i_bottom = i + 1;
- }
- else
- {
- i_top = i - 1;
- }
- i = i_bottom + ( i_top - i_bottom ) / 2;
- }
- if( p_playlist->pp_all_items[i]->input.i_id == p_root->input.i_id )
- {
- REMOVE_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size, i );
- }
- playlist_ItemDelete( p_root );
- }
- return VLC_SUCCESS;
-}
-
-
-/**
- * Adds an item to the childs of a node
- *
- * \param p_playlist the playlist
- * \param i_view the view of the node ( needed for parent search )
- * \param p_item the item to append
- * \param p_parent the parent node
- * \return VLC_SUCCESS or an error
- */
-int playlist_NodeAppend( playlist_t *p_playlist,
- int i_view,
- playlist_item_t *p_item,
- playlist_item_t *p_parent )
-{
- return playlist_NodeInsert( p_playlist, i_view, p_item, p_parent, -1 );
-}
-
-int playlist_NodeInsert( playlist_t *p_playlist,
- int i_view,
- playlist_item_t *p_item,
- playlist_item_t *p_parent,
- int i_position )
-{
- int i;
- vlc_bool_t b_found = VLC_FALSE;
- if( !p_parent || p_parent->i_children == -1 )
- {
- msg_Err( p_playlist, "invalid node" );
- return VLC_EGENERIC;
- }
-
- if( i_position == -1 ) i_position = p_parent->i_children ;
-
- INSERT_ELEM( p_parent->pp_children,
- p_parent->i_children,
- i_position,
- p_item );
-
- /* Add the parent to the array */
- for( i= 0; i< p_item->i_parents ; i++ )
- {
- if( p_item->pp_parents[i]->i_view == i_view )
- {
- b_found = VLC_TRUE;
- break;
- }
- }
- if( b_found == VLC_FALSE )
- {
- struct item_parent_t *p_ip = (struct item_parent_t *)
- malloc(sizeof(struct item_parent_t) );
- p_ip->i_view = i_view;
- p_ip->p_parent = p_parent;
-
- INSERT_ELEM( p_item->pp_parents,
- p_item->i_parents, p_item->i_parents,
- p_ip );
- }
-
- /* Let the interface know this has been updated */
- p_parent->i_serial++;
- return VLC_SUCCESS;
-}
-
-/**
- * Deletes a parent from the parent list of a node
- *
- * \param p_playlist the playlist
- * \param p_item the item to remove
- * \param p_parent the parent node
- * \return VLC_SUCCESS or an error
- */
-int playlist_NodeRemoveParent( playlist_t *p_playlist,
- playlist_item_t *p_item,
- playlist_item_t *p_parent )
-{
- int i;
- if( !p_parent || p_parent->i_children == -1 )
- {
- msg_Err( p_playlist, "invalid node" );
- }
-
- for( i = 0; i < p_item->i_parents; i++ )
- {
- if( p_item->pp_parents[i]->p_parent == p_parent )
- {
- if( p_item->pp_parents[i] )
- {
- free( p_item->pp_parents[i] );
- }
- REMOVE_ELEM( p_item->pp_parents, p_item->i_parents, i );
- }
- }
- p_item->i_serial++;
- return VLC_SUCCESS;
-}
-
-/**
- * Deletes an item from the children of a node
- *
- * \param p_playlist the playlist
- * \param p_item the item to remove
- * \param p_parent the parent node
- * \return VLC_SUCCESS or an error
- */
-int playlist_NodeRemoveItem( playlist_t *p_playlist,
- playlist_item_t *p_item,
- playlist_item_t *p_parent )
-{
- int i;
- for( i= 0; i< p_parent->i_children ; i++ )
- {
- if( p_parent->pp_children[i] == p_item )
- {
- REMOVE_ELEM( p_parent->pp_children, p_parent->i_children, i );
- }
- }
-
- /* Let the interface know this has been updated */
- p_parent->i_serial++;
-
- return VLC_SUCCESS;
-}
-
-
-/**
- * Count the children of a node
- *
- * \param p_playlist the playlist
- * \param p_node the node
- * \return the number of children
- */
-int playlist_NodeChildrenCount( playlist_t *p_playlist, playlist_item_t*p_node)
-{
- int i;
- int i_nb = 0;
- if( p_node->i_children == -1 )
- {
- return 0;
- }
-
- for( i=0 ; i< p_node->i_children;i++ )
- {
- if( p_node->pp_children[i]->i_children == -1 )
- {
- i_nb++;
- }
- else
- {
- i_nb += playlist_NodeChildrenCount( p_playlist,
- p_node->pp_children[i] );
- }
- }
- return i_nb;
-}
-
-/**
- * Search a child of a node by its name
- *
- * \param p_node the node
- * \param psz_search the name of the child to search
- * \return the child item or NULL if not found or error
- */
-playlist_item_t *playlist_ChildSearchName( playlist_item_t *p_node,
- const char *psz_search )
-{
- int i;
-
- if( p_node->i_children < 0 )
- {
- return NULL;
- }
- for( i = 0 ; i< p_node->i_children; i++ )
- {
- if( !strcmp( p_node->pp_children[i]->input.psz_name, psz_search ) )
- {
- return p_node->pp_children[i];
- }
- }
- return NULL;
-}
-
-
-/**********************************************************************
- * Tree functions
- **********************************************************************/
-
-/**
- * Finds the next item to play
- *
- * \param p_playlist the playlist
- * \param i_view the view
- * \param p_root the root node
- * \param p_node the node we are playing from
- * \param p_item the item we were playing (NULL if none )
- * \return the next item to play, or NULL if none found
- */
-playlist_item_t *playlist_FindNextFromParent( playlist_t *p_playlist,
- int i_view, /* FIXME: useless */
- playlist_item_t *p_root,
- playlist_item_t *p_node,
- playlist_item_t *p_item )
-{
- playlist_item_t *p_search, *p_next;
-
-#ifdef PLAYLIST_DEBUG
- if( p_item != NULL )
- {
- msg_Dbg( p_playlist, "finding next of %s within %s - root %s",
- p_item->input.psz_name, p_node->input.psz_name,
- p_root->input.psz_name );
- }
- else
- {
- msg_Dbg( p_playlist, "finding something to play within %s -root %s",
- p_node->input.psz_name, p_root->input.psz_name );
-
- }
-#endif
-
- if( !p_node || p_node->i_children == -1 )
- {
- msg_Err( p_playlist,"invalid arguments for FindNextFromParent" );
- return NULL;
- }
-
- /* Find the parent node of the item */
- if( p_item != NULL )
- {
- p_search = playlist_FindDirectParent( p_playlist, p_item, i_view );
- if( p_search == NULL )
- {
- msg_Err( p_playlist, "parent node not found" );
- return NULL;
- }
- }
- else
- {
- p_search = p_node;
- }
-
- /* Now, go up the tree until we find a suitable next item */
- p_next = playlist_RecursiveFindNext( p_playlist,i_view,
- p_node, p_item, p_search );
-
- /* Not found, do we go past p_node ? */
- if( p_next == NULL )
- {
- if( p_playlist->b_go_next )
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "moving on to next node: search from %s",
- p_root->input.psz_name );
-#endif
- p_next = playlist_RecursiveFindNext( p_playlist, i_view,
- p_root, p_item, p_search );
- if( p_next == NULL )
- {
- return NULL;
- }
- /* OK, we could continue, so set our current node to the root */
- p_playlist->status.p_node = p_root;
- }
- else
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "not moving on to next node: you loose" );
-#endif
- return NULL;
- }
- }
- return p_next;
-}
-
-/**
- * Finds the previous item to play
- *
- * \param p_playlist the playlist
- * \param i_view the view
- * \param p_root the root node
- * \param p_node the node we are playing from
- * \param p_item the item we were playing (NULL if none )
- * \return the next item to play, or NULL if none found
- */
-playlist_item_t *playlist_FindPrevFromParent( playlist_t *p_playlist,
- int i_view,
- playlist_item_t *p_root,
- playlist_item_t *p_node,
- playlist_item_t *p_item )
-{
- playlist_item_t *p_search, *p_next;
-
-#ifdef PLAYLIST_DEBUG
- if( p_item != NULL )
- {
- msg_Dbg( p_playlist, "finding prev of %s within %s",
- p_item->input.psz_name, p_node->input.psz_name );
- }
- else
- {
- msg_Dbg( p_playlist, "finding prev from %s",p_node->input.psz_name );
- }
-#endif
-
- if( !p_node || p_node->i_children == -1 )
- {
- msg_Err( p_playlist,"Invalid arguments for FindPrevFromParent" );
- return NULL;
- }
-
- /* Find the parent node of the item */
- if( p_item != NULL )
- {
- p_search = playlist_FindDirectParent( p_playlist, p_item, i_view );
- if( p_search == NULL )
- {
- msg_Err( p_playlist, "parent node not found" );
- return NULL;
- }
- }
- else
- {
- p_search = p_node;
- }
-
- /* Now, go up the tree until we find a suitable next item */
- p_next = playlist_RecursiveFindPrev( p_playlist,i_view,
- p_node, p_item, p_search );
-
- if( p_next == NULL )
- {
- if( p_playlist->b_go_next )
- {
- p_next = playlist_RecursiveFindPrev( p_playlist, i_view,
- p_root, p_item, p_search );
- if( p_next == NULL )
- {
- return NULL;
- }
- /* OK, we could continue, so set our current node to the root */
- p_playlist->status.p_node = p_root;
- }
- else
- {
- return NULL;
- }
- }
- return p_next;
-}
-
-/************************************************************************
- * Following functions are local
- ***********************************************************************/
-
-
-/* Recursively search the tree for next item */
-playlist_item_t *playlist_RecursiveFindNext( playlist_t *p_playlist,
- int i_view,
- playlist_item_t *p_root,
- playlist_item_t *p_item,
- playlist_item_t *p_parent )
-{
- int i;
- playlist_item_t *p_parent_parent;
-
- for( i= 0 ; i < p_parent->i_children ; i++ )
- {
- if( p_parent->pp_children[i] == p_item || p_item == NULL )
- {
- if( p_item == NULL )
- {
- i = -1;
- }
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist,"current item found, child %i of %s",
- i , p_parent->input.psz_name );
-#endif
- /* We found our item */
- if( i+1 >= p_parent->i_children )
- {
- /* Too far... */
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "going up the tree, at parent of %s",
- p_parent->input.psz_name );
-#endif
- if( p_parent == p_root )
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "at root item (%s)",
- p_root->input.psz_name );
-#endif
- /* Hmm, seems it's the end for you, guy ! */
- return NULL;
- }
-
- /* Go up one level */
- p_parent_parent = playlist_FindDirectParent( p_playlist,
- p_parent, i_view );
- if( p_parent_parent == NULL )
- {
- msg_Warn( p_playlist, "unable to find parent!");
- return NULL;
- }
- return playlist_RecursiveFindNext( p_playlist, i_view,p_root,
- p_parent, p_parent_parent );
- }
- else
- {
- if( p_parent->pp_children[i+1]->i_children == -1 )
- {
- /* Cool, we have found a real item to play */
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "playing child %i of %s",
- i+1 , p_parent->input.psz_name );
-#endif
- return p_parent->pp_children[i+1];
- }
- else if( p_parent->pp_children[i+1]->i_children > 0 )
- {
- /* Select the first child of this node */
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "%s is a node with children, "
- "playing the first",
- p_parent->pp_children[i+1]->input.psz_name);
-#endif
- if( p_parent->pp_children[i+1]->pp_children[0]
- ->i_children >= 0 )
- {
- /* first child is a node ! */
- return playlist_RecursiveFindNext( p_playlist, i_view,
- p_root, NULL ,
- p_parent->pp_children[i+1]->pp_children[0]);
- }
- return p_parent->pp_children[i+1]->pp_children[0];
- }
- else
- {
- /* This node has no child... We must continue */
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "%s is a node with no children",
- p_parent->pp_children[i+1]->input.psz_name);
-#endif
- p_item = p_parent->pp_children[i+1];
- }
- }
- }
- }
- /* Just in case :) */
- return NULL;
-}
-
-/* Recursively search the tree for previous item */
-playlist_item_t *playlist_RecursiveFindPrev( playlist_t *p_playlist,
- int i_view,
- playlist_item_t *p_root,
- playlist_item_t *p_item,
- playlist_item_t *p_parent )
-{
- int i;
- playlist_item_t *p_parent_parent;
-
- for( i= p_parent->i_children - 1 ; i >= 0 ; i-- )
- {
- if( p_parent->pp_children[i] == p_item || p_item == NULL )
- {
- if( p_item == NULL )
- {
- i = -1;
- }
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist,"current item found, child %i of %s",
- i , p_parent->input.psz_name );
-#endif
- /* We found our item */
- if( i < 1 )
- {
- /* Too far... */
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "going up the tree, at parent of %s",
- p_parent->input.psz_name );
-#endif
- if( p_parent == p_root )
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "at root item (%s)",
- p_root->input.psz_name );
-#endif
- /* Hmm, seems it's the end for you, guy ! */
- return NULL;
- }
- /* Go up one level */
- p_parent_parent = playlist_FindDirectParent( p_playlist,
- p_parent, i_view );
- if( p_parent_parent == NULL )
- {
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "mmmh, couldn't find parent" );
-#endif
- return NULL;
- }
- return playlist_RecursiveFindPrev( p_playlist, i_view,p_root,
- p_parent, p_parent_parent );
- }
- else
- {
- if( p_parent->pp_children[i-1]->i_children == -1 )
- {
- /* Cool, we have found a real item to play */
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "playing child %i of %s",
- i-1, p_parent->input.psz_name );
-#endif
- return p_parent->pp_children[i-1];
- }
- else if( p_parent->pp_children[i-1]->i_children > 0 )
- {
- /* Select the last child of this node */
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "%s is a node with children,"
- " playing the last",
- p_parent->pp_children[i-1]->input.psz_name);
-#endif
- if( p_parent->pp_children[i-1]->pp_children[p_parent->
- pp_children[i-1]->i_children-1]->i_children >= 0 )
- {
- /* Last child is a node */
- return playlist_RecursiveFindPrev( p_playlist, i_view,
- p_root,NULL,
- p_parent->pp_children[i-1]->pp_children[
- p_parent->pp_children[i-1]->i_children-1]);
- }
- return p_parent->pp_children[i-1]->pp_children[
- p_parent->pp_children[i-1]->i_children-1];
- }
- else
- {
- /* This node has no child... We must continue */
-#ifdef PLAYLIST_DEBUG
- msg_Dbg( p_playlist, "%s is a node with no children",
- p_parent->pp_children[i-1]->input.psz_name);
-#endif
- p_item = p_parent->pp_children[i-1];
- }
- }
- }
- }
- return NULL;
-}
-
-/* This function returns the parent of an item in a view */
-playlist_item_t *playlist_FindDirectParent( playlist_t *p_playlist,
- playlist_item_t *p_item,
- int i_view )
-{
- int i = 0;
- for( i= 0; i< p_item->i_parents ; i++ )
- {
- if( p_item->pp_parents[i]->i_view == i_view )
- {
- return p_item->pp_parents[i]->p_parent;
- }
- }
- return NULL;
-}
-
-
-#ifdef PLAYLIST_DEBUG
-/* This function dumps a node : to be used only for debug*/
-void playlist_NodeDump( playlist_t *p_playlist, playlist_item_t *p_item,
- int i_level )
-{
- char str[512];
- int i;
-
- if( i_level == 1 )
- {
- msg_Dbg( p_playlist, "%s (%i)",
- p_item->input.psz_name, p_item->i_children );
- }
-
- if( p_item->i_children == -1 )
- {
- return;
- }
-
- for( i = 0; i< p_item->i_children; i++ )
- {
- memset( str, 32, 512 );
- sprintf( str + 2 * i_level , "%s (%i)",
- p_item->pp_children[i]->input.psz_name,
- p_item->pp_children[i]->i_children );
- msg_Dbg( p_playlist, "%s",str );
- if( p_item->pp_children[i]->i_children >= 0 )
- {
- playlist_NodeDump( p_playlist, p_item->pp_children[i],
- i_level + 1 );
- }
- }
- return;
-}
-#endif
--- /dev/null
+import unittest
+
+import native_gc_test
+
+class NativeGcTestCase( unittest.TestCase ):
+ def testGc( self ):
+ """[GC] Test GC"""
+ native_gc_test.gc_test()
--- /dev/null
+#include "../pyunit.h"
+#include <vlc/vlc.h>
+
+#include <vlc_common.h>
+
+struct mygc
+{
+ VLC_GC_MEMBERS;
+ int i;
+};
+
+typedef struct mygc mygc;
+
+static void mygc_destructor( gc_object_t *p_gc )
+{
+ free( p_gc );
+ p_gc = NULL;
+};
+
+static PyObject *gc_test( PyObject *self, PyObject *args )
+{
+ mygc *gc = (mygc *)malloc( sizeof( mygc ) );
+
+ vlc_gc_init( gc, mygc_destructor );
+ gc->i_gc_refcount = 0;
+
+ vlc_gc_incref( gc );
+ ASSERT( gc->i_gc_refcount == 1, "Refcount should be 1" );
+ vlc_gc_incref( gc );
+ ASSERT( gc->i_gc_refcount == 2, "Refcount should be 2" );
+ gc->i++;
+ vlc_gc_decref( gc );
+ ASSERT( gc->i_gc_refcount == 1, "Refcount should be 1" );
+ vlc_gc_decref( gc );
+
+ Py_INCREF( Py_None );
+ return Py_None;
+};
+
+static PyMethodDef native_gc_test_methods[] = {
+ DEF_METHOD( gc_test, "Test GC" )
+ { NULL, NULL, 0, NULL }
+};
+
+DECLARE_MODULE( native_gc_test )