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