Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
628b01be
Commit
628b01be
authored
Mar 24, 2013
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: remove media library support
parent
acee3359
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
0 additions
and
1675 deletions
+0
-1675
configure.ac
configure.ac
+0
-11
include/vlc_media_library.h
include/vlc_media_library.h
+0
-1130
src/Makefile.am
src/Makefile.am
+0
-1
src/libvlc-module.c
src/libvlc-module.c
+0
-4
src/libvlc.c
src/libvlc.c
+0
-33
src/libvlc.h
src/libvlc.h
+0
-2
src/libvlccore.sym
src/libvlccore.sym
+0
-6
src/misc/media_library.c
src/misc/media_library.c
+0
-417
src/missing.c
src/missing.c
+0
-71
No files found.
configure.ac
View file @
628b01be
...
...
@@ -3959,17 +3959,6 @@ dnl Libnotify notification plugin
dnl
PKG_ENABLE_MODULES_VLC([NOTIFY], [], [libnotify gtk+-2.0], [libnotify notification], [auto])
dnl
dnl media library
dnl
AC_ARG_ENABLE(media-library,
[ --enable-media-library media library (default disabled)])
AS_IF([test "${enable_media_library}" = "yes"], [
AC_DEFINE([MEDIA_LIBRARY], 1, [Define if you want to use the VLC media library])
VLC_ADD_CPPFLAGS([qt4],"-DMEDIA_LIBRARY")
])
dnl
dnl Endianness check
dnl
...
...
include/vlc_media_library.h
View file @
628b01be
...
...
@@ -32,9 +32,6 @@
extern
"C"
{
# endif
#include <vlc_common.h>
#include <vlc_playlist.h>
/*****************************************************************************
* ML Enums
*****************************************************************************/
...
...
@@ -45,8 +42,6 @@ extern "C" {
#define ML_PERSON_PUBLISHER "Publisher"
#define ml_priv( gc, t ) ((t *)(((char *)(gc)) - offsetof(t, ml_gc_data)))
/** List of Query select types.
* In a query array or variable argument list, each select type is followed
* by an argument (X) of variable type (char* or int, @see ml_element_t).
...
...
@@ -125,1131 +120,6 @@ typedef enum {
ML_TYPE_MEDIA
,
/**< A pointer to a media ml_media_t* */
}
ml_result_type_e
;
/** Arguments for VLC Control for the media library */
typedef
enum
{
ML_SET_DATABASE
,
/**< arg1 = char *psz_host
arg2 = int i_port
arg3 = char *psz_user
arg4 = char *psz_pass */
ML_INIT_DATABASE
,
/**< No arg */
ML_ADD_INPUT_ITEM
,
/**< arg1 = input_item_t* */
ML_ADD_PLAYLIST_ITEM
,
/**< arg1 = playlist_item_t * */
ML_ADD_MONITORED
,
/**< arg1 = char* */
ML_DEL_MONITORED
,
/**< arg1 = char* */
ML_GET_MONITORED
,
/**< arg1 = vlc_array_t* */
}
ml_control_e
;
/* Operations that can be specified between find conditions */
typedef
enum
{
ML_OP_NONE
=
0
,
/**< This is to specify an actual condition */
ML_OP_AND
,
/**< AND condition */
ML_OP_OR
,
/**< OR condition */
ML_OP_NOT
,
/**< NOT condition */
ML_OP_SPECIAL
/**< This is for inclusion of
* special stuffs like LIMIT */
}
ml_op_e
;
/* Comparison operators used in a single find condition */
typedef
enum
{
ML_COMP_NONE
=
0
,
ML_COMP_LESSER
,
///< <
ML_COMP_LESSER_OR_EQUAL
,
///< <=
ML_COMP_EQUAL
,
///< ==
ML_COMP_GREATER_OR_EQUAL
,
///< >=
ML_COMP_GREATER
,
///< >
ML_COMP_HAS
,
///< "Contains", equivalent to SQL "LIKE %x%"
ML_COMP_STARTS_WITH
,
///< Equivalent to SQL "LIKE %x"
ML_COMP_ENDS_WITH
,
///< Equivalent to SQL "LIKE x%"
}
ml_comp_e
;
/*****************************************************************************
* ML Structures and types
*****************************************************************************/
typedef
struct
media_library_t
media_library_t
;
typedef
struct
media_library_sys_t
media_library_sys_t
;
typedef
struct
ml_media_t
ml_media_t
;
typedef
struct
ml_result_t
ml_result_t
;
typedef
struct
ml_element_t
ml_element_t
;
typedef
struct
ml_person_t
ml_person_t
;
typedef
struct
ml_ftree_t
ml_ftree_t
;
typedef
struct
ml_gc_object_t
{
bool
pool
;
uintptr_t
refs
;
void
(
*
pf_destructor
)
(
struct
ml_gc_object_t
*
);
}
ml_gc_object_t
;
#define ML_GC_MEMBERS ml_gc_object_t ml_gc_data;
/** Main structure of the media library. VLC object. */
struct
media_library_t
{
VLC_COMMON_MEMBERS
module_t
*
p_module
;
/**< the media library module */
media_library_sys_t
*
p_sys
;
/**< internal struture */
/** Member functions */
struct
{
/**< Search in the database */
int
(
*
pf_Find
)
(
media_library_t
*
p_media_library
,
vlc_array_t
*
p_result_array
,
va_list
args
);
/**< Search in the database using an array of arguments */
int
(
*
pf_FindAdv
)
(
media_library_t
*
p_media_library
,
vlc_array_t
*
p_result_array
,
ml_select_e
selected_type
,
const
char
*
psz_lvalue
,
ml_ftree_t
*
tree
);
/**< Update the database using an array of arguments */
int
(
*
pf_Update
)
(
media_library_t
*
p_media_library
,
ml_select_e
selected_type
,
const
char
*
psz_lvalue
,
ml_ftree_t
*
where
,
vlc_array_t
*
changes
);
/**< Delete many medias in the database */
int
(
*
pf_Delete
)
(
media_library_t
*
p_media_library
,
vlc_array_t
*
p_array
);
/**< Control the media library */
int
(
*
pf_Control
)
(
media_library_t
*
p_media_library
,
int
i_query
,
va_list
args
);
/**< Create associated input item */
input_item_t
*
(
*
pf_InputItemFromMedia
)
(
media_library_t
*
p_media_library
,
int
i_media
);
/**< Get a media */
ml_media_t
*
(
*
pf_GetMedia
)
(
media_library_t
*
p_media_library
,
int
i_media
,
ml_select_e
select
,
bool
reload
);
}
functions
;
};
/**
* @brief Structure to describe a media
*
* This is the main structure holding the meta data in ML.
* @see b_sparse indicates whether the media struct has valid values
* in its Extra fields. Otherwise, it must be loaded with the API
* function.
* @see i_id indicates whether this struct is saved in the ML if i_id > 0
* Otherwise, it can be added to the database
*/
struct
ml_media_t
{
ML_GC_MEMBERS
vlc_mutex_t
lock
;
/**< Mutex for multithreaded access */
bool
b_sparse
;
/**< Specifies if media is loaded fully */
ml_type_e
i_type
;
/**< Type of the media (ml_type_e) */
int8_t
i_vote
;
/**< User vote */
int16_t
i_disc_number
;
/**< Disc number of media */
int16_t
i_track_number
;
/**< Track number */
int16_t
i_year
;
/**< Year of release */
int32_t
i_id
;
/**< Media ID in the database */
int32_t
i_score
;
/**< Score computed about the media */
int32_t
i_album_id
;
/**< Album id */
int32_t
i_played_count
;
/**< How many time the media was played */
int32_t
i_skipped_count
;
/**< No. of times file was skipped */
int32_t
i_bitrate
;
/**< Extra: Bitrate of the media */
int32_t
i_samplerate
;
/**< Extra: Samplerate of the media */
int32_t
i_bpm
;
/**< Extra: Beats per minute */
char
*
psz_uri
;
/**< URI to find the media */
char
*
psz_title
;
/**< Title of the media */
char
*
psz_orig_title
;
/**< Original title (mainly for movies) */
char
*
psz_album
;
/**< Name of the album */
char
*
psz_cover
;
/**< URI of the cover */
char
*
psz_genre
;
/**< Genre of the media */
char
*
psz_preview
;
/**< Preview thumbnail for video, if any */
char
*
psz_comment
;
/**< Comment or description about media */
char
*
psz_language
;
/**< Extra: Language */
char
*
psz_extra
;
/**< Extra: Some extra datas like lyrics */
ml_person_t
*
p_people
;
/**< Extra: People associated with this
media This meta holds only one
artist if b_sparse = true */
int64_t
i_filesize
;
/**< Size of the file */
mtime_t
i_duration
;
/**< Duration in microseconds */
mtime_t
i_last_played
;
/**< Time when the media was last played */
mtime_t
i_last_skipped
;
/**< Time when the media was last skipped */
mtime_t
i_first_played
;
/**< First played */
mtime_t
i_import_time
;
/**< Time when media was added */
};
/**
* @brief Main communication struct between GUI and sql_media_library.
* Generic representation of an ML/SQL query result.
*/
struct
ml_result_t
{
int32_t
id
;
/**< Media/Album/Artist... ID (if any) */
ml_result_type_e
type
;
/**< Type of value */
union
{
/* Classical results */
int
i
;
char
*
psz
;
mtime_t
time
;
/* Complex result: media descriptor */
ml_media_t
*
p_media
;
}
value
;
/**< Value of the result obtained */
};
/**
* @brief Element of a query: criteria type/value pair
* Used for update and delete queries
*/
struct
ml_element_t
{
ml_select_e
criteria
;
/**< SELECT criteria type. @see ml_select_e */
union
{
int
i
;
char
*
str
;
}
value
;
/**< SELECT criteria value (string or int) */
union
{
int
i
;
char
*
str
;
}
lvalue
;
/**< Refer to @see ml_ftree_t lvalue docs */
};
/**
* Binary tree used to parse the WHERE condition for a search
*
* Let [expr] indicate a valid expression
* [expr] = [expr] AND [expr], where the left and right are respective
* [expr] = [expr] OR [expr]
* [expr] = [expr] NOT [NULL]
* [expr] = [expr] SPEC [spec_expr]
* [expr] = [criteria=val]
* [spec_expr] = [DISTINCT/LIMIT/ASC/DESC = val ]
*/
struct
ml_ftree_t
{
ml_op_e
op
;
/**< Operator. ML_OP_NONE means this is a leaf
* node. Criteria and value gives its data.
* ML_OP_SPECIAL specifies a special node
* that does not form a part of the WHERE.
* The right node consists of the data
* with its criteria set to the special val
* and the left node is the corresponding
* subtree of the parent node.
* ML_OP_NOT only left sub tree is considered
* ML_OP_AND and ML_OP_OR consider both
* left and right subtrees */
ml_ftree_t
*
left
;
/**< Left child of Bin tree */
ml_ftree_t
*
right
;
/**< Right child of Bin tree */
ml_select_e
criteria
;
/**< SELECT criteria type @see ml_select_e
* The criteria value is considered only when
* op = ML_OP_NONE i.e. in leaf nodes */
ml_comp_e
comp
;
/**< Condition between type and value */
union
{
int
i
;
char
*
str
;
}
value
;
/**< SELECT criteria value ( string or int ) */
union
{
int
i
;
char
*
str
;
}
lvalue
;
/**< Used as key value for people types/roles.
An empty string "" denotes ANY person role.
NULL is used for all other criterias */
};
/**
* Person class. Implemented as a linked list
*/
struct
ml_person_t
{
char
*
psz_role
;
/**< Type of person */
char
*
psz_name
;
/**< Name of the person */
int
i_id
;
/**< ID in the database */
ml_person_t
*
p_next
;
/**< Next person in list */
};
/*****************************************************************************
* ML Function headers
*****************************************************************************/
/**
* @brief Acquire a reference to the media library singleton
* @param p_this The object holding the media library
* @return The media library object. NULL if the media library
* object could not be loaded
*/
VLC_API
media_library_t
*
ml_Get
(
vlc_object_t
*
p_this
);
#define ml_Get( a ) ml_Get( VLC_OBJECT(a) )
/**
* @brief Create a Media Library VLC object.
* @param p_this Parent to attach the ML object to.
* @param psz_name Name for the module
* @return The ML object.
*/
media_library_t
*
ml_Create
(
vlc_object_t
*
p_this
,
char
*
psz_name
);
/**
* @brief Destructor for the Media library singleton
* @param p_this Parent the ML object is attached to
*/
void
ml_Destroy
(
vlc_object_t
*
p_this
);
/**
* @brief Control the Media Library
* @param p_media_library the media library object
* @param i_type one of ml_control_e values @see ml_control_e.
* @param ... optional arguments.
* @return VLC_SUCCESS or an error
*/
static
inline
int
ml_ControlVa
(
media_library_t
*
p_media_library
,
ml_control_e
i_type
,
va_list
args
)
{
return
p_media_library
->
functions
.
pf_Control
(
p_media_library
,
i_type
,
args
);
}
/**
* @brief Control the Media Library
* @param i_type one of ml_control_e values @see ml_control_e.
* Variable arguments list equivalent
*/
#define ml_Control( a, b, args... ) __ml_Control( a, b, ## args )
static
inline
int
__ml_Control
(
media_library_t
*
p_media_library
,
ml_control_e
i_type
,
...
)
{
va_list
args
;
int
returned
;
va_start
(
args
,
i_type
);
returned
=
ml_ControlVa
(
p_media_library
,
i_type
,
args
);
va_end
(
args
);
return
returned
;
}
/**
* @brief Determine an attribute's type (int or string)
* @param meta Attribute to test @see ml_select_e
* @return -1 if invalid, 0 if this is an integer, 1 if this is a string
*/
static
inline
int
ml_AttributeIsString
(
ml_select_e
meta
)
{
switch
(
meta
)
{
/* Strings */
case
ML_ALBUM
:
case
ML_ARTIST
:
case
ML_COMMENT
:
case
ML_COVER
:
case
ML_EXTRA
:
case
ML_GENRE
:
case
ML_LANGUAGE
:
case
ML_PREVIEW
:
case
ML_PEOPLE
:
case
ML_PEOPLE_ROLE
:
case
ML_ORIGINAL_TITLE
:
case
ML_TITLE
:
case
ML_URI
:
return
1
;
/* Integers */
case
ML_ALBUM_ID
:
case
ML_ARTIST_ID
:
case
ML_DURATION
:
case
ML_DISC_NUMBER
:
case
ML_COUNT_MEDIA
:
case
ML_COUNT_ALBUM
:
case
ML_COUNT_PEOPLE
:
case
ML_FILESIZE
:
case
ML_FIRST_PLAYED
:
case
ML_ID
:
case
ML_IMPORT_TIME
:
case
ML_LAST_PLAYED
:
case
ML_LIMIT
:
case
ML_PLAYED_COUNT
:
case
ML_PEOPLE_ID
:
case
ML_SCORE
:
case
ML_SKIPPED_COUNT
:
case
ML_TRACK_NUMBER
:
case
ML_TYPE
:
case
ML_VOTE
:
case
ML_YEAR
:
return
0
;
/* Invalid or no following value (in a SELECT statement) */
default:
return
-
1
;
}
}
/* Reference Counting Functions */
/**
* @brief Increment reference count of media
* @param p_media The media object
*/
static
inline
void
ml_gc_incref
(
ml_media_t
*
p_media
)
{
ml_gc_object_t
*
p_gc
=
&
p_media
->
ml_gc_data
;
if
(
p_gc
==
NULL
)
return
;
++
p_gc
->
refs
;
}
/**
* @brief Decrease reference count of media
* @param p_media The media object
*/
static
inline
void
ml_gc_decref
(
ml_media_t
*
p_media
)
{
/* The below code is from vlc_release(). */
unsigned
refs
;
bool
pool
;
ml_gc_object_t
*
p_gc
=
&
p_media
->
ml_gc_data
;
if
(
p_gc
==
NULL
)
return
;
refs
=
--
p_gc
->
refs
;
pool
=
p_gc
->
pool
;
if
(
refs
==
0
&&
!
pool
)
{
p_gc
->
pf_destructor
(
p_gc
);
}
}
/*****************************************************************************
* ML Free Functions
*****************************************************************************/
/**
* @brief Free a person object
* @param p_media Person object to free
* @note This function is NOT threadsafe
*/
static
inline
void
ml_FreePeople
(
ml_person_t
*
p_person
)
{
if
(
p_person
==
NULL
)
return
;
ml_FreePeople
(
p_person
->
p_next
);
free
(
p_person
->
psz_name
);
free
(
p_person
->
psz_role
);
free
(
p_person
);
}
/**
* @brief Free only the content of a media. @see ml_media_t
* @param p_media Media object
* @note This function is NOT threadsafe.
*/
static
inline
void
ml_FreeMediaContent
(
ml_media_t
*
p_media
)
{
FREENULL
(
p_media
->
psz_uri
);
FREENULL
(
p_media
->
psz_title
);
FREENULL
(
p_media
->
psz_orig_title
);
FREENULL
(
p_media
->
psz_cover
);
FREENULL
(
p_media
->
psz_comment
);
FREENULL
(
p_media
->
psz_extra
);
FREENULL
(
p_media
->
psz_genre
);
FREENULL
(
p_media
->
psz_album
);
FREENULL
(
p_media
->
psz_preview
);
FREENULL
(
p_media
->
psz_language
);
ml_FreePeople
(
p_media
->
p_people
);
p_media
->
b_sparse
=
true
;
p_media
->
i_id
=
0
;
p_media
->
i_type
=
ML_UNKNOWN
;
p_media
->
i_album_id
=
0
;
p_media
->
i_disc_number
=
0
;
p_media
->
i_track_number
=
0
;
p_media
->
i_year
=
0
;
p_media
->
i_vote
=
0
;
p_media
->
i_score
=
0
;
p_media
->
i_filesize
=
0
;
p_media
->
i_duration
=
0
;
p_media
->
i_played_count
=
0
;
p_media
->
i_last_played
=
0
;
p_media
->
i_skipped_count
=
0
;
p_media
->
i_last_skipped
=
0
;
p_media
->
i_first_played
=
0
;
p_media
->
i_import_time
=
0
;
p_media
->
i_bitrate
=
0
;
p_media
->
i_samplerate
=
0
;
p_media
->
i_bpm
=
0
;
}
/**
* @brief Free a result item. @see ml_result_t
* @param p_result Result item to free
* @note This will free any strings and decref medias.
*/
static
inline
void
ml_FreeResult
(
ml_result_t
*
p_result
)
{
if
(
p_result
)
{
switch
(
p_result
->
type
)
{
case
ML_TYPE_PSZ
:
free
(
p_result
->
value
.
psz
);
break
;
case
ML_TYPE_MEDIA
:
ml_gc_decref
(
p_result
->
value
.
p_media
);
break
;
default:
break
;
}
free
(
p_result
);
}
}
/**
* @brief Free a ml_element_t item.
* @param p_find Find object to free
* @see ml_element_t */
static
inline
void
ml_FreeElement
(
ml_element_t
*
p_elt
)
{
if
(
p_elt
)
{
if
(
ml_AttributeIsString
(
p_elt
->
criteria
)
)
{
free
(
p_elt
->
value
.
str
);
}
if
(
p_elt
->
criteria
==
ML_PEOPLE
)
{
free
(
p_elt
->
lvalue
.
str
);
}
free
(
p_elt
);
}
}
/**
* @brief Destroy a vlc_array_t of ml_result_t
* @param ml_result_array The result array to free
* @note Frees all results and contents of the results
*/
static
inline
void
ml_DestroyResultArray
(
vlc_array_t
*
p_result_array
)
{
for
(
int
i
=
0
;
i
<
vlc_array_count
(
p_result_array
);
i
++
)
{
ml_FreeResult
(
(
ml_result_t
*
)
vlc_array_item_at_index
(
p_result_array
,
i
)
);
}
}
/*****************************************************************************
* ML Object Management Functions
*****************************************************************************/
/** Helpers for locking and unlocking */
#define ml_LockMedia( a ) vlc_mutex_lock( &a->lock )
#define ml_UnlockMedia( a ) vlc_mutex_unlock( &a->lock )
/**
* @brief Object constructor for ml_media_t
* @param p_ml The media library object
* @param id If 0, this item isn't in database. If non zero, it is and
* it will be a singleton
* @param select Type of object
* @param reload Whether to reload from database
*/
VLC_API
ml_media_t
*
media_New
(
media_library_t
*
p_ml
,
int
id
,
ml_select_e
select
,
bool
reload
);
/* Forward declaration */
static
inline
int
ml_CopyPersons
(
ml_person_t
**
a
,
ml_person_t
*
b
);
/**
* @brief Copy all members of a ml_media_t to another.
* @param b Destination media, already allocated
* @param a Source media, cannot be NULL, const
* @note This does not check memory allocation (for strdup). It is threadsafe
* @todo Free b content, before inserting a?
*/
static
inline
int
ml_CopyMedia
(
ml_media_t
*
b
,
ml_media_t
*
a
)
{
if
(
!
a
||
!
b
)
return
VLC_EGENERIC
;
if
(
a
==
b
)
return
VLC_SUCCESS
;
ml_LockMedia
(
a
);
ml_LockMedia
(
b
);
b
->
b_sparse
=
a
->
b_sparse
;
b
->
i_id
=
a
->
i_id
;
b
->
i_type
=
a
->
i_type
;
b
->
i_album_id
=
a
->
i_album_id
;
b
->
i_disc_number
=
a
->
i_disc_number
;
b
->
i_track_number
=
a
->
i_track_number
;
b
->
i_year
=
a
->
i_year
;
b
->
i_vote
=
a
->
i_vote
;
b
->
i_score
=
a
->
i_score
;
b
->
i_filesize
=
a
->
i_filesize
;
b
->
i_duration
=
a
->
i_duration
;
b
->
i_played_count
=
a
->
i_played_count
;
b
->
i_last_played
=
a
->
i_last_played
;
b
->
i_skipped_count
=
a
->
i_skipped_count
;
b
->
i_last_skipped
=
a
->
i_last_skipped
;
b
->
i_first_played
=
a
->
i_first_played
;
b
->
i_import_time
=
a
->
i_import_time
;
b
->
i_bitrate
=
a
->
i_bitrate
;
b
->
i_samplerate
=
a
->
i_samplerate
;
b
->
i_bpm
=
a
->
i_bpm
;
FREENULL
(
b
->
psz_uri
);
if
(
a
->
psz_uri
)
b
->
psz_uri
=
strdup
(
a
->
psz_uri
);
FREENULL
(
b
->
psz_title
);
if
(
a
->
psz_title
)
b
->
psz_title
=
strdup
(
a
->
psz_title
);
FREENULL
(
b
->
psz_orig_title
);
if
(
a
->
psz_orig_title
)
b
->
psz_orig_title
=
strdup
(
a
->
psz_orig_title
);
FREENULL
(
b
->
psz_album
);
if
(
a
->
psz_album
)
b
->
psz_album
=
strdup
(
a
->
psz_album
);
FREENULL
(
b
->
psz_cover
);
if
(
a
->
psz_cover
)
b
->
psz_cover
=
strdup
(
a
->
psz_cover
);
FREENULL
(
b
->
psz_genre
);
if
(
a
->
psz_genre
)
b
->
psz_genre
=
strdup
(
a
->
psz_genre
);
FREENULL
(
b
->
psz_comment
);
if
(
a
->
psz_comment
)
b
->
psz_comment
=
strdup
(
a
->
psz_comment
);
FREENULL
(
b
->
psz_extra
);
if
(
a
->
psz_extra
)
b
->
psz_extra
=
strdup
(
a
->
psz_extra
);
FREENULL
(
b
->
psz_preview
);
if
(
a
->
psz_preview
)
b
->
psz_preview
=
strdup
(
a
->
psz_preview
);
FREENULL
(
b
->
psz_language
);
if
(
a
->
psz_language
)
b
->
psz_language
=
strdup
(
a
->
psz_language
);
ml_FreePeople
(
b
->
p_people
);
b
->
p_people
=
NULL
;
if
(
a
->
p_people
)
ml_CopyPersons
(
&
(
b
->
p_people
),
a
->
p_people
);
ml_UnlockMedia
(
b
);
ml_UnlockMedia
(
a
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* ML Find Tree Related Functions
*****************************************************************************/
#define ml_FreeFindTree( tree ) ml_GenericFreeFindTree( tree, true )
#define ml_ShallowFreeFindTree( tree ) ml_GenericFreeFindTree( tree, false )
/**
* @brief Free a find tree
* @param Find tree to free
* @param true to free any associated strings, false to not free them
*/
static
inline
void
ml_GenericFreeFindTree
(
ml_ftree_t
*
tree
,
bool
freestrings
)
{
if
(
tree
==
NULL
)
return
;
if
(
tree
->
left
)
{
ml_GenericFreeFindTree
(
tree
->
left
,
freestrings
);
free
(
tree
->
left
);
}
if
(
tree
->
right
)
{
ml_GenericFreeFindTree
(
tree
->
right
,
freestrings
);
free
(
tree
->
right
);
}
if
(
tree
->
op
==
ML_OP_NONE
&&
ml_AttributeIsString
(
tree
->
criteria
)
&&
freestrings
)
{
free
(
tree
->
value
.
str
);
if
(
tree
->
criteria
==
ML_PEOPLE
)
free
(
tree
->
lvalue
.
str
);
}
}
/**
* @brief Checks if a given find tree has leaf nodes
* @param Find tree
* @return Number of leaf nodes
*/
static
inline
int
ml_FtreeHasOp
(
ml_ftree_t
*
tree
)
{
if
(
tree
==
NULL
)
return
0
;
if
(
tree
->
criteria
>
0
&&
tree
->
op
==
ML_OP_NONE
)
return
1
;
else
return
ml_FtreeHasOp
(
tree
->
left
)
+
ml_FtreeHasOp
(
tree
->
right
);
}
/**
* @brief Connect up a find tree
* @param op operator to connect with
* If op = ML_OP_NONE, then you are connecting to a tree consisting of
* only SPECIAL nodes.
* If op = ML_OP_NOT, then right MUST be NULL
* op must not be ML_OP_SPECIAL, @see ml_FtreeSpec
* @param left part of the tree
* @param right part of the tree
* @return Pointer to new tree
* @note Use the helpers!
*/
VLC_API
ml_ftree_t
*
ml_OpConnectChilds
(
ml_op_e
op
,
ml_ftree_t
*
left
,
ml_ftree_t
*
right
);
/**
* @brief Attaches a special node to a tree
* @param tree Tree to attach special node to
* @param crit Criteria may be SORT_ASC, SORT_DESC, LIMIT or DISTINCT
* @param limit Limit used if LIMIT criteria used
* @param Sort string used if SORT criteria is used
* @return Pointer to new tree
* @note Use the helpers
*/
VLC_API
ml_ftree_t
*
ml_FtreeSpec
(
ml_ftree_t
*
tree
,
ml_select_e
crit
,
int
limit
,
char
*
sort
);
/**
* @brief This function gives quick sequential adding capability
* @param left Tree to add to. This may be NULL
* @param right Tree to append. May not be NULL
* @return Pointer to new tree.*/
static
inline
ml_ftree_t
*
ml_FtreeFastAnd
(
ml_ftree_t
*
left
,
ml_ftree_t
*
right
)
{
if
(
ml_FtreeHasOp
(
left
)
==
0
)
{
return
ml_OpConnectChilds
(
ML_OP_NONE
,
left
,
right
);
}
else
{
return
ml_OpConnectChilds
(
ML_OP_AND
,
left
,
right
);
}
}
#define ml_FtreeAnd( left, right ) ml_OpConnectChilds( ML_OP_AND, left, right )
#define ml_FtreeOr( left, right ) ml_OpConnectChilds( ML_OP_OR, left, right )
#define ml_FtreeNot( left ) ml_OpConnectChilds( ML_OP_NOT, left, NULL )
#define ml_FtreeSpecAsc( tree, str ) ml_FtreeSpec( tree, ML_SORT_ASC, 0, str )
#define ml_FtreeSpecDesc( tree, str ) ml_FtreeSpec( tree, ML_SORT_DESC, 0, str )
#define ml_FtreeSpecLimit( tree, limit ) ml_FtreeSpec( tree, ML_LIMIT, limit, NULL )
#define ml_FtreeSpecDistinct( tree ) ml_FtreeSpec( tree, ML_DISTINCT, 0, NULL )
/*****************************************************************************
* ML Core Functions
*****************************************************************************/
/**
* @brief Create input item from media
* @param p_media_library This ML instance.
* @param i_media_id ID of the media to use to create an input_item.
* @return The media item.
*/
static
inline
input_item_t
*
ml_CreateInputItem
(
media_library_t
*
p_media_library
,
int
i_media_id
)
{
return
p_media_library
->
functions
.
pf_InputItemFromMedia
(
p_media_library
,
i_media_id
);
}
/**
* @brief Search in the database according some criterias
*
* @param p_media_library the media library object
* @param result a pointer to a result array
* @param ... parameters to select the data
* @return VLC_SUCCESS or an error
*/
static
inline
int
__ml_Find
(
media_library_t
*
p_media_library
,
vlc_array_t
*
p_result_array
,
...
)
{
va_list
args
;
int
returned
;
va_start
(
args
,
p_result_array
);
returned
=
p_media_library
->
functions
.
pf_Find
(
p_media_library
,
p_result_array
,
args
);
va_end
(
args
);
return
returned
;
}
/**
* @brief Search in the database according some criterias (threaded)
* @param p_media_library the media library object
* @param result_array a pointer to a result array
* @param result_type type of data to retrieve
* @param psz_lvalue This should contain any necessary lvalue/key
* for the given result_type. Used for ML_PEOPLE. Otherwise NULL
* @param args parameters to select the data
* @return VLC_SUCCESS or an error
*/
static
inline
int
ml_FindAdv
(
media_library_t
*
p_media_library
,
vlc_array_t
*
p_result_array
,
ml_select_e
result_type
,
char
*
psz_lvalue
,
ml_ftree_t
*
tree
)
{
return
p_media_library
->
functions
.
pf_FindAdv
(
p_media_library
,
p_result_array
,
result_type
,
psz_lvalue
,
tree
);
}
/**
* @brief Find a value in the ML database, fill p_result with it.
* @param p_media_library Media library object
* @param p_result Object to put result into
* @param Args [ SelectType [ PersonType ] Value ] ... ML_END
* @note Do not use this function directly.
*/
static
inline
int
__ml_GetValue
(
media_library_t
*
p_media_library
,
ml_result_t
*
p_result
,
va_list
args
)
{
vlc_array_t
*
p_result_array
=
vlc_array_new
();
int
i_ret
=
p_media_library
->
functions
.
pf_Find
(
p_media_library
,
p_result_array
,
args
);
if
(
i_ret
!=
VLC_SUCCESS
)
goto
exit
;
if
(
vlc_array_count
(
p_result_array
)
>
0
)
memcpy
(
p_result
,
(
ml_result_t
*
)
vlc_array_item_at_index
(
p_result_array
,
0
),
sizeof
(
ml_result_t
)
);
else
i_ret
=
VLC_EGENERIC
;
exit:
/* Note: Do not free the results, because of memcpy */
vlc_array_destroy
(
p_result_array
);
return
i_ret
;
}
/**
* @brief Search an INTEGER in the database
* This uses a Query but returns only one integer (>0), or an error code.
*
* @param p_media_library the media library object
* @param va_args parameters to select the data
* @return Found INTEGER >= 0 or an error
*/
#define ml_GetInt( ml, ... ) __ml_GetInt( ml, __VA_ARGS__, ML_LIMIT, 1, ML_END )
static
inline
int
__ml_GetInt
(
media_library_t
*
p_media_library
,
...
)
{
va_list
args
;
va_start
(
args
,
p_media_library
);
ml_result_t
result
;
int
i_ret
=
__ml_GetValue
(
p_media_library
,
&
result
,
args
);
va_end
(
args
);
if
(
i_ret
!=
VLC_SUCCESS
)
return
i_ret
;
else
return
result
.
value
.
i
;
}
/**
* @brief Search a string (VARCHAR) in the database
* This uses a Query but returns only one integer (>0), or an error code.
*
* @param p_media_library the media library object
* @param va_args parameters to select the data
* @return Found string, or NULL if not found or in case of error
*/
#define ml_FindPsz( ml, ... ) __ml_GetPsz( ml, __VA_ARGS__, ML_LIMIT, 1, ML_END )
static
inline
char
*
__ml_GetPsz
(
media_library_t
*
p_media_library
,
...
)
{
va_list
args
;
va_start
(
args
,
p_media_library
);
ml_result_t
result
;
int
i_ret
=
__ml_GetValue
(
p_media_library
,
&
result
,
args
);
va_end
(
args
);
if
(
i_ret
!=
VLC_SUCCESS
)
return
NULL
;
else
return
result
.
value
.
psz
;
// no need to duplicate
}
/**
* @brief Generic update in Media Library database
*
* @param p_media_library the media library object
* @param selected_type the type of the element we're selecting
* @param where list of ids/uris to be changed
* @param changes list of changes to make in the entries
* @return VLC_SUCCESS or VLC_EGENERIC
*/
static
inline
int
ml_Update
(
media_library_t
*
p_media_library
,
ml_select_e
selected_type
,
const
char
*
psz_lvalue
,
ml_ftree_t
*
where
,
vlc_array_t
*
changes
)
{
return
p_media_library
->
functions
.
pf_Update
(
p_media_library
,
selected_type
,
psz_lvalue
,
where
,
changes
);
}
/**
* @brief Update a given table
* @param p_media_library The media library object
* @param selected_type The table to update
* @param psz_lvalue The role of the person if selected_type = ML_PEOPLE
* @param id The id of the row to update
* @param ... The update data. [SelectType [RoleType] Value]
*/
VLC_API
int
ml_UpdateSimple
(
media_library_t
*
p_media_library
,
ml_select_e
selected_type
,
const
char
*
psz_lvalue
,
int
id
,
...
);
#define ml_UpdateSimple( ml, sel, lval, id, ... ) \
ml_UpdateSimple( ml, sel, lval, id, __VA_ARGS__, ML_END )
/**
* @brief Generic DELETE function
* Delete a media and all its references which don't point
* to anything else.
*
* @param p_media_library This media_library_t object
* @param id the id of the media to delete
* @return VLC_SUCCESS or VLC_EGENERIC
*/
static
inline
int
ml_DeleteSimple
(
media_library_t
*
p_media_library
,
int
id
)
{
vlc_array_t
*
p_where
=
vlc_array_new
();
ml_element_t
*
p_find
=
(
ml_element_t
*
)
calloc
(
1
,
sizeof
(
ml_element_t
)
);
p_find
->
criteria
=
ML_ID
;
p_find
->
value
.
i
=
id
;
vlc_array_append
(
p_where
,
p_find
);
int
i_return
=
p_media_library
->
functions
.
pf_Delete
(
p_media_library
,
p_where
);
free
(
p_find
);
vlc_array_destroy
(
p_where
);
return
i_return
;
}
/**
* @brief Delete many medias in the media library
* @param p_media_library Media library object
* @param p_array Array of ids to delete
* @return VLC_SUCCESS or VLC_EGENERIC
*/
static
inline
int
ml_Delete
(
media_library_t
*
p_media_library
,
vlc_array_t
*
p_array
)
{
return
p_media_library
->
functions
.
pf_Delete
(
p_media_library
,
p_array
);
}
/*****************************************************************************
* ML Person Related Functions
*****************************************************************************/
/**
* @brief Create and append a person object to the given list
* @param pp_person pointer to person list. Set the address to null to create new list
* @param i_role The role of the person
* @param psz_name The name string. Will be strdup'd
* @param i_id The id in the database
* @note This function is NOT thread safe. Please lock any associated media
*/
static
inline
int
ml_CreateAppendPersonAdv
(
ml_person_t
**
pp_person
,
const
char
*
psz_role
,
const
char
*
psz_name
,
int
i_id
)
{
if
(
i_id
==
0
||
!
(
psz_name
&&
*
psz_name
&&
psz_role
&&
*
psz_role
)
)
return
VLC_SUCCESS
;
if
(
!
pp_person
)
return
VLC_EGENERIC
;
if
(
*
pp_person
!=
NULL
)
return
ml_CreateAppendPersonAdv
(
&
((
**
pp_person
).
p_next
),
psz_role
,
psz_name
,
i_id
);
*
pp_person
=
(
ml_person_t
*
)
calloc
(
1
,
sizeof
(
ml_person_t
)
);
(
*
pp_person
)
->
psz_name
=
(
psz_name
&&
*
psz_name
)
?
strdup
(
psz_name
)
:
NULL
;
(
*
pp_person
)
->
psz_role
=
(
psz_role
&&
*
psz_role
)
?
strdup
(
psz_role
)
:
NULL
;
(
*
pp_person
)
->
i_id
=
i_id
;
(
*
pp_person
)
->
p_next
=
NULL
;
return
VLC_SUCCESS
;
}
/**
* @brief Create and append a person object to the given list
* @param pp_person pointer to person list.
* Set the address to NULL to create a new list
* @param personfrom Person object to copy from
* @note Ignores the next variable and copies only the variables.
* Uses ml_CreateAppendPersonAdv
* @note This function is NOT threadsafe
*/
static
inline
int
ml_CreateAppendPerson
(
ml_person_t
**
pp_person
,
ml_person_t
*
p_personfrom
)
{
return
ml_CreateAppendPersonAdv
(
pp_person
,
p_personfrom
->
psz_role
,
p_personfrom
->
psz_name
,
p_personfrom
->
i_id
);
}
/**
* @brief Copy one person list into another
* @param a To list
* @param b From list
* @note On errors, you have to free any allocated persons yourself
* @note This function is NOT threadsafe. Please ensure your medias are locked
*/
static
inline
int
ml_CopyPersons
(
ml_person_t
**
a
,
ml_person_t
*
b
)
{
int
i_ret
;
while
(
b
)
{
i_ret
=
ml_CreateAppendPerson
(
a
,
b
);
if
(
i_ret
!=
VLC_SUCCESS
)
return
i_ret
;
b
=
b
->
p_next
;
}
return
VLC_SUCCESS
;
}
/**
* @brief Returns a person list of given type
* @param p_ml The ML object
* @param p_media The Media object
* @param i_type The person type
* @note This function is thread safe
*/
VLC_API
ml_person_t
*
ml_GetPersonsFromMedia
(
media_library_t
*
p_ml
,
ml_media_t
*
p_media
,
const
char
*
psz_role
);
#define ml_GetAlbumArtistsFromMedia( a, b ) ml_GetPersonsFromMedia( a, b, ML_PERSON_ALBUM_ARTIST );
#define ml_GetArtistsFromMedia( a, b ) ml_GetPersonsFromMedia( a, b, ML_PERSON_ARTIST );
#define ml_GetEncodersFromMedia( a, b ) ml_GetPersonsFromMedia( a, b, ML_PERSON_ENCODER );
#define ml_GetPublishersFromMedia( a, b ) ml_GetPersonsFromMedia( a, b, ML_PERSON_PUBLISHER );
/**
* @brief Delete a certain type of people from a media
* @param p_media Media to delete from
* @param i_type Type of person to delete
* @note This function is threadsafe
*/
VLC_API
void
ml_DeletePersonTypeFromMedia
(
ml_media_t
*
p_media
,
const
char
*
psz_role
);
/**
* Convenience Macros
*/
/**
* Get information using the *media* ID. This returns only 1 information.
* @note You have to free the string returned (if that's a string!).
*/
#define ml_GetAlbumById( a, id ) ml_GetPsz( a, ML_ALBUM, ML_ID, id )
#define ml_GetArtistById( a, id ) ml_GetPsz( a, ML_PEOPLE, ML_PERSON_ARTIST, ML_ID, id )
#define ml_GetCoverUriById( a, id ) ml_GetPsz( a, ML_COVER, ML_ID, id )
#define ml_GetEncoderById( a, id ) ml_GetPsz( a, ML_PEOPLE, ML_PERSON_ENCODER, ML_ID, id )
#define ml_GetExtraById( a, id ) ml_GetPsz( a, ML_EXTRA, ML_ID, id )
#define ml_GetGenreById( a, id ) ml_GetPsz( a, ML_GENRE, ML_ID, id )
#define ml_GetOriginalTitleById( a, id ) ml_GetPsz( a, ML_ORIGINAL_TITLE, ML_ID, id )
#define ml_GetPublisherById( a, id ) ml_GetPsz( a, ML_PEOPLE, ML_PERSON_PUBLISHER, ML_ID, id )
#define ml_GetTitleById( a, id ) ml_GetPsz( a, ML_TITLE, ML_ID, id )
#define ml_GetUriById( a, id ) ml_GetPsz( a, ML_URI, ML_ID, id )
#define ml_GetAlbumIdById( a, id ) ml_GetInt( a, ML_ALBUM_ID, ML_ID, id )
#define ml_GetArtistIdById( a, id ) ml_GetInt( a, ML_PEOPLE_ID, ML_PERSON_ARTIST, ML_ID, id )
#define ml_GetDurationById( a, id ) ml_GetInt( a, ML_DURATION, ML_ID, id )
#define ml_GetEncoderIdById( a, id ) ml_GetInt( a, ML_PEOPLE_ID, ML_PERSON_ENCODER, ML_ID, id )
#define ml_GetLastPlayedById( a, id ) ml_GetInt( a, ML_LAST_PLAYED, ML_ID, id )
#define ml_GetPlayedCountById( a, id ) ml_GetInt( a, ML_PLAYED_COUNT, ML_ID, id )
#define ml_GetPublisherIdById( a, id ) ml_GetInt( a, ML_PEOPLE_ID, ML_PERSON_PUBLISHER, ML_ID, id )
#define ml_GetScoreById( a, id ) ml_GetInt( a, ML_SCORE, ML_ID, id )
#define ml_GetTrackNumberById( a, id ) ml_GetInt( a, ML_TRACK_NUMBER, ML_ID, id )
#define ml_GetTypeById( a, id ) ml_GetInt( a, ML_TYPE, ML_ID, id )
#define ml_GetYearById( a, id ) ml_GetInt( a, ML_YEAR, ML_ID, id )
#define ml_GetVoteById( a, id ) ml_GetInt( a, ML_VOTE, ML_ID, id )
/** Albums handling */
#define ml_GetAlbumId( a, b ) ml_GetInt( a, ML_ALBUM_ID, ML_ALBUM, b )
/** People handling */
#define ml_GetArtistId( a, b ) ml_GetInt( a, ML_PERSON_ID, ML_PERSON_ARTIST, ML_PERSON, ML_PERSON_ARTIST, b )
#define ml_GetEncoderId( a, b ) ml_GetInt( a, ML_PERSON_ID, ML_PERSON_ENCODER, ML_PERSON, ML_PERSON_ENCODER, b )
#define ml_GetPublisherId( a, b ) ml_GetInt( a, ML_PERSON_ID, ML_PERSON_PUBLISHER, ML_PERSON, ML_PERSON_PUBLISHER, b )
/** Counts handling */
#define ml_GetMediaCount( a, ... ) __ml_GetInt( a, ML_COUNT_MEDIA, __VA_ARGS__, ML_END )
#define ml_GetAlbumCount( a, ... ) __ml_GetInt( a, ML_COUNT_ALBUM, __VA_ARGS__, ML_END )
#define ml_GetPeopleCount( a, ... ) __ml_GetInt( a, ML_COUNT_PEOPLE, __VA_ARGS__, ML_END )
#define ml_Find( a, b, ... ) __ml_Find( a, b, __VA_ARGS__, ML_END )
#define ml_FindAlbum( a, b, ... ) __ml_Find( a, b, ML_ALBUM, __VA_ARGS__, ML_END )
#define ml_FindArtist( a, b, ... ) __ml_Find( a, b, ML_PERSON, ML_PERSON_ARTIST, __VA_ARGS__, ML_END )
#define ml_FindEncoder( a, b, ... ) __ml_Find( a, b, ML_PERSON, ML_PERSON_ENCODER, __VA_ARGS__, ML_END )
#define ml_FindGenre( a, b, ... ) __ml_Find( a, b, ML_GENRE, __VA_ARGS__, ML_END )
#define ml_FindMedia( a, b, ... ) __ml_Find( a, b, ML_MEDIA, __VA_ARGS__, ML_END )
#define ml_FindOriginalTitle( a, b, ... ) __ml_Find( a, b, ML_ORIGINAL_TITLE, __VA_ARGS__, ML_END )
#define ml_FindPublisher( a, b, ... ) __ml_Find( a, b, ML_PERSON, ML_PERSON_PUBLISHER, __VA_ARGS__, ML_END )
#define ml_FindTitle( a, b, ... ) __ml_Find( a, b, ML_TITLE, __VA_ARGS__, ML_END )
#define ml_FindType( a, b, ... ) __ml_Find( a, b, ML_TYPE, __VA_ARGS__, ML_END )
#define ml_FindUri( a, b, ... ) __ml_Find( a, b, ML_URI, __VA_ARGS__, ML_END )
#define ml_FindYear( a, b, ... ) __ml_Find( a, b, ML_YEAR, __VA_ARGS__, ML_END )
#define ml_FindAllAlbums( a, b ) ml_FindAlbum( a, b, ML_DISTINCT )
#define ml_FindAllArtists( a, b ) ml_FindArtist( a, b, ML_DISTINCT )
#define ml_FindAllGenres( a, b ) ml_FindGenre( a, b, ML_DISTINCT )
#define ml_FindAllMedias( a, b ) ml_FindMedia( a, b, ML_DISTINCT )
#define ml_FindAllOriginalTitles( a, b ) ml_FindOriginalTitle( a, b, ML_DISTINCT )
#define ml_FindAllPublishers( a, b, ... ) ml_FindPublisher( a, b, ML_DISTINCT )
#define ml_FindAllTitles( a, b ) ml_FindTitle( a, b, ML_DISTINCT )
#define ml_FindAllTypes( a, b ) ml_FindType( a, b, ML_DISTINCT )
#define ml_FindAllUris( a, b ) ml_FindUri( a, b, ML_DISTINCT )
#define ml_FindAllYears( a, b ) ml_FindYear( a, b, ML_DISTINCT )
#define ml_FindAlbumAdv( a, b, c ) ml_FindAdv( a, b, ML_ALBUM, NULL, c )
#define ml_FindArtistAdv( a, b, c ) ml_FindAdv( a, b, ML_PERSON, ML_PERSON_ARTIST, c )
#define ml_FindEncoderAdv( a, b, c ) ml_FindAdv( a, b, ML_PERSON, ML_PERSON_ENCODER, c )
#define ml_FindGenreAdv( a, b, c ) ml_FindAdv( a, b, ML_GENRE, NULL, c )
#define ml_FindMediaAdv( a, b, c ) ml_FindAdv( a, b, ML_MEDIA, NULL, c )
#define ml_FindOriginalTitleAdv( a, b, c ) ml_FindAdv( a, b, ML_ORIGINAL_TITLE,NULL, c )
#define ml_FindPublisherAdv( a, b, c ) ml_FindAdv( a, b, ML_PUBLISHER, ML_PERSON_PUBLISHER, c )
#define ml_FindTitleAdv( a, b, c ) ml_FindAdv( a, b, ML_TITLE, NULL, c )
#define ml_FindTypeAdv( a, b, c ) ml_FindAdv( a, b, ML_TYPE, NULL, c )
#define ml_FindUriAdv( a, b, c ) ml_FindAdv( a, b, ML_URI, NULL, c )
#define ml_FindYearAdv( a, b, c ) ml_FindAdv( a, b, ML_YEAR, NULL, c )
#ifdef __cplusplus
}
#endif
/* C++ */
...
...
src/Makefile.am
View file @
628b01be
...
...
@@ -461,7 +461,6 @@ SOURCES_libvlc_common = \
misc/update.c
\
misc/update_crypto.c
\
misc/xml.c
\
misc/media_library.c
\
extras/libc.c
\
extras/tdestroy.c
\
misc/filter.c
\
...
...
src/libvlc-module.c
View file @
628b01be
...
...
@@ -2033,10 +2033,6 @@ vlc_module_begin ()
PLAYLISTENQUEUE_LONGTEXT
,
true
)
#endif
add_bool
(
"media-library"
,
0
,
ML_TEXT
,
ML_LONGTEXT
,
false
)
#if defined( MEDIA_LIBRARY )
add_bool
(
"load-media-library-on-startup"
,
1
,
LOAD_ML_TEXT
,
LOAD_ML_LONGTEXT
,
false
)
#endif
add_bool
(
"playlist-tree"
,
0
,
PLTREE_TEXT
,
PLTREE_LONGTEXT
,
false
)
add_string
(
"open"
,
""
,
OPEN_TEXT
,
OPEN_LONGTEXT
,
false
)
...
...
src/libvlc.c
View file @
628b01be
...
...
@@ -55,7 +55,6 @@
#endif
#include <vlc_media_library.h>
#include <vlc_playlist.h>
#include <vlc_interface.h>
...
...
@@ -109,12 +108,9 @@ libvlc_int_t * libvlc_InternalCreate( void )
priv
=
libvlc_priv
(
p_libvlc
);
priv
->
p_playlist
=
NULL
;
priv
->
p_ml
=
NULL
;
priv
->
p_dialog_provider
=
NULL
;
priv
->
p_vlm
=
NULL
;
/* Initialize mutexes */
vlc_mutex_init
(
&
priv
->
ml_lock
);
vlc_ExitInit
(
&
priv
->
exit
);
return
p_libvlc
;
...
...
@@ -395,23 +391,6 @@ dbus_out:
/* System specific configuration */
system_Configure
(
p_libvlc
,
i_argc
-
vlc_optind
,
ppsz_argv
+
vlc_optind
);
#if defined(MEDIA_LIBRARY)
/* Get the ML */
if
(
var_GetBool
(
p_libvlc
,
"load-media-library-on-startup"
)
)
{
priv
->
p_ml
=
ml_Create
(
VLC_OBJECT
(
p_libvlc
),
NULL
);
if
(
!
priv
->
p_ml
)
{
msg_Err
(
p_libvlc
,
"ML initialization failed"
);
return
VLC_EGENERIC
;
}
}
else
{
priv
->
p_ml
=
NULL
;
}
#endif
#ifdef ENABLE_VLM
/* Initialize VLM if vlm-conf is specified */
psz_parser
=
var_CreateGetNonEmptyString
(
p_libvlc
,
"vlm-conf"
);
...
...
@@ -551,16 +530,6 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
}
#endif
#if defined(MEDIA_LIBRARY)
media_library_t
*
p_ml
=
priv
->
p_ml
;
if
(
p_ml
)
{
ml_Destroy
(
VLC_OBJECT
(
p_ml
)
);
vlc_object_release
(
p_ml
);
libvlc_priv
(
p_playlist
->
p_libvlc
)
->
p_ml
=
NULL
;
}
#endif
/* Free playlist now, all threads are gone */
playlist_t
*
p_playlist
=
libvlc_priv
(
p_libvlc
)
->
p_playlist
;
if
(
p_playlist
!=
NULL
)
...
...
@@ -612,9 +581,7 @@ void libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
{
libvlc_priv_t
*
priv
=
libvlc_priv
(
p_libvlc
);
/* Destroy mutexes */
vlc_ExitDestroy
(
&
priv
->
exit
);
vlc_mutex_destroy
(
&
priv
->
ml_lock
);
assert
(
atomic_load
(
&
(
vlc_internals
(
p_libvlc
)
->
refs
))
==
1
);
vlc_object_release
(
p_libvlc
);
...
...
src/libvlc.h
View file @
628b01be
...
...
@@ -159,8 +159,6 @@ typedef struct libvlc_priv_t
/* Singleton objects */
playlist_t
*
p_playlist
;
///< the playlist singleton
struct
media_library_t
*
p_ml
;
///< the ML singleton
vlc_mutex_t
ml_lock
;
///< Mutex for ML creation
vlm_t
*
p_vlm
;
///< the VLM singleton (or NULL)
vlc_object_t
*
p_dialog_provider
;
///< dialog provider
#ifdef ENABLE_SOUT
...
...
src/libvlccore.sym
View file @
628b01be
...
...
@@ -230,13 +230,7 @@ vlc_UrlClean
vlc_path2uri
make_path
mdate
ml_Get
media_New
ml_OpConnectChilds
ml_FtreeSpec
ml_UpdateSimple
ml_GetPersonsFromMedia
ml_DeletePersonTypeFromMedia
module_config_free
module_config_get
module_exists
...
...
src/misc/media_library.c
deleted
100644 → 0
View file @
acee3359
/*****************************************************************************
* media_library.c: SQL-based media library: ML creators and destructors
*****************************************************************************
* Copyright (C) 2009-2010 VLC authors and VideoLAN and AUTHORS
* $Id$
*
* Authors: Srikanth Raju <srikiraju at gmail dot com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if defined(MEDIA_LIBRARY)
#include <assert.h>
#include <vlc_media_library.h>
#include <vlc_modules.h>
#include "../libvlc.h"
/**
* @brief Destroy the medialibrary object
* @param Parent object that holds the media library object
*/
void
ml_Destroy
(
vlc_object_t
*
p_this
)
{
media_library_t
*
p_ml
=
(
media_library_t
*
)
p_this
;
module_unneed
(
p_ml
,
p_ml
->
p_module
);
}
/**
* Atomically set the reference count to 1.
* @param p_gc reference counted object
* @param pf_destruct destruction calback
* @return p_gc.
*/
static
void
*
ml_gc_init
(
ml_gc_object_t
*
p_gc
,
void
(
*
pf_destruct
)
(
ml_gc_object_t
*
))
{
/* There is no point in using the GC if there is no destructor... */
assert
(
pf_destruct
);
p_gc
->
pf_destructor
=
pf_destruct
;
p_gc
->
pool
=
false
;
p_gc
->
refs
=
1
;
return
p_gc
;
}
/**
* @brief Create an instance of the media library
* @param p_this Parent object
* @param psz_name Name which is passed to module_need (not needed)
* @return p_ml created and attached, module loaded. NULL if
* not able to load
*/
media_library_t
*
ml_Create
(
vlc_object_t
*
p_this
,
char
*
psz_name
)
{
media_library_t
*
p_ml
;
p_ml
=
(
media_library_t
*
)
vlc_custom_create
(
p_this
,
sizeof
(
media_library_t
),
"media-library"
);
if
(
!
p_ml
)
{
msg_Err
(
p_this
,
"unable to create media library object"
);
return
NULL
;
}
p_ml
->
p_module
=
module_need
(
p_ml
,
"media-library"
,
psz_name
,
false
);
if
(
!
p_ml
->
p_module
)
{
vlc_object_release
(
p_ml
);
msg_Err
(
p_this
,
"Media Library provider not found"
);
return
NULL
;
}
return
p_ml
;
}
#undef ml_Get
/**
* @brief Acquire a reference to the media library singleton
* @param p_this Object that holds the reference
* @return media_library_t The ml object. NULL if not compiled with
* media library or if unable to load
*/
media_library_t
*
ml_Get
(
vlc_object_t
*
p_this
)
{
media_library_t
*
p_ml
;
vlc_mutex_lock
(
&
(
libvlc_priv
(
p_this
->
p_libvlc
)
->
ml_lock
)
);
p_ml
=
libvlc_priv
(
p_this
->
p_libvlc
)
->
p_ml
;
assert
(
VLC_OBJECT
(
p_ml
)
!=
p_this
);
if
(
p_ml
==
NULL
&&
!
var_GetBool
(
p_this
->
p_libvlc
,
"load-media-library-on-startup"
)
)
{
libvlc_priv
(
p_this
->
p_libvlc
)
->
p_ml
=
ml_Create
(
VLC_OBJECT
(
p_this
->
p_libvlc
),
NULL
);
p_ml
=
libvlc_priv
(
p_this
->
p_libvlc
)
->
p_ml
;
}
vlc_mutex_unlock
(
&
(
libvlc_priv
(
p_this
->
p_libvlc
)
->
ml_lock
)
);
return
p_ml
;
}
/**
* @brief Destructor for ml_media_t
*/
static
void
media_Destroy
(
ml_gc_object_t
*
p_gc
)
{
ml_media_t
*
p_media
=
ml_priv
(
p_gc
,
ml_media_t
);
vlc_mutex_destroy
(
&
p_media
->
lock
);
ml_FreeMediaContent
(
p_media
);
free
(
p_media
);
}
/**
* @brief Object constructor for ml_media_t
* @param p_ml The media library object
* @param id If 0, this item isn't in database. If non zero, it is and
* it will be a singleton
* @param select Type of object
* @param reload Whether to reload from database
*/
ml_media_t
*
media_New
(
media_library_t
*
p_ml
,
int
id
,
ml_select_e
select
,
bool
reload
)
{
if
(
id
==
0
)
{
ml_media_t
*
p_media
=
NULL
;
p_media
=
(
ml_media_t
*
)
calloc
(
1
,
sizeof
(
ml_media_t
)
);
ml_gc_init
(
&
p_media
->
ml_gc_data
,
media_Destroy
);
vlc_mutex_init
(
&
p_media
->
lock
);
return
p_media
;
}
else
return
p_ml
->
functions
.
pf_GetMedia
(
p_ml
,
id
,
select
,
reload
);
}
#undef ml_UpdateSimple
/**
* @brief Update a given table
* @param p_media_library The media library object
* @param selected_type The table to update
* @param psz_lvalue The role of the person if selected_type = ML_PEOPLE
* @param id The id of the row to update
* @param ... The update data. [SelectType [RoleType] Value] ... ML_END
*/
int
ml_UpdateSimple
(
media_library_t
*
p_media_library
,
ml_select_e
selected_type
,
const
char
*
psz_lvalue
,
int
id
,
...
)
{
ml_element_t
*
update
;
vlc_array_t
*
array
=
vlc_array_new
();
int
i_ret
=
VLC_SUCCESS
;
va_list
args
;
va_start
(
args
,
id
);
ml_select_e
sel
;
do
{
update
=
(
ml_element_t
*
)
calloc
(
1
,
sizeof
(
ml_element_t
)
);
sel
=
(
ml_select_e
)
va_arg
(
args
,
int
);
update
->
criteria
=
sel
;
if
(
sel
==
ML_PEOPLE
)
{
update
->
lvalue
.
str
=
va_arg
(
args
,
char
*
);
update
->
value
.
str
=
va_arg
(
args
,
char
*
);
vlc_array_append
(
array
,
update
);
}
else
if
(
sel
==
ML_PEOPLE_ID
)
{
update
->
lvalue
.
str
=
va_arg
(
args
,
char
*
);
update
->
value
.
i
=
va_arg
(
args
,
int
);
vlc_array_append
(
array
,
update
);
}
else
if
(
sel
==
ML_PEOPLE_ROLE
)
{
#ifndef NDEBUG
msg_Dbg
(
p_media_library
,
"this argument is invalid for Update: %d"
,
(
int
)
sel
);
#endif
}
else
{
switch
(
ml_AttributeIsString
(
sel
)
)
{
case
-
1
:
if
(
sel
!=
ML_END
)
{
#ifndef NDEBUG
msg_Dbg
(
p_media_library
,
"this argument is invalid for Update: %d"
,
(
int
)
sel
);
#endif
i_ret
=
VLC_EBADVAR
;
}
else
if
(
sel
==
ML_END
)
vlc_array_append
(
array
,
update
);
break
;
case
1
:
update
->
value
.
str
=
va_arg
(
args
,
char
*
);
vlc_array_append
(
array
,
update
);
break
;
case
0
:
update
->
value
.
i
=
va_arg
(
args
,
int
);
vlc_array_append
(
array
,
update
);
break
;
}
}
}
while
(
sel
!=
ML_END
);
va_end
(
args
);
ml_ftree_t
*
p_where
=
NULL
;
ml_ftree_t
*
find
=
(
ml_ftree_t
*
)
calloc
(
1
,
sizeof
(
ml_ftree_t
)
);
find
->
criteria
=
ML_ID
;
find
->
value
.
i
=
id
;
find
->
comp
=
ML_COMP_EQUAL
;
p_where
=
ml_FtreeFastAnd
(
p_where
,
find
);
/* Let's update the database ! */
if
(
i_ret
==
VLC_SUCCESS
)
i_ret
=
ml_Update
(
p_media_library
,
selected_type
,
psz_lvalue
,
p_where
,
array
);
/* Destroying array */
for
(
int
i
=
0
;
i
<
vlc_array_count
(
array
);
i
++
)
{
free
(
vlc_array_item_at_index
(
array
,
i
)
);
}
vlc_array_destroy
(
array
);
ml_FreeFindTree
(
p_where
);
return
i_ret
;
}
/**
* @brief Connect up a find tree
* @param op operator to connect with
* If op = ML_OP_NONE, then you are connecting to a tree consisting of
* only SPECIAL nodes.
* If op = ML_OP_NOT, then right MUST be NULL
* op must not be ML_OP_SPECIAL, @see ml_FtreeSpec
* @param left part of the tree
* @param right part of the tree
* @return Pointer to new tree
* @note Use the helpers!
*/
ml_ftree_t
*
ml_OpConnectChilds
(
ml_op_e
op
,
ml_ftree_t
*
left
,
ml_ftree_t
*
right
)
{
/* Use this Op for fresh trees (with only special nodes/none at all!) */
if
(
op
==
ML_OP_NONE
)
{
assert
(
ml_FtreeHasOp
(
left
)
==
0
);
if
(
left
==
NULL
)
return
right
;
/* Percolate down tree only for special nodes */
assert
(
left
->
op
==
ML_OP_SPECIAL
);
if
(
left
->
left
==
NULL
)
{
left
->
left
=
right
;
return
left
;
}
else
{
return
ml_OpConnectChilds
(
ML_OP_NONE
,
left
->
left
,
right
);
}
}
else
if
(
op
==
ML_OP_NOT
)
{
assert
(
right
==
NULL
&&
left
!=
NULL
);
assert
(
ml_FtreeHasOp
(
left
)
>
0
);
}
else
if
(
op
==
ML_OP_SPECIAL
)
{
assert
(
0
);
}
else
{
assert
(
right
!=
NULL
&&
left
!=
NULL
);
assert
(
ml_FtreeHasOp
(
left
)
>
0
);
assert
(
ml_FtreeHasOp
(
right
)
>
0
);
}
ml_ftree_t
*
p_parent
=
(
ml_ftree_t
*
)
calloc
(
1
,
sizeof
(
ml_ftree_t
)
);
p_parent
->
op
=
op
;
p_parent
->
left
=
left
;
p_parent
->
right
=
right
;
return
p_parent
;
}
#undef ml_FtreeSpec
/**
* @brief Attaches a special node to a tree
* @param tree Tree to attach special node to
* @param crit Criteria may be SORT_ASC, SORT_DESC, LIMIT or DISTINCT
* @param limit Limit used if LIMIT criteria used
* @param Sort string used if SORT criteria is used
* @return Pointer to new tree
* @note Use the helpers
*/
ml_ftree_t
*
ml_FtreeSpec
(
ml_ftree_t
*
tree
,
ml_select_e
crit
,
int
limit
,
char
*
sort
)
{
assert
(
crit
==
ML_SORT_ASC
||
crit
==
ML_LIMIT
||
crit
==
ML_SORT_DESC
||
crit
==
ML_DISTINCT
);
ml_ftree_t
*
right
=
(
ml_ftree_t
*
)
calloc
(
1
,
sizeof
(
ml_ftree_t
)
);
right
->
criteria
=
crit
;
if
(
crit
==
ML_LIMIT
)
right
->
value
.
i
=
limit
;
else
if
(
crit
==
ML_SORT_ASC
||
crit
==
ML_SORT_DESC
)
right
->
value
.
str
=
strdup
(
sort
);
right
->
op
=
ML_OP_NONE
;
ml_ftree_t
*
p_parent
=
(
ml_ftree_t
*
)
calloc
(
1
,
sizeof
(
ml_ftree_t
)
);
p_parent
->
right
=
right
;
p_parent
->
op
=
ML_OP_SPECIAL
;
p_parent
->
left
=
tree
;
return
p_parent
;
}
/**
* @brief Returns a person list of given type
* @param p_ml The ML object
* @param p_media The Media object
* @param i_type The person type
* @note This function is thread safe
*/
ml_person_t
*
ml_GetPersonsFromMedia
(
media_library_t
*
p_ml
,
ml_media_t
*
p_media
,
const
char
*
psz_role
)
{
VLC_UNUSED
(
p_ml
);
assert
(
p_media
!=
NULL
);
ml_person_t
*
p_return
=
NULL
;
ml_LockMedia
(
p_media
);
ml_person_t
*
p_person
=
p_media
->
p_people
;
while
(
p_person
)
{
if
(
strcmp
(
p_person
->
psz_role
,
psz_role
)
==
0
)
{
int
i_ret
=
ml_CreateAppendPerson
(
&
p_return
,
p_person
);
if
(
i_ret
!=
VLC_SUCCESS
)
{
ml_UnlockMedia
(
p_media
);
ml_FreePeople
(
p_return
);
return
NULL
;
}
}
p_person
=
p_person
->
p_next
;
}
ml_UnlockMedia
(
p_media
);
//TODO: Fill up empty names + clean up list
return
p_return
;
}
/**
* @brief Delete a certain type of people from a media
* @param p_media Media to delete from
* @param i_type Type of person to delete
* @note This function is threadsafe
*/
void
ml_DeletePersonTypeFromMedia
(
ml_media_t
*
p_media
,
const
char
*
psz_role
)
{
assert
(
p_media
);
ml_LockMedia
(
p_media
);
ml_person_t
*
p_prev
=
NULL
;
ml_person_t
*
p_person
=
p_media
->
p_people
;
while
(
p_person
)
{
if
(
strcmp
(
p_person
->
psz_role
,
psz_role
)
==
0
)
{
if
(
p_prev
==
NULL
)
{
p_media
->
p_people
=
p_person
->
p_next
;
p_person
->
p_next
=
NULL
;
ml_FreePeople
(
p_person
);
p_person
=
p_media
->
p_people
;
}
else
{
p_prev
->
p_next
=
p_person
->
p_next
;
p_person
->
p_next
=
NULL
;
ml_FreePeople
(
p_person
);
p_person
=
p_prev
->
p_next
;
}
}
else
{
p_prev
=
p_person
;
p_person
=
p_person
->
p_next
;
}
}
ml_UnlockMedia
(
p_media
);
}
#endif
/* MEDIA_LIBRARY */
src/missing.c
View file @
628b01be
...
...
@@ -368,74 +368,3 @@ vlm_t *vlm_New (vlc_object_t *obj)
return
NULL
;
}
#endif
/* !ENABLE_VLM */
#ifndef MEDIA_LIBRARY
#include<vlc_media_library.h>
#undef ml_Get
media_library_t
*
ml_Get
(
vlc_object_t
*
p_this
)
{
VLC_UNUSED
(
p_this
);
return
NULL
;
}
ml_media_t
*
media_New
(
media_library_t
*
p_ml
,
int
id
,
ml_select_e
select
,
bool
reload
)
{
VLC_UNUSED
(
p_ml
);
VLC_UNUSED
(
id
);
VLC_UNUSED
(
select
);
VLC_UNUSED
(
reload
);
assert
(
0
);
return
NULL
;
}
#undef ml_UpdateSimple
int
ml_UpdateSimple
(
media_library_t
*
p_media_library
,
ml_select_e
selected_type
,
const
char
*
psz_lvalue
,
int
id
,
...
)
{
VLC_UNUSED
(
p_media_library
);
VLC_UNUSED
(
selected_type
);
VLC_UNUSED
(
psz_lvalue
);
VLC_UNUSED
(
id
);
assert
(
0
);
return
0
;
}
ml_ftree_t
*
ml_OpConnectChilds
(
ml_op_e
op
,
ml_ftree_t
*
left
,
ml_ftree_t
*
right
)
{
VLC_UNUSED
(
op
);
VLC_UNUSED
(
left
);
VLC_UNUSED
(
right
);
assert
(
0
);
return
NULL
;
}
ml_ftree_t
*
ml_FtreeSpec
(
ml_ftree_t
*
tree
,
ml_select_e
crit
,
int
limit
,
char
*
sort
)
{
VLC_UNUSED
(
tree
);
VLC_UNUSED
(
crit
);
VLC_UNUSED
(
limit
);
VLC_UNUSED
(
sort
);
assert
(
0
);
return
NULL
;
}
void
ml_DeletePersonTypeFromMedia
(
ml_media_t
*
p_media
,
const
char
*
psz_role
)
{
VLC_UNUSED
(
p_media
);
VLC_UNUSED
(
psz_role
);
assert
(
0
);
}
ml_person_t
*
ml_GetPersonsFromMedia
(
media_library_t
*
p_ml
,
ml_media_t
*
p_media
,
const
char
*
psz_role
)
{
VLC_UNUSED
(
p_ml
);
VLC_UNUSED
(
p_media
);
VLC_UNUSED
(
psz_role
);
assert
(
0
);
return
NULL
;
}
#endif
/* !MEDIA_LIBRARY */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment