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