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