]> git.sesse.net Git - vlc/blob - modules/stream_out/setid.c
a2d8d4a8863af4e2096e48a333445d7438937904
[vlc] / modules / stream_out / setid.c
1 /*****************************************************************************
2  * setid.c: set ID/lang on a stream
3  *****************************************************************************
4  * Copyright (C) 2009-2011 VideoLAN and AUTHORS
5  *
6  * Authors: Christophe Massiot <massiot@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 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 General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, 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_t *AddId   ( sout_stream_t *, es_format_t * );
99 static sout_stream_id_t *AddLang ( sout_stream_t *, es_format_t * );
100 static int               Del     ( sout_stream_t *, sout_stream_id_t * );
101 static int               Send    ( sout_stream_t *, sout_stream_id_t *, block_t * );
102
103 struct sout_stream_sys_t
104 {
105     sout_stream_t    *p_out;
106     int              i_id;
107     int              i_new_id;
108     char             *psz_language;
109 };
110
111 /*****************************************************************************
112  * Open:
113  *****************************************************************************/
114 static int OpenCommon( vlc_object_t *p_this )
115 {
116     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
117     sout_stream_sys_t *p_sys;
118
119     p_sys = malloc( sizeof( sout_stream_sys_t ) );
120     if( unlikely( !p_sys ) )
121         return VLC_ENOMEM;
122
123     if( !p_stream->p_next )
124     {
125         msg_Err( p_stream, "cannot create chain" );
126         free( p_sys );
127         return VLC_EGENERIC;
128     }
129
130     p_stream->pf_del    = Del;
131     p_stream->pf_send   = Send;
132
133     p_stream->p_sys     = p_sys;
134
135     return VLC_SUCCESS;
136 }
137
138 static int OpenId( vlc_object_t *p_this )
139 {
140     int i_ret = OpenCommon( p_this );
141     if( i_ret != VLC_SUCCESS )
142         return i_ret;
143
144     sout_stream_t *p_stream = (sout_stream_t*)p_this;
145
146     config_ChainParse( p_stream, SOUT_CFG_PREFIX_ID, ppsz_sout_options_id,
147                        p_stream->p_cfg );
148
149     p_stream->p_sys->i_id = var_GetInteger( p_stream, SOUT_CFG_PREFIX_ID "id" );
150     p_stream->p_sys->i_new_id = var_GetInteger( p_stream, SOUT_CFG_PREFIX_ID "new-id" );
151     p_stream->p_sys->psz_language = NULL;
152
153     p_stream->pf_add = AddId;
154
155     return VLC_SUCCESS;
156 }
157
158 static int OpenLang( vlc_object_t *p_this )
159 {
160     int i_ret = OpenCommon( p_this );
161     if( i_ret != VLC_SUCCESS )
162         return i_ret;
163
164     sout_stream_t *p_stream = (sout_stream_t*)p_this;
165
166     config_ChainParse( p_stream, SOUT_CFG_PREFIX_LANG, ppsz_sout_options_lang,
167                        p_stream->p_cfg );
168
169     p_stream->p_sys->i_id = var_GetInteger( p_stream, SOUT_CFG_PREFIX_LANG "id" );
170     p_stream->p_sys->i_new_id = -1;
171     p_stream->p_sys->psz_language = var_GetString( p_stream, SOUT_CFG_PREFIX_LANG "lang" );
172
173     p_stream->pf_add = AddLang;
174
175     return VLC_SUCCESS;
176 }
177
178 /*****************************************************************************
179  * Close:
180  *****************************************************************************/
181 static void Close( vlc_object_t * p_this )
182 {
183     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
184     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
185
186     free( p_sys->psz_language );
187     free( p_sys );
188 }
189
190 static sout_stream_id_t * AddId( sout_stream_t *p_stream, es_format_t *p_fmt )
191 {
192     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
193
194     if ( p_fmt->i_id == p_sys->i_id )
195     {
196         msg_Dbg( p_stream, "turning ID %d to %d",
197                  p_sys->i_id, p_sys->i_new_id );
198         p_fmt->i_id = p_sys->i_new_id;
199     }
200
201     return p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
202 }
203
204 static sout_stream_id_t * AddLang( sout_stream_t *p_stream, es_format_t *p_fmt )
205 {
206     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
207
208     if ( p_fmt->i_id == p_sys->i_id )
209     {
210         msg_Dbg( p_stream, "turning language %s of ID %d to %s",
211                  p_fmt->psz_language ? p_fmt->psz_language : "unk",
212                  p_sys->i_id, p_sys->psz_language );
213         p_fmt->psz_language = strdup( p_sys->psz_language );
214     }
215
216     return p_sys->p_out->pf_add( p_sys->p_out, p_fmt );
217 }
218
219 static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
220 {
221     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
222
223     return p_sys->p_out->pf_del( p_sys->p_out, id );
224 }
225
226 static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
227                  block_t *p_buffer )
228 {
229     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
230
231     return p_sys->p_out->pf_send( p_sys->p_out, id, p_buffer );
232 }