X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=lib%2Fmedia_player.c;h=daa9def3dadf6bdd3cea84e020e58513356ceb8c;hb=3ed3b149558322dba122e924164a958bde55b04d;hp=02c157096b501957c1a582a92d52736e51b5d103;hpb=ace5352f6c5aafc22d71c1af1cc0752b32a0f6de;p=vlc diff --git a/lib/media_player.c b/lib/media_player.c index 02c157096b..daa9def3da 100644 --- a/lib/media_player.c +++ b/lib/media_player.c @@ -1,23 +1,23 @@ /***************************************************************************** * media_player.c: Libvlc API Media Instance management functions ***************************************************************************** - * Copyright (C) 2005-2011 the VideoLAN team + * Copyright (C) 2005-2011 VLC authors and VideoLAN * * Authors: Clément Stenac * - * 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 + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser 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. + * You should have received a copy of the GNU Lesser 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 @@ -33,28 +33,13 @@ #include #include #include +#include #include #include "libvlc_internal.h" #include "media_internal.h" // libvlc_media_set_state() #include "media_player_internal.h" -/* - * mapping of libvlc_navigate_mode_t to vlc_action_t - */ -static const vlc_action_t libvlc_navigate_to_action[] = -{ - ACTIONID_NAV_ACTIVATE, - ACTIONID_NAV_UP, - ACTIONID_NAV_DOWN, - ACTIONID_NAV_LEFT, - ACTIONID_NAV_RIGHT -}; - -static const uint32_t libvlc_navigate_to_action_size = \ - sizeof( libvlc_navigate_to_action ) / sizeof( libvlc_navigate_to_action[0] ); - - static int input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd, vlc_value_t oldval, vlc_value_t newval, @@ -64,6 +49,10 @@ input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd, 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 ); @@ -132,6 +121,8 @@ static void release_input_thread( libvlc_media_player_t *p_mi, bool b_input_abor 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 ); @@ -226,6 +217,24 @@ input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd, 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, @@ -357,13 +366,6 @@ static int snapshot_was_taken(vlc_object_t *p_this, char const *psz_cmd, return VLC_SUCCESS; } -static input_thread_t *find_input (vlc_object_t *obj) -{ - libvlc_media_player_t *mp = (libvlc_media_player_t *)obj; - - return libvlc_get_input_thread (mp); -} - /* */ static void libvlc_media_player_destroy( libvlc_media_player_t * ); @@ -413,7 +415,7 @@ libvlc_media_player_new( libvlc_instance_t *instance ) 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, "drawable-xid", VLC_VAR_INTEGER); -#ifdef WIN32 +#if defined (_WIN32) || defined (__OS2__) var_Create (mp, "drawable-hwnd", VLC_VAR_INTEGER); #endif #ifdef __APPLE__ @@ -465,9 +467,8 @@ libvlc_media_player_new( libvlc_instance_t *instance ) /* Audio */ var_Create (mp, "aout", VLC_VAR_STRING | VLC_VAR_DOINHERIT); var_Create (mp, "mute", VLC_VAR_BOOL); - var_Create (mp, "volume", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); - var_Create (mp, "find-input-callback", VLC_VAR_ADDRESS); - var_SetAddress (mp, "find-input-callback", find_input); + var_Create (mp, "volume", VLC_VAR_FLOAT); + var_Create (mp, "corks", VLC_VAR_INTEGER); var_Create (mp, "amem-data", VLC_VAR_ADDRESS); var_Create (mp, "amem-setup", VLC_VAR_ADDRESS); var_Create (mp, "amem-cleanup", VLC_VAR_ADDRESS); @@ -481,16 +482,31 @@ libvlc_media_player_new( libvlc_instance_t *instance ) 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-bands", VLC_VAR_STRING); + mp->p_md = NULL; mp->state = libvlc_NothingSpecial; mp->p_libvlc_instance = instance; mp->input.p_thread = NULL; - mp->input.p_resource = NULL; + mp->input.p_resource = input_resource_New(VLC_OBJECT(mp)); + if (unlikely(mp->input.p_resource == NULL)) + { + vlc_object_release(mp); + return NULL; + } vlc_mutex_init (&mp->input.lock); mp->i_refcount = 1; mp->p_event_manager = libvlc_event_manager_new(mp, instance); if (unlikely(mp->p_event_manager == NULL)) { + input_resource_Release(mp->input.p_resource); vlc_object_release(mp); return NULL; } @@ -515,6 +531,7 @@ libvlc_media_player_new( libvlc_instance_t *instance ) register_event(mp, PausableChanged); register_event(mp, Vout); + register_event(mp, ScrambledChanged); /* Snapshot initialization */ register_event(mp, SnapshotTaken); @@ -568,12 +585,8 @@ static void libvlc_media_player_destroy( libvlc_media_player_t *p_mi ) /* No need for lock_input() because no other threads knows us anymore */ if( p_mi->input.p_thread ) release_input_thread(p_mi, true); - if( p_mi->input.p_resource ) - { - input_resource_Terminate( p_mi->input.p_resource ); - input_resource_Release( p_mi->input.p_resource ); - p_mi->input.p_resource = NULL; - } + input_resource_Terminate( p_mi->input.p_resource ); + input_resource_Release( p_mi->input.p_resource ); vlc_mutex_destroy( &p_mi->input.lock ); libvlc_event_manager_release( p_mi->p_event_manager ); @@ -717,8 +730,6 @@ int libvlc_media_player_play( libvlc_media_player_t *p_mi ) return -1; } - if( !p_mi->input.p_resource ) - p_mi->input.p_resource = input_resource_New( VLC_OBJECT( p_mi ) ); p_input_thread = input_Create( p_mi, p_mi->p_md->p_input_item, NULL, p_mi->input.p_resource ); unlock(p_mi); @@ -731,6 +742,7 @@ int libvlc_media_player_play( libvlc_media_player_t *p_mi ) 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 ); if( input_Start( p_input_thread ) ) @@ -738,6 +750,7 @@ int libvlc_media_player_play( libvlc_media_player_t *p_mi ) unlock_input(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" ); @@ -818,8 +831,7 @@ void libvlc_media_player_stop( libvlc_media_player_t *p_mi ) libvlc_event_send( p_mi->p_event_manager, &event ); } - if( p_mi->input.p_resource != NULL ) - input_resource_Terminate( p_mi->input.p_resource ); + input_resource_Terminate( p_mi->input.p_resource ); unlock_input(p_mi); } @@ -935,7 +947,7 @@ void libvlc_media_player_set_hwnd( libvlc_media_player_t *p_mi, void *drawable ) { assert (p_mi != NULL); -#ifdef WIN32 +#if defined (_WIN32) || defined (__OS2__) var_SetString (p_mi, "window", (drawable != NULL) ? "embed-hwnd,any" : ""); var_SetInteger (p_mi, "drawable-hwnd", (uintptr_t)drawable); @@ -950,7 +962,7 @@ void libvlc_media_player_set_hwnd( libvlc_media_player_t *p_mi, void *libvlc_media_player_get_hwnd( libvlc_media_player_t *p_mi ) { assert (p_mi != NULL); -#ifdef WIN32 +#if defined (_WIN32) || defined (__OS2__) return (void *)(uintptr_t)var_GetInteger (p_mi, "drawable-hwnd"); #else return NULL; @@ -1239,7 +1251,7 @@ int libvlc_media_player_will_play( libvlc_media_player_t *p_mi ) if ( !p_input_thread ) return false; - b_will_play = !p_input_thread->b_die && !p_input_thread->b_dead; + b_will_play = !p_input_thread->b_dead; vlc_object_release( p_input_thread ); return b_will_play; @@ -1247,12 +1259,6 @@ int libvlc_media_player_will_play( 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 ); @@ -1293,19 +1299,21 @@ int libvlc_media_player_is_seekable( libvlc_media_player_t *p_mi ) void libvlc_media_player_navigate( libvlc_media_player_t* p_mi, unsigned navigate ) { - input_thread_t *p_input_thread; + static const vlc_action_t map[] = + { + INPUT_NAV_ACTIVATE, INPUT_NAV_UP, INPUT_NAV_DOWN, + INPUT_NAV_LEFT, INPUT_NAV_RIGHT, + }; - if ( navigate > libvlc_navigate_to_action_size) + if( navigate >= sizeof(map) / sizeof(map[0]) ) return; - p_input_thread = libvlc_get_input_thread ( p_mi ); - if ( !p_input_thread ) + input_thread_t *p_input = libvlc_get_input_thread ( p_mi ); + if ( p_input == NULL ) return; - var_SetInteger( p_mi->p_libvlc_instance->p_libvlc_int, - "key-action", libvlc_navigate_to_action[navigate] ); - - vlc_object_release( p_input_thread ); + input_Control( p_input, map[navigate], NULL ); + vlc_object_release( p_input ); } /* internal function, used by audio, video */ @@ -1344,7 +1352,7 @@ libvlc_track_description_t * malloc( sizeof( libvlc_track_description_t ) ); if ( !p_actual ) { - libvlc_track_description_release( p_track_description ); + libvlc_track_description_list_release( p_track_description ); libvlc_printerr( "Not enough memory" ); goto end; } @@ -1365,7 +1373,13 @@ end: return p_track_description; } +// Deprecated alias for libvlc_track_description_list_release void libvlc_track_description_release( libvlc_track_description_t *p_td ) +{ + libvlc_track_description_list_release( p_td ); +} + +void libvlc_track_description_list_release( libvlc_track_description_t *p_td ) { libvlc_track_description_t *p_actual, *p_before; p_actual = p_td; @@ -1393,6 +1407,20 @@ int libvlc_media_player_can_pause( libvlc_media_player_t *p_mi ) 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 ); @@ -1402,3 +1430,77 @@ void libvlc_media_player_next_frame( libvlc_media_player_t *p_mi ) vlc_object_release( p_input_thread ); } } + +void libvlc_media_player_set_video_title_display( libvlc_media_player_t *p_mi, libvlc_position_t position, unsigned timeout ) +{ + if ( position != libvlc_position_disable ) + { + var_SetBool( p_mi, "video-title-show", true ); + var_SetInteger( p_mi, "video-title-position", 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 ) +{ + float f_preamp; + char *psz_bands; + + if ( p_equalizer ) + { + f_preamp = p_equalizer->f_preamp; + + psz_bands = malloc( EQZ_BANDS_MAX * EQZ_BAND_VALUE_SIZE + 1 ); + if ( unlikely( psz_bands == NULL ) ) + return -1; + + char *p = psz_bands; + int c; + for ( int i = 0; i < EQZ_BANDS_MAX; i++ ) + { + c = snprintf( p, EQZ_BAND_VALUE_SIZE + 1, " %.07f", p_equalizer->f_amp[i] ); + if ( unlikely( c >= EQZ_BAND_VALUE_SIZE + 1 ) ) + { + free( psz_bands ); + return -1; + } + + p += c; + } + } + else + { + f_preamp = 0.f; + psz_bands = NULL; + } + + var_SetFloat( p_mi, "equalizer-preamp", f_preamp ); + var_SetString( p_mi, "equalizer-bands", psz_bands ); + + audio_output_t *p_aout = input_resource_HoldAout( p_mi->input.p_resource ); + if ( p_aout ) + { + var_SetFloat( p_aout, "equalizer-preamp", f_preamp ); + var_SetString( p_aout, "equalizer-bands", psz_bands ); + + vlc_object_release( p_aout ); + } + + free( psz_bands ); + return 0; +}