#include <vlc_demux.h>
#include <vlc_input.h>
#include <vlc_vout.h>
+#include <vlc_aout.h>
#include <vlc_keys.h>
#include "libvlc_internal.h"
vlc_value_t oldval, vlc_value_t newval,
void * p_userdata );
static int
+input_scrambled_changed( vlc_object_t * p_this, char const * psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval,
+ void * p_userdata );
+static int
input_event_changed( vlc_object_t * p_this, char const * psz_cmd,
vlc_value_t oldval, vlc_value_t newval,
void * p_userdata );
+static int
+input_es_changed( vlc_object_t * p_this, char const * psz_cmd,
+ int action, vlc_value_t *p_val,
+ void *p_userdata);
+
+static int
+input_es_selected( vlc_object_t * p_this, char const * psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval,
+ void * p_userdata );
+
+static void
+add_es_callbacks( input_thread_t *p_input_thread, libvlc_media_player_t *p_mi );
+
+static void
+del_es_callbacks( input_thread_t *p_input_thread, libvlc_media_player_t *p_mi );
+
static int
snapshot_was_taken( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void *p_data );
* Object lock is NOT held.
* Input lock is held or instance is being destroyed.
*/
-static void release_input_thread( libvlc_media_player_t *p_mi, bool b_input_abort )
+static void release_input_thread( libvlc_media_player_t *p_mi )
{
assert( p_mi );
input_seekable_changed, p_mi );
var_DelCallback( p_input_thread, "can-pause",
input_pausable_changed, p_mi );
+ var_DelCallback( p_input_thread, "program-scrambled",
+ input_scrambled_changed, p_mi );
var_DelCallback( p_input_thread, "intf-event",
input_event_changed, p_mi );
+ del_es_callbacks( p_input_thread, p_mi );
/* We owned this one */
- input_Stop( p_input_thread, b_input_abort );
+ input_Stop( p_input_thread );
input_Close( p_input_thread );
}
return VLC_SUCCESS;
}
+static int
+input_scrambled_changed( vlc_object_t * p_this, char const * psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval,
+ void * p_userdata )
+{
+ VLC_UNUSED(oldval);
+ VLC_UNUSED(p_this);
+ VLC_UNUSED(psz_cmd);
+ libvlc_media_player_t * p_mi = p_userdata;
+ libvlc_event_t event;
+
+ event.type = libvlc_MediaPlayerScrambledChanged;
+ event.u.media_player_scrambled_changed.new_scrambled = newval.b_bool;
+
+ libvlc_event_send( p_mi->p_event_manager, &event );
+ return VLC_SUCCESS;
+}
+
static int
input_event_changed( vlc_object_t * p_this, char const * psz_cmd,
vlc_value_t oldval, vlc_value_t newval,
set_state( p_mi, libvlc_state, false );
libvlc_event_send( p_mi->p_event_manager, &event );
}
- else if( newval.i_int == INPUT_EVENT_ABORT )
+ else if( newval.i_int == INPUT_EVENT_DEAD )
{
- libvlc_state_t libvlc_state = libvlc_Stopped;
+ libvlc_state_t libvlc_state = libvlc_Ended;
event.type = libvlc_MediaPlayerStopped;
set_state( p_mi, libvlc_state, false );
return VLC_SUCCESS;
}
+static int track_type_from_name(const char *psz_name)
+{
+ if( !strcmp( psz_name, "video-es" ) )
+ return libvlc_track_video;
+ else if( !strcmp( psz_name, "audio-es" ) )
+ return libvlc_track_audio;
+ else if( !strcmp( psz_name, "spu-es" ) )
+ return libvlc_track_text;
+ else
+ return libvlc_track_unknown;
+}
+
+static int input_es_changed( vlc_object_t *p_this,
+ char const *psz_cmd,
+ int action,
+ vlc_value_t *p_val,
+ void *p_userdata )
+{
+ VLC_UNUSED(p_this);
+ libvlc_media_player_t *mp = p_userdata;
+ libvlc_event_t event;
+
+ /* Ignore the "Disable" element */
+ if (p_val && p_val->i_int < 0)
+ return VLC_EGENERIC;
+
+ switch (action)
+ {
+ case VLC_VAR_ADDCHOICE:
+ event.type = libvlc_MediaPlayerESAdded;
+ break;
+ case VLC_VAR_DELCHOICE:
+ case VLC_VAR_CLEARCHOICES:
+ event.type = libvlc_MediaPlayerESDeleted;
+ break;
+ default:
+ return VLC_EGENERIC;
+ }
+
+ event.u.media_player_es_changed.i_type = track_type_from_name(psz_cmd);
+
+ int i_id;
+ if (action != VLC_VAR_CLEARCHOICES)
+ {
+ if (!p_val)
+ return VLC_EGENERIC;
+ i_id = p_val->i_int;
+ }
+ else
+ {
+ /* -1 means all ES tracks of this type were deleted. */
+ i_id = -1;
+ }
+ event.u.media_player_es_changed.i_id = i_id;
+
+ libvlc_event_send(mp->p_event_manager, &event);
+
+ return VLC_SUCCESS;
+}
+
+static int
+input_es_selected( vlc_object_t * p_this, char const * psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval,
+ void * p_userdata )
+{
+ VLC_UNUSED(p_this);
+ VLC_UNUSED(oldval);
+ libvlc_media_player_t *mp = p_userdata;
+ libvlc_event_t event;
+
+ event.type = libvlc_MediaPlayerESSelected;
+ event.u.media_player_es_changed.i_type = track_type_from_name(psz_cmd);
+ event.u.media_player_es_changed.i_id = newval.i_int;
+
+ libvlc_event_send(mp->p_event_manager, &event);
+
+ return VLC_SUCCESS;
+}
+
/**************************************************************************
* Snapshot Taken Event.
*
return VLC_SUCCESS;
}
-/* */
-static void libvlc_media_player_destroy( libvlc_media_player_t * );
-
-
/**************************************************************************
* Create a Media Instance object.
*
var_Create (mp, "vmem-width", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
var_Create (mp, "vmem-height", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
var_Create (mp, "vmem-pitch", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
+ var_Create (mp, "avcodec-hw", VLC_VAR_STRING);
var_Create (mp, "drawable-xid", VLC_VAR_INTEGER);
#if defined (_WIN32) || defined (__OS2__)
var_Create (mp, "drawable-hwnd", VLC_VAR_INTEGER);
var_SetBool (mp, "mouse-events", true);
var_Create (mp, "fullscreen", VLC_VAR_BOOL);
- var_Create (mp, "autoscale", VLC_VAR_BOOL);
- var_SetBool (mp, "autoscale", true);
- var_Create (mp, "scale", VLC_VAR_FLOAT);
- var_SetFloat (mp, "scale", 1.);
+ var_Create (mp, "autoscale", VLC_VAR_BOOL | VLC_VAR_DOINHERIT);
+ var_Create (mp, "zoom", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);
var_Create (mp, "aspect-ratio", VLC_VAR_STRING);
var_Create (mp, "crop", VLC_VAR_STRING);
var_Create (mp, "deinterlace", VLC_VAR_INTEGER);
var_Create (mp, "deinterlace-mode", VLC_VAR_STRING);
var_Create (mp, "vbi-page", VLC_VAR_INTEGER);
+ var_SetInteger (mp, "vbi-page", 100);
var_Create (mp, "marq-marquee", VLC_VAR_STRING);
var_Create (mp, "marq-color", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
var_Create (mp, "contrast", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);
var_Create (mp, "brightness", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);
- var_Create (mp, "hue", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
+ var_Create (mp, "hue", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);
var_Create (mp, "saturation", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);
var_Create (mp, "gamma", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);
var_Create (mp, "mute", VLC_VAR_BOOL);
var_Create (mp, "volume", VLC_VAR_FLOAT);
var_Create (mp, "corks", VLC_VAR_INTEGER);
+ var_Create (mp, "audio-filter", VLC_VAR_STRING);
var_Create (mp, "amem-data", VLC_VAR_ADDRESS);
var_Create (mp, "amem-setup", VLC_VAR_ADDRESS);
var_Create (mp, "amem-cleanup", VLC_VAR_ADDRESS);
var_Create (mp, "amem-rate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
var_Create (mp, "amem-channels", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
+ /* Video Title */
+ var_Create (mp, "video-title-show", VLC_VAR_BOOL);
+ var_Create (mp, "video-title-position", VLC_VAR_INTEGER);
+ var_Create (mp, "video-title-timeout", VLC_VAR_INTEGER);
+
+ /* Equalizer */
+ var_Create (mp, "equalizer-preamp", VLC_VAR_FLOAT);
+ var_Create (mp, "equalizer-vlcfreqs", VLC_VAR_BOOL);
+ var_Create (mp, "equalizer-bands", VLC_VAR_STRING);
+
mp->p_md = NULL;
mp->state = libvlc_NothingSpecial;
mp->p_libvlc_instance = instance;
vlc_object_release(mp);
return NULL;
}
+ audio_output_t *aout = input_resource_GetAout(mp->input.p_resource);
+ if( aout != NULL )
+ input_resource_PutAout(mp->input.p_resource, aout);
+
vlc_mutex_init (&mp->input.lock);
mp->i_refcount = 1;
mp->p_event_manager = libvlc_event_manager_new(mp, instance);
register_event(mp, PausableChanged);
register_event(mp, Vout);
+ register_event(mp, ScrambledChanged);
+ register_event(mp, ESAdded);
+ register_event(mp, ESDeleted);
+ register_event(mp, ESSelected);
/* Snapshot initialization */
register_event(mp, SnapshotTaken);
/* No need for lock_input() because no other threads knows us anymore */
if( p_mi->input.p_thread )
- release_input_thread(p_mi, true);
+ release_input_thread(p_mi);
input_resource_Terminate( p_mi->input.p_resource );
input_resource_Release( p_mi->input.p_resource );
vlc_mutex_destroy( &p_mi->input.lock );
{
lock_input(p_mi);
- /* FIXME I am not sure if it is a user request or on die(eof/error)
- * request here */
- release_input_thread( p_mi,
- p_mi->input.p_thread &&
- !p_mi->input.p_thread->b_eof &&
- !p_mi->input.p_thread->b_error );
+ release_input_thread( p_mi );
lock( p_mi );
set_state( p_mi, libvlc_NothingSpecial, true );
{
libvlc_media_t *p_m;
- lock(p_mi);
+ lock( p_mi );
p_m = p_mi->p_md;
if( p_m )
- libvlc_media_retain( p_mi->p_md );
- unlock(p_mi);
- return p_mi->p_md;
+ libvlc_media_retain( p_m );
+ unlock( p_mi );
+
+ return p_m;
}
/**************************************************************************
return p_mi->p_event_manager;
}
+static void add_es_callbacks( input_thread_t *p_input_thread, libvlc_media_player_t *p_mi )
+{
+ var_AddListCallback( p_input_thread, "video-es", input_es_changed, p_mi );
+ var_AddListCallback( p_input_thread, "audio-es", input_es_changed, p_mi );
+ var_AddListCallback( p_input_thread, "spu-es", input_es_changed, p_mi );
+ var_AddCallback( p_input_thread, "video-es", input_es_selected, p_mi );
+ var_AddCallback( p_input_thread, "audio-es", input_es_selected, p_mi );
+ var_AddCallback( p_input_thread, "spu-es", input_es_selected, p_mi );
+}
+
+static void del_es_callbacks( input_thread_t *p_input_thread, libvlc_media_player_t *p_mi )
+{
+ var_DelListCallback( p_input_thread, "video-es", input_es_changed, p_mi );
+ var_DelListCallback( p_input_thread, "audio-es", input_es_changed, p_mi );
+ var_DelListCallback( p_input_thread, "spu-es", input_es_changed, p_mi );
+ var_DelCallback( p_input_thread, "video-es", input_es_selected, p_mi );
+ var_DelCallback( p_input_thread, "audio-es", input_es_selected, p_mi );
+ var_DelCallback( p_input_thread, "spu-es", input_es_selected, p_mi );
+}
+
/**************************************************************************
* Tell media player to start playing.
**************************************************************************/
var_AddCallback( p_input_thread, "can-seek", input_seekable_changed, p_mi );
var_AddCallback( p_input_thread, "can-pause", input_pausable_changed, p_mi );
+ var_AddCallback( p_input_thread, "program-scrambled", input_scrambled_changed, p_mi );
var_AddCallback( p_input_thread, "intf-event", input_event_changed, p_mi );
+ add_es_callbacks( p_input_thread, p_mi );
if( input_Start( p_input_thread ) )
{
unlock_input(p_mi);
+ del_es_callbacks( p_input_thread, p_mi );
var_DelCallback( p_input_thread, "intf-event", input_event_changed, p_mi );
var_DelCallback( p_input_thread, "can-pause", input_pausable_changed, p_mi );
+ var_DelCallback( p_input_thread, "program-scrambled", input_scrambled_changed, p_mi );
var_DelCallback( p_input_thread, "can-seek", input_seekable_changed, p_mi );
vlc_object_release( p_input_thread );
libvlc_printerr( "Input initialization failure" );
if( libvlc_media_player_can_pause( p_mi ) )
input_Control( p_input_thread, INPUT_SET_STATE, PAUSE_S );
else
- libvlc_media_player_stop( p_mi );
+ input_Stop( p_input_thread );
}
}
else
**************************************************************************/
void libvlc_media_player_stop( libvlc_media_player_t *p_mi )
{
- libvlc_state_t state = libvlc_media_player_get_state( p_mi );
-
lock_input(p_mi);
- release_input_thread( p_mi, true ); /* This will stop the input thread */
+ release_input_thread( p_mi ); /* This will stop the input thread */
/* Force to go to stopped state, in case we were in Ended, or Error
* state. */
- if( state != libvlc_Stopped )
+ if( p_mi->state != libvlc_Stopped )
{
set_state( p_mi, libvlc_Stopped, false );
var_SetAddress( mp, "vmem-display", display_cb );
var_SetAddress( mp, "vmem-data", opaque );
var_SetString( mp, "vout", "vmem" );
+ var_SetString( mp, "avcodec-hw", "none" );
}
void libvlc_video_set_format_callbacks( libvlc_media_player_t *mp,
{
assert (p_mi != NULL);
+ var_SetString (p_mi, "avcodec-hw", "");
var_SetString (p_mi, "vout", drawable ? "xid" : "any");
var_SetString (p_mi, "window", drawable ? "embed-xid,any" : "any");
var_SetInteger (p_mi, "drawable-xid", drawable);
var_SetAddress( mp, "amem-drain", drain_cb );
var_SetAddress( mp, "amem-data", opaque );
var_SetString( mp, "aout", "amem,none" );
+
+ input_resource_ResetAout(mp->input.p_resource);
}
void libvlc_audio_set_volume_callback( libvlc_media_player_t *mp,
libvlc_audio_set_volume_cb cb )
{
var_SetAddress( mp, "amem-set-volume", cb );
+
+ input_resource_ResetAout(mp->input.p_resource);
}
void libvlc_audio_set_format_callbacks( libvlc_media_player_t *mp,
{
var_SetAddress( mp, "amem-setup", setup );
var_SetAddress( mp, "amem-cleanup", cleanup );
+
+ input_resource_ResetAout(mp->input.p_resource);
}
void libvlc_audio_set_format( libvlc_media_player_t *mp, const char *format,
var_SetString( mp, "amem-format", format );
var_SetInteger( mp, "amem-rate", rate );
var_SetInteger( mp, "amem-channels", channels );
+
+ input_resource_ResetAout(mp->input.p_resource);
}
if( !p_input_thread )
return -1;
- var_Change( p_input_thread, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
+ int i_ret = var_Change( p_input_thread, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
vlc_object_release( p_input_thread );
- return val.i_int;
+ return i_ret == VLC_SUCCESS ? val.i_int : -1;
}
int libvlc_media_player_get_chapter_count_for_title(
vlc_object_release( p_input_thread );
return -1;
}
- var_Change( p_input_thread, psz_name, VLC_VAR_CHOICESCOUNT, &val, NULL );
+ int i_ret = var_Change( p_input_thread, psz_name, VLC_VAR_CHOICESCOUNT, &val, NULL );
vlc_object_release( p_input_thread );
free( psz_name );
- return val.i_int;
+ return i_ret == VLC_SUCCESS ? val.i_int : -1;
}
void libvlc_media_player_set_title( libvlc_media_player_t *p_mi,
if( !p_input_thread )
return -1;
- var_Change( p_input_thread, "title", VLC_VAR_CHOICESCOUNT, &val, NULL );
+ int i_ret = var_Change( p_input_thread, "title", VLC_VAR_CHOICESCOUNT, &val, NULL );
vlc_object_release( p_input_thread );
- return val.i_int;
+ return i_ret == VLC_SUCCESS ? val.i_int : -1;
}
void libvlc_media_player_next_chapter( libvlc_media_player_t *p_mi )
int libvlc_media_player_set_rate( libvlc_media_player_t *p_mi, float rate )
{
- if (rate < 0.)
- {
- libvlc_printerr ("Playing backward not supported");
- return -1;
- }
-
var_SetFloat (p_mi, "rate", rate);
input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi );
return NULL;
vlc_value_t val_list, text_list;
- var_Change( p_input, psz_variable, VLC_VAR_GETLIST, &val_list, &text_list);
+ int i_ret = var_Change( p_input, psz_variable, VLC_VAR_GETCHOICES, &val_list, &text_list );
+ if( i_ret != VLC_SUCCESS )
+ return NULL;
/* no tracks */
if( val_list.p_list->i_count <= 0 )
return b_can_pause;
}
+int libvlc_media_player_program_scrambled( libvlc_media_player_t *p_mi )
+{
+ input_thread_t *p_input_thread;
+ bool b_program_scrambled;
+
+ p_input_thread = libvlc_get_input_thread ( p_mi );
+ if ( !p_input_thread )
+ return false;
+ b_program_scrambled = var_GetBool( p_input_thread, "program-scrambled" );
+ vlc_object_release( p_input_thread );
+
+ return b_program_scrambled;
+}
+
void libvlc_media_player_next_frame( libvlc_media_player_t *p_mi )
{
input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi );
vlc_object_release( p_input_thread );
}
}
+
+/**
+ * Private lookup table to get subpicture alignment flag values corresponding
+ * to a libvlc_position_t enumerated value.
+ */
+static const unsigned char position_subpicture_alignment[] = {
+ [libvlc_position_center] = 0,
+ [libvlc_position_left] = SUBPICTURE_ALIGN_LEFT,
+ [libvlc_position_right] = SUBPICTURE_ALIGN_RIGHT,
+ [libvlc_position_top] = SUBPICTURE_ALIGN_TOP,
+ [libvlc_position_top_left] = SUBPICTURE_ALIGN_TOP | SUBPICTURE_ALIGN_LEFT,
+ [libvlc_position_top_right] = SUBPICTURE_ALIGN_TOP | SUBPICTURE_ALIGN_RIGHT,
+ [libvlc_position_bottom] = SUBPICTURE_ALIGN_BOTTOM,
+ [libvlc_position_bottom_left] = SUBPICTURE_ALIGN_BOTTOM | SUBPICTURE_ALIGN_LEFT,
+ [libvlc_position_bottom_right] = SUBPICTURE_ALIGN_BOTTOM | SUBPICTURE_ALIGN_RIGHT
+};
+
+void libvlc_media_player_set_video_title_display( libvlc_media_player_t *p_mi, libvlc_position_t position, unsigned timeout )
+{
+ assert( position >= libvlc_position_disable && position <= libvlc_position_bottom_right );
+
+ if ( position != libvlc_position_disable )
+ {
+ var_SetBool( p_mi, "video-title-show", true );
+ var_SetInteger( p_mi, "video-title-position", position_subpicture_alignment[position] );
+ var_SetInteger( p_mi, "video-title-timeout", timeout );
+ }
+ else
+ {
+ var_SetBool( p_mi, "video-title-show", false );
+ }
+}
+
+/**
+ * Maximum size of a formatted equalizer amplification band frequency value.
+ *
+ * The allowed value range is supposed to be constrained from -20.0 to 20.0.
+ *
+ * The format string " %.07f" with a minimum value of "-20" gives a maximum
+ * string length of e.g. " -19.1234567", i.e. 12 bytes (not including the null
+ * terminator).
+ */
+#define EQZ_BAND_VALUE_SIZE 12
+
+int libvlc_media_player_set_equalizer( libvlc_media_player_t *p_mi, libvlc_equalizer_t *p_equalizer )
+{
+ char bands[EQZ_BANDS_MAX * EQZ_BAND_VALUE_SIZE + 1];
+
+ if( p_equalizer != NULL )
+ {
+ for( unsigned i = 0, c = 0; i < EQZ_BANDS_MAX; i++ )
+ {
+ c += snprintf( bands + c, sizeof(bands) - c, " %.07f",
+ p_equalizer->f_amp[i] );
+ if( unlikely(c >= sizeof(bands)) )
+ return -1;
+ }
+
+ var_SetFloat( p_mi, "equalizer-preamp", p_equalizer->f_preamp );
+ var_SetString( p_mi, "equalizer-bands", bands );
+ }
+ var_SetString( p_mi, "audio-filter", p_equalizer ? "equalizer" : "" );
+
+ audio_output_t *p_aout = input_resource_HoldAout( p_mi->input.p_resource );
+ if( p_aout != NULL )
+ {
+ if( p_equalizer != NULL )
+ {
+ var_SetFloat( p_aout, "equalizer-preamp", p_equalizer->f_preamp );
+ var_SetString( p_aout, "equalizer-bands", bands );
+ }
+
+ var_SetString( p_aout, "audio-filter", p_equalizer ? "equalizer" : "" );
+ vlc_object_release( p_aout );
+ }
+
+ return 0;
+}