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