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