1 /*****************************************************************************
2 * ps.c: MPEG PS (ISO/IEC 13818-1) / MPEG SYSTEM (ISO/IEC 1172-1)
3 * multiplexer module for vlc
4 *****************************************************************************
5 * Copyright (C) 2001, 2002 VLC authors and VideoLAN
8 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * Eric Petit <titer@videolan.org>
10 * Gildas Bazin <gbazin@videolan.org>
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU Lesser General Public License as published by
14 * the Free Software Foundation; either version 2.1 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
38 #include <vlc_block.h>
43 #include <vlc_iso_lang.h>
45 /*****************************************************************************
47 *****************************************************************************/
48 #define DTS_TEXT N_("DTS delay (ms)")
49 #define DTS_LONGTEXT N_("Delay the DTS (decoding time " \
50 "stamps) and PTS (presentation timestamps) of the data in the " \
51 "stream, compared to the SCRs. This allows for some buffering inside " \
52 "the client decoder.")
54 #define PES_SIZE_TEXT N_("PES maximum size")
55 #define PES_SIZE_LONGTEXT N_("Set the maximum allowed PES "\
56 "size when producing the MPEG PS streams.")
58 static int Open ( vlc_object_t
* );
59 static void Close ( vlc_object_t
* );
61 #define SOUT_CFG_PREFIX "sout-ps-"
64 set_description( N_("PS muxer") )
65 set_shortname( "MPEG-PS" )
66 set_category( CAT_SOUT
)
67 set_subcategory( SUBCAT_SOUT_MUX
)
68 set_capability( "sout mux", 50 )
69 add_shortcut( "ps", "mpeg1", "dvd" )
70 set_callbacks( Open
, Close
)
72 add_integer( SOUT_CFG_PREFIX
"dts-delay", 200, DTS_TEXT
,
74 add_integer( SOUT_CFG_PREFIX
"pes-max-size", PES_PAYLOAD_SIZE_MAX
,
75 PES_SIZE_TEXT
, PES_SIZE_LONGTEXT
, true )
78 /*****************************************************************************
80 *****************************************************************************/
81 static int Control ( sout_mux_t
*, int, va_list );
82 static int AddStream( sout_mux_t
*, sout_input_t
* );
83 static void DelStream( sout_mux_t
*, sout_input_t
* );
84 static int Mux ( sout_mux_t
* );
86 /*****************************************************************************
88 *****************************************************************************/
90 static void MuxWritePackHeader ( sout_mux_t
*, block_t
**, mtime_t
);
91 static void MuxWriteSystemHeader( sout_mux_t
*, block_t
**, mtime_t
);
92 static void MuxWritePSM ( sout_mux_t
*, block_t
**, mtime_t
);
94 static void StreamIdInit ( bool *id
, int i_range
);
95 static int StreamIdGet ( bool *id
, int i_id_min
, int i_id_max
);
96 static void StreamIdRelease ( bool *id
, int i_id_min
, int i_id
);
98 typedef struct ps_stream_s
102 int i_max_buff_size
; /* used in system header */
104 /* Language is iso639-2T */
112 /* Which id are unused */
113 bool stream_id_mpga
[16]; /* 0xc0 -> 0xcf */
114 bool stream_id_mpgv
[16]; /* 0xe0 -> 0xef */
115 bool stream_id_a52
[8]; /* 0x80 -> 0x87 <- FIXME I'm not sure */
116 bool stream_id_spu
[32]; /* 0x20 -> 0x3f */
117 bool stream_id_dts
[8]; /* 0x88 -> 0x8f */
118 bool stream_id_lpcm
[16]; /* 0xa0 -> 0xaf */
125 int i_rate_bound
; /* units of 50 bytes/second */
127 int64_t i_instant_bitrate
;
128 int64_t i_instant_size
;
129 mtime_t i_instant_dts
;
136 uint32_t crc32_table
[256];
139 static const char *const ppsz_sout_options
[] = {
140 "dts-delay", "pes-max-size", NULL
143 /*****************************************************************************
145 *****************************************************************************/
146 static int Open( vlc_object_t
*p_this
)
148 sout_mux_t
*p_mux
= (sout_mux_t
*)p_this
;
149 sout_mux_sys_t
*p_sys
;
152 msg_Info( p_mux
, "Open" );
153 config_ChainParse( p_mux
, SOUT_CFG_PREFIX
, ppsz_sout_options
, p_mux
->p_cfg
);
155 p_mux
->pf_control
= Control
;
156 p_mux
->pf_addstream
= AddStream
;
157 p_mux
->pf_delstream
= DelStream
;
159 p_mux
->p_sys
= p_sys
= malloc( sizeof( sout_mux_sys_t
) );
161 /* Init free stream id */
162 StreamIdInit( p_sys
->stream_id_a52
, 8 );
163 StreamIdInit( p_sys
->stream_id_dts
, 8 );
164 StreamIdInit( p_sys
->stream_id_mpga
, 16 );
165 StreamIdInit( p_sys
->stream_id_mpgv
, 16 );
166 StreamIdInit( p_sys
->stream_id_lpcm
, 16 );
167 StreamIdInit( p_sys
->stream_id_spu
, 32 );
169 p_sys
->i_audio_bound
= 0;
170 p_sys
->i_video_bound
= 0;
171 p_sys
->i_system_header
= 0;
172 p_sys
->i_pes_count
= 0;
174 p_sys
->i_psm_version
= 0;
176 p_sys
->i_instant_bitrate
= 0;
177 p_sys
->i_instant_size
= 0;
178 p_sys
->i_instant_dts
= 0;
179 p_sys
->i_rate_bound
= 0;
180 p_sys
->b_mpeg2
= !(p_mux
->psz_mux
&& !strcmp( p_mux
->psz_mux
, "mpeg1" ));
182 var_Get( p_mux
, SOUT_CFG_PREFIX
"dts-delay", &val
);
183 p_sys
->i_dts_delay
= (int64_t)val
.i_int
* 1000;
185 var_Get( p_mux
, SOUT_CFG_PREFIX
"pes-max-size", &val
);
186 p_sys
->i_pes_max_size
= (int64_t)val
.i_int
;
188 /* Initialise CRC32 table */
193 for( i
= 0; i
< 256; i
++ )
196 for( j
= (i
<< 24) | 0x800000; j
!= 0x80000000; j
<<= 1 )
197 k
= (k
<< 1) ^ (((k
^ j
) & 0x80000000) ? 0x04c11db7 : 0);
199 p_sys
->crc32_table
[i
] = k
;
206 /*****************************************************************************
208 *****************************************************************************/
209 static void Close( vlc_object_t
* p_this
)
211 sout_mux_t
*p_mux
= (sout_mux_t
*)p_this
;
212 sout_mux_sys_t
*p_sys
= p_mux
->p_sys
;
216 msg_Info( p_mux
, "Close" );
218 p_end
= block_Alloc( 4 );
221 p_end
->p_buffer
[0] = 0x00; p_end
->p_buffer
[1] = 0x00;
222 p_end
->p_buffer
[2] = 0x01; p_end
->p_buffer
[3] = 0xb9;
224 sout_AccessOutWrite( p_mux
->p_access
, p_end
);
230 /*****************************************************************************
232 *****************************************************************************/
233 static int Control( sout_mux_t
*p_mux
, int i_query
, va_list args
)
241 case MUX_CAN_ADD_STREAM_WHILE_MUXING
:
242 pb_bool
= va_arg( args
, bool * );
246 case MUX_GET_ADD_STREAM_WAIT
:
247 pb_bool
= va_arg( args
, bool * );
252 ppsz
= va_arg( args
, char ** );
253 *ppsz
= strdup( "video/mpeg" );
261 /*****************************************************************************
263 *****************************************************************************/
264 static int AddStream( sout_mux_t
*p_mux
, sout_input_t
*p_input
)
266 sout_mux_sys_t
*p_sys
= p_mux
->p_sys
;
267 ps_stream_t
*p_stream
;
270 msg_Dbg( p_mux
, "adding input codec=%4.4s",
271 (char*)&p_input
->p_fmt
->i_codec
);
273 p_input
->p_sys
= p_stream
= malloc( sizeof( ps_stream_t
) );
274 if( unlikely(p_input
->p_sys
== NULL
) )
276 p_stream
->i_stream_type
= 0x81;
277 p_stream
->i_dts
= -1;
279 /* Init this new stream */
280 switch( p_input
->p_fmt
->i_codec
)
285 p_stream
->i_stream_id
=
286 StreamIdGet( p_sys
->stream_id_mpgv
, 0xe0, 0xef );
287 p_stream
->i_stream_type
= 0x02; /* ISO/IEC 13818 Video */
290 p_stream
->i_stream_id
=
291 StreamIdGet( p_sys
->stream_id_mpgv
, 0xe0, 0xef );
292 p_stream
->i_stream_type
= 0x10;
295 p_stream
->i_stream_id
=
296 StreamIdGet( p_sys
->stream_id_mpgv
, 0xe0, 0xef );
297 p_stream
->i_stream_type
= 0x1b;
299 case VLC_CODEC_DVD_LPCM
:
300 p_stream
->i_stream_id
=
301 0xbd00 | StreamIdGet( p_sys
->stream_id_lpcm
, 0xa0, 0xaf );
304 p_stream
->i_stream_id
=
305 0xbd00 | StreamIdGet( p_sys
->stream_id_dts
, 0x88, 0x8f );
308 p_stream
->i_stream_id
=
309 0xbd00 | StreamIdGet( p_sys
->stream_id_a52
, 0x80, 0x87 );
312 p_stream
->i_stream_id
=
313 StreamIdGet( p_sys
->stream_id_mpga
, 0xc0, 0xcf );
314 p_stream
->i_stream_type
= 0x03; /* ISO/IEC 11172 Audio */
317 p_stream
->i_stream_id
=
318 StreamIdGet( p_sys
->stream_id_mpga
, 0xc0, 0xcf );
319 p_stream
->i_stream_type
= 0x0f;
322 p_stream
->i_stream_id
=
323 0xbd00 | StreamIdGet( p_sys
->stream_id_spu
, 0x20, 0x3f );
329 if( p_stream
->i_stream_id
< 0 ) goto error
;
331 if( p_input
->p_fmt
->i_cat
== AUDIO_ES
)
333 p_sys
->i_audio_bound
++;
334 p_stream
->i_max_buff_size
= 4 * 1024;
336 else if( p_input
->p_fmt
->i_cat
== VIDEO_ES
)
338 p_sys
->i_video_bound
++;
339 p_stream
->i_max_buff_size
= 400 * 1024; /* FIXME -- VCD uses 46, SVCD
340 uses 230, ffmpeg has 230 with a note that it is small */
343 { /* FIXME -- what's valid for not audio or video? */
344 p_stream
->i_max_buff_size
= 4 * 1024;
347 /* Try to set a sensible default value for the instant bitrate */
348 p_sys
->i_instant_bitrate
+= p_input
->p_fmt
->i_bitrate
+ 1000/* overhead */;
350 /* FIXME -- spec requires an upper limit rate boundary in the system header;
351 our codecs are VBR; using 2x nominal rate, convert to 50 bytes/sec */
352 p_sys
->i_rate_bound
+= p_input
->p_fmt
->i_bitrate
* 2 / (8 * 50);
353 p_sys
->i_psm_version
++;
355 p_stream
->lang
[0] = p_stream
->lang
[1] = p_stream
->lang
[2] = 0;
356 if( p_input
->p_fmt
->psz_language
)
358 char *psz
= p_input
->p_fmt
->psz_language
;
359 const iso639_lang_t
*pl
= NULL
;
361 if( strlen( psz
) == 2 )
363 pl
= GetLang_1( psz
);
365 else if( strlen( psz
) == 3 )
367 pl
= GetLang_2B( psz
);
368 if( !strcmp( pl
->psz_iso639_1
, "??" ) )
370 pl
= GetLang_2T( psz
);
373 if( pl
&& strcmp( pl
->psz_iso639_1
, "??" ) )
375 p_stream
->lang
[0] = pl
->psz_iso639_2T
[0];
376 p_stream
->lang
[1] = pl
->psz_iso639_2T
[1];
377 p_stream
->lang
[2] = pl
->psz_iso639_2T
[2];
379 msg_Dbg( p_mux
, " - lang=%c%c%c",
380 p_stream
->lang
[0], p_stream
->lang
[1], p_stream
->lang
[2] );
390 /*****************************************************************************
392 *****************************************************************************/
393 static void DelStream( sout_mux_t
*p_mux
, sout_input_t
*p_input
)
395 sout_mux_sys_t
*p_sys
= p_mux
->p_sys
;
396 ps_stream_t
*p_stream
=(ps_stream_t
*)p_input
->p_sys
;
398 msg_Dbg( p_mux
, "removing input" );
399 switch( p_input
->p_fmt
->i_codec
)
402 StreamIdRelease( p_sys
->stream_id_mpgv
, 0xe0,
403 p_stream
->i_stream_id
);
405 case VLC_CODEC_DVD_LPCM
:
406 StreamIdRelease( p_sys
->stream_id_lpcm
, 0xa0,
407 p_stream
->i_stream_id
&0xff );
410 StreamIdRelease( p_sys
->stream_id_dts
, 0x88,
411 p_stream
->i_stream_id
&0xff );
414 StreamIdRelease( p_sys
->stream_id_a52
, 0x80,
415 p_stream
->i_stream_id
&0xff );
418 StreamIdRelease( p_sys
->stream_id_mpga
, 0xc0,
419 p_stream
->i_stream_id
);
422 StreamIdRelease( p_sys
->stream_id_spu
, 0x20,
423 p_stream
->i_stream_id
&0xff );
430 if( p_input
->p_fmt
->i_cat
== AUDIO_ES
)
432 p_sys
->i_audio_bound
--;
434 else if( p_input
->p_fmt
->i_cat
== VIDEO_ES
)
436 p_sys
->i_video_bound
--;
439 /* Try to set a sensible default value for the instant bitrate */
440 p_sys
->i_instant_bitrate
-= (p_input
->p_fmt
->i_bitrate
+ 1000);
441 /* rate_bound is in units of 50 bytes/second */
442 p_sys
->i_rate_bound
-= (p_input
->p_fmt
->i_bitrate
* 2)/(8 * 50);
444 p_sys
->i_psm_version
++;
449 /*****************************************************************************
450 * Mux: Call each time there is new data for at least one stream
451 *****************************************************************************/
452 static int Mux( sout_mux_t
*p_mux
)
454 sout_mux_sys_t
*p_sys
= p_mux
->p_sys
;
458 sout_input_t
*p_input
;
459 ps_stream_t
*p_stream
;
461 block_t
*p_ps
, *p_data
;
465 /* Choose which stream to mux */
466 int i_stream
= sout_MuxGetStream( p_mux
, 1, &i_dts
);
472 p_input
= p_mux
->pp_inputs
[i_stream
];
473 p_stream
= (ps_stream_t
*)p_input
->p_sys
;
476 p_stream
->i_dts
= i_dts
;
478 /* Write regulary PackHeader */
479 if( p_sys
->i_pes_count
% 30 == 0)
481 mtime_t i_mindts
= INT64_MAX
;
482 for( size_t i
=0; i
<p_mux
->i_nb_inputs
; i
++ )
484 ps_stream_t
*p_s
= (ps_stream_t
*)p_input
->p_sys
;
485 if( p_input
->p_fmt
->i_cat
== SPU_ES
&& p_mux
->i_nb_inputs
> 1 )
487 if( p_s
->i_dts
>= 0 && i_mindts
> p_s
->i_dts
)
488 i_mindts
= p_s
->i_dts
;
491 if( i_mindts
> p_sys
->i_instant_dts
)
493 /* Update the instant bitrate every second or so */
494 if( p_sys
->i_instant_size
&&
495 i_dts
- p_sys
->i_instant_dts
> 1*CLOCK_FREQ
)
497 int64_t i_instant_bitrate
= p_sys
->i_instant_size
* 8000000 /
498 ( i_dts
- p_sys
->i_instant_dts
);
500 p_sys
->i_instant_bitrate
+= i_instant_bitrate
;
501 p_sys
->i_instant_bitrate
/= 2;
503 p_sys
->i_instant_size
= 0;
504 p_sys
->i_instant_dts
= i_dts
;
506 else if( !p_sys
->i_instant_size
)
508 p_sys
->i_instant_dts
= i_dts
;
511 MuxWritePackHeader( p_mux
, &p_ps
, i_dts
);
515 /* Write regulary SystemHeader */
516 if( p_sys
->i_pes_count
% 300 == 0 )
520 MuxWriteSystemHeader( p_mux
, &p_ps
, i_dts
);
522 /* For MPEG1 streaming, set HEADER flag */
523 for( p_pk
= p_ps
; p_pk
!= NULL
; p_pk
= p_pk
->p_next
)
525 p_pk
->i_flags
|= BLOCK_FLAG_HEADER
;
529 /* Write regulary ProgramStreamMap */
530 if( p_sys
->b_mpeg2
&& p_sys
->i_pes_count
% 300 == 0 )
532 MuxWritePSM( p_mux
, &p_ps
, i_dts
);
535 /* Get and mux a packet */
536 p_data
= block_FifoGet( p_input
->p_fifo
);
537 EStoPES ( &p_data
, p_input
->p_fmt
, p_stream
->i_stream_id
,
538 p_sys
->b_mpeg2
, 0, 0, p_sys
->i_pes_max_size
, 0 );
540 block_ChainAppend( &p_ps
, p_data
);
542 /* Get size of output data so we can calculate the instant bitrate */
543 for( p_data
= p_ps
; p_data
; p_data
= p_data
->p_next
)
545 p_sys
->i_instant_size
+= p_data
->i_buffer
;
548 sout_AccessOutWrite( p_mux
->p_access
, p_ps
);
550 /* Increase counter */
551 p_sys
->i_pes_count
++;
557 /*****************************************************************************
559 *****************************************************************************/
560 static void StreamIdInit( bool *id
, int i_range
)
564 for( i
= 0; i
< i_range
; i
++ )
569 static int StreamIdGet( bool *id
, int i_id_min
, int i_id_max
)
573 for( i
= 0; i
<= i_id_max
- i_id_min
; i
++ )
584 static void StreamIdRelease( bool *id
, int i_id_min
, int i_id
)
586 id
[i_id
- i_id_min
] = true;
589 static void MuxWritePackHeader( sout_mux_t
*p_mux
, block_t
**p_buf
,
592 sout_mux_sys_t
*p_sys
= p_mux
->p_sys
;
598 i_scr
= (i_dts
- p_sys
->i_dts_delay
) * 9 / 100;
600 p_hdr
= block_Alloc( 18 );
603 p_hdr
->i_pts
= p_hdr
->i_dts
= i_dts
;
604 bits_initwrite( &bits
, 14, p_hdr
->p_buffer
);
605 bits_write( &bits
, 32, 0x01ba );
607 /* The spec specifies that the mux rate must be rounded upwards */
608 i_mux_rate
= (p_sys
->i_instant_bitrate
+ 8 * 50 - 1 ) / (8 * 50);
612 bits_write( &bits
, 2, 0x01 );
616 bits_write( &bits
, 4, 0x02 );
619 bits_write( &bits
, 3, ( i_scr
>> 30 )&0x07 );
620 bits_write( &bits
, 1, 1 ); // marker
621 bits_write( &bits
, 15, ( i_scr
>> 15 )&0x7fff );
622 bits_write( &bits
, 1, 1 ); // marker
623 bits_write( &bits
, 15, i_scr
&0x7fff );
624 bits_write( &bits
, 1, 1 ); // marker
628 bits_write( &bits
, 9, 0 ); // src extension
630 bits_write( &bits
, 1, 1 ); // marker
632 bits_write( &bits
, 22, i_mux_rate
);
633 bits_write( &bits
, 1, 1 ); // marker
637 bits_write( &bits
, 1, 1 ); // marker
638 bits_write( &bits
, 5, 0x1f ); // reserved
639 bits_write( &bits
, 3, 0 ); // stuffing bytes
642 p_hdr
->i_buffer
= p_sys
->b_mpeg2
? 14: 12;
644 block_ChainAppend( p_buf
, p_hdr
);
647 static void MuxWriteSystemHeader( sout_mux_t
*p_mux
, block_t
**p_buf
,
650 sout_mux_sys_t
*p_sys
= p_mux
->p_sys
;
656 int i_nb_private
, i_nb_stream
;
659 /* Count the number of private stream */
660 for( i
= 0, i_nb_private
= 0; i
< p_mux
->i_nb_inputs
; i
++ )
662 ps_stream_t
*p_stream
;
664 p_stream
= (ps_stream_t
*)p_mux
->pp_inputs
[i
]->p_sys
;
666 if( ( p_stream
->i_stream_id
&0xff00 ) == 0xbd00 )
672 /* Private stream are declared only one time */
673 i_nb_stream
= p_mux
->i_nb_inputs
-
674 ( i_nb_private
> 0 ? i_nb_private
- 1 : 0 );
676 p_hdr
= block_Alloc( 12 + i_nb_stream
* 3 );
679 p_hdr
->i_dts
= p_hdr
->i_pts
= i_dts
;
681 /* The spec specifies that the reported rate_bound must be upper limit */
682 i_rate_bound
= (p_sys
->i_rate_bound
);
684 bits_initwrite( &bits
, 12 + i_nb_stream
* 3, p_hdr
->p_buffer
);
685 bits_write( &bits
, 32, 0x01bb );
686 bits_write( &bits
, 16, 12 - 6 + i_nb_stream
* 3 );
687 bits_write( &bits
, 1, 1 ); // marker bit
688 bits_write( &bits
, 22, i_rate_bound
);
689 bits_write( &bits
, 1, 1 ); // marker bit
691 bits_write( &bits
, 6, p_sys
->i_audio_bound
);
692 bits_write( &bits
, 1, 0 ); // fixed flag
693 bits_write( &bits
, 1, 0 ); // CSPS flag
694 bits_write( &bits
, 1, 0 ); // system audio lock flag
695 bits_write( &bits
, 1, 0 ); // system video lock flag
697 bits_write( &bits
, 1, 1 ); // marker bit
699 bits_write( &bits
, 5, p_sys
->i_video_bound
);
700 bits_write( &bits
, 1, 1 ); // packet rate restriction flag (1 for mpeg1)
701 bits_write( &bits
, 7, 0xff ); // reserved bits
703 /* stream_id table */
704 for( i
= 0, b_private
= false; i
< p_mux
->i_nb_inputs
; i
++ )
706 sout_input_t
*p_input
;
707 ps_stream_t
*p_stream
;
709 p_input
= p_mux
->pp_inputs
[i
];
710 p_stream
= (ps_stream_t
*)p_input
->p_sys
;
712 if( ( p_stream
->i_stream_id
&0xff00 ) == 0xbd00 )
719 /* Write stream id */
720 bits_write( &bits
, 8, 0xbd );
724 /* Write stream id */
725 bits_write( &bits
, 8, p_stream
->i_stream_id
&0xff );
728 bits_write( &bits
, 2, 0x03 ); /* reserved */
729 if( p_input
->p_fmt
->i_cat
== AUDIO_ES
)
731 bits_write( &bits
, 1, 0 );
732 bits_write( &bits
, 13, p_stream
->i_max_buff_size
/ 128 );
734 else if( p_input
->p_fmt
->i_cat
== VIDEO_ES
)
736 bits_write( &bits
, 1, 1 );
737 bits_write( &bits
, 13, p_stream
->i_max_buff_size
/ 1024);
741 /* FIXME -- the scale of 0 means do a /128 */
742 bits_write( &bits
, 1, 0 );
743 bits_write( &bits
, 13, p_stream
->i_max_buff_size
/ 128 );
747 block_ChainAppend( p_buf
, p_hdr
);
750 static void MuxWritePSM( sout_mux_t
*p_mux
, block_t
**p_buf
, mtime_t i_dts
)
752 sout_mux_sys_t
*p_sys
= p_mux
->p_sys
;
755 int i
, i_psm_size
= 16, i_es_map_size
= 0;
757 for( i
= 0; i
< p_mux
->i_nb_inputs
; i
++ )
759 sout_input_t
*p_input
= p_mux
->pp_inputs
[i
];
760 ps_stream_t
*p_stream
= p_input
->p_sys
;
763 if( p_stream
->lang
[0] != 0 ) i_es_map_size
+= 6;
766 i_psm_size
+= i_es_map_size
;
768 p_hdr
= block_Alloc( i_psm_size
);
771 p_hdr
->i_dts
= p_hdr
->i_pts
= i_dts
;
773 memset( p_hdr
->p_buffer
, 0, p_hdr
->i_buffer
);
774 bits_initwrite( &bits
, i_psm_size
, p_hdr
->p_buffer
);
775 bits_write( &bits
, 32, 0x01bc );
776 bits_write( &bits
, 16, i_psm_size
- 6 );
777 bits_write( &bits
, 1, 1 ); /* current_next_indicator */
778 bits_write( &bits
, 2, 0xF ); /* reserved */
779 bits_write( &bits
, 5, p_sys
->i_psm_version
);
780 bits_write( &bits
, 7, 0xFF ); /* reserved */
781 bits_write( &bits
, 1, 1 ); /* marker */
783 bits_write( &bits
, 16, 0 ); /* program_stream_info_length */
786 bits_write( &bits
, 16, i_es_map_size
); /* elementary_stream_map_length */
787 for( i
= 0; i
< p_mux
->i_nb_inputs
; i
++ )
789 sout_input_t
*p_input
= p_mux
->pp_inputs
[i
];
790 ps_stream_t
*p_stream
= p_input
->p_sys
;
792 bits_write( &bits
, 8, p_stream
->i_stream_type
); /* stream_type */
793 bits_write( &bits
, 8, p_stream
->i_stream_id
); /* elementary_stream_id */
795 /* ISO639 language descriptor */
796 if( p_stream
->lang
[0] != 0 )
798 bits_write( &bits
, 16, 6 ); /* elementary_stream_info_length */
800 bits_write( &bits
, 8, 0x0a ); /* descriptor_tag */
801 bits_write( &bits
, 8, 4 ); /* descriptor_length */
803 bits_write( &bits
, 8, p_stream
->lang
[0] );
804 bits_write( &bits
, 8, p_stream
->lang
[1] );
805 bits_write( &bits
, 8, p_stream
->lang
[2] );
806 bits_write( &bits
, 8, 0 ); /* audio type: 0x00 undefined */
810 bits_write( &bits
, 16, 0 ); /* elementary_stream_info_length */
816 uint32_t i_crc
= 0xffffffff;
817 for( i
= 0; (size_t)i
< p_hdr
->i_buffer
; i
++ )
818 i_crc
= (i_crc
<< 8) ^
819 p_sys
->crc32_table
[((i_crc
>> 24) ^ p_hdr
->p_buffer
[i
]) & 0xff];
821 bits_write( &bits
, 32, i_crc
);
824 block_ChainAppend( p_buf
, p_hdr
);