]> git.sesse.net Git - vlc/blob - modules/mux/mpeg/ts.c
* ts: added lpcm and dts stream. (untested)
[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.39 2003/11/22 20:25:01 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( 'l', 'p','c', 'm' ):
478                     p_stream->i_stream_type = 0x83;
479                     p_stream->i_stream_id = 0xbd;
480                     break;
481                 case VLC_FOURCC( 'd', 't','s', ' ' ):
482                     p_stream->i_stream_type = 0x85;
483                     p_stream->i_stream_id = 0xbd;
484                     break;
485
486                 case VLC_FOURCC( 'm', 'p','4', 'a' ):
487                     p_stream->i_stream_type = 0x11;
488                     p_stream->i_stream_id = 0xfa;
489                     p_sys->i_mpeg4_streams++;
490                     p_stream->i_es_id = p_stream->i_pid;
491                     break;
492                 default:
493                     free( p_stream );
494                     return VLC_EGENERIC;
495             }
496             p_sys->i_audio_bound++;
497             break;
498
499         case SPU_ES:
500             switch( p_input->p_fmt->i_codec )
501             {
502                 case VLC_FOURCC( 's', 'p','u', ' ' ):
503                     p_stream->i_stream_type = 0x82;
504                     p_stream->i_stream_id = 0xbd;
505                     break;
506                 default:
507                     free( p_stream );
508                     return VLC_EGENERIC;
509             }
510             break;
511
512         default:
513             free( p_stream );
514             return VLC_EGENERIC;
515     }
516
517     /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
518     p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
519     if( p_stream->i_decoder_specific_info > 0 )
520     {
521         p_stream->p_decoder_specific_info =
522             malloc( p_stream->i_decoder_specific_info );
523         memcpy( p_stream->p_decoder_specific_info,
524                 p_input->p_fmt->p_extra,
525                 p_input->p_fmt->i_extra );
526     }
527
528     /* Init pes chain */
529     BufferChainInit( &p_stream->chain_pes );
530     p_stream->i_pes_dts    = 0;
531     p_stream->i_pes_length = 0;
532     p_stream->i_pes_used   = 0;
533
534     /* We only change PMT version (PAT isn't changed) */
535     p_sys->i_pmt_version_number = ( p_sys->i_pmt_version_number + 1 )%32;
536
537     /* Update pcr_pid */
538     if( p_input->p_fmt->i_cat != SPU_ES &&
539         ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) )
540     {
541         if( p_sys->p_pcr_input )
542         {
543             /* There was already a PCR stream, so clean context */
544             /* FIXME */
545         }
546         p_sys->i_pcr_pid   = p_stream->i_pid;
547         p_sys->p_pcr_input = p_input;
548     }
549
550     return VLC_SUCCESS;
551 }
552
553 /*****************************************************************************
554  * DelStream: called before a stream deletion
555  *****************************************************************************/
556 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
557 {
558     sout_mux_sys_t  *p_sys = p_mux->p_sys;
559     ts_stream_t     *p_stream;
560     char            *val;
561
562     msg_Dbg( p_mux, "removing input" );
563     p_stream = (ts_stream_t*)p_input->p_sys;
564
565     if( p_sys->i_pcr_pid == p_stream->i_pid )
566     {
567         int i;
568
569         /* Find a new pcr stream (Prefer Video Stream) */
570         p_sys->i_pcr_pid = 0x1fff;
571         p_sys->p_pcr_input = NULL;
572         for( i = 0; i < p_mux->i_nb_inputs; i++ )
573         {
574             if( p_mux->pp_inputs[i] == p_input )
575             {
576                 continue;
577             }
578
579             if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
580             {
581                 p_sys->i_pcr_pid  =
582                     ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
583                 p_sys->p_pcr_input= p_mux->pp_inputs[i];
584                 break;
585             }
586             else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
587                      p_sys->i_pcr_pid == 0x1fff )
588             {
589                 p_sys->i_pcr_pid  =
590                     ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
591                 p_sys->p_pcr_input= p_mux->pp_inputs[i];
592             }
593         }
594         if( p_sys->p_pcr_input )
595         {
596             /* Empty TS buffer */
597             /* FIXME */
598         }
599     }
600
601     /* Empty all data in chain_pes */
602     BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
603
604     if( p_stream->p_decoder_specific_info )
605     {
606         free( p_stream->p_decoder_specific_info );
607     }
608     if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
609     {
610         p_sys->i_mpeg4_streams--;
611     }
612     if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-video" ) ) )
613     {
614         int i_pid_video = strtol( val, NULL, 0 );
615         if ( i_pid_video == p_stream->i_pid )
616         {
617             p_sys->i_pid_video = i_pid_video;
618         }
619     }
620     if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-audio" ) ) )
621     {
622         int i_pid_audio = strtol( val, NULL, 0 );
623         if ( i_pid_audio == p_stream->i_pid )
624         {
625             p_sys->i_pid_audio = i_pid_audio;
626         }
627     }
628     free( p_stream );
629
630     /* We only change PMT version (PAT isn't changed) */
631     p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
632
633     return VLC_SUCCESS;
634 }
635
636 /*****************************************************************************
637  * Mux: Call each time there is new data for at least one stream
638  *****************************************************************************
639  *
640  *****************************************************************************/
641 static int Mux( sout_mux_t *p_mux )
642 {
643     sout_mux_sys_t  *p_sys = p_mux->p_sys;
644     ts_stream_t     *p_pcr_stream;
645
646     if( p_sys->i_pcr_pid == 0x1fff )
647     {
648         msg_Dbg( p_mux, "waiting PCR streams" );
649         msleep( 1000 );
650         return VLC_SUCCESS;
651     }
652     p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
653
654     for( ;; )
655     {
656         sout_buffer_chain_t chain_ts;
657         int                 i_packet_count;
658         int                 i_packet_pos;
659         mtime_t             i_pcr_dts;
660         mtime_t             i_pcr_length;
661         int i;
662
663         /* 1: get enough PES packet for all input */
664         for( ;; )
665         {
666             vlc_bool_t b_ok = VLC_TRUE;
667             sout_buffer_t *p_data;
668
669             /* Accumulate enough data in the pcr stream (>i_caching_delay) */
670             /* Accumulate enough data in all other stream ( >= length of pcr) */
671             for( i = 0; i < p_mux->i_nb_inputs; i++ )
672             {
673                 sout_input_t *p_input = p_mux->pp_inputs[i];
674                 ts_stream_t *p_stream = (ts_stream_t*)p_input->p_sys;
675
676                 if( ( p_stream == p_pcr_stream && p_stream->i_pes_length <= p_sys->i_caching_delay ) ||
677                     p_stream->i_pes_dts + p_stream->i_pes_length < p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
678                 {
679                     /* Need more data */
680                     if( p_input->p_fifo->i_depth <= 1 )
681                     {
682                         if( p_input->p_fmt->i_cat == AUDIO_ES ||
683                             p_input->p_fmt->i_cat == VIDEO_ES )
684                         {
685                             /* We need more data */
686                             return VLC_SUCCESS;
687                         }
688                         else if( p_input->p_fifo->i_depth <= 0 )
689                         {
690                             /* spu, only one packet is needed */
691                             continue;
692                         }
693                     }
694                     b_ok = VLC_FALSE;
695
696                     p_data = sout_FifoGet( p_input->p_fifo );
697                     if( p_input->p_fifo->i_depth > 0 )
698                     {
699                         sout_buffer_t *p_next = sout_FifoShow( p_input->p_fifo );
700
701                         p_data->i_length = p_next->i_dts - p_data->i_dts;
702                     }
703
704                     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 ) ||
705                         p_data->i_dts < p_stream->i_pes_dts ||
706                         ( p_stream->i_pes_dts > 0 && p_data->i_dts - 2000000 > p_stream->i_pes_dts + p_stream->i_pes_length ) )
707                     {
708                         msg_Warn( p_mux, "packet with too strange dts (dts=%lld,old=%lld,pcr=%lld)",
709                                   p_data->i_dts,
710                                   p_stream->i_pes_dts,
711                                   p_pcr_stream->i_pes_dts );
712                         sout_BufferDelete( p_mux->p_sout, p_data );
713
714                         BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
715                         p_stream->i_pes_dts = 0;
716                         p_stream->i_pes_used = 0;
717                         p_stream->i_pes_length = 0;
718
719                         BufferChainClean( p_mux->p_sout, &p_pcr_stream->chain_pes );
720                         p_pcr_stream->i_pes_dts = 0;
721                         p_pcr_stream->i_pes_used = 0;
722                         p_pcr_stream->i_pes_length = 0;
723
724                     }
725                     else
726                     {
727                         p_stream->i_pes_length += p_data->i_length;
728                         if( p_stream->i_pes_dts == 0 )
729                         {
730                             p_stream->i_pes_dts = p_data->i_dts;
731                         }
732
733                         /* Convert to pes */
734                         E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 );
735
736                         BufferChainAppend( &p_stream->chain_pes, p_data );
737                     }
738                 }
739             }
740
741             if( b_ok )
742             {
743                 break;
744             }
745         }
746
747         /* save */
748         i_pcr_dts      = p_pcr_stream->i_pes_dts;
749         i_pcr_length   = p_pcr_stream->i_pes_length;
750
751         /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
752         /* 2: calculate non accurate total size of muxed ts */
753         i_packet_count = 0;
754         for( i = 0; i < p_mux->i_nb_inputs; i++ )
755         {
756             ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
757             sout_buffer_t *p_pes;
758
759             /* False for pcr stream but it will be eough to do PCR algo */
760             for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL; p_pes = p_pes->p_next )
761             {
762                 int i_size = p_pes->i_size;
763                 if( p_pes->i_dts + p_pes->i_length > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
764                 {
765                     mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts;
766                     if( i_frag < 0 )
767                     {
768                         /* Next stream */
769                         break;
770                     }
771                     i_size = p_pes->i_size * i_frag / p_pes->i_length;
772                 }
773                 i_packet_count += ( i_size + 183 ) / 184;
774             }
775         }
776         /* add overhead for PCR (not really exact) */
777         i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176;
778
779
780         /* 3: mux PES into TS */
781         BufferChainInit( &chain_ts );
782         /* append PAT/PMT  -> FIXME with big pcr delay it won't have enough pat/pmt */
783         GetPAT( p_mux, &chain_ts);
784         GetPMT( p_mux, &chain_ts );
785         i_packet_pos = 0;
786         i_packet_count += chain_ts.i_depth;
787         /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
788
789         for( ;; )
790         {
791             int         i_stream;
792             mtime_t     i_dts;
793             ts_stream_t *p_stream;
794             sout_buffer_t *p_ts;
795             vlc_bool_t   b_pcr;
796
797             /* Select stream (lowest dts)*/
798             for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
799             {
800                 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
801
802                 if( p_stream->i_pes_dts == 0 )
803                 {
804                     continue;
805                 }
806
807                 if( i_stream == -1 ||
808                     p_stream->i_pes_dts < i_dts )
809                 {
810                     i_stream = i;
811                     i_dts = p_stream->i_pes_dts;
812                 }
813             }
814             if( i_stream == -1 )
815             {
816                 break;
817             }
818             p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
819
820             /* do we need to issue pcr */
821             b_pcr = VLC_FALSE;
822             if( p_stream == p_pcr_stream &&
823                 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >= p_sys->i_pcr + p_sys->i_pcr_delay )
824             {
825                 b_pcr = VLC_TRUE;
826                 p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count;
827             }
828
829             /* Build the TS packet */
830             p_ts = TSNew( p_mux, p_stream, b_pcr );
831             i_packet_pos++;
832
833             /* */
834             BufferChainAppend( &chain_ts, p_ts );
835         }
836
837         /* 4: date and send */
838         i_packet_count = chain_ts.i_depth;
839         /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
840         for( i = 0; i < i_packet_count; i++ )
841         {
842             sout_buffer_t *p_ts = BufferChainGet( &chain_ts );
843
844             p_ts->i_dts    = i_pcr_dts + i_pcr_length * i / i_packet_count;
845             p_ts->i_length = i_pcr_length / i_packet_count;
846
847             if( p_ts->i_flags&SOUT_BUFFER_FLAGS_PRIVATE_PCR )
848             {
849                 /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
850                 TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
851             }
852
853             /* latency */
854             p_ts->i_dts += 3*p_sys->i_caching_delay/2;
855
856             sout_AccessOutWrite( p_mux->p_access, p_ts );
857         }
858     }
859 }
860
861 static sout_buffer_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr )
862 {
863     sout_buffer_t *p_pes = p_stream->chain_pes.p_first;
864     sout_buffer_t *p_ts;
865
866     vlc_bool_t b_new_pes = VLC_FALSE;
867     vlc_bool_t b_adaptation_field = VLC_FALSE;
868
869     int        i_payload_max = 184 - ( b_pcr ? 8 : 0 );
870     int        i_payload;
871
872     if( p_stream->i_pes_used <= 0 )
873     {
874         b_new_pes = VLC_TRUE;
875     }
876     i_payload = __MIN( (int)p_pes->i_size - p_stream->i_pes_used, i_payload_max );
877
878     if( b_pcr || i_payload < i_payload_max )
879     {
880         b_adaptation_field = VLC_TRUE;
881     }
882
883     p_ts = sout_BufferNew( p_mux->p_sout, 188 );
884
885     p_ts->p_buffer[0] = 0x47;
886     p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|( ( p_stream->i_pid >> 8 )&0x1f );
887     p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
888     p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|p_stream->i_continuity_counter;
889
890     p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
891
892     if( b_adaptation_field )
893     {
894         int i;
895
896         if( b_pcr )
897         {
898             int     i_stuffing = i_payload_max - i_payload;
899
900             p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
901
902             p_ts->p_buffer[4] = 7 + i_stuffing;
903             p_ts->p_buffer[5] = 0x10;   /* flags */
904             p_ts->p_buffer[6] = ( 0 )&0xff;
905             p_ts->p_buffer[7] = ( 0 )&0xff;
906             p_ts->p_buffer[8] = ( 0 )&0xff;
907             p_ts->p_buffer[9] = ( 0 )&0xff;
908             p_ts->p_buffer[10]= ( 0 )&0x80;
909             p_ts->p_buffer[11]= 0;
910
911             for( i = 12; i < 12 + i_stuffing; i++ )
912             {
913                 p_ts->p_buffer[i] = 0xff;
914             }
915         }
916         else
917         {
918             int i_stuffing = i_payload_max - i_payload;
919
920             p_ts->p_buffer[4] = i_stuffing - 1;
921             if( i_stuffing > 1 )
922             {
923                 p_ts->p_buffer[5] = 0x00;
924                 for( i = 6; i < 6 + i_stuffing - 2; i++ )
925                 {
926                     p_ts->p_buffer[i] = 0xff;
927                 }
928             }
929         }
930     }
931
932     /* copy payload */
933     memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
934
935     p_stream->i_pes_used += i_payload;
936     p_stream->i_pes_dts      = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_size;
937     p_stream->i_pes_length  -= p_pes->i_length * i_payload / p_pes->i_size;
938
939     if( p_stream->i_pes_used >= (int)p_pes->i_size )
940     {
941         p_pes = BufferChainGet( &p_stream->chain_pes );
942         sout_BufferDelete( p_mux->p_sout, p_pes );
943
944         p_pes = p_stream->chain_pes.p_first;
945         if( p_pes )
946         {
947             p_stream->i_pes_dts    = p_pes->i_dts;
948             p_stream->i_pes_length = 0;
949             while( p_pes )
950             {
951                 p_stream->i_pes_length += p_pes->i_length;
952
953                 p_pes = p_pes->p_next;
954             }
955         }
956         else
957         {
958             p_stream->i_pes_dts = 0;
959             p_stream->i_pes_length = 0;
960         }
961         p_stream->i_pes_used = 0;
962     }
963
964     return p_ts;
965 }
966
967
968 static void TSSetPCR( sout_buffer_t *p_ts, mtime_t i_dts )
969 {
970     mtime_t i_pcr = 9 * i_dts / 100;
971
972     p_ts->p_buffer[6]  = ( i_pcr >> 25 )&0xff;
973     p_ts->p_buffer[7]  = ( i_pcr >> 17 )&0xff;
974     p_ts->p_buffer[8]  = ( i_pcr >> 9  )&0xff;
975     p_ts->p_buffer[9]  = ( i_pcr >> 1  )&0xff;
976     p_ts->p_buffer[10]|= ( i_pcr << 7  )&0x80;
977 }
978
979 #if 0
980 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 )
981 {
982     sout_mux_sys_t  *p_sys = p_mux->p_sys;
983     sout_buffer_chain_t s = *c;
984
985     int i_packets = 0;
986     int i_packets_min = 0;
987     int i_packets_max = 0;
988
989     if( i_length <= 0 )
990     {
991         return;
992     }
993
994     i_packets     = c->i_depth;
995     i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000  + 187 ) / 188;
996     i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000  + 187 ) / 188;
997
998     if( i_packets < i_packets_min && i_packets_min > 0 )
999     {
1000         sout_buffer_t *p_pk;
1001         int i_div = ( i_packets_min - i_packets ) / i_packets;
1002         int i_mod = ( i_packets_min - i_packets ) % i_packets;
1003         int i_rest = 0;
1004
1005         /* We need to pad with null packets (pid=0x1fff)
1006          * We try to melt null packets with true packets */
1007         msg_Dbg( p_mux,
1008                  "packets=%d but min=%d -> adding %d packets of padding",
1009                  i_packets, i_packets_min, i_packets_min - i_packets );
1010
1011         BufferChainInit( c );
1012         while( ( p_pk = BufferChainGet( &s ) ) )
1013         {
1014             int i, i_null;
1015
1016             BufferChainAppend( c, p_pk );
1017
1018             i_null = i_div + ( i_rest + i_mod ) / i_packets;
1019
1020             for( i = 0; i < i_null; i++ )
1021             {
1022                 sout_buffer_t *p_null;
1023
1024                 p_null = sout_BufferNew( p_mux->p_sout, 188 );
1025                 p_null->p_buffer[0] = 0x47;
1026                 p_null->p_buffer[1] = 0x1f;
1027                 p_null->p_buffer[2] = 0xff;
1028                 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
1029                 memset( &p_null->p_buffer[4], 0, 184 );
1030                 p_sys->i_null_continuity_counter =
1031                     ( p_sys->i_null_continuity_counter + 1 ) % 16;
1032
1033                 BufferChainAppend( c, p_null );
1034             }
1035
1036             i_rest = ( i_rest + i_mod ) % i_packets;
1037         }
1038     }
1039     else if( i_packets > i_packets_max && i_packets_max > 0 )
1040     {
1041         sout_buffer_t *p_pk;
1042         int           i;
1043
1044         /* Arg, we need to drop packets, I don't do something clever (like
1045          * dropping complete pid, b frames, ... ), I just get the right amount
1046          * of packets and discard the others */
1047         msg_Warn( p_mux,
1048                   "packets=%d but max=%d -> removing %d packets -> stream broken",
1049                   i_packets, i_packets_max, i_packets - i_packets_max );
1050
1051         BufferChainInit( c );
1052         for( i = 0; i < i_packets_max; i++ )
1053         {
1054             BufferChainAppend( c, BufferChainGet( &s ) );
1055         }
1056
1057         while( ( p_pk = BufferChainGet( &s ) ) )
1058         {
1059             sout_BufferDelete( p_mux->p_sout, p_pk );
1060         }
1061     }
1062 }
1063 #endif
1064
1065 static void PEStoTS( sout_instance_t *p_sout,
1066                      sout_buffer_chain_t *c, sout_buffer_t *p_pes,
1067                      ts_stream_t *p_stream )
1068 {
1069     uint8_t *p_data;
1070     int     i_size;
1071     int     b_new_pes;
1072
1073     /* get PES total size */
1074     i_size = p_pes->i_size;
1075     p_data = p_pes->p_buffer;
1076
1077     b_new_pes = VLC_TRUE;
1078
1079     for( ;; )
1080     {
1081         int           b_adaptation_field;
1082         int           i_copy;
1083         sout_buffer_t *p_ts;
1084
1085         p_ts = sout_BufferNew( p_sout, 188 );
1086         /* write header
1087          * 8b   0x47    sync byte
1088          * 1b           transport_error_indicator
1089          * 1b           payload_unit_start
1090          * 1b           transport_priority
1091          * 13b          pid
1092          * 2b           transport_scrambling_control
1093          * 2b           if adaptation_field 0x03 else 0x01
1094          * 4b           continuity_counter
1095          */
1096
1097         i_copy    = __MIN( i_size, 184 );
1098         b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
1099
1100         p_ts->p_buffer[0] = 0x47;
1101         p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
1102                             ( ( p_stream->i_pid >> 8 )&0x1f );
1103         p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1104         p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
1105                             p_stream->i_continuity_counter;
1106
1107         b_new_pes = VLC_FALSE;
1108         p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1109
1110         if( b_adaptation_field )
1111         {
1112             int i_stuffing = 184 - i_copy;
1113             int i;
1114
1115             p_ts->p_buffer[4] = i_stuffing - 1;
1116             if( i_stuffing > 1 )
1117             {
1118                 p_ts->p_buffer[5] = 0x00;
1119                 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1120                 {
1121                     p_ts->p_buffer[i] = 0xff;
1122                 }
1123             }
1124         }
1125         /* copy payload */
1126         memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1127         p_data += i_copy;
1128         i_size -= i_copy;
1129
1130         BufferChainAppend( c, p_ts );
1131
1132         if( i_size <= 0 )
1133         {
1134             sout_buffer_t *p_next = p_pes->p_next;
1135
1136             p_pes->p_next = NULL;
1137             sout_BufferDelete( p_sout, p_pes );
1138             if( p_next == NULL )
1139             {
1140                 break;
1141             }
1142             b_new_pes = VLC_TRUE;
1143             p_pes = p_next;
1144             i_size = p_pes->i_size;
1145             p_data = p_pes->p_buffer;
1146         }
1147     }
1148
1149     return;
1150 }
1151
1152 #if defined MODULE_NAME_IS_mux_ts
1153 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1154 {
1155     static uint32_t CRC32[256] =
1156     {
1157         0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1158         0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1159         0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1160         0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1161         0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1162         0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1163         0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1164         0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1165         0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1166         0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1167         0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1168         0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1169         0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1170         0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1171         0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1172         0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1173         0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1174         0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1175         0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1176         0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1177         0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1178         0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1179         0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1180         0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1181         0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1182         0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1183         0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1184         0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1185         0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1186         0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1187         0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1188         0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1189         0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1190         0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1191         0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1192         0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1193         0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1194         0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1195         0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1196         0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1197         0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1198         0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1199         0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1200         0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1201         0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1202         0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1203         0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1204         0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1205         0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1206         0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1207         0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1208         0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1209         0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1210         0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1211         0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1212         0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1213         0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1214         0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1215         0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1216         0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1217         0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1218         0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1219         0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1220         0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1221     };
1222
1223     uint32_t i_crc = 0xffffffff;
1224
1225     /* Calculate the CRC */
1226     while( i_count > 0 )
1227     {
1228         i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1229         p_begin++;
1230         i_count--;
1231     }
1232
1233     return( i_crc );
1234 }
1235
1236 static void GetPAT( sout_mux_t *p_mux,
1237                     sout_buffer_chain_t *c )
1238 {
1239     sout_mux_sys_t      *p_sys = p_mux->p_sys;
1240     sout_buffer_t       *p_pat;
1241     bits_buffer_t bits;
1242
1243     p_pat = sout_BufferNew( p_mux->p_sout, 1024 );
1244
1245     p_pat->i_pts = 0;
1246     p_pat->i_dts = 0;
1247     p_pat->i_length = 0;
1248
1249     bits_initwrite( &bits, 1024, p_pat->p_buffer );
1250
1251     bits_write( &bits, 8, 0 );      // pointer
1252     bits_write( &bits, 8, 0x00 );   // table id
1253     bits_write( &bits, 1,  1 );     // section_syntax_indicator
1254     bits_write( &bits, 1,  0 );     // 0
1255     bits_write( &bits, 2,  0x03 );     // reserved FIXME
1256     bits_write( &bits, 12, 13 );    // XXX for one program only XXX 
1257     bits_write( &bits, 16, 0x01 );  // FIXME stream id
1258     bits_write( &bits, 2,  0x03 );     //  FIXME
1259     bits_write( &bits, 5,  p_sys->i_pat_version_number );
1260     bits_write( &bits, 1,  1 );     // current_next_indicator
1261     bits_write( &bits, 8,  0 );     // section number
1262     bits_write( &bits, 8,  0 );     // last section number
1263
1264     bits_write( &bits, 16, 1 );     // program number
1265     bits_write( &bits,  3, 0x07 );     // reserved
1266     bits_write( &bits, 13, p_sys->pmt.i_pid );  // program map pid
1267
1268     bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1269
1270     p_pat->i_size = bits.i_data;
1271
1272     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1273 }
1274
1275 static void GetPMT( sout_mux_t *p_mux,
1276                     sout_buffer_chain_t *c )
1277 {
1278     sout_mux_sys_t      *p_sys = p_mux->p_sys;
1279     sout_buffer_t       *p_pmt;
1280     bits_buffer_t bits;
1281     int           i_stream;
1282
1283     p_pmt = sout_BufferNew( p_mux->p_sout, 1024 );
1284
1285     p_pmt->i_pts = 0;
1286     p_pmt->i_dts = 0;
1287     p_pmt->i_length = 0;
1288
1289     bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1290
1291     bits_write( &bits, 8, 0 );      // pointer
1292     bits_write( &bits, 8, 0x02 );   // table id
1293     bits_write( &bits, 1,  1 );     // section_syntax_indicator
1294     bits_write( &bits, 1,  0 );     // 0
1295     bits_write( &bits, 2,  0 );     // reserved FIXME
1296     bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1297     bits_write( &bits, 16, 1 );     // FIXME program number
1298     bits_write( &bits, 2,  0 );     //  FIXME
1299     bits_write( &bits, 5,  p_sys->i_pmt_version_number );
1300     bits_write( &bits, 1,  1 );     // current_next_indicator
1301     bits_write( &bits, 8,  0 );     // section number
1302     bits_write( &bits, 8,  0 );     // last section number
1303
1304     bits_write( &bits,  3, 0 );     // reserved
1305
1306     bits_write( &bits, 13, p_sys->i_pcr_pid );     //  FIXME FXIME PCR_PID FIXME
1307     bits_write( &bits,  4, 0 );     // reserved FIXME
1308
1309     bits_write( &bits, 12, 0 );    // program info len FIXME
1310
1311     for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1312     {
1313         ts_stream_t *p_stream;
1314
1315         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1316
1317         bits_write( &bits,  8, p_stream->i_stream_type ); // stream_type
1318         bits_write( &bits,  3, 0 );                 // reserved
1319         bits_write( &bits, 13, p_stream->i_pid );   // es pid
1320         bits_write( &bits,  4, 0 );                 //reserved
1321         bits_write( &bits, 12, 0 );                 // es info len FIXME
1322     }
1323
1324     bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1325
1326     p_pmt->i_size = bits.i_data;
1327
1328     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1329 }
1330 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1331
1332 static sout_buffer_t *WritePSISection( sout_instance_t *p_sout,
1333                                        dvbpsi_psi_section_t* p_section )
1334 {
1335     sout_buffer_t   *p_psi, *p_first = NULL;
1336
1337
1338     while( p_section )
1339     {
1340         int             i_size;
1341
1342         i_size =  (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1343                   ( p_section->b_syntax_indicator ? 4 : 0 );
1344
1345         p_psi = sout_BufferNew( p_sout, i_size + 1 );
1346         p_psi->i_pts = 0;
1347         p_psi->i_dts = 0;
1348         p_psi->i_length = 0;
1349         p_psi->i_size = i_size + 1;
1350
1351         p_psi->p_buffer[0] = 0; // pointer
1352         memcpy( p_psi->p_buffer + 1,
1353                 p_section->p_data,
1354                 i_size );
1355
1356         sout_BufferChain( &p_first, p_psi );
1357
1358         p_section = p_section->p_next;
1359     }
1360
1361     return( p_first );
1362 }
1363
1364 static void GetPAT( sout_mux_t *p_mux,
1365                     sout_buffer_chain_t *c )
1366 {
1367     sout_mux_sys_t       *p_sys = p_mux->p_sys;
1368     sout_buffer_t        *p_pat;
1369     dvbpsi_pat_t         pat;
1370     dvbpsi_psi_section_t *p_section;
1371
1372     dvbpsi_InitPAT( &pat,
1373                     0x01,    // i_ts_id
1374                     p_sys->i_pat_version_number,
1375                     1 );      // b_current_next
1376     /* add all program (only one) */
1377     dvbpsi_PATAddProgram( &pat,
1378                           1,                    // i_number
1379                           p_sys->pmt.i_pid );   // i_pid
1380
1381     p_section = dvbpsi_GenPATSections( &pat,
1382                                        0 );     // max program per section
1383
1384     p_pat = WritePSISection( p_mux->p_sout, p_section );
1385
1386     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1387
1388     dvbpsi_DeletePSISections( p_section );
1389     dvbpsi_EmptyPAT( &pat );
1390 }
1391
1392 static uint32_t GetDescriptorLength24b( int i_length )
1393 {
1394     uint32_t    i_l1, i_l2, i_l3;
1395
1396     i_l1 = i_length&0x7f;
1397     i_l2 = ( i_length >> 7 )&0x7f;
1398     i_l3 = ( i_length >> 14 )&0x7f;
1399
1400     return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1401 }
1402
1403 static void GetPMT( sout_mux_t *p_mux,
1404                     sout_buffer_chain_t *c )
1405 {
1406     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1407     sout_buffer_t   *p_pmt;
1408
1409     dvbpsi_pmt_t        pmt;
1410     dvbpsi_pmt_es_t     *p_es;
1411     dvbpsi_psi_section_t *p_section;
1412
1413     int                 i_stream;
1414
1415     dvbpsi_InitPMT( &pmt,
1416                     0x01,   // program number
1417                     p_sys->i_pmt_version_number,
1418                     1,      // b_current_next
1419                     p_sys->i_pcr_pid );
1420
1421     if( p_sys->i_mpeg4_streams > 0 )
1422     {
1423         uint8_t iod[4096];
1424         bits_buffer_t bits;
1425         bits_buffer_t bits_fix_IOD;
1426
1427         /* Make valgrind happy : it works at byte level not bit one so
1428          * bit_write confuse it (but DON'T CHANGE the way that bit_write is
1429          * working (needed when fixing some bits) */
1430         memset( iod, 0, 4096 );
1431
1432         bits_initwrite( &bits, 4096, iod );
1433         // IOD_label
1434         bits_write( &bits, 8,   0x01 );
1435         // InitialObjectDescriptor
1436         bits_align( &bits );
1437         bits_write( &bits, 8,   0x02 );     // tag
1438         bits_fix_IOD = bits;    // save states to fix length later
1439         bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1440         bits_write( &bits, 10,  0x01 );     // ObjectDescriptorID
1441         bits_write( &bits, 1,   0x00 );     // URL Flag
1442         bits_write( &bits, 1,   0x00 );     // includeInlineProfileLevelFlag
1443         bits_write( &bits, 4,   0x0f );     // reserved
1444         bits_write( &bits, 8,   0xff );     // ODProfile (no ODcapability )
1445         bits_write( &bits, 8,   0xff );     // sceneProfile
1446         bits_write( &bits, 8,   0xfe );     // audioProfile (unspecified)
1447         bits_write( &bits, 8,   0xfe );     // visualProfile( // )
1448         bits_write( &bits, 8,   0xff );     // graphicProfile (no )
1449         for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1450         {
1451             ts_stream_t *p_stream;
1452             p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1453
1454             if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1455             {
1456                 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1457                 /* ES descriptor */
1458                 bits_align( &bits );
1459                 bits_write( &bits, 8,   0x03 );     // ES_DescrTag
1460                 bits_fix_ESDescr = bits;
1461                 bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) ); // variable size
1462                 bits_write( &bits, 16,  p_stream->i_es_id );
1463                 bits_write( &bits, 1,   0x00 );     // streamDependency
1464                 bits_write( &bits, 1,   0x00 );     // URL Flag
1465                 bits_write( &bits, 1,   0x00 );     // OCRStreamFlag
1466                 bits_write( &bits, 5,   0x1f );     // streamPriority
1467
1468                     // DecoderConfigDesciptor
1469                 bits_align( &bits );
1470                 bits_write( &bits, 8,   0x04 ); // DecoderConfigDescrTag
1471                 bits_fix_Decoder = bits;
1472                 bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) );
1473                 if( p_stream->i_stream_type == 0x10 )
1474                 {
1475                     bits_write( &bits, 8, 0x20 );   // Visual 14496-2
1476                     bits_write( &bits, 6, 0x04 );   // VisualStream
1477                 }
1478                 else if( p_stream->i_stream_type == 0x11 )
1479                 {
1480                     bits_write( &bits, 8, 0x40 );   // Audio 14496-3
1481                     bits_write( &bits, 6, 0x05 );   // AudioStream
1482                 }
1483                 else
1484                 {
1485                     bits_write( &bits, 8, 0x00 );
1486                     bits_write( &bits, 6, 0x00 );
1487
1488                     msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1489                 }
1490                 bits_write( &bits, 1,   0x00 );     // UpStream
1491                 bits_write( &bits, 1,   0x01 );     // reserved
1492                 bits_write( &bits, 24,  1024 * 1024 );  // bufferSizeDB
1493                 bits_write( &bits, 32,  0x7fffffff );   // maxBitrate
1494                 bits_write( &bits, 32,  0 );            // avgBitrate
1495
1496                 if( p_stream->i_decoder_specific_info > 0 )
1497                 {
1498                     int i;
1499                     // DecoderSpecificInfo
1500                     bits_align( &bits );
1501                     bits_write( &bits, 8,   0x05 ); // tag
1502                     bits_write( &bits, 24,
1503                                 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1504                     for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1505                     {
1506                         bits_write( &bits, 8,   ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1507                     }
1508                 }
1509                 /* fix Decoder length */
1510                 bits_write( &bits_fix_Decoder, 24,
1511                             GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1512
1513                 /* SLConfigDescriptor : predifined (0x01) */
1514                 bits_align( &bits );
1515                 bits_write( &bits, 8,   0x06 ); // tag
1516                 bits_write( &bits, 24,  GetDescriptorLength24b( 8 ) );
1517                 bits_write( &bits, 8,   0x01 ); // predefined
1518                 bits_write( &bits, 1,   0 );   // durationFlag
1519                 bits_write( &bits, 32,  0 );   // OCRResolution
1520                 bits_write( &bits, 8,   0 );   // OCRLength
1521                 bits_write( &bits, 8,   0 );   // InstantBitrateLength
1522                 bits_align( &bits );
1523
1524                 /* fix ESDescr length */
1525                 bits_write( &bits_fix_ESDescr, 24,
1526                             GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1527             }
1528         }
1529         bits_align( &bits );
1530         /* fix IOD length */
1531         bits_write( &bits_fix_IOD, 24,
1532                     GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1533         dvbpsi_PMTAddDescriptor( &pmt,
1534                                  0x1d,
1535                                  bits.i_data,
1536                                  bits.p_data );
1537     }
1538
1539     for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1540     {
1541         ts_stream_t *p_stream;
1542
1543         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1544
1545         p_es = dvbpsi_PMTAddES( &pmt,
1546                                 p_stream->i_stream_type,
1547                                 p_stream->i_pid );
1548         if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1549         {
1550             uint8_t     es_id[2];
1551
1552             /* SL descriptor */
1553             es_id[0] = (p_stream->i_es_id >> 8)&0xff;
1554             es_id[1] = (p_stream->i_es_id)&0xff;
1555             dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
1556         }
1557         else if( p_stream->i_stream_type == 0xa0 )
1558         {
1559             uint8_t     data[512];
1560             int         i_extra = __MIN( p_stream->i_decoder_specific_info,
1561                                         502 );
1562
1563             /* private DIV3 descripor */
1564             memcpy( &data[0], &p_stream->i_bih_codec, 4 );
1565             data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
1566             data[5] = ( p_stream->i_bih_width      )&0xff;
1567             data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
1568             data[7] = ( p_stream->i_bih_height     )&0xff;
1569             data[8] = ( i_extra >> 8 )&0xff;
1570             data[9] = ( i_extra      )&0xff;
1571             if( i_extra > 0 )
1572             {
1573                 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1574             }
1575
1576             /* 0xa0 is private */
1577             dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra  + 10, data );
1578         }
1579         else if( p_stream->i_stream_type == 0x81 )
1580         {
1581             uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1582
1583             /* "registration" descriptor : "AC-3" */
1584             dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1585         }
1586     }
1587
1588     p_section = dvbpsi_GenPMTSections( &pmt );
1589
1590     p_pmt = WritePSISection( p_mux->p_sout, p_section );
1591
1592     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1593
1594     dvbpsi_DeletePSISections( p_section );
1595     dvbpsi_EmptyPMT( &pmt );
1596 }
1597
1598 #endif
1599