📄 svlc_event.c
字号:
/*****************************************************************************
* svlc_event.c: a simple shared library wrapper around libvlc
*****************************************************************************
* Copyright (C) 2004 Markus Kern <mkern@users.sourceforge.net>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "config.h"
//#include <stdlib.h>
#define __BUILTIN__
#define __VLC__
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/input.h>
#include <vlc/vout.h>
#include <vlc/aout.h>
#include "svlc_event.h"
#define EVENT_THREAD_SLEEP 100 /* ms */
/******************************************************************************
* Some internal helper functions
*****************************************************************************/
#ifdef DEBUG
/* This resides in libvcl.c but is not in the headers. */
vlc_t * vlc_current_object (int i_object);
static char * state_str (SVlcPlaybackState state)
{
switch (state)
{
case SVLC_PLAYBACK_CLOSED: return "Closed";
case SVLC_PLAYBACK_LOADING: return "Loading";
case SVLC_PLAYBACK_OPEN: return "Open";
case SVLC_PLAYBACK_PLAYING: return "Playing";
case SVLC_PLAYBACK_PAUSED: return "Paused";
case SVLC_PLAYBACK_STOPPED: return "Stopped";
default: return "UNKNOWN";
};
}
static void log_state_change (HSVLC svlc, SVlcPlaybackState old_state,
SVlcPlaybackState new_state)
{
vlc_t *vlc;
if (!(vlc = vlc_current_object (svlc->vlc)))
return;
msg_Dbg (vlc, "STATE CHANGE: %s => %s",
state_str (old_state), state_str (new_state));
vlc_object_release (vlc);
}
#endif
/*****************************************************************************
* Polling thread
*****************************************************************************/
#if 0
/* polling thread function */
static void event_thread_func (svlc_event_thread_t *thread)
{
#if 0
playlist_t *playlist;
/* find playlist */
if (!(playlist = vlc_object_find (vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD)))
{
}
/* start with closed state */
svlc_event_set_playback_state (thread->svlc, SVLC_PLAYBACK_CLOSED);
#endif
/* tell creating thread that we're ready */
vlc_thread_ready (thread);
while (!thread->b_die)
{
msleep (EVENT_THREAD_SLEEP);
}
#if 0
/* end with closed state */
svlc_event_set_playback_state (thread->svlc, SVLC_PLAYBACK_CLOSED);
vlc_object_release (playlist);
#endif
}
/* create and start event polling thread */
svlc_event_thread_t * svlc_event_create_thread (HSVLC svlc, vlc_t *vlc)
{
svlc_event_thread_t *thread;
if(!(thread = vlc_object_create (vlc, sizeof (svlc_event_thread_t))))
{
msg_Err (vlc, "out of memory");
return NULL;
}
thread->svlc = svlc;
/* start thread and wait till it is ready */
if (vlc_thread_create( thread, "svlc_event_thread", event_thread_func,
VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) != 0)
{
msg_Err (thread, "cannot spawn event polling thread");
vlc_object_destroy (thread);
return NULL;
}
#if 0
/* The object has been initialized, now attach it */
vlc_object_attach (thread, vlc);
#endif
return thread;
}
/* join and free event polling thread */
vlc_bool_t svlc_event_join_thread (svlc_event_thread_t *thread)
{
/* wait for thread completion */
thread->b_die = 1;
vlc_thread_join (thread);
/* free object */
vlc_object_destroy (thread);
return VLC_TRUE;
}
#endif
/*****************************************************************************
* Handlers for VLC variable changes
*****************************************************************************/
static int popup_callback (vlc_object_t *this, char const *cmd,
vlc_value_t oldval, vlc_value_t newval,
void *data)
{
HSVLC svlc = (HSVLC)data;
if (newval.b_bool != oldval.b_bool)
{
SVlcCbDisplayPopupData popup_data;
popup_data.show = newval.b_bool;
svlc->callback (svlc, SVLC_CB_DISPLAY_POPUP, (void*)&popup_data,
svlc->udata);
}
return VLC_SUCCESS;
}
static int key_pressed_callback (vlc_object_t *this, char const *cmd,
vlc_value_t oldval, vlc_value_t newval,
void *data)
{
HSVLC svlc = (HSVLC)data;
SVlcCbKeyPressedData key_data;
#ifdef DEBUG
vlc_t *vlc = (vlc_t *)this;
msg_Dbg (vlc, "cmd=%s old=%d new=%d", cmd,
oldval.i_int, newval.i_int);
#endif
key_data.key = newval.i_int;
svlc->callback (svlc, SVLC_CB_KEY_PRESSED, (void*)&key_data,
svlc->udata);
return VLC_SUCCESS;
}
static int intf_change_callback (vlc_object_t *this, char const *cmd,
vlc_value_t oldval, vlc_value_t newval,
void *data)
{
HSVLC svlc = (HSVLC)data;
input_thread_t *input = (input_thread_t *)this;
SVlcPlaybackState new_state;
#if 0
msg_Dbg (input, "cmd=%s old=%d new=%d", cmd,
oldval.i_int, newval.i_int);
#endif
/* check for state changes */
switch (input->i_state)
{
case INIT_S: new_state = SVLC_PLAYBACK_LOADING; break;
case PLAYING_S: new_state = SVLC_PLAYBACK_PLAYING; break;
case PAUSE_S: new_state = SVLC_PLAYBACK_PAUSED; break;
case END_S: new_state = SVLC_PLAYBACK_STOPPED; break;
default: new_state = svlc->playback_state; /* change nothing */
}
if(input->b_error)
new_state = SVLC_PLAYBACK_ERROR; /* implies SVLC_PLAYBACK_CLOSED */
/* if we go from loading to playing squeze an open in */
if (svlc->playback_state == SVLC_PLAYBACK_LOADING &&
new_state == SVLC_PLAYBACK_PLAYING)
svlc_event_set_playback_state (svlc, SVLC_PLAYBACK_OPEN);
svlc_event_set_playback_state (svlc, new_state);
/* currently stopping means closing as well */
if (new_state == SVLC_PLAYBACK_STOPPED)
svlc_event_set_playback_state (svlc, SVLC_PLAYBACK_CLOSED);
/* update position */
if (svlc->cb_events & SVLC_CB_POSITION_CHANGE &&
svlc->playback_state == SVLC_PLAYBACK_PLAYING)
{
vlc_value_t val;
SVlcCbPositionChangeData position_data;
var_Get (input, "position", &val);
position_data.position = val.f_float;
var_Get (input, "length", &val);
position_data.duration = val.i_time / 1000;
/*
msg_Dbg (input, "POSITION: %f", position_data.position);
*/
/* call back to user */
svlc->callback (svlc, SVLC_CB_POSITION_CHANGE, (void*)&position_data,
svlc->udata);
}
return VLC_SUCCESS;
}
/* we use this to hook the new input */
static int input_change_callback (vlc_object_t *this, char const *cmd,
vlc_value_t oldval, vlc_value_t newval,
void *data)
{
HSVLC svlc = (HSVLC)data;
playlist_t *playlist = (playlist_t *)this;
#ifdef DEBUG
msg_Dbg (playlist, "cmd=%s old=%d new=%d", cmd,
oldval.i_int, newval.i_int);
#endif
/* Clearly we are loading with a new input */
svlc_event_set_playback_state (svlc, SVLC_PLAYBACK_LOADING);
/* hook new input */
vlc_mutex_lock (&playlist->object_lock);
var_AddCallback (playlist->p_input, "intf-change",
intf_change_callback, (void*)svlc);
vlc_mutex_unlock (&playlist->object_lock);
return VLC_SUCCESS;
}
/*****************************************************************************
* Event registration
*****************************************************************************/
vlc_bool_t svlc_event_register_callbacks (HSVLC svlc, vlc_t *vlc)
{
input_thread_t *input;
playlist_t *playlist;
/* vlc events */
if (svlc->cb_events & SVLC_CB_KEY_PRESSED)
{
var_AddCallback (vlc, "key-pressed", key_pressed_callback,
(void*)svlc);
}
/* input events */
if ((input = vlc_object_find (vlc, VLC_OBJECT_INPUT, FIND_CHILD)))
{
vlc_object_release (input);
}
/* playlist events */
if ((playlist = vlc_object_find (vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD)))
{
if (svlc->cb_events & SVLC_CB_DISPLAY_POPUP)
var_AddCallback (playlist, "intf-popupmenu",
popup_callback, (void*)svlc);
/* we always want this to hook the input if neccessary */
var_AddCallback (playlist, "playlist-current",
input_change_callback, (void*)svlc);
vlc_object_release (playlist);
}
return VLC_TRUE;
}
vlc_bool_t svlc_event_unregister_callbacks (HSVLC svlc, vlc_t *vlc)
{
input_thread_t *input;
playlist_t *playlist;
/* vlc events */
if (svlc->cb_events & SVLC_CB_KEY_PRESSED)
{
var_DelCallback (vlc, "key-pressed", key_pressed_callback,
(void*)svlc);
}
/* input events */
if ((input = vlc_object_find (vlc, VLC_OBJECT_INPUT, FIND_CHILD)))
{
vlc_object_release (input);
}
/* playlist events */
if ((playlist = vlc_object_find (vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD)))
{
if (svlc->cb_events & SVLC_CB_DISPLAY_POPUP)
var_DelCallback (playlist, "intf-popupmenu",
popup_callback, (void*)svlc);
/* we always want this to hook the input if neccessary */
var_DelCallback (playlist, "playlist-current",
input_change_callback, (void*)svlc);
vlc_object_release (playlist);
}
return VLC_TRUE;
}
vlc_bool_t svlc_event_set_playback_state (HSVLC svlc,
SVlcPlaybackState new_state)
{
SVlcCbStateData state_data;
if (new_state == svlc->playback_state)
return VLC_FALSE;
state_data.old_state = svlc->playback_state;
state_data.new_state = new_state;
svlc->playback_state = new_state;
#ifdef DEBUG
log_state_change (svlc, state_data.old_state, state_data.new_state);
#endif
if (svlc->cb_events & SVLC_CB_STATE_CHANGE)
{
/* call back to user */
svlc->callback (svlc, SVLC_CB_STATE_CHANGE, (void*)&state_data,
svlc->udata);
}
return VLC_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -