]> git.sesse.net Git - vlc/blob - modules/stream_out/setid.c
aout: add wait parameter to aout_DecFlush()
[vlc] / modules / stream_out / setid.c
1 /*****************************************************************************
2  * setid.c: set ID/lang on a stream
3  *****************************************************************************
4  * Copyright © 2009-2011 VLC authors and VideoLAN
5  *
6  * Authors: Christophe Massiot <massiot@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 <stdlib.h>
32 #include <string.h>
33
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_sout.h>
37
38 /*****************************************************************************
39  * Module descriptor
40  *****************************************************************************/
41 #define ID_TEXT N_("Elementary Stream ID")
42 #define ID_LONGTEXT N_( \
43     "Specify an identifier integer for this elementary stream" )
44
45 #define NEWID_TEXT N_("New ES ID")
46 #define NEWID_LONGTEXT N_( \
47     "Specify an new identifier integer for this elementary stream" )
48
49 #define LANG_TEXT N_("Language")
50 #define LANG_LONGTEXT N_( \
51     "Specify an ISO-639 code (three characters) for this elementary stream" )
52
53 static int  OpenId    ( vlc_object_t * );
54 static int  OpenLang  ( vlc_object_t * );
55 static void Close     ( vlc_object_t * );
56
57 #define SOUT_CFG_PREFIX_ID   "sout-setid-"
58 #define SOUT_CFG_PREFIX_LANG "sout-setlang-"
59
60 vlc_module_begin()
61     set_shortname( N_("Set ID"))
62     set_section( N_("Set ES id"), NULL )
63     set_description( N_("Change the id of an elementary stream"))
64     set_capability( "sout stream", 50 )
65     add_shortcut( "setid" )
66     set_category( CAT_SOUT )
67     set_subcategory( SUBCAT_SOUT_STREAM )
68     set_callbacks( OpenId, Close )
69     add_integer( SOUT_CFG_PREFIX_ID "id", 0, ID_TEXT, ID_LONGTEXT, false )
70     add_integer( SOUT_CFG_PREFIX_ID "new-id", 0, NEWID_TEXT, NEWID_LONGTEXT,
71                  false )
72
73     add_submodule ()
74     set_section( N_("Set ES Lang"), NULL )
75     set_shortname( N_("Set Lang"))
76     set_description( N_("Change the language of an elementary stream"))
77     set_capability( "sout stream", 50 )
78     add_shortcut( "setlang" );
79     set_callbacks( OpenLang, Close )
80     add_integer( SOUT_CFG_PREFIX_LANG "id", 0, ID_TEXT, ID_LONGTEXT, false )
81     add_string( SOUT_CFG_PREFIX_LANG "lang", "eng", LANG_TEXT, LANG_LONGTEXT,
82                 false );
83
84 vlc_module_end()
85
86
87 /*****************************************************************************
88  * Local prototypes
89  *****************************************************************************/
90 static const char *ppsz_sout_options_id[] = {
91     "id", "new-id", NULL
92 };
93
94 static const char *ppsz_sout_options_lang[] = {
95     "id", "lang", NULL
96 };
97
98 static sout_stream_id_sys_t *AddId  ( sout_stream_t *, const es_format_t * );
99 static sout_stream_id_sys_t *AddLang( sout_stream_t *, const es_format_t * );
100 static void              Del     ( sout_stream_t *, sout_stream_id_sys_t * );
101 static int               Send    ( sout_stream_t *, sout_stream_id_sys_t *, block_t * );
102
103 struct sout_stream_sys_t
104 {
105     int              i_id;
106     int              i_new_id;
107     char             *psz_language;
108 };
109
110 /*****************************************************************************
111  * Open:
112  *****************************************************************************/
113 static int OpenCommon( vlc_object_t *p_this )
114 {
115     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
116     sout_stream_sys_t *p_sys;
117
118     if( !p_stream->p_next )
119     {
120         msg_Err( p_stream, "cannot create chain" );
121         return VLC_EGENERIC;
122     }
123
124     p_sys = malloc( sizeof( sout_stream_sys_t ) );
125     if( unlikely( !p_sys ) )
126         return VLC_ENOMEM;
127
128     p_stream->pf_del    = Del;
129     p_stream->pf_send   = Send;
130
131     p_stream->p_sys     = p_sys;
132
133     return VLC_SUCCESS;
134 }
135
136 static int OpenId( vlc_object_t *p_this )
137 {
138     int i_ret = OpenCommon( p_this );
139     if( i_ret != VLC_SUCCESS )
140         return i_ret;
141
142     sout_stream_t *p_stream = (sout_stream_t*)p_this;
143
144     config_ChainParse( p_stream, SOUT_CFG_PREFIX_ID, ppsz_sout_options_id,
145                        p_stream->p_cfg );
146
147     p_stream->p_sys->i_id = var_GetInteger( p_stream, SOUT_CFG_PREFIX_ID "id" );
148     p_stream->p_sys->i_new_id = var_GetInteger( p_stream, SOUT_CFG_PREFIX_ID "new-id" );
149     p_stream->p_sys->psz_language = NULL;
150
151     p_stream->pf_add = AddId;
152
153     return VLC_SUCCESS;
154 }
155
156 static int OpenLang( vlc_object_t *p_this )
157 {
158     int i_ret = OpenCommon( p_this );
159     if( i_ret != VLC_SUCCESS )
160         return i_ret;
161
162     sout_stream_t *p_stream = (sout_stream_t*)p_this;
163
164     config_ChainParse( p_stream, SOUT_CFG_PREFIX_LANG, ppsz_sout_options_lang,
165                        p_stream->p_cfg );
166
167     p_stream->p_sys->i_id = var_GetInteger( p_stream, SOUT_CFG_PREFIX_LANG "id" );
168     p_stream->p_sys->i_new_id = -1;
169     p_stream->p_sys->psz_language = var_GetString( p_stream, SOUT_CFG_PREFIX_LANG "lang" );
170
171     p_stream->pf_add = AddLang;
172
173     return VLC_SUCCESS;
174 }
175
176 /*****************************************************************************
177  * Close:
178  *****************************************************************************/
179 static void Close( vlc_object_t * p_this )
180 {
181     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
182     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
183
184     free( p_sys->psz_language );
185     free( p_sys );
186 }
187
188 static sout_stream_id_sys_t * AddId( sout_stream_t *p_stream, const es_format_t *p_fmt )
189 {
190     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
191     es_format_t fmt;
192
193     if( p_fmt->i_id == p_sys->i_id )
194     {
195         msg_Dbg( p_stream, "turning ID %d to %d", p_sys->i_id,
196                  p_sys->i_new_id );
197
198         fmt = *p_fmt;
199         fmt.i_id = p_sys->i_new_id;
200         p_fmt = &fmt;
201     }
202
203     return sout_StreamIdAdd( p_stream->p_next, p_fmt );
204 }
205
206 static sout_stream_id_sys_t * AddLang( sout_stream_t *p_stream, const es_format_t *p_fmt )
207 {
208     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
209     es_format_t fmt;
210
211     if ( p_fmt->i_id == p_sys->i_id )
212     {
213         msg_Dbg( p_stream, "turning language %s of ID %d to %s",
214                  p_fmt->psz_language ? p_fmt->psz_language : "unk",
215                  p_sys->i_id, p_sys->psz_language );
216
217         fmt = *p_fmt;
218         fmt.psz_language = p_sys->psz_language;
219         p_fmt = &fmt;
220     }
221
222     return sout_StreamIdAdd( p_stream->p_next, p_fmt );
223 }
224
225 static void Del( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
226 {
227     p_stream->p_next->pf_del( p_stream->p_next, id );
228 }
229
230 static int Send( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
231                  block_t *p_buffer )
232 {
233     return p_stream->p_next->pf_send( p_stream->p_next, id, p_buffer );
234 }