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