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