Commit 17d78502 authored by Clément Stenac's avatar Clément Stenac

* Implement INPUT_GET_SUBDELAY and INPUT_SET_SUBDELAY

* Allow to modify subtitle delay on the fly and implement hotkeys 
  (h and j)

* When framerate is available with subrip, use sub-fps to make corrections
  (sub-fps default value is now 0, if left to this value, 25fps will be
   assumed in microdvd mode and no correction will be applied in subrip)

Main problem is that when seeking in the subtitles, you easily get
several of them displayed. Maybe we could add a flag to subpicture_t,
like SUBTITLE_PICTURE to say that only one of them must be displayed at
a time, but that other subpictures (OSD, ...) can remain present on the
screen at the same time.
parent 200a3bc0
......@@ -378,6 +378,9 @@ enum input_query_e
INPUT_DEL_BOOKMARK, /* arg1= seekpoint_t * res=can fail */
INPUT_SET_BOOKMARK, /* arg1= int res=can fail */
INPUT_GET_SUBDELAY, /* arg1 = int* res=can fail */
INPUT_SET_SUBDELAY, /* arg1 = int res=can fail */
INPUT_GET_DIVISIONS
};
......
......@@ -226,3 +226,5 @@ static inline int StringToKey( char *psz_key )
#define ACTIONID_PLAY_BOOKMARK9 44
#define ACTIONID_PLAY_BOOKMARK10 45
/* end of contiguous zone */
#define ACTIONID_SUBDELAY_UP 46
#define ACTIONID_SUBDELAY_DOWN 47
......@@ -2,7 +2,7 @@
* hotkeys.c: Hotkey handling for vlc
*****************************************************************************
* Copyright (C) 2004 VideoLAN
* $Id: hotkeys.c,v 1.17 2004/02/17 03:12:00 hartman Exp $
* $Id$
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
......@@ -247,6 +247,28 @@ static void Run( intf_thread_t *p_intf )
aout_VolumeDown( p_intf, 1, &i_newvol );
vout_OSDMessage( p_intf, "Vol %d%%", i_newvol*100/AOUT_VOLUME_MAX);
}
else if( i_action == ACTIONID_SUBDELAY_DOWN )
{
int i_delay;
if( input_Control( p_input, INPUT_GET_SUBDELAY, &i_delay ) ==
VLC_SUCCESS )
{
i_delay--;
input_Control( p_input, INPUT_SET_SUBDELAY, i_delay );
vout_OSDMessage( p_intf, "Subtitle delay %i ms",i_delay*100);
}
}
else if( i_action == ACTIONID_SUBDELAY_UP )
{
int i_delay;
if( input_Control( p_input, INPUT_GET_SUBDELAY, &i_delay ) ==
VLC_SUCCESS )
{
i_delay++;
input_Control( p_input, INPUT_SET_SUBDELAY, i_delay );
vout_OSDMessage( p_intf, "Subtitle delay %i ms",i_delay*100);
}
}
else if( i_action == ACTIONID_VOL_MUTE )
{
audio_volume_t i_newvol = -1;
......@@ -257,7 +279,8 @@ static void Run( intf_thread_t *p_intf )
}
else
{
vout_OSDMessage( p_intf, "Vol %d%%", i_newvol*100/AOUT_VOLUME_MAX );
vout_OSDMessage( p_intf, "Vol %d%%",
i_newvol*100/AOUT_VOLUME_MAX );
}
}
else if( i_action == ACTIONID_FULLSCREEN )
......
......@@ -2,7 +2,7 @@
* sub.c: subtitle demux for external subtitle files
*****************************************************************************
* Copyright (C) 1999-2004 VideoLAN
* $Id: sub.c,v 1.52 2004/02/22 15:59:53 fenrir Exp $
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Derk-Jan Hartman <hartman at videolan dot org>
......@@ -73,7 +73,7 @@ static char *ppsz_sub_type[] = { "auto", "microdvd", "subrip", "ssa1",
vlc_module_begin();
set_description( _("Text subtitles demux") );
set_capability( "subtitle demux", 12 );
add_float( "sub-fps", 25.0, NULL,
add_float( "sub-fps", 0.0, NULL,
N_("Frames per second"),
SUB_FPS_LONGTEXT, VLC_TRUE );
add_integer( "sub-delay", 0, NULL,
......@@ -274,6 +274,7 @@ static int sub_open( subtitle_demux_t *p_sub, input_thread_t *p_input,
p_sub->i_subtitles = 0;
p_sub->subtitle = NULL;
p_sub->p_vobsub_file = 0;
p_sub->i_original_mspf = i_microsecperframe;
p_sub->p_input = p_input;
if( !psz_name || !*psz_name )
......@@ -296,9 +297,15 @@ static int sub_open( subtitle_demux_t *p_sub, input_thread_t *p_input,
{
i_microsecperframe = (mtime_t)( (float)1000000 / val.f_float );
}
else if( val.f_float == 0 )
{
/* No value given */
i_microsecperframe = 0;
}
else if( val.f_float <= 0 )
{
i_microsecperframe = 40000; /* default: 25fps */
/* invalid value, default = 25fps */
i_microsecperframe = 40000;
}
var_Get( p_sub, "sub-type", &val);
......@@ -499,6 +506,8 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
{
input_thread_t *p_input = p_sub->p_input;
vlc_bool_t b;
vlc_value_t val;
mtime_t i_delay;
es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE, p_sub->p_es, &b );
if( b && !p_sub->i_previously_selected )
......@@ -515,8 +524,10 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
if( p_sub->i_sub_type != SUB_TYPE_VOBSUB )
{
var_Get( p_sub, "sub-delay", &val );
i_delay = (mtime_t) val.i_int * 100000;
while( p_sub->i_subtitle < p_sub->i_subtitles &&
p_sub->subtitle[p_sub->i_subtitle].i_start < i_maxdate )
p_sub->subtitle[p_sub->i_subtitle].i_start < i_maxdate - i_delay )
{
block_t *p_block;
int i_len = strlen( p_sub->subtitle[p_sub->i_subtitle].psz_text ) + 1;
......@@ -534,8 +545,13 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
continue;
}
/* XXX we should convert all demuxers to use es_out_Control to set pcr and
* then remove that */
/* XXX we should convert all demuxers to use es_out_Control to set * pcr and then remove that */
if( i_delay != 0 )
{
p_sub->subtitle[p_sub->i_subtitle].i_start += i_delay;
p_sub->subtitle[p_sub->i_subtitle].i_stop += i_delay;
}
p_block->i_pts =
input_ClockGetTS( p_sub->p_input,
p_sub->p_input->stream.p_selected_program,
......@@ -551,7 +567,6 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
}
memcpy( p_block->p_buffer, p_sub->subtitle[p_sub->i_subtitle].psz_text, i_len );
if( p_block->i_pts > 0 )
{
es_out_Send( p_input->p_es_out, p_sub->p_es, p_block );
......@@ -760,6 +775,10 @@ static int sub_MicroDvdRead( subtitle_demux_t *p_sub, text_t *txt, subtitle_t *
buffer_text[i] = '\n';
}
}
if( i_microsecperframe == 0)
{
i_microsecperframe = 40000;
}
p_subtitle->i_start = (mtime_t)i_start * (mtime_t)i_microsecperframe;
p_subtitle->i_stop = (mtime_t)i_stop * (mtime_t)i_microsecperframe;
p_subtitle->psz_text = strndup( buffer_text, MAX_LINE );
......@@ -827,6 +846,16 @@ static int sub_SubRipRead( subtitle_demux_t *p_sub, text_t *txt, subtitle_t *p_
p_subtitle->i_start = i_start;
p_subtitle->i_stop = i_stop;
p_subtitle->psz_text = strdup( buffer_text );
/* If framerate is available, use sub-fps */
if( i_microsecperframe != 0 && p_sub->i_original_mspf != 0)
{
p_subtitle->i_start = (mtime_t)i_start *
(mtime_t)p_sub->i_original_mspf /
(mtime_t)i_microsecperframe;
p_subtitle->i_stop = (mtime_t)i_stop *
(mtime_t)p_sub->i_original_mspf /
(mtime_t)i_microsecperframe;
}
return( 0 );
}
else
......
......@@ -2,7 +2,7 @@
* sub.h
*****************************************************************************
* Copyright (C) 2001-2004 VideoLAN
* $Id: sub.h,v 1.20 2004/03/03 20:39:52 gbazin Exp $
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -67,6 +67,7 @@ typedef struct subtitle_demux_s
es_out_id_t *p_es;
int i_previously_selected; /* to make pf_seek */
FILE *p_vobsub_file;
mtime_t i_original_mspf;
} subtitle_demux_t;
......
......@@ -26,6 +26,15 @@
#include <vlc/input.h>
#include "ninput.h"
#include "../../modules/demux/util/sub.h"
struct input_thread_sys_t
{
/* subtitles */
int i_sub;
subtitle_demux_t **sub;
int64_t i_stop_time;
};
/****************************************************************************
* input_Control
......@@ -53,6 +62,7 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
int i_ret;
seekpoint_t *p_bkmk, ***ppp_bkmk;
int i_bkmk, *pi_bkmk;
int i, *pi;
vlc_value_t val, text;
vlc_mutex_lock( &p_input->stream.stream_lock );
......@@ -177,6 +187,52 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
}
break;
case INPUT_GET_SUBDELAY:
pi = (int)va_arg( args, int *);
/* We work on the first subtitle */
if( p_input->p_sys != NULL )
{
if( p_input->p_sys->i_sub > 0 )
{
i_ret = var_Get( (vlc_object_t *)p_input->p_sys->sub[0],
"sub-delay", &val );
*pi = val.i_int;
}
else
{
msg_Dbg( p_input,"no subtitle track");
i_ret = VLC_EGENERIC;
}
}
else
{
i_ret = VLC_EGENERIC;
}
break;
case INPUT_SET_SUBDELAY:
i = (int)va_arg( args, int );
/* We work on the first subtitle */
if( p_input->p_sys )
{
if( p_input->p_sys->i_sub > 0 )
{
val.i_int = i;
i_ret = var_Set( (vlc_object_t *)p_input->p_sys->sub[0],
"sub-delay", val );
}
else
{
msg_Dbg( p_input,"no subtitle track");
i_ret = VLC_EGENERIC;
}
}
else
{
i_ret = VLC_EGENERIC;
}
break;
default:
msg_Err( p_input, "unknown query in input_vaControl" );
i_ret = VLC_EGENERIC;
......
......@@ -621,7 +621,8 @@ static int RunThread( input_thread_t *p_input )
static int InitThread( input_thread_t * p_input )
{
vlc_meta_t *p_meta = NULL, *p_meta_user = NULL;
float f_fps;
// float f_fps;
double f_fps;
playlist_t *p_playlist;
mtime_t i_length;
......@@ -1092,7 +1093,6 @@ static int InitThread( input_thread_t * p_input )
/* Get fps */
if( demux_Control( p_input, DEMUX_GET_FPS, &f_fps ) || f_fps < 0.1 )
{
i_microsecondperframe = 0;
}
else
{
......
......@@ -660,6 +660,10 @@ static char *ppsz_align_descriptions[] =
#define VOL_DOWN_KEY_LONGTEXT N_("Select the key to decrease audio volume.")
#define VOL_MUTE_KEY_TEXT N_("Mute")
#define VOL_MUTE_KEY_LONGTEXT N_("Select the key to turn off audio volume.")
#define SUBDELAY_UP_KEY_TEXT N_("Subtitle delay up")
#define SUBDELAY_UP_KEY_LONGTEXT N_("Select the key to increase the subtitle delay.")
#define SUBDELAY_DOWN_KEY_TEXT N_("Subtitle delay down")
#define SUBDELAY_DOWN_KEY_LONGTEXT N_("Select the key to decrease the subtitle delay.")
#define PLAY_BOOKMARK1_KEY_TEXT N_("Play playlist bookmark 1")
#define PLAY_BOOKMARK2_KEY_TEXT N_("Play playlist bookmark 2")
#define PLAY_BOOKMARK3_KEY_TEXT N_("Play playlist bookmark 3")
......@@ -959,6 +963,10 @@ vlc_module_begin();
add_key( "key-vol-up", KEY_MODIFIER_COMMAND|KEY_UP, NULL, VOL_UP_KEY_TEXT, VOL_UP_KEY_LONGTEXT, VLC_FALSE );
add_key( "key-vol-down", KEY_MODIFIER_COMMAND|KEY_DOWN, NULL, VOL_DOWN_KEY_TEXT, VOL_DOWN_KEY_LONGTEXT, VLC_FALSE );
add_key( "key-vol-mute", KEY_MODIFIER_COMMAND|KEY_MODIFIER_SHIFT|'m', NULL, VOL_MUTE_KEY_TEXT, VOL_MUTE_KEY_LONGTEXT, VLC_FALSE );
add_key( "key-subdelay-up", KEY_MODIFIER_COMMAND|'j', NULL,
SUBDELAY_UP_KEY_TEXT, SUBDELAY_UP_KEY_LONGTEXT, VLC_FALSE );
add_key( "key-subdelay-down", KEY_MODIFIER_COMMAND|'h', NULL,
SUBDELAY_DOWN_KEY_TEXT, SUBDELAY_DOWN_KEY_LONGTEXT, VLC_FALSE );
add_key( "key-set-bookmark1", KEY_MODIFIER_COMMAND|KEY_F1, NULL, SET_BOOKMARK1_KEY_TEXT, SET_BOOKMARK_KEY_LONGTEXT, VLC_TRUE );
add_key( "key-set-bookmark2", KEY_MODIFIER_COMMAND|KEY_F2, NULL, SET_BOOKMARK2_KEY_TEXT, SET_BOOKMARK_KEY_LONGTEXT, VLC_TRUE );
add_key( "key-set-bookmark3", KEY_MODIFIER_COMMAND|KEY_F3, NULL, SET_BOOKMARK3_KEY_TEXT, SET_BOOKMARK_KEY_LONGTEXT, VLC_TRUE );
......@@ -1005,6 +1013,10 @@ vlc_module_begin();
add_key( "key-vol-up", 'a', NULL, VOL_UP_KEY_TEXT, VOL_UP_KEY_LONGTEXT, VLC_FALSE );
add_key( "key-vol-down", 'z', NULL, VOL_DOWN_KEY_TEXT, VOL_DOWN_KEY_LONGTEXT, VLC_FALSE );
add_key( "key-vol-mute", 'm', NULL, VOL_MUTE_KEY_TEXT, VOL_MUTE_KEY_LONGTEXT, VLC_FALSE );
add_key( "key-subdelay-up", KEY_MODIFIER_COMMAND|'h', NULL,
SUBDELAY_UP_KEY_TEXT, SUBDELAY_UP_KEY_LONGTEXT, VLC_FALSE );
add_key( "key-subdelay-down", KEY_MODIFIER_COMMAND|'j', NULL,
SUBDELAY_DOWN_KEY_TEXT, SUBDELAY_DOWN_KEY_LONGTEXT, VLC_FALSE );
add_key( "key-set-bookmark1", KEY_MODIFIER_CTRL|KEY_F1, NULL, SET_BOOKMARK1_KEY_TEXT, SET_BOOKMARK_KEY_LONGTEXT, VLC_TRUE );
add_key( "key-set-bookmark2", KEY_MODIFIER_CTRL|KEY_F2, NULL, SET_BOOKMARK2_KEY_TEXT, SET_BOOKMARK_KEY_LONGTEXT, VLC_TRUE );
add_key( "key-set-bookmark3", KEY_MODIFIER_CTRL|KEY_F3, NULL, SET_BOOKMARK3_KEY_TEXT, SET_BOOKMARK_KEY_LONGTEXT, VLC_TRUE );
......@@ -1084,6 +1096,8 @@ static struct hotkey p_hotkeys[] =
{ "key-vol-up", ACTIONID_VOL_UP, 0 },
{ "key-vol-down", ACTIONID_VOL_DOWN, 0 },
{ "key-vol-mute", ACTIONID_VOL_MUTE, 0 },
{ "key-subdelay-down", ACTIONID_SUBDELAY_DOWN, 0 },
{ "key-subdelay-up", ACTIONID_SUBDELAY_UP, 0 },
{ "key-nav-activate", ACTIONID_NAV_ACTIVATE, 0 },
{ "key-nav-up", ACTIONID_NAV_UP, 0 },
{ "key-nav-down", ACTIONID_NAV_DOWN, 0 },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment