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