]> git.sesse.net Git - vlc/blob - modules/stream_out/display.c
aout: add wait parameter to aout_DecFlush()
[vlc] / modules / stream_out / display.c
1 /*****************************************************************************
2  * display.c: display stream output module
3  *****************************************************************************
4  * Copyright (C) 2001-2011 VLC authors and VideoLAN
5  *
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_input.h>
34 #include <vlc_sout.h>
35 #include <vlc_block.h>
36
37 /*****************************************************************************
38  * Module descriptor
39  *****************************************************************************/
40 #define AUDIO_TEXT N_("Enable audio")
41 #define AUDIO_LONGTEXT N_( "Enable/disable audio rendering." )
42 #define VIDEO_TEXT N_("Enable video")
43 #define VIDEO_LONGTEXT N_( "Enable/disable video rendering." )
44 #define DELAY_TEXT N_("Delay (ms)")
45 #define DELAY_LONGTEXT N_( "Introduces a delay in the display of the stream." )
46
47 static int  Open ( vlc_object_t * );
48 static void Close( vlc_object_t * );
49
50 #define SOUT_CFG_PREFIX "sout-display-"
51
52 vlc_module_begin ()
53     set_shortname( N_("Display"))
54     set_description( N_("Display stream output") )
55     set_capability( "sout stream", 50 )
56     add_shortcut( "display" )
57     set_category( CAT_SOUT )
58     set_subcategory( SUBCAT_SOUT_STREAM )
59
60     add_bool( SOUT_CFG_PREFIX "audio", true, AUDIO_TEXT,
61               AUDIO_LONGTEXT, true )
62     add_bool( SOUT_CFG_PREFIX "video", true, VIDEO_TEXT,
63               VIDEO_LONGTEXT, true )
64     add_integer( SOUT_CFG_PREFIX "delay", 100, DELAY_TEXT,
65                  DELAY_LONGTEXT, true )
66     set_callbacks( Open, Close )
67 vlc_module_end ()
68
69
70 /*****************************************************************************
71  * Exported prototypes
72  *****************************************************************************/
73 static const char *const ppsz_sout_options[] = {
74     "audio", "video", "delay", NULL
75 };
76
77 static sout_stream_id_sys_t *Add( sout_stream_t *, const es_format_t * );
78 static void              Del ( sout_stream_t *, sout_stream_id_sys_t * );
79 static int               Send( sout_stream_t *, sout_stream_id_sys_t *, block_t* );
80
81 struct sout_stream_sys_t
82 {
83     bool     b_audio;
84     bool     b_video;
85
86     mtime_t        i_delay;
87     input_resource_t *p_resource;
88 };
89
90 /*****************************************************************************
91  * Open:
92  *****************************************************************************/
93 static int Open( vlc_object_t *p_this )
94 {
95     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
96     sout_stream_sys_t *p_sys;
97
98     p_sys = malloc( sizeof( sout_stream_sys_t ) );
99     if( p_sys == NULL )
100         return VLC_ENOMEM;
101
102     p_sys->p_resource = input_resource_New( p_this );
103     if( unlikely(p_sys->p_resource == NULL) )
104     {
105         free( p_sys );
106         return VLC_ENOMEM;
107     }
108
109     config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
110                    p_stream->p_cfg );
111
112     p_sys->b_audio = var_GetBool( p_stream, SOUT_CFG_PREFIX"audio" );
113     p_sys->b_video = var_GetBool( p_stream, SOUT_CFG_PREFIX "video" );
114     p_sys->i_delay = var_GetInteger( p_stream, SOUT_CFG_PREFIX "delay" );
115     p_sys->i_delay = p_sys->i_delay * CLOCK_FREQ / 1000;
116
117     p_stream->pf_add    = Add;
118     p_stream->pf_del    = Del;
119     p_stream->pf_send   = Send;
120     p_stream->p_sys     = p_sys;
121     p_stream->pace_nocontrol = true;
122
123     return VLC_SUCCESS;
124 }
125
126 /*****************************************************************************
127  * Close:
128  *****************************************************************************/
129 static void Close( vlc_object_t * p_this )
130 {
131     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
132     sout_stream_sys_t *p_sys = p_stream->p_sys;
133
134     input_resource_Terminate( p_sys->p_resource );
135     input_resource_Release( p_sys->p_resource );
136     free( p_sys );
137 }
138
139 static sout_stream_id_sys_t * Add( sout_stream_t *p_stream, const es_format_t *p_fmt )
140 {
141     sout_stream_sys_t *p_sys = p_stream->p_sys;
142
143     if( ( p_fmt->i_cat == AUDIO_ES && !p_sys->b_audio )||
144         ( p_fmt->i_cat == VIDEO_ES && !p_sys->b_video ) )
145     {
146         return NULL;
147     }
148
149     decoder_t *p_dec = input_DecoderCreate( VLC_OBJECT(p_stream), p_fmt,
150                                             p_sys->p_resource );
151     if( p_dec == NULL )
152     {
153         msg_Err( p_stream, "cannot create decoder for fcc=`%4.4s'",
154                  (char*)&p_fmt->i_codec );
155         return NULL;
156     }
157     return (sout_stream_id_sys_t *)p_dec;
158 }
159
160 static void Del( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
161 {
162     (void) p_stream;
163     input_DecoderDelete( (decoder_t *)id );
164 }
165
166 static int Send( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
167                  block_t *p_buffer )
168 {
169     sout_stream_sys_t *p_sys = p_stream->p_sys;
170
171     while( p_buffer )
172     {
173         block_t *p_next = p_buffer->p_next;
174
175         p_buffer->p_next = NULL;
176
177         if( id != NULL && p_buffer->i_buffer > 0 )
178         {
179             if( p_buffer->i_dts <= VLC_TS_INVALID )
180                 p_buffer->i_dts = 0;
181             else
182                 p_buffer->i_dts += p_sys->i_delay;
183
184             if( p_buffer->i_pts <= VLC_TS_INVALID )
185                 p_buffer->i_pts = 0;
186             else
187                 p_buffer->i_pts += p_sys->i_delay;
188
189             input_DecoderDecode( (decoder_t *)id, p_buffer, false );
190         }
191
192         p_buffer = p_next;
193     }
194
195     return VLC_SUCCESS;
196 }