]> git.sesse.net Git - vlc/blob - modules/mux/mpeg/ts.c
* all: cast of lvalues ...
[vlc] / modules / mux / mpeg / ts.c
1 /*****************************************************************************
2  * ts.c: MPEG-II TS Muxer
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Eric Petit <titer@videolan.org>
9  *
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <stdlib.h>
30
31 #include <vlc/vlc.h>
32 #include <vlc/input.h>
33 #include <vlc/sout.h>
34
35 #include "iso_lang.h"
36
37 #include "bits.h"
38 #include "pes.h"
39 #include "csa.h"
40
41 #if defined MODULE_NAME_IS_mux_ts_dvbpsi
42 #   ifdef HAVE_DVBPSI_DR_H
43 #       include <dvbpsi/dvbpsi.h>
44 #       include <dvbpsi/descriptor.h>
45 #       include <dvbpsi/pat.h>
46 #       include <dvbpsi/pmt.h>
47 #       include <dvbpsi/dr.h>
48 #       include <dvbpsi/psi.h>
49 #   else
50 #       include "dvbpsi.h"
51 #       include "descriptor.h"
52 #       include "tables/pat.h"
53 #       include "tables/pmt.h"
54 #       include "descriptors/dr.h"
55 #       include "psi.h"
56 #   endif
57 #endif
58
59 /*
60  * TODO:
61  *  - check PCR frequency requirement
62  *  - check PAT/PMT  "        "
63  *  - check PCR/PCR "soft"
64  *  - check if "registration" descriptor : "AC-3" should be a program
65  *    descriptor or an es one. (xine want an es one)
66  *
67  *  - remove creation of PAT/PMT without dvbpsi
68  *  - ?
69  * FIXME:
70  *  - subtitle support is far from perfect. I expect some subtitles drop
71  *    if they arrive a bit late
72  *    (We cannot rely on the fact that the fifo should be full)
73  */
74 /*****************************************************************************
75  * Module descriptor
76  *****************************************************************************/
77 static int     Open   ( vlc_object_t * );
78 static void    Close  ( vlc_object_t * );
79
80 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 << BLOCK_FLAG_PRIVATE_SHIFT )
99 #define SOUT_BUFFER_FLAGS_PRIVATE_CSA  ( 2 << BLOCK_FLAG_PRIVATE_SHIFT )
100 typedef struct
101 {
102     int           i_depth;
103     block_t *p_first;
104     block_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, block_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 block_t *BufferChainGet( sout_buffer_chain_t *c )
126 {
127     block_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 block_t *BufferChainPeek( sout_buffer_chain_t *c )
144 {
145     block_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     block_t *b;
152
153     while( ( b = BufferChainGet( c ) ) )
154     {
155         block_Release( 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     vlc_bool_t          b_crypt_audio;
225 };
226
227
228 /* Reserve a pid and return it */
229 static int  AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
230 {
231     int i_pid;
232     if ( i_cat == VIDEO_ES && p_sys->i_pid_video )
233     {
234         i_pid = p_sys->i_pid_video;
235         p_sys->i_pid_video = 0;
236     }
237     else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio )
238     {
239         i_pid = p_sys->i_pid_audio;
240         p_sys->i_pid_audio = 0;
241     }
242     else
243     {
244         i_pid = ++p_sys->i_pid_free;
245     }
246     return i_pid;
247 }
248
249 /*****************************************************************************
250  * Local prototypes
251  *****************************************************************************/
252 static int     Capability(sout_mux_t *, int, void *, void * );
253 static int     AddStream( sout_mux_t *, sout_input_t * );
254 static int     DelStream( sout_mux_t *, sout_input_t * );
255 static int     Mux      ( sout_mux_t * );
256
257 static void TSSchedule  ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
258                           mtime_t i_pcr_length, mtime_t i_pcr_dts );
259 static void TSDate      ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
260                           mtime_t i_pcr_length, mtime_t i_pcr_dts );
261 static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
262 static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
263
264 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr );
265 static void TSSetPCR( block_t *p_ts, mtime_t i_dts );
266
267 static void PEStoTS  ( sout_instance_t *, sout_buffer_chain_t *, block_t *, ts_stream_t * );
268
269 /*****************************************************************************
270  * Open:
271  *****************************************************************************/
272 static int Open( vlc_object_t *p_this )
273 {
274     sout_mux_t          *p_mux =(sout_mux_t*)p_this;
275     sout_mux_sys_t      *p_sys;
276     char                *val;
277
278     msg_Dbg( p_mux, "Open" );
279
280     p_sys = malloc( sizeof( sout_mux_sys_t ) );
281
282     p_mux->pf_capacity  = Capability;
283     p_mux->pf_addstream = AddStream;
284     p_mux->pf_delstream = DelStream;
285     p_mux->pf_mux       = Mux;
286     p_mux->p_sys        = p_sys;
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 = VLC_FALSE;
379     if( sout_cfg_find( p_mux->p_cfg, "use-key-frames" ) )
380     {
381         p_sys->b_use_key_frames = VLC_TRUE;
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             uint64_t i_ck = strtoll( val, NULL, 16 );
411             uint8_t  ck[8];
412             int      i;
413
414             for( i = 0; i < 8; i++ )
415             {
416                 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
417             }
418
419             msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x",
420                      ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
421
422             p_sys->csa = csa_New();
423             csa_SetCW( p_sys->csa, ck, ck );
424         }
425     }
426     p_sys->b_crypt_audio = VLC_TRUE;
427     if( sout_cfg_find( p_mux->p_cfg, "no-crypt-audio" ) )
428     {
429         p_sys->b_crypt_audio = VLC_FALSE;
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 = 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             block_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 = block_FifoGet( p_input->p_fifo );
808                     if( p_input->p_fifo->i_depth > 0 )
809                     {
810                         block_t *p_next = block_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                         block_Release( 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                         if( p_stream->i_stream_id == 0xa0 && p_data->i_pts <= 0 )
852                         {
853                             /* XXX yes I know, it's awfull, but it's needed, so don't remove it ... */
854                             p_data->i_pts = p_data->i_dts;
855                         }
856                         E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 );
857
858                         BufferChainAppend( &p_stream->chain_pes, p_data );
859
860                         if( p_sys->b_use_key_frames && p_stream == p_pcr_stream
861                             && (p_data->i_flags & BLOCK_FLAG_TYPE_I )
862                             && (p_stream->i_pes_length > 300000) )
863                         {
864                             i_shaping_delay = p_stream->i_pes_length;
865                             p_stream->b_key_frame = 1;
866                         }
867                     }
868                 }
869             }
870
871             if( b_ok )
872             {
873                 break;
874             }
875         }
876
877         /* save */
878         i_pcr_dts      = p_pcr_stream->i_pes_dts;
879         i_pcr_length   = p_pcr_stream->i_pes_length;
880         p_pcr_stream->b_key_frame = 0;
881
882         /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
883         /* 2: calculate non accurate total size of muxed ts */
884         i_packet_count = 0;
885         for( i = 0; i < p_mux->i_nb_inputs; i++ )
886         {
887             ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
888             block_t *p_pes;
889
890             /* False for pcr stream but it will be enough to do PCR algo */
891             for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL; p_pes = p_pes->p_next )
892             {
893                 int i_size = p_pes->i_buffer;
894                 if( p_pes->i_dts + p_pes->i_length > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
895                 {
896                     mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts;
897                     if( i_frag < 0 )
898                     {
899                         /* Next stream */
900                         break;
901                     }
902                     i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
903                 }
904                 i_packet_count += ( i_size + 183 ) / 184;
905             }
906         }
907         /* add overhead for PCR (not really exact) */
908         i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176;
909
910
911         /* 3: mux PES into TS */
912         BufferChainInit( &chain_ts );
913         /* append PAT/PMT  -> FIXME with big pcr delay it won't have enough pat/pmt */
914         GetPAT( p_mux, &chain_ts);
915         GetPMT( p_mux, &chain_ts );
916         i_packet_pos = 0;
917         i_packet_count += chain_ts.i_depth;
918         /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
919
920         for( ;; )
921         {
922             int         i_stream;
923             mtime_t     i_dts;
924             ts_stream_t *p_stream;
925             sout_input_t *p_input;
926             block_t *p_ts;
927             vlc_bool_t   b_pcr;
928
929             /* Select stream (lowest dts) */
930             for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
931             {
932                 p_input = p_mux->pp_inputs[i];
933                 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
934
935                 if( p_stream->i_pes_dts == 0 )
936                 {
937                     continue;
938                 }
939
940                 if( i_stream == -1 ||
941                     p_stream->i_pes_dts < i_dts )
942                 {
943                     i_stream = i;
944                     i_dts = p_stream->i_pes_dts;
945                 }
946             }
947             if( i_stream == -1 )
948             {
949                 break;
950             }
951             p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
952
953             /* do we need to issue pcr */
954             b_pcr = VLC_FALSE;
955             if( p_stream == p_pcr_stream &&
956                 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >= p_sys->i_pcr + p_sys->i_pcr_delay )
957             {
958                 b_pcr = VLC_TRUE;
959                 p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count;
960             }
961
962             /* Build the TS packet */
963             p_ts = TSNew( p_mux, p_stream, b_pcr );
964             if( p_sys->csa != NULL &&
965                  (p_input->p_fmt->i_cat != AUDIO_ES || p_sys->b_crypt_audio) )
966             {
967                 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
968             }
969             i_packet_pos++;
970
971             /* */
972             BufferChainAppend( &chain_ts, p_ts );
973         }
974
975         /* 4: date and send */
976         TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
977     }
978 }
979
980 static void TSSchedule( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
981                         mtime_t i_pcr_length, mtime_t i_pcr_dts )
982 {
983     sout_mux_sys_t  *p_sys = p_mux->p_sys;
984     sout_buffer_chain_t new_chain;
985     int i_packet_count = p_chain_ts->i_depth;
986     int i;
987
988     BufferChainInit( &new_chain );
989
990     if ( i_pcr_length <= 0 )
991     {
992         i_pcr_length = i_packet_count;
993     }
994
995     for( i = 0; i < i_packet_count; i++ )
996     {
997         block_t *p_ts = BufferChainGet( p_chain_ts );
998         mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
999
1000         BufferChainAppend( &new_chain, p_ts );
1001
1002         if( p_ts->i_dts &&
1003             p_ts->i_dts + p_sys->i_dts_delay * 2/3 < i_new_dts )
1004         {
1005             mtime_t i_max_diff = i_new_dts - p_ts->i_dts;
1006             mtime_t i_cut_dts = p_ts->i_dts;
1007
1008             p_ts = BufferChainPeek( p_chain_ts );
1009             i++;
1010             i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1011             while ( p_ts != NULL && i_new_dts - p_ts->i_dts >= i_max_diff )
1012             {
1013                 p_ts = BufferChainGet( p_chain_ts );
1014                 i_max_diff = i_new_dts - p_ts->i_dts;
1015                 i_cut_dts = p_ts->i_dts;
1016                 BufferChainAppend( &new_chain, p_ts );
1017
1018                 p_ts = BufferChainPeek( p_chain_ts );
1019                 i++;
1020                 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1021             }
1022             msg_Dbg( p_mux, "adjusting rate at "I64Fd"/"I64Fd" (%d/%d)",
1023                      i_cut_dts - i_pcr_dts, i_pcr_length, new_chain.i_depth,
1024                      p_chain_ts->i_depth );
1025             if ( new_chain.i_depth )
1026                 TSDate( p_mux, &new_chain,
1027                         i_cut_dts - i_pcr_dts,
1028                         i_pcr_dts );
1029             if ( p_chain_ts->i_depth )
1030                 TSSchedule( p_mux,
1031                             p_chain_ts, i_pcr_dts + i_pcr_length - i_cut_dts,
1032                             i_cut_dts );
1033             return;
1034         }
1035     }
1036
1037     if ( new_chain.i_depth )
1038         TSDate( p_mux, &new_chain, i_pcr_length, i_pcr_dts );
1039 }
1040
1041 static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1042                     mtime_t i_pcr_length, mtime_t i_pcr_dts )
1043 {
1044     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1045     int i_packet_count = p_chain_ts->i_depth;
1046     int i;
1047
1048     if ( i_pcr_length > 0 )
1049     {
1050         int i_bitrate = ((uint64_t)i_packet_count * 188 * 8000)
1051                           / (uint64_t)(i_pcr_length / 1000);
1052         if ( p_sys->i_bitrate_max && p_sys->i_bitrate_max < i_bitrate )
1053         {
1054             msg_Warn( p_mux,
1055                 "max bitrate exceeded at %lld (%d bi/s for %d pkt in %lld us)",
1056                 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1057                 i_bitrate, i_packet_count, i_pcr_length);
1058         }
1059 #if 0
1060         else
1061         {
1062             msg_Dbg( p_mux,
1063                 "starting at %lld (%d bi/s for %d packets in %lld us)",
1064                 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1065                 i_bitrate, i_packet_count, i_pcr_length);
1066         }
1067 #endif
1068     }
1069     else
1070     {
1071         /* This shouldn't happen, but happens in some rare heavy load
1072          * and packet losses conditions. */
1073         i_pcr_length = i_packet_count;
1074     }
1075
1076     /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
1077     for( i = 0; i < i_packet_count; i++ )
1078     {
1079         block_t *p_ts = BufferChainGet( p_chain_ts );
1080         mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1081
1082         p_ts->i_dts    = i_new_dts;
1083         p_ts->i_length = i_pcr_length / i_packet_count;
1084
1085         if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_PCR )
1086         {
1087             /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
1088             TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
1089         }
1090         if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_CSA )
1091         {
1092             csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
1093         }
1094
1095         /* latency */
1096         p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
1097
1098         sout_AccessOutWrite( p_mux->p_access, p_ts );
1099     }
1100 }
1101
1102 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr )
1103 {
1104     block_t *p_pes = p_stream->chain_pes.p_first;
1105     block_t *p_ts;
1106
1107     vlc_bool_t b_new_pes = VLC_FALSE;
1108     vlc_bool_t b_adaptation_field = VLC_FALSE;
1109
1110     int        i_payload_max = 184 - ( b_pcr ? 8 : 0 );
1111     int        i_payload;
1112
1113     if( p_stream->i_pes_used <= 0 )
1114     {
1115         b_new_pes = VLC_TRUE;
1116     }
1117     i_payload = __MIN( (int)p_pes->i_buffer - p_stream->i_pes_used, i_payload_max );
1118
1119     if( b_pcr || i_payload < i_payload_max )
1120     {
1121         b_adaptation_field = VLC_TRUE;
1122     }
1123
1124     p_ts = block_New( p_mux, 188 );
1125     p_ts->i_dts = p_pes->i_dts;
1126
1127     p_ts->p_buffer[0] = 0x47;
1128     p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|( ( p_stream->i_pid >> 8 )&0x1f );
1129     p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1130     p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|p_stream->i_continuity_counter;
1131
1132     p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1133
1134     if( b_adaptation_field )
1135     {
1136         int i;
1137
1138         if( b_pcr )
1139         {
1140             int     i_stuffing = i_payload_max - i_payload;
1141
1142             p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
1143
1144             p_ts->p_buffer[4] = 7 + i_stuffing;
1145             p_ts->p_buffer[5] = 0x10;   /* flags */
1146             p_ts->p_buffer[6] = ( 0 )&0xff;
1147             p_ts->p_buffer[7] = ( 0 )&0xff;
1148             p_ts->p_buffer[8] = ( 0 )&0xff;
1149             p_ts->p_buffer[9] = ( 0 )&0xff;
1150             p_ts->p_buffer[10]= ( 0 )&0x80;
1151             p_ts->p_buffer[11]= 0;
1152
1153             for( i = 12; i < 12 + i_stuffing; i++ )
1154             {
1155                 p_ts->p_buffer[i] = 0xff;
1156             }
1157         }
1158         else
1159         {
1160             int i_stuffing = i_payload_max - i_payload;
1161
1162             p_ts->p_buffer[4] = i_stuffing - 1;
1163             if( i_stuffing > 1 )
1164             {
1165                 p_ts->p_buffer[5] = 0x00;
1166                 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1167                 {
1168                     p_ts->p_buffer[i] = 0xff;
1169                 }
1170             }
1171         }
1172     }
1173
1174     /* copy payload */
1175     memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
1176
1177     p_stream->i_pes_used += i_payload;
1178     p_stream->i_pes_dts      = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_buffer;
1179     p_stream->i_pes_length  -= p_pes->i_length * i_payload / p_pes->i_buffer;
1180
1181     if( p_stream->i_pes_used >= (int)p_pes->i_buffer )
1182     {
1183         p_pes = BufferChainGet( &p_stream->chain_pes );
1184         block_Release( p_pes );
1185
1186         p_pes = p_stream->chain_pes.p_first;
1187         if( p_pes )
1188         {
1189             p_stream->i_pes_dts    = p_pes->i_dts;
1190             p_stream->i_pes_length = 0;
1191             while( p_pes )
1192             {
1193                 p_stream->i_pes_length += p_pes->i_length;
1194
1195                 p_pes = p_pes->p_next;
1196             }
1197         }
1198         else
1199         {
1200             p_stream->i_pes_dts = 0;
1201             p_stream->i_pes_length = 0;
1202         }
1203         p_stream->i_pes_used = 0;
1204     }
1205
1206     return p_ts;
1207 }
1208
1209
1210 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
1211 {
1212     mtime_t i_pcr = 9 * i_dts / 100;
1213
1214     p_ts->p_buffer[6]  = ( i_pcr >> 25 )&0xff;
1215     p_ts->p_buffer[7]  = ( i_pcr >> 17 )&0xff;
1216     p_ts->p_buffer[8]  = ( i_pcr >> 9  )&0xff;
1217     p_ts->p_buffer[9]  = ( i_pcr >> 1  )&0xff;
1218     p_ts->p_buffer[10]|= ( i_pcr << 7  )&0x80;
1219 }
1220
1221 #if 0
1222 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 )
1223 {
1224     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1225     sout_buffer_chain_t s = *c;
1226
1227     int i_packets = 0;
1228     int i_packets_min = 0;
1229     int i_packets_max = 0;
1230
1231     if( i_length <= 0 )
1232     {
1233         return;
1234     }
1235
1236     i_packets     = c->i_depth;
1237     i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000  + 187 ) / 188;
1238     i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000  + 187 ) / 188;
1239
1240     if( i_packets < i_packets_min && i_packets_min > 0 )
1241     {
1242         block_t *p_pk;
1243         int i_div = ( i_packets_min - i_packets ) / i_packets;
1244         int i_mod = ( i_packets_min - i_packets ) % i_packets;
1245         int i_rest = 0;
1246
1247         /* We need to pad with null packets (pid=0x1fff)
1248          * We try to melt null packets with true packets */
1249         msg_Dbg( p_mux,
1250                  "packets=%d but min=%d -> adding %d packets of padding",
1251                  i_packets, i_packets_min, i_packets_min - i_packets );
1252
1253         BufferChainInit( c );
1254         while( ( p_pk = BufferChainGet( &s ) ) )
1255         {
1256             int i, i_null;
1257
1258             BufferChainAppend( c, p_pk );
1259
1260             i_null = i_div + ( i_rest + i_mod ) / i_packets;
1261
1262             for( i = 0; i < i_null; i++ )
1263             {
1264                 block_t *p_null;
1265
1266                 p_null = sout_BufferNew( p_mux->p_sout, 188 );
1267                 p_null->p_buffer[0] = 0x47;
1268                 p_null->p_buffer[1] = 0x1f;
1269                 p_null->p_buffer[2] = 0xff;
1270                 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
1271                 memset( &p_null->p_buffer[4], 0, 184 );
1272                 p_sys->i_null_continuity_counter =
1273                     ( p_sys->i_null_continuity_counter + 1 ) % 16;
1274
1275                 BufferChainAppend( c, p_null );
1276             }
1277
1278             i_rest = ( i_rest + i_mod ) % i_packets;
1279         }
1280     }
1281     else if( i_packets > i_packets_max && i_packets_max > 0 )
1282     {
1283         block_t *p_pk;
1284         int           i;
1285
1286         /* Arg, we need to drop packets, I don't do something clever (like
1287          * dropping complete pid, b frames, ... ), I just get the right amount
1288          * of packets and discard the others */
1289         msg_Warn( p_mux,
1290                   "packets=%d but max=%d -> removing %d packets -> stream broken",
1291                   i_packets, i_packets_max, i_packets - i_packets_max );
1292
1293         BufferChainInit( c );
1294         for( i = 0; i < i_packets_max; i++ )
1295         {
1296             BufferChainAppend( c, BufferChainGet( &s ) );
1297         }
1298
1299         while( ( p_pk = BufferChainGet( &s ) ) )
1300         {
1301             sout_BufferDelete( p_mux->p_sout, p_pk );
1302         }
1303     }
1304 }
1305 #endif
1306
1307 static void PEStoTS( sout_instance_t *p_sout,
1308                      sout_buffer_chain_t *c, block_t *p_pes,
1309                      ts_stream_t *p_stream )
1310 {
1311     uint8_t *p_data;
1312     int     i_size;
1313     int     b_new_pes;
1314
1315     /* get PES total size */
1316     i_size = p_pes->i_buffer;
1317     p_data = p_pes->p_buffer;
1318
1319     b_new_pes = VLC_TRUE;
1320
1321     for( ;; )
1322     {
1323         int           b_adaptation_field;
1324         int           i_copy;
1325         block_t *p_ts;
1326
1327         p_ts = block_New( p_sout, 188 );
1328         /* write header
1329          * 8b   0x47    sync byte
1330          * 1b           transport_error_indicator
1331          * 1b           payload_unit_start
1332          * 1b           transport_priority
1333          * 13b          pid
1334          * 2b           transport_scrambling_control
1335          * 2b           if adaptation_field 0x03 else 0x01
1336          * 4b           continuity_counter
1337          */
1338
1339         i_copy    = __MIN( i_size, 184 );
1340         b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
1341
1342         p_ts->p_buffer[0] = 0x47;
1343         p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
1344                             ( ( p_stream->i_pid >> 8 )&0x1f );
1345         p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1346         p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
1347                             p_stream->i_continuity_counter;
1348
1349         b_new_pes = VLC_FALSE;
1350         p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1351
1352         if( b_adaptation_field )
1353         {
1354             int i_stuffing = 184 - i_copy;
1355             int i;
1356
1357             p_ts->p_buffer[4] = i_stuffing - 1;
1358             if( i_stuffing > 1 )
1359             {
1360                 p_ts->p_buffer[5] = 0x00;
1361                 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1362                 {
1363                     p_ts->p_buffer[i] = 0xff;
1364                 }
1365             }
1366         }
1367         /* copy payload */
1368         memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1369         p_data += i_copy;
1370         i_size -= i_copy;
1371
1372         BufferChainAppend( c, p_ts );
1373
1374         if( i_size <= 0 )
1375         {
1376             block_t *p_next = p_pes->p_next;
1377
1378             p_pes->p_next = NULL;
1379             block_Release( p_pes );
1380             if( p_next == NULL )
1381             {
1382                 break;
1383             }
1384             b_new_pes = VLC_TRUE;
1385             p_pes = p_next;
1386             i_size = p_pes->i_buffer;
1387             p_data = p_pes->p_buffer;
1388         }
1389     }
1390
1391     return;
1392 }
1393
1394 #if defined MODULE_NAME_IS_mux_ts
1395 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1396 {
1397     static uint32_t CRC32[256] =
1398     {
1399         0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1400         0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1401         0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1402         0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1403         0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1404         0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1405         0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1406         0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1407         0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1408         0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1409         0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1410         0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1411         0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1412         0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1413         0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1414         0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1415         0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1416         0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1417         0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1418         0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1419         0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1420         0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1421         0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1422         0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1423         0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1424         0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1425         0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1426         0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1427         0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1428         0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1429         0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1430         0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1431         0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1432         0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1433         0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1434         0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1435         0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1436         0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1437         0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1438         0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1439         0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1440         0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1441         0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1442         0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1443         0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1444         0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1445         0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1446         0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1447         0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1448         0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1449         0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1450         0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1451         0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1452         0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1453         0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1454         0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1455         0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1456         0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1457         0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1458         0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1459         0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1460         0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1461         0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1462         0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1463     };
1464
1465     uint32_t i_crc = 0xffffffff;
1466
1467     /* Calculate the CRC */
1468     while( i_count > 0 )
1469     {
1470         i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1471         p_begin++;
1472         i_count--;
1473     }
1474
1475     return( i_crc );
1476 }
1477
1478 static void GetPAT( sout_mux_t *p_mux,
1479                     sout_buffer_chain_t *c )
1480 {
1481     sout_mux_sys_t      *p_sys = p_mux->p_sys;
1482     block_t       *p_pat;
1483     bits_buffer_t bits;
1484
1485     p_pat = block_New( p_mux, 1024 );
1486
1487     p_pat->i_pts = 0;
1488     p_pat->i_dts = 0;
1489     p_pat->i_length = 0;
1490
1491     bits_initwrite( &bits, 1024, p_pat->p_buffer );
1492
1493     bits_write( &bits, 8, 0 );      // pointer
1494     bits_write( &bits, 8, 0x00 );   // table id
1495     bits_write( &bits, 1,  1 );     // section_syntax_indicator
1496     bits_write( &bits, 1,  0 );     // 0
1497     bits_write( &bits, 2,  0x03 );     // reserved FIXME
1498     bits_write( &bits, 12, 13 );    // XXX for one program only XXX 
1499     bits_write( &bits, 16, 0x01 );  // FIXME stream id
1500     bits_write( &bits, 2,  0x03 );     //  FIXME
1501     bits_write( &bits, 5,  p_sys->i_pat_version_number );
1502     bits_write( &bits, 1,  1 );     // current_next_indicator
1503     bits_write( &bits, 8,  0 );     // section number
1504     bits_write( &bits, 8,  0 );     // last section number
1505
1506     bits_write( &bits, 16, 1 );     // program number
1507     bits_write( &bits,  3, 0x07 );     // reserved
1508     bits_write( &bits, 13, p_sys->pmt.i_pid );  // program map pid
1509
1510     bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1511
1512     p_pat->i_buffer = bits.i_data;
1513
1514     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1515 }
1516
1517 static void GetPMT( sout_mux_t *p_mux,
1518                     sout_buffer_chain_t *c )
1519 {
1520     sout_mux_sys_t      *p_sys = p_mux->p_sys;
1521     block_t       *p_pmt;
1522     bits_buffer_t bits;
1523     int           i_stream;
1524
1525     p_pmt = block_New( p_mux, 1024 );
1526
1527     p_pmt->i_pts = 0;
1528     p_pmt->i_dts = 0;
1529     p_pmt->i_length = 0;
1530
1531     bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1532
1533     bits_write( &bits, 8, 0 );      // pointer
1534     bits_write( &bits, 8, 0x02 );   // table id
1535     bits_write( &bits, 1,  1 );     // section_syntax_indicator
1536     bits_write( &bits, 1,  0 );     // 0
1537     bits_write( &bits, 2,  0 );     // reserved FIXME
1538     bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1539     bits_write( &bits, 16, 1 );     // FIXME program number
1540     bits_write( &bits, 2,  0 );     //  FIXME
1541     bits_write( &bits, 5,  p_sys->i_pmt_version_number );
1542     bits_write( &bits, 1,  1 );     // current_next_indicator
1543     bits_write( &bits, 8,  0 );     // section number
1544     bits_write( &bits, 8,  0 );     // last section number
1545
1546     bits_write( &bits,  3, 0 );     // reserved
1547
1548     bits_write( &bits, 13, p_sys->i_pcr_pid );     //  FIXME FXIME PCR_PID FIXME
1549     bits_write( &bits,  4, 0 );     // reserved FIXME
1550
1551     bits_write( &bits, 12, 0 );    // program info len FIXME
1552
1553     for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1554     {
1555         ts_stream_t *p_stream;
1556
1557         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1558
1559         bits_write( &bits,  8, p_stream->i_stream_type ); // stream_type
1560         bits_write( &bits,  3, 0 );                 // reserved
1561         bits_write( &bits, 13, p_stream->i_pid );   // es pid
1562         bits_write( &bits,  4, 0 );                 //reserved
1563         bits_write( &bits, 12, 0 );                 // es info len FIXME
1564     }
1565
1566     bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1567
1568     p_pmt->i_buffer = bits.i_data;
1569
1570     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1571 }
1572 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1573
1574 static block_t *WritePSISection( sout_instance_t *p_sout,
1575                                        dvbpsi_psi_section_t* p_section )
1576 {
1577     block_t   *p_psi, *p_first = NULL;
1578
1579
1580     while( p_section )
1581     {
1582         int             i_size;
1583
1584         i_size =  (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1585                   ( p_section->b_syntax_indicator ? 4 : 0 );
1586
1587         p_psi = block_New( p_sout, i_size + 1 );
1588         p_psi->i_pts = 0;
1589         p_psi->i_dts = 0;
1590         p_psi->i_length = 0;
1591         p_psi->i_buffer = i_size + 1;
1592
1593         p_psi->p_buffer[0] = 0; // pointer
1594         memcpy( p_psi->p_buffer + 1,
1595                 p_section->p_data,
1596                 i_size );
1597
1598         block_ChainAppend( &p_first, p_psi );
1599
1600         p_section = p_section->p_next;
1601     }
1602
1603     return( p_first );
1604 }
1605
1606 static void GetPAT( sout_mux_t *p_mux,
1607                     sout_buffer_chain_t *c )
1608 {
1609     sout_mux_sys_t       *p_sys = p_mux->p_sys;
1610     block_t        *p_pat;
1611     dvbpsi_pat_t         pat;
1612     dvbpsi_psi_section_t *p_section;
1613
1614     dvbpsi_InitPAT( &pat,
1615                     0x01,    // i_ts_id
1616                     p_sys->i_pat_version_number,
1617                     1 );      // b_current_next
1618     /* add all program (only one) */
1619     dvbpsi_PATAddProgram( &pat,
1620                           1,                    // i_number
1621                           p_sys->pmt.i_pid );   // i_pid
1622
1623     p_section = dvbpsi_GenPATSections( &pat,
1624                                        0 );     // max program per section
1625
1626     p_pat = WritePSISection( p_mux->p_sout, p_section );
1627
1628     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1629
1630     dvbpsi_DeletePSISections( p_section );
1631     dvbpsi_EmptyPAT( &pat );
1632 }
1633
1634 static uint32_t GetDescriptorLength24b( int i_length )
1635 {
1636     uint32_t    i_l1, i_l2, i_l3;
1637
1638     i_l1 = i_length&0x7f;
1639     i_l2 = ( i_length >> 7 )&0x7f;
1640     i_l3 = ( i_length >> 14 )&0x7f;
1641
1642     return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1643 }
1644
1645 static void GetPMT( sout_mux_t *p_mux,
1646                     sout_buffer_chain_t *c )
1647 {
1648     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1649     block_t   *p_pmt;
1650
1651     dvbpsi_pmt_t        pmt;
1652     dvbpsi_pmt_es_t     *p_es;
1653     dvbpsi_psi_section_t *p_section;
1654
1655     int                 i_stream;
1656
1657     dvbpsi_InitPMT( &pmt,
1658                     0x01,   // program number
1659                     p_sys->i_pmt_version_number,
1660                     1,      // b_current_next
1661                     p_sys->i_pcr_pid );
1662
1663     if( p_sys->i_mpeg4_streams > 0 )
1664     {
1665         uint8_t iod[4096];
1666         bits_buffer_t bits;
1667         bits_buffer_t bits_fix_IOD;
1668
1669         /* Make valgrind happy : it works at byte level not bit one so
1670          * bit_write confuse it (but DON'T CHANGE the way that bit_write is
1671          * working (needed when fixing some bits) */
1672         memset( iod, 0, 4096 );
1673
1674         bits_initwrite( &bits, 4096, iod );
1675         // IOD_label
1676         bits_write( &bits, 8,   0x01 );
1677         // InitialObjectDescriptor
1678         bits_align( &bits );
1679         bits_write( &bits, 8,   0x02 );     // tag
1680         bits_fix_IOD = bits;    // save states to fix length later
1681         bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1682         bits_write( &bits, 10,  0x01 );     // ObjectDescriptorID
1683         bits_write( &bits, 1,   0x00 );     // URL Flag
1684         bits_write( &bits, 1,   0x00 );     // includeInlineProfileLevelFlag
1685         bits_write( &bits, 4,   0x0f );     // reserved
1686         bits_write( &bits, 8,   0xff );     // ODProfile (no ODcapability )
1687         bits_write( &bits, 8,   0xff );     // sceneProfile
1688         bits_write( &bits, 8,   0xfe );     // audioProfile (unspecified)
1689         bits_write( &bits, 8,   0xfe );     // visualProfile( // )
1690         bits_write( &bits, 8,   0xff );     // graphicProfile (no )
1691         for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1692         {
1693             ts_stream_t *p_stream;
1694             p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1695
1696             if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1697             {
1698                 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1699                 /* ES descriptor */
1700                 bits_align( &bits );
1701                 bits_write( &bits, 8,   0x03 );     // ES_DescrTag
1702                 bits_fix_ESDescr = bits;
1703                 bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) ); // variable size
1704                 bits_write( &bits, 16,  p_stream->i_es_id );
1705                 bits_write( &bits, 1,   0x00 );     // streamDependency
1706                 bits_write( &bits, 1,   0x00 );     // URL Flag
1707                 bits_write( &bits, 1,   0x00 );     // OCRStreamFlag
1708                 bits_write( &bits, 5,   0x1f );     // streamPriority
1709
1710                     // DecoderConfigDesciptor
1711                 bits_align( &bits );
1712                 bits_write( &bits, 8,   0x04 ); // DecoderConfigDescrTag
1713                 bits_fix_Decoder = bits;
1714                 bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) );
1715                 if( p_stream->i_stream_type == 0x10 )
1716                 {
1717                     bits_write( &bits, 8, 0x20 );   // Visual 14496-2
1718                     bits_write( &bits, 6, 0x04 );   // VisualStream
1719                 }
1720                 else if( p_stream->i_stream_type == 0x11 )
1721                 {
1722                     bits_write( &bits, 8, 0x40 );   // Audio 14496-3
1723                     bits_write( &bits, 6, 0x05 );   // AudioStream
1724                 }
1725                 else
1726                 {
1727                     bits_write( &bits, 8, 0x00 );
1728                     bits_write( &bits, 6, 0x00 );
1729
1730                     msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1731                 }
1732                 bits_write( &bits, 1,   0x00 );     // UpStream
1733                 bits_write( &bits, 1,   0x01 );     // reserved
1734                 bits_write( &bits, 24,  1024 * 1024 );  // bufferSizeDB
1735                 bits_write( &bits, 32,  0x7fffffff );   // maxBitrate
1736                 bits_write( &bits, 32,  0 );            // avgBitrate
1737
1738                 if( p_stream->i_decoder_specific_info > 0 )
1739                 {
1740                     int i;
1741                     // DecoderSpecificInfo
1742                     bits_align( &bits );
1743                     bits_write( &bits, 8,   0x05 ); // tag
1744                     bits_write( &bits, 24,
1745                                 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1746                     for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1747                     {
1748                         bits_write( &bits, 8,   ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1749                     }
1750                 }
1751                 /* fix Decoder length */
1752                 bits_write( &bits_fix_Decoder, 24,
1753                             GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1754
1755                 /* SLConfigDescriptor : predifined (0x01) */
1756                 bits_align( &bits );
1757                 bits_write( &bits, 8,   0x06 ); // tag
1758                 bits_write( &bits, 24,  GetDescriptorLength24b( 8 ) );
1759                 bits_write( &bits, 8,   0x01 ); // predefined
1760                 bits_write( &bits, 1,   0 );   // durationFlag
1761                 bits_write( &bits, 32,  0 );   // OCRResolution
1762                 bits_write( &bits, 8,   0 );   // OCRLength
1763                 bits_write( &bits, 8,   0 );   // InstantBitrateLength
1764                 bits_align( &bits );
1765
1766                 /* fix ESDescr length */
1767                 bits_write( &bits_fix_ESDescr, 24,
1768                             GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1769             }
1770         }
1771         bits_align( &bits );
1772         /* fix IOD length */
1773         bits_write( &bits_fix_IOD, 24,
1774                     GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1775         dvbpsi_PMTAddDescriptor( &pmt,
1776                                  0x1d,
1777                                  bits.i_data,
1778                                  bits.p_data );
1779     }
1780
1781     for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1782     {
1783         ts_stream_t *p_stream;
1784
1785         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1786
1787         p_es = dvbpsi_PMTAddES( &pmt,
1788                                 p_stream->i_stream_type,
1789                                 p_stream->i_pid );
1790         if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1791         {
1792             uint8_t     es_id[2];
1793
1794             /* SL descriptor */
1795             es_id[0] = (p_stream->i_es_id >> 8)&0xff;
1796             es_id[1] = (p_stream->i_es_id)&0xff;
1797             dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
1798         }
1799         else if( p_stream->i_stream_type == 0xa0 )
1800         {
1801             uint8_t     data[512];
1802             int         i_extra = __MIN( p_stream->i_decoder_specific_info,
1803                                         502 );
1804
1805             /* private DIV3 descripor */
1806             memcpy( &data[0], &p_stream->i_bih_codec, 4 );
1807             data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
1808             data[5] = ( p_stream->i_bih_width      )&0xff;
1809             data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
1810             data[7] = ( p_stream->i_bih_height     )&0xff;
1811             data[8] = ( i_extra >> 8 )&0xff;
1812             data[9] = ( i_extra      )&0xff;
1813             if( i_extra > 0 )
1814             {
1815                 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1816             }
1817
1818             /* 0xa0 is private */
1819             dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra  + 10, data );
1820         }
1821         else if( p_stream->i_stream_type == 0x81 )
1822         {
1823             uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1824
1825             /* "registration" descriptor : "AC-3" */
1826             dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1827         }
1828
1829         if( p_stream->lang[0] != 0 )
1830         {
1831             uint8_t data[4];
1832
1833             /* I construct the content myself, way faster than looking at
1834              * over complicated/mind broken libdvbpsi way */
1835             data[0] = p_stream->lang[0];
1836             data[1] = p_stream->lang[1];
1837             data[2] = p_stream->lang[2];
1838             data[3] = 0x00; /* audio type: 0x00 undefined */
1839
1840             dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data );
1841         }
1842     }
1843
1844     p_section = dvbpsi_GenPMTSections( &pmt );
1845
1846     p_pmt = WritePSISection( p_mux->p_sout, p_section );
1847
1848     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1849
1850     dvbpsi_DeletePSISections( p_section );
1851     dvbpsi_EmptyPMT( &pmt );
1852 }
1853
1854 #endif
1855