📄 svlc_interface.c
字号:
/*****************************************************************************
* svlc_interface.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 <aout_internal.h>
#include "svlc_interface.h"
#include "svlc_event.h"
#define VOUT_PLUGINS "directx,dummy"
#define AOUT_PLUGINS "directx,waveout,dummy"
#define VLC_PLUGIN_DIR "vlcplugins"
#define VLC_CONFIG_FILE "vlc.conf"
/******************************************************************************
* Some internal helper functions
*****************************************************************************/
/**
* This resides in libvcl.c but is not in the headers.
*/
vlc_t * vlc_current_object (int i_object);
static vlc_t * aquire_vlc (HSVLC svlc)
{
vlc_t *vlc;
if (!svlc)
return NULL;
if (!(vlc = vlc_current_object (svlc->vlc)))
return NULL;
return vlc;
}
static void release_vlc (vlc_t *vlc)
{
vlc_object_release (vlc);
}
/*****************************************************************************
* Instance management
*****************************************************************************/
/**
* Create simplevlc instance.
*
* @param verbosity >= 0 Logging verbosity.
* -1 Quiet, don't log anything.
*
* @return Handle to instance on success.
* NULL on error.
*/
static HSVLC SVLC_CC if_create (int verbosity)
{
SVlcInstance *svlc;
vlc_t *vlc;
int ret;
vlc_value_t val;
#ifdef DEBUG
char *ppsz_argv[] = { "vlc",
"--config=" VLC_CONFIG_FILE,
"--plugin-path=" VLC_PLUGIN_DIR,
"--vout=" VOUT_PLUGINS,
"--aout=" AOUT_PLUGINS,
"--no-plugins-cache",
"--intf=none",
"--fast-mutex",
"--win9x-cv-method=1" };
#else
char *ppsz_argv[] = { "vlc",
"--config=" VLC_CONFIG_FILE,
"--plugin-path=" VLC_PLUGIN_DIR,
"--vout=" VOUT_PLUGINS,
"--aout=" AOUT_PLUGINS,
"--no-plugins-cache",
"--intf=none" };
#endif
if ((svlc = malloc (sizeof (SVlcInstance))) == NULL)
return NULL;
svlc->callback = NULL;
svlc->cb_events = 0;
svlc->udata = NULL;
svlc->playback_state = SVLC_PLAYBACK_CLOSED;
svlc->saved_volume = -1;
if((svlc->vlc = VLC_Create()) < 0)
{
free (svlc);
return NULL;
}
if((ret = VLC_Init(svlc->vlc, sizeof(ppsz_argv)/sizeof(char*), ppsz_argv)) != VLC_SUCCESS)
{
VLC_Destroy (svlc->vlc);
free (svlc);
return NULL;
}
/* set verbosity */
val.i_int = verbosity;
VLC_VariableSet (svlc->vlc, "verbose", val);
/* add logger interface if verbosity not set to quiet */
if (verbosity >= 0)
{
VLC_AddIntf (svlc->vlc, "logger,none", VLC_FALSE, VLC_FALSE);
}
if (!(vlc = aquire_vlc (svlc)))
{
VLC_Destroy (svlc->vlc);
free (svlc);
return NULL;
}
/* create some vars so we start in a consistent state */
var_Create (vlc, "scale", VLC_VAR_BOOL);
val.b_bool = VLC_TRUE;
var_Set (vlc, "scale", val);
var_Create (vlc, "fullscreen", VLC_VAR_BOOL);
val.b_bool = VLC_FALSE;
var_Set (vlc, "fullscreen", val);
var_Create (vlc, "zoom", VLC_VAR_FLOAT);
val.f_float = 1.0;
var_Set (vlc, "zoom", val);
release_vlc (vlc);
return svlc;
}
/**
* Destroy simplevlc instance.
*/
static void SVLC_CC if_destroy (HSVLC svlc)
{
if (!svlc)
return;
/* Don't ask me why there are three functions */
VLC_Die (svlc->vlc);
VLC_CleanUp (svlc->vlc);
VLC_Destroy (svlc->vlc);
free (svlc);
}
/**
* Set callback function.
*
* @param callback The function that should be called.
* @param events The events you want to be notified about.
*
* @return 0 Success.
* -1 Error.
*/
static int SVLC_CC if_set_callback (HSVLC svlc, SVlcCallbackFunc callback, unsigned int events)
{
vlc_t *vlc;
if (!(vlc = aquire_vlc (svlc)))
return -1;
/* remove any previously registered vlc callbacks */
if (!svlc_event_unregister_callbacks (svlc, vlc))
{
release_vlc (vlc);
return -1;
}
svlc->callback = NULL;
svlc->cb_events = 0;
if (callback != NULL)
{
/* set new func and events */
svlc->callback = callback;
svlc->cb_events = events;
/* register vlc callbacks */
if (!svlc_event_register_callbacks (svlc, vlc))
{
release_vlc (vlc);
return -1;
}
}
release_vlc (vlc);
return 0;
}
/**
* Return static VLC version string.
*/
static char const * SVLC_CC if_get_vlc_version (void)
{
return VERSION_MESSAGE;
}
/**
* Retrieve user data.
*/
static void * SVLC_CC if_get_udata (HSVLC svlc)
{
if (!svlc)
return NULL;
return svlc->udata;
}
/**
* Attach user data.
*/
static void SVLC_CC if_set_udata (HSVLC svlc, void *udata)
{
if (!svlc)
return;
svlc->udata = udata;
}
/*****************************************************************************
* Video output
*****************************************************************************/
/**
* Set video output window.
*
* @param window Window for video output (HWND on windows).
*
* @return 0 Success.
* -1 Error.
*/
static int SVLC_CC if_set_window (HSVLC svlc, unsigned int window)
{
vlc_t *vlc;
vlc_value_t value;
if (!(vlc = aquire_vlc (svlc)))
return -1;
value.i_int = (int) (ptrdiff_t) (void *) window;
var_Set (vlc, "drawable", value);
release_vlc (vlc);
return 0;
}
/**
* Set visualization plugin used for audio playback.
*
* @param name Name of the visualization plugin, e.g. "goom". NULL removes
* anything previously set.
*
* @return 0 Success.
* -1 Error.
*/
static int SVLC_CC if_set_visualization (HSVLC svlc, const char *name)
{
vlc_t *vlc;
vlc_value_t value;
aout_instance_t *aout;
if (!(vlc = aquire_vlc (svlc)))
return -1;
if ((aout = vlc_object_find (vlc, VLC_OBJECT_AOUT, FIND_CHILD)) &&
var_Type (aout, "visual") != 0)
{
msg_Dbg (vlc, "Setting visualization '%s' directly with aout", name);
value.psz_string = (name != NULL) ? (char *)name : "";
var_Set (aout, "visual", value);
vlc_object_release (aout);
}
else
{
/* HACKHACK: Set filter directly in vlc object which is inherited by
* future aouts.
*
* FIXME: Does this really work?
*/
char *p;
/* Can happen because of the above ANDed if clause. */
if (aout)
vlc_object_release (aout);
if (var_Type (vlc, "audio-filter") == 0)
var_Create (vlc, "audio-filter", VLC_VAR_STRING);
var_Get (vlc, "audio-filter", &value);
if (!value.psz_string)
value.psz_string = strdup("");
if ((p = strstr (value.psz_string, name)))
{
/* remove if requested */
if (name == NULL)
{
char *rest = p + strlen(name) + ((p[strlen(name)] == ',') ? 1 : 0);
memmove (p, rest, strlen(rest) + 1);
var_Set (vlc, "audio-filter", value);
}
}
else
{
/* add if requested */
if (name != NULL)
{
char *tmp = value.psz_string;
asprintf (&value.psz_string,
(value.psz_string[0] != '\0') ? "%s,%s" : "%s%s",
value.psz_string, name);
free (tmp);
var_Set (vlc, "audio-filter", value);
}
}
free (value.psz_string);
}
release_vlc (vlc);
return 0;
}
/**
* Get fullscreen mode.
*
* @return 1 Fullscreen on.
* 0 Fullscreen off.
* -1 Error.
*/
static int SVLC_CC if_get_fullscreen (HSVLC svlc)
{
vlc_t *vlc;
vout_thread_t *vout;
playlist_t *playlist;
vlc_value_t val;
int ret = VLC_ENOVAR;
if (!(vlc = aquire_vlc (svlc)))
return -1;
if ((vout = vlc_object_find (vlc, VLC_OBJECT_VOUT, FIND_CHILD)))
{
ret = var_Get (vout, "fullscreen", &val);
vlc_object_release (vout);
}
else if ((playlist = vlc_object_find (vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD)))
{
ret = var_Get (playlist, "fullscreen", &val);
vlc_object_release (playlist);
}
if (ret != VLC_SUCCESS)
ret = var_Get (vlc, "fullscreen", &val);
release_vlc (vlc);
return (ret == VLC_SUCCESS) ? val.b_bool : -1;
}
/**
* Set fullscreen mode. This merely maximizes the output window on windows
* (probably other platforms too) so you need to set fitwindow to true and
* the window set with set_window must have no (non-maximized) parents.
*
* @param fullscreen 1 Switch fullscreen on
* 0 Switch fullscreen off
* -1 Toggle fullscreen
*
* @return 0 Success.
* -1 Error.
*/
static int SVLC_CC if_set_fullscreen (HSVLC svlc, int fullscreen)
{
vlc_t *vlc;
vout_thread_t *vout;
playlist_t *playlist;
vlc_value_t val;
int current;
if((current = if_get_fullscreen (svlc)) < 0)
return -1;
if (fullscreen == -1)
val.b_bool = (current == 0);
else if (current != fullscreen)
val.b_bool = (fullscreen != 0);
else
return 0; /* the specified state is already set */
if (!(vlc = aquire_vlc (svlc)))
return -1;
if ((vout = vlc_object_find (vlc, VLC_OBJECT_VOUT, FIND_CHILD)))
{
/* setting this negates the actual fullscreen while ignoring val */
var_Set (vout, "fullscreen", val);
vlc_object_release (vout);
}
if ((playlist = vlc_object_find (vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD)))
{
var_Set (playlist, "fullscreen", val);
vlc_object_release (playlist);
}
var_Set (vlc, "fullscreen", val);
release_vlc (vlc);
return 0;
}
/**
* Get fit to window mode.
*
* @return 1 Fitting on.
* 0 Fitting off.
* -1 Error.
*/
static int SVLC_CC if_get_fitwindow (HSVLC svlc)
{
vlc_t *vlc;
vout_thread_t *vout;
playlist_t *playlist;
vlc_value_t val;
int ret = VLC_ENOVAR;
if (!(vlc = aquire_vlc (svlc)))
return -1;
if ((vout = vlc_object_find (vlc, VLC_OBJECT_VOUT, FIND_CHILD)))
{
ret = var_Get (vout, "scale", &val);
vlc_object_release (vout);
}
else if ((playlist = vlc_object_find (vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD)))
{
ret = var_Get (playlist, "scale", &val);
vlc_object_release (playlist);
}
if (ret != VLC_SUCCESS)
ret = var_Get (vlc, "scale", &val);
release_vlc (vlc);
return (ret == VLC_SUCCESS) ? val.b_bool : -1;
}
/**
* Scale video output to match window size.
*
* @param fullscreen 1 Fit to window.
* 0 Don't fit to window.
* -1 Toggle fit.
*
* @return 0 Success.
* -1 Error.
*/
static int SVLC_CC if_set_fitwindow (HSVLC svlc, int fit)
{
vlc_t *vlc;
vout_thread_t *vout;
playlist_t *playlist;
vlc_value_t val;
int current;
if((current = if_get_fitwindow (svlc)) < 0)
return -1;
if (fit == -1)
val.b_bool = (current == 0);
else if (current != fit)
val.b_bool = (fit != 0);
else
return 0; /* the specified state is already set */
if (!(vlc = aquire_vlc (svlc)))
return -1;
if ((vout = vlc_object_find (vlc, VLC_OBJECT_VOUT, FIND_CHILD)))
{
var_Set (vout, "scale", val);
vlc_object_release (vout);
}
if ((playlist = vlc_object_find (vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD)))
{
var_Set (playlist, "scale", val);
vlc_object_release (playlist);
}
var_Set (vlc, "scale", val);
release_vlc (vlc);
return 0;
}
/**
* Get current zoom factor.
*
* @return >= 0 Current zoom factor.
* -1 Error.
*/
static float SVLC_CC if_get_zoom (HSVLC svlc)
{
vlc_t *vlc;
vout_thread_t *vout;
playlist_t *playlist;
vlc_value_t val;
int ret = VLC_SUCCESS;
if (!(vlc = aquire_vlc (svlc)))
return -1;
if ((vout = vlc_object_find (vlc, VLC_OBJECT_VOUT, FIND_CHILD)))
{
ret = var_Get (vout, "zoom", &val);
vlc_object_release (vout);
}
else if ((playlist = vlc_object_find (vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD)))
{
ret = var_Get (playlist, "zoom", &val);
vlc_object_release (playlist);
}
if (ret != VLC_SUCCESS)
ret = var_Get (vlc, "zoom", &val);
release_vlc (vlc);
return (ret == VLC_SUCCESS) ? val.f_float : -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -