]> git.sesse.net Git - vlc/blob - modules/mux/mpeg/ts.c
7b7031c29b195b81574253496022f82ed1ca416a
[vlc] / modules / mux / mpeg / ts.c
1 /*****************************************************************************
2  * ts.c: MPEG-II TS Muxer
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Eric Petit <titer@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>
29
30 #include <vlc/vlc.h>
31 #include <vlc/input.h>
32 #include <vlc/sout.h>
33
34 #include "iso_lang.h"
35
36 #include "bits.h"
37 #include "pes.h"
38 #include "csa.h"
39
40 #ifdef HAVE_DVBPSI_DR_H
41 #   include <dvbpsi/dvbpsi.h>
42 #   include <dvbpsi/descriptor.h>
43 #   include <dvbpsi/pat.h>
44 #   include <dvbpsi/pmt.h>
45 #   include <dvbpsi/dr.h>
46 #   include <dvbpsi/psi.h>
47 #else
48 #   include "dvbpsi.h"
49 #   include "descriptor.h"
50 #   include "tables/pat.h"
51 #   include "tables/pmt.h"
52 #   include "descriptors/dr.h"
53 #   include "psi.h"
54 #endif
55
56 /*
57  * TODO:
58  *  - check PCR frequency requirement
59  *  - check PAT/PMT  "        "
60  *  - check PCR/PCR "soft"
61  *  - check if "registration" descriptor : "AC-3" should be a program
62  *    descriptor or an es one. (xine want an es one)
63  *
64  *  - remove creation of PAT/PMT without dvbpsi
65  *  - ?
66  * FIXME:
67  *  - subtitle support is far from perfect. I expect some subtitles drop
68  *    if they arrive a bit late
69  *    (We cannot rely on the fact that the fifo should be full)
70  */
71 /*****************************************************************************
72  * Module descriptor
73  *****************************************************************************/
74 static int     Open   ( vlc_object_t * );
75 static void    Close  ( vlc_object_t * );
76
77 #define VPID_TEXT N_("Video PID")
78 #define VPID_LONGTEXT N_("Assigns a fixed PID to the video stream. The PCR " \
79   "PID will automatically be the video.")
80 #define APID_TEXT N_("Audio PID")
81 #define APID_LONGTEXT N_("Assigns a fixed PID to the audio stream.")
82 #define SPUPID_TEXT N_("SPU PID")
83 #define SPUPID_LONGTEXT N_("Assigns a fixed PID to the SPU.")
84 #define PMTPID_TEXT N_("PMT PID")
85 #define PMTPID_LONGTEXT N_("Assings a fixed PID to the PMT")
86 #define TSID_TEXT N_("TS ID")
87 #define TSID_LONGTEXT N_("Assigns a fixed Transport Stream ID.")
88
89 #define SHAPING_TEXT N_("Shaping delay (ms)")
90 #define SHAPING_LONGTEXT N_("If enabled, the TS muxer will cut the " \
91   "stream in slices of the given duration, and ensure a constant bitrate " \
92   "between the two boundaries. This avoids having huge bitrate peaks for " \
93   "reference frames, in particular.")
94 #define KEYF_TEXT N_("Use keyframes")
95 #define KEYF_LONGTEXT N_("If enabled, and shaping is specified, " \
96   "the TS muxer will place the boundaries at the end of I pictures. In " \
97   "that case, the shaping duration given by the user is a worse case " \
98   "used when no reference frame is available. This enhances the efficiency " \
99   "of the shaping algorithm, since I frames are usually the biggest " \
100   "frames in the stream.")
101
102 #define PCR_TEXT N_("PCR delay (ms)")
103 #define PCR_LONGTEXT N_("This option allows you to set at which interval " \
104   "PCRs (Program Clock Reference) will be sent. " \
105   "This value should be below 100ms. (default is 30)")
106
107 #define BMIN_TEXT N_( "Minimum B (deprecated)")
108 #define BMIN_LONGTEXT N_( "This setting is deprecated and not used anymore" )
109
110 #define BMAX_TEXT N_( "Maximum B (deprecated)")
111 #define BMAX_LONGTEXT N_( "This setting is deprecated and not used anymore")
112
113 #define DTS_TEXT N_("DTS delay (ms)")
114 #define DTS_LONGTEXT N_("This option will delay the DTS (decoding time " \
115   "stamps) and PTS (presentation timestamps) of the data in the " \
116   "stream, compared to the PCRs. This allows for some buffering inside " \
117   "the client decoder.")
118
119 #define ACRYPT_TEXT N_("Crypt audio")
120 #define ACRYPT_LONGTEXT N_("Crypt audio using CSA")
121
122 #define CK_TEXT N_("CSA Key")
123 #define CK_LONGTEXT N_("Defines the CSA encryption key. This must be a " \
124   "16 char string (8 hexadecimal bytes).")
125
126 #define SOUT_CFG_PREFIX "sout-ts-"
127
128 vlc_module_begin();
129     set_description( _("TS muxer (libdvbpsi)") );
130     set_capability( "sout mux", 120 );
131     add_shortcut( "ts" );
132
133     add_integer( SOUT_CFG_PREFIX "pid-video", 0, NULL,VPID_TEXT, VPID_LONGTEXT,
134                                   VLC_TRUE );
135     add_integer( SOUT_CFG_PREFIX "pid-audio", 0, NULL, APID_TEXT,
136                  APID_LONGTEXT, VLC_TRUE );
137     add_integer( SOUT_CFG_PREFIX "pid-spu", 0, NULL, SPUPID_TEXT,
138                  SPUPID_LONGTEXT, VLC_TRUE );
139     add_integer( SOUT_CFG_PREFIX "pid-pmt", 0, NULL, PMTPID_TEXT,
140                  PMTPID_LONGTEXT, VLC_TRUE );
141     add_integer( SOUT_CFG_PREFIX "tsid", 0, NULL, TSID_TEXT,
142                  TSID_LONGTEXT, VLC_TRUE );
143
144     add_integer( SOUT_CFG_PREFIX "shaping", 200, NULL,SHAPING_TEXT,
145                  SHAPING_LONGTEXT, VLC_TRUE );
146     add_bool( SOUT_CFG_PREFIX "use-key-frames", VLC_FALSE, NULL, KEYF_TEXT,
147               KEYF_LONGTEXT, VLC_TRUE );
148
149     add_integer( SOUT_CFG_PREFIX "pcr", 30, NULL, PCR_TEXT, PCR_LONGTEXT,
150                  VLC_TRUE );
151     add_integer( SOUT_CFG_PREFIX "bmin", 0, NULL, BMIN_TEXT, BMIN_LONGTEXT,
152                  VLC_TRUE );
153     add_integer( SOUT_CFG_PREFIX "bmax", 0, NULL, BMAX_TEXT, BMAX_LONGTEXT,
154                  VLC_TRUE );
155     add_integer( SOUT_CFG_PREFIX "dts-delay", 200, NULL, DTS_TEXT,
156                  DTS_LONGTEXT, VLC_TRUE );
157
158     add_bool( SOUT_CFG_PREFIX "crypt-audio", VLC_TRUE, NULL, ACRYPT_TEXT,
159               ACRYPT_LONGTEXT, VLC_TRUE );
160
161     add_string( SOUT_CFG_PREFIX "csa-ck", NULL, NULL, CK_TEXT, CK_LONGTEXT,
162                 VLC_TRUE );
163
164     set_callbacks( Open, Close );
165 vlc_module_end();
166
167 /*****************************************************************************
168  * Local data structures
169  *****************************************************************************/
170 static const char *ppsz_sout_options[] = {
171     "pid-video", "pid-audio", "pid-spu", "pid-pmt", "tsid", "shaping", "pcr",
172     "bmin", "bmax", "use-key-frames", "dts-delay", "csa-ck", "crypt-audio",
173     NULL
174 };
175
176 #define SOUT_BUFFER_FLAGS_PRIVATE_PCR  ( 1 << BLOCK_FLAG_PRIVATE_SHIFT )
177 #define SOUT_BUFFER_FLAGS_PRIVATE_CSA  ( 2 << BLOCK_FLAG_PRIVATE_SHIFT )
178 typedef struct
179 {
180     int     i_depth;
181     block_t *p_first;
182     block_t **pp_last;
183 } sout_buffer_chain_t;
184
185 static inline void BufferChainInit  ( sout_buffer_chain_t *c )
186 {
187     c->i_depth = 0;
188     c->p_first = NULL;
189     c->pp_last = &c->p_first;
190 }
191 static inline void BufferChainAppend( sout_buffer_chain_t *c, block_t *b )
192 {
193     *c->pp_last = b;
194     c->i_depth++;
195
196     while( b->p_next )
197     {
198         b = b->p_next;
199         c->i_depth++;
200     }
201     c->pp_last = &b->p_next;
202 }
203 static inline block_t *BufferChainGet( sout_buffer_chain_t *c )
204 {
205     block_t *b = c->p_first;
206
207     if( b )
208     {
209         c->i_depth--;
210         c->p_first = b->p_next;
211
212         if( c->p_first == NULL )
213         {
214             c->pp_last = &c->p_first;
215         }
216
217         b->p_next = NULL;
218     }
219     return b;
220 }
221 static inline block_t *BufferChainPeek( sout_buffer_chain_t *c )
222 {
223     block_t *b = c->p_first;
224
225     return b;
226 }
227 static inline void BufferChainClean( sout_instance_t *p_sout,
228                                      sout_buffer_chain_t *c )
229 {
230     block_t *b;
231
232     while( ( b = BufferChainGet( c ) ) )
233     {
234         block_Release( b );
235     }
236     BufferChainInit( c );
237 }
238
239 typedef struct ts_stream_t
240 {
241     int             i_pid;
242     vlc_fourcc_t    i_codec;
243
244     int             i_stream_type;
245     int             i_stream_id;
246     int             i_continuity_counter;
247
248     /* to be used for carriege of DIV3 */
249     vlc_fourcc_t    i_bih_codec;
250     int             i_bih_width, i_bih_height;
251
252     /* Specific to mpeg4 in mpeg2ts */
253     int             i_es_id;
254
255     int             i_decoder_specific_info;
256     uint8_t         *p_decoder_specific_info;
257
258     /* language is iso639-2T */
259     uint8_t         lang[3];
260
261     sout_buffer_chain_t chain_pes;
262     mtime_t             i_pes_dts;
263     mtime_t             i_pes_length;
264     int                 i_pes_used;
265     vlc_bool_t          b_key_frame;
266
267 } ts_stream_t;
268
269 struct sout_mux_sys_t
270 {
271     int             i_pcr_pid;
272     sout_input_t    *p_pcr_input;
273
274     int             i_audio_bound;
275     int             i_video_bound;
276
277     int             i_pid_video;
278     int             i_pid_audio;
279     int             i_pid_spu;
280     int             i_pid_free; // first usable pid
281
282     int             i_tsid;
283     int             i_pat_version_number;
284     ts_stream_t     pat;
285
286     int             i_pmt_version_number;
287     ts_stream_t     pmt;        // Up to now only one program
288
289     int             i_mpeg4_streams;
290
291     int             i_null_continuity_counter;  /* Needed ? */
292
293     /* for TS building */
294     int64_t             i_bitrate_min;
295     int64_t             i_bitrate_max;
296
297     int64_t             i_shaping_delay;
298     int64_t             i_pcr_delay;
299
300     int64_t             i_dts_delay;
301
302     vlc_bool_t          b_use_key_frames;
303
304     mtime_t             i_pcr;  /* last PCR emited */
305
306     csa_t               *csa;
307     vlc_bool_t          b_crypt_audio;
308 };
309
310
311 /* Reserve a pid and return it */
312 static int  AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
313 {
314     int i_pid;
315     if ( i_cat == VIDEO_ES && p_sys->i_pid_video )
316     {
317         i_pid = p_sys->i_pid_video;
318         p_sys->i_pid_video = 0;
319     }
320     else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio )
321     {
322         i_pid = p_sys->i_pid_audio;
323         p_sys->i_pid_audio = 0;
324     }
325     else if ( i_cat == SPU_ES && p_sys->i_pid_spu )
326     {
327         i_pid = p_sys->i_pid_spu;
328         p_sys->i_pid_spu = 0;
329     }
330     else
331     {
332         i_pid = ++p_sys->i_pid_free;
333     }
334     return i_pid;
335 }
336
337 /*****************************************************************************
338  * Local prototypes
339  *****************************************************************************/
340 static int Control  ( sout_mux_t *, int, va_list );
341 static int AddStream( sout_mux_t *, sout_input_t * );
342 static int DelStream( sout_mux_t *, sout_input_t * );
343 static int Mux      ( sout_mux_t * );
344
345 static void TSSchedule  ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
346                           mtime_t i_pcr_length, mtime_t i_pcr_dts );
347 static void TSDate      ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
348                           mtime_t i_pcr_length, mtime_t i_pcr_dts );
349 static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
350 static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
351
352 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr );
353 static void TSSetPCR( block_t *p_ts, mtime_t i_dts );
354
355 static void PEStoTS  ( sout_instance_t *, sout_buffer_chain_t *, block_t *, ts_stream_t * );
356
357 /*****************************************************************************
358  * Open:
359  *****************************************************************************/
360 static int Open( vlc_object_t *p_this )
361 {
362     sout_mux_t          *p_mux =(sout_mux_t*)p_this;
363     sout_mux_sys_t      *p_sys;
364     vlc_value_t         val;
365
366     msg_Dbg( p_mux, "Open" );
367     sout_CfgParse( p_mux, SOUT_CFG_PREFIX, ppsz_sout_options, p_mux->p_cfg );
368
369     p_sys = malloc( sizeof( sout_mux_sys_t ) );
370
371     p_mux->pf_control   = Control;
372     p_mux->pf_addstream = AddStream;
373     p_mux->pf_delstream = DelStream;
374     p_mux->pf_mux       = Mux;
375     p_mux->p_sys        = p_sys;
376
377     srand( (uint32_t)mdate() );
378
379     p_sys->i_audio_bound = 0;
380     p_sys->i_video_bound = 0;
381
382     p_sys->i_pat_version_number = rand() % 32;
383     p_sys->pat.i_pid = 0;
384     p_sys->pat.i_continuity_counter = 0;
385
386     var_Get( p_mux, SOUT_CFG_PREFIX "tsid", &val );
387     if ( val.i_int )
388         p_sys->i_tsid = val.i_int;
389     else
390         p_sys->i_tsid = rand() % 65536;
391     p_sys->i_pmt_version_number = rand() % 32;
392     p_sys->pmt.i_continuity_counter = 0;
393
394     var_Get( p_mux, SOUT_CFG_PREFIX "pid-pmt", &val );
395     if (val.i_int )
396     {
397         p_sys->pmt.i_pid = val.i_int;
398     }
399     else
400     {
401        p_sys->pmt.i_pid = 0x42;
402     }
403
404     p_sys->i_pid_free = p_sys->pmt.i_pid + 1;
405
406     var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );
407     p_sys->i_pid_video = val.i_int;
408     if ( p_sys->i_pid_video > p_sys->i_pid_free )
409     {
410         p_sys->i_pid_free = p_sys->i_pid_video + 1;
411     }
412
413     var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );
414     p_sys->i_pid_audio = val.i_int;
415     if ( p_sys->i_pid_audio > p_sys->i_pid_free )
416     {
417         p_sys->i_pid_free = p_sys->i_pid_audio + 1;
418     }
419
420     var_Get( p_mux, SOUT_CFG_PREFIX "pid-spu", &val );
421     p_sys->i_pid_spu = val.i_int;
422     if ( p_sys->i_pid_spu > p_sys->i_pid_free )
423     {
424         p_sys->i_pid_free = p_sys->i_pid_spu + 1;
425     }
426
427     p_sys->i_pcr_pid = 0x1fff;
428     p_sys->p_pcr_input = NULL;
429
430     p_sys->i_mpeg4_streams = 0;
431
432     p_sys->i_null_continuity_counter = 0;
433
434     /* Allow to create constrained stream */
435     var_Get( p_mux, SOUT_CFG_PREFIX "bmin", &val );
436     p_sys->i_bitrate_min = val.i_int;
437
438     var_Get( p_mux, SOUT_CFG_PREFIX "bmax", &val );
439     p_sys->i_bitrate_max = val.i_int;
440
441     if( p_sys->i_bitrate_min > 0 && p_sys->i_bitrate_max > 0 &&
442         p_sys->i_bitrate_min > p_sys->i_bitrate_max )
443     {
444         msg_Err( p_mux, "incompatible minimum and maximum bitrate, "
445                  "disabling bitrate control" );
446         p_sys->i_bitrate_min = 0;
447         p_sys->i_bitrate_max = 0;
448     }
449     if( p_sys->i_bitrate_min > 0 || p_sys->i_bitrate_max > 0 )
450     {
451         msg_Err( p_mux, "bmin and bmax no more supported "
452                  "(if you need them report it)" );
453     }
454
455     var_Get( p_mux, SOUT_CFG_PREFIX "shaping", &val );
456     p_sys->i_shaping_delay = (int64_t)val.i_int * 1000;
457     if( p_sys->i_shaping_delay <= 0 )
458     {
459         msg_Err( p_mux,
460                  "invalid shaping ("I64Fd"ms) resetting to 200ms",
461                  p_sys->i_shaping_delay / 1000 );
462         p_sys->i_shaping_delay = 200000;
463     }
464
465     var_Get( p_mux, SOUT_CFG_PREFIX "pcr", &val );
466     p_sys->i_pcr_delay = (int64_t)val.i_int * 1000;
467     if( p_sys->i_pcr_delay <= 0 ||
468         p_sys->i_pcr_delay >= p_sys->i_shaping_delay )
469     {
470         msg_Err( p_mux,
471                  "invalid pcr delay ("I64Fd"ms) resetting to 30ms",
472                  p_sys->i_pcr_delay / 1000 );
473         p_sys->i_pcr_delay = 30000;
474     }
475
476     var_Get( p_mux, SOUT_CFG_PREFIX "dts-delay", &val );
477     p_sys->i_dts_delay = (int64_t)val.i_int * 1000;
478
479     msg_Dbg( p_mux, "shaping="I64Fd" pcr="I64Fd" dts_delay="I64Fd,
480              p_sys->i_shaping_delay, p_sys->i_pcr_delay, p_sys->i_dts_delay );
481
482     var_Get( p_mux, SOUT_CFG_PREFIX "use-key-frames", &val );
483     p_sys->b_use_key_frames = val.b_bool;
484
485     /* for TS generation */
486     p_sys->i_pcr    = 0;
487
488     p_sys->csa      = NULL;
489     var_Get( p_mux, SOUT_CFG_PREFIX "csa-ck", &val );
490     if( val.psz_string )
491     {
492         char *psz = val.psz_string;
493
494         /* skip 0x */
495         if( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) )
496         {
497             psz += 2;
498         }
499         if( strlen( psz ) != 16 )
500         {
501             msg_Dbg( p_mux, "invalid csa ck (it must be 16 chars long)" );
502         }
503         else
504         {
505             uint64_t i_ck = strtoull( psz, NULL, 16 );
506             uint8_t  ck[8];
507             int      i;
508
509             for( i = 0; i < 8; i++ )
510             {
511                 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
512             }
513
514             msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x",
515                      ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
516
517             p_sys->csa = csa_New();
518             csa_SetCW( p_sys->csa, ck, ck );
519         }
520     }
521     if( val.psz_string ) free( val.psz_string );
522
523     var_Get( p_mux, SOUT_CFG_PREFIX "crypt-audio", &val );
524     p_sys->b_crypt_audio = val.b_bool;
525
526     return VLC_SUCCESS;
527 }
528
529 /*****************************************************************************
530  * Close:
531  *****************************************************************************/
532 static void Close( vlc_object_t * p_this )
533 {
534     sout_mux_t          *p_mux = (sout_mux_t*)p_this;
535     sout_mux_sys_t      *p_sys = p_mux->p_sys;
536
537     msg_Dbg( p_mux, "Close" );
538     if( p_sys->csa )
539     {
540         csa_Delete( p_sys->csa );
541     }
542
543     free( p_sys );
544 }
545
546 /*****************************************************************************
547  * Control:
548  *****************************************************************************/
549 static int Control( sout_mux_t *p_mux, int i_query, va_list args )
550 {
551     vlc_bool_t *pb_bool;
552     char **ppsz;
553
554    switch( i_query )
555    {
556        case MUX_CAN_ADD_STREAM_WHILE_MUXING:
557            pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
558            *pb_bool = VLC_TRUE;
559            return VLC_SUCCESS;
560
561        case MUX_GET_ADD_STREAM_WAIT:
562            pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
563            *pb_bool = VLC_FALSE;
564            return VLC_SUCCESS;
565
566        case MUX_GET_MIME:
567            ppsz = (char**)va_arg( args, char ** );
568            *ppsz = strdup( "video/mpeg" );  /* FIXME not sure */
569            return VLC_SUCCESS;
570
571         default:
572             return VLC_EGENERIC;
573    }
574 }
575
576 /*****************************************************************************
577  * AddStream: called for each stream addition
578  *****************************************************************************/
579 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
580 {
581     sout_mux_sys_t      *p_sys = p_mux->p_sys;
582     ts_stream_t         *p_stream;
583
584     p_input->p_sys = p_stream = malloc( sizeof( ts_stream_t ) );
585
586     /* Init this new stream */
587     p_stream->i_pid = AllocatePID( p_sys, p_input->p_fmt->i_cat );
588     p_stream->i_codec = p_input->p_fmt->i_codec;
589     p_stream->i_continuity_counter    = 0;
590     p_stream->i_decoder_specific_info = 0;
591     p_stream->p_decoder_specific_info = NULL;
592
593     msg_Dbg( p_mux, "adding input codec=%4.4s pid=%d",
594              (char*)&p_input->p_fmt->i_codec, p_stream->i_pid );
595
596     /* All others fields depand on codec */
597     switch( p_input->p_fmt->i_cat )
598     {
599         case VIDEO_ES:
600             switch( p_input->p_fmt->i_codec )
601             {
602                 case VLC_FOURCC( 'm', 'p','g', 'v' ):
603                     /* TODO: do we need to check MPEG-I/II ? */
604                     p_stream->i_stream_type = 0x02;
605                     p_stream->i_stream_id = 0xe0;
606                     break;
607                 case VLC_FOURCC( 'm', 'p','4', 'v' ):
608                     p_stream->i_stream_type = 0x10;
609                     p_stream->i_stream_id = 0xfa;
610                     p_sys->i_mpeg4_streams++;
611                     p_stream->i_es_id = p_stream->i_pid;
612                     break;
613                 case VLC_FOURCC( 'h', '2','6', '4' ):
614                     p_stream->i_stream_type = 0x1b;
615                     p_stream->i_stream_id = 0xe0;
616                     break;
617                 /* XXX dirty dirty but somebody want that:
618                  *     using crapy MS-codec XXX */
619                 /* I didn't want to do that :P */
620                 case VLC_FOURCC( 'H', '2', '6', '3' ):
621                 case VLC_FOURCC( 'I', '2', '6', '3' ):
622                 case VLC_FOURCC( 'W', 'M', 'V', '3' ):
623                 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
624                 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
625                 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
626                 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
627                 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
628                 case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
629                     p_stream->i_stream_type = 0xa0; // private
630                     p_stream->i_stream_id = 0xa0;   // beurk
631                     p_stream->i_bih_codec  = p_input->p_fmt->i_codec;
632                     p_stream->i_bih_width  = p_input->p_fmt->video.i_width;
633                     p_stream->i_bih_height = p_input->p_fmt->video.i_height;
634                     break;
635                 default:
636                     free( p_stream );
637                     return VLC_EGENERIC;
638             }
639             p_sys->i_video_bound++;
640             break;
641
642         case AUDIO_ES:
643             switch( p_input->p_fmt->i_codec )
644             {
645                 case VLC_FOURCC( 'm', 'p','g', 'a' ):
646                     p_stream->i_stream_type =
647                         p_input->p_fmt->audio.i_rate >= 32000 ? 0x03 : 0x04;
648                     p_stream->i_stream_id = 0xc0;
649                     break;
650                 case VLC_FOURCC( 'a', '5','2', ' ' ):
651                     p_stream->i_stream_type = 0x81;
652                     p_stream->i_stream_id = 0xbd;
653                     break;
654                 case VLC_FOURCC( 'l', 'p','c', 'm' ):
655                     p_stream->i_stream_type = 0x83;
656                     p_stream->i_stream_id = 0xbd;
657                     break;
658                 case VLC_FOURCC( 'd', 't','s', ' ' ):
659                     p_stream->i_stream_type = 0x06;
660                     p_stream->i_stream_id = 0xbd;
661                     break;
662
663                 case VLC_FOURCC( 'm', 'p','4', 'a' ):
664                     p_stream->i_stream_type = 0x11;
665                     p_stream->i_stream_id = 0xfa;
666                     p_sys->i_mpeg4_streams++;
667                     p_stream->i_es_id = p_stream->i_pid;
668                     break;
669                 default:
670                     free( p_stream );
671                     return VLC_EGENERIC;
672             }
673             p_sys->i_audio_bound++;
674             break;
675
676         case SPU_ES:
677             switch( p_input->p_fmt->i_codec )
678             {
679                 case VLC_FOURCC( 's', 'p','u', ' ' ):
680                     p_stream->i_stream_type = 0x82;
681                     p_stream->i_stream_id = 0xbd;
682                     break;
683                 case VLC_FOURCC( 's', 'u','b', 't' ):
684                     p_stream->i_stream_type = 0x12;
685                     p_stream->i_stream_id = 0xfa;
686                     p_sys->i_mpeg4_streams++;
687                     p_stream->i_es_id = p_stream->i_pid;
688                     break;
689                 case VLC_FOURCC('d','v','b','s'):
690                     p_stream->i_stream_type = 0x06;
691                     p_stream->i_es_id = p_input->p_fmt->subs.dvb.i_id;
692                     p_stream->i_stream_id = 0xbd;
693                     break;
694                 case VLC_FOURCC('t','e','l','x'):
695                     p_stream->i_stream_type = 0x06;
696                     p_stream->i_stream_id = 0xbd; /* FIXME */
697                     break;
698                 default:
699                     free( p_stream );
700                     return VLC_EGENERIC;
701             }
702             break;
703
704         default:
705             free( p_stream );
706             return VLC_EGENERIC;
707     }
708
709     p_stream->lang[0] =
710     p_stream->lang[1] =
711     p_stream->lang[2] = '\0';
712     if( p_input->p_fmt->psz_language )
713     {
714         char *psz = p_input->p_fmt->psz_language;
715         const iso639_lang_t *pl = NULL;
716
717         if( strlen( psz ) == 2 )
718         {
719             pl = GetLang_1( psz );
720         }
721         else if( strlen( psz ) == 3 )
722         {
723             pl = GetLang_2B( psz );
724             if( !strcmp( pl->psz_iso639_1, "??" ) )
725             {
726                 pl = GetLang_2T( psz );
727             }
728         }
729         if( pl && strcmp( pl->psz_iso639_1, "??" ) )
730         {
731             p_stream->lang[0] = pl->psz_iso639_2T[0];
732             p_stream->lang[1] = pl->psz_iso639_2T[1];
733             p_stream->lang[2] = pl->psz_iso639_2T[2];
734
735             msg_Dbg( p_mux, "    - lang=%c%c%c",
736                      p_stream->lang[0], p_stream->lang[1], p_stream->lang[2] );
737         }
738     }
739
740
741     /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
742     p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
743     if( p_stream->i_decoder_specific_info > 0 )
744     {
745         p_stream->p_decoder_specific_info =
746             malloc( p_stream->i_decoder_specific_info );
747         memcpy( p_stream->p_decoder_specific_info,
748                 p_input->p_fmt->p_extra,
749                 p_input->p_fmt->i_extra );
750     }
751
752     /* Create decoder specific info for subt */
753     if( p_stream->i_codec == VLC_FOURCC( 's', 'u','b', 't' ) )
754     {
755         uint8_t *p;
756
757         p_stream->i_decoder_specific_info = 55;
758         p_stream->p_decoder_specific_info = p =
759             malloc( p_stream->i_decoder_specific_info );
760
761         p[0] = 0x10;    /* textFormat, 0x10 for 3GPP TS 26.245 */
762         p[1] = 0x00;    /* flags: 1b: associated video info flag
763                                   3b: reserved
764                                   1b: duration flag
765                                   3b: reserved */
766         p[2] = 52;      /* remaining size */
767
768         p += 3;
769
770         p[0] = p[1] = p[2] = p[3] = 0; p+=4;    /* display flags */
771         *p++ = 0;  /* horizontal justification (-1: left, 0 center, 1 right) */
772         *p++ = 1;  /* vertical   justification (-1: top, 0 center, 1 bottom) */
773
774         p[0] = p[1] = p[2] = 0x00; p+=3;/* background rgb */
775         *p++ = 0xff;                    /* background a */
776
777         p[0] = p[1] = 0; p += 2;        /* text box top */
778         p[0] = p[1] = 0; p += 2;        /* text box left */
779         p[0] = p[1] = 0; p += 2;        /* text box bottom */
780         p[0] = p[1] = 0; p += 2;        /* text box right */
781
782         p[0] = p[1] = 0; p += 2;        /* start char */
783         p[0] = p[1] = 0; p += 2;        /* end char */
784         p[0] = p[1] = 0; p += 2;        /* default font id */
785
786         *p++ = 0;                       /* font style flags */
787         *p++ = 12;                      /* font size */
788
789         p[0] = p[1] = p[2] = 0x00; p+=3;/* foreground rgb */
790         *p++ = 0x00;                    /* foreground a */
791
792         p[0] = p[1] = p[2] = 0; p[3] = 22; p += 4;
793         memcpy( p, "ftab", 4 ); p += 4;
794         *p++ = 0; *p++ = 1;             /* entry count */
795         p[0] = p[1] = 0; p += 2;        /* font id */
796         *p++ = 9;                       /* font name length */
797         memcpy( p, "Helvetica", 9 );    /* font name */
798     }
799
800     /* Init pes chain */
801     BufferChainInit( &p_stream->chain_pes );
802     p_stream->i_pes_dts    = 0;
803     p_stream->i_pes_length = 0;
804     p_stream->i_pes_used   = 0;
805     p_stream->b_key_frame  = 0;
806
807     /* We only change PMT version (PAT isn't changed) */
808     p_sys->i_pmt_version_number = ( p_sys->i_pmt_version_number + 1 )%32;
809
810     /* Update pcr_pid */
811     if( p_input->p_fmt->i_cat != SPU_ES &&
812         ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) )
813     {
814         if( p_sys->p_pcr_input )
815         {
816             /* There was already a PCR stream, so clean context */
817             /* FIXME */
818         }
819         p_sys->i_pcr_pid   = p_stream->i_pid;
820         p_sys->p_pcr_input = p_input;
821
822         msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
823     }
824
825     return VLC_SUCCESS;
826 }
827
828 /*****************************************************************************
829  * DelStream: called before a stream deletion
830  *****************************************************************************/
831 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
832 {
833     sout_mux_sys_t  *p_sys = p_mux->p_sys;
834     ts_stream_t     *p_stream;
835     vlc_value_t     val;
836
837     p_stream = (ts_stream_t*)p_input->p_sys;
838     msg_Dbg( p_mux, "removing input pid=%d", p_stream->i_pid );
839
840     if( p_sys->i_pcr_pid == p_stream->i_pid )
841     {
842         int i;
843
844         /* Find a new pcr stream (Prefer Video Stream) */
845         p_sys->i_pcr_pid = 0x1fff;
846         p_sys->p_pcr_input = NULL;
847         for( i = 0; i < p_mux->i_nb_inputs; i++ )
848         {
849             if( p_mux->pp_inputs[i] == p_input )
850             {
851                 continue;
852             }
853
854             if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
855             {
856                 p_sys->i_pcr_pid  =
857                     ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
858                 p_sys->p_pcr_input= p_mux->pp_inputs[i];
859                 break;
860             }
861             else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
862                      p_sys->i_pcr_pid == 0x1fff )
863             {
864                 p_sys->i_pcr_pid  =
865                     ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
866                 p_sys->p_pcr_input= p_mux->pp_inputs[i];
867             }
868         }
869         if( p_sys->p_pcr_input )
870         {
871             /* Empty TS buffer */
872             /* FIXME */
873         }
874         msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
875     }
876
877     /* Empty all data in chain_pes */
878     BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
879
880     if( p_stream->p_decoder_specific_info )
881     {
882         free( p_stream->p_decoder_specific_info );
883     }
884     if( p_stream->i_stream_id == 0xfa ||
885         p_stream->i_stream_id == 0xfb ||
886         p_stream->i_stream_id == 0xfe )
887     {
888         p_sys->i_mpeg4_streams--;
889     }
890
891     var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );
892     if( val.i_int > 0 )
893     {
894         int i_pid_video = val.i_int;
895         if ( i_pid_video == p_stream->i_pid )
896         {
897             p_sys->i_pid_video = i_pid_video;
898             msg_Dbg( p_mux, "freeing video PID %d", i_pid_video );
899         }
900     }
901     var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );
902     if( val.i_int > 0 )
903     {
904         int i_pid_audio = val.i_int;
905         if ( i_pid_audio == p_stream->i_pid )
906         {
907             p_sys->i_pid_audio = i_pid_audio;
908             msg_Dbg( p_mux, "freeing audio PID %d", i_pid_audio );
909         }
910     }
911     var_Get( p_mux, SOUT_CFG_PREFIX "pid-spu", &val );
912     if( val.i_int > 0 )
913     {
914         int i_pid_spu = val.i_int;
915         if ( i_pid_spu == p_stream->i_pid )
916         {
917             p_sys->i_pid_spu = i_pid_spu;
918             msg_Dbg( p_mux, "freeing spu PID %d", i_pid_spu );
919         }
920     }
921     free( p_stream );
922
923     /* We only change PMT version (PAT isn't changed) */
924     p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
925
926     return VLC_SUCCESS;
927 }
928
929 /*****************************************************************************
930  * Mux: Call each time there is new data for at least one stream
931  *****************************************************************************
932  *
933  *****************************************************************************/
934 static int Mux( sout_mux_t *p_mux )
935 {
936     sout_mux_sys_t  *p_sys = p_mux->p_sys;
937     ts_stream_t     *p_pcr_stream;
938
939     if( p_sys->i_pcr_pid == 0x1fff )
940     {
941         msg_Dbg( p_mux, "waiting for PCR streams" );
942         msleep( 1000 );
943         return VLC_SUCCESS;
944     }
945     p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
946
947     for( ;; )
948     {
949         sout_buffer_chain_t chain_ts;
950         int                 i_packet_count;
951         int                 i_packet_pos;
952         mtime_t             i_pcr_dts;
953         mtime_t             i_pcr_length;
954         mtime_t             i_shaping_delay;
955         int i;
956
957         if( p_pcr_stream->b_key_frame )
958         {
959             i_shaping_delay = p_pcr_stream->i_pes_length;
960         }
961         else
962         {
963             i_shaping_delay = p_sys->i_shaping_delay;
964         }
965
966         /* 1: get enough PES packet for all input */
967         for( ;; )
968         {
969             vlc_bool_t b_ok = VLC_TRUE;
970             block_t *p_data;
971
972             /* Accumulate enough data in the pcr stream (>i_shaping_delay) */
973             /* Accumulate enough data in all other stream ( >= length of pcr)*/
974             for( i = 0; i < p_mux->i_nb_inputs; i++ )
975             {
976                 sout_input_t *p_input = p_mux->pp_inputs[i];
977                 ts_stream_t *p_stream = (ts_stream_t*)p_input->p_sys;
978                 int64_t i_spu_delay = 0;
979
980                 if( ( p_stream == p_pcr_stream &&
981                       p_stream->i_pes_length < i_shaping_delay ) ||
982                     p_stream->i_pes_dts + p_stream->i_pes_length <
983                     p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
984                 {
985                     /* Need more data */
986                     if( p_input->p_fifo->i_depth <= 1 )
987                     {
988                         if( p_input->p_fmt->i_cat == AUDIO_ES ||
989                             p_input->p_fmt->i_cat == VIDEO_ES )
990                         {
991                             /* We need more data */
992                             return VLC_SUCCESS;
993                         }
994                         else if( p_input->p_fifo->i_depth <= 0 )
995                         {
996                             /* spu, only one packet is needed */
997                             continue;
998                         }
999                         else
1000                         {
1001                             /* Don't mux the SPU yet if it is too early */
1002                             block_t *p_spu = block_FifoShow( p_input->p_fifo );
1003
1004                             i_spu_delay =
1005                                 p_spu->i_dts - p_pcr_stream->i_pes_dts;
1006
1007                             if( i_spu_delay > i_shaping_delay &&
1008                                 i_spu_delay < I64C(100000000) )
1009                                 continue;
1010
1011                             if ( i_spu_delay >= I64C(100000000)
1012                                   || i_spu_delay < 10000 )
1013                             {
1014                                 BufferChainClean( p_mux->p_sout,
1015                                                   &p_stream->chain_pes );
1016                                 p_stream->i_pes_dts = 0;
1017                                 p_stream->i_pes_used = 0;
1018                                 p_stream->i_pes_length = 0;
1019                                 continue;
1020                             }
1021                         }
1022                     }
1023                     b_ok = VLC_FALSE;
1024
1025                     p_data = block_FifoGet( p_input->p_fifo );
1026                     if( p_input->p_fifo->i_depth > 0 &&
1027                         p_input->p_fmt->i_cat != SPU_ES )
1028                     {
1029                         block_t *p_next = block_FifoShow( p_input->p_fifo );
1030                         p_data->i_length = p_next->i_dts - p_data->i_dts;
1031                     }
1032                     else
1033                         p_data->i_length = 1000;
1034
1035                     if( ( p_pcr_stream->i_pes_dts > 0 &&
1036                           p_data->i_dts - 10000000 > p_pcr_stream->i_pes_dts +
1037                           p_pcr_stream->i_pes_length ) ||
1038                         p_data->i_dts < p_stream->i_pes_dts ||
1039                         ( p_stream->i_pes_dts > 0 &&
1040                           p_input->p_fmt->i_cat != SPU_ES &&
1041                           p_data->i_dts - 10000000 > p_stream->i_pes_dts +
1042                           p_stream->i_pes_length ) )
1043                     {
1044                         msg_Warn( p_mux, "packet with too strange dts "
1045                                   "(dts="I64Fd",old="I64Fd",pcr="I64Fd")",
1046                                   p_data->i_dts, p_stream->i_pes_dts,
1047                                   p_pcr_stream->i_pes_dts );
1048                         block_Release( p_data );
1049
1050                         BufferChainClean( p_mux->p_sout,
1051                                           &p_stream->chain_pes );
1052                         p_stream->i_pes_dts = 0;
1053                         p_stream->i_pes_used = 0;
1054                         p_stream->i_pes_length = 0;
1055
1056                         if( p_input->p_fmt->i_cat != SPU_ES )
1057                         {
1058                             BufferChainClean( p_mux->p_sout,
1059                                               &p_pcr_stream->chain_pes );
1060                             p_pcr_stream->i_pes_dts = 0;
1061                             p_pcr_stream->i_pes_used = 0;
1062                             p_pcr_stream->i_pes_length = 0;
1063                         }
1064                     }
1065                     else
1066                     {
1067                         int i_header_size = 0;
1068                         int b_data_alignment = 0;
1069                         if( p_input->p_fmt->i_cat == SPU_ES )
1070                         {
1071                             if( p_input->p_fmt->i_codec ==
1072                                 VLC_FOURCC('s','u','b','t') )
1073                             {
1074                                 /* Prepend header */
1075                                 p_data = block_Realloc( p_data, 2,
1076                                                         p_data->i_buffer );
1077                                 p_data->p_buffer[0] =
1078                                     ( (p_data->i_buffer - 2) >> 8) & 0xff;
1079                                 p_data->p_buffer[1] =
1080                                     ( (p_data->i_buffer - 2)     ) & 0xff;
1081
1082                                 /* remove trailling \0 if any */
1083                                 if( p_data->i_buffer > 2 &&
1084                                     p_data->p_buffer[p_data->i_buffer -1] ==
1085                                     '\0' )
1086                                     p_data->i_buffer--;
1087
1088                                 /* Append a empty sub (sub text only) */
1089                                 if( p_data->i_length > 0 &&
1090                                     !( p_data->i_buffer == 1 &&
1091                                        *p_data->p_buffer == ' ' ) )
1092                                 {
1093                                     block_t *p_spu = block_New( p_mux, 3 );
1094
1095                                     p_spu->i_dts = p_spu->i_pts =
1096                                         p_data->i_dts + p_data->i_length;
1097                                     p_spu->i_length = 1000;
1098
1099                                     p_spu->p_buffer[0] = 0;
1100                                     p_spu->p_buffer[1] = 1;
1101                                     p_spu->p_buffer[2] = ' ';
1102
1103                                     E_(EStoPES)( p_mux->p_sout, &p_spu, p_spu,
1104                                                  p_input->p_fmt,
1105                                                  p_stream->i_stream_id, 1,
1106                                                  0, 0 );
1107                                     p_data->p_next = p_spu;
1108                                 }
1109                             }
1110                             else if( p_input->p_fmt->i_codec ==
1111                                        VLC_FOURCC('t','e','l','x') )
1112                             {
1113                                 /* EN 300 472 */
1114                                 i_header_size = 0x24;
1115                                 b_data_alignment = 1;
1116                             }
1117                         }
1118                         else if( p_data->i_length < 0 ||
1119                                  p_data->i_length > 2000000 )
1120                         {
1121                             /* FIXME choose a better value, but anyway we
1122                              * should never have to do that */
1123                             p_data->i_length = 1000;
1124                         }
1125
1126                         p_stream->i_pes_length += p_data->i_length;
1127                         if( p_stream->i_pes_dts == 0 )
1128                         {
1129                             p_stream->i_pes_dts = p_data->i_dts;
1130                         }
1131
1132                         /* Convert to pes */
1133                         if( p_stream->i_stream_id == 0xa0 &&
1134                             p_data->i_pts <= 0 )
1135                         {
1136                             /* XXX yes I know, it's awfull, but it's needed,
1137                              * so don't remove it ... */
1138                             p_data->i_pts = p_data->i_dts;
1139                         }
1140                         E_( EStoPES )( p_mux->p_sout, &p_data, p_data,
1141                                        p_input->p_fmt, p_stream->i_stream_id,
1142                                        1, b_data_alignment, i_header_size );
1143
1144                         BufferChainAppend( &p_stream->chain_pes, p_data );
1145
1146                         if( p_sys->b_use_key_frames && p_stream == p_pcr_stream
1147                             && (p_data->i_flags & BLOCK_FLAG_TYPE_I)
1148                             && !(p_data->i_flags & BLOCK_FLAG_NO_KEYFRAME)
1149                             && (p_stream->i_pes_length > 400000) )
1150                         {
1151                             i_shaping_delay = p_stream->i_pes_length;
1152                             p_stream->b_key_frame = 1;
1153                         }
1154                     }
1155                 }
1156             }
1157
1158             if( b_ok )
1159             {
1160                 break;
1161             }
1162         }
1163
1164         /* save */
1165         i_pcr_dts      = p_pcr_stream->i_pes_dts;
1166         i_pcr_length   = p_pcr_stream->i_pes_length;
1167         p_pcr_stream->b_key_frame = 0;
1168
1169         /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
1170         /* 2: calculate non accurate total size of muxed ts */
1171         i_packet_count = 0;
1172         for( i = 0; i < p_mux->i_nb_inputs; i++ )
1173         {
1174             ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
1175             block_t *p_pes;
1176
1177             /* False for pcr stream but it will be enough to do PCR algo */
1178             for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL;
1179                  p_pes = p_pes->p_next )
1180             {
1181                 int i_size = p_pes->i_buffer;
1182                 if( p_pes->i_dts + p_pes->i_length >
1183                     p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
1184                 {
1185                     mtime_t i_frag = p_pcr_stream->i_pes_dts +
1186                         p_pcr_stream->i_pes_length - p_pes->i_dts;
1187                     if( i_frag < 0 )
1188                     {
1189                         /* Next stream */
1190                         break;
1191                     }
1192                     i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
1193                 }
1194                 i_packet_count += ( i_size + 183 ) / 184;
1195             }
1196         }
1197         /* add overhead for PCR (not really exact) */
1198         i_packet_count += (8 * i_pcr_length / p_sys->i_pcr_delay + 175) / 176;
1199
1200         /* 3: mux PES into TS */
1201         BufferChainInit( &chain_ts );
1202         /* append PAT/PMT  -> FIXME with big pcr delay it won't have enough pat/pmt */
1203         GetPAT( p_mux, &chain_ts);
1204         GetPMT( p_mux, &chain_ts );
1205         i_packet_pos = 0;
1206         i_packet_count += chain_ts.i_depth;
1207         /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
1208
1209         for( ;; )
1210         {
1211             int         i_stream;
1212             mtime_t     i_dts;
1213             ts_stream_t *p_stream;
1214             sout_input_t *p_input;
1215             block_t *p_ts;
1216             vlc_bool_t   b_pcr;
1217
1218             /* Select stream (lowest dts) */
1219             for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
1220             {
1221                 p_input = p_mux->pp_inputs[i];
1222                 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
1223
1224                 if( p_stream->i_pes_dts == 0 )
1225                 {
1226                     continue;
1227                 }
1228
1229                 if( i_stream == -1 ||
1230                     p_stream->i_pes_dts < i_dts )
1231                 {
1232                     i_stream = i;
1233                     i_dts = p_stream->i_pes_dts;
1234                 }
1235             }
1236             if( i_stream == -1 || i_dts > i_pcr_dts + i_pcr_length )
1237             {
1238                 break;
1239             }
1240             p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1241
1242             /* do we need to issue pcr */
1243             b_pcr = VLC_FALSE;
1244             if( p_stream == p_pcr_stream &&
1245                 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >=
1246                 p_sys->i_pcr + p_sys->i_pcr_delay )
1247             {
1248                 b_pcr = VLC_TRUE;
1249                 p_sys->i_pcr = i_pcr_dts + i_packet_pos *
1250                     i_pcr_length / i_packet_count;
1251             }
1252
1253             /* Build the TS packet */
1254             p_ts = TSNew( p_mux, p_stream, b_pcr );
1255             if( p_sys->csa != NULL &&
1256                  (p_input->p_fmt->i_cat != AUDIO_ES || p_sys->b_crypt_audio) )
1257             {
1258                 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
1259             }
1260             i_packet_pos++;
1261
1262             /* */
1263             BufferChainAppend( &chain_ts, p_ts );
1264         }
1265
1266         /* 4: date and send */
1267         TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
1268     }
1269 }
1270
1271 static void TSSchedule( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1272                         mtime_t i_pcr_length, mtime_t i_pcr_dts )
1273 {
1274     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1275     sout_buffer_chain_t new_chain;
1276     int i_packet_count = p_chain_ts->i_depth;
1277     int i;
1278
1279     BufferChainInit( &new_chain );
1280
1281     if ( i_pcr_length <= 0 )
1282     {
1283         i_pcr_length = i_packet_count;
1284     }
1285
1286     for( i = 0; i < i_packet_count; i++ )
1287     {
1288         block_t *p_ts = BufferChainGet( p_chain_ts );
1289         mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1290
1291         BufferChainAppend( &new_chain, p_ts );
1292
1293         if( p_ts->i_dts &&
1294             p_ts->i_dts + p_sys->i_dts_delay * 2/3 < i_new_dts )
1295         {
1296             mtime_t i_max_diff = i_new_dts - p_ts->i_dts;
1297             mtime_t i_cut_dts = p_ts->i_dts;
1298
1299             p_ts = BufferChainPeek( p_chain_ts );
1300             i++;
1301             i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1302             while ( p_ts != NULL && i_new_dts - p_ts->i_dts >= i_max_diff )
1303             {
1304                 p_ts = BufferChainGet( p_chain_ts );
1305                 i_max_diff = i_new_dts - p_ts->i_dts;
1306                 i_cut_dts = p_ts->i_dts;
1307                 BufferChainAppend( &new_chain, p_ts );
1308
1309                 p_ts = BufferChainPeek( p_chain_ts );
1310                 i++;
1311                 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1312             }
1313             msg_Dbg( p_mux, "adjusting rate at "I64Fd"/"I64Fd" (%d/%d)",
1314                      i_cut_dts - i_pcr_dts, i_pcr_length, new_chain.i_depth,
1315                      p_chain_ts->i_depth );
1316             if ( new_chain.i_depth )
1317                 TSDate( p_mux, &new_chain,
1318                         i_cut_dts - i_pcr_dts,
1319                         i_pcr_dts );
1320             if ( p_chain_ts->i_depth )
1321                 TSSchedule( p_mux,
1322                             p_chain_ts, i_pcr_dts + i_pcr_length - i_cut_dts,
1323                             i_cut_dts );
1324             return;
1325         }
1326     }
1327
1328     if ( new_chain.i_depth )
1329         TSDate( p_mux, &new_chain, i_pcr_length, i_pcr_dts );
1330 }
1331
1332 static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1333                     mtime_t i_pcr_length, mtime_t i_pcr_dts )
1334 {
1335     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1336     int i_packet_count = p_chain_ts->i_depth;
1337     int i;
1338
1339     if ( i_pcr_length / 1000 > 0 )
1340     {
1341         int i_bitrate = ((uint64_t)i_packet_count * 188 * 8000)
1342                           / (uint64_t)(i_pcr_length / 1000);
1343         if ( p_sys->i_bitrate_max && p_sys->i_bitrate_max < i_bitrate )
1344         {
1345             msg_Warn( p_mux, "max bitrate exceeded at "I64Fd
1346                       " (%d bi/s for %d pkt in "I64Fd" us)",
1347                       i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1348                       i_bitrate, i_packet_count, i_pcr_length);
1349         }
1350 #if 0
1351         else
1352         {
1353             msg_Dbg( p_mux, "starting at "I64Fd
1354                      " (%d bi/s for %d packets in "I64Fd" us)",
1355                      i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1356                      i_bitrate, i_packet_count, i_pcr_length);
1357         }
1358 #endif
1359     }
1360     else
1361     {
1362         /* This shouldn't happen, but happens in some rare heavy load
1363          * and packet losses conditions. */
1364         i_pcr_length = i_packet_count;
1365     }
1366
1367     /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
1368     for( i = 0; i < i_packet_count; i++ )
1369     {
1370         block_t *p_ts = BufferChainGet( p_chain_ts );
1371         mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1372
1373         p_ts->i_dts    = i_new_dts;
1374         p_ts->i_length = i_pcr_length / i_packet_count;
1375
1376         if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_PCR )
1377         {
1378             /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
1379             TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
1380         }
1381         if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_CSA )
1382         {
1383             csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
1384         }
1385
1386         /* latency */
1387         p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
1388
1389         sout_AccessOutWrite( p_mux->p_access, p_ts );
1390     }
1391 }
1392
1393 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream,
1394                        vlc_bool_t b_pcr )
1395 {
1396     block_t *p_pes = p_stream->chain_pes.p_first;
1397     block_t *p_ts;
1398
1399     vlc_bool_t b_new_pes = VLC_FALSE;
1400     vlc_bool_t b_adaptation_field = VLC_FALSE;
1401
1402     int        i_payload_max = 184 - ( b_pcr ? 8 : 0 );
1403     int        i_payload;
1404
1405     if( p_stream->i_pes_used <= 0 )
1406     {
1407         b_new_pes = VLC_TRUE;
1408     }
1409     i_payload = __MIN( (int)p_pes->i_buffer - p_stream->i_pes_used,
1410                        i_payload_max );
1411
1412     if( b_pcr || i_payload < i_payload_max )
1413     {
1414         b_adaptation_field = VLC_TRUE;
1415     }
1416
1417     p_ts = block_New( p_mux, 188 );
1418     p_ts->i_dts = p_pes->i_dts;
1419
1420     p_ts->p_buffer[0] = 0x47;
1421     p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 ) |
1422         ( ( p_stream->i_pid >> 8 )&0x1f );
1423     p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1424     p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 ) |
1425         p_stream->i_continuity_counter;
1426
1427     p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1428
1429     if( b_adaptation_field )
1430     {
1431         int i;
1432
1433         if( b_pcr )
1434         {
1435             int     i_stuffing = i_payload_max - i_payload;
1436
1437             p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
1438
1439             p_ts->p_buffer[4] = 7 + i_stuffing;
1440             p_ts->p_buffer[5] = 0x10;   /* flags */
1441             p_ts->p_buffer[6] = ( 0 )&0xff;
1442             p_ts->p_buffer[7] = ( 0 )&0xff;
1443             p_ts->p_buffer[8] = ( 0 )&0xff;
1444             p_ts->p_buffer[9] = ( 0 )&0xff;
1445             p_ts->p_buffer[10]= ( 0 )&0x80;
1446             p_ts->p_buffer[11]= 0;
1447
1448             for( i = 12; i < 12 + i_stuffing; i++ )
1449             {
1450                 p_ts->p_buffer[i] = 0xff;
1451             }
1452         }
1453         else
1454         {
1455             int i_stuffing = i_payload_max - i_payload;
1456
1457             p_ts->p_buffer[4] = i_stuffing - 1;
1458             if( i_stuffing > 1 )
1459             {
1460                 p_ts->p_buffer[5] = 0x00;
1461                 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1462                 {
1463                     p_ts->p_buffer[i] = 0xff;
1464                 }
1465             }
1466         }
1467     }
1468
1469     /* copy payload */
1470     memcpy( &p_ts->p_buffer[188 - i_payload],
1471             &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
1472
1473     p_stream->i_pes_used += i_payload;
1474     p_stream->i_pes_dts = p_pes->i_dts + p_pes->i_length *
1475         p_stream->i_pes_used / p_pes->i_buffer;
1476     p_stream->i_pes_length -= p_pes->i_length * i_payload / p_pes->i_buffer;
1477
1478     if( p_stream->i_pes_used >= (int)p_pes->i_buffer )
1479     {
1480         p_pes = BufferChainGet( &p_stream->chain_pes );
1481         block_Release( p_pes );
1482
1483         p_pes = p_stream->chain_pes.p_first;
1484         if( p_pes )
1485         {
1486             p_stream->i_pes_dts    = p_pes->i_dts;
1487             p_stream->i_pes_length = 0;
1488             while( p_pes )
1489             {
1490                 p_stream->i_pes_length += p_pes->i_length;
1491
1492                 p_pes = p_pes->p_next;
1493             }
1494         }
1495         else
1496         {
1497             p_stream->i_pes_dts = 0;
1498             p_stream->i_pes_length = 0;
1499         }
1500         p_stream->i_pes_used = 0;
1501     }
1502
1503     return p_ts;
1504 }
1505
1506
1507 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
1508 {
1509     mtime_t i_pcr = 9 * i_dts / 100;
1510
1511     p_ts->p_buffer[6]  = ( i_pcr >> 25 )&0xff;
1512     p_ts->p_buffer[7]  = ( i_pcr >> 17 )&0xff;
1513     p_ts->p_buffer[8]  = ( i_pcr >> 9  )&0xff;
1514     p_ts->p_buffer[9]  = ( i_pcr >> 1  )&0xff;
1515     p_ts->p_buffer[10]|= ( i_pcr << 7  )&0x80;
1516 }
1517
1518 #if 0
1519 static void TSSetConstraints( sout_mux_t *p_mux, sout_buffer_chain_t *c,
1520                               mtime_t i_length, int i_bitrate_min,
1521                               int i_bitrate_max )
1522 {
1523     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1524     sout_buffer_chain_t s = *c;
1525
1526     int i_packets = 0;
1527     int i_packets_min = 0;
1528     int i_packets_max = 0;
1529
1530     if( i_length <= 0 )
1531     {
1532         return;
1533     }
1534
1535     i_packets     = c->i_depth;
1536     i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000  + 187 ) / 188;
1537     i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000  + 187 ) / 188;
1538
1539     if( i_packets < i_packets_min && i_packets_min > 0 )
1540     {
1541         block_t *p_pk;
1542         int i_div = ( i_packets_min - i_packets ) / i_packets;
1543         int i_mod = ( i_packets_min - i_packets ) % i_packets;
1544         int i_rest = 0;
1545
1546         /* We need to pad with null packets (pid=0x1fff)
1547          * We try to melt null packets with true packets */
1548         msg_Dbg( p_mux,
1549                  "packets=%d but min=%d -> adding %d packets of padding",
1550                  i_packets, i_packets_min, i_packets_min - i_packets );
1551
1552         BufferChainInit( c );
1553         while( ( p_pk = BufferChainGet( &s ) ) )
1554         {
1555             int i, i_null;
1556
1557             BufferChainAppend( c, p_pk );
1558
1559             i_null = i_div + ( i_rest + i_mod ) / i_packets;
1560
1561             for( i = 0; i < i_null; i++ )
1562             {
1563                 block_t *p_null;
1564
1565                 p_null = sout_BufferNew( p_mux->p_sout, 188 );
1566                 p_null->p_buffer[0] = 0x47;
1567                 p_null->p_buffer[1] = 0x1f;
1568                 p_null->p_buffer[2] = 0xff;
1569                 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
1570                 memset( &p_null->p_buffer[4], 0, 184 );
1571                 p_sys->i_null_continuity_counter =
1572                     ( p_sys->i_null_continuity_counter + 1 ) % 16;
1573
1574                 BufferChainAppend( c, p_null );
1575             }
1576
1577             i_rest = ( i_rest + i_mod ) % i_packets;
1578         }
1579     }
1580     else if( i_packets > i_packets_max && i_packets_max > 0 )
1581     {
1582         block_t *p_pk;
1583         int           i;
1584
1585         /* Arg, we need to drop packets, I don't do something clever (like
1586          * dropping complete pid, b frames, ... ), I just get the right amount
1587          * of packets and discard the others */
1588         msg_Warn( p_mux,
1589                   "packets=%d but max=%d -> removing %d packets -> stream broken",
1590                   i_packets, i_packets_max, i_packets - i_packets_max );
1591
1592         BufferChainInit( c );
1593         for( i = 0; i < i_packets_max; i++ )
1594         {
1595             BufferChainAppend( c, BufferChainGet( &s ) );
1596         }
1597
1598         while( ( p_pk = BufferChainGet( &s ) ) )
1599         {
1600             sout_BufferDelete( p_mux->p_sout, p_pk );
1601         }
1602     }
1603 }
1604 #endif
1605
1606 static void PEStoTS( sout_instance_t *p_sout,
1607                      sout_buffer_chain_t *c, block_t *p_pes,
1608                      ts_stream_t *p_stream )
1609 {
1610     uint8_t *p_data;
1611     int     i_size;
1612     int     b_new_pes;
1613
1614     /* get PES total size */
1615     i_size = p_pes->i_buffer;
1616     p_data = p_pes->p_buffer;
1617
1618     b_new_pes = VLC_TRUE;
1619
1620     for( ;; )
1621     {
1622         int           b_adaptation_field;
1623         int           i_copy;
1624         block_t *p_ts;
1625
1626         p_ts = block_New( p_sout, 188 );
1627         /* write header
1628          * 8b   0x47    sync byte
1629          * 1b           transport_error_indicator
1630          * 1b           payload_unit_start
1631          * 1b           transport_priority
1632          * 13b          pid
1633          * 2b           transport_scrambling_control
1634          * 2b           if adaptation_field 0x03 else 0x01
1635          * 4b           continuity_counter
1636          */
1637
1638         i_copy    = __MIN( i_size, 184 );
1639         b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
1640
1641         p_ts->p_buffer[0] = 0x47;
1642         p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
1643                             ( ( p_stream->i_pid >> 8 )&0x1f );
1644         p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1645         p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
1646                             p_stream->i_continuity_counter;
1647
1648         b_new_pes = VLC_FALSE;
1649         p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1650
1651         if( b_adaptation_field )
1652         {
1653             int i_stuffing = 184 - i_copy;
1654             int i;
1655
1656             p_ts->p_buffer[4] = i_stuffing - 1;
1657             if( i_stuffing > 1 )
1658             {
1659                 p_ts->p_buffer[5] = 0x00;
1660                 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1661                 {
1662                     p_ts->p_buffer[i] = 0xff;
1663                 }
1664             }
1665         }
1666         /* copy payload */
1667         memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1668         p_data += i_copy;
1669         i_size -= i_copy;
1670
1671         BufferChainAppend( c, p_ts );
1672
1673         if( i_size <= 0 )
1674         {
1675             block_t *p_next = p_pes->p_next;
1676
1677             p_pes->p_next = NULL;
1678             block_Release( p_pes );
1679             if( p_next == NULL )
1680             {
1681                 break;
1682             }
1683             b_new_pes = VLC_TRUE;
1684             p_pes = p_next;
1685             i_size = p_pes->i_buffer;
1686             p_data = p_pes->p_buffer;
1687         }
1688     }
1689
1690     return;
1691 }
1692
1693 static block_t *WritePSISection( sout_instance_t *p_sout,
1694                                        dvbpsi_psi_section_t* p_section )
1695 {
1696     block_t   *p_psi, *p_first = NULL;
1697
1698
1699     while( p_section )
1700     {
1701         int             i_size;
1702
1703         i_size =  (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1704                   ( p_section->b_syntax_indicator ? 4 : 0 );
1705
1706         p_psi = block_New( p_sout, i_size + 1 );
1707         p_psi->i_pts = 0;
1708         p_psi->i_dts = 0;
1709         p_psi->i_length = 0;
1710         p_psi->i_buffer = i_size + 1;
1711
1712         p_psi->p_buffer[0] = 0; // pointer
1713         memcpy( p_psi->p_buffer + 1,
1714                 p_section->p_data,
1715                 i_size );
1716
1717         block_ChainAppend( &p_first, p_psi );
1718
1719         p_section = p_section->p_next;
1720     }
1721
1722     return( p_first );
1723 }
1724
1725 static void GetPAT( sout_mux_t *p_mux,
1726                     sout_buffer_chain_t *c )
1727 {
1728     sout_mux_sys_t       *p_sys = p_mux->p_sys;
1729     block_t        *p_pat;
1730     dvbpsi_pat_t         pat;
1731     dvbpsi_psi_section_t *p_section;
1732
1733     dvbpsi_InitPAT( &pat, p_sys->i_tsid, p_sys->i_pat_version_number,
1734                     1 );      // b_current_next
1735     /* add all program (only one) */
1736     dvbpsi_PATAddProgram( &pat,
1737                           1,                    // i_number
1738                           p_sys->pmt.i_pid );   // i_pid
1739
1740     p_section = dvbpsi_GenPATSections( &pat,
1741                                        0 );     // max program per section
1742
1743     p_pat = WritePSISection( p_mux->p_sout, p_section );
1744
1745     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1746
1747     dvbpsi_DeletePSISections( p_section );
1748     dvbpsi_EmptyPAT( &pat );
1749 }
1750
1751 static uint32_t GetDescriptorLength24b( int i_length )
1752 {
1753     uint32_t i_l1, i_l2, i_l3;
1754
1755     i_l1 = i_length&0x7f;
1756     i_l2 = ( i_length >> 7 )&0x7f;
1757     i_l3 = ( i_length >> 14 )&0x7f;
1758
1759     return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1760 }
1761
1762 static void GetPMT( sout_mux_t *p_mux,
1763                     sout_buffer_chain_t *c )
1764 {
1765     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1766     block_t   *p_pmt;
1767
1768     dvbpsi_pmt_t        pmt;
1769     dvbpsi_pmt_es_t     *p_es;
1770     dvbpsi_psi_section_t *p_section;
1771
1772     int                 i_stream;
1773
1774     dvbpsi_InitPMT( &pmt,
1775                     0x01,   // program number
1776                     p_sys->i_pmt_version_number,
1777                     1,      // b_current_next
1778                     p_sys->i_pcr_pid );
1779
1780     if( p_sys->i_mpeg4_streams > 0 )
1781     {
1782         uint8_t iod[4096];
1783         bits_buffer_t bits;
1784         bits_buffer_t bits_fix_IOD;
1785
1786         /* Make valgrind happy : it works at byte level not bit one so
1787          * bit_write confuse it (but DON'T CHANGE the way that bit_write is
1788          * working (needed when fixing some bits) */
1789         memset( iod, 0, 4096 );
1790
1791         bits_initwrite( &bits, 4096, iod );
1792         // IOD_label
1793         bits_write( &bits, 8,   0x01 );
1794         // InitialObjectDescriptor
1795         bits_align( &bits );
1796         bits_write( &bits, 8,   0x02 );     // tag
1797         bits_fix_IOD = bits;    // save states to fix length later
1798         bits_write( &bits, 24,
1799             GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1800         bits_write( &bits, 10,  0x01 );     // ObjectDescriptorID
1801         bits_write( &bits, 1,   0x00 );     // URL Flag
1802         bits_write( &bits, 1,   0x00 );     // includeInlineProfileLevelFlag
1803         bits_write( &bits, 4,   0x0f );     // reserved
1804         bits_write( &bits, 8,   0xff );     // ODProfile (no ODcapability )
1805         bits_write( &bits, 8,   0xff );     // sceneProfile
1806         bits_write( &bits, 8,   0xfe );     // audioProfile (unspecified)
1807         bits_write( &bits, 8,   0xfe );     // visualProfile( // )
1808         bits_write( &bits, 8,   0xff );     // graphicProfile (no )
1809         for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1810         {
1811             ts_stream_t *p_stream;
1812             p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1813
1814             if( p_stream->i_stream_id == 0xfa ||
1815                 p_stream->i_stream_id == 0xfb ||
1816                 p_stream->i_stream_id == 0xfe )
1817             {
1818                 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1819                 /* ES descriptor */
1820                 bits_align( &bits );
1821                 bits_write( &bits, 8,   0x03 );     // ES_DescrTag
1822                 bits_fix_ESDescr = bits;
1823                 bits_write( &bits, 24,
1824                             GetDescriptorLength24b( 0 ) ); // variable size
1825                 bits_write( &bits, 16,  p_stream->i_es_id );
1826                 bits_write( &bits, 1,   0x00 );     // streamDependency
1827                 bits_write( &bits, 1,   0x00 );     // URL Flag
1828                 bits_write( &bits, 1,   0x00 );     // OCRStreamFlag
1829                 bits_write( &bits, 5,   0x1f );     // streamPriority
1830
1831                 // DecoderConfigDesciptor
1832                 bits_align( &bits );
1833                 bits_write( &bits, 8,   0x04 ); // DecoderConfigDescrTag
1834                 bits_fix_Decoder = bits;
1835                 bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) );
1836                 if( p_stream->i_stream_type == 0x10 )
1837                 {
1838                     bits_write( &bits, 8, 0x20 );   // Visual 14496-2
1839                     bits_write( &bits, 6, 0x04 );   // VisualStream
1840                 }
1841                 else if( p_stream->i_stream_type == 0x11 )
1842                 {
1843                     bits_write( &bits, 8, 0x40 );   // Audio 14496-3
1844                     bits_write( &bits, 6, 0x05 );   // AudioStream
1845                 }
1846                 else if( p_stream->i_stream_type == 0x12 &&
1847                          p_stream->i_codec == VLC_FOURCC('s','u','b','t') )
1848                 {
1849                     bits_write( &bits, 8, 0x0B );   // Text Stream
1850                     bits_write( &bits, 6, 0x04 );   // VisualStream
1851                 }
1852                 else
1853                 {
1854                     bits_write( &bits, 8, 0x00 );
1855                     bits_write( &bits, 6, 0x00 );
1856
1857                     msg_Err( p_mux->p_sout,"Unsupported stream_type => "
1858                              "broken IOD" );
1859                 }
1860                 bits_write( &bits, 1,   0x00 );     // UpStream
1861                 bits_write( &bits, 1,   0x01 );     // reserved
1862                 bits_write( &bits, 24,  1024 * 1024 );  // bufferSizeDB
1863                 bits_write( &bits, 32,  0x7fffffff );   // maxBitrate
1864                 bits_write( &bits, 32,  0 );            // avgBitrate
1865
1866                 if( p_stream->i_decoder_specific_info > 0 )
1867                 {
1868                     int i;
1869                     // DecoderSpecificInfo
1870                     bits_align( &bits );
1871                     bits_write( &bits, 8,   0x05 ); // tag
1872                     bits_write( &bits, 24, GetDescriptorLength24b(
1873                                 p_stream->i_decoder_specific_info ) );
1874                     for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1875                     {
1876                         bits_write( &bits, 8,
1877                             ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1878                     }
1879                 }
1880                 /* fix Decoder length */
1881                 bits_write( &bits_fix_Decoder, 24,
1882                             GetDescriptorLength24b( bits.i_data -
1883                             bits_fix_Decoder.i_data - 3 ) );
1884
1885                 /* SLConfigDescriptor : predifined (0x01) */
1886                 bits_align( &bits );
1887                 bits_write( &bits, 8,   0x06 ); // tag
1888                 bits_write( &bits, 24,  GetDescriptorLength24b( 8 ) );
1889                 bits_write( &bits, 8,   0x01 ); // predefined
1890                 bits_write( &bits, 1,   0 );   // durationFlag
1891                 bits_write( &bits, 32,  0 );   // OCRResolution
1892                 bits_write( &bits, 8,   0 );   // OCRLength
1893                 bits_write( &bits, 8,   0 );   // InstantBitrateLength
1894                 bits_align( &bits );
1895
1896                 /* fix ESDescr length */
1897                 bits_write( &bits_fix_ESDescr, 24,
1898                             GetDescriptorLength24b( bits.i_data -
1899                             bits_fix_ESDescr.i_data - 3 ) );
1900             }
1901         }
1902         bits_align( &bits );
1903         /* fix IOD length */
1904         bits_write( &bits_fix_IOD, 24,
1905                     GetDescriptorLength24b( bits.i_data -
1906                                             bits_fix_IOD.i_data - 3 ) );
1907         dvbpsi_PMTAddDescriptor( &pmt, 0x1d, bits.i_data, bits.p_data );
1908     }
1909
1910     for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1911     {
1912         ts_stream_t *p_stream;
1913
1914         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1915
1916         p_es = dvbpsi_PMTAddES( &pmt, p_stream->i_stream_type,
1917                                 p_stream->i_pid );
1918         if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1919         {
1920             uint8_t     es_id[2];
1921
1922             /* SL descriptor */
1923             es_id[0] = (p_stream->i_es_id >> 8)&0xff;
1924             es_id[1] = (p_stream->i_es_id)&0xff;
1925             dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
1926         }
1927         else if( p_stream->i_stream_type == 0xa0 )
1928         {
1929             uint8_t data[512];
1930             int i_extra = __MIN( p_stream->i_decoder_specific_info, 502 );
1931
1932             /* private DIV3 descripor */
1933             memcpy( &data[0], &p_stream->i_bih_codec, 4 );
1934             data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
1935             data[5] = ( p_stream->i_bih_width      )&0xff;
1936             data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
1937             data[7] = ( p_stream->i_bih_height     )&0xff;
1938             data[8] = ( i_extra >> 8 )&0xff;
1939             data[9] = ( i_extra      )&0xff;
1940             if( i_extra > 0 )
1941             {
1942                 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1943             }
1944
1945             /* 0xa0 is private */
1946             dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
1947         }
1948         else if( p_stream->i_stream_type == 0x81 )
1949         {
1950             uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1951
1952             /* "registration" descriptor : "AC-3" */
1953             dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1954         }
1955         else if( p_stream->i_codec == VLC_FOURCC('d','t','s',' ') )
1956         {
1957             /* DTS registration descriptor (ETSI TS 101 154 Annex F) */
1958
1959             /* DTS format identifier, frame size 1024 - FIXME */
1960             uint8_t data[4] = { 0x44, 0x54, 0x53, 0x32 };
1961             dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, data );
1962         }
1963         else if( p_stream->i_codec == VLC_FOURCC('t','e','l','x') )
1964         {
1965             dvbpsi_PMTESAddDescriptor( p_es, 0x56,
1966                                        p_stream->i_decoder_specific_info,
1967                                        p_stream->p_decoder_specific_info );
1968         }
1969 #ifdef _DVBPSI_DR_59_H_
1970         else if( p_stream->i_codec == VLC_FOURCC('d','v','b','s') )
1971         {
1972             /* DVB subtitles */
1973             dvbpsi_subtitling_dr_t descr;
1974             dvbpsi_subtitle_t sub;
1975             dvbpsi_descriptor_t *p_descr;
1976
1977             memcpy( sub.i_iso6392_language_code, p_stream->lang, 3 );
1978             sub.i_subtitling_type = 0x10; /* no aspect-ratio criticality */
1979             sub.i_composition_page_id = p_stream->i_es_id & 0xFF;
1980             sub.i_ancillary_page_id = p_stream->i_es_id >> 16;
1981
1982             descr.i_subtitles_number = 1;
1983             descr.p_subtitle[0] = sub;
1984
1985             p_descr = dvbpsi_GenSubtitlingDr( &descr, 0 );
1986             /* Work around bug in old libdvbpsi */ p_descr->i_length = 8;
1987             dvbpsi_PMTESAddDescriptor( p_es, p_descr->i_tag,
1988                                        p_descr->i_length, p_descr->p_data );
1989             continue;
1990         }
1991 #endif /* _DVBPSI_DR_59_H_ */
1992
1993         if( p_stream->lang[0] != 0 )
1994         {
1995             uint8_t data[4];
1996
1997             /* I construct the content myself, way faster than looking at
1998              * over complicated/mind broken libdvbpsi way */
1999             data[0] = p_stream->lang[0];
2000             data[1] = p_stream->lang[1];
2001             data[2] = p_stream->lang[2];
2002             data[3] = 0x00; /* audio type: 0x00 undefined */
2003
2004             dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data );
2005         }
2006     }
2007
2008     p_section = dvbpsi_GenPMTSections( &pmt );
2009
2010     p_pmt = WritePSISection( p_mux->p_sout, p_section );
2011
2012     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
2013
2014     dvbpsi_DeletePSISections( p_section );
2015     dvbpsi_EmptyPMT( &pmt );
2016 }