📄 control.c
字号:
/***************************************************************************** * control.c : Handle control of the playlist & running through it ***************************************************************************** * Copyright (C) 1999-2004 the VideoLAN team * $Id: 3e2abc479bd1a4e1b5f02c2505200c127fca0bed $ * * Authors: Samuel Hocevar <sam@zoy.org> * Clément Stenac <zorglub@videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include "vlc_playlist.h"#include "playlist_internal.h"#include <assert.h>/***************************************************************************** * Local prototypes *****************************************************************************/static int PlaylistVAControl( playlist_t * p_playlist, int i_query, va_list args );static void PreparseEnqueueItemSub( playlist_t *, playlist_item_t * );/***************************************************************************** * Playlist control *****************************************************************************/playlist_t *__pl_Yield( vlc_object_t *p_this ){ playlist_t *pl; barrier (); pl = libvlc_priv (p_this->p_libvlc)->p_playlist; assert( VLC_OBJECT(pl) != p_this /* This does not make sense to yield the playlist using pl_Yield. use vlc_object_yield in this case */ ); if (pl) vlc_object_yield (pl); return pl;}void __pl_Release( vlc_object_t *p_this ){ playlist_t *pl = libvlc_priv (p_this->p_libvlc)->p_playlist; assert( pl != NULL ); assert( VLC_OBJECT(pl) != p_this /* The rule is that pl_Release() should act on the same object than pl_Yield() */ ); vlc_object_release( pl );}int playlist_Control( playlist_t * p_playlist, int i_query, bool b_locked, ... ){ va_list args; int i_result; va_start( args, b_locked ); PL_LOCK_IF( !b_locked ); i_result = PlaylistVAControl( p_playlist, i_query, args ); va_end( args ); PL_UNLOCK_IF( !b_locked ); return i_result;}static int PlaylistVAControl( playlist_t * p_playlist, int i_query, va_list args ){ playlist_item_t *p_item, *p_node; vlc_value_t val; PL_ASSERT_LOCKED; if( !vlc_object_alive( p_playlist ) ) return VLC_EGENERIC; if( playlist_IsEmpty( p_playlist ) ) return VLC_EGENERIC; switch( i_query ) { case PLAYLIST_STOP: p_playlist->request.i_status = PLAYLIST_STOPPED; p_playlist->request.b_request = true; p_playlist->request.p_item = NULL; break; // Node can be null, it will keep the same. Use with care ... // Item null = take the first child of node case PLAYLIST_VIEWPLAY: p_node = (playlist_item_t *)va_arg( args, playlist_item_t * ); p_item = (playlist_item_t *)va_arg( args, playlist_item_t * ); if ( p_node == NULL ) { p_node = get_current_status_node( p_playlist ); assert( p_node ); } p_playlist->request.i_status = PLAYLIST_RUNNING; p_playlist->request.i_skip = 0; p_playlist->request.b_request = true; p_playlist->request.p_node = p_node; p_playlist->request.p_item = p_item; if( p_item && var_GetBool( p_playlist, "random" ) ) p_playlist->b_reset_currently_playing = true; break; case PLAYLIST_PLAY: if( p_playlist->p_input ) { val.i_int = PLAYING_S; var_Set( p_playlist->p_input, "state", val ); break; } else { p_playlist->request.i_status = PLAYLIST_RUNNING; p_playlist->request.b_request = true; p_playlist->request.p_node = get_current_status_node( p_playlist ); p_playlist->request.p_item = get_current_status_item( p_playlist ); p_playlist->request.i_skip = 0; } break; case PLAYLIST_PAUSE: val.i_int = 0; if( p_playlist->p_input ) var_Get( p_playlist->p_input, "state", &val ); if( val.i_int == PAUSE_S ) { p_playlist->status.i_status = PLAYLIST_RUNNING; if( p_playlist->p_input ) { val.i_int = PLAYING_S; var_Set( p_playlist->p_input, "state", val ); } } else { p_playlist->status.i_status = PLAYLIST_PAUSED; if( p_playlist->p_input ) { val.i_int = PAUSE_S; var_Set( p_playlist->p_input, "state", val ); } } break; case PLAYLIST_SKIP: p_playlist->request.p_node = get_current_status_node( p_playlist ); p_playlist->request.p_item = get_current_status_item( p_playlist ); p_playlist->request.i_skip = (int) va_arg( args, int ); /* if already running, keep running */ if( p_playlist->status.i_status != PLAYLIST_STOPPED ) p_playlist->request.i_status = p_playlist->status.i_status; p_playlist->request.b_request = true; break; default: msg_Err( p_playlist, "unknown playlist query" ); return VLC_EBADVAR; break; } vlc_object_signal_unlocked( p_playlist ); return VLC_SUCCESS;}/***************************************************************************** * Preparse control *****************************************************************************//** Enqueue an item for preparsing */int playlist_PreparseEnqueue( playlist_t *p_playlist, input_item_t *p_item ){ vlc_object_lock( p_playlist->p_preparse ); if( !vlc_object_alive( p_playlist->p_preparse ) ) { vlc_object_unlock( p_playlist->p_preparse ); return VLC_EGENERIC; } vlc_gc_incref( p_item ); INSERT_ELEM( p_playlist->p_preparse->pp_waiting, p_playlist->p_preparse->i_waiting, p_playlist->p_preparse->i_waiting, p_item ); vlc_object_signal_unlocked( p_playlist->p_preparse ); vlc_object_unlock( p_playlist->p_preparse ); return VLC_SUCCESS;}/** Enqueue a playlist item or a node for peparsing. * This function should be entered without playlist and preparser locks */int playlist_PreparseEnqueueItem( playlist_t *p_playlist, playlist_item_t *p_item ){ vlc_object_lock( p_playlist ); vlc_object_lock( p_playlist->p_preparse ); if( !vlc_object_alive( p_playlist->p_preparse ) ) { vlc_object_unlock( p_playlist->p_preparse ); vlc_object_unlock( p_playlist ); return VLC_EGENERIC; } PreparseEnqueueItemSub( p_playlist, p_item ); vlc_object_unlock( p_playlist->p_preparse ); vlc_object_unlock( p_playlist ); return VLC_SUCCESS;}int playlist_AskForArtEnqueue( playlist_t *p_playlist, input_item_t *p_item ){ vlc_object_lock( p_playlist->p_fetcher ); if( !vlc_object_alive( p_playlist->p_fetcher ) ) { vlc_object_unlock( p_playlist->p_fetcher ); return VLC_EGENERIC; } vlc_gc_incref( p_item ); INSERT_ELEM( p_playlist->p_fetcher->pp_waiting, p_playlist->p_fetcher->i_waiting, p_playlist->p_fetcher->i_waiting, p_item ); vlc_object_signal_unlocked( p_playlist->p_fetcher ); vlc_object_unlock( p_playlist->p_fetcher ); return VLC_SUCCESS;}static void PreparseEnqueueItemSub( playlist_t *p_playlist, playlist_item_t *p_item ){ int i; if( p_item->i_children == -1 ) { vlc_gc_incref( p_item->p_input ); INSERT_ELEM( p_playlist->p_preparse->pp_waiting, p_playlist->p_preparse->i_waiting, p_playlist->p_preparse->i_waiting, p_item->p_input ); } else { for( i = 0; i < p_item->i_children; i++) { PreparseEnqueueItemSub( p_playlist, p_item->pp_children[i] ); } }}/***************************************************************************** * Playback logic *****************************************************************************//** * Synchronise the current index of the playlist * to match the index of the current item. * * \param p_playlist the playlist structure * \param p_cur the current playlist item * \return nothing */static void ResyncCurrentIndex( playlist_t *p_playlist, playlist_item_t *p_cur ){ PL_DEBUG( "resyncing on %s", PLI_NAME( p_cur ) ); /* Simply resync index */ int i; p_playlist->i_current_index = -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -