item-ext.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:18k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * item-ext.c : Playlist item management functions
  3.  *****************************************************************************
  4.  * Copyright (C) 1999-2004 VideoLAN
  5.  * $Id: item-ext.c 7997 2004-06-18 11:35:45Z sigmunau $
  6.  *
  7.  * Authors: Samuel Hocevar <sam@zoy.org>
  8.  *          Cl閙ent Stenac <zorglub@videolan.org>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. #include <stdlib.h>                                      /* free(), strtol() */
  25. #include <stdio.h>                                              /* sprintf() */
  26. #include <string.h>                                            /* strerror() */
  27. #include <vlc/vlc.h>
  28. #include <vlc/input.h>
  29. #include "vlc_playlist.h"
  30. /***************************************************************************
  31.  * Item creation/addition functions
  32.  ***************************************************************************/
  33. /**
  34.  * Add a MRL into the playlist, duration and options given
  35.  *
  36.  * param p_playlist the playlist to add into
  37.  * param psz_uri the mrl to add to the playlist
  38.  * param psz_name a text giving a name or description of this item
  39.  * param i_mode the mode used when adding
  40.  * param i_pos the position in the playlist where to add. If this is
  41.  *        PLAYLIST_END the item will be added at the end of the playlist
  42.  *        regardless of it's size
  43.  * param i_duration length of the item in milliseconds.
  44.  * param ppsz_options an array of options
  45.  * param i_options the number of options
  46.  * return The id of the playlist item
  47. */
  48. int playlist_AddExt( playlist_t *p_playlist, const char * psz_uri,
  49.                      const char *psz_name, int i_mode, int i_pos,
  50.                      mtime_t i_duration, const char **ppsz_options,
  51.                      int i_options )
  52. {
  53.     playlist_item_t *p_item =
  54.         playlist_ItemNew( p_playlist , psz_uri, psz_name );
  55.     if( p_item == NULL )
  56.     {
  57.         msg_Err( p_playlist, "unable to add item to playlist" );
  58.         return -1;
  59.     }
  60.     p_item->input.i_duration = i_duration;
  61.     p_item->input.i_options = i_options;
  62.     p_item->input.ppsz_options = NULL;
  63.     for( p_item->input.i_options = 0; p_item->input.i_options < i_options;
  64.          p_item->input.i_options++ )
  65.     {
  66.         if( !p_item->input.i_options )
  67.         {
  68.             p_item->input.ppsz_options = malloc( i_options * sizeof(char *) );
  69.             if( !p_item->input.ppsz_options ) break;
  70.         }
  71.         p_item->input.ppsz_options[p_item->input.i_options] =
  72.             strdup( ppsz_options[p_item->input.i_options] );
  73.     }
  74.     return playlist_AddItem( p_playlist, p_item, i_mode, i_pos );
  75. }
  76. /**
  77.  * Add a MRL into the playlist.
  78.  *
  79.  * param p_playlist the playlist to add into
  80.  * param psz_uri the mrl to add to the playlist
  81.  * param psz_name a text giving a name or description of this item
  82.  * param i_mode the mode used when adding
  83.  * param i_pos the position in the playlist where to add. If this is
  84.  *        PLAYLIST_END the item will be added at the end of the playlist
  85.  *        regardless of it's size
  86.  * return The id of the playlist item
  87. */
  88. int playlist_Add( playlist_t *p_playlist, const char *psz_uri,
  89.                   const char *psz_name, int i_mode, int i_pos )
  90. {
  91.     return playlist_AddExt( p_playlist, psz_uri, psz_name, i_mode, i_pos,
  92.                             -1, NULL, 0 );
  93. }
  94. /***************************************************************************
  95.  * Item search functions
  96.  ***************************************************************************/
  97. /**
  98.  * Search the position of an item by its id
  99.  * This function must be entered with the playlist lock
  100.  *
  101.  * param p_playlist the playlist
  102.  * param i_id the id to find
  103.  * return the position, or VLC_EGENERIC on failure
  104.  */
  105. int playlist_GetPositionById( playlist_t * p_playlist , int i_id )
  106. {
  107.     int i;
  108.     for( i =  0 ; i < p_playlist->i_size ; i++ )
  109.     {
  110.         if( p_playlist->pp_items[i]->i_id == i_id )
  111.         {
  112.             return i;
  113.         }
  114.     }
  115.     return VLC_EGENERIC;
  116. }
  117. /**
  118.  * Search an item by its id
  119.  *
  120.  * param p_playlist the playlist
  121.  * param i_id the id to find
  122.  * return the item, or NULL on failure
  123.  */
  124. playlist_item_t * playlist_ItemGetById( playlist_t * p_playlist , int i_id )
  125. {
  126.     int i;
  127.     for( i =  0 ; i < p_playlist->i_size ; i++ )
  128.     {
  129.         if( p_playlist->pp_items[i]->i_id == i_id )
  130.         {
  131.             return p_playlist->pp_items[i];
  132.         }
  133.     }
  134.     return NULL;
  135. }
  136. /**
  137.  * Search an item by its position
  138.  * This function must be entered with the playlist lock
  139.  *
  140.  * param p_playlist the playlist
  141.  * param i_pos the position of the item to find
  142.  * return the item, or NULL on failure
  143.  */
  144. playlist_item_t * playlist_ItemGetByPos( playlist_t * p_playlist , int i_pos )
  145. {
  146.     if( i_pos >= 0 && i_pos < p_playlist->i_size)
  147.     {
  148.         return p_playlist->pp_items[i_pos];
  149.     }
  150.     else if( p_playlist->i_size > 0)
  151.     {
  152.         return p_playlist->pp_items[p_playlist->i_index];
  153.     }
  154.     else
  155.     {
  156.         return NULL;
  157.     }
  158. }
  159. /**********************************************************************
  160.  * playlist_item_t structure accessors
  161.  * These functions give access to the fields of the playlist_item_t
  162.  * structure
  163.  **********************************************************************/
  164. /**
  165.  * Set the group of a playlist item
  166.  *
  167.  * param p_item the item
  168.  * param i_group the group to set
  169.  * return VLC_SUCCESS on success
  170.  */
  171. int playlist_ItemSetGroup( playlist_item_t *p_item, int i_group)
  172. {
  173.     p_item->i_group = i_group;
  174.     return VLC_SUCCESS;
  175. }
  176. /**
  177.  * Set the group of a playlist item (by position)
  178.  * This function must be entered with the playlist lock
  179.  * Legacy function due to disappear (locks the whole playlist)
  180.  *
  181.  * param p_playlist the playlist
  182.  * param i_pos the postition of the item of which we change the group
  183.  * param i_group the new group
  184.  * return VLC_SUCCESS on success, VLC_EGENERIC on failure
  185.  */
  186. int playlist_SetGroup( playlist_t *p_playlist, int i_pos, int i_group )
  187. {
  188.     vlc_value_t val;
  189.     playlist_item_t *p_item;
  190.     if( !p_playlist )
  191.     {
  192.         return VLC_ENOOBJ;
  193.     }
  194.     p_item = playlist_ItemGetByPos( p_playlist , i_pos );
  195.     if( !p_item )
  196.     {
  197.         return VLC_ENOOBJ;
  198.     }
  199.     vlc_mutex_lock( &p_item->input.lock );
  200.     playlist_ItemSetGroup( p_item , i_group );
  201.     vlc_mutex_unlock( &p_item->input.lock );
  202.     val.b_bool = (i_pos >= 0 && i_pos < p_playlist->i_size ) ? i_pos : -1;
  203.     var_Set( p_playlist, "item-change", val );
  204.     return VLC_SUCCESS;
  205. }
  206. /**
  207.  * Set the name of a playlist item
  208.  *
  209.  * param p_item the item
  210.  * param psz_name the new name
  211.  * return VLC_SUCCESS on success, VLC_EGENERIC on failure
  212.  */
  213. int playlist_ItemSetName( playlist_item_t *p_item, char *psz_name )
  214. {
  215.     if( psz_name && p_item )
  216.     {
  217.         p_item->input.psz_name = strdup( psz_name );
  218.         return VLC_SUCCESS;
  219.     }
  220.     return VLC_EGENERIC;
  221. }
  222. /**
  223.  * Set the name of a playlist item (by position)
  224.  * This function must be entered with the playlist lock
  225.  * Legacy function due to disappear (locks the whole playlist)
  226.  *
  227.  * param p_playlist the playlist
  228.  * param i_pos the position of the item of which we change the name
  229.  * param psz_name the new name
  230.  * return VLC_SUCCESS on success, VLC_EGENERIC on failure
  231.  */
  232. int playlist_SetName( playlist_t *p_playlist, int i_pos, char *psz_name )
  233. {
  234.     vlc_value_t val;
  235.     playlist_item_t *p_item;
  236.     if( !p_playlist )
  237.     {
  238.         return VLC_ENOOBJ;
  239.     }
  240.     p_item = playlist_ItemGetByPos( p_playlist , i_pos );
  241.     if( !p_item )
  242.     {
  243.         return VLC_ENOOBJ;
  244.     }
  245.     vlc_mutex_lock( &p_item->input.lock );
  246.     playlist_ItemSetName( p_item , psz_name );
  247.     vlc_mutex_unlock( &p_item->input.lock );
  248.     val.b_bool = (i_pos >= 0 && i_pos < p_playlist->i_size ) ? i_pos : -1;
  249.     var_Set( p_playlist, "item-change", val );
  250.     return VLC_SUCCESS;
  251. }
  252. /**
  253.  * Set the duration of a playlist item
  254.  * This function must be entered with the item lock
  255.  *
  256.  * param p_item the item
  257.  * param i_duration the new duration
  258.  * return VLC_SUCCESS on success, VLC_EGENERIC on failure
  259.  */
  260. int playlist_ItemSetDuration( playlist_item_t *p_item, mtime_t i_duration )
  261. {
  262.     char psz_buffer[MSTRTIME_MAX_SIZE];
  263.     if( p_item )
  264.     {
  265.         p_item->input.i_duration = i_duration;
  266.         if( i_duration != -1 )
  267.         {
  268.             secstotimestr( psz_buffer, i_duration/1000000 );
  269.         }
  270.         else
  271.         {
  272.             memcpy( psz_buffer, "--:--:--", sizeof("--:--:--") );
  273.         }
  274.         playlist_ItemAddInfo( p_item, _("General") , _("Duration"),
  275.                               "%s", psz_buffer );
  276.         return VLC_SUCCESS;
  277.     }
  278.     return VLC_EGENERIC;
  279. }
  280. /**
  281.  * Set the duration of a playlist item
  282.  * This function must be entered with the playlist lock
  283.  * Legacy function due to disappear (locks the whole playlist)
  284.  *
  285.  * param p_playlist the playlist
  286.  * param i_pos the position of the item of which we change the duration
  287.  * param i_duration the duration to set
  288.  * return VLC_SUCCESS on success, VLC_EGENERIC on failure
  289.  */
  290. int playlist_SetDuration( playlist_t *p_playlist, int i_pos, mtime_t i_duration )
  291. {
  292.     vlc_value_t val;
  293.     playlist_item_t *p_item;
  294.     if( !p_playlist )
  295.     {
  296.         return VLC_ENOOBJ;
  297.     }
  298.     p_item = playlist_ItemGetByPos( p_playlist , i_pos );
  299.     if( !p_item )
  300.     {
  301.         return VLC_ENOOBJ;
  302.     }
  303.     vlc_mutex_lock( &p_item->input.lock );
  304.     playlist_ItemSetDuration( p_item , i_duration );
  305.     vlc_mutex_unlock( &p_item->input.lock );
  306.     val.b_bool = (i_pos >= 0 && i_pos < p_playlist->i_size ) ? i_pos : -1;
  307.     var_Set( p_playlist, "item-change", val );
  308.     return VLC_SUCCESS;
  309. }
  310. /**********************************************************************
  311.  * Actions on existing playlist items
  312.  **********************************************************************/
  313. /**
  314.  * delete an item from a playlist.
  315.  *
  316.  * param p_playlist the playlist to remove from.
  317.  * param i_pos the position of the item to remove
  318.  * return returns 0
  319.  */
  320. int playlist_Delete( playlist_t * p_playlist, int i_pos )
  321. {
  322.     vlc_value_t     val;
  323.     /* if i_pos is the current played item, playlist should stop playing it */
  324.     if( ( p_playlist->i_status == PLAYLIST_RUNNING) &&
  325.                     (p_playlist->i_index == i_pos) )
  326.     {
  327.         playlist_Command( p_playlist, PLAYLIST_STOP, 0 );
  328.     }
  329.     vlc_mutex_lock( &p_playlist->object_lock );
  330.     if( i_pos >= 0 && i_pos < p_playlist->i_size )
  331.     {
  332.         playlist_item_t *p_item = p_playlist->pp_items[i_pos];
  333.         msg_Dbg( p_playlist, "deleting playlist item `%s'",
  334.                  p_item->input.psz_name );
  335.         playlist_ItemDelete( p_item );
  336.         if( i_pos <= p_playlist->i_index )
  337.         {
  338.             p_playlist->i_index--;
  339.         }
  340.         /* Renumber the playlist */
  341.         REMOVE_ELEM( p_playlist->pp_items, p_playlist->i_size, i_pos );
  342.         if( p_playlist->i_enabled > 0 ) p_playlist->i_enabled--;
  343.     }
  344.     vlc_mutex_unlock( &p_playlist->object_lock );
  345.     val.b_bool = VLC_TRUE;
  346.     var_Set( p_playlist, "intf-change", val );
  347.     return 0;
  348. }
  349. /**
  350.  * Clear all playlist items
  351.  *
  352.  * param p_playlist the playlist to be cleared.
  353.  * return returns 0
  354.  */
  355. int playlist_Clear( playlist_t * p_playlist )
  356. {
  357.     while( p_playlist->i_groups > 0 )
  358.     {
  359.         playlist_DeleteGroup( p_playlist, p_playlist->pp_groups[0]->i_id );
  360.     }
  361.     while( p_playlist->i_size > 0 )
  362.     {
  363.         playlist_Delete( p_playlist, 0 );
  364.     }
  365.     p_playlist->i_index = -1;
  366.     p_playlist->i_size = 0;
  367.     p_playlist->pp_items = NULL;
  368.     p_playlist->i_groups = 0;
  369.     p_playlist->pp_groups = NULL;
  370.     return 0;
  371. }
  372. /**
  373.  * Disables a playlist item
  374.  *
  375.  * param p_playlist the playlist to disable from.
  376.  * param i_pos the position of the item to disable
  377.  * return returns 0
  378.  */
  379. int playlist_Disable( playlist_t * p_playlist, int i_pos )
  380. {
  381.     vlc_value_t     val;
  382.     vlc_mutex_lock( &p_playlist->object_lock );
  383.     if( i_pos >= 0 && i_pos < p_playlist->i_size )
  384.     {
  385.         msg_Dbg( p_playlist, "disabling playlist item `%s'",
  386.                  p_playlist->pp_items[i_pos]->input.psz_name );
  387.         if( p_playlist->pp_items[i_pos]->b_enabled == VLC_TRUE )
  388.             p_playlist->i_enabled--;
  389.         p_playlist->pp_items[i_pos]->b_enabled = VLC_FALSE;
  390.     }
  391.     vlc_mutex_unlock( &p_playlist->object_lock );
  392.     val.b_bool = i_pos;
  393.     var_Set( p_playlist, "item-change", val );
  394.     return 0;
  395. }
  396. /**
  397.  * Enables a playlist item
  398.  *
  399.  * param p_playlist the playlist to enable from.
  400.  * param i_pos the position of the item to enable
  401.  * return returns 0
  402.  */
  403. int playlist_Enable( playlist_t * p_playlist, int i_pos )
  404. {
  405.     vlc_value_t     val;
  406.     vlc_mutex_lock( &p_playlist->object_lock );
  407.     if( i_pos >= 0 && i_pos < p_playlist->i_size )
  408.     {
  409.         msg_Dbg( p_playlist, "enabling playlist item `%s'",
  410.                  p_playlist->pp_items[i_pos]->input.psz_name );
  411.         if( p_playlist->pp_items[i_pos]->b_enabled == VLC_FALSE )
  412.             p_playlist->i_enabled++;
  413.         p_playlist->pp_items[i_pos]->b_enabled = VLC_TRUE;
  414.     }
  415.     vlc_mutex_unlock( &p_playlist->object_lock );
  416.     val.b_bool = i_pos;
  417.     var_Set( p_playlist, "item-change", val );
  418.     return 0;
  419. }
  420. /**
  421.  * Disables a playlist group
  422.  *
  423.  * param p_playlist the playlist to disable from.
  424.  * param i_group the id of the group to disable
  425.  * return returns 0
  426.  */
  427. int playlist_DisableGroup( playlist_t * p_playlist, int i_group )
  428. {
  429.     vlc_value_t     val;
  430.     int i;
  431.     vlc_mutex_lock( &p_playlist->object_lock );
  432.     msg_Dbg( p_playlist, "disabling group %i", i_group );
  433.     for( i = 0 ; i< p_playlist->i_size; i++ )
  434.     {
  435.         if( p_playlist->pp_items[i]->i_group == i_group )
  436.         {
  437.             msg_Dbg( p_playlist, "disabling playlist item `%s'",
  438.                      p_playlist->pp_items[i]->input.psz_name );
  439.             if( p_playlist->pp_items[i]->b_enabled == VLC_TRUE )
  440.                 p_playlist->i_enabled--;
  441.             p_playlist->pp_items[i]->b_enabled = VLC_FALSE;
  442.             val.b_bool = i;
  443.             var_Set( p_playlist, "item-change", val );
  444.         }
  445.     }
  446.     vlc_mutex_unlock( &p_playlist->object_lock );
  447.     return 0;
  448. }
  449. /**
  450.  * Enables a playlist group
  451.  *
  452.  * param p_playlist the playlist to enable from.
  453.  * param i_group the id of the group to enable
  454.  * return returns 0
  455.  */
  456. int playlist_EnableGroup( playlist_t * p_playlist, int i_group )
  457. {
  458.     vlc_value_t val;
  459.     int i;
  460.     vlc_mutex_lock( &p_playlist->object_lock );
  461.     for( i = 0; i< p_playlist->i_size; i++ )
  462.     {
  463.         if( p_playlist->pp_items[i]->i_group == i_group )
  464.         {
  465.             msg_Dbg( p_playlist, "enabling playlist item `%s'",
  466.                      p_playlist->pp_items[i]->input.psz_name );
  467.             if( p_playlist->pp_items[i]->b_enabled == VLC_FALSE )
  468.                 p_playlist->i_enabled++;
  469.             p_playlist->pp_items[i]->b_enabled = VLC_TRUE;
  470.             val.b_bool = i;
  471.             var_Set( p_playlist, "item-change", val );
  472.         }
  473.     }
  474.     vlc_mutex_unlock( &p_playlist->object_lock );
  475.     return 0;
  476. }
  477. /**
  478.  * Move an item in a playlist
  479.  *
  480.  * Move the item in the playlist with position i_pos before the current item
  481.  * at position i_newpos.
  482.  * param p_playlist the playlist to move items in
  483.  * param i_pos the position of the item to move
  484.  * param i_newpos the position of the item that will be behind the moved item
  485.  *        after the move
  486.  * return returns VLC_SUCCESS
  487.  */
  488. int playlist_Move( playlist_t * p_playlist, int i_pos, int i_newpos )
  489. {
  490.     vlc_value_t val;
  491.     vlc_mutex_lock( &p_playlist->object_lock );
  492.     /* take into account that our own row disappears. */
  493.     if( i_pos < i_newpos ) i_newpos--;
  494.     if( i_pos >= 0 && i_newpos >=0 && i_pos <= p_playlist->i_size &&
  495.         i_newpos <= p_playlist->i_size )
  496.     {
  497.         playlist_item_t * temp;
  498.         msg_Dbg( p_playlist, "moving playlist item `%s' (%i -> %i)",
  499.                  p_playlist->pp_items[i_pos]->input.psz_name, i_pos, i_newpos);
  500.         if( i_pos == p_playlist->i_index )
  501.         {
  502.             p_playlist->i_index = i_newpos;
  503.         }
  504.         else if( i_pos > p_playlist->i_index && i_newpos <= p_playlist->i_index )
  505.         {
  506.             p_playlist->i_index++;
  507.         }
  508.         else if( i_pos < p_playlist->i_index && i_newpos >= p_playlist->i_index )
  509.         {
  510.             p_playlist->i_index--;
  511.         }
  512.         if ( i_pos < i_newpos )
  513.         {
  514.             temp = p_playlist->pp_items[i_pos];
  515.             while ( i_pos < i_newpos )
  516.             {
  517.                 p_playlist->pp_items[i_pos] = p_playlist->pp_items[i_pos+1];
  518.                 i_pos++;
  519.             }
  520.             p_playlist->pp_items[i_newpos] = temp;
  521.         }
  522.         else if ( i_pos > i_newpos )
  523.         {
  524.             temp = p_playlist->pp_items[i_pos];
  525.             while ( i_pos > i_newpos )
  526.             {
  527.                 p_playlist->pp_items[i_pos] = p_playlist->pp_items[i_pos-1];
  528.                 i_pos--;
  529.             }
  530.             p_playlist->pp_items[i_newpos] = temp;
  531.         }
  532.     }
  533.     vlc_mutex_unlock( &p_playlist->object_lock );
  534.     val.b_bool = VLC_TRUE;
  535.     var_Set( p_playlist, "intf-change", val );
  536.     return VLC_SUCCESS;
  537. }