demux: wav: check implicit duration
[vlc.git] / modules / stream_out / delay.c
blob6e76264a09beb3d6c510d56070b0851eae95c621
1 /*****************************************************************************
2 * delay.c: delay a stream
3 *****************************************************************************
4 * Copyright © 2009-2011 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_sout.h>
34 #include <vlc_block.h>
36 /*****************************************************************************
37 * Module descriptor
38 *****************************************************************************/
39 #define ID_TEXT N_("Elementary Stream ID")
40 #define ID_LONGTEXT N_( \
41 "Specify an identifier integer for this elementary stream" )
43 #define DELAY_TEXT N_("Delay of the ES (ms)")
44 #define DELAY_LONGTEXT N_( \
45 "Specify a delay (in ms) for this elementary stream. " \
46 "Positive means delay and negative means advance." )
48 static int Open ( vlc_object_t * );
49 static void Close ( vlc_object_t * );
51 #define SOUT_CFG_PREFIX "sout-delay-"
53 vlc_module_begin()
54 set_shortname( N_("Delay"))
55 set_description( N_("Delay a stream"))
56 set_capability( "sout stream", 50 )
57 add_shortcut( "delay" )
58 set_category( CAT_SOUT )
59 set_subcategory( SUBCAT_SOUT_STREAM )
60 set_callbacks( Open, Close )
61 add_integer( SOUT_CFG_PREFIX "id", 0, ID_TEXT, ID_LONGTEXT,
62 false )
63 add_integer( SOUT_CFG_PREFIX "delay", 0, DELAY_TEXT, DELAY_LONGTEXT,
64 false )
65 vlc_module_end()
68 /*****************************************************************************
69 * Local prototypes
70 *****************************************************************************/
71 static const char *ppsz_sout_options[] = {
72 "id", "delay", NULL
75 static void *Add( sout_stream_t *, const es_format_t * );
76 static void Del( sout_stream_t *, void * );
77 static int Send( sout_stream_t *, void *, block_t * );
79 typedef struct
81 void *id;
82 int i_id;
83 vlc_tick_t i_delay;
84 } sout_stream_sys_t;
86 /*****************************************************************************
87 * Open:
88 *****************************************************************************/
89 static int Open( vlc_object_t *p_this )
91 sout_stream_t *p_stream = (sout_stream_t*)p_this;
92 sout_stream_sys_t *p_sys;
94 if( !p_stream->p_next )
96 msg_Err( p_stream, "cannot create chain" );
97 return VLC_EGENERIC;
100 p_sys = calloc( 1, sizeof( sout_stream_sys_t ) );
101 if( !p_sys )
102 return VLC_ENOMEM;
105 config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
106 p_stream->p_cfg );
108 p_sys->i_id = var_GetInteger( p_stream, SOUT_CFG_PREFIX "id" );
109 p_sys->i_delay = VLC_TICK_FROM_MS(var_GetInteger( p_stream, SOUT_CFG_PREFIX "delay" ));
111 p_stream->pf_add = Add;
112 p_stream->pf_del = Del;
113 p_stream->pf_send = Send;
115 p_stream->p_sys = p_sys;
117 return VLC_SUCCESS;
120 /*****************************************************************************
121 * Close:
122 *****************************************************************************/
123 static void Close( vlc_object_t * p_this )
125 sout_stream_t *p_stream = (sout_stream_t*)p_this;
126 sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
128 free( p_sys );
131 static void *Add( sout_stream_t *p_stream, const es_format_t *p_fmt )
133 sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
135 if ( p_fmt->i_id == p_sys->i_id )
137 msg_Dbg( p_stream, "delaying ID %d by %"PRId64,
138 p_sys->i_id, p_sys->i_delay );
139 p_sys->id = sout_StreamIdAdd( p_stream->p_next, p_fmt );
140 return p_sys->id;
143 return sout_StreamIdAdd( p_stream->p_next, p_fmt );
146 static void Del( sout_stream_t *p_stream, void *id )
148 sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
150 if ( id == p_sys->id )
151 p_sys->id = NULL;
153 sout_StreamIdDel( p_stream->p_next, id );
156 static int Send( sout_stream_t *p_stream, void *id, block_t *p_buffer )
158 sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
160 if ( id == p_sys->id )
162 block_t *p_block = p_buffer;
163 while ( p_block != NULL )
165 if ( p_block->i_pts != VLC_TICK_INVALID )
166 p_block->i_pts += p_sys->i_delay;
167 if ( p_block->i_dts != VLC_TICK_INVALID )
168 p_block->i_dts += p_sys->i_delay;
169 p_block = p_block->p_next;
173 return sout_StreamIdSend( p_stream->p_next, id, p_buffer );