[vlc-devel] Re: ff / rew based on time ...
John Michael Zorko
j.zorko at att.net
Tue May 27 01:03:38 CEST 2003
DJ,
My friends' server is down, so here is the diff so far. Some things I
still want to work on are:
1. SetDemuxOptions() is a bit too specific to MP3 or MPEG I think (time
offset, frame offset) but maybe not so bad ...
2. none of the frame-seeking code is in yet (just stubbed out if's, but
i'm working on it)
3. how to seek backwards n frames, when a frame could be:
a.) be spread across more than 1 pack
b.) could have it's start code spread across more than 1 pack
c.) variable length i.e. MP3 VBR
Thoughts?
? diffstuff
? stoneseggs.mp3
Index: include/input_ext-intf.h
===================================================================
RCS file: /var/cvs/videolan/vlc/include/input_ext-intf.h,v
retrieving revision 1.90
diff -u -r1.90 input_ext-intf.h
--- include/input_ext-intf.h 17 May 2003 22:00:00 -0000 1.90
+++ include/input_ext-intf.h 26 May 2003 22:28:32 -0000
@@ -316,6 +316,10 @@
/* Demux module */
module_t * p_demux;
int (* pf_demux ) ( input_thread_t * );
+ int (* pf_setdemuxoptions ) ( input_thread_t *p_input,
+ int i_offsettime, /* -:
rewind, +: ff */
+ int i_offsetframe, /* -:
rewind, +: ff */
+ int i_drop ); /* packets
to drop b4 playing */
int (* pf_rewind ) ( input_thread_t * );
/* NULL if we don't support
going *
* backwards (it's gonna be
fun) */
@@ -365,6 +369,14 @@
#define INPUT_STATUS_PAUSE 2
#define INPUT_STATUS_FASTER 3
#define INPUT_STATUS_SLOWER 4
+#define INPUT_STATUS_FASTFORWARD_TS 5 // fast-forward by skipping time
+#define INPUT_STATUS_REWIND_TS 6 // rewind " " "
+#define INPUT_STATUS_FASTFORWARD_FS 7 // fast-forward by skipping
frames
+#define INPUT_STATUS_REWIND_FS 8 // rewind " " "
+
+/* maximum seconds to skip when doing ff / rew using time-based
skipping (PS) */
+
+#define MAX_FF_REW_SKIP 10
/* Seek modes */
#define INPUT_SEEK_SET 0x00
@@ -373,6 +385,8 @@
#define INPUT_SEEK_BYTES 0x00
#define INPUT_SEEK_SECONDS 0x10
#define INPUT_SEEK_PERCENT 0x20
+#define INPUT_SEEK_SPECIAL 0x30
+
/
************************************************************************
*****
* Prototypes
Index: include/stream_control.h
===================================================================
RCS file: /var/cvs/videolan/vlc/include/stream_control.h,v
retrieving revision 1.10
diff -u -r1.10 stream_control.h
--- include/stream_control.h 31 Jul 2002 20:56:50 -0000 1.10
+++ include/stream_control.h 26 May 2003 22:28:33 -0000
@@ -41,6 +41,12 @@
/* if i_status == FORWARD_S or BACKWARD_S */
int i_rate;
+ /* for packet-skipping fast-forward / rewind implementation */
+ int i_packet_skip_rate;
+
+ /* for frame-skipping fast-forward / rewind implementation */
+ int i_frame_skip_rate;
+
vlc_bool_t b_mute;
vlc_bool_t b_grayscale; /* use color or
grayscale */
};
Index: modules/control/rc/rc.c
===================================================================
RCS file: /var/cvs/videolan/vlc/modules/control/rc/rc.c,v
retrieving revision 1.34
diff -u -r1.34 rc.c
--- modules/control/rc/rc.c 15 May 2003 22:27:37 -0000 1.34
+++ modules/control/rc/rc.c 26 May 2003 22:28:41 -0000
@@ -196,6 +196,15 @@
var_Create( p_intf, "achan", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
var_AddCallback( p_intf, "achan", AudioConfig, NULL );
+ var_Create( p_intf, "ff_ts", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+ var_AddCallback( p_intf, "ff_ts", Input, NULL );
+ var_Create( p_intf, "rew_ts", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+ var_AddCallback( p_intf, "rew_ts", Input, NULL );
+ var_Create( p_intf, "ff_fs", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+ var_AddCallback( p_intf, "ff_fs", Input, NULL );
+ var_Create( p_intf, "rew_fs", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
+ var_AddCallback( p_intf, "rew_fs", Input, NULL );
+
#ifdef WIN32
/* Get the file descriptor of the console input */
hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
@@ -472,6 +481,13 @@
printf("| f . . . . . . . . . . . . . . toggle
fullscreen\n");
printf("| info . . . information about the current
stream\n");
printf("| \n");
+ printf("| ff_ts . . . . fast-forward using time
skipping\n");
+ printf("| (enter command again to go
faster)\n");
+ printf("| rew_ts . . . . . . . rewind using time
skipping\n");
+ printf("| (enter command again to go
faster)\n");
+ printf("| ff_fs . . . . fast-forward using frame
skipping\n");
+ printf("| rew_fs . . . . . . . rewind using frame
skipping\n");
+ printf("| \n");
printf("| volume [X] . . . . . . . . set/get audio
volume\n");
printf("| volup [X] . . . . . raise audio volume X
steps\n");
printf("| voldown [X] . . . . lower audio volume X
steps\n");
@@ -529,6 +545,22 @@
{
input_Seek( p_input, atoi( newval.psz_string ),
INPUT_SEEK_SECONDS | INPUT_SEEK_SET );
+ }
+ else if ( !strcmp( psz_cmd, "ff_ts" ) )
+ {
+ input_SetStatus( p_input, INPUT_STATUS_FASTFORWARD_TS );
+ }
+ else if ( !strcmp( psz_cmd, "rew_ts" ) )
+ {
+ input_SetStatus( p_input, INPUT_STATUS_REWIND_TS );
+ }
+ else if ( !strcmp( psz_cmd, "ff_ts" ) )
+ {
+ input_SetStatus( p_input, INPUT_STATUS_FASTFORWARD_FS );
+ }
+ else if ( !strcmp( psz_cmd, "rew_fs" ) )
+ {
+ input_SetStatus( p_input, INPUT_STATUS_REWIND_FS );
}
else if( !strcmp( psz_cmd, "chapter" ) ||
!strcmp( psz_cmd, "chapter_n" ) ||
Index: modules/demux/mpeg/audio.c
===================================================================
RCS file: /var/cvs/videolan/vlc/modules/demux/mpeg/audio.c,v
retrieving revision 1.18
diff -u -r1.18 audio.c
--- modules/demux/mpeg/audio.c 5 May 2003 22:23:36 -0000 1.18
+++ modules/demux/mpeg/audio.c 26 May 2003 22:28:45 -0000
@@ -37,6 +37,7 @@
************************************************************************
*****/
static int Activate ( vlc_object_t * );
static int Demux ( input_thread_t * );
+static int SetDemuxOptions( input_thread_t *, int, int, int );
/* TODO: support MPEG-2.5, not difficult, but I need somes samples...
*/
@@ -105,6 +106,12 @@
int i_samplerate;
int i_samplelength;
int i_framelength;
+
+ /* info for SetDemuxOptions i.e. ff / rew */
+ int i_packet_skip_rate;
+ int i_frame_skip_rate;
+ int i_drop_count;
+ int i_packet_counter;
};
@@ -490,6 +497,7 @@
int i_max_pos;
/* Set the demux function */
+ p_input->pf_setdemuxoptions = SetDemuxOptions;
p_input->pf_demux = Demux;
/* Initialize access plug-in structures. */
@@ -650,6 +658,29 @@
}
/
************************************************************************
*****
+ * SetDemuxOptions: sets options for the demuxer to work with i.e. ff
/ rew
+ * parameters. The idea is that only the demux plugin(s) know how to
identify
+ * things like MP3 frames, MPEG sequence headers, GOPs, I-frames, etc.
and if
+ * we want to be able to seek in a more specific manner i.e. "go back
10 MP3
+ * frames" or "advance to the third GOP from now" the demux plugin(s)
should
+ * be involved, so we won't need to duplicate code elsewhere.
+
************************************************************************
*****/
+
+static int SetDemuxOptions( input_thread_t *p_input,
+ int i_offsettime,
+ int i_offsetframe,
+ int i_drop )
+{
+ demux_sys_t *p_demux = p_input->p_demux_data;
+
+ p_demux->i_packet_skip_rate = i_offsettime;
+ p_demux->i_frame_skip_rate = i_offsetframe;
+ p_demux->i_drop_count = i_drop;
+
+ return 0;
+}
+
+/
************************************************************************
*****
* Demux: reads and demuxes data packets
************************************************************************
*****
* Returns -1 in case of error, 0 in case of EOF, 1 otherwise
@@ -660,6 +691,29 @@
pes_packet_t *p_pes;
int i_skip;
+ /* First see if we're in ff / rewind mode and if we need to seek */
+
+ p_demux->i_packet_counter ++;
+
+ #define A p_input->stream
+
+ if ( p_demux->i_packet_counter % p_demux->i_drop_count == 0 )
+ {
+ if ( p_demux->i_packet_skip_rate != 1 )
+ {
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ int i_new_pos = A.p_selected_area->i_tell / ( 50 *
A.i_mux_rate ) +
+ p_demux->i_packet_skip_rate;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ input_Seek( p_input, i_new_pos, INPUT_SEEK_SECONDS |
INPUT_SEEK_SET );
+ }
+ else if ( p_demux->i_frame_skip_rate != 0 )
+ {
+ }
+ }
+
+ #undef A
+
if( !GetHeader( p_input,
&p_demux->mpeg,
8192,
@@ -714,7 +768,18 @@
}
else
{
- input_DecodePES( p_demux->p_es->p_decoder_fifo, p_pes );
+ if ( p_demux->i_frame_skip_rate == 0 )
+ {
+ input_DecodePES( p_demux->p_es->p_decoder_fifo, p_pes );
+ }
+ else if ( p_demux->i_packet_counter % p_demux->i_drop_count !=
0 )
+ {
+ #define A p_input->stream
+ input_DecodePES( p_demux->p_es->p_decoder_fifo, p_pes );
+
+
+ #undef A
+ }
}
p_demux->i_pts += (mtime_t)90000 *
(mtime_t)p_demux->i_samplelength /
Index: src/input/input.c
===================================================================
RCS file: /var/cvs/videolan/vlc/src/input/input.c,v
retrieving revision 1.230
diff -u -r1.230 input.c
--- src/input/input.c 22 May 2003 16:01:02 -0000 1.230
+++ src/input/input.c 26 May 2003 22:28:53 -0000
@@ -84,6 +84,7 @@
/* Demux */
p_input->p_demux = NULL;
+ p_input->pf_setdemuxoptions = NULL;
/* Access */
p_input->p_access = NULL;
@@ -134,6 +135,8 @@
p_input->stream.control.i_rate = DEFAULT_RATE;
p_input->stream.control.b_mute = 0;
p_input->stream.control.b_grayscale = config_GetInt( p_input,
"grayscale" );
+ p_input->stream.control.i_packet_skip_rate = 1;
+ p_input->stream.control.i_frame_skip_rate = 0;
/* Initialize input info */
p_input->stream.p_info = malloc( sizeof( input_info_category_t ) );
@@ -335,6 +338,20 @@
p_input->stream.b_new_mute = MUTE_NO_CHANGE;
}
+
+ /* Set demux options (if we need to ff / rew or not, for
instance */
+
+ #define A p_input->stream
+
+ if ( p_input->pf_setdemuxoptions )
+ {
+ p_input->pf_setdemuxoptions( p_input,
+ A.control.i_packet_skip_rate,
+ A.control.i_frame_skip_rate,
+ 10 );
+ }
+
+ #undef A
vlc_mutex_unlock( &p_input->stream.stream_lock );
Index: src/input/input_clock.c
===================================================================
RCS file: /var/cvs/videolan/vlc/src/input/input_clock.c,v
retrieving revision 1.37
diff -u -r1.37 input_clock.c
--- src/input/input_clock.c 22 May 2003 16:01:02 -0000 1.37
+++ src/input/input_clock.c 26 May 2003 22:28:56 -0000
@@ -188,7 +188,10 @@
ClockNewRef( p_pgrm, i_clock,
ClockToSysdate( p_input, p_pgrm, i_clock ) );
- if( p_input->stream.control.i_status == PLAYING_S )
+ if( p_input->stream.control.i_status == PLAYING_S ||
+ p_input->stream.control.i_status == REWIND_S ||
+ p_input->stream.control.i_status == FORWARD_S )
+
{
p_input->stream.control.i_rate = DEFAULT_RATE;
p_input->stream.control.b_mute = 0;
Index: src/input/input_ext-intf.c
===================================================================
RCS file: /var/cvs/videolan/vlc/src/input/input_ext-intf.c,v
retrieving revision 1.49
diff -u -r1.49 input_ext-intf.c
--- src/input/input_ext-intf.c 4 May 2003 22:42:17 -0000 1.49
+++ src/input/input_ext-intf.c 26 May 2003 22:28:59 -0000
@@ -52,6 +52,84 @@
switch( i_mode )
{
+ case INPUT_STATUS_FASTFORWARD_TS:
+ if ( p_input->stream.control.i_packet_skip_rate ==
MAX_FF_REW_SKIP )
+ {
+ msg_Dbg( p_input, "can't do packet-skipping fast-forward
any faster" );
+ }
+ else
+ {
+ p_input->stream.control.i_packet_skip_rate ++;
+
+ if ( p_input->stream.control.i_packet_skip_rate == 0 )
+ {
+ p_input->stream.control.i_packet_skip_rate ++;
+ }
+
+ p_input->stream.i_new_status = FORWARD_S;
+ }
+ break;
+
+ case INPUT_STATUS_REWIND_TS:
+ if ( p_input->stream.control.i_packet_skip_rate == 0 -
MAX_FF_REW_SKIP )
+ {
+ msg_Dbg( p_input, "can't do packet-skipping rewind any
faster" );
+ }
+ else
+ {
+ p_input->stream.control.i_packet_skip_rate --;
+
+ if ( p_input->stream.control.i_packet_skip_rate == 0 )
+ {
+ p_input->stream.control.i_packet_skip_rate --;
+ }
+
+ p_input->stream.i_new_status = REWIND_S;
+ }
+ break;
+
+ case INPUT_STATUS_FASTFORWARD_FS:
+
+ if ( p_input->stream.control.i_frame_skip_rate ==
MAX_FF_REW_SKIP )
+ {
+ msg_Dbg( p_input, "can't do frame-skipping fast-forward
any faster" );
+ }
+ else
+ {
+ p_input->stream.control.i_frame_skip_rate ++;
+
+ if ( p_input->stream.control.i_frame_skip_rate == 0 )
+ {
+ p_input->stream.control.i_frame_skip_rate ++;
+ }
+
+ p_input->stream.p_selected_area->i_seek = 1;
+ p_input->stream.i_new_status = FORWARD_S;
+ }
+
+ break;
+
+ case INPUT_STATUS_REWIND_FS:
+
+ if ( p_input->stream.control.i_frame_skip_rate == 0 -
MAX_FF_REW_SKIP )
+ {
+ msg_Dbg( p_input, "can't do frame-skipping rewind any
faster" );
+ }
+ else
+ {
+ p_input->stream.control.i_frame_skip_rate --;
+
+ if ( p_input->stream.control.i_frame_skip_rate == 0 )
+ {
+ p_input->stream.control.i_frame_skip_rate --;
+ }
+
+ p_input->stream.p_selected_area->i_seek = 1;
+ p_input->stream.i_new_status = REWIND_S;
+ }
+
+ break;
+
case INPUT_STATUS_END:
p_input->stream.i_new_status = PLAYING_S;
p_input->b_eof = 1;
@@ -60,6 +138,8 @@
case INPUT_STATUS_PLAY:
p_input->stream.i_new_status = PLAYING_S;
+ p_input->stream.control.i_packet_skip_rate = 1;
+ p_input->stream.control.i_frame_skip_rate = 0;
msg_Dbg( p_input, "playing at normal rate" );
break;
> Just send it to the list, or send a link to a download location (even
> better).
Regards,
John
Falling You - exploring the beauty of voice and sound
New EP, "hope thrown down," available now at
http://www.mp3.com/fallingyou
--
This is the vlc-devel mailing-list, see http://www.videolan.org/vlc/
To unsubscribe, please read http://developers.videolan.org/lists.html
If you are in trouble, please contact <postmaster at videolan.org>
More information about the vlc-devel
mailing list