⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svlc_interface.c

📁 Last change: 2008-02-03 This is the source code of KCeasy。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 * 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 + -