]> git.sesse.net Git - vlc/blob - modules/mux/mpeg/ts.c
* modules/mux/mpeg/ts.c: oops.
[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.26 2003/08/10 14:23:15 gbazin 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 "codecs.h"
36 #include "bits.h"
37 #include "pes.h"
38
39 #if defined MODULE_NAME_IS_mux_ts_dvbpsi
40 #   ifdef HAVE_DVBPSI_DR_H
41 #       include <dvbpsi/dvbpsi.h>
42 #       include <dvbpsi/descriptor.h>
43 #       include <dvbpsi/pat.h>
44 #       include <dvbpsi/pmt.h>
45 #       include <dvbpsi/dr.h>
46 #       include <dvbpsi/psi.h>
47 #   else
48 #       include "dvbpsi.h"
49 #       include "descriptor.h"
50 #       include "tables/pat.h"
51 #       include "tables/pmt.h"
52 #       include "descriptors/dr.h"
53 #       include "psi.h"
54 #   endif
55 #endif
56
57 /*
58  * TODO:
59  *  - check PCR frequency requirement
60  *  - check PAT/PMT  "        "
61  *  - check PCR/PCR "soft"
62  *
63  *  - remove creation of PAT/PMT without dvbpsi
64  *  - ?
65  * FIXME:
66  *  - subtitle support is far from perfect. I expect some subtitles drop
67  *    if they arrive a bit late
68  *    (We cannot rely on the fact that the fifo should be full)
69  */
70 /*****************************************************************************
71  * Module descriptor
72  *****************************************************************************/
73 static int     Open   ( vlc_object_t * );
74 static void    Close  ( vlc_object_t * );
75
76 vlc_module_begin();
77 #if defined MODULE_NAME_IS_mux_ts
78     set_description( _("TS muxer") );
79     set_capability( "sout mux", 100 );
80     add_shortcut( "ts" );
81     add_shortcut( "ts_nodvbpsi" );
82 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
83     set_description( _("TS muxer (libdvbpsi)") );
84     set_capability( "sout mux", 120 );
85     add_shortcut( "ts" );
86     add_shortcut( "ts_dvbpsi" );
87 #endif
88     set_callbacks( Open, Close );
89 vlc_module_end();
90
91 /*****************************************************************************
92  * Exported prototypes
93  *****************************************************************************/
94 static int     Capability(sout_mux_t *, int, void *, void * );
95 static int     AddStream( sout_mux_t *, sout_input_t * );
96 static int     DelStream( sout_mux_t *, sout_input_t * );
97 static int     Mux      ( sout_mux_t * );
98
99 /*****************************************************************************
100  * Local prototypes
101  *****************************************************************************/
102 #define SOUT_BUFFER_FLAGS_PRIVATE_PCR_SOFT  ( 1 << SOUT_BUFFER_FLAGS_PRIVATE_SHIFT )
103 typedef struct
104 {
105     int           i_depth;
106     sout_buffer_t *p_first;
107     sout_buffer_t **pp_last;
108 } sout_buffer_chain_t;
109
110 static inline void BufferChainInit  ( sout_buffer_chain_t *c )
111 {
112     c->i_depth = 0;
113     c->p_first = NULL;
114     c->pp_last = &c->p_first;
115 }
116 static inline void BufferChainAppend( sout_buffer_chain_t *c, sout_buffer_t *b )
117 {
118     *c->pp_last = b;
119     c->i_depth++;
120
121     while( b->p_next )
122     {
123         b = b->p_next;
124         c->i_depth++;
125     }
126     c->pp_last = &b->p_next;
127 }
128 static inline sout_buffer_t *BufferChainGet( sout_buffer_chain_t *c )
129 {
130     sout_buffer_t *b = c->p_first;
131
132     if( b )
133     {
134         c->i_depth--;
135         c->p_first = b->p_next;
136
137         if( c->p_first == NULL )
138         {
139             c->pp_last = &c->p_first;
140         }
141
142         b->p_next = NULL;
143     }
144     return b;
145 }
146
147 typedef struct ts_stream_s
148 {
149     int             i_pid;
150     int             i_stream_type;
151     int             i_stream_id;
152     int             i_continuity_counter;
153
154     /* to be used for carriege of DIV3 */
155     vlc_fourcc_t    i_bih_codec;
156     int             i_bih_width, i_bih_height;
157
158     /* Specific to mpeg4 in mpeg2ts */
159     int             i_es_id;
160
161     int             i_decoder_specific_info;
162     uint8_t         *p_decoder_specific_info;
163
164     /* for TS building */
165     sout_buffer_chain_t chain_ts;
166
167 } ts_stream_t;
168
169 struct sout_mux_sys_t
170 {
171     int             i_pcr_pid;
172     sout_input_t    *p_pcr_input;
173
174     int             i_stream_id_mpga;
175     int             i_stream_id_mpgv;
176     int             i_stream_id_a52;
177
178     int             i_audio_bound;
179     int             i_video_bound;
180
181     int             i_pid_free; // first usable pid
182
183     int             i_pat_version_number;
184     ts_stream_t     pat;
185
186     int             i_pmt_version_number;
187     ts_stream_t     pmt;        // Up to now only one program
188
189     int             i_mpeg4_streams;
190
191     int             i_null_continuity_counter;  /* Needed ? */
192
193     /* for TS building */
194     int64_t             i_bitrate_min;
195     int64_t             i_bitrate_max;
196     int64_t             i_pcr_delay;
197     int64_t             i_pcr_soft_delay;
198
199     mtime_t             i_pcr;  /* last PCR emited (for pcr-soft) */
200     mtime_t             i_dts;
201     mtime_t             i_length;
202     sout_buffer_chain_t chain_ts;
203 };
204
205
206 /* Reserve a pid and return it */
207 static int  AllocatePID( sout_mux_sys_t *p_sys )
208 {
209     return( ++p_sys->i_pid_free );
210 }
211
212 static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
213 static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
214
215 static int  TSFill   ( sout_mux_t *, sout_input_t * );
216 static void PEStoTS  ( sout_instance_t *, sout_buffer_chain_t *, sout_buffer_t *, ts_stream_t *, vlc_bool_t );
217 static void TSSetDate( sout_buffer_chain_t *, mtime_t, mtime_t );
218 static void TSSetConstraints( sout_mux_t*, sout_buffer_chain_t *,
219                               mtime_t i_length, int i_bitrate_min, int i_bitrate_max );
220
221 #if !defined( HAVE_ATOLL )
222 /* Et oui y'a des systemes de MERDE (ex: OS X, Solaris) qui ne l'ont pas :((( */
223 static long long atoll(const char *str)
224 {
225     long long i_value = 0;
226     int sign = 1;
227
228     if( *str == '-' )
229     {
230         sign = -1;
231     }
232
233     while( *str >= '0' && *str <= '9' )
234     {
235         i_value = i_value * 10 + ( *str - '0' );
236     }
237
238     return i_value * sign;
239 }
240 #endif
241
242
243 /*****************************************************************************
244  * Open:
245  *****************************************************************************/
246 static int Open( vlc_object_t *p_this )
247 {
248     sout_mux_t          *p_mux =(sout_mux_t*)p_this;
249     sout_mux_sys_t      *p_sys;
250     char                *val;
251
252     msg_Dbg( p_mux, "Open" );
253
254     p_sys = malloc( sizeof( sout_mux_sys_t ) );
255
256     p_mux->pf_capacity  = Capability;
257     p_mux->pf_addstream = AddStream;
258     p_mux->pf_delstream = DelStream;
259     p_mux->pf_mux       = Mux;
260     p_mux->p_sys        = p_sys;
261     p_mux->i_preheader  = 30; // really enough for a pes header
262
263     srand( (uint32_t)mdate() );
264
265     p_sys->i_stream_id_mpga = 0xc0;
266     p_sys->i_stream_id_a52  = 0x80;
267     p_sys->i_stream_id_mpgv = 0xe0;
268
269     p_sys->i_audio_bound = 0;
270     p_sys->i_video_bound = 0;
271
272     p_sys->i_pat_version_number = rand() % 32;
273     p_sys->pat.i_pid = 0;
274     p_sys->pat.i_continuity_counter = 0;
275
276     p_sys->i_pmt_version_number = rand() % 32;
277     p_sys->pmt.i_pid = 0x42;
278     p_sys->pmt.i_continuity_counter = 0;
279
280     p_sys->i_pid_free = 0x43;
281
282     p_sys->i_pcr_pid = 0x1fff;
283     p_sys->p_pcr_input = NULL;
284
285     p_sys->i_mpeg4_streams = 0;
286
287     p_sys->i_null_continuity_counter = 0;
288
289     /* Allow to create constrained stream */
290     p_sys->i_bitrate_min = 0;
291     p_sys->i_bitrate_max = 0;
292     if( ( val = sout_cfg_find_value( p_mux->p_cfg, "bmin" ) ) )
293     {
294         p_sys->i_bitrate_min = atoll( val );
295     }
296     if( ( val = sout_cfg_find_value( p_mux->p_cfg, "bmax" ) ) )
297     {
298         p_sys->i_bitrate_max = atoll( val );
299     }
300     if( p_sys->i_bitrate_min > 0 && p_sys->i_bitrate_max > 0 &&
301         p_sys->i_bitrate_min > p_sys->i_bitrate_max )
302     {
303         msg_Err( p_mux, "incompatible minimum and maximum bitrate, "
304                  "disabling bitrate control" );
305         p_sys->i_bitrate_min = 0;
306         p_sys->i_bitrate_max = 0;
307     }
308     p_sys->i_pcr_delay = 100000;
309     if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pcr" ) ) )
310     {
311         p_sys->i_pcr_delay = (int64_t)atoi( val ) * 1000;
312         if( p_sys->i_pcr_delay <= 0 )
313         {
314             msg_Err( p_mux,
315                      "invalid pcr delay ("I64Fd"ms) reseting to 100ms",
316                      p_sys->i_pcr_delay / 1000 );
317             p_sys->i_pcr_delay = 100000;
318         }
319     }
320     p_sys->i_pcr_soft_delay = 0;
321     if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pcr-soft" ) ) )
322     {
323         p_sys->i_pcr_soft_delay = (int64_t)atoi( val ) * 1000;
324         if( p_sys->i_pcr_soft_delay <= 0 ||
325             p_sys->i_pcr_soft_delay >= p_sys->i_pcr_delay )
326         {
327             msg_Err( p_mux,
328                      "invalid pcr-soft delay ("I64Fd"ms) disabled",
329                      p_sys->i_pcr_soft_delay / 1000 );
330             p_sys->i_pcr_soft_delay = 0;
331         }
332     }
333
334     msg_Dbg( p_mux, "pcr_delay="I64Fd" pcr_soft_delay="I64Fd,
335              p_sys->i_pcr_delay, p_sys->i_pcr_soft_delay );
336
337     /* for TS génération */
338     p_sys->i_pcr    = 0;
339     p_sys->i_dts    = 0;
340     p_sys->i_length = 0;
341     BufferChainInit( &p_sys->chain_ts );
342     return VLC_SUCCESS;
343 }
344
345 /*****************************************************************************
346  * Close:
347  *****************************************************************************/
348 static void Close( vlc_object_t * p_this )
349 {
350     sout_mux_t          *p_mux = (sout_mux_t*)p_this;
351     sout_mux_sys_t      *p_sys = p_mux->p_sys;
352     sout_buffer_t       *p_data;
353
354     msg_Dbg( p_mux, "Close" );
355
356     /* Empty TS buffer */
357     while( ( p_data = BufferChainGet( &p_sys->chain_ts ) ) )
358     {
359         sout_BufferDelete( p_mux->p_sout, p_data );
360     }
361
362     free( p_sys );
363 }
364
365 /*****************************************************************************
366  * Capability:
367  *****************************************************************************/
368 static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
369 {
370    switch( i_query )
371    {
372         case SOUT_MUX_CAP_GET_ADD_STREAM_ANY_TIME:
373             *(vlc_bool_t*)p_answer = VLC_TRUE;
374             return( SOUT_MUX_CAP_ERR_OK );
375         default:
376             return( SOUT_MUX_CAP_ERR_UNIMPLEMENTED );
377    }
378 }
379
380 /*****************************************************************************
381  * AddStream: called for each stream addition
382  *****************************************************************************/
383 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
384 {
385     sout_mux_sys_t      *p_sys = p_mux->p_sys;
386     ts_stream_t         *p_stream;
387
388     msg_Dbg( p_mux, "adding input codec=%4.4s", (char*)&p_input->p_fmt->i_fourcc );
389
390     p_input->p_sys = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
391
392     /* Init this new stream */
393     p_stream->i_pid = AllocatePID( p_sys );
394     p_stream->i_continuity_counter    = 0;
395     p_stream->i_decoder_specific_info = 0;
396     p_stream->p_decoder_specific_info = NULL;
397
398     /* All others fields depand on codec */
399     switch( p_input->p_fmt->i_cat )
400     {
401         case VIDEO_ES:
402             switch( p_input->p_fmt->i_fourcc )
403             {
404                 case VLC_FOURCC( 'm', 'p','g', 'v' ):
405                     /* TODO: do we need to check MPEG-I/II ? */
406                     p_stream->i_stream_type = 0x02;
407                     p_stream->i_stream_id = p_sys->i_stream_id_mpgv;
408                     p_sys->i_stream_id_mpgv++;
409                     break;
410                 case VLC_FOURCC( 'm', 'p','4', 'v' ):
411                     p_stream->i_stream_type = 0x10;
412                     p_stream->i_stream_id = 0xfa;
413                     p_sys->i_mpeg4_streams++;
414                     p_stream->i_es_id = p_stream->i_pid;
415                     break;
416                 /* XXX dirty dirty but somebody want that : using crapy MS-codec XXX */
417                 /* I didn't want to do that :P */
418                 case VLC_FOURCC( 'H', '2', '6', '3' ):
419                 case VLC_FOURCC( 'I', '2', '6', '3' ):
420                 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
421                 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
422                 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
423                 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
424                 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
425                 case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
426                     p_stream->i_stream_type = 0xa0; // private
427                     p_stream->i_stream_id = 0xa0;   // beurk
428                     p_stream->i_bih_codec  = p_input->p_fmt->i_fourcc;
429                     p_stream->i_bih_width  = p_input->p_fmt->i_width;
430                     p_stream->i_bih_height = p_input->p_fmt->i_height;
431                     break;
432                 default:
433                     free( p_stream );
434                     return VLC_EGENERIC;
435             }
436             p_sys->i_video_bound++;
437             break;
438
439         case AUDIO_ES:
440             switch( p_input->p_fmt->i_fourcc )
441             {
442                 case VLC_FOURCC( 'm', 'p','g', 'a' ):
443                     p_stream->i_stream_type = p_input->p_fmt->i_sample_rate >= 32000 ? 0x03 : 0x04;
444                     p_stream->i_stream_id = p_sys->i_stream_id_mpga;
445                     p_sys->i_stream_id_mpga++;
446                     break;
447                 case VLC_FOURCC( 'a', '5','2', ' ' ):
448                     p_stream->i_stream_type = 0x81;
449                     p_stream->i_stream_id = p_sys->i_stream_id_a52;
450                     p_sys->i_stream_id_a52++;
451                     break;
452                 case VLC_FOURCC( 'm', 'p','4', 'a' ):
453                     p_stream->i_stream_type = 0x11;
454                     p_stream->i_stream_id = 0xfa;
455                     p_sys->i_mpeg4_streams++;
456                     p_stream->i_es_id = p_stream->i_pid;
457                     break;
458                 default:
459                     free( p_stream );
460                     return VLC_EGENERIC;
461             }
462             p_sys->i_audio_bound++;
463             break;
464
465         case SPU_ES:
466             switch( p_input->p_fmt->i_fourcc )
467             {
468                 case VLC_FOURCC( 's', 'p','u', ' ' ):
469                     p_stream->i_stream_type = 0x82;
470                     p_stream->i_stream_id = 0x82;
471                     break;
472                 default:
473                     free( p_stream );
474                     return VLC_EGENERIC;
475             }
476             break;
477
478         default:
479             free( p_stream );
480             return VLC_EGENERIC;
481     }
482
483     /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
484     p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra_data;
485     if( p_stream->i_decoder_specific_info > 0 )
486     {
487         p_stream->p_decoder_specific_info =
488             malloc( p_stream->i_decoder_specific_info );
489         memcpy( p_stream->p_decoder_specific_info,
490                 p_input->p_fmt->p_extra_data,
491                 p_input->p_fmt->i_extra_data );
492     }
493     /* Init chain for TS building */
494     BufferChainInit( &p_stream->chain_ts );
495
496     /* We only change PMT version (PAT isn't changed) */
497     p_sys->i_pmt_version_number = ( p_sys->i_pmt_version_number + 1 )%32;
498
499     /* Update pcr_pid */
500     if( p_input->p_fmt->i_cat != SPU_ES &&
501         ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) )
502     {
503         sout_buffer_t *p_data;
504
505         if( p_sys->p_pcr_input )
506         {
507             /* There was already a PCR stream, so clean context */
508             ts_stream_t   *p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
509
510             while( ( p_data = BufferChainGet( &p_pcr_stream->chain_ts ) ) )
511             {
512                 sout_BufferDelete( p_mux->p_sout, p_data );
513             }
514         }
515         p_sys->i_pcr_pid   = p_stream->i_pid;
516         p_sys->p_pcr_input = p_input;
517
518         /* Empty TS buffer (avoid broken data/problems with pcr stream changement ) */
519         while( ( p_data = BufferChainGet( &p_sys->chain_ts ) ) )
520         {
521             sout_BufferDelete( p_mux->p_sout, p_data );
522         }
523     }
524
525     return VLC_SUCCESS;
526 }
527
528 /*****************************************************************************
529  * DelStream: called before a stream deletion
530  *****************************************************************************/
531 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
532 {
533     sout_mux_sys_t  *p_sys = p_mux->p_sys;
534     ts_stream_t     *p_stream;
535     sout_buffer_t   *p_data;
536
537     msg_Dbg( p_mux, "removing input" );
538     p_stream = (ts_stream_t*)p_input->p_sys;
539
540     if( p_sys->i_pcr_pid == p_stream->i_pid )
541     {
542         int i;
543
544         /* Find a new pcr stream (Prefer Video Stream) */
545         p_sys->i_pcr_pid = 0x1fff;
546         p_sys->p_pcr_input = NULL;
547         for( i = 0; i < p_mux->i_nb_inputs; i++ )
548         {
549             if( p_mux->pp_inputs[i] == p_input )
550             {
551                 continue;
552             }
553
554             if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
555             {
556                 p_sys->i_pcr_pid  =
557                     ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
558                 p_sys->p_pcr_input= p_mux->pp_inputs[i];
559                 break;
560             }
561             else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
562                      p_sys->i_pcr_pid == 0x1fff )
563             {
564                 p_sys->i_pcr_pid  =
565                     ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
566                 p_sys->p_pcr_input= p_mux->pp_inputs[i];
567             }
568         }
569         if( p_sys->p_pcr_input )
570         {
571             /* Empty TS buffer */
572             while( ( p_data = BufferChainGet( &((ts_stream_t*)p_sys->p_pcr_input->p_sys)->chain_ts ) ) )
573             {
574                 sout_BufferDelete( p_mux->p_sout, p_data );
575             }
576         }
577     }
578
579     /* Empty all data in chain_ts */
580     while( ( p_data = BufferChainGet( &p_stream->chain_ts ) ) )
581     {
582         sout_BufferDelete( p_mux->p_sout, p_data );
583     }
584     if( p_stream->p_decoder_specific_info )
585     {
586         free( p_stream->p_decoder_specific_info );
587     }
588     if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
589     {
590         p_sys->i_mpeg4_streams--;
591     }
592     free( p_stream );
593
594     /* We only change PMT version (PAT isn't changed) */
595     p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
596
597     /*Empty TS buffer (avoid broken data/problems with pcr stream changement) */
598     while( ( p_data = BufferChainGet( &p_sys->chain_ts ) ) )
599     {
600         sout_BufferDelete( p_mux->p_sout, p_data );
601     }
602
603     return VLC_SUCCESS;
604 }
605
606 /*****************************************************************************
607  * Mux: Call each time there is new data for at least one stream
608  *****************************************************************************
609  *
610  *****************************************************************************/
611 static int Mux( sout_mux_t *p_mux )
612 {
613     sout_mux_sys_t  *p_sys = p_mux->p_sys;
614
615     sout_input_t    *p_pcr_input = p_sys->p_pcr_input;
616     ts_stream_t     *p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
617
618     if( p_sys->i_pcr_pid == 0x1fff )
619     {
620         msg_Dbg( p_mux, "waiting PCR streams" );
621         msleep( 1000 );
622         return VLC_SUCCESS;
623     }
624
625     for( ;; )
626     {
627         ts_stream_t   *p_stream = NULL;
628         sout_buffer_t *p_data;
629
630         int     i_stream, i;
631         mtime_t i_dts;
632
633         /* fill ts packets for pcr XXX before GetPAT/GetPMT */
634         if( p_pcr_stream->chain_ts.p_first == NULL && TSFill( p_mux, p_pcr_input ) )
635         {
636             /* We need more data */
637             return VLC_SUCCESS;
638         }
639
640         if( p_sys->chain_ts.p_first == NULL  )
641         {
642             /* Every pcr packet send PAT/PMT */
643             GetPAT( p_mux, &p_sys->chain_ts);
644             GetPMT( p_mux, &p_sys->chain_ts );
645         }
646
647         /* search stream with lowest dts */
648         for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
649         {
650             p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
651
652             if( p_stream->chain_ts.p_first == NULL )
653             {
654                 if( TSFill( p_mux, p_mux->pp_inputs[i] ) )
655                 {
656                     /* We need more data */
657                     return VLC_SUCCESS;
658                 }
659                 if( p_stream->chain_ts.p_first == NULL )
660                 {
661                     continue; /* SPU_ES */
662                 }
663             }
664
665             if( i_stream == -1 ||
666                 p_stream->chain_ts.p_first->i_dts < i_dts )
667             {
668                 i_stream = i;
669                 i_dts = p_stream->chain_ts.p_first->i_dts;
670             }
671         }
672
673         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
674
675         p_data = BufferChainGet( &p_stream->chain_ts );
676         BufferChainAppend( &p_sys->chain_ts, p_data );
677
678         if( p_stream->i_pid == p_pcr_stream->i_pid && p_stream->chain_ts.p_first == NULL )
679         {
680             sout_buffer_t *p_ts = p_sys->chain_ts.p_first;
681
682             /* We have consume all TS packets from the PCR stream */
683
684             if( p_sys->i_length > p_sys->i_pcr_delay )
685             {
686                 /* Send TS data if last PCR was i_pcr_delay ago */
687
688                 if( p_sys->i_bitrate_min > 0 ||
689                     p_sys->i_bitrate_max > 0 )
690                 {
691                     TSSetConstraints( p_mux, &p_sys->chain_ts, p_sys->i_length,
692                                       p_sys->i_bitrate_min, p_sys->i_bitrate_max );
693                 }
694
695                 /* Send all data */
696                 TSSetDate( &p_sys->chain_ts,
697                            p_sys->i_dts + 3  * p_sys->i_pcr_delay / 2,    /* latency is equal to i_pcr_delay, 3/2 is for security */
698                            p_sys->i_length );
699                 sout_AccessOutWrite( p_mux->p_access, p_ts );
700
701                 /* Reset the ts chain */
702                 BufferChainInit( &p_sys->chain_ts );
703
704                 p_sys->i_length = 0;
705             }
706         }
707     }
708
709     return VLC_SUCCESS;
710 }
711
712
713
714 /*****************************************************************************
715  *
716  *
717  *****************************************************************************/
718 static int TSFill( sout_mux_t *p_mux, sout_input_t *p_input )
719 {
720     sout_mux_sys_t  *p_sys = p_mux->p_sys;
721
722     ts_stream_t     *p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
723     ts_stream_t     *p_stream = (ts_stream_t*)p_input->p_sys;
724     mtime_t         i_dts, i_length;
725     sout_buffer_t   *p_data;
726     vlc_bool_t      b_pcr = VLC_FALSE;
727     vlc_bool_t      b_pcr_soft = VLC_FALSE;
728
729
730     for( ;; )
731     {
732         if( p_input->p_fifo->i_depth <= 0 )
733         {
734             if( p_input->p_fmt->i_cat == AUDIO_ES ||
735                 p_input->p_fmt->i_cat == VIDEO_ES )
736             {
737                 /* We need more data */
738                 return VLC_EGENERIC;
739             }
740             else
741             {
742                 return VLC_SUCCESS;
743             }
744         }
745         p_data = sout_FifoGet( p_input->p_fifo );
746         i_dts    = p_data->i_dts;
747         i_length = p_data->i_length;
748
749         if(  p_stream->i_pid == p_pcr_stream->i_pid &&
750              p_stream->chain_ts.p_first == NULL )
751         {
752             p_sys->i_length+= i_length;
753             if( p_sys->chain_ts.p_first == NULL )
754             {
755                 p_sys->i_dts    = i_dts;
756                 p_sys->i_pcr    = i_dts;
757                 b_pcr = VLC_TRUE;
758             }
759             else if( p_sys->i_pcr_soft_delay > 0 &&
760                      p_sys->i_pcr + p_sys->i_pcr_soft_delay < i_dts )
761             {
762                 p_sys->i_pcr    = i_dts;
763                 b_pcr = VLC_TRUE;
764                 b_pcr_soft = VLC_TRUE;
765             }
766             break;
767         }
768
769         if( ( p_sys->i_dts + p_sys->i_length ) - i_dts > 2000000 ||
770             ( p_sys->i_dts + p_sys->i_length ) - i_dts < -2000000 )
771         {
772             msg_Err( p_mux, "| buffer_dts - pcr_pts | > 2s ("I64Fd") empting "
773                      "pcr TS buffers", p_sys->i_dts + p_sys->i_length - i_dts);
774
775             sout_BufferDelete( p_mux->p_sout, p_data );
776
777             while( ( p_data = BufferChainGet( &p_pcr_stream->chain_ts ) ) )
778             {
779                 sout_BufferDelete( p_mux->p_sout, p_data );
780             }
781             while( ( p_data = BufferChainGet( &p_sys->chain_ts ) ) )
782             {
783                 sout_BufferDelete( p_mux->p_sout, p_data );
784             }
785             return VLC_EGENERIC;
786         }
787
788         if( i_dts >= p_sys->i_dts )
789         {
790             break;
791         }
792
793         msg_Dbg( p_mux, "dropping buffer size=%d dts="I64Fd" pcr_dts="I64Fd
794                  " diff="I64Fd, p_data->i_size, i_dts, p_sys->i_dts,
795                  p_sys->i_dts + p_sys->i_length - i_dts );
796         sout_BufferDelete( p_mux->p_sout, p_data );
797     }
798
799     E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1);
800
801     BufferChainInit( &p_stream->chain_ts );
802     PEStoTS( p_mux->p_sout, &p_stream->chain_ts, p_data, p_stream, b_pcr );
803
804     TSSetDate( &p_stream->chain_ts, i_dts, i_length );
805
806     if( b_pcr_soft && p_stream->chain_ts.p_first )
807     {
808         p_stream->chain_ts.p_first->i_flags=SOUT_BUFFER_FLAGS_PRIVATE_PCR_SOFT;
809     }
810
811     return VLC_SUCCESS;
812 }
813
814 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 )
815 {
816     sout_mux_sys_t  *p_sys = p_mux->p_sys;
817     sout_buffer_chain_t s = *c;
818
819     int i_packets = 0;
820     int i_packets_min = 0;
821     int i_packets_max = 0;
822
823     if( i_length <= 0 )
824     {
825         return;
826     }
827
828     i_packets     = c->i_depth;
829     i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000  + 187 ) / 188;
830     i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000  + 187 ) / 188;
831
832     if( i_packets < i_packets_min && i_packets_min > 0 )
833     {
834         sout_buffer_t *p_pk;
835         int i_div = ( i_packets_min - i_packets ) / i_packets;
836         int i_mod = ( i_packets_min - i_packets ) % i_packets;
837         int i_rest = 0;
838
839         /* We need to pad with null packets (pid=0x1fff)
840          * We try to melt null packets with true packets */
841         msg_Dbg( p_mux,
842                  "packets=%d but min=%d -> adding %d packets of padding",
843                  i_packets, i_packets_min, i_packets_min - i_packets );
844
845         BufferChainInit( c );
846         while( ( p_pk = BufferChainGet( &s ) ) )
847         {
848             int i, i_null;
849
850             BufferChainAppend( c, p_pk );
851
852             i_null = i_div + ( i_rest + i_mod ) / i_packets;
853
854             for( i = 0; i < i_null; i++ )
855             {
856                 sout_buffer_t *p_null;
857
858                 p_null = sout_BufferNew( p_mux->p_sout, 188 );
859                 p_null->p_buffer[0] = 0x47;
860                 p_null->p_buffer[1] = 0x1f;
861                 p_null->p_buffer[2] = 0xff;
862                 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
863                 memset( &p_null->p_buffer[4], 0, 184 );
864                 p_sys->i_null_continuity_counter =
865                     ( p_sys->i_null_continuity_counter + 1 ) % 16;
866
867                 BufferChainAppend( c, p_null );
868             }
869
870             i_rest = ( i_rest + i_mod ) % i_packets;
871         }
872     }
873     else if( i_packets > i_packets_max && i_packets_max > 0 )
874     {
875         sout_buffer_t *p_pk;
876         int           i;
877
878         /* Arg, we need to drop packets, I don't do something clever (like
879          * dropping complete pid, b frames, ... ), I just get the right amount
880          * of packets and discard the others */
881         msg_Warn( p_mux,
882                   "packets=%d but max=%d -> removing %d packets -> stream broken",
883                   i_packets, i_packets_max, i_packets - i_packets_max );
884
885         BufferChainInit( c );
886         for( i = 0; i < i_packets_max; i++ )
887         {
888             BufferChainAppend( c, BufferChainGet( &s ) );
889         }
890
891         while( ( p_pk = BufferChainGet( &s ) ) )
892         {
893             sout_BufferDelete( p_mux->p_sout, p_pk );
894         }
895     }
896 }
897
898 static void TSSetDate( sout_buffer_chain_t *c, mtime_t i_dts, mtime_t i_length )
899 {
900     sout_buffer_t *p_ts;
901     mtime_t       i_delta = i_length / c->i_depth;
902     int           i_packet = 0;
903
904     for( p_ts = c->p_first; p_ts != NULL; p_ts = p_ts->p_next )
905     {
906         p_ts->i_dts    = i_dts + i_packet * i_length / c->i_depth;  /* avoid rounding error */
907         p_ts->i_length = i_delta;
908
909         if( p_ts->i_flags&SOUT_BUFFER_FLAGS_PRIVATE_PCR_SOFT )
910         {
911             mtime_t i_pcr = 9 * p_ts->i_dts / 100;
912
913             p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
914             p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
915             p_ts->p_buffer[8] = ( i_pcr >> 9  )&0xff;
916             p_ts->p_buffer[9] = ( i_pcr >> 1  )&0xff;
917             p_ts->p_buffer[10]= ( i_pcr << 7  )&0x80;
918         }
919
920         i_packet++;
921     }
922 }
923
924 static void PEStoTS( sout_instance_t *p_sout,
925                      sout_buffer_chain_t *c, sout_buffer_t *p_pes,
926                      ts_stream_t *p_stream,
927                      vlc_bool_t b_pcr )
928 {
929     uint8_t *p_data;
930     int     i_size;
931     int     b_new_pes;
932
933     /* get PES total size */
934     i_size = p_pes->i_size;
935     p_data = p_pes->p_buffer;
936
937     /* Set pcr only with valid DTS */
938     if( p_pes->i_dts <= 0 )
939     {
940         b_pcr = VLC_FALSE;
941     }
942
943     b_new_pes = VLC_TRUE;
944
945     for( ;; )
946     {
947         int           b_adaptation_field;
948         int           i_payload;
949         int           i_copy;
950         sout_buffer_t *p_ts;
951
952         p_ts = sout_BufferNew( p_sout, 188 );
953         /* write header
954          * 8b   0x47    sync byte
955          * 1b           transport_error_indicator
956          * 1b           payload_unit_start
957          * 1b           transport_priority
958          * 13b          pid
959          * 2b           transport_scrambling_control
960          * 2b           if adaptation_field 0x03 else 0x01
961          * 4b           continuity_counter
962          */
963
964         i_payload = 184 - ( b_pcr ? 8 : 0 );
965         i_copy    = __MIN( i_size, i_payload );
966         b_adaptation_field = (b_pcr||i_size<i_payload) ? VLC_TRUE : VLC_FALSE;
967
968         p_ts->p_buffer[0] = 0x47;
969         p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
970                             ( ( p_stream->i_pid >> 8 )&0x1f );
971         p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
972         p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
973                             p_stream->i_continuity_counter;
974
975         b_new_pes = VLC_FALSE;
976         p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
977
978         if( b_adaptation_field )
979         {
980             int i;
981
982             if( b_pcr )
983             {
984                 mtime_t i_pcr = p_pes->i_dts * 9 / 100;
985                 int     i_stuffing = i_payload - i_copy;
986
987                 p_ts->p_buffer[4] = 7 + i_stuffing;
988                 p_ts->p_buffer[5] = 0x10;   /* flags */
989                 p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
990                 p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
991                 p_ts->p_buffer[8] = ( i_pcr >> 9  )&0xff;
992                 p_ts->p_buffer[9] = ( i_pcr >> 1  )&0xff;
993                 p_ts->p_buffer[10]= ( i_pcr << 7  )&0x80;
994                 p_ts->p_buffer[11]= 0;
995
996                 b_pcr = VLC_FALSE;
997                 for( i = 12; i < 12 + i_stuffing; i++ )
998                 {
999                     p_ts->p_buffer[i] = 0xff;
1000                 }
1001             }
1002             else
1003             {
1004                 int i_stuffing = i_payload - i_copy;
1005
1006                 p_ts->p_buffer[4] = i_stuffing - 1;
1007                 if( i_stuffing > 1 )
1008                 {
1009                     p_ts->p_buffer[5] = 0x00;
1010                     for( i = 6; i < 6 + i_stuffing - 2; i++ )
1011                     {
1012                         p_ts->p_buffer[i] = 0xff;
1013                     }
1014                 }
1015             }
1016         }
1017         /* copy payload */
1018         memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1019         p_data += i_copy;
1020         i_size -= i_copy;
1021
1022         BufferChainAppend( c, p_ts );
1023
1024         if( i_size <= 0 )
1025         {
1026             sout_buffer_t *p_next = p_pes->p_next;
1027
1028             p_pes->p_next = NULL;
1029             sout_BufferDelete( p_sout, p_pes );
1030             if( p_next == NULL )
1031             {
1032                 break;
1033             }
1034             b_new_pes = VLC_TRUE;
1035             p_pes = p_next;
1036             i_size = p_pes->i_size;
1037             p_data = p_pes->p_buffer;
1038         }
1039     }
1040
1041     return;
1042 }
1043
1044 #if defined MODULE_NAME_IS_mux_ts
1045 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1046 {
1047     static uint32_t CRC32[256] =
1048     {
1049         0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1050         0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1051         0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1052         0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1053         0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1054         0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1055         0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1056         0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1057         0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1058         0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1059         0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1060         0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1061         0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1062         0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1063         0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1064         0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1065         0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1066         0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1067         0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1068         0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1069         0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1070         0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1071         0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1072         0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1073         0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1074         0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1075         0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1076         0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1077         0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1078         0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1079         0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1080         0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1081         0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1082         0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1083         0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1084         0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1085         0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1086         0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1087         0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1088         0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1089         0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1090         0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1091         0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1092         0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1093         0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1094         0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1095         0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1096         0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1097         0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1098         0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1099         0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1100         0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1101         0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1102         0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1103         0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1104         0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1105         0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1106         0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1107         0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1108         0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1109         0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1110         0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1111         0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1112         0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1113     };
1114
1115     uint32_t i_crc = 0xffffffff;
1116
1117     /* Calculate the CRC */
1118     while( i_count > 0 )
1119     {
1120         i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1121         p_begin++;
1122         i_count--;
1123     }
1124
1125     return( i_crc );
1126 }
1127
1128 static void GetPAT( sout_mux_t *p_mux,
1129                     sout_buffer_chain_t *c )
1130 {
1131     sout_mux_sys_t      *p_sys = p_mux->p_sys;
1132     sout_buffer_t       *p_pat;
1133     bits_buffer_t bits;
1134
1135     p_pat = sout_BufferNew( p_mux->p_sout, 1024 );
1136
1137     p_pat->i_pts = 0;
1138     p_pat->i_dts = 0;
1139     p_pat->i_length = 0;
1140
1141     bits_initwrite( &bits, 1024, p_pat->p_buffer );
1142
1143     bits_write( &bits, 8, 0 );      // pointer
1144     bits_write( &bits, 8, 0x00 );   // table id
1145     bits_write( &bits, 1,  1 );     // section_syntax_indicator
1146     bits_write( &bits, 1,  0 );     // 0
1147     bits_write( &bits, 2,  0x03 );     // reserved FIXME
1148     bits_write( &bits, 12, 13 );    // XXX for one program only XXX 
1149     bits_write( &bits, 16, 0x01 );  // FIXME stream id
1150     bits_write( &bits, 2,  0x03 );     //  FIXME
1151     bits_write( &bits, 5,  p_sys->i_pat_version_number );
1152     bits_write( &bits, 1,  1 );     // current_next_indicator
1153     bits_write( &bits, 8,  0 );     // section number
1154     bits_write( &bits, 8,  0 );     // last section number
1155
1156     bits_write( &bits, 16, 1 );     // program number
1157     bits_write( &bits,  3, 0x07 );     // reserved
1158     bits_write( &bits, 13, p_sys->pmt.i_pid );  // program map pid
1159
1160     bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1161
1162     p_pat->i_size = bits.i_data;
1163
1164     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat, VLC_FALSE );
1165 }
1166
1167 static void GetPMT( sout_mux_t *p_mux,
1168                     sout_buffer_chain_t *c )
1169 {
1170     sout_mux_sys_t      *p_sys = p_mux->p_sys;
1171     sout_buffer_t       *p_pmt;
1172     bits_buffer_t bits;
1173     int           i_stream;
1174
1175     p_pmt = sout_BufferNew( p_mux->p_sout, 1024 );
1176
1177     p_pmt->i_pts = 0;
1178     p_pmt->i_dts = 0;
1179     p_pmt->i_length = 0;
1180
1181     bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1182
1183     bits_write( &bits, 8, 0 );      // pointer
1184     bits_write( &bits, 8, 0x02 );   // table id
1185     bits_write( &bits, 1,  1 );     // section_syntax_indicator
1186     bits_write( &bits, 1,  0 );     // 0
1187     bits_write( &bits, 2,  0 );     // reserved FIXME
1188     bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1189     bits_write( &bits, 16, 1 );     // FIXME program number
1190     bits_write( &bits, 2,  0 );     //  FIXME
1191     bits_write( &bits, 5,  p_sys->i_pmt_version_number );
1192     bits_write( &bits, 1,  1 );     // current_next_indicator
1193     bits_write( &bits, 8,  0 );     // section number
1194     bits_write( &bits, 8,  0 );     // last section number
1195
1196     bits_write( &bits,  3, 0 );     // reserved
1197
1198     bits_write( &bits, 13, p_sys->i_pcr_pid );     //  FIXME FXIME PCR_PID FIXME
1199     bits_write( &bits,  4, 0 );     // reserved FIXME
1200
1201     bits_write( &bits, 12, 0 );    // program info len FIXME
1202
1203     for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1204     {
1205         ts_stream_t *p_stream;
1206
1207         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1208
1209         bits_write( &bits,  8, p_stream->i_stream_type ); // stream_type
1210         bits_write( &bits,  3, 0 );                 // reserved
1211         bits_write( &bits, 13, p_stream->i_pid );   // es pid
1212         bits_write( &bits,  4, 0 );                 //reserved
1213         bits_write( &bits, 12, 0 );                 // es info len FIXME
1214     }
1215
1216     bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1217
1218     p_pmt->i_size = bits.i_data;
1219
1220     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt, VLC_FALSE );
1221 }
1222 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1223
1224 static sout_buffer_t *WritePSISection( sout_instance_t *p_sout,
1225                                        dvbpsi_psi_section_t* p_section )
1226 {
1227     sout_buffer_t   *p_psi, *p_first = NULL;
1228
1229
1230     while( p_section )
1231     {
1232         int             i_size;
1233
1234         i_size =  (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1235                   ( p_section->b_syntax_indicator ? 4 : 0 );
1236
1237         p_psi = sout_BufferNew( p_sout, i_size + 1 );
1238         p_psi->i_pts = 0;
1239         p_psi->i_dts = 0;
1240         p_psi->i_length = 0;
1241         p_psi->i_size = i_size + 1;
1242
1243         p_psi->p_buffer[0] = 0; // pointer
1244         memcpy( p_psi->p_buffer + 1,
1245                 p_section->p_data,
1246                 i_size );
1247
1248         sout_BufferChain( &p_first, p_psi );
1249
1250         p_section = p_section->p_next;
1251     }
1252
1253     return( p_first );
1254 }
1255
1256 static void GetPAT( sout_mux_t *p_mux,
1257                     sout_buffer_chain_t *c )
1258 {
1259     sout_mux_sys_t       *p_sys = p_mux->p_sys;
1260     sout_buffer_t        *p_pat;
1261     dvbpsi_pat_t         pat;
1262     dvbpsi_psi_section_t *p_section;
1263
1264     dvbpsi_InitPAT( &pat,
1265                     0x01,    // i_ts_id
1266                     p_sys->i_pat_version_number,
1267                     1 );      // b_current_next
1268     /* add all program (only one) */
1269     dvbpsi_PATAddProgram( &pat,
1270                           1,                    // i_number
1271                           p_sys->pmt.i_pid );   // i_pid
1272
1273     p_section = dvbpsi_GenPATSections( &pat,
1274                                        0 );     // max program per section
1275
1276     p_pat = WritePSISection( p_mux->p_sout, p_section );
1277
1278     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat, VLC_FALSE );
1279
1280     dvbpsi_DeletePSISections( p_section );
1281     dvbpsi_EmptyPAT( &pat );
1282 }
1283
1284 static uint32_t GetDescriptorLength24b( int i_length )
1285 {
1286     uint32_t    i_l1, i_l2, i_l3;
1287
1288     i_l1 = i_length&0x7f;
1289     i_l2 = ( i_length >> 7 )&0x7f;
1290     i_l3 = ( i_length >> 14 )&0x7f;
1291
1292     return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1293 }
1294
1295 static void GetPMT( sout_mux_t *p_mux,
1296                     sout_buffer_chain_t *c )
1297 {
1298     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1299     sout_buffer_t   *p_pmt;
1300
1301     dvbpsi_pmt_t        pmt;
1302     dvbpsi_pmt_es_t     *p_es;
1303     dvbpsi_psi_section_t *p_section;
1304
1305     int                 i_stream;
1306
1307     dvbpsi_InitPMT( &pmt,
1308                     0x01,   // program number
1309                     p_sys->i_pmt_version_number,
1310                     1,      // b_current_next
1311                     p_sys->i_pcr_pid );
1312
1313     if( p_sys->i_mpeg4_streams > 0 )
1314     {
1315         uint8_t iod[4096];
1316         bits_buffer_t bits;
1317         bits_buffer_t bits_fix_IOD;
1318
1319         bits_initwrite( &bits, 4096, iod );
1320         // IOD_label
1321         bits_write( &bits, 8,   0x01 );
1322         // InitialObjectDescriptor
1323         bits_align( &bits );
1324         bits_write( &bits, 8,   0x02 );     // tag
1325         bits_fix_IOD = bits;    // save states to fix length later
1326         bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1327         bits_write( &bits, 10,  0x01 );     // ObjectDescriptorID
1328         bits_write( &bits, 1,   0x00 );     // URL Flag
1329         bits_write( &bits, 1,   0x00 );     // includeInlineProfileLevelFlag
1330         bits_write( &bits, 4,   0x0f );     // reserved
1331         bits_write( &bits, 8,   0xff );     // ODProfile (no ODcapability )
1332         bits_write( &bits, 8,   0xff );     // sceneProfile
1333         bits_write( &bits, 8,   0xfe );     // audioProfile (unspecified)
1334         bits_write( &bits, 8,   0xfe );     // visualProfile( // )
1335         bits_write( &bits, 8,   0xff );     // graphicProfile (no )
1336         for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1337         {
1338             ts_stream_t *p_stream;
1339             p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1340
1341             if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1342             {
1343                 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1344                 /* ES descriptor */
1345                 bits_align( &bits );
1346                 bits_write( &bits, 8,   0x03 );     // ES_DescrTag
1347                 bits_fix_ESDescr = bits;
1348                 bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) ); // variable size
1349                 bits_write( &bits, 16,  p_stream->i_es_id );
1350                 bits_write( &bits, 1,   0x00 );     // streamDependency
1351                 bits_write( &bits, 1,   0x00 );     // URL Flag
1352                 bits_write( &bits, 1,   0x00 );     // OCRStreamFlag
1353                 bits_write( &bits, 5,   0x1f );     // streamPriority
1354
1355                     // DecoderConfigDesciptor
1356                 bits_align( &bits );
1357                 bits_write( &bits, 8,   0x04 ); // DecoderConfigDescrTag
1358                 bits_fix_Decoder = bits;
1359                 bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) );
1360                 if( p_stream->i_stream_type == 0x10 )
1361                 {
1362                     bits_write( &bits, 8, 0x20 );   // Visual 14496-2
1363                     bits_write( &bits, 6, 0x04 );   // VisualStream
1364                 }
1365                 else if( p_stream->i_stream_type == 0x11 )
1366                 {
1367                     bits_write( &bits, 8, 0x40 );   // Audio 14496-3
1368                     bits_write( &bits, 6, 0x05 );   // AudioStream
1369                 }
1370                 else
1371                 {
1372                     bits_write( &bits, 8, 0x00 );
1373                     bits_write( &bits, 6, 0x00 );
1374
1375                     msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1376                 }
1377                 bits_write( &bits, 1,   0x00 );     // UpStream
1378                 bits_write( &bits, 1,   0x01 );     // reserved
1379                 bits_write( &bits, 24,  1024 * 1024 );  // bufferSizeDB
1380                 bits_write( &bits, 32,  0x7fffffff );   // maxBitrate
1381                 bits_write( &bits, 32,  0 );            // avgBitrate
1382
1383                 if( p_stream->i_decoder_specific_info > 0 )
1384                 {
1385                     int i;
1386                     // DecoderSpecificInfo
1387                     bits_align( &bits );
1388                     bits_write( &bits, 8,   0x05 ); // tag
1389                     bits_write( &bits, 24,
1390                                 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1391                     for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1392                     {
1393                         bits_write( &bits, 8,   ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1394                     }
1395                 }
1396                 /* fix Decoder length */
1397                 bits_write( &bits_fix_Decoder, 24,
1398                             GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1399
1400                 /* SLConfigDescriptor : predifined (0x01) */
1401                 bits_align( &bits );
1402                 bits_write( &bits, 8,   0x06 ); // tag
1403                 bits_write( &bits, 24,  GetDescriptorLength24b( 8 ) );
1404                 bits_write( &bits, 8,   0x01 ); // predefined
1405                 bits_write( &bits, 1,   0 );   // durationFlag
1406                 bits_write( &bits, 32,  0 );   // OCRResolution
1407                 bits_write( &bits, 8,   0 );   // OCRLength
1408                 bits_write( &bits, 8,   0 );   // InstantBitrateLength
1409                 bits_align( &bits );
1410
1411                 /* fix ESDescr length */
1412                 bits_write( &bits_fix_ESDescr, 24,
1413                             GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1414             }
1415         }
1416         bits_align( &bits );
1417         /* fix IOD length */
1418         bits_write( &bits_fix_IOD, 24,
1419                     GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1420         dvbpsi_PMTAddDescriptor( &pmt,
1421                                  0x1d,
1422                                  bits.i_data,
1423                                  bits.p_data );
1424     }
1425
1426     for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1427     {
1428         ts_stream_t *p_stream;
1429
1430         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1431
1432         p_es = dvbpsi_PMTAddES( &pmt,
1433                                 p_stream->i_stream_type,
1434                                 p_stream->i_pid );
1435         if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1436         {
1437             uint8_t     data[512];
1438             bits_buffer_t bits;
1439
1440             /* SL descriptor */
1441             bits_initwrite( &bits, 512, data );
1442             bits_write( &bits, 16, p_stream->i_es_id );
1443
1444             dvbpsi_PMTESAddDescriptor( p_es,
1445                                        0x1f,
1446                                        bits.i_data,
1447                                        bits.p_data );
1448         }
1449         else if( p_stream->i_stream_id == 0xa0 )
1450         {
1451             uint8_t     data[512];
1452             uint8_t     fcc[4];
1453             bits_buffer_t bits;
1454
1455             memcpy( fcc, &p_stream->i_bih_codec, 4 );
1456
1457             /* private DIV3 descripor */
1458             bits_initwrite( &bits, 512, data );
1459             bits_write( &bits, 8,  fcc[0]);
1460             bits_write( &bits, 8,  fcc[1]);
1461             bits_write( &bits, 8,  fcc[2]);
1462             bits_write( &bits, 8,  fcc[3]);
1463             bits_write( &bits, 16, p_stream->i_bih_width );
1464             bits_write( &bits, 16, p_stream->i_bih_height );
1465             bits_write( &bits, 16, p_stream->i_decoder_specific_info );
1466             if( p_stream->i_decoder_specific_info > 0 )
1467             {
1468                 int i;
1469                 for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1470                 {
1471                     bits_write( &bits, 8, p_stream->p_decoder_specific_info[i] );
1472                 }
1473             }
1474             dvbpsi_PMTESAddDescriptor( p_es,
1475                                        0xa0,    // private
1476                                        bits.i_data,
1477                                        bits.p_data );
1478         }
1479     }
1480
1481     p_section = dvbpsi_GenPMTSections( &pmt );
1482
1483     p_pmt = WritePSISection( p_mux->p_sout, p_section );
1484
1485     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt, VLC_FALSE );
1486
1487     dvbpsi_DeletePSISections( p_section );
1488     dvbpsi_EmptyPMT( &pmt );
1489 }
1490
1491 #endif
1492