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