home *** CD-ROM | disk | FTP | other *** search
/ mail.altrad.com / 2015.02.mail.altrad.com.tar / mail.altrad.com / TEST / vlc-2-0-5-win32.exe / sdk / include / vlc / plugins / vlc_media_library.h < prev    next >
C/C++ Source or Header  |  2012-12-12  |  48KB  |  1,273 lines

  1. /*****************************************************************************
  2.  * vlc_media_library.h: SQL-based media library
  3.  *****************************************************************************
  4.  * Copyright (C) 2008-2010 the VideoLAN Team and AUTHORS
  5.  * $Id: 2529dd51c1c6b95061828b21b3ea0d0daf81710b $
  6.  *
  7.  * Authors: Antoine Lejeune <phytos@videolan.org>
  8.  *          Jean-Philippe Andr├⌐ <jpeg@videolan.org>
  9.  *          R├⌐mi Duraffort <ivoire@videolan.org>
  10.  *          Adrien Maglo <magsoft@videolan.org>
  11.  *          Srikanth Raju <srikiraju at gmail dot com>
  12.  *
  13.  * This program is free software; you can redistribute it and/or modify it
  14.  * under the terms of the GNU Lesser General Public License as published by
  15.  * the Free Software Foundation; either version 2.1 of the License, or
  16.  * (at your option) any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21.  * GNU Lesser General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU Lesser General Public License
  24.  * along with this program; if not, write to the Free Software Foundation,
  25.  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  26.  *****************************************************************************/
  27.  
  28. #ifndef VLC_MEDIA_LIBRARY_H
  29. # define VLC_MEDIA_LIBRARY_H
  30.  
  31. # ifdef __cplusplus
  32. extern "C" {
  33. # endif
  34.  
  35. #include <vlc_common.h>
  36. #include <vlc_playlist.h>
  37.  
  38. /*****************************************************************************
  39.  * ML Enums
  40.  *****************************************************************************/
  41.  
  42. #define ML_PERSON_ARTIST        "Artist"
  43. #define ML_PERSON_ALBUM_ARTIST  "Album Artist"
  44. #define ML_PERSON_ENCODER       "Encoder"
  45. #define ML_PERSON_PUBLISHER     "Publisher"
  46.  
  47.  
  48. #define ml_priv( gc, t ) ((t *)(((char *)(gc)) - offsetof(t, ml_gc_data)))
  49.  
  50. /** List of Query select types.
  51.  * In a query array or variable argument list, each select type is followed
  52.  * by an argument (X) of variable type (char* or int, @see ml_element_t).
  53.  * These types can be used either in the query list or in the result array.
  54.  * Some types are reserved for the result array:
  55.  */
  56. typedef enum
  57. {
  58.     ML_ALBUM = 1,              /**< Album Title */
  59.     ML_ALBUM_ID,               /**< Album ID */
  60.     ML_ALBUM_COVER,            /**< Album Cover art url */
  61.     /* FIXME: Remove ML_ARTIST */
  62.     ML_ARTIST,                 /**< Artist, interpreted as ML_PEOPLE
  63.                                     && ML_PEOPLE_ROLE = ML_PERSON_ARTIST */
  64.     ML_ARTIST_ID,              /**< Artist ID, interpreted as ML_PEOPLE_ID
  65.                                     && ML_PEOPLE_ROLE = ML_PERSON_ARTIST */
  66.     ML_COMMENT,                /**< Comment about media */
  67.     ML_COUNT_MEDIA,            /**< Number of medias */
  68.     ML_COUNT_ALBUM,            /**< Number of albums */
  69.     ML_COUNT_PEOPLE,           /**< Number of people */
  70.     ML_COVER,                  /**< Cover art url */
  71.     ML_DURATION,               /**< Duration in ms */
  72.     ML_DISC_NUMBER,            /**< Disc number of the track */
  73.     ML_EXTRA,                  /**< Extra/comment (string) on the media */
  74.     ML_FIRST_PLAYED,           /**< First time media was played */
  75.     ML_FILESIZE,               /**< Size of the media file */
  76.     ML_GENRE,                  /**< Genre of the media (if any) */
  77.     ML_ID,                     /**< Media ID */
  78.     ML_IMPORT_TIME,            /**< Date when media was imported */
  79.     ML_LANGUAGE,               /**< Language */
  80.     ML_LAST_PLAYED,            /**< Last play UNIX timestamp */
  81.     ML_LAST_SKIPPED,           /**< Time when media was last skipped */
  82.     ML_ORIGINAL_TITLE,         /**< Media original title (if any) */
  83.     ML_PEOPLE,                 /**< Any People associated with this media */
  84.     ML_PEOPLE_ID,              /**< Id of a person */
  85.     ML_PEOPLE_ROLE,            /**< Person role */
  86.     ML_PLAYED_COUNT,           /**< Media play count */
  87.     ML_PREVIEW,                /**< Url of the video preview */
  88.     ML_SKIPPED_COUNT,          /**< Number of times skipped */
  89.     ML_SCORE,                  /**< Computed media score */
  90.     ML_TITLE,                  /**< Media title */
  91.     ML_TRACK_NUMBER,           /**< Media track number (if any) */
  92.     ML_TYPE,                   /**< Media type. @see ml_type_e */
  93.     ML_URI,                    /**< Media full URI. */
  94.     ML_VOTE,                   /**< Media user vote value */
  95.     ML_YEAR,                   /**< Media publishing year */
  96.     ML_DIRECTORY,              /**< Monitored directory */
  97.     ML_MEDIA,                  /**< Full media descriptor. @see ml_media_t */
  98.     ML_MEDIA_SPARSE,           /**< Sparse media. @see ml_media_t */
  99.     ML_MEDIA_EXTRA,            /**< Sparse + Extra = Full media */
  100.  
  101.     /* Some special elements */
  102.     ML_LIMIT     = -1,         /**< Limit a query to X results */
  103.     ML_SORT_DESC = -2,         /**< Sort a query descending on argument X */
  104.     ML_SORT_ASC  = -3,         /**< Sort a query ascending on argument X */
  105.     ML_DISTINCT  = -4,         /**< Add DISTINCT to SELECT statements. */
  106.     ML_END       = -42         /**< End of argument list */
  107. } ml_select_e;
  108.  
  109. /** Media types (audio, video, etc...) */
  110. typedef enum
  111. {
  112.     ML_UNKNOWN   = 0,       /**< Unknown media type */
  113.     ML_AUDIO     = 1 << 0,  /**< Audio only media */
  114.     ML_VIDEO     = 1 << 1,  /**< Video media. May contain audio channels */
  115.     ML_STREAM    = 1 << 2,  /**< Streamed media = not a local file */
  116.     ML_NODE      = 1 << 3,  /**< Nodes like simple nodes, directories, playlists, etc */
  117.     ML_REMOVABLE = 1 << 4,  /**< Removable media: CD/DVD/Card/... */
  118. } ml_type_e;
  119.  
  120. /** Query result item/list type: integers, strings, medias, timestamps */
  121. typedef enum {
  122.     ML_TYPE_INT,        /**< Object is an int */
  123.     ML_TYPE_PSZ,        /**< A string char* */
  124.     ML_TYPE_TIME,       /**< A timestamp mtime_t */
  125.     ML_TYPE_MEDIA,      /**< A pointer to a media ml_media_t* */
  126. } ml_result_type_e;
  127.  
  128. /** Arguments for VLC Control for the media library */
  129. typedef enum
  130. {
  131.     ML_SET_DATABASE,      /**< arg1 = char *psz_host
  132.                                arg2 = int i_port
  133.                                arg3 = char *psz_user
  134.                                arg4 = char *psz_pass */
  135.     ML_INIT_DATABASE,     /**< No arg */
  136.     ML_ADD_INPUT_ITEM,    /**< arg1 = input_item_t* */
  137.     ML_ADD_PLAYLIST_ITEM, /**< arg1 = playlist_item_t * */
  138.     ML_ADD_MONITORED,     /**< arg1 = char* */
  139.     ML_DEL_MONITORED,     /**< arg1 = char* */
  140.     ML_GET_MONITORED,     /**< arg1 = vlc_array_t* */
  141. } ml_control_e;
  142.  
  143. /* Operations that can be specified between find conditions */
  144. typedef enum
  145. {
  146.     ML_OP_NONE = 0,       /**< This is to specify an actual condition */
  147.     ML_OP_AND,            /**< AND condition */
  148.     ML_OP_OR,             /**< OR condition */
  149.     ML_OP_NOT,            /**< NOT condition */
  150.     ML_OP_SPECIAL         /**< This is for inclusion of
  151.                             *  special stuffs like LIMIT */
  152. } ml_op_e;
  153.  
  154. /* Comparison operators used in a single find condition */
  155. typedef enum
  156. {
  157.     ML_COMP_NONE = 0,
  158.     ML_COMP_LESSER,              ///< <
  159.     ML_COMP_LESSER_OR_EQUAL,     ///< <=
  160.     ML_COMP_EQUAL,               ///< ==
  161.     ML_COMP_GREATER_OR_EQUAL,    ///< >=
  162.     ML_COMP_GREATER,             ///< >
  163.     ML_COMP_HAS,                 ///< "Contains", equivalent to SQL "LIKE %x%"
  164.     ML_COMP_STARTS_WITH,         ///< Equivalent to SQL "LIKE %x"
  165.     ML_COMP_ENDS_WITH,           ///< Equivalent to SQL "LIKE x%"
  166. } ml_comp_e;
  167.  
  168. /*****************************************************************************
  169.  * ML Structures and types
  170.  *****************************************************************************/
  171.  
  172. typedef struct media_library_t media_library_t;
  173. typedef struct media_library_sys_t media_library_sys_t;
  174.  
  175. typedef struct ml_media_t      ml_media_t;
  176. typedef struct ml_result_t     ml_result_t;
  177. typedef struct ml_element_t    ml_element_t;
  178. typedef struct ml_person_t     ml_person_t;
  179. typedef struct ml_ftree_t      ml_ftree_t;
  180.  
  181.  
  182. typedef struct ml_gc_object_t
  183. {
  184.     vlc_spinlock_t spin;
  185.     bool           pool;
  186.     uintptr_t      refs;
  187.     void          (*pf_destructor) (struct ml_gc_object_t *);
  188. } ml_gc_object_t;
  189.  
  190. #define ML_GC_MEMBERS ml_gc_object_t ml_gc_data;
  191.  
  192. /** Main structure of the media library. VLC object. */
  193. struct media_library_t
  194. {
  195.     VLC_COMMON_MEMBERS
  196.  
  197.     module_t             *p_module;  /**< the media library module */
  198.     media_library_sys_t  *p_sys;     /**< internal struture */
  199.  
  200.     /** Member functions */
  201.     struct
  202.     {
  203.         /**< Search in the database */
  204.         int ( * pf_Find )            ( media_library_t *p_media_library,
  205.                                        vlc_array_t *p_result_array,
  206.                                        va_list args );
  207.  
  208.         /**< Search in the database using an array of arguments */
  209.         int ( * pf_FindAdv )         ( media_library_t *p_media_library,
  210.                                        vlc_array_t *p_result_array,
  211.                                        ml_select_e selected_type,
  212.                                        const char *psz_lvalue,
  213.                                        ml_ftree_t *tree );
  214.  
  215.         /**< Update the database using an array of arguments */
  216.         int ( * pf_Update )          ( media_library_t *p_media_library,
  217.                                        ml_select_e selected_type,
  218.                                        const char *psz_lvalue,
  219.                                        ml_ftree_t *where,
  220.                                        vlc_array_t *changes );
  221.  
  222.         /**< Delete many medias in the database */
  223.         int ( * pf_Delete )    ( media_library_t *p_media_library,
  224.                                        vlc_array_t *p_array );
  225.  
  226.         /**< Control the media library */
  227.         int ( * pf_Control ) ( media_library_t *p_media_library,
  228.                                int i_query, va_list args );
  229.  
  230.         /**< Create associated input item */
  231.         input_item_t* ( * pf_InputItemFromMedia ) (
  232.                     media_library_t *p_media_library, int i_media );
  233.  
  234.         /**< Get a media */
  235.         ml_media_t* ( * pf_GetMedia ) (
  236.                     media_library_t *p_media_library, int i_media,
  237.                     ml_select_e select, bool reload );
  238.     } functions;
  239. };
  240.  
  241.  
  242. /**
  243.  * @brief Structure to describe a media
  244.  *
  245.  * This is the main structure holding the meta data in ML.
  246.  * @see b_sparse indicates whether the media struct has valid values
  247.  * in its Extra fields. Otherwise, it must be loaded with the API
  248.  * function.
  249.  * @see i_id indicates whether this struct is saved in the ML if i_id > 0
  250.  * Otherwise, it can be added to the database
  251.  */
  252. struct ml_media_t
  253. {
  254.     ML_GC_MEMBERS
  255.     vlc_mutex_t     lock;               /**< Mutex for multithreaded access */
  256.     bool            b_sparse;           /**< Specifies if media is loaded fully */
  257.     ml_type_e       i_type;             /**< Type of the media (ml_type_e) */
  258.     int8_t          i_vote;             /**< User vote */
  259.     int16_t         i_disc_number;      /**< Disc number of media */
  260.     int16_t         i_track_number;     /**< Track number */
  261.     int16_t         i_year;             /**< Year of release */
  262.     int32_t         i_id;               /**< Media ID in the database */
  263.     int32_t         i_score;            /**< Score computed about the media */
  264.     int32_t         i_album_id;         /**< Album id */
  265.     int32_t         i_played_count;     /**< How many time the media was played */
  266.     int32_t         i_skipped_count;    /**< No. of times file was skipped */
  267.     int32_t         i_bitrate;          /**< Extra: Bitrate of the media */
  268.     int32_t         i_samplerate;       /**< Extra: Samplerate of the media */
  269.     int32_t         i_bpm;              /**< Extra: Beats per minute */
  270.     char            *psz_uri;           /**< URI to find the media */
  271.     char            *psz_title;         /**< Title of the media */
  272.     char            *psz_orig_title;    /**< Original title (mainly for movies) */
  273.     char            *psz_album;         /**< Name of the album */
  274.     char            *psz_cover;         /**< URI of the cover */
  275.     char            *psz_genre;         /**< Genre of the media */
  276.     char            *psz_preview;       /**< Preview thumbnail for video, if any */
  277.     char            *psz_comment;       /**< Comment or description about media */
  278.     char            *psz_language;      /**< Extra: Language */
  279.     char            *psz_extra;         /**< Extra: Some extra datas like lyrics */
  280.     ml_person_t     *p_people;          /**< Extra: People associated with this
  281.                                              media This meta holds only one
  282.                                              artist if b_sparse = true */
  283.     int64_t         i_filesize;         /**< Size of the file */
  284.     mtime_t         i_duration;         /**< Duration in microseconds */
  285.     mtime_t         i_last_played;      /**< Time when the media was last played */
  286.     mtime_t         i_last_skipped;     /**< Time when the media was last skipped */
  287.     mtime_t         i_first_played;     /**< First played */
  288.     mtime_t         i_import_time;      /**< Time when media was added */
  289.  
  290. };
  291.  
  292.  
  293. /**
  294.  * @brief Main communication struct between GUI and sql_media_library.
  295.  * Generic representation of an ML/SQL query result.
  296.  */
  297. struct ml_result_t
  298. {
  299.     int32_t          id;        /**< Media/Album/Artist... ID (if any) */
  300.     ml_result_type_e type;      /**< Type of value */
  301.     union
  302.     {
  303.         /* Classical results */
  304.         int             i;
  305.         char           *psz;
  306.         mtime_t         time;
  307.  
  308.         /* Complex result: media descriptor */
  309.         ml_media_t     *p_media;
  310.     } value;                    /**< Value of the result obtained */
  311. };
  312.  
  313.  
  314. /**
  315.  * @brief Element of a query: criteria type/value pair
  316.  * Used for update and delete queries
  317.  */
  318. struct ml_element_t
  319. {
  320.     ml_select_e    criteria;    /**< SELECT criteria type. @see ml_select_e */
  321.     union
  322.     {
  323.         int     i;
  324.         char*   str;
  325.     } value;                    /**< SELECT criteria value (string or int) */
  326.     union
  327.     {
  328.         int     i;
  329.         char*   str;
  330.     } lvalue;                   /**< Refer to @see ml_ftree_t lvalue docs */
  331. };
  332.  
  333. /**
  334.  * Binary tree used to parse the WHERE condition for a search
  335.  *
  336.  * Let [expr] indicate a valid expression
  337.  * [expr] = [expr] AND [expr], where the left and right are respective
  338.  * [expr] = [expr] OR [expr]
  339.  * [expr] = [expr] NOT [NULL]
  340.  * [expr] = [expr] SPEC [spec_expr]
  341.  * [expr] = [criteria=val]
  342.  * [spec_expr] = [DISTINCT/LIMIT/ASC/DESC = val ]
  343.  */
  344. struct ml_ftree_t
  345. {
  346.     ml_op_e         op;         /**< Operator. ML_OP_NONE means this is a leaf
  347.                                   *  node. Criteria and value gives its data.
  348.                                   *  ML_OP_SPECIAL specifies a special node
  349.                                   *  that does not form a part of the WHERE.
  350.                                   *  The right node consists of the data
  351.                                   *  with its criteria set to the special val
  352.                                   *  and the left node is the corresponding
  353.                                   *  subtree of the parent node.
  354.                                   *  ML_OP_NOT only left sub tree is considered
  355.                                   *  ML_OP_AND and ML_OP_OR consider both
  356.                                   *  left and right subtrees */
  357.     ml_ftree_t      *left;      /**< Left child of Bin tree */
  358.     ml_ftree_t      *right;     /**< Right child of Bin tree */
  359.     ml_select_e     criteria;   /**< SELECT criteria type @see ml_select_e
  360.                                   *  The criteria value is considered only when
  361.                                   *  op = ML_OP_NONE i.e. in leaf nodes */
  362.     ml_comp_e       comp;       /**< Condition between type and value */
  363.     union
  364.     {
  365.         int     i;
  366.         char    *str;
  367.     } value;                    /**< SELECT criteria value ( string or int ) */
  368.     union
  369.     {
  370.         int     i;
  371.         char    *str;
  372.     } lvalue;                   /**< Used as key value for people types/roles.
  373.                                      An empty string "" denotes ANY person role.
  374.                                      NULL is used for all other criterias */
  375. };
  376.  
  377.  
  378. /**
  379.  * Person class. Implemented as a linked list
  380.  */
  381. struct ml_person_t
  382. {
  383.     char               *psz_role;   /**< Type of person */
  384.     char               *psz_name;   /**< Name of the person */
  385.     int                 i_id;       /**< ID in the database */
  386.     ml_person_t        *p_next;     /**< Next person in list */
  387. };
  388.  
  389.  
  390. /*****************************************************************************
  391.  * ML Function headers
  392.  *****************************************************************************/
  393.  
  394. /**
  395.  * @brief Acquire a reference to the media library singleton
  396.  * @param p_this The object holding the media library
  397.  * @return The media library object. NULL if the media library
  398.  * object could not be loaded
  399.  */
  400. VLC_API media_library_t* ml_Get( vlc_object_t* p_this );
  401. #define ml_Get( a ) ml_Get( VLC_OBJECT(a) )
  402.  
  403. /**
  404.  * @brief Create a Media Library VLC object.
  405.  * @param p_this Parent to attach the ML object to.
  406.  * @param psz_name Name for the module
  407.  * @return The ML object.
  408.  */
  409. VLC_API media_library_t* ml_Create( vlc_object_t *p_this, char* psz_name );
  410.  
  411. /**
  412.  * @brief Destructor for the Media library singleton
  413.  * @param p_this Parent the ML object is attached to
  414.  */
  415. VLC_API void ml_Destroy( vlc_object_t* p_this );
  416.  
  417. /**
  418.  * @brief Control the Media Library
  419.  * @param p_media_library the media library object
  420.  * @param i_type one of ml_control_e values @see ml_control_e.
  421.  * @param ... optional arguments.
  422.  * @return VLC_SUCCESS or an error
  423.  */
  424. static inline int ml_ControlVa( media_library_t *p_media_library,
  425.                                 ml_control_e i_type, va_list args )
  426. {
  427.     return p_media_library->functions.pf_Control( p_media_library,
  428.                                                   i_type,
  429.                                                   args );
  430. }
  431.  
  432. /**
  433.  * @brief Control the Media Library
  434.  * @param i_type one of ml_control_e values @see ml_control_e.
  435.  * Variable arguments list equivalent
  436.  */
  437. #define ml_Control( a, b, args... )     __ml_Control( a, b, ## args )
  438. static inline int __ml_Control( media_library_t *p_media_library,
  439.                                 ml_control_e i_type, ... )
  440. {
  441.     va_list args;
  442.     int returned;
  443.  
  444.     va_start( args, i_type );
  445.     returned = ml_ControlVa( p_media_library, i_type, args );
  446.     va_end( args );
  447.  
  448.     return returned;
  449. }
  450.  
  451. /**
  452.  * @brief Determine an attribute's type (int or string)
  453.  * @param meta Attribute to test @see ml_select_e
  454.  * @return -1 if invalid, 0 if this is an integer, 1 if this is a string
  455.  */
  456. static inline int ml_AttributeIsString( ml_select_e meta )
  457. {
  458.     switch( meta )
  459.     {
  460.     /* Strings */
  461.     case ML_ALBUM:
  462.     case ML_ARTIST:
  463.     case ML_COMMENT:
  464.     case ML_COVER:
  465.     case ML_EXTRA:
  466.     case ML_GENRE:
  467.     case ML_LANGUAGE:
  468.     case ML_PREVIEW:
  469.     case ML_PEOPLE:
  470.     case ML_PEOPLE_ROLE:
  471.     case ML_ORIGINAL_TITLE:
  472.     case ML_TITLE:
  473.     case ML_URI:
  474.         return 1;
  475.  
  476.     /* Integers */
  477.     case ML_ALBUM_ID:
  478.     case ML_ARTIST_ID:
  479.     case ML_DURATION:
  480.     case ML_DISC_NUMBER:
  481.     case ML_COUNT_MEDIA:
  482.     case ML_COUNT_ALBUM:
  483.     case ML_COUNT_PEOPLE:
  484.     case ML_FILESIZE:
  485.     case ML_FIRST_PLAYED:
  486.     case ML_ID:
  487.     case ML_IMPORT_TIME:
  488.     case ML_LAST_PLAYED:
  489.     case ML_LIMIT:
  490.     case ML_PLAYED_COUNT:
  491.     case ML_PEOPLE_ID:
  492.     case ML_SCORE:
  493.     case ML_SKIPPED_COUNT:
  494.     case ML_TRACK_NUMBER:
  495.     case ML_TYPE:
  496.     case ML_VOTE:
  497.     case ML_YEAR:
  498.         return 0;
  499.  
  500.     /* Invalid or no following value (in a SELECT statement) */
  501.     default:
  502.         return -1;
  503.     }
  504. }
  505.  
  506. /* Reference Counting Functions */
  507. /**
  508.  * @brief Increment reference count of media
  509.  * @param p_media The media object
  510.  */
  511. static inline void ml_gc_incref( ml_media_t* p_media )
  512. {
  513.     ml_gc_object_t* p_gc = &p_media->ml_gc_data;
  514.     if( p_gc == NULL )
  515.         return;
  516.  
  517.     vlc_spin_lock (&p_gc->spin);
  518.     ++p_gc->refs;
  519.     vlc_spin_unlock (&p_gc->spin);
  520. }
  521.  
  522. /**
  523.  * @brief Decrease reference count of media
  524.  * @param p_media The media object
  525.  */
  526. static inline void ml_gc_decref( ml_media_t* p_media )
  527. {
  528.     /* The below code is from vlc_release(). */
  529.     unsigned refs;
  530.     bool pool;
  531.     ml_gc_object_t* p_gc = &p_media->ml_gc_data;
  532.     if( p_gc == NULL )
  533.         return;
  534.  
  535.     vlc_spin_lock (&p_gc->spin);
  536.     refs = --p_gc->refs;
  537.     pool = p_gc->pool;
  538.     vlc_spin_unlock (&p_gc->spin);
  539.  
  540.     if( refs == 0 && !pool )
  541.     {
  542.         vlc_spin_destroy (&p_gc->spin);
  543.         p_gc->pf_destructor (p_gc);
  544.     }
  545. }
  546.  
  547. /*****************************************************************************
  548.  * ML Free Functions
  549.  *****************************************************************************/
  550.  
  551. /**
  552.  * @brief Free a person object
  553.  * @param p_media Person object to free
  554.  * @note This function is NOT threadsafe
  555.  */
  556. static inline void ml_FreePeople( ml_person_t *p_person )
  557. {
  558.     if( p_person == NULL )
  559.         return;
  560.     ml_FreePeople( p_person->p_next );
  561.     free( p_person->psz_name );
  562.     free( p_person->psz_role );
  563.     free( p_person );
  564. }
  565.  
  566. /**
  567.  * @brief Free only the content of a media. @see ml_media_t
  568.  * @param p_media Media object
  569.  * @note This function is NOT threadsafe.
  570.  */
  571. static inline void ml_FreeMediaContent( ml_media_t *p_media )
  572. {
  573.     free( p_media->psz_uri );
  574.     free( p_media->psz_title );
  575.     free( p_media->psz_orig_title );
  576.     free( p_media->psz_cover );
  577.     free( p_media->psz_comment );
  578.     free( p_media->psz_extra );
  579.     free( p_media->psz_genre );
  580.     free( p_media->psz_album );
  581.     free( p_media->psz_preview );
  582.     free( p_media->psz_language );
  583.     ml_FreePeople( p_media->p_people );
  584.     p_media->b_sparse = true;
  585.     p_media->i_id = 0;
  586.     p_media->i_type = ML_UNKNOWN;
  587.     p_media->i_album_id = 0;
  588.     p_media->i_disc_number = 0;
  589.     p_media->i_track_number = 0;
  590.     p_media->i_year = 0;
  591.     p_media->i_vote = 0;
  592.     p_media->i_score = 0;
  593.     p_media->i_filesize = 0;
  594.     p_media->i_duration = 0;
  595.     p_media->i_played_count = 0;
  596.     p_media->i_last_played = 0;
  597.     p_media->i_skipped_count = 0;
  598.     p_media->i_last_skipped = 0;
  599.     p_media->i_first_played = 0;
  600.     p_media->i_import_time = 0;
  601.     p_media->i_bitrate = 0;
  602.     p_media->i_samplerate = 0;
  603.     p_media->i_bpm = 0;
  604. }
  605.  
  606. /**
  607.  * @brief Free a result item. @see ml_result_t
  608.  * @param p_result Result item to free
  609.  * @note This will free any strings and decref medias.
  610.  */
  611. static inline void ml_FreeResult( ml_result_t *p_result )
  612. {
  613.     if( p_result )
  614.     {
  615.         switch( p_result->type )
  616.         {
  617.             case ML_TYPE_PSZ:
  618.                 free( p_result->value.psz );
  619.                 break;
  620.             case ML_TYPE_MEDIA:
  621.                 ml_gc_decref( p_result->value.p_media );
  622.                 break;
  623.             default:
  624.                 break;
  625.         }
  626.         free( p_result );
  627.     }
  628. }
  629.  
  630.  
  631. /**
  632.  * @brief Free a ml_element_t item.
  633.  * @param p_find Find object to free
  634.  * @see ml_element_t */
  635. static inline void ml_FreeElement( ml_element_t *p_elt )
  636. {
  637.     if( p_elt )
  638.     {
  639.         if( ml_AttributeIsString( p_elt->criteria ) )
  640.         {
  641.             free( p_elt->value.str );
  642.         }
  643.         if( p_elt->criteria == ML_PEOPLE )
  644.         {
  645.             free( p_elt->lvalue.str );
  646.         }
  647.         free( p_elt );
  648.     }
  649. }
  650.  
  651.  
  652. /**
  653.  * @brief Destroy a vlc_array_t of ml_result_t
  654.  * @param ml_result_array The result array to free
  655.  * @note Frees all results and contents of the results
  656.  */
  657. static inline void ml_DestroyResultArray( vlc_array_t *p_result_array )
  658. {
  659.     for( int i = 0; i < vlc_array_count( p_result_array ); i++ )
  660.     {
  661.         ml_FreeResult( ( ml_result_t* ) vlc_array_item_at_index(
  662.                 p_result_array, i ) );
  663.     }
  664. }
  665.  
  666.  
  667.  
  668. /*****************************************************************************
  669.  * ML Object Management Functions
  670.  *****************************************************************************/
  671.  
  672. /** Helpers for locking and unlocking */
  673. #define ml_LockMedia( a )      vlc_mutex_lock( &a->lock )
  674. #define ml_UnlockMedia( a )    vlc_mutex_unlock( &a->lock )
  675.  
  676. /**
  677.  * @brief Object constructor for ml_media_t
  678.  * @param p_ml The media library object
  679.  * @param id If 0, this item isn't in database. If non zero, it is and
  680.  * it will be a singleton
  681.  * @param select Type of object
  682.  * @param reload Whether to reload from database
  683.  */
  684. VLC_API ml_media_t *media_New( media_library_t* p_ml, int id,
  685.         ml_select_e select, bool reload );
  686.  
  687.  
  688. /* Forward declaration */
  689. static inline int ml_CopyPersons( ml_person_t** a, ml_person_t* b );
  690.  
  691. /**
  692.  * @brief Copy all members of a ml_media_t to another.
  693.  * @param b Destination media, already allocated
  694.  * @param a Source media, cannot be NULL, const
  695.  * @note This does not check memory allocation (for strdup). It is threadsafe
  696.  * @todo Free b content, before inserting a?
  697.  */
  698. static inline int ml_CopyMedia( ml_media_t *b, ml_media_t *a )
  699. {
  700.     if( !a || !b ) return VLC_EGENERIC;
  701.     if( a == b ) return VLC_SUCCESS;
  702.     ml_LockMedia( a );
  703.     ml_LockMedia( b );
  704.     b->b_sparse = a->b_sparse;
  705.     b->i_id = a->i_id;
  706.     b->i_type = a->i_type;
  707.     b->i_album_id = a->i_album_id;
  708.     b->i_disc_number = a->i_disc_number;
  709.     b->i_track_number = a->i_track_number;
  710.     b->i_year = a->i_year;
  711.     b->i_vote = a->i_vote;
  712.     b->i_score = a->i_score;
  713.     b->i_filesize = a->i_filesize;
  714.     b->i_duration = a->i_duration;
  715.     b->i_played_count = a->i_played_count;
  716.     b->i_last_played = a->i_last_played;
  717.     b->i_skipped_count = a->i_skipped_count;
  718.     b->i_last_skipped = a->i_last_skipped;
  719.     b->i_first_played = a->i_first_played;
  720.     b->i_import_time = a->i_import_time;
  721.     b->i_bitrate = a->i_bitrate;
  722.     b->i_samplerate = a->i_samplerate;
  723.     b->i_bpm = a->i_bpm;
  724.     free( b->psz_uri );
  725.     if( a->psz_uri )
  726.         b->psz_uri = strdup( a->psz_uri );
  727.     free( b->psz_title );
  728.     if( a->psz_title )
  729.         b->psz_title = strdup( a->psz_title );
  730.     free( b->psz_orig_title );
  731.     if( a->psz_orig_title )
  732.         b->psz_orig_title = strdup( a->psz_orig_title );
  733.     free( b->psz_album );
  734.     if( a->psz_album )
  735.         b->psz_album = strdup( a->psz_album );
  736.     free( b->psz_cover );
  737.     if( a->psz_cover )
  738.         b->psz_cover = strdup( a->psz_cover );
  739.     free( b->psz_genre );
  740.     if( a->psz_genre )
  741.         b->psz_genre = strdup( a->psz_genre );
  742.     free( b->psz_comment );
  743.     if( a->psz_comment )
  744.         b->psz_comment = strdup( a->psz_comment );
  745.     free( b->psz_extra );
  746.     if( a->psz_extra )
  747.         b->psz_extra = strdup( a->psz_extra );
  748.     free( b->psz_preview );
  749.     if( a->psz_preview )
  750.         b->psz_preview = strdup( a->psz_preview );
  751.     free( b->psz_language );
  752.     if( a->psz_language )
  753.         b->psz_language = strdup( a->psz_language );
  754.     ml_FreePeople( b->p_people );
  755.     if( a->p_people )        ml_CopyPersons( &( b->p_people ), a->p_people );
  756.     ml_UnlockMedia( b );
  757.     ml_UnlockMedia( a );
  758.     return VLC_SUCCESS;
  759. }
  760.  
  761. /*****************************************************************************
  762.  * ML Find Tree Related Functions
  763.  *****************************************************************************/
  764. #define ml_FreeFindTree( tree )          ml_GenericFreeFindTree( tree, true )
  765. #define ml_ShallowFreeFindTree( tree )   ml_GenericFreeFindTree( tree, false )
  766. /**
  767.  * @brief Free a find tree
  768.  * @param Find tree to free
  769.  * @param true to free any associated strings, false to not free them
  770.  */
  771. static inline void ml_GenericFreeFindTree( ml_ftree_t* tree, bool freestrings )
  772. {
  773.     if( tree == NULL )
  774.         return;
  775.     if( tree->left )
  776.     {
  777.         ml_GenericFreeFindTree( tree->left, freestrings );
  778.         free( tree->left );
  779.     }
  780.     if( tree->right )
  781.     {
  782.         ml_GenericFreeFindTree( tree->right, freestrings );
  783.         free( tree->right );
  784.     }
  785.     if( tree->op == ML_OP_NONE && ml_AttributeIsString( tree->criteria )
  786.             && freestrings)
  787.     {
  788.         free( tree->value.str );
  789.         if( tree->criteria == ML_PEOPLE )
  790.             free( tree->lvalue.str );
  791.     }
  792. }
  793.  
  794. /**
  795.  * @brief Checks if a given find tree has leaf nodes
  796.  * @param Find tree
  797.  * @return Number of leaf nodes
  798.  */
  799. static inline int ml_FtreeHasOp( ml_ftree_t* tree )
  800. {
  801.     if( tree == NULL )
  802.         return 0;
  803.     if( tree->criteria > 0 && tree->op == ML_OP_NONE )
  804.         return 1;
  805.     else
  806.         return ml_FtreeHasOp( tree->left ) + ml_FtreeHasOp( tree->right );
  807. }
  808.  
  809.  
  810. /**
  811.  * @brief Connect up a find tree
  812.  * @param op operator to connect with
  813.  * If op = ML_OP_NONE, then you are connecting to a tree consisting of
  814.  * only SPECIAL nodes.
  815.  * If op = ML_OP_NOT, then right MUST be NULL
  816.  * op must not be ML_OP_SPECIAL, @see ml_FtreeSpec
  817.  * @param left part of the tree
  818.  * @param right part of the tree
  819.  * @return Pointer to new tree
  820.  * @note Use the helpers!
  821.  */
  822. VLC_API ml_ftree_t *ml_OpConnectChilds( ml_op_e op, ml_ftree_t* left,
  823.         ml_ftree_t* right );
  824.  
  825. /**
  826.  * @brief Attaches a special node to a tree
  827.  * @param tree Tree to attach special node to
  828.  * @param crit Criteria may be SORT_ASC, SORT_DESC, LIMIT or DISTINCT
  829.  * @param limit Limit used if LIMIT criteria used
  830.  * @param Sort string used if SORT criteria is used
  831.  * @return Pointer to new tree
  832.  * @note Use the helpers
  833.  */
  834. VLC_API ml_ftree_t *ml_FtreeSpec( ml_ftree_t* tree,
  835.                                           ml_select_e crit,
  836.                                           int limit,
  837.                                           char* sort );
  838.  
  839. /**
  840.  * @brief This function gives quick sequential adding capability
  841.  * @param left Tree to add to. This may be NULL
  842.  * @param right Tree to append. May not be NULL
  843.  * @return Pointer to new tree.*/
  844. static inline ml_ftree_t* ml_FtreeFastAnd( ml_ftree_t* left,
  845.                                            ml_ftree_t* right )
  846. {
  847.     if( ml_FtreeHasOp( left ) == 0 )
  848.     {
  849.         return ml_OpConnectChilds( ML_OP_NONE, left, right );
  850.     }
  851.     else
  852.     {
  853.         return ml_OpConnectChilds( ML_OP_AND, left, right );
  854.     }
  855. }
  856. #define ml_FtreeAnd( left, right ) ml_OpConnectChilds( ML_OP_AND, left, right )
  857. #define ml_FtreeOr( left, right )  ml_OpConnectChilds( ML_OP_OR, left, right )
  858. #define ml_FtreeNot( left )        ml_OpConnectChilds( ML_OP_NOT, left, NULL )
  859.  
  860. #define ml_FtreeSpecAsc( tree, str )        ml_FtreeSpec( tree, ML_SORT_ASC, 0, str )
  861. #define ml_FtreeSpecDesc( tree, str )       ml_FtreeSpec( tree, ML_SORT_DESC, 0, str )
  862. #define ml_FtreeSpecLimit( tree, limit )    ml_FtreeSpec( tree, ML_LIMIT, limit, NULL )
  863. #define ml_FtreeSpecDistinct( tree )        ml_FtreeSpec( tree, ML_DISTINCT, 0, NULL )
  864.  
  865.  
  866. /*****************************************************************************
  867.  * ML Core Functions
  868.  *****************************************************************************/
  869.  
  870. /**
  871.  * @brief Create input item from media
  872.  * @param p_media_library This ML instance.
  873.  * @param i_media_id ID of the media to use to create an input_item.
  874.  * @return The media item.
  875.  */
  876. static inline input_item_t* ml_CreateInputItem(
  877.         media_library_t *p_media_library, int i_media_id )
  878. {
  879.     return p_media_library->functions.pf_InputItemFromMedia( p_media_library,
  880.                                                              i_media_id );
  881. }
  882.  
  883. /**
  884.  * @brief Search in the database according some criterias
  885.  *
  886.  * @param p_media_library the media library object
  887.  * @param result a pointer to a result array
  888.  * @param ... parameters to select the data
  889.  * @return VLC_SUCCESS or an error
  890.  */
  891. static inline int __ml_Find( media_library_t *p_media_library,
  892.                              vlc_array_t *p_result_array, ... )
  893. {
  894.     va_list args;
  895.     int returned;
  896.  
  897.     va_start( args, p_result_array );
  898.     returned = p_media_library->functions.pf_Find( p_media_library,
  899.                                                    p_result_array, args );
  900.     va_end( args );
  901.  
  902.     return returned;
  903. }
  904.  
  905.  
  906. /**
  907.  * @brief Search in the database according some criterias (threaded)
  908.  * @param p_media_library the media library object
  909.  * @param result_array a pointer to a result array
  910.  * @param result_type type of data to retrieve
  911.  * @param psz_lvalue This should contain any necessary lvalue/key
  912.  * for the given result_type. Used for ML_PEOPLE. Otherwise NULL
  913.  * @param args parameters to select the data
  914.  * @return VLC_SUCCESS or an error
  915.  */
  916. static inline int ml_FindAdv( media_library_t *p_media_library,
  917.                               vlc_array_t *p_result_array,
  918.                               ml_select_e result_type,
  919.                               char* psz_lvalue,
  920.                               ml_ftree_t *tree )
  921. {
  922.     return p_media_library->functions.pf_FindAdv( p_media_library,
  923.                                                   p_result_array,
  924.                                                   result_type,
  925.                                                   psz_lvalue,
  926.                                                   tree );
  927. }
  928.  
  929.  
  930. /**
  931.  * @brief Find a value in the ML database, fill p_result with it.
  932.  * @param p_media_library Media library object
  933.  * @param p_result Object to put result into
  934.  * @param Args [ SelectType [ PersonType ] Value ] ... ML_END
  935.  * @note Do not use this function directly.
  936.  */
  937. static inline int __ml_GetValue( media_library_t *p_media_library,
  938.                                   ml_result_t *p_result,
  939.                                   va_list args )
  940. {
  941.     vlc_array_t *p_result_array = vlc_array_new();
  942.     int i_ret = p_media_library->functions.pf_Find( p_media_library,
  943.                                                     p_result_array,
  944.                                                     args );
  945.     if( i_ret != VLC_SUCCESS )
  946.         goto exit;
  947.     if( vlc_array_count( p_result_array ) > 0 )
  948.         memcpy( p_result,
  949.                 ( ml_result_t* ) vlc_array_item_at_index( p_result_array, 0 ),
  950.                 sizeof( ml_result_t) );
  951.     else
  952.         i_ret = VLC_EGENERIC;
  953.  
  954. exit:
  955.     /* Note: Do not free the results, because of memcpy */
  956.     vlc_array_destroy( p_result_array );
  957.     return i_ret;
  958. }
  959.  
  960. /**
  961.  * @brief Search an INTEGER in the database
  962.  * This uses a Query but returns only one integer (>0), or an error code.
  963.  *
  964.  * @param p_media_library the media library object
  965.  * @param va_args parameters to select the data
  966.  * @return Found INTEGER >= 0 or an error
  967.  */
  968. #define ml_GetInt( ml, ... ) __ml_GetInt( ml, __VA_ARGS__, ML_LIMIT, 1, ML_END )
  969. static inline int __ml_GetInt( media_library_t *p_media_library, ... )
  970. {
  971.     va_list args;
  972.     va_start( args, p_media_library );
  973.     ml_result_t result;
  974.     int i_ret = __ml_GetValue( p_media_library, &result, args );
  975.     va_end( args );
  976.     if( i_ret != VLC_SUCCESS )
  977.         return i_ret;
  978.     else
  979.         return result.value.i;
  980. }
  981.  
  982.  
  983. /**
  984.  * @brief Search a string (VARCHAR) in the database
  985.  * This uses a Query but returns only one integer (>0), or an error code.
  986.  *
  987.  * @param p_media_library the media library object
  988.  * @param va_args parameters to select the data
  989.  * @return Found string, or NULL if not found or in case of error
  990.  */
  991. #define ml_FindPsz( ml, ... ) __ml_GetPsz( ml, __VA_ARGS__, ML_LIMIT, 1, ML_END )
  992. static inline char* __ml_GetPsz( media_library_t *p_media_library, ... )
  993. {
  994.     va_list args;
  995.     va_start( args, p_media_library );
  996.     ml_result_t result;
  997.     int i_ret = __ml_GetValue( p_media_library, &result, args );
  998.     va_end( args );
  999.     if( i_ret != VLC_SUCCESS )
  1000.         return NULL;
  1001.     else
  1002.         return result.value.psz; // no need to duplicate
  1003. }
  1004.  
  1005. /**
  1006.  * @brief Generic update in Media Library database
  1007.  *
  1008.  * @param p_media_library the media library object
  1009.  * @param selected_type the type of the element we're selecting
  1010.  * @param where list of ids/uris to be changed
  1011.  * @param changes list of changes to make in the entries
  1012.  * @return VLC_SUCCESS or VLC_EGENERIC
  1013.  */
  1014. static inline int ml_Update( media_library_t *p_media_library,
  1015.                              ml_select_e selected_type,
  1016.                              const char* psz_lvalue,
  1017.                              ml_ftree_t *where,
  1018.                              vlc_array_t *changes )
  1019. {
  1020.     return p_media_library->functions.pf_Update( p_media_library,
  1021.                                                  selected_type, psz_lvalue,
  1022.                                                  where, changes );
  1023. }
  1024.  
  1025. /**
  1026.  * @brief Update a given table
  1027.  * @param p_media_library The media library object
  1028.  * @param selected_type The table to update
  1029.  * @param psz_lvalue The role of the person if selected_type = ML_PEOPLE
  1030.  * @param id The id of the row to update
  1031.  * @param ... The update data. [SelectType [RoleType] Value]
  1032.  */
  1033. VLC_API int ml_UpdateSimple( media_library_t *p_media_library,
  1034.                                      ml_select_e selected_type,
  1035.                                      const char* psz_lvalue,
  1036.                                      int id, ... );
  1037. #define ml_UpdateSimple( ml, sel, lval, id, ... ) \
  1038.         ml_UpdateSimple( ml, sel, lval, id, __VA_ARGS__, ML_END )
  1039.  
  1040. /**
  1041.  * @brief Generic DELETE function
  1042.  * Delete a media and all its references which don't point
  1043.  * to anything else.
  1044.  *
  1045.  * @param p_media_library This media_library_t object
  1046.  * @param id the id of the media to delete
  1047.  * @return VLC_SUCCESS or VLC_EGENERIC
  1048.  */
  1049. static inline int
  1050. ml_DeleteSimple( media_library_t *p_media_library, int id )
  1051. {
  1052.     vlc_array_t* p_where = vlc_array_new();
  1053.     ml_element_t* p_find = (ml_element_t *) calloc( 1, sizeof( ml_element_t ) );
  1054.     p_find->criteria = ML_ID;
  1055.     p_find->value.i = id;
  1056.     vlc_array_append( p_where, p_find );
  1057.     int i_return =  p_media_library->functions.pf_Delete( p_media_library,
  1058.             p_where );
  1059.     free( p_find );
  1060.     vlc_array_destroy( p_where );
  1061.     return i_return;
  1062. }
  1063.  
  1064. /**
  1065.  * @brief Delete many medias in the media library
  1066.  * @param p_media_library Media library object
  1067.  * @param p_array Array of ids to delete
  1068.  * @return VLC_SUCCESS or VLC_EGENERIC
  1069.  */
  1070. static inline int
  1071. ml_Delete( media_library_t *p_media_library, vlc_array_t* p_array )
  1072. {
  1073.     return p_media_library->functions.pf_Delete( p_media_library,
  1074.                                                         p_array );
  1075. }
  1076.  
  1077.  
  1078. /*****************************************************************************
  1079.  * ML Person Related Functions
  1080.  *****************************************************************************/
  1081.  
  1082. /**
  1083.  * @brief Create and append a person object to the given list
  1084.  * @param pp_person pointer to person list. Set the address to null to create new list
  1085.  * @param i_role The role of the person
  1086.  * @param psz_name The name string. Will be strdup'd
  1087.  * @param i_id The id in the database
  1088.  * @note This function is NOT thread safe. Please lock any associated media
  1089.  */
  1090. static inline int ml_CreateAppendPersonAdv( ml_person_t **pp_person,
  1091.         const char* psz_role, const char* psz_name, int i_id )
  1092. {
  1093.     if( i_id == 0 || !( psz_name && *psz_name && psz_role && *psz_role ) )
  1094.         return VLC_SUCCESS;
  1095.     if( !pp_person )
  1096.         return VLC_EGENERIC;
  1097.     if( *pp_person != NULL )
  1098.         return ml_CreateAppendPersonAdv( &((**pp_person).p_next),
  1099.                                          psz_role, psz_name, i_id);
  1100.     *pp_person = ( ml_person_t * ) calloc( 1, sizeof( ml_person_t ) );
  1101.     (*pp_person)->psz_name = (psz_name && *psz_name) ? strdup( psz_name ): NULL;
  1102.     (*pp_person)->psz_role = (psz_role && *psz_role) ? strdup( psz_role ): NULL;
  1103.     (*pp_person)->i_id = i_id;
  1104.     (*pp_person)->p_next = NULL;
  1105.     return VLC_SUCCESS;
  1106. }
  1107.  
  1108. /**
  1109.  * @brief Create and append a person object to the given list
  1110.  * @param pp_person pointer to person list.
  1111.  * Set the address to NULL to create a new list
  1112.  * @param personfrom Person object to copy from
  1113.  * @note Ignores the next variable and copies only the variables.
  1114.  * Uses ml_CreateAppendPersonAdv
  1115.  * @note This function is NOT threadsafe
  1116.  */
  1117. static inline int ml_CreateAppendPerson( ml_person_t **pp_person,
  1118.                                          ml_person_t *p_personfrom )
  1119. {
  1120.     return ml_CreateAppendPersonAdv( pp_person,
  1121.                                      p_personfrom->psz_role,
  1122.                                      p_personfrom->psz_name,
  1123.                                      p_personfrom->i_id );
  1124. }
  1125.  
  1126. /**
  1127.  * @brief Copy one person list into another
  1128.  * @param a To list
  1129.  * @param b From list
  1130.  * @note On errors, you have to free any allocated persons yourself
  1131.  * @note This function is NOT threadsafe. Please ensure your medias are locked
  1132.  */
  1133. static inline int ml_CopyPersons( ml_person_t** a, ml_person_t* b )
  1134. {
  1135.     int i_ret;
  1136.     while( b )
  1137.     {
  1138.         i_ret = ml_CreateAppendPerson( a, b );
  1139.         if( i_ret != VLC_SUCCESS )
  1140.             return i_ret;
  1141.         b = b->p_next;
  1142.     }
  1143.     return VLC_SUCCESS;
  1144. }
  1145.  
  1146.  
  1147. /**
  1148.  * @brief Returns a person list of given type
  1149.  * @param p_ml The ML object
  1150.  * @param p_media The Media object
  1151.  * @param i_type The person type
  1152.  * @note This function is thread safe
  1153.  */
  1154. VLC_API ml_person_t *ml_GetPersonsFromMedia( media_library_t* p_ml,
  1155.                                                     ml_media_t* p_media,
  1156.                                                     const char *psz_role );
  1157.  
  1158.  
  1159. #define ml_GetAlbumArtistsFromMedia( a, b ) ml_GetPersonsFromMedia( a, b, ML_PERSON_ALBUM_ARTIST );
  1160. #define ml_GetArtistsFromMedia( a, b )      ml_GetPersonsFromMedia( a, b, ML_PERSON_ARTIST );
  1161. #define ml_GetEncodersFromMedia( a, b )     ml_GetPersonsFromMedia( a, b, ML_PERSON_ENCODER );
  1162. #define ml_GetPublishersFromMedia( a, b )   ml_GetPersonsFromMedia( a, b, ML_PERSON_PUBLISHER );
  1163.  
  1164. /**
  1165.  * @brief Delete a certain type of people from a media
  1166.  * @param p_media Media to delete from
  1167.  * @param i_type Type of person to delete
  1168.  * @note This function is threadsafe
  1169.  */
  1170. VLC_API void ml_DeletePersonTypeFromMedia( ml_media_t* p_media,
  1171.                                                  const char *psz_role );
  1172.  
  1173.  
  1174. /**
  1175.  * @brief Creates and adds the playlist based on a given find tree
  1176.  * @param p_ml Media library object
  1177.  * @param p_tree Find tree to create SELECT
  1178.  */
  1179.  
  1180. VLC_API void ml_PlaySmartPlaylistBasedOn( media_library_t* p_ml,
  1181.                                                 ml_ftree_t* p_tree );
  1182.  
  1183.  
  1184. /**
  1185.  * Convenience Macros
  1186.  */
  1187.  
  1188. /**
  1189.  * Get information using the *media* ID. This returns only 1 information.
  1190.  * @note You have to free the string returned (if that's a string!).
  1191.  */
  1192. #define ml_GetAlbumById( a, id )            ml_GetPsz( a, ML_ALBUM, ML_ID, id )
  1193. #define ml_GetArtistById( a, id )           ml_GetPsz( a, ML_PEOPLE, ML_PERSON_ARTIST, ML_ID, id )
  1194. #define ml_GetCoverUriById( a, id )         ml_GetPsz( a, ML_COVER, ML_ID, id )
  1195. #define ml_GetEncoderById( a, id )          ml_GetPsz( a, ML_PEOPLE, ML_PERSON_ENCODER, ML_ID, id )
  1196. #define ml_GetExtraById( a, id )            ml_GetPsz( a, ML_EXTRA, ML_ID, id )
  1197. #define ml_GetGenreById( a, id )            ml_GetPsz( a, ML_GENRE, ML_ID, id )
  1198. #define ml_GetOriginalTitleById( a, id )    ml_GetPsz( a, ML_ORIGINAL_TITLE, ML_ID, id )
  1199. #define ml_GetPublisherById( a, id )        ml_GetPsz( a, ML_PEOPLE, ML_PERSON_PUBLISHER, ML_ID, id )
  1200. #define ml_GetTitleById( a, id )            ml_GetPsz( a, ML_TITLE, ML_ID, id )
  1201. #define ml_GetUriById( a, id )              ml_GetPsz( a, ML_URI, ML_ID, id )
  1202.  
  1203. #define ml_GetAlbumIdById( a, id )          ml_GetInt( a, ML_ALBUM_ID, ML_ID, id )
  1204. #define ml_GetArtistIdById( a, id )         ml_GetInt( a, ML_PEOPLE_ID, ML_PERSON_ARTIST, ML_ID, id )
  1205. #define ml_GetDurationById( a, id )         ml_GetInt( a, ML_DURATION, ML_ID, id )
  1206. #define ml_GetEncoderIdById( a, id )        ml_GetInt( a, ML_PEOPLE_ID, ML_PERSON_ENCODER, ML_ID, id )
  1207. #define ml_GetLastPlayedById( a, id )       ml_GetInt( a, ML_LAST_PLAYED, ML_ID, id )
  1208. #define ml_GetPlayedCountById( a, id )      ml_GetInt( a, ML_PLAYED_COUNT, ML_ID, id )
  1209. #define ml_GetPublisherIdById( a, id )      ml_GetInt( a, ML_PEOPLE_ID, ML_PERSON_PUBLISHER, ML_ID, id )
  1210. #define ml_GetScoreById( a, id )            ml_GetInt( a, ML_SCORE, ML_ID, id )
  1211. #define ml_GetTrackNumberById( a, id )      ml_GetInt( a, ML_TRACK_NUMBER, ML_ID, id )
  1212. #define ml_GetTypeById( a, id )             ml_GetInt( a, ML_TYPE, ML_ID, id )
  1213. #define ml_GetYearById( a, id )             ml_GetInt( a, ML_YEAR, ML_ID, id )
  1214. #define ml_GetVoteById( a, id )             ml_GetInt( a, ML_VOTE, ML_ID, id )
  1215.  
  1216. /** Albums handling */
  1217. #define ml_GetAlbumId( a, b )               ml_GetInt( a, ML_ALBUM_ID, ML_ALBUM, b )
  1218.  
  1219. /** People handling */
  1220. #define ml_GetArtistId( a, b )              ml_GetInt( a, ML_PERSON_ID, ML_PERSON_ARTIST, ML_PERSON, ML_PERSON_ARTIST, b )
  1221. #define ml_GetEncoderId( a, b )             ml_GetInt( a, ML_PERSON_ID, ML_PERSON_ENCODER, ML_PERSON, ML_PERSON_ENCODER, b )
  1222. #define ml_GetPublisherId( a, b )           ml_GetInt( a, ML_PERSON_ID, ML_PERSON_PUBLISHER, ML_PERSON, ML_PERSON_PUBLISHER, b )
  1223.  
  1224. /** Counts handling */
  1225. #define ml_GetMediaCount( a, ... )          __ml_GetInt( a, ML_COUNT_MEDIA,      __VA_ARGS__, ML_END )
  1226. #define ml_GetAlbumCount( a, ... )          __ml_GetInt( a, ML_COUNT_ALBUM,      __VA_ARGS__, ML_END )
  1227. #define ml_GetPeopleCount( a, ... )         __ml_GetInt( a, ML_COUNT_PEOPLE,     __VA_ARGS__, ML_END )
  1228.  
  1229. #define ml_Find( a, b, ... )                __ml_Find( a, b, __VA_ARGS__, ML_END )
  1230.  
  1231. #define ml_FindAlbum( a, b, ... )           __ml_Find( a, b, ML_ALBUM,           __VA_ARGS__, ML_END )
  1232. #define ml_FindArtist( a, b, ... )          __ml_Find( a, b, ML_PERSON, ML_PERSON_ARTIST, __VA_ARGS__, ML_END )
  1233. #define ml_FindEncoder( a, b, ... )         __ml_Find( a, b, ML_PERSON, ML_PERSON_ENCODER, __VA_ARGS__, ML_END )
  1234. #define ml_FindGenre( a, b, ... )           __ml_Find( a, b, ML_GENRE,           __VA_ARGS__, ML_END )
  1235. #define ml_FindMedia( a, b, ... )           __ml_Find( a, b, ML_MEDIA,           __VA_ARGS__, ML_END )
  1236. #define ml_FindOriginalTitle( a, b, ... )   __ml_Find( a, b, ML_ORIGINAL_TITLE,  __VA_ARGS__, ML_END )
  1237. #define ml_FindPublisher( a, b, ... )       __ml_Find( a, b, ML_PERSON, ML_PERSON_PUBLISHER, __VA_ARGS__, ML_END )
  1238. #define ml_FindTitle( a, b, ... )           __ml_Find( a, b, ML_TITLE,           __VA_ARGS__, ML_END )
  1239. #define ml_FindType( a, b, ... )            __ml_Find( a, b, ML_TYPE,            __VA_ARGS__, ML_END )
  1240. #define ml_FindUri( a, b, ... )             __ml_Find( a, b, ML_URI,             __VA_ARGS__, ML_END )
  1241. #define ml_FindYear( a, b, ... )            __ml_Find( a, b, ML_YEAR,            __VA_ARGS__, ML_END )
  1242.  
  1243. #define ml_FindAllAlbums( a, b )            ml_FindAlbum( a, b,         ML_DISTINCT )
  1244. #define ml_FindAllArtists( a, b )           ml_FindArtist( a, b,        ML_DISTINCT )
  1245. #define ml_FindAllGenres( a, b )            ml_FindGenre( a, b,         ML_DISTINCT )
  1246. #define ml_FindAllMedias( a, b )            ml_FindMedia( a, b,         ML_DISTINCT )
  1247. #define ml_FindAllOriginalTitles( a, b )    ml_FindOriginalTitle( a, b, ML_DISTINCT )
  1248. #define ml_FindAllPublishers( a, b, ... )   ml_FindPublisher( a, b,     ML_DISTINCT )
  1249. #define ml_FindAllTitles( a, b )            ml_FindTitle( a, b,         ML_DISTINCT )
  1250. #define ml_FindAllTypes( a, b )             ml_FindType( a, b,          ML_DISTINCT )
  1251. #define ml_FindAllUris( a, b )              ml_FindUri( a, b,           ML_DISTINCT )
  1252. #define ml_FindAllYears( a, b )             ml_FindYear( a, b,          ML_DISTINCT )
  1253.  
  1254. #define ml_FindAlbumAdv( a, b, c )          ml_FindAdv( a, b, ML_ALBUM,         NULL, c )
  1255. #define ml_FindArtistAdv( a, b, c )         ml_FindAdv( a, b, ML_PERSON,        ML_PERSON_ARTIST, c )
  1256. #define ml_FindEncoderAdv( a, b, c )        ml_FindAdv( a, b, ML_PERSON,        ML_PERSON_ENCODER, c )
  1257. #define ml_FindGenreAdv( a, b, c )          ml_FindAdv( a, b, ML_GENRE,         NULL, c )
  1258. #define ml_FindMediaAdv( a, b, c )          ml_FindAdv( a, b, ML_MEDIA,         NULL, c )
  1259. #define ml_FindOriginalTitleAdv( a, b, c )  ml_FindAdv( a, b, ML_ORIGINAL_TITLE,NULL, c )
  1260. #define ml_FindPublisherAdv( a, b, c )      ml_FindAdv( a, b, ML_PUBLISHER,     ML_PERSON_PUBLISHER, c )
  1261. #define ml_FindTitleAdv( a, b, c )          ml_FindAdv( a, b, ML_TITLE,         NULL, c )
  1262. #define ml_FindTypeAdv( a, b, c )           ml_FindAdv( a, b, ML_TYPE,          NULL, c )
  1263. #define ml_FindUriAdv( a, b, c )            ml_FindAdv( a, b, ML_URI,           NULL, c )
  1264. #define ml_FindYearAdv( a, b, c )           ml_FindAdv( a, b, ML_YEAR,          NULL, c )
  1265.  
  1266.  
  1267.  
  1268. #ifdef __cplusplus
  1269. }
  1270. #endif /* C++ */
  1271.  
  1272. #endif /* VLC_MEDIA_LIBRARY_H */
  1273.