X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcontrol%2Fhotkeys.c;h=d1a898f8bf370f274c0f6d7043a244fe4c12d7bf;hb=5adb3308b8f818c6175c49aa91c9617c9d85b70c;hp=4547316d56d635d9fe910f9e396c23173ceefe23;hpb=ddfbadf34563e74e62f55fc7ee0a27118126e207;p=vlc diff --git a/modules/control/hotkeys.c b/modules/control/hotkeys.c index 4547316d56..d1a898f8bf 100644 --- a/modules/control/hotkeys.c +++ b/modules/control/hotkeys.c @@ -48,6 +48,13 @@ struct intf_sys_t { vout_thread_t *p_last_vout; int slider_chan; + + /*subtitle_delaybookmarks: placeholder for storing subtitle sync timestamps*/ + struct + { + int64_t i_time_subtitle; + int64_t i_time_audio; + } subtitle_delaybookmarks; }; /***************************************************************************** @@ -101,6 +108,8 @@ static int Open( vlc_object_t *p_this ) p_intf->p_sys = p_sys; p_sys->p_last_vout = NULL; + p_sys->subtitle_delaybookmarks.i_time_audio = 0; + p_sys->subtitle_delaybookmarks.i_time_subtitle = 0; var_AddCallback( p_intf->p_libvlc, "key-action", ActionEvent, p_intf ); return VLC_SUCCESS; @@ -163,22 +172,37 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) /* Playlist actions (including audio) */ case ACTIONID_LOOP: + { /* Toggle Normal -> Loop -> Repeat -> Normal ... */ + const char *mode; if( var_GetBool( p_playlist, "repeat" ) ) + { var_SetBool( p_playlist, "repeat", false ); + mode = N_("Off"); + } else if( var_GetBool( p_playlist, "loop" ) ) { /* FIXME: this is not atomic, we should use a real tristate */ var_SetBool( p_playlist, "loop", false ); var_SetBool( p_playlist, "repeat", true ); + mode = N_("One"); } else + { var_SetBool( p_playlist, "loop", true ); + mode = N_("All"); + } + DisplayMessage( p_vout, _("Loop: %s"), vlc_gettext(mode) ); break; + } case ACTIONID_RANDOM: - var_ToggleBool( p_playlist, "random" ); + { + const bool state = var_ToggleBool( p_playlist, "random" ); + DisplayMessage( p_vout, _("Random: %s"), + vlc_gettext( state ? N_("On") : N_("Off") ) ); break; + } case ACTIONID_NEXT: DisplayMessage( p_vout, _("Next") ); @@ -262,18 +286,24 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) break; } case ACTIONID_VOL_MUTE: - if( playlist_MuteToggle( p_playlist ) == 0 ) + { + int mute = playlist_MuteGet( p_playlist ); + if( mute < 0 ) + break; + mute = !mute; + if( playlist_MuteSet( p_playlist, mute ) ) + break; + + float vol = playlist_VolumeGet( p_playlist ); + if( mute || vol == 0.f ) { - float vol = playlist_VolumeGet( p_playlist ); - if( playlist_MuteGet( p_playlist ) > 0 || vol == 0.f ) - { - ClearChannels( p_intf, p_vout ); - DisplayIcon( p_vout, OSD_MUTE_ICON ); - } - else - DisplayVolume( p_intf, p_vout, vol ); + ClearChannels( p_intf, p_vout ); + DisplayIcon( p_vout, OSD_MUTE_ICON ); } + else + DisplayVolume( p_intf, p_vout, vol ); break; + } case ACTIONID_AUDIODEVICE_CYCLE: { @@ -326,9 +356,9 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) break; case ACTIONID_PLAY: - if( p_input && var_GetFloat( p_input, "rate" ) != 1. ) + if( p_input && var_GetFloat( p_input, "rate" ) != 1.f ) /* Return to normal speed */ - var_SetFloat( p_input, "rate", 1. ); + var_SetFloat( p_input, "rate", 1.f ); else { ClearChannels( p_intf, p_vout ); @@ -339,10 +369,10 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) /* Playlist + video output actions */ case ACTIONID_WALLPAPER: - { /* FIXME: this is invalid if not using DirectX output!!! */ - vlc_object_t *obj = p_vout ? VLC_OBJECT(p_vout) - : VLC_OBJECT(p_playlist); - var_ToggleBool( obj, "video-wallpaper" ); + { + bool wp = var_ToggleBool( p_playlist, "video-wallpaper" ); + if( p_vout ) + var_SetBool( p_vout, "video-wallpaper", wp ); break; } @@ -373,18 +403,104 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) } break; + case ACTIONID_SUBSYNC_MARKAUDIO: + { + p_sys->subtitle_delaybookmarks.i_time_audio = mdate(); + DisplayMessage( p_vout, _("Sub sync: bookmarked audio time")); + break; + } + case ACTIONID_SUBSYNC_MARKSUB: + if( p_input ) + { + vlc_value_t val, list, list2; + int i_count; + var_Get( p_input, "spu-es", &val ); + + var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES, + &list, &list2 ); + i_count = list.p_list->i_count; + if( i_count < 1 || val.i_int < 0 ) + { + DisplayMessage( p_vout, _("No active subtitle") ); + var_FreeList( &list, &list2 ); + break; + } + p_sys->subtitle_delaybookmarks.i_time_subtitle = mdate(); + DisplayMessage( p_vout, + _("Sub sync: bookmarked subtitle time")); + var_FreeList( &list, &list2 ); + } + break; + case ACTIONID_SUBSYNC_APPLY: + { + /* Warning! Can yield a pause in the playback. + * For example, the following succession of actions will yield a 5 second delay : + * - Pressing Shift-H (ACTIONID_SUBSYNC_MARKAUDIO) + * - wait 5 second + * - Press Shift-J (ACTIONID_SUBSYNC_MARKSUB) + * - Press Shift-K (ACTIONID_SUBSYNC_APPLY) + * --> 5 seconds pause + * This is due to var_SetTime() (and ultimately UpdatePtsDelay()) + * which causes the video to pause for an equivalent duration + * (This problem is also present in the "Track synchronization" window) */ + if ( p_input ) + { + if ( (p_sys->subtitle_delaybookmarks.i_time_audio == 0) || (p_sys->subtitle_delaybookmarks.i_time_subtitle == 0) ) + { + DisplayMessage( p_vout, _( "Sub sync: set bookmarks first!" ) ); + } + else + { + int64_t i_current_subdelay = var_GetTime( p_input, "spu-delay" ); + int64_t i_additional_subdelay = p_sys->subtitle_delaybookmarks.i_time_audio - p_sys->subtitle_delaybookmarks.i_time_subtitle; + int64_t i_total_subdelay = i_current_subdelay + i_additional_subdelay; + var_SetTime( p_input, "spu-delay", i_total_subdelay); + ClearChannels( p_intf, p_vout ); + DisplayMessage( p_vout, _( "Sub sync: corrected %i ms (total delay = %i ms)" ), + (int)(i_additional_subdelay / 1000), + (int)(i_total_subdelay / 1000) ); + p_sys->subtitle_delaybookmarks.i_time_audio = 0; + p_sys->subtitle_delaybookmarks.i_time_subtitle = 0; + } + } + break; + } + case ACTIONID_SUBSYNC_RESET: + { + var_SetTime( p_input, "spu-delay", 0); + ClearChannels( p_intf, p_vout ); + DisplayMessage( p_vout, _( "Sub sync: delay reset" ) ); + p_sys->subtitle_delaybookmarks.i_time_audio = 0; + p_sys->subtitle_delaybookmarks.i_time_subtitle = 0; + break; + } + case ACTIONID_SUBDELAY_DOWN: case ACTIONID_SUBDELAY_UP: { int diff = (i_action == ACTIONID_SUBDELAY_UP) ? 50000 : -50000; if( p_input ) { + vlc_value_t val, list, list2; + int i_count; + var_Get( p_input, "spu-es", &val ); + + var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES, + &list, &list2 ); + i_count = list.p_list->i_count; + if( i_count < 1 || val.i_int < 0 ) + { + DisplayMessage( p_vout, _("No active subtitle") ); + var_FreeList( &list, &list2 ); + break; + } int64_t i_delay = var_GetTime( p_input, "spu-delay" ) + diff; var_SetTime( p_input, "spu-delay", i_delay ); ClearChannels( p_intf, p_vout ); DisplayMessage( p_vout, _( "Subtitle delay %i ms" ), (int)(i_delay/1000) ); + var_FreeList( &list, &list2 ); } break; } @@ -475,12 +591,63 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) i = 0; else i++; - var_Set( p_input, "spu-es", list.p_list->p_values[i] ); + var_SetInteger( p_input, "spu-es", list.p_list->p_values[i].i_int ); + var_SetInteger( p_input, "spu-choice", list.p_list->p_values[i].i_int ); DisplayMessage( p_vout, _("Subtitle track: %s"), list2.p_list->p_values[i].psz_string ); var_FreeList( &list, &list2 ); } break; + case ACTIONID_SUBTITLE_TOGGLE: + if( p_input ) + { + vlc_value_t list, list2; + int i_count, i_sel_index, i_sel_id, i_old_id, i_new_index; + i_old_id = var_GetInteger( p_input, "spu-es" ); + i_sel_id = var_GetInteger( p_input, "spu-choice" ); + + var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES, + &list, &list2 ); + i_count = list.p_list->i_count; + if( i_count <= 1 ) + { + DisplayMessage( p_vout, _("Subtitle track: %s"), + _("N/A") ); + var_FreeList( &list, &list2 ); + break; + } + for( i_sel_index = 0; i_sel_index < i_count; i_sel_index++ ) + { + if( i_sel_id == list.p_list->p_values[i_sel_index].i_int ) + { + break; + } + } + /* if there is nothing to toggle choose the first track */ + if( !i_sel_index ) { + i_sel_index = 1; + i_sel_id = list.p_list->p_values[1].i_int; + var_SetInteger( p_input, "spu-choice", i_sel_id ); + } + + i_new_index = 0; + if( i_old_id != i_sel_id ) + { + if( i_sel_index >= i_count ) + { + var_SetInteger( p_input, "spu-choice", list.p_list->p_values[0].i_int ); + } + else + { + i_new_index = i_sel_index; + } + } + var_SetInteger( p_input, "spu-es", list.p_list->p_values[i_new_index].i_int ); + DisplayMessage( p_vout, _("Subtitle track: %s"), + list2.p_list->p_values[i_new_index].psz_string ); + var_FreeList( &list, &list2 ); + } + break; case ACTIONID_PROGRAM_SID_NEXT: case ACTIONID_PROGRAM_SID_PREV: if( p_input ) @@ -617,9 +784,13 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) case ACTIONID_TOGGLE_FULLSCREEN: { - bool fs = var_ToggleBool( p_playlist, "fullscreen" ); if( p_vout ) - var_SetBool( p_vout, "fullscreen", fs ); + { + bool fs = var_ToggleBool( p_vout, "fullscreen" ); + var_SetBool( p_playlist, "fullscreen", fs ); + } + else + var_ToggleBool( p_playlist, "fullscreen" ); break; } @@ -829,7 +1000,7 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) char *psz_mode = var_GetString( p_vout, "deinterlace-mode" ); vlc_value_t vlist, tlist; - if( psz_mode && !var_Change( p_vout, "deinterlace-mode", VLC_VAR_GETCHOICES, &vlist, &tlist ) >= 0 ) + if( psz_mode && !var_Change( p_vout, "deinterlace-mode", VLC_VAR_GETCHOICES, &vlist, &tlist ) ) { const char *psz_text = NULL; for( int i = 0; i < vlist.p_list->i_count; i++ ) @@ -854,7 +1025,7 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) { char *psz_mode = var_GetString( p_vout, "deinterlace-mode" ); vlc_value_t vlist, tlist; - if( psz_mode && !var_Change( p_vout, "deinterlace-mode", VLC_VAR_GETCHOICES, &vlist, &tlist ) >= 0 ) + if( psz_mode && !var_Change( p_vout, "deinterlace-mode", VLC_VAR_GETCHOICES, &vlist, &tlist )) { const char *psz_text = NULL; int i; @@ -891,14 +1062,33 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) case ACTIONID_SUBPOS_DOWN: case ACTIONID_SUBPOS_UP: { - int i_pos; - if( i_action == ACTIONID_SUBPOS_DOWN ) - i_pos = var_DecInteger( p_vout, "sub-margin" ); - else - i_pos = var_IncInteger( p_vout, "sub-margin" ); + if( p_input ) + { + vlc_value_t val, list, list2; + int i_count; + var_Get( p_input, "spu-es", &val ); - ClearChannels( p_intf, p_vout ); - DisplayMessage( p_vout, _( "Subtitle position %d px" ), i_pos ); + var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES, + &list, &list2 ); + i_count = list.p_list->i_count; + if( i_count < 1 || val.i_int < 0 ) + { + DisplayMessage( p_vout, + _("Subtitle position: no active subtitle") ); + var_FreeList( &list, &list2 ); + break; + } + + int i_pos; + if( i_action == ACTIONID_SUBPOS_DOWN ) + i_pos = var_DecInteger( p_vout, "sub-margin" ); + else + i_pos = var_IncInteger( p_vout, "sub-margin" ); + + ClearChannels( p_intf, p_vout ); + DisplayMessage( p_vout, _( "Subtitle position %d px" ), i_pos ); + var_FreeList( &list, &list2 ); + } break; } @@ -1035,7 +1225,7 @@ static void DisplayVolume( intf_thread_t *p_intf, vout_thread_t *p_vout, static void DisplayRate( vout_thread_t *p_vout, float f_rate ) { - DisplayMessage( p_vout, _("Speed: %.2fx"), f_rate ); + DisplayMessage( p_vout, _("Speed: %.2fx"), (double) f_rate ); } static float AdjustRateFine( vlc_object_t *p_obj, const int i_dir )