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