]> git.sesse.net Git - vlc/blob - modules/mux/mpeg/ts.c
* modules/demux/mkv.cpp, modules/mux/avi.c, modules/mux/mpeg/ts.c, modules/packetizer...
[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.25 2003/08/10 14:21:16 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="I64d" 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         sout_BufferDelete( p_mux->p_sout, p_data );
796     }
797
798     E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1);
799
800     BufferChainInit( &p_stream->chain_ts );
801     PEStoTS( p_mux->p_sout, &p_stream->chain_ts, p_data, p_stream, b_pcr );
802
803     TSSetDate( &p_stream->chain_ts, i_dts, i_length );
804
805     if( b_pcr_soft && p_stream->chain_ts.p_first )
806     {
807         p_stream->chain_ts.p_first->i_flags=SOUT_BUFFER_FLAGS_PRIVATE_PCR_SOFT;
808     }
809
810     return VLC_SUCCESS;
811 }
812
813 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 )
814 {
815     sout_mux_sys_t  *p_sys = p_mux->p_sys;
816     sout_buffer_chain_t s = *c;
817
818     int i_packets = 0;
819     int i_packets_min = 0;
820     int i_packets_max = 0;
821
822     if( i_length <= 0 )
823     {
824         return;
825     }
826
827     i_packets     = c->i_depth;
828     i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000  + 187 ) / 188;
829     i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000  + 187 ) / 188;
830
831     if( i_packets < i_packets_min && i_packets_min > 0 )
832     {
833         sout_buffer_t *p_pk;
834         int i_div = ( i_packets_min - i_packets ) / i_packets;
835         int i_mod = ( i_packets_min - i_packets ) % i_packets;
836         int i_rest = 0;
837
838         /* We need to pad with null packets (pid=0x1fff)
839          * We try to melt null packets with true packets */
840         msg_Dbg( p_mux,
841                  "packets=%d but min=%d -> adding %d packets of padding",
842                  i_packets, i_packets_min, i_packets_min - i_packets );
843
844         BufferChainInit( c );
845         while( ( p_pk = BufferChainGet( &s ) ) )
846         {
847             int i, i_null;
848
849             BufferChainAppend( c, p_pk );
850
851             i_null = i_div + ( i_rest + i_mod ) / i_packets;
852
853             for( i = 0; i < i_null; i++ )
854             {
855                 sout_buffer_t *p_null;
856
857                 p_null = sout_BufferNew( p_mux->p_sout, 188 );
858                 p_null->p_buffer[0] = 0x47;
859                 p_null->p_buffer[1] = 0x1f;
860                 p_null->p_buffer[2] = 0xff;
861                 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
862                 memset( &p_null->p_buffer[4], 0, 184 );
863                 p_sys->i_null_continuity_counter =
864                     ( p_sys->i_null_continuity_counter + 1 ) % 16;
865
866                 BufferChainAppend( c, p_null );
867             }
868
869             i_rest = ( i_rest + i_mod ) % i_packets;
870         }
871     }
872     else if( i_packets > i_packets_max && i_packets_max > 0 )
873     {
874         sout_buffer_t *p_pk;
875         int           i;
876
877         /* Arg, we need to drop packets, I don't do something clever (like
878          * dropping complete pid, b frames, ... ), I just get the right amount
879          * of packets and discard the others */
880         msg_Warn( p_mux,
881                   "packets=%d but max=%d -> removing %d packets -> stream broken",
882                   i_packets, i_packets_max, i_packets - i_packets_max );
883
884         BufferChainInit( c );
885         for( i = 0; i < i_packets_max; i++ )
886         {
887             BufferChainAppend( c, BufferChainGet( &s ) );
888         }
889
890         while( ( p_pk = BufferChainGet( &s ) ) )
891         {
892             sout_BufferDelete( p_mux->p_sout, p_pk );
893         }
894     }
895 }
896
897 static void TSSetDate( sout_buffer_chain_t *c, mtime_t i_dts, mtime_t i_length )
898 {
899     sout_buffer_t *p_ts;
900     mtime_t       i_delta = i_length / c->i_depth;
901     int           i_packet = 0;
902
903     for( p_ts = c->p_first; p_ts != NULL; p_ts = p_ts->p_next )
904     {
905         p_ts->i_dts    = i_dts + i_packet * i_length / c->i_depth;  /* avoid rounding error */
906         p_ts->i_length = i_delta;
907
908         if( p_ts->i_flags&SOUT_BUFFER_FLAGS_PRIVATE_PCR_SOFT )
909         {
910             mtime_t i_pcr = 9 * p_ts->i_dts / 100;
911
912             p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
913             p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
914             p_ts->p_buffer[8] = ( i_pcr >> 9  )&0xff;
915             p_ts->p_buffer[9] = ( i_pcr >> 1  )&0xff;
916             p_ts->p_buffer[10]= ( i_pcr << 7  )&0x80;
917         }
918
919         i_packet++;
920     }
921 }
922
923 static void PEStoTS( sout_instance_t *p_sout,
924                      sout_buffer_chain_t *c, sout_buffer_t *p_pes,
925                      ts_stream_t *p_stream,
926                      vlc_bool_t b_pcr )
927 {
928     uint8_t *p_data;
929     int     i_size;
930     int     b_new_pes;
931
932     /* get PES total size */
933     i_size = p_pes->i_size;
934     p_data = p_pes->p_buffer;
935
936     /* Set pcr only with valid DTS */
937     if( p_pes->i_dts <= 0 )
938     {
939         b_pcr = VLC_FALSE;
940     }
941
942     b_new_pes = VLC_TRUE;
943
944     for( ;; )
945     {
946         int           b_adaptation_field;
947         int           i_payload;
948         int           i_copy;
949         sout_buffer_t *p_ts;
950
951         p_ts = sout_BufferNew( p_sout, 188 );
952         /* write header
953          * 8b   0x47    sync byte
954          * 1b           transport_error_indicator
955          * 1b           payload_unit_start
956          * 1b           transport_priority
957          * 13b          pid
958          * 2b           transport_scrambling_control
959          * 2b           if adaptation_field 0x03 else 0x01
960          * 4b           continuity_counter
961          */
962
963         i_payload = 184 - ( b_pcr ? 8 : 0 );
964         i_copy    = __MIN( i_size, i_payload );
965         b_adaptation_field = (b_pcr||i_size<i_payload) ? VLC_TRUE : VLC_FALSE;
966
967         p_ts->p_buffer[0] = 0x47;
968         p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
969                             ( ( p_stream->i_pid >> 8 )&0x1f );
970         p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
971         p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
972                             p_stream->i_continuity_counter;
973
974         b_new_pes = VLC_FALSE;
975         p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
976
977         if( b_adaptation_field )
978         {
979             int i;
980
981             if( b_pcr )
982             {
983                 mtime_t i_pcr = p_pes->i_dts * 9 / 100;
984                 int     i_stuffing = i_payload - i_copy;
985
986                 p_ts->p_buffer[4] = 7 + i_stuffing;
987                 p_ts->p_buffer[5] = 0x10;   /* flags */
988                 p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
989                 p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
990                 p_ts->p_buffer[8] = ( i_pcr >> 9  )&0xff;
991                 p_ts->p_buffer[9] = ( i_pcr >> 1  )&0xff;
992                 p_ts->p_buffer[10]= ( i_pcr << 7  )&0x80;
993                 p_ts->p_buffer[11]= 0;
994
995                 b_pcr = VLC_FALSE;
996                 for( i = 12; i < 12 + i_stuffing; i++ )
997                 {
998                     p_ts->p_buffer[i] = 0xff;
999                 }
1000             }
1001             else
1002             {
1003                 int i_stuffing = i_payload - i_copy;
1004
1005                 p_ts->p_buffer[4] = i_stuffing - 1;
1006                 if( i_stuffing > 1 )
1007                 {
1008                     p_ts->p_buffer[5] = 0x00;
1009                     for( i = 6; i < 6 + i_stuffing - 2; i++ )
1010                     {
1011                         p_ts->p_buffer[i] = 0xff;
1012                     }
1013                 }
1014             }
1015         }
1016         /* copy payload */
1017         memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1018         p_data += i_copy;
1019         i_size -= i_copy;
1020
1021         BufferChainAppend( c, p_ts );
1022
1023         if( i_size <= 0 )
1024         {
1025             sout_buffer_t *p_next = p_pes->p_next;
1026
1027             p_pes->p_next = NULL;
1028             sout_BufferDelete( p_sout, p_pes );
1029             if( p_next == NULL )
1030             {
1031                 break;
1032             }
1033             b_new_pes = VLC_TRUE;
1034             p_pes = p_next;
1035             i_size = p_pes->i_size;
1036             p_data = p_pes->p_buffer;
1037         }
1038     }
1039
1040     return;
1041 }
1042
1043 #if defined MODULE_NAME_IS_mux_ts
1044 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1045 {
1046     static uint32_t CRC32[256] =
1047     {
1048         0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1049         0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1050         0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1051         0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1052         0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1053         0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1054         0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1055         0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1056         0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1057         0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1058         0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1059         0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1060         0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1061         0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1062         0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1063         0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1064         0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1065         0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1066         0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1067         0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1068         0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1069         0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1070         0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1071         0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1072         0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1073         0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1074         0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1075         0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1076         0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1077         0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1078         0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1079         0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1080         0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1081         0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1082         0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1083         0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1084         0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1085         0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1086         0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1087         0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1088         0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1089         0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1090         0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1091         0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1092         0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1093         0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1094         0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1095         0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1096         0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1097         0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1098         0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1099         0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1100         0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1101         0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1102         0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1103         0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1104         0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1105         0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1106         0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1107         0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1108         0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1109         0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1110         0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1111         0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1112     };
1113
1114     uint32_t i_crc = 0xffffffff;
1115
1116     /* Calculate the CRC */
1117     while( i_count > 0 )
1118     {
1119         i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1120         p_begin++;
1121         i_count--;
1122     }
1123
1124     return( i_crc );
1125 }
1126
1127 static void GetPAT( sout_mux_t *p_mux,
1128                     sout_buffer_chain_t *c )
1129 {
1130     sout_mux_sys_t      *p_sys = p_mux->p_sys;
1131     sout_buffer_t       *p_pat;
1132     bits_buffer_t bits;
1133
1134     p_pat = sout_BufferNew( p_mux->p_sout, 1024 );
1135
1136     p_pat->i_pts = 0;
1137     p_pat->i_dts = 0;
1138     p_pat->i_length = 0;
1139
1140     bits_initwrite( &bits, 1024, p_pat->p_buffer );
1141
1142     bits_write( &bits, 8, 0 );      // pointer
1143     bits_write( &bits, 8, 0x00 );   // table id
1144     bits_write( &bits, 1,  1 );     // section_syntax_indicator
1145     bits_write( &bits, 1,  0 );     // 0
1146     bits_write( &bits, 2,  0x03 );     // reserved FIXME
1147     bits_write( &bits, 12, 13 );    // XXX for one program only XXX 
1148     bits_write( &bits, 16, 0x01 );  // FIXME stream id
1149     bits_write( &bits, 2,  0x03 );     //  FIXME
1150     bits_write( &bits, 5,  p_sys->i_pat_version_number );
1151     bits_write( &bits, 1,  1 );     // current_next_indicator
1152     bits_write( &bits, 8,  0 );     // section number
1153     bits_write( &bits, 8,  0 );     // last section number
1154
1155     bits_write( &bits, 16, 1 );     // program number
1156     bits_write( &bits,  3, 0x07 );     // reserved
1157     bits_write( &bits, 13, p_sys->pmt.i_pid );  // program map pid
1158
1159     bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1160
1161     p_pat->i_size = bits.i_data;
1162
1163     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat, VLC_FALSE );
1164 }
1165
1166 static void GetPMT( sout_mux_t *p_mux,
1167                     sout_buffer_chain_t *c )
1168 {
1169     sout_mux_sys_t      *p_sys = p_mux->p_sys;
1170     sout_buffer_t       *p_pmt;
1171     bits_buffer_t bits;
1172     int           i_stream;
1173
1174     p_pmt = sout_BufferNew( p_mux->p_sout, 1024 );
1175
1176     p_pmt->i_pts = 0;
1177     p_pmt->i_dts = 0;
1178     p_pmt->i_length = 0;
1179
1180     bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1181
1182     bits_write( &bits, 8, 0 );      // pointer
1183     bits_write( &bits, 8, 0x02 );   // table id
1184     bits_write( &bits, 1,  1 );     // section_syntax_indicator
1185     bits_write( &bits, 1,  0 );     // 0
1186     bits_write( &bits, 2,  0 );     // reserved FIXME
1187     bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1188     bits_write( &bits, 16, 1 );     // FIXME program number
1189     bits_write( &bits, 2,  0 );     //  FIXME
1190     bits_write( &bits, 5,  p_sys->i_pmt_version_number );
1191     bits_write( &bits, 1,  1 );     // current_next_indicator
1192     bits_write( &bits, 8,  0 );     // section number
1193     bits_write( &bits, 8,  0 );     // last section number
1194
1195     bits_write( &bits,  3, 0 );     // reserved
1196
1197     bits_write( &bits, 13, p_sys->i_pcr_pid );     //  FIXME FXIME PCR_PID FIXME
1198     bits_write( &bits,  4, 0 );     // reserved FIXME
1199
1200     bits_write( &bits, 12, 0 );    // program info len FIXME
1201
1202     for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1203     {
1204         ts_stream_t *p_stream;
1205
1206         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1207
1208         bits_write( &bits,  8, p_stream->i_stream_type ); // stream_type
1209         bits_write( &bits,  3, 0 );                 // reserved
1210         bits_write( &bits, 13, p_stream->i_pid );   // es pid
1211         bits_write( &bits,  4, 0 );                 //reserved
1212         bits_write( &bits, 12, 0 );                 // es info len FIXME
1213     }
1214
1215     bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1216
1217     p_pmt->i_size = bits.i_data;
1218
1219     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt, VLC_FALSE );
1220 }
1221 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1222
1223 static sout_buffer_t *WritePSISection( sout_instance_t *p_sout,
1224                                        dvbpsi_psi_section_t* p_section )
1225 {
1226     sout_buffer_t   *p_psi, *p_first = NULL;
1227
1228
1229     while( p_section )
1230     {
1231         int             i_size;
1232
1233         i_size =  (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1234                   ( p_section->b_syntax_indicator ? 4 : 0 );
1235
1236         p_psi = sout_BufferNew( p_sout, i_size + 1 );
1237         p_psi->i_pts = 0;
1238         p_psi->i_dts = 0;
1239         p_psi->i_length = 0;
1240         p_psi->i_size = i_size + 1;
1241
1242         p_psi->p_buffer[0] = 0; // pointer
1243         memcpy( p_psi->p_buffer + 1,
1244                 p_section->p_data,
1245                 i_size );
1246
1247         sout_BufferChain( &p_first, p_psi );
1248
1249         p_section = p_section->p_next;
1250     }
1251
1252     return( p_first );
1253 }
1254
1255 static void GetPAT( sout_mux_t *p_mux,
1256                     sout_buffer_chain_t *c )
1257 {
1258     sout_mux_sys_t       *p_sys = p_mux->p_sys;
1259     sout_buffer_t        *p_pat;
1260     dvbpsi_pat_t         pat;
1261     dvbpsi_psi_section_t *p_section;
1262
1263     dvbpsi_InitPAT( &pat,
1264                     0x01,    // i_ts_id
1265                     p_sys->i_pat_version_number,
1266                     1 );      // b_current_next
1267     /* add all program (only one) */
1268     dvbpsi_PATAddProgram( &pat,
1269                           1,                    // i_number
1270                           p_sys->pmt.i_pid );   // i_pid
1271
1272     p_section = dvbpsi_GenPATSections( &pat,
1273                                        0 );     // max program per section
1274
1275     p_pat = WritePSISection( p_mux->p_sout, p_section );
1276
1277     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat, VLC_FALSE );
1278
1279     dvbpsi_DeletePSISections( p_section );
1280     dvbpsi_EmptyPAT( &pat );
1281 }
1282
1283 static uint32_t GetDescriptorLength24b( int i_length )
1284 {
1285     uint32_t    i_l1, i_l2, i_l3;
1286
1287     i_l1 = i_length&0x7f;
1288     i_l2 = ( i_length >> 7 )&0x7f;
1289     i_l3 = ( i_length >> 14 )&0x7f;
1290
1291     return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1292 }
1293
1294 static void GetPMT( sout_mux_t *p_mux,
1295                     sout_buffer_chain_t *c )
1296 {
1297     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1298     sout_buffer_t   *p_pmt;
1299
1300     dvbpsi_pmt_t        pmt;
1301     dvbpsi_pmt_es_t     *p_es;
1302     dvbpsi_psi_section_t *p_section;
1303
1304     int                 i_stream;
1305
1306     dvbpsi_InitPMT( &pmt,
1307                     0x01,   // program number
1308                     p_sys->i_pmt_version_number,
1309                     1,      // b_current_next
1310                     p_sys->i_pcr_pid );
1311
1312     if( p_sys->i_mpeg4_streams > 0 )
1313     {
1314         uint8_t iod[4096];
1315         bits_buffer_t bits;
1316         bits_buffer_t bits_fix_IOD;
1317
1318         bits_initwrite( &bits, 4096, iod );
1319         // IOD_label
1320         bits_write( &bits, 8,   0x01 );
1321         // InitialObjectDescriptor
1322         bits_align( &bits );
1323         bits_write( &bits, 8,   0x02 );     // tag
1324         bits_fix_IOD = bits;    // save states to fix length later
1325         bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1326         bits_write( &bits, 10,  0x01 );     // ObjectDescriptorID
1327         bits_write( &bits, 1,   0x00 );     // URL Flag
1328         bits_write( &bits, 1,   0x00 );     // includeInlineProfileLevelFlag
1329         bits_write( &bits, 4,   0x0f );     // reserved
1330         bits_write( &bits, 8,   0xff );     // ODProfile (no ODcapability )
1331         bits_write( &bits, 8,   0xff );     // sceneProfile
1332         bits_write( &bits, 8,   0xfe );     // audioProfile (unspecified)
1333         bits_write( &bits, 8,   0xfe );     // visualProfile( // )
1334         bits_write( &bits, 8,   0xff );     // graphicProfile (no )
1335         for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1336         {
1337             ts_stream_t *p_stream;
1338             p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1339
1340             if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1341             {
1342                 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1343                 /* ES descriptor */
1344                 bits_align( &bits );
1345                 bits_write( &bits, 8,   0x03 );     // ES_DescrTag
1346                 bits_fix_ESDescr = bits;
1347                 bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) ); // variable size
1348                 bits_write( &bits, 16,  p_stream->i_es_id );
1349                 bits_write( &bits, 1,   0x00 );     // streamDependency
1350                 bits_write( &bits, 1,   0x00 );     // URL Flag
1351                 bits_write( &bits, 1,   0x00 );     // OCRStreamFlag
1352                 bits_write( &bits, 5,   0x1f );     // streamPriority
1353
1354                     // DecoderConfigDesciptor
1355                 bits_align( &bits );
1356                 bits_write( &bits, 8,   0x04 ); // DecoderConfigDescrTag
1357                 bits_fix_Decoder = bits;
1358                 bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) );
1359                 if( p_stream->i_stream_type == 0x10 )
1360                 {
1361                     bits_write( &bits, 8, 0x20 );   // Visual 14496-2
1362                     bits_write( &bits, 6, 0x04 );   // VisualStream
1363                 }
1364                 else if( p_stream->i_stream_type == 0x11 )
1365                 {
1366                     bits_write( &bits, 8, 0x40 );   // Audio 14496-3
1367                     bits_write( &bits, 6, 0x05 );   // AudioStream
1368                 }
1369                 else
1370                 {
1371                     bits_write( &bits, 8, 0x00 );
1372                     bits_write( &bits, 6, 0x00 );
1373
1374                     msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1375                 }
1376                 bits_write( &bits, 1,   0x00 );     // UpStream
1377                 bits_write( &bits, 1,   0x01 );     // reserved
1378                 bits_write( &bits, 24,  1024 * 1024 );  // bufferSizeDB
1379                 bits_write( &bits, 32,  0x7fffffff );   // maxBitrate
1380                 bits_write( &bits, 32,  0 );            // avgBitrate
1381
1382                 if( p_stream->i_decoder_specific_info > 0 )
1383                 {
1384                     int i;
1385                     // DecoderSpecificInfo
1386                     bits_align( &bits );
1387                     bits_write( &bits, 8,   0x05 ); // tag
1388                     bits_write( &bits, 24,
1389                                 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1390                     for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1391                     {
1392                         bits_write( &bits, 8,   ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1393                     }
1394                 }
1395                 /* fix Decoder length */
1396                 bits_write( &bits_fix_Decoder, 24,
1397                             GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1398
1399                 /* SLConfigDescriptor : predifined (0x01) */
1400                 bits_align( &bits );
1401                 bits_write( &bits, 8,   0x06 ); // tag
1402                 bits_write( &bits, 24,  GetDescriptorLength24b( 8 ) );
1403                 bits_write( &bits, 8,   0x01 ); // predefined
1404                 bits_write( &bits, 1,   0 );   // durationFlag
1405                 bits_write( &bits, 32,  0 );   // OCRResolution
1406                 bits_write( &bits, 8,   0 );   // OCRLength
1407                 bits_write( &bits, 8,   0 );   // InstantBitrateLength
1408                 bits_align( &bits );
1409
1410                 /* fix ESDescr length */
1411                 bits_write( &bits_fix_ESDescr, 24,
1412                             GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1413             }
1414         }
1415         bits_align( &bits );
1416         /* fix IOD length */
1417         bits_write( &bits_fix_IOD, 24,
1418                     GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1419         dvbpsi_PMTAddDescriptor( &pmt,
1420                                  0x1d,
1421                                  bits.i_data,
1422                                  bits.p_data );
1423     }
1424
1425     for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1426     {
1427         ts_stream_t *p_stream;
1428
1429         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1430
1431         p_es = dvbpsi_PMTAddES( &pmt,
1432                                 p_stream->i_stream_type,
1433                                 p_stream->i_pid );
1434         if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1435         {
1436             uint8_t     data[512];
1437             bits_buffer_t bits;
1438
1439             /* SL descriptor */
1440             bits_initwrite( &bits, 512, data );
1441             bits_write( &bits, 16, p_stream->i_es_id );
1442
1443             dvbpsi_PMTESAddDescriptor( p_es,
1444                                        0x1f,
1445                                        bits.i_data,
1446                                        bits.p_data );
1447         }
1448         else if( p_stream->i_stream_id == 0xa0 )
1449         {
1450             uint8_t     data[512];
1451             uint8_t     fcc[4];
1452             bits_buffer_t bits;
1453
1454             memcpy( fcc, &p_stream->i_bih_codec, 4 );
1455
1456             /* private DIV3 descripor */
1457             bits_initwrite( &bits, 512, data );
1458             bits_write( &bits, 8,  fcc[0]);
1459             bits_write( &bits, 8,  fcc[1]);
1460             bits_write( &bits, 8,  fcc[2]);
1461             bits_write( &bits, 8,  fcc[3]);
1462             bits_write( &bits, 16, p_stream->i_bih_width );
1463             bits_write( &bits, 16, p_stream->i_bih_height );
1464             bits_write( &bits, 16, p_stream->i_decoder_specific_info );
1465             if( p_stream->i_decoder_specific_info > 0 )
1466             {
1467                 int i;
1468                 for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1469                 {
1470                     bits_write( &bits, 8, p_stream->p_decoder_specific_info[i] );
1471                 }
1472             }
1473             dvbpsi_PMTESAddDescriptor( p_es,
1474                                        0xa0,    // private
1475                                        bits.i_data,
1476                                        bits.p_data );
1477         }
1478     }
1479
1480     p_section = dvbpsi_GenPMTSections( &pmt );
1481
1482     p_pmt = WritePSISection( p_mux->p_sout, p_section );
1483
1484     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt, VLC_FALSE );
1485
1486     dvbpsi_DeletePSISections( p_section );
1487     dvbpsi_EmptyPMT( &pmt );
1488 }
1489
1490 #endif
1491