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