packetizer: hevc: don't double store poc prev msb/lsb
[vlc.git] / modules / stream_out / es.c
bloba03c40276d39776e92e5525be9f4ac9509aa35ce
1 /*****************************************************************************
2 * es.c: Elementary stream output module
3 *****************************************************************************
4 * Copyright (C) 2003-2004 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Laurent Aimar <fenrir@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 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_input.h>
35 #include <vlc_sout.h>
36 #include <vlc_dialog.h>
37 #include <vlc_memstream.h>
39 /*****************************************************************************
40 * Module descriptor
41 *****************************************************************************/
42 #define ACCESS_TEXT N_("Output access method")
43 #define ACCESS_LONGTEXT N_( \
44 "This is the default output access method that will be used." )
46 #define ACCESSA_TEXT N_("Audio output access method")
47 #define ACCESSA_LONGTEXT N_( \
48 "This is the output access method that will be used for audio." )
49 #define ACCESSV_TEXT N_("Video output access method")
50 #define ACCESSV_LONGTEXT N_( \
51 "This is the output access method that will be used for video." )
53 #define MUX_TEXT N_("Output muxer")
54 #define MUX_LONGTEXT N_( \
55 "This is the default muxer method that will be used." )
56 #define MUXA_TEXT N_("Audio output muxer")
57 #define MUXA_LONGTEXT N_( \
58 "This is the muxer that will be used for audio." )
59 #define MUXV_TEXT N_("Video output muxer")
60 #define MUXV_LONGTEXT N_( \
61 "This is the muxer that will be used for video." )
63 #define DEST_TEXT N_("Output URL")
64 #define DEST_LONGTEXT N_( \
65 "This is the default output URI." )
66 #define DESTA_TEXT N_("Audio output URL")
67 #define DESTA_LONGTEXT N_( \
68 "This is the output URI that will be used for audio." )
69 #define DESTV_TEXT N_("Video output URL")
70 #define DESTV_LONGTEXT N_( \
71 "This is the output URI that will be used for video." )
73 static int Open ( vlc_object_t * );
74 static void Close ( vlc_object_t * );
76 #define SOUT_CFG_PREFIX "sout-es-"
78 vlc_module_begin ()
79 set_shortname( "ES" )
80 set_description( N_("Elementary stream output") )
81 set_capability( "sout stream", 50 )
82 add_shortcut( "es" )
83 set_category( CAT_SOUT )
84 set_subcategory( SUBCAT_SOUT_STREAM )
86 set_section( N_("Generic"), NULL )
87 add_string( SOUT_CFG_PREFIX "access", "", ACCESS_TEXT,
88 ACCESS_LONGTEXT, true )
89 add_string( SOUT_CFG_PREFIX "mux", "", MUX_TEXT,
90 MUX_LONGTEXT, true )
91 add_string( SOUT_CFG_PREFIX "dst", "", DEST_TEXT,
92 DEST_LONGTEXT, true )
94 set_section( N_("Audio"), NULL )
95 add_string( SOUT_CFG_PREFIX "access-audio", "", ACCESSA_TEXT,
96 ACCESSA_LONGTEXT, true )
97 add_string( SOUT_CFG_PREFIX "mux-audio", "", MUXA_TEXT,
98 MUXA_LONGTEXT, true )
99 add_string( SOUT_CFG_PREFIX "dst-audio", "", DESTA_TEXT,
100 DESTA_LONGTEXT, true )
102 set_section( N_("Video"), NULL )
103 add_string( SOUT_CFG_PREFIX "access-video", "", ACCESSV_TEXT,
104 ACCESSV_LONGTEXT, true )
105 add_string( SOUT_CFG_PREFIX "mux-video", "", MUXV_TEXT,
106 MUXV_LONGTEXT, true )
107 add_string( SOUT_CFG_PREFIX "dst-video", "", DESTV_TEXT,
108 DESTV_LONGTEXT, true )
110 set_callbacks( Open, Close )
111 vlc_module_end ()
113 /*****************************************************************************
114 * Exported prototypes
115 *****************************************************************************/
116 static const char *const ppsz_sout_options[] = {
117 "access", "access-audio", "access-video",
118 "mux", "mux-audio", "mux-video",
119 "dst", "dst-audio", "dst-video",
120 NULL
123 static sout_stream_id_sys_t *Add( sout_stream_t *, const es_format_t * );
124 static void Del ( sout_stream_t *, sout_stream_id_sys_t * );
125 static int Send( sout_stream_t *, sout_stream_id_sys_t *, block_t* );
127 struct sout_stream_sys_t
129 int i_count_audio;
130 int i_count_video;
131 int i_count;
133 char *psz_mux;
134 char *psz_mux_audio;
135 char *psz_mux_video;
137 char *psz_access;
138 char *psz_access_audio;
139 char *psz_access_video;
141 char *psz_dst;
142 char *psz_dst_audio;
143 char *psz_dst_video;
146 /*****************************************************************************
147 * Open:
148 *****************************************************************************/
149 static int Open( vlc_object_t *p_this )
151 sout_stream_t *p_stream = (sout_stream_t*)p_this;
152 sout_stream_sys_t *p_sys;
154 config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg );
155 p_sys = malloc( sizeof( sout_stream_sys_t ) );
157 p_sys->i_count = 0;
158 p_sys->i_count_audio = 0;
159 p_sys->i_count_video = 0;
161 p_sys->psz_access = var_GetString( p_stream, SOUT_CFG_PREFIX "access" );
162 p_sys->psz_access_audio = var_GetString( p_stream, SOUT_CFG_PREFIX "access-audio" );
163 p_sys->psz_access_video = var_GetString( p_stream, SOUT_CFG_PREFIX "access-video" );
165 p_sys->psz_mux = var_GetString( p_stream, SOUT_CFG_PREFIX "mux" );
166 p_sys->psz_mux_audio = var_GetString( p_stream, SOUT_CFG_PREFIX "mux-audio" );
167 p_sys->psz_mux_video = var_GetString( p_stream, SOUT_CFG_PREFIX "mux-video" );
169 p_sys->psz_dst = var_GetString( p_stream, SOUT_CFG_PREFIX "dst" );
170 p_sys->psz_dst_audio = var_GetString( p_stream, SOUT_CFG_PREFIX "dst-audio" );
171 p_sys->psz_dst_video = var_GetString( p_stream, SOUT_CFG_PREFIX "dst-video" );
173 p_stream->pf_add = Add;
174 p_stream->pf_del = Del;
175 p_stream->pf_send = Send;
177 p_stream->p_sys = p_sys;
179 return VLC_SUCCESS;
182 /*****************************************************************************
183 * Close:
184 *****************************************************************************/
186 static void Close( vlc_object_t * p_this )
188 sout_stream_t *p_stream = (sout_stream_t*)p_this;
189 sout_stream_sys_t *p_sys = p_stream->p_sys;
191 free( p_sys->psz_access );
192 free( p_sys->psz_access_audio );
193 free( p_sys->psz_access_video );
195 free( p_sys->psz_mux );
196 free( p_sys->psz_mux_audio );
197 free( p_sys->psz_mux_video );
199 free( p_sys->psz_dst );
200 free( p_sys->psz_dst_audio );
201 free( p_sys->psz_dst_video );
203 free( p_sys );
206 struct sout_stream_id_sys_t
208 sout_input_t *p_input;
209 sout_mux_t *p_mux;
212 static char * es_print_url( const char *psz_fmt, vlc_fourcc_t i_fourcc, int i_count,
213 const char *psz_access, const char *psz_mux )
215 struct vlc_memstream stream;
216 unsigned char c;
218 if (vlc_memstream_open(&stream))
219 return NULL;
221 if( psz_fmt == NULL || !*psz_fmt )
222 psz_fmt = "stream-%n-%c.%m";
224 while ((c = *(psz_fmt++)) != '\0')
226 if (c != '%')
228 vlc_memstream_putc(&stream, c);
229 continue;
232 switch (c = *(psz_fmt++))
234 case 'n':
235 vlc_memstream_printf(&stream, "%d", i_count);
236 break;
237 case 'c':
238 vlc_memstream_printf(&stream, "%4.4s", (char *)&i_fourcc);
239 break;
240 case 'm':
241 vlc_memstream_puts(&stream, psz_mux);
242 break;
243 case 'a':
244 vlc_memstream_puts(&stream, psz_access);
245 break;
246 case '\0':
247 vlc_memstream_putc(&stream, '%');
248 goto out;
249 default:
250 vlc_memstream_printf(&stream, "%%%c", (int) c);
251 break;
254 out:
255 if (vlc_memstream_close(&stream))
256 return NULL;
257 return stream.ptr;
260 static sout_stream_id_sys_t *Add( sout_stream_t *p_stream, const es_format_t *p_fmt )
262 sout_stream_sys_t *p_sys = p_stream->p_sys;
263 sout_stream_id_sys_t *id;
265 const char *psz_access;
266 const char *psz_mux;
267 char *psz_dst;
269 sout_access_out_t *p_access;
270 sout_mux_t *p_mux;
272 /* *** get access name *** */
273 if( p_fmt->i_cat == AUDIO_ES && p_sys->psz_access_audio && *p_sys->psz_access_audio )
275 psz_access = p_sys->psz_access_audio;
277 else if( p_fmt->i_cat == VIDEO_ES && p_sys->psz_access_video && *p_sys->psz_access_video )
279 psz_access = p_sys->psz_access_video;
281 else
283 psz_access = p_sys->psz_access;
286 /* *** get mux name *** */
287 if( p_fmt->i_cat == AUDIO_ES && p_sys->psz_mux_audio && *p_sys->psz_mux_audio )
289 psz_mux = p_sys->psz_mux_audio;
291 else if( p_fmt->i_cat == VIDEO_ES && p_sys->psz_mux_video && *p_sys->psz_mux_video )
293 psz_mux = p_sys->psz_mux_video;
295 else
297 psz_mux = p_sys->psz_mux;
300 /* Get url (%d expanded as a codec count, %c expanded as codec fcc ) */
301 if( p_fmt->i_cat == AUDIO_ES && p_sys->psz_dst_audio && *p_sys->psz_dst_audio )
303 psz_dst = es_print_url( p_sys->psz_dst_audio, p_fmt->i_codec,
304 p_sys->i_count_audio, psz_access, psz_mux );
306 else if( p_fmt->i_cat == VIDEO_ES && p_sys->psz_dst_video && *p_sys->psz_dst_video )
308 psz_dst = es_print_url( p_sys->psz_dst_video, p_fmt->i_codec,
309 p_sys->i_count_video, psz_access, psz_mux );
311 else
313 int i_count;
314 if( p_fmt->i_cat == VIDEO_ES )
316 i_count = p_sys->i_count_video;
318 else if( p_fmt->i_cat == AUDIO_ES )
320 i_count = p_sys->i_count_audio;
322 else
324 i_count = p_sys->i_count;
327 psz_dst = es_print_url( p_sys->psz_dst, p_fmt->i_codec,
328 i_count, psz_access, psz_mux );
331 p_sys->i_count++;
332 if( p_fmt->i_cat == VIDEO_ES )
334 p_sys->i_count_video++;
336 else if( p_fmt->i_cat == AUDIO_ES )
338 p_sys->i_count_audio++;
340 msg_Dbg( p_stream, "creating `%s/%s://%s'",
341 psz_access, psz_mux, psz_dst );
343 /* *** find and open appropriate access module *** */
344 p_access = sout_AccessOutNew( p_stream, psz_access, psz_dst );
345 if( p_access == NULL )
347 msg_Err( p_stream, "no suitable sout access module for `%s/%s://%s'",
348 psz_access, psz_mux, psz_dst );
349 vlc_dialog_display_error( p_stream, _("Streaming / Transcoding failed"),
350 _("There is no suitable stream-output access module for \"%s/%s://%s\"."),
351 psz_access, psz_mux, psz_dst );
352 free( psz_dst );
353 return( NULL );
356 /* *** find and open appropriate mux module *** */
357 p_mux = sout_MuxNew( p_stream->p_sout, psz_mux, p_access );
358 if( p_mux == NULL )
360 msg_Err( p_stream, "no suitable sout mux module for `%s/%s://%s'",
361 psz_access, psz_mux, psz_dst );
362 vlc_dialog_display_error( p_stream, _("Streaming / Transcoding failed"),
363 _("There is no suitable stream-output access module "\
364 "for \"%s/%s://%s\"."), psz_access, psz_mux, psz_dst );
365 sout_AccessOutDelete( p_access );
366 free( psz_dst );
367 return( NULL );
369 free( psz_dst );
371 id = malloc( sizeof( sout_stream_id_sys_t ) );
372 if( !id )
374 sout_MuxDelete( p_mux );
375 sout_AccessOutDelete( p_access );
376 return NULL;
378 id->p_mux = p_mux;
379 id->p_input = sout_MuxAddStream( p_mux, p_fmt );
381 if( id->p_input == NULL )
383 sout_MuxDelete( p_mux );
384 sout_AccessOutDelete( p_access );
385 free( id );
386 return NULL;
389 if( !sout_AccessOutCanControlPace( p_access ) )
390 p_stream->p_sout->i_out_pace_nocontrol++;
392 return id;
395 static void Del( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
397 VLC_UNUSED(p_stream);
398 sout_access_out_t *p_access = id->p_mux->p_access;
400 sout_MuxDeleteStream( id->p_mux, id->p_input );
401 sout_MuxDelete( id->p_mux );
402 if( !sout_AccessOutCanControlPace( p_access ) )
403 p_stream->p_sout->i_out_pace_nocontrol--;
404 sout_AccessOutDelete( p_access );
406 free( id );
409 static int Send( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
410 block_t *p_buffer )
412 VLC_UNUSED(p_stream);
413 return sout_MuxSendBuffer( id->p_mux, id->p_input, p_buffer );