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