]> git.sesse.net Git - vlc/blob - modules/mux/mpeg/ts.c
* ts: added 14496-17 (text sub) support. It assumes that input is utf8
[vlc] / modules / mux / mpeg / ts.c
1 /*****************************************************************************
2  * ts.c: MPEG-II TS Muxer
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Eric Petit <titer@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>
29
30 #include <vlc/vlc.h>
31 #include <vlc/input.h>
32 #include <vlc/sout.h>
33
34 #include "iso_lang.h"
35
36 #include "bits.h"
37 #include "pes.h"
38 #include "csa.h"
39
40 #if defined MODULE_NAME_IS_mux_ts_dvbpsi
41 #   ifdef HAVE_DVBPSI_DR_H
42 #       include <dvbpsi/dvbpsi.h>
43 #       include <dvbpsi/descriptor.h>
44 #       include <dvbpsi/pat.h>
45 #       include <dvbpsi/pmt.h>
46 #       include <dvbpsi/dr.h>
47 #       include <dvbpsi/psi.h>
48 #   else
49 #       include "dvbpsi.h"
50 #       include "descriptor.h"
51 #       include "tables/pat.h"
52 #       include "tables/pmt.h"
53 #       include "descriptors/dr.h"
54 #       include "psi.h"
55 #   endif
56 #endif
57
58 /*
59  * TODO:
60  *  - check PCR frequency requirement
61  *  - check PAT/PMT  "        "
62  *  - check PCR/PCR "soft"
63  *  - check if "registration" descriptor : "AC-3" should be a program
64  *    descriptor or an es one. (xine want an es one)
65  *
66  *  - remove creation of PAT/PMT without dvbpsi
67  *  - ?
68  * FIXME:
69  *  - subtitle support is far from perfect. I expect some subtitles drop
70  *    if they arrive a bit late
71  *    (We cannot rely on the fact that the fifo should be full)
72  */
73 /*****************************************************************************
74  * Module descriptor
75  *****************************************************************************/
76 static int     Open   ( vlc_object_t * );
77 static void    Close  ( vlc_object_t * );
78
79 #define VPID_TEXT N_("Video PID")
80 #define VPID_LONGTEXT N_("Assigns a fixed PID to the video stream. The PCR " \
81   "PID will automatically be the video.")
82 #define APID_TEXT N_("Audio PID")
83 #define APID_LONGTEXT N_("Assigns a fixed PID to the audio stream.")
84
85 #define SHAPING_TEXT N_("Shaping delay (ms)")
86 #define SHAPING_LONGTEXT N_("If enabled, the TS muxer will cut the " \
87   "stream in slices of the given duration, and ensure a constant bitrate " \
88   "between the two boundaries. This avoids having huge bitrate peaks for " \
89   "reference frames, in particular.")
90 #define KEYF_TEXT N_("Use keyframes")
91 #define KEYF_LONGTEXT N_("If enabled, and shaping is specified, " \
92   "the TS muxer will place the boundaries at the end of I pictures. In " \
93   "that case, the shaping duration given by the user is a worse case " \
94   "used when no reference frame is available. This enhances the efficiency " \
95   "of the shaping algorithm, since I frames are usually the biggest " \
96   "frames in the stream.")
97
98 #define PCR_TEXT N_("PCR delay (ms)")
99 #define PCR_LONGTEXT N_("This option allows you to set at which interval " \
100   "PCRs (Program Clock Reference) will be sent. " \
101   "This value should be below 100ms. (default is 30)")
102
103 #define DTS_TEXT N_("DTS delay (ms)")
104 #define DTS_LONGTEXT N_("This option will delay the DTS (decoding time " \
105   "stamps) and PTS (presentation timestamps) of the data in the " \
106   "stream, compared to the PCRs. This allows for some buffering inside " \
107   "the client decoder.")
108
109 #define ACRYPT_TEXT N_("Crypt audio")
110 #define ACRYPT_LONGTEXT N_("Crypt audio using CSA")
111
112 #define CK_TEXT N_("CSA Key")
113 #define CK_LONGTEXT N_("Defines the CSA encryption key. This must be a " \
114   "16 char string (8 hexadecimal bytes).")
115
116 #define SOUT_CFG_PREFIX "sout-ts-"
117
118 vlc_module_begin();
119 #if defined MODULE_NAME_IS_mux_ts
120     set_description( _("TS muxer") );
121     set_capability( "sout mux", 100 );
122     add_shortcut( "ts" );
123     add_shortcut( "ts_nodvbpsi" );
124 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
125     set_description( _("TS muxer (libdvbpsi)") );
126     set_capability( "sout mux", 120 );
127     add_shortcut( "ts" );
128     add_shortcut( "ts_dvbpsi" );
129 #endif
130
131     add_integer( SOUT_CFG_PREFIX "pid-video", 0, NULL,VPID_TEXT, VPID_LONGTEXT,
132                                   VLC_TRUE );
133     add_integer( SOUT_CFG_PREFIX "pid-audio", 0, NULL, APID_TEXT,
134                  APID_LONGTEXT, VLC_TRUE );
135
136     add_integer( SOUT_CFG_PREFIX "shaping", 200, NULL,SHAPING_TEXT,
137                  SHAPING_LONGTEXT, VLC_TRUE );
138     add_bool( SOUT_CFG_PREFIX "use-key-frames", VLC_FALSE, NULL, KEYF_TEXT,
139               KEYF_LONGTEXT, VLC_TRUE );
140
141     add_integer( SOUT_CFG_PREFIX "pcr", 30, NULL, PCR_TEXT, PCR_LONGTEXT,
142                  VLC_TRUE );
143     add_integer( SOUT_CFG_PREFIX "dts-delay", 200, NULL, DTS_TEXT,
144                  DTS_LONGTEXT, VLC_TRUE );
145
146     add_bool( SOUT_CFG_PREFIX "crypt-audio", VLC_TRUE, NULL, ACRYPT_TEXT,
147               ACRYPT_LONGTEXT, VLC_TRUE );
148
149     add_string( SOUT_CFG_PREFIX "csa-ck", NULL, NULL, CK_TEXT, CK_LONGTEXT,
150                 VLC_TRUE );
151
152     set_callbacks( Open, Close );
153 vlc_module_end();
154
155 /*****************************************************************************
156  * Local data structures
157  *****************************************************************************/
158 static const char *ppsz_sout_options[] = {
159     "pid-video", "pid-audio", "shaping", "pcr",
160     "use-key-frames", "dts-delay", "csa-ck", "crypt-audio", NULL
161 };
162
163 #define SOUT_BUFFER_FLAGS_PRIVATE_PCR  ( 1 << BLOCK_FLAG_PRIVATE_SHIFT )
164 #define SOUT_BUFFER_FLAGS_PRIVATE_CSA  ( 2 << BLOCK_FLAG_PRIVATE_SHIFT )
165 typedef struct
166 {
167     int     i_depth;
168     block_t *p_first;
169     block_t **pp_last;
170 } sout_buffer_chain_t;
171
172 static inline void BufferChainInit  ( sout_buffer_chain_t *c )
173 {
174     c->i_depth = 0;
175     c->p_first = NULL;
176     c->pp_last = &c->p_first;
177 }
178 static inline void BufferChainAppend( sout_buffer_chain_t *c, block_t *b )
179 {
180     *c->pp_last = b;
181     c->i_depth++;
182
183     while( b->p_next )
184     {
185         b = b->p_next;
186         c->i_depth++;
187     }
188     c->pp_last = &b->p_next;
189 }
190 static inline block_t *BufferChainGet( sout_buffer_chain_t *c )
191 {
192     block_t *b = c->p_first;
193
194     if( b )
195     {
196         c->i_depth--;
197         c->p_first = b->p_next;
198
199         if( c->p_first == NULL )
200         {
201             c->pp_last = &c->p_first;
202         }
203
204         b->p_next = NULL;
205     }
206     return b;
207 }
208 static inline block_t *BufferChainPeek( sout_buffer_chain_t *c )
209 {
210     block_t *b = c->p_first;
211
212     return b;
213 }
214 static inline void BufferChainClean( sout_instance_t *p_sout, sout_buffer_chain_t *c )
215 {
216     block_t *b;
217
218     while( ( b = BufferChainGet( c ) ) )
219     {
220         block_Release( b );
221     }
222     BufferChainInit( c );
223 }
224
225 typedef struct ts_stream_t
226 {
227     int             i_pid;
228     vlc_fourcc_t    i_codec;
229
230     int             i_stream_type;
231     int             i_stream_id;
232     int             i_continuity_counter;
233
234     /* to be used for carriege of DIV3 */
235     vlc_fourcc_t    i_bih_codec;
236     int             i_bih_width, i_bih_height;
237
238     /* Specific to mpeg4 in mpeg2ts */
239     int             i_es_id;
240
241     int             i_decoder_specific_info;
242     uint8_t         *p_decoder_specific_info;
243
244     /* language is iso639-2T */
245     uint8_t         lang[3];
246
247     sout_buffer_chain_t chain_pes;
248     mtime_t             i_pes_dts;
249     mtime_t             i_pes_length;
250     int                 i_pes_used;
251     vlc_bool_t          b_key_frame;
252
253 } ts_stream_t;
254
255 struct sout_mux_sys_t
256 {
257     int             i_pcr_pid;
258     sout_input_t    *p_pcr_input;
259
260     int             i_audio_bound;
261     int             i_video_bound;
262
263     int             i_pid_video;
264     int             i_pid_audio;
265     int             i_pid_free; // first usable pid
266
267     int             i_pat_version_number;
268     ts_stream_t     pat;
269
270     int             i_pmt_version_number;
271     ts_stream_t     pmt;        // Up to now only one program
272
273     int             i_mpeg4_streams;
274
275     int             i_null_continuity_counter;  /* Needed ? */
276
277     /* for TS building */
278     int64_t             i_bitrate_min;
279     int64_t             i_bitrate_max;
280
281     int64_t             i_shaping_delay;
282     int64_t             i_pcr_delay;
283
284     int64_t             i_dts_delay;
285
286     vlc_bool_t          b_use_key_frames;
287
288     mtime_t             i_pcr;  /* last PCR emited */
289
290     csa_t               *csa;
291     vlc_bool_t          b_crypt_audio;
292 };
293
294
295 /* Reserve a pid and return it */
296 static int  AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
297 {
298     int i_pid;
299     if ( i_cat == VIDEO_ES && p_sys->i_pid_video )
300     {
301         i_pid = p_sys->i_pid_video;
302         p_sys->i_pid_video = 0;
303     }
304     else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio )
305     {
306         i_pid = p_sys->i_pid_audio;
307         p_sys->i_pid_audio = 0;
308     }
309     else
310     {
311         i_pid = ++p_sys->i_pid_free;
312     }
313     return i_pid;
314 }
315
316 /*****************************************************************************
317  * Local prototypes
318  *****************************************************************************/
319 static int     Capability(sout_mux_t *, int, void *, void * );
320 static int     AddStream( sout_mux_t *, sout_input_t * );
321 static int     DelStream( sout_mux_t *, sout_input_t * );
322 static int     Mux      ( sout_mux_t * );
323
324 static void TSSchedule  ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
325                           mtime_t i_pcr_length, mtime_t i_pcr_dts );
326 static void TSDate      ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
327                           mtime_t i_pcr_length, mtime_t i_pcr_dts );
328 static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
329 static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
330
331 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr );
332 static void TSSetPCR( block_t *p_ts, mtime_t i_dts );
333
334 static void PEStoTS  ( sout_instance_t *, sout_buffer_chain_t *, block_t *, ts_stream_t * );
335
336 /*****************************************************************************
337  * Open:
338  *****************************************************************************/
339 static int Open( vlc_object_t *p_this )
340 {
341     sout_mux_t          *p_mux =(sout_mux_t*)p_this;
342     sout_mux_sys_t      *p_sys;
343     vlc_value_t         val;
344
345     msg_Dbg( p_mux, "Open" );
346     sout_ParseCfg( p_mux, SOUT_CFG_PREFIX, ppsz_sout_options, p_mux->p_cfg );
347
348     p_sys = malloc( sizeof( sout_mux_sys_t ) );
349
350     p_mux->pf_capacity  = Capability;
351     p_mux->pf_addstream = AddStream;
352     p_mux->pf_delstream = DelStream;
353     p_mux->pf_mux       = Mux;
354     p_mux->p_sys        = p_sys;
355
356     srand( (uint32_t)mdate() );
357
358     p_sys->i_audio_bound = 0;
359     p_sys->i_video_bound = 0;
360
361     p_sys->i_pat_version_number = rand() % 32;
362     p_sys->pat.i_pid = 0;
363     p_sys->pat.i_continuity_counter = 0;
364
365     p_sys->i_pmt_version_number = rand() % 32;
366     p_sys->pmt.i_pid = 0x42;
367     p_sys->pmt.i_continuity_counter = 0;
368
369     p_sys->i_pid_free = 0x43;
370
371     var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );
372     p_sys->i_pid_video = val.i_int;
373     if ( p_sys->i_pid_video > p_sys->i_pid_free )
374     {
375         p_sys->i_pid_free = p_sys->i_pid_video + 1;
376     }
377
378     var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );
379     p_sys->i_pid_audio = val.i_int;
380     if ( p_sys->i_pid_audio > p_sys->i_pid_free )
381     {
382         p_sys->i_pid_free = p_sys->i_pid_audio + 1;
383     }
384
385     p_sys->i_pcr_pid = 0x1fff;
386     p_sys->p_pcr_input = NULL;
387
388     p_sys->i_mpeg4_streams = 0;
389
390     p_sys->i_null_continuity_counter = 0;
391
392     /* Allow to create constrained stream */
393     var_Get( p_mux, SOUT_CFG_PREFIX "bmin", &val );
394     p_sys->i_bitrate_min = 0;/*val.i_int;*/
395
396     var_Get( p_mux, SOUT_CFG_PREFIX "bmax", &val );
397     p_sys->i_bitrate_max = 0;/*val.i_int;*/
398
399     if( p_sys->i_bitrate_min > 0 && p_sys->i_bitrate_max > 0 &&
400         p_sys->i_bitrate_min > p_sys->i_bitrate_max )
401     {
402         msg_Err( p_mux, "incompatible minimum and maximum bitrate, "
403                  "disabling bitrate control" );
404         p_sys->i_bitrate_min = 0;
405         p_sys->i_bitrate_max = 0;
406     }
407     if( p_sys->i_bitrate_min > 0 || p_sys->i_bitrate_max > 0 )
408     {
409         msg_Err( p_mux, "bmin and bmax no more supported (if you need them report it)" );
410     }
411
412     var_Get( p_mux, SOUT_CFG_PREFIX "shaping", &val );
413     p_sys->i_shaping_delay = (int64_t)val.i_int * 1000;
414     if( p_sys->i_shaping_delay <= 0 )
415     {
416         msg_Err( p_mux,
417                  "invalid shaping ("I64Fd"ms) resetting to 200ms",
418                  p_sys->i_shaping_delay / 1000 );
419         p_sys->i_shaping_delay = 200000;
420     }
421
422     var_Get( p_mux, SOUT_CFG_PREFIX "pcr", &val );
423     p_sys->i_pcr_delay = (int64_t)val.i_int * 1000;
424     if( p_sys->i_pcr_delay <= 0 ||
425         p_sys->i_pcr_delay >= p_sys->i_shaping_delay )
426     {
427         msg_Err( p_mux,
428                  "invalid pcr delay ("I64Fd"ms) resetting to 30ms",
429                  p_sys->i_pcr_delay / 1000 );
430         p_sys->i_pcr_delay = 30000;
431     }
432
433     var_Get( p_mux, SOUT_CFG_PREFIX "dts-delay", &val );
434     p_sys->i_dts_delay = (int64_t)val.i_int * 1000;
435
436     msg_Dbg( p_mux, "shaping="I64Fd" pcr="I64Fd" dts_delay="I64Fd,
437              p_sys->i_shaping_delay, p_sys->i_pcr_delay, p_sys->i_dts_delay );
438
439     var_Get( p_mux, SOUT_CFG_PREFIX "use-key-frames", &val );
440     p_sys->b_use_key_frames = val.b_bool;
441
442     /* for TS generation */
443     p_sys->i_pcr    = 0;
444
445     p_sys->csa      = NULL;
446     var_Get( p_mux, SOUT_CFG_PREFIX "csa-ck", &val );
447     if( val.psz_string )
448     {
449         char *psz = val.psz_string;
450
451         /* skip 0x */
452         if( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) )
453         {
454             psz += 2;
455         }
456         if( strlen( psz ) != 16 )
457         {
458             msg_Dbg( p_mux, "invalid csa ck (it must be 16 chars long)" );
459         }
460         else
461         {
462             uint64_t i_ck = strtoll( psz, NULL, 16 );
463             uint8_t  ck[8];
464             int      i;
465
466             for( i = 0; i < 8; i++ )
467             {
468                 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
469             }
470
471             msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x",
472                      ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
473
474             p_sys->csa = csa_New();
475             csa_SetCW( p_sys->csa, ck, ck );
476         }
477     }
478     if( val.psz_string ) free( val.psz_string );
479
480     var_Get( p_mux, SOUT_CFG_PREFIX "crypt-audio", &val );
481     p_sys->b_crypt_audio = val.b_bool;
482
483     return VLC_SUCCESS;
484 }
485
486 /*****************************************************************************
487  * Close:
488  *****************************************************************************/
489 static void Close( vlc_object_t * p_this )
490 {
491     sout_mux_t          *p_mux = (sout_mux_t*)p_this;
492     sout_mux_sys_t      *p_sys = p_mux->p_sys;
493
494     msg_Dbg( p_mux, "Close" );
495     if( p_sys->csa )
496     {
497         csa_Delete( p_sys->csa );
498     }
499
500     free( p_sys );
501 }
502
503 /*****************************************************************************
504  * Capability:
505  *****************************************************************************/
506 static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
507 {
508    switch( i_query )
509    {
510         case SOUT_MUX_CAP_GET_ADD_STREAM_ANY_TIME:
511             *(vlc_bool_t*)p_answer = VLC_TRUE;
512             return( SOUT_MUX_CAP_ERR_OK );
513         default:
514             return( SOUT_MUX_CAP_ERR_UNIMPLEMENTED );
515    }
516 }
517
518 /*****************************************************************************
519  * AddStream: called for each stream addition
520  *****************************************************************************/
521 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
522 {
523     sout_mux_sys_t      *p_sys = p_mux->p_sys;
524     ts_stream_t         *p_stream;
525
526     p_input->p_sys = p_stream = malloc( sizeof( ts_stream_t ) );
527
528     /* Init this new stream */
529     p_stream->i_pid = AllocatePID( p_sys, p_input->p_fmt->i_cat );
530     p_stream->i_codec = p_input->p_fmt->i_codec;
531     p_stream->i_continuity_counter    = 0;
532     p_stream->i_decoder_specific_info = 0;
533     p_stream->p_decoder_specific_info = NULL;
534
535     msg_Dbg( p_mux, "adding input codec=%4.4s pid=%d", (char*)&p_input->p_fmt->i_codec, p_stream->i_pid );
536
537     /* All others fields depand on codec */
538     switch( p_input->p_fmt->i_cat )
539     {
540         case VIDEO_ES:
541             switch( p_input->p_fmt->i_codec )
542             {
543                 case VLC_FOURCC( 'm', 'p','g', 'v' ):
544                     /* TODO: do we need to check MPEG-I/II ? */
545                     p_stream->i_stream_type = 0x02;
546                     p_stream->i_stream_id = 0xe0;
547                     break;
548                 case VLC_FOURCC( 'm', 'p','4', 'v' ):
549                     p_stream->i_stream_type = 0x10;
550                     p_stream->i_stream_id = 0xfa;
551                     p_sys->i_mpeg4_streams++;
552                     p_stream->i_es_id = p_stream->i_pid;
553                     break;
554                 case VLC_FOURCC( 'h', '2','6', '4' ):
555                     p_stream->i_stream_type = 0x1b;
556                     p_stream->i_stream_id = 0xe0;
557                     break;
558                 /* XXX dirty dirty but somebody want that : using crapy MS-codec XXX */
559                 /* I didn't want to do that :P */
560                 case VLC_FOURCC( 'H', '2', '6', '3' ):
561                 case VLC_FOURCC( 'I', '2', '6', '3' ):
562                 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
563                 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
564                 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
565                 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
566                 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
567                 case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
568                     p_stream->i_stream_type = 0xa0; // private
569                     p_stream->i_stream_id = 0xa0;   // beurk
570                     p_stream->i_bih_codec  = p_input->p_fmt->i_codec;
571                     p_stream->i_bih_width  = p_input->p_fmt->video.i_width;
572                     p_stream->i_bih_height = p_input->p_fmt->video.i_height;
573                     break;
574                 default:
575                     free( p_stream );
576                     return VLC_EGENERIC;
577             }
578             p_sys->i_video_bound++;
579             break;
580
581         case AUDIO_ES:
582             switch( p_input->p_fmt->i_codec )
583             {
584                 case VLC_FOURCC( 'm', 'p','g', 'a' ):
585                     p_stream->i_stream_type = p_input->p_fmt->audio.i_rate >= 32000 ? 0x03 : 0x04;
586                     p_stream->i_stream_id = 0xc0;
587                     break;
588                 case VLC_FOURCC( 'a', '5','2', ' ' ):
589                     p_stream->i_stream_type = 0x81;
590                     p_stream->i_stream_id = 0xbd;
591                     break;
592                 case VLC_FOURCC( 'l', 'p','c', 'm' ):
593                     p_stream->i_stream_type = 0x83;
594                     p_stream->i_stream_id = 0xbd;
595                     break;
596                 case VLC_FOURCC( 'd', 't','s', ' ' ):
597                     p_stream->i_stream_type = 0x85;
598                     p_stream->i_stream_id = 0xbd;
599                     break;
600
601                 case VLC_FOURCC( 'm', 'p','4', 'a' ):
602                     p_stream->i_stream_type = 0x11;
603                     p_stream->i_stream_id = 0xfa;
604                     p_sys->i_mpeg4_streams++;
605                     p_stream->i_es_id = p_stream->i_pid;
606                     break;
607                 default:
608                     free( p_stream );
609                     return VLC_EGENERIC;
610             }
611             p_sys->i_audio_bound++;
612             break;
613
614         case SPU_ES:
615             switch( p_input->p_fmt->i_codec )
616             {
617                 case VLC_FOURCC( 's', 'p','u', ' ' ):
618                     p_stream->i_stream_type = 0x82;
619                     p_stream->i_stream_id = 0xbd;
620                     break;
621                 case VLC_FOURCC( 's', 'u','b', 't' ):
622                     p_stream->i_stream_type = 0x12;
623                     p_stream->i_stream_id = 0xfa;
624                     p_sys->i_mpeg4_streams++;
625                     p_stream->i_es_id = p_stream->i_pid;
626                     break;
627                 default:
628                     free( p_stream );
629                     return VLC_EGENERIC;
630             }
631             break;
632
633         default:
634             free( p_stream );
635             return VLC_EGENERIC;
636     }
637
638     p_stream->lang[0] =
639     p_stream->lang[1] =
640     p_stream->lang[2] = '\0';
641     if( p_input->p_fmt->psz_language )
642     {
643         char *psz = p_input->p_fmt->psz_language;
644         const iso639_lang_t *pl = NULL;
645
646         if( strlen( psz ) == 2 )
647         {
648             pl = GetLang_1( psz );
649         }
650         else if( strlen( psz ) == 3 )
651         {
652             pl = GetLang_2B( psz );
653             if( !strcmp( pl->psz_iso639_1, "??" ) )
654             {
655                 pl = GetLang_2T( psz );
656             }
657         }
658         if( pl && strcmp( pl->psz_iso639_1, "??" ) )
659         {
660             p_stream->lang[0] = pl->psz_iso639_2T[0];
661             p_stream->lang[1] = pl->psz_iso639_2T[1];
662             p_stream->lang[2] = pl->psz_iso639_2T[2];
663
664             msg_Dbg( p_mux, "    - lang=%c%c%c",
665                      p_stream->lang[0],
666                      p_stream->lang[1],
667                      p_stream->lang[2] );
668         }
669     }
670
671
672     /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
673     p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
674     if( p_stream->i_decoder_specific_info > 0 )
675     {
676         p_stream->p_decoder_specific_info =
677             malloc( p_stream->i_decoder_specific_info );
678         memcpy( p_stream->p_decoder_specific_info,
679                 p_input->p_fmt->p_extra,
680                 p_input->p_fmt->i_extra );
681     }
682
683     /* Create decoder specific info for subt */
684     if( p_stream->i_codec == VLC_FOURCC( 's', 'u','b', 't' ) )
685     {
686         uint8_t *p;
687
688         p_stream->i_decoder_specific_info = 55;
689         p_stream->p_decoder_specific_info = p = malloc( p_stream->i_decoder_specific_info );
690
691         p[0] = 0x10;    /* textFormat, 0x10 for 3GPP TS 26.245 */
692         p[1] = 0x00;    /* flags: 1b: associated video info flag
693                                   3b: reserved
694                                   1b: duration flag
695                                   3b: reserved */
696         p[2] = 52;      /* remaining size */
697
698         p += 3;
699
700         p[0] = p[1] = p[2] = p[3] = 0; p+=4;    /* display flags */
701         *p++ = 0;                       /* horizontal justification (-1: left, 0 center, 1 right) */
702         *p++ = 1;                       /* vertical   justification (-1: top, 0 center, 1 bottom) */
703
704         p[0] = p[1] = p[2] = 0x00; p+=3;/* background rgb */
705         *p++ = 0xff;                    /* background a */
706
707         p[0] = p[1] = 0; p += 2;        /* text box top */
708         p[0] = p[1] = 0; p += 2;        /* text box left */
709         p[0] = p[1] = 0; p += 2;        /* text box bottom */
710         p[0] = p[1] = 0; p += 2;        /* text box right */
711
712         p[0] = p[1] = 0; p += 2;        /* start char */
713         p[0] = p[1] = 0; p += 2;        /* end char */
714         p[0] = p[1] = 0; p += 2;        /* default font id */
715
716         *p++ = 0;                       /* font style flags */
717         *p++ = 12;                      /* font size */
718
719         p[0] = p[1] = p[2] = 0x00; p+=3;/* foreground rgb */
720         *p++ = 0x00;                    /* foreground a */
721
722         p[0] = p[1] = p[2] = 0; p[3] = 22; p += 4;
723         memcpy( p, "ftab", 4 ); p += 4;
724         *p++ = 0; *p++ = 1;             /* entry count */
725         p[0] = p[1] = 0; p += 2;        /* font id */
726         *p++ = 9;                       /* font name length */
727         memcpy( p, "Helvetica", 9 );    /* font name */
728     }
729
730     /* Init pes chain */
731     BufferChainInit( &p_stream->chain_pes );
732     p_stream->i_pes_dts    = 0;
733     p_stream->i_pes_length = 0;
734     p_stream->i_pes_used   = 0;
735     p_stream->b_key_frame  = 0;
736
737     /* We only change PMT version (PAT isn't changed) */
738     p_sys->i_pmt_version_number = ( p_sys->i_pmt_version_number + 1 )%32;
739
740     /* Update pcr_pid */
741     if( p_input->p_fmt->i_cat != SPU_ES &&
742         ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) )
743     {
744         if( p_sys->p_pcr_input )
745         {
746             /* There was already a PCR stream, so clean context */
747             /* FIXME */
748         }
749         p_sys->i_pcr_pid   = p_stream->i_pid;
750         p_sys->p_pcr_input = p_input;
751
752         msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
753     }
754
755     return VLC_SUCCESS;
756 }
757
758 /*****************************************************************************
759  * DelStream: called before a stream deletion
760  *****************************************************************************/
761 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
762 {
763     sout_mux_sys_t  *p_sys = p_mux->p_sys;
764     ts_stream_t     *p_stream;
765     vlc_value_t     val;
766
767     p_stream = (ts_stream_t*)p_input->p_sys;
768     msg_Dbg( p_mux, "removing input pid=%d", p_stream->i_pid );
769
770     if( p_sys->i_pcr_pid == p_stream->i_pid )
771     {
772         int i;
773
774         /* Find a new pcr stream (Prefer Video Stream) */
775         p_sys->i_pcr_pid = 0x1fff;
776         p_sys->p_pcr_input = NULL;
777         for( i = 0; i < p_mux->i_nb_inputs; i++ )
778         {
779             if( p_mux->pp_inputs[i] == p_input )
780             {
781                 continue;
782             }
783
784             if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
785             {
786                 p_sys->i_pcr_pid  =
787                     ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
788                 p_sys->p_pcr_input= p_mux->pp_inputs[i];
789                 break;
790             }
791             else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
792                      p_sys->i_pcr_pid == 0x1fff )
793             {
794                 p_sys->i_pcr_pid  =
795                     ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
796                 p_sys->p_pcr_input= p_mux->pp_inputs[i];
797             }
798         }
799         if( p_sys->p_pcr_input )
800         {
801             /* Empty TS buffer */
802             /* FIXME */
803         }
804         msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
805     }
806
807     /* Empty all data in chain_pes */
808     BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
809
810     if( p_stream->p_decoder_specific_info )
811     {
812         free( p_stream->p_decoder_specific_info );
813     }
814     if( p_stream->i_stream_id == 0xfa ||
815         p_stream->i_stream_id == 0xfb ||
816         p_stream->i_stream_id == 0xfe )
817     {
818         p_sys->i_mpeg4_streams--;
819     }
820
821     var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );
822     if( val.i_int > 0 )
823     {
824         int i_pid_video = val.i_int;
825         if ( i_pid_video == p_stream->i_pid )
826         {
827             p_sys->i_pid_video = i_pid_video;
828             msg_Dbg( p_mux, "freeing video PID %d", i_pid_video );
829         }
830     }
831     var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );
832     if( val.i_int > 0 )
833     {
834         int i_pid_audio = val.i_int;
835         if ( i_pid_audio == p_stream->i_pid )
836         {
837             p_sys->i_pid_audio = i_pid_audio;
838             msg_Dbg( p_mux, "freeing audio PID %d", i_pid_audio );
839         }
840     }
841     free( p_stream );
842
843     /* We only change PMT version (PAT isn't changed) */
844     p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
845
846     return VLC_SUCCESS;
847 }
848
849 /*****************************************************************************
850  * Mux: Call each time there is new data for at least one stream
851  *****************************************************************************
852  *
853  *****************************************************************************/
854 static int Mux( sout_mux_t *p_mux )
855 {
856     sout_mux_sys_t  *p_sys = p_mux->p_sys;
857     ts_stream_t     *p_pcr_stream;
858
859     if( p_sys->i_pcr_pid == 0x1fff )
860     {
861         msg_Dbg( p_mux, "waiting for PCR streams" );
862         msleep( 1000 );
863         return VLC_SUCCESS;
864     }
865     p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
866
867     for( ;; )
868     {
869         sout_buffer_chain_t chain_ts;
870         int                 i_packet_count;
871         int                 i_packet_pos;
872         mtime_t             i_pcr_dts;
873         mtime_t             i_pcr_length;
874         mtime_t             i_shaping_delay;
875         int i;
876
877         if( p_pcr_stream->b_key_frame )
878         {
879             i_shaping_delay = p_pcr_stream->i_pes_length;
880         }
881         else
882         {
883             i_shaping_delay = p_sys->i_shaping_delay;
884         }
885
886         /* 1: get enough PES packet for all input */
887         for( ;; )
888         {
889             vlc_bool_t b_ok = VLC_TRUE;
890             block_t *p_data;
891
892             /* Accumulate enough data in the pcr stream (>i_shaping_delay) */
893             /* Accumulate enough data in all other stream ( >= length of pcr) */
894             for( i = 0; i < p_mux->i_nb_inputs; i++ )
895             {
896                 sout_input_t *p_input = p_mux->pp_inputs[i];
897                 ts_stream_t *p_stream = (ts_stream_t*)p_input->p_sys;
898                 int64_t i_spu_length = 0;
899                 int64_t i_spu_dts    = 0;
900
901
902                 if( ( p_stream == p_pcr_stream
903                             && p_stream->i_pes_length < i_shaping_delay ) ||
904                     p_stream->i_pes_dts + p_stream->i_pes_length
905                         < p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
906                 {
907                     /* Need more data */
908                     if( p_input->p_fifo->i_depth <= 50 )
909                     {
910                         if( p_input->p_fmt->i_cat == AUDIO_ES ||
911                             p_input->p_fmt->i_cat == VIDEO_ES )
912                         {
913                             /* We need more data */
914                             return VLC_SUCCESS;
915                         }
916                         else if( p_input->p_fifo->i_depth <= 0 )
917                         {
918                             /* spu, only one packet is needed */
919                             continue;
920                         }
921                     }
922                     b_ok = VLC_FALSE;
923
924                     p_data = block_FifoGet( p_input->p_fifo );
925                     if( p_input->p_fmt->i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) )
926                     {
927                         i_spu_length = p_data->i_length;    /* save info for SPU */
928                         i_spu_dts    = p_data->i_dts;
929                     }
930                     if( p_input->p_fifo->i_depth > 0 )
931                     {
932                         block_t *p_next = block_FifoShow( p_input->p_fifo );
933
934                         p_data->i_length = p_next->i_dts - p_data->i_dts;
935                     }
936
937                     if( ( p_pcr_stream->i_pes_dts > 0 && p_data->i_dts - 2000000 > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length ) ||
938                         p_data->i_dts < p_stream->i_pes_dts ||
939                         ( p_stream->i_pes_dts > 0 && p_input->p_fmt->i_cat != SPU_ES && p_data->i_dts - 2000000 > p_stream->i_pes_dts + p_stream->i_pes_length ) )
940                     {
941                         msg_Warn( p_mux, "packet with too strange dts (dts=%lld,old=%lld,pcr=%lld)",
942                                   p_data->i_dts,
943                                   p_stream->i_pes_dts,
944                                   p_pcr_stream->i_pes_dts );
945                         block_Release( p_data );
946
947                         BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
948                         p_stream->i_pes_dts = 0;
949                         p_stream->i_pes_used = 0;
950                         p_stream->i_pes_length = 0;
951
952                         BufferChainClean( p_mux->p_sout, &p_pcr_stream->chain_pes );
953                         p_pcr_stream->i_pes_dts = 0;
954                         p_pcr_stream->i_pes_used = 0;
955                         p_pcr_stream->i_pes_length = 0;
956
957                     }
958                     else
959                     {
960                         if( p_input->p_fmt->i_cat == SPU_ES )
961                         {
962                             /* Arbitrary */
963                             p_data->i_length = 1000;
964                             if( p_input->p_fmt->i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) )
965                             {
966                                 /* Prepend header */
967                                 p_data = block_Realloc( p_data, 2, p_data->i_buffer );
968                                 p_data->p_buffer[0] = ( (p_data->i_buffer - 2) >> 8)&0xff;
969                                 p_data->p_buffer[1] = ( (p_data->i_buffer - 2)     )&0xff;
970
971                                 /* remove trailling \0 if any */
972                                 if( p_data->i_buffer > 2 && p_data->p_buffer[p_data->i_buffer -1] == '\0' )
973                                     p_data->i_buffer--;
974                             }
975                         }
976                         else if( p_data->i_length < 0 || p_data->i_length > 2000000 )
977                         {
978                             /* FIXME choose a better value, but anyway we should never
979                              * have to do that */
980                             p_data->i_length = 1000;
981                         }
982
983                         p_stream->i_pes_length += p_data->i_length;
984                         if( p_stream->i_pes_dts == 0 )
985                         {
986                             p_stream->i_pes_dts = p_data->i_dts;
987                         }
988
989                         /* Convert to pes */
990                         if( p_stream->i_stream_id == 0xa0 && p_data->i_pts <= 0 )
991                         {
992                             /* XXX yes I know, it's awfull, but it's needed, so don't remove it ... */
993                             p_data->i_pts = p_data->i_dts;
994                         }
995                         E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 );
996
997                         BufferChainAppend( &p_stream->chain_pes, p_data );
998
999                         if( p_sys->b_use_key_frames && p_stream == p_pcr_stream
1000                             && (p_data->i_flags & BLOCK_FLAG_TYPE_I )
1001                             && (p_stream->i_pes_length > 300000) )
1002                         {
1003                             i_shaping_delay = p_stream->i_pes_length;
1004                             p_stream->b_key_frame = 1;
1005                         }
1006
1007                         /* Append a empty sub (sub text only) */
1008                         if( i_spu_length > 0 )
1009                         {
1010                             block_t *p_spu = block_New( p_mux, 3 );
1011
1012                             p_spu->i_dts = p_spu->i_pts = i_spu_dts + i_spu_length;
1013                             p_spu->i_length = 1000;
1014
1015                             p_spu->p_buffer[0] = 0;
1016                             p_spu->p_buffer[1] = 1;
1017                             p_spu->p_buffer[2] = ' ';
1018
1019                             p_stream->i_pes_length += p_spu->i_length;
1020                             E_( EStoPES )( p_mux->p_sout, &p_spu, p_spu, p_stream->i_stream_id, 1 );
1021                             BufferChainAppend( &p_stream->chain_pes, p_spu );
1022                         }
1023                     }
1024                 }
1025             }
1026
1027             if( b_ok )
1028             {
1029                 break;
1030             }
1031         }
1032
1033         /* save */
1034         i_pcr_dts      = p_pcr_stream->i_pes_dts;
1035         i_pcr_length   = p_pcr_stream->i_pes_length;
1036         p_pcr_stream->b_key_frame = 0;
1037
1038         /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
1039         /* 2: calculate non accurate total size of muxed ts */
1040         i_packet_count = 0;
1041         for( i = 0; i < p_mux->i_nb_inputs; i++ )
1042         {
1043             ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
1044             block_t *p_pes;
1045
1046             /* False for pcr stream but it will be enough to do PCR algo */
1047             for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL; p_pes = p_pes->p_next )
1048             {
1049                 int i_size = p_pes->i_buffer;
1050                 if( p_pes->i_dts + p_pes->i_length > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
1051                 {
1052                     mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts;
1053                     if( i_frag < 0 )
1054                     {
1055                         /* Next stream */
1056                         break;
1057                     }
1058                     i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
1059                 }
1060                 i_packet_count += ( i_size + 183 ) / 184;
1061             }
1062         }
1063         /* add overhead for PCR (not really exact) */
1064         i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176;
1065
1066
1067         /* 3: mux PES into TS */
1068         BufferChainInit( &chain_ts );
1069         /* append PAT/PMT  -> FIXME with big pcr delay it won't have enough pat/pmt */
1070         GetPAT( p_mux, &chain_ts);
1071         GetPMT( p_mux, &chain_ts );
1072         i_packet_pos = 0;
1073         i_packet_count += chain_ts.i_depth;
1074         /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
1075
1076         for( ;; )
1077         {
1078             int         i_stream;
1079             mtime_t     i_dts;
1080             ts_stream_t *p_stream;
1081             sout_input_t *p_input;
1082             block_t *p_ts;
1083             vlc_bool_t   b_pcr;
1084
1085             /* Select stream (lowest dts) */
1086             for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
1087             {
1088                 p_input = p_mux->pp_inputs[i];
1089                 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
1090
1091                 if( p_stream->i_pes_dts == 0 )
1092                 {
1093                     continue;
1094                 }
1095
1096                 if( i_stream == -1 ||
1097                     p_stream->i_pes_dts < i_dts )
1098                 {
1099                     i_stream = i;
1100                     i_dts = p_stream->i_pes_dts;
1101                 }
1102             }
1103             if( i_stream == -1 || i_dts > i_pcr_dts + i_pcr_length )
1104             {
1105                 break;
1106             }
1107             p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1108
1109             /* do we need to issue pcr */
1110             b_pcr = VLC_FALSE;
1111             if( p_stream == p_pcr_stream &&
1112                 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >= p_sys->i_pcr + p_sys->i_pcr_delay )
1113             {
1114                 b_pcr = VLC_TRUE;
1115                 p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count;
1116             }
1117
1118             /* Build the TS packet */
1119             p_ts = TSNew( p_mux, p_stream, b_pcr );
1120             if( p_sys->csa != NULL &&
1121                  (p_input->p_fmt->i_cat != AUDIO_ES || p_sys->b_crypt_audio) )
1122             {
1123                 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
1124             }
1125             i_packet_pos++;
1126
1127             /* */
1128             BufferChainAppend( &chain_ts, p_ts );
1129         }
1130
1131         /* 4: date and send */
1132         TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
1133     }
1134 }
1135
1136 static void TSSchedule( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1137                         mtime_t i_pcr_length, mtime_t i_pcr_dts )
1138 {
1139     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1140     sout_buffer_chain_t new_chain;
1141     int i_packet_count = p_chain_ts->i_depth;
1142     int i;
1143
1144     BufferChainInit( &new_chain );
1145
1146     if ( i_pcr_length <= 0 )
1147     {
1148         i_pcr_length = i_packet_count;
1149     }
1150
1151     for( i = 0; i < i_packet_count; i++ )
1152     {
1153         block_t *p_ts = BufferChainGet( p_chain_ts );
1154         mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1155
1156         BufferChainAppend( &new_chain, p_ts );
1157
1158         if( p_ts->i_dts &&
1159             p_ts->i_dts + p_sys->i_dts_delay * 2/3 < i_new_dts )
1160         {
1161             mtime_t i_max_diff = i_new_dts - p_ts->i_dts;
1162             mtime_t i_cut_dts = p_ts->i_dts;
1163
1164             p_ts = BufferChainPeek( p_chain_ts );
1165             i++;
1166             i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1167             while ( p_ts != NULL && i_new_dts - p_ts->i_dts >= i_max_diff )
1168             {
1169                 p_ts = BufferChainGet( p_chain_ts );
1170                 i_max_diff = i_new_dts - p_ts->i_dts;
1171                 i_cut_dts = p_ts->i_dts;
1172                 BufferChainAppend( &new_chain, p_ts );
1173
1174                 p_ts = BufferChainPeek( p_chain_ts );
1175                 i++;
1176                 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1177             }
1178             msg_Dbg( p_mux, "adjusting rate at "I64Fd"/"I64Fd" (%d/%d)",
1179                      i_cut_dts - i_pcr_dts, i_pcr_length, new_chain.i_depth,
1180                      p_chain_ts->i_depth );
1181             if ( new_chain.i_depth )
1182                 TSDate( p_mux, &new_chain,
1183                         i_cut_dts - i_pcr_dts,
1184                         i_pcr_dts );
1185             if ( p_chain_ts->i_depth )
1186                 TSSchedule( p_mux,
1187                             p_chain_ts, i_pcr_dts + i_pcr_length - i_cut_dts,
1188                             i_cut_dts );
1189             return;
1190         }
1191     }
1192
1193     if ( new_chain.i_depth )
1194         TSDate( p_mux, &new_chain, i_pcr_length, i_pcr_dts );
1195 }
1196
1197 static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1198                     mtime_t i_pcr_length, mtime_t i_pcr_dts )
1199 {
1200     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1201     int i_packet_count = p_chain_ts->i_depth;
1202     int i;
1203
1204     if ( i_pcr_length / 1000 > 0 )
1205     {
1206         int i_bitrate = ((uint64_t)i_packet_count * 188 * 8000)
1207                           / (uint64_t)(i_pcr_length / 1000);
1208         if ( p_sys->i_bitrate_max && p_sys->i_bitrate_max < i_bitrate )
1209         {
1210             msg_Warn( p_mux,
1211                 "max bitrate exceeded at %lld (%d bi/s for %d pkt in %lld us)",
1212                 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1213                 i_bitrate, i_packet_count, i_pcr_length);
1214         }
1215 #if 0
1216         else
1217         {
1218             msg_Dbg( p_mux,
1219                 "starting at %lld (%d bi/s for %d packets in %lld us)",
1220                 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1221                 i_bitrate, i_packet_count, i_pcr_length);
1222         }
1223 #endif
1224     }
1225     else
1226     {
1227         /* This shouldn't happen, but happens in some rare heavy load
1228          * and packet losses conditions. */
1229         i_pcr_length = i_packet_count;
1230     }
1231
1232     /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
1233     for( i = 0; i < i_packet_count; i++ )
1234     {
1235         block_t *p_ts = BufferChainGet( p_chain_ts );
1236         mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1237
1238         p_ts->i_dts    = i_new_dts;
1239         p_ts->i_length = i_pcr_length / i_packet_count;
1240
1241         if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_PCR )
1242         {
1243             /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
1244             TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
1245         }
1246         if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_CSA )
1247         {
1248             csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
1249         }
1250
1251         /* latency */
1252         p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
1253
1254         sout_AccessOutWrite( p_mux->p_access, p_ts );
1255     }
1256 }
1257
1258 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr )
1259 {
1260     block_t *p_pes = p_stream->chain_pes.p_first;
1261     block_t *p_ts;
1262
1263     vlc_bool_t b_new_pes = VLC_FALSE;
1264     vlc_bool_t b_adaptation_field = VLC_FALSE;
1265
1266     int        i_payload_max = 184 - ( b_pcr ? 8 : 0 );
1267     int        i_payload;
1268
1269     if( p_stream->i_pes_used <= 0 )
1270     {
1271         b_new_pes = VLC_TRUE;
1272     }
1273     i_payload = __MIN( (int)p_pes->i_buffer - p_stream->i_pes_used, i_payload_max );
1274
1275     if( b_pcr || i_payload < i_payload_max )
1276     {
1277         b_adaptation_field = VLC_TRUE;
1278     }
1279
1280     p_ts = block_New( p_mux, 188 );
1281     p_ts->i_dts = p_pes->i_dts;
1282
1283     p_ts->p_buffer[0] = 0x47;
1284     p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|( ( p_stream->i_pid >> 8 )&0x1f );
1285     p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1286     p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|p_stream->i_continuity_counter;
1287
1288     p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1289
1290     if( b_adaptation_field )
1291     {
1292         int i;
1293
1294         if( b_pcr )
1295         {
1296             int     i_stuffing = i_payload_max - i_payload;
1297
1298             p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
1299
1300             p_ts->p_buffer[4] = 7 + i_stuffing;
1301             p_ts->p_buffer[5] = 0x10;   /* flags */
1302             p_ts->p_buffer[6] = ( 0 )&0xff;
1303             p_ts->p_buffer[7] = ( 0 )&0xff;
1304             p_ts->p_buffer[8] = ( 0 )&0xff;
1305             p_ts->p_buffer[9] = ( 0 )&0xff;
1306             p_ts->p_buffer[10]= ( 0 )&0x80;
1307             p_ts->p_buffer[11]= 0;
1308
1309             for( i = 12; i < 12 + i_stuffing; i++ )
1310             {
1311                 p_ts->p_buffer[i] = 0xff;
1312             }
1313         }
1314         else
1315         {
1316             int i_stuffing = i_payload_max - i_payload;
1317
1318             p_ts->p_buffer[4] = i_stuffing - 1;
1319             if( i_stuffing > 1 )
1320             {
1321                 p_ts->p_buffer[5] = 0x00;
1322                 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1323                 {
1324                     p_ts->p_buffer[i] = 0xff;
1325                 }
1326             }
1327         }
1328     }
1329
1330     /* copy payload */
1331     memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
1332
1333     p_stream->i_pes_used += i_payload;
1334     p_stream->i_pes_dts      = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_buffer;
1335     p_stream->i_pes_length  -= p_pes->i_length * i_payload / p_pes->i_buffer;
1336
1337     if( p_stream->i_pes_used >= (int)p_pes->i_buffer )
1338     {
1339         p_pes = BufferChainGet( &p_stream->chain_pes );
1340         block_Release( p_pes );
1341
1342         p_pes = p_stream->chain_pes.p_first;
1343         if( p_pes )
1344         {
1345             p_stream->i_pes_dts    = p_pes->i_dts;
1346             p_stream->i_pes_length = 0;
1347             while( p_pes )
1348             {
1349                 p_stream->i_pes_length += p_pes->i_length;
1350
1351                 p_pes = p_pes->p_next;
1352             }
1353         }
1354         else
1355         {
1356             p_stream->i_pes_dts = 0;
1357             p_stream->i_pes_length = 0;
1358         }
1359         p_stream->i_pes_used = 0;
1360     }
1361
1362     return p_ts;
1363 }
1364
1365
1366 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
1367 {
1368     mtime_t i_pcr = 9 * i_dts / 100;
1369
1370     p_ts->p_buffer[6]  = ( i_pcr >> 25 )&0xff;
1371     p_ts->p_buffer[7]  = ( i_pcr >> 17 )&0xff;
1372     p_ts->p_buffer[8]  = ( i_pcr >> 9  )&0xff;
1373     p_ts->p_buffer[9]  = ( i_pcr >> 1  )&0xff;
1374     p_ts->p_buffer[10]|= ( i_pcr << 7  )&0x80;
1375 }
1376
1377 #if 0
1378 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 )
1379 {
1380     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1381     sout_buffer_chain_t s = *c;
1382
1383     int i_packets = 0;
1384     int i_packets_min = 0;
1385     int i_packets_max = 0;
1386
1387     if( i_length <= 0 )
1388     {
1389         return;
1390     }
1391
1392     i_packets     = c->i_depth;
1393     i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000  + 187 ) / 188;
1394     i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000  + 187 ) / 188;
1395
1396     if( i_packets < i_packets_min && i_packets_min > 0 )
1397     {
1398         block_t *p_pk;
1399         int i_div = ( i_packets_min - i_packets ) / i_packets;
1400         int i_mod = ( i_packets_min - i_packets ) % i_packets;
1401         int i_rest = 0;
1402
1403         /* We need to pad with null packets (pid=0x1fff)
1404          * We try to melt null packets with true packets */
1405         msg_Dbg( p_mux,
1406                  "packets=%d but min=%d -> adding %d packets of padding",
1407                  i_packets, i_packets_min, i_packets_min - i_packets );
1408
1409         BufferChainInit( c );
1410         while( ( p_pk = BufferChainGet( &s ) ) )
1411         {
1412             int i, i_null;
1413
1414             BufferChainAppend( c, p_pk );
1415
1416             i_null = i_div + ( i_rest + i_mod ) / i_packets;
1417
1418             for( i = 0; i < i_null; i++ )
1419             {
1420                 block_t *p_null;
1421
1422                 p_null = sout_BufferNew( p_mux->p_sout, 188 );
1423                 p_null->p_buffer[0] = 0x47;
1424                 p_null->p_buffer[1] = 0x1f;
1425                 p_null->p_buffer[2] = 0xff;
1426                 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
1427                 memset( &p_null->p_buffer[4], 0, 184 );
1428                 p_sys->i_null_continuity_counter =
1429                     ( p_sys->i_null_continuity_counter + 1 ) % 16;
1430
1431                 BufferChainAppend( c, p_null );
1432             }
1433
1434             i_rest = ( i_rest + i_mod ) % i_packets;
1435         }
1436     }
1437     else if( i_packets > i_packets_max && i_packets_max > 0 )
1438     {
1439         block_t *p_pk;
1440         int           i;
1441
1442         /* Arg, we need to drop packets, I don't do something clever (like
1443          * dropping complete pid, b frames, ... ), I just get the right amount
1444          * of packets and discard the others */
1445         msg_Warn( p_mux,
1446                   "packets=%d but max=%d -> removing %d packets -> stream broken",
1447                   i_packets, i_packets_max, i_packets - i_packets_max );
1448
1449         BufferChainInit( c );
1450         for( i = 0; i < i_packets_max; i++ )
1451         {
1452             BufferChainAppend( c, BufferChainGet( &s ) );
1453         }
1454
1455         while( ( p_pk = BufferChainGet( &s ) ) )
1456         {
1457             sout_BufferDelete( p_mux->p_sout, p_pk );
1458         }
1459     }
1460 }
1461 #endif
1462
1463 static void PEStoTS( sout_instance_t *p_sout,
1464                      sout_buffer_chain_t *c, block_t *p_pes,
1465                      ts_stream_t *p_stream )
1466 {
1467     uint8_t *p_data;
1468     int     i_size;
1469     int     b_new_pes;
1470
1471     /* get PES total size */
1472     i_size = p_pes->i_buffer;
1473     p_data = p_pes->p_buffer;
1474
1475     b_new_pes = VLC_TRUE;
1476
1477     for( ;; )
1478     {
1479         int           b_adaptation_field;
1480         int           i_copy;
1481         block_t *p_ts;
1482
1483         p_ts = block_New( p_sout, 188 );
1484         /* write header
1485          * 8b   0x47    sync byte
1486          * 1b           transport_error_indicator
1487          * 1b           payload_unit_start
1488          * 1b           transport_priority
1489          * 13b          pid
1490          * 2b           transport_scrambling_control
1491          * 2b           if adaptation_field 0x03 else 0x01
1492          * 4b           continuity_counter
1493          */
1494
1495         i_copy    = __MIN( i_size, 184 );
1496         b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
1497
1498         p_ts->p_buffer[0] = 0x47;
1499         p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
1500                             ( ( p_stream->i_pid >> 8 )&0x1f );
1501         p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1502         p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
1503                             p_stream->i_continuity_counter;
1504
1505         b_new_pes = VLC_FALSE;
1506         p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1507
1508         if( b_adaptation_field )
1509         {
1510             int i_stuffing = 184 - i_copy;
1511             int i;
1512
1513             p_ts->p_buffer[4] = i_stuffing - 1;
1514             if( i_stuffing > 1 )
1515             {
1516                 p_ts->p_buffer[5] = 0x00;
1517                 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1518                 {
1519                     p_ts->p_buffer[i] = 0xff;
1520                 }
1521             }
1522         }
1523         /* copy payload */
1524         memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1525         p_data += i_copy;
1526         i_size -= i_copy;
1527
1528         BufferChainAppend( c, p_ts );
1529
1530         if( i_size <= 0 )
1531         {
1532             block_t *p_next = p_pes->p_next;
1533
1534             p_pes->p_next = NULL;
1535             block_Release( p_pes );
1536             if( p_next == NULL )
1537             {
1538                 break;
1539             }
1540             b_new_pes = VLC_TRUE;
1541             p_pes = p_next;
1542             i_size = p_pes->i_buffer;
1543             p_data = p_pes->p_buffer;
1544         }
1545     }
1546
1547     return;
1548 }
1549
1550 #if defined MODULE_NAME_IS_mux_ts
1551 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1552 {
1553     static uint32_t CRC32[256] =
1554     {
1555         0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1556         0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1557         0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1558         0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1559         0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1560         0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1561         0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1562         0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1563         0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1564         0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1565         0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1566         0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1567         0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1568         0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1569         0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1570         0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1571         0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1572         0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1573         0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1574         0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1575         0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1576         0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1577         0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1578         0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1579         0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1580         0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1581         0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1582         0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1583         0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1584         0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1585         0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1586         0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1587         0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1588         0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1589         0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1590         0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1591         0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1592         0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1593         0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1594         0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1595         0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1596         0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1597         0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1598         0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1599         0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1600         0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1601         0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1602         0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1603         0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1604         0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1605         0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1606         0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1607         0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1608         0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1609         0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1610         0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1611         0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1612         0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1613         0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1614         0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1615         0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1616         0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1617         0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1618         0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1619     };
1620
1621     uint32_t i_crc = 0xffffffff;
1622
1623     /* Calculate the CRC */
1624     while( i_count > 0 )
1625     {
1626         i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1627         p_begin++;
1628         i_count--;
1629     }
1630
1631     return( i_crc );
1632 }
1633
1634 static void GetPAT( sout_mux_t *p_mux,
1635                     sout_buffer_chain_t *c )
1636 {
1637     sout_mux_sys_t      *p_sys = p_mux->p_sys;
1638     block_t       *p_pat;
1639     bits_buffer_t bits;
1640
1641     p_pat = block_New( p_mux, 1024 );
1642
1643     p_pat->i_pts = 0;
1644     p_pat->i_dts = 0;
1645     p_pat->i_length = 0;
1646
1647     bits_initwrite( &bits, 1024, p_pat->p_buffer );
1648
1649     bits_write( &bits, 8, 0 );      // pointer
1650     bits_write( &bits, 8, 0x00 );   // table id
1651     bits_write( &bits, 1,  1 );     // section_syntax_indicator
1652     bits_write( &bits, 1,  0 );     // 0
1653     bits_write( &bits, 2,  0x03 );     // reserved FIXME
1654     bits_write( &bits, 12, 13 );    // XXX for one program only XXX 
1655     bits_write( &bits, 16, 0x01 );  // FIXME stream id
1656     bits_write( &bits, 2,  0x03 );     //  FIXME
1657     bits_write( &bits, 5,  p_sys->i_pat_version_number );
1658     bits_write( &bits, 1,  1 );     // current_next_indicator
1659     bits_write( &bits, 8,  0 );     // section number
1660     bits_write( &bits, 8,  0 );     // last section number
1661
1662     bits_write( &bits, 16, 1 );     // program number
1663     bits_write( &bits,  3, 0x07 );     // reserved
1664     bits_write( &bits, 13, p_sys->pmt.i_pid );  // program map pid
1665
1666     bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1667
1668     p_pat->i_buffer = bits.i_data;
1669
1670     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1671 }
1672
1673 static void GetPMT( sout_mux_t *p_mux,
1674                     sout_buffer_chain_t *c )
1675 {
1676     sout_mux_sys_t      *p_sys = p_mux->p_sys;
1677     block_t       *p_pmt;
1678     bits_buffer_t bits;
1679     int           i_stream;
1680
1681     p_pmt = block_New( p_mux, 1024 );
1682
1683     p_pmt->i_pts = 0;
1684     p_pmt->i_dts = 0;
1685     p_pmt->i_length = 0;
1686
1687     bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1688
1689     bits_write( &bits, 8, 0 );      // pointer
1690     bits_write( &bits, 8, 0x02 );   // table id
1691     bits_write( &bits, 1,  1 );     // section_syntax_indicator
1692     bits_write( &bits, 1,  0 );     // 0
1693     bits_write( &bits, 2,  0 );     // reserved FIXME
1694     bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1695     bits_write( &bits, 16, 1 );     // FIXME program number
1696     bits_write( &bits, 2,  0 );     //  FIXME
1697     bits_write( &bits, 5,  p_sys->i_pmt_version_number );
1698     bits_write( &bits, 1,  1 );     // current_next_indicator
1699     bits_write( &bits, 8,  0 );     // section number
1700     bits_write( &bits, 8,  0 );     // last section number
1701
1702     bits_write( &bits,  3, 0 );     // reserved
1703
1704     bits_write( &bits, 13, p_sys->i_pcr_pid );     //  FIXME FXIME PCR_PID FIXME
1705     bits_write( &bits,  4, 0 );     // reserved FIXME
1706
1707     bits_write( &bits, 12, 0 );    // program info len FIXME
1708
1709     for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1710     {
1711         ts_stream_t *p_stream;
1712
1713         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1714
1715         bits_write( &bits,  8, p_stream->i_stream_type ); // stream_type
1716         bits_write( &bits,  3, 0 );                 // reserved
1717         bits_write( &bits, 13, p_stream->i_pid );   // es pid
1718         bits_write( &bits,  4, 0 );                 //reserved
1719         bits_write( &bits, 12, 0 );                 // es info len FIXME
1720     }
1721
1722     bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1723
1724     p_pmt->i_buffer = bits.i_data;
1725
1726     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1727 }
1728 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1729
1730 static block_t *WritePSISection( sout_instance_t *p_sout,
1731                                        dvbpsi_psi_section_t* p_section )
1732 {
1733     block_t   *p_psi, *p_first = NULL;
1734
1735
1736     while( p_section )
1737     {
1738         int             i_size;
1739
1740         i_size =  (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1741                   ( p_section->b_syntax_indicator ? 4 : 0 );
1742
1743         p_psi = block_New( p_sout, i_size + 1 );
1744         p_psi->i_pts = 0;
1745         p_psi->i_dts = 0;
1746         p_psi->i_length = 0;
1747         p_psi->i_buffer = i_size + 1;
1748
1749         p_psi->p_buffer[0] = 0; // pointer
1750         memcpy( p_psi->p_buffer + 1,
1751                 p_section->p_data,
1752                 i_size );
1753
1754         block_ChainAppend( &p_first, p_psi );
1755
1756         p_section = p_section->p_next;
1757     }
1758
1759     return( p_first );
1760 }
1761
1762 static void GetPAT( sout_mux_t *p_mux,
1763                     sout_buffer_chain_t *c )
1764 {
1765     sout_mux_sys_t       *p_sys = p_mux->p_sys;
1766     block_t        *p_pat;
1767     dvbpsi_pat_t         pat;
1768     dvbpsi_psi_section_t *p_section;
1769
1770     dvbpsi_InitPAT( &pat,
1771                     0x01,    // i_ts_id
1772                     p_sys->i_pat_version_number,
1773                     1 );      // b_current_next
1774     /* add all program (only one) */
1775     dvbpsi_PATAddProgram( &pat,
1776                           1,                    // i_number
1777                           p_sys->pmt.i_pid );   // i_pid
1778
1779     p_section = dvbpsi_GenPATSections( &pat,
1780                                        0 );     // max program per section
1781
1782     p_pat = WritePSISection( p_mux->p_sout, p_section );
1783
1784     PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1785
1786     dvbpsi_DeletePSISections( p_section );
1787     dvbpsi_EmptyPAT( &pat );
1788 }
1789
1790 static uint32_t GetDescriptorLength24b( int i_length )
1791 {
1792     uint32_t    i_l1, i_l2, i_l3;
1793
1794     i_l1 = i_length&0x7f;
1795     i_l2 = ( i_length >> 7 )&0x7f;
1796     i_l3 = ( i_length >> 14 )&0x7f;
1797
1798     return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1799 }
1800
1801 static void GetPMT( sout_mux_t *p_mux,
1802                     sout_buffer_chain_t *c )
1803 {
1804     sout_mux_sys_t  *p_sys = p_mux->p_sys;
1805     block_t   *p_pmt;
1806
1807     dvbpsi_pmt_t        pmt;
1808     dvbpsi_pmt_es_t     *p_es;
1809     dvbpsi_psi_section_t *p_section;
1810
1811     int                 i_stream;
1812
1813     dvbpsi_InitPMT( &pmt,
1814                     0x01,   // program number
1815                     p_sys->i_pmt_version_number,
1816                     1,      // b_current_next
1817                     p_sys->i_pcr_pid );
1818
1819     if( p_sys->i_mpeg4_streams > 0 )
1820     {
1821         uint8_t iod[4096];
1822         bits_buffer_t bits;
1823         bits_buffer_t bits_fix_IOD;
1824
1825         /* Make valgrind happy : it works at byte level not bit one so
1826          * bit_write confuse it (but DON'T CHANGE the way that bit_write is
1827          * working (needed when fixing some bits) */
1828         memset( iod, 0, 4096 );
1829
1830         bits_initwrite( &bits, 4096, iod );
1831         // IOD_label
1832         bits_write( &bits, 8,   0x01 );
1833         // InitialObjectDescriptor
1834         bits_align( &bits );
1835         bits_write( &bits, 8,   0x02 );     // tag
1836         bits_fix_IOD = bits;    // save states to fix length later
1837         bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1838         bits_write( &bits, 10,  0x01 );     // ObjectDescriptorID
1839         bits_write( &bits, 1,   0x00 );     // URL Flag
1840         bits_write( &bits, 1,   0x00 );     // includeInlineProfileLevelFlag
1841         bits_write( &bits, 4,   0x0f );     // reserved
1842         bits_write( &bits, 8,   0xff );     // ODProfile (no ODcapability )
1843         bits_write( &bits, 8,   0xff );     // sceneProfile
1844         bits_write( &bits, 8,   0xfe );     // audioProfile (unspecified)
1845         bits_write( &bits, 8,   0xfe );     // visualProfile( // )
1846         bits_write( &bits, 8,   0xff );     // graphicProfile (no )
1847         for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1848         {
1849             ts_stream_t *p_stream;
1850             p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1851
1852             if( p_stream->i_stream_id == 0xfa ||
1853                 p_stream->i_stream_id == 0xfb ||
1854                 p_stream->i_stream_id == 0xfe )
1855             {
1856                 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1857                 /* ES descriptor */
1858                 bits_align( &bits );
1859                 bits_write( &bits, 8,   0x03 );     // ES_DescrTag
1860                 bits_fix_ESDescr = bits;
1861                 bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) ); // variable size
1862                 bits_write( &bits, 16,  p_stream->i_es_id );
1863                 bits_write( &bits, 1,   0x00 );     // streamDependency
1864                 bits_write( &bits, 1,   0x00 );     // URL Flag
1865                 bits_write( &bits, 1,   0x00 );     // OCRStreamFlag
1866                 bits_write( &bits, 5,   0x1f );     // streamPriority
1867
1868                     // DecoderConfigDesciptor
1869                 bits_align( &bits );
1870                 bits_write( &bits, 8,   0x04 ); // DecoderConfigDescrTag
1871                 bits_fix_Decoder = bits;
1872                 bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) );
1873                 if( p_stream->i_stream_type == 0x10 )
1874                 {
1875                     bits_write( &bits, 8, 0x20 );   // Visual 14496-2
1876                     bits_write( &bits, 6, 0x04 );   // VisualStream
1877                 }
1878                 else if( p_stream->i_stream_type == 0x11 )
1879                 {
1880                     bits_write( &bits, 8, 0x40 );   // Audio 14496-3
1881                     bits_write( &bits, 6, 0x05 );   // AudioStream
1882                 }
1883                 else if( p_stream->i_stream_type == 0x12 && p_stream->i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) )
1884                 {
1885                     bits_write( &bits, 8, 0x0B );   // Text Stream
1886                     bits_write( &bits, 6, 0x04 );   // VisualStream
1887                 }
1888                 else
1889                 {
1890                     bits_write( &bits, 8, 0x00 );
1891                     bits_write( &bits, 6, 0x00 );
1892
1893                     msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1894                 }
1895                 bits_write( &bits, 1,   0x00 );     // UpStream
1896                 bits_write( &bits, 1,   0x01 );     // reserved
1897                 bits_write( &bits, 24,  1024 * 1024 );  // bufferSizeDB
1898                 bits_write( &bits, 32,  0x7fffffff );   // maxBitrate
1899                 bits_write( &bits, 32,  0 );            // avgBitrate
1900
1901                 if( p_stream->i_decoder_specific_info > 0 )
1902                 {
1903                     int i;
1904                     // DecoderSpecificInfo
1905                     bits_align( &bits );
1906                     bits_write( &bits, 8,   0x05 ); // tag
1907                     bits_write( &bits, 24,
1908                                 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1909                     for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1910                     {
1911                         bits_write( &bits, 8,   ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1912                     }
1913                 }
1914                 /* fix Decoder length */
1915                 bits_write( &bits_fix_Decoder, 24,
1916                             GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1917
1918                 /* SLConfigDescriptor : predifined (0x01) */
1919                 bits_align( &bits );
1920                 bits_write( &bits, 8,   0x06 ); // tag
1921                 bits_write( &bits, 24,  GetDescriptorLength24b( 8 ) );
1922                 bits_write( &bits, 8,   0x01 ); // predefined
1923                 bits_write( &bits, 1,   0 );   // durationFlag
1924                 bits_write( &bits, 32,  0 );   // OCRResolution
1925                 bits_write( &bits, 8,   0 );   // OCRLength
1926                 bits_write( &bits, 8,   0 );   // InstantBitrateLength
1927                 bits_align( &bits );
1928
1929                 /* fix ESDescr length */
1930                 bits_write( &bits_fix_ESDescr, 24,
1931                             GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1932             }
1933         }
1934         bits_align( &bits );
1935         /* fix IOD length */
1936         bits_write( &bits_fix_IOD, 24,
1937                     GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1938         dvbpsi_PMTAddDescriptor( &pmt,
1939                                  0x1d,
1940                                  bits.i_data,
1941                                  bits.p_data );
1942     }
1943
1944     for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1945     {
1946         ts_stream_t *p_stream;
1947
1948         p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1949
1950         p_es = dvbpsi_PMTAddES( &pmt,
1951                                 p_stream->i_stream_type,
1952                                 p_stream->i_pid );
1953         if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1954         {
1955             uint8_t     es_id[2];
1956
1957             /* SL descriptor */
1958             es_id[0] = (p_stream->i_es_id >> 8)&0xff;
1959             es_id[1] = (p_stream->i_es_id)&0xff;
1960             dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
1961         }
1962         else if( p_stream->i_stream_type == 0xa0 )
1963         {
1964             uint8_t     data[512];
1965             int         i_extra = __MIN( p_stream->i_decoder_specific_info,
1966                                         502 );
1967
1968             /* private DIV3 descripor */
1969             memcpy( &data[0], &p_stream->i_bih_codec, 4 );
1970             data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
1971             data[5] = ( p_stream->i_bih_width      )&0xff;
1972             data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
1973             data[7] = ( p_stream->i_bih_height     )&0xff;
1974             data[8] = ( i_extra >> 8 )&0xff;
1975             data[9] = ( i_extra      )&0xff;
1976             if( i_extra > 0 )
1977             {
1978                 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1979             }
1980
1981             /* 0xa0 is private */
1982             dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra  + 10, data );
1983         }
1984         else if( p_stream->i_stream_type == 0x81 )
1985         {
1986             uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1987
1988             /* "registration" descriptor : "AC-3" */
1989             dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1990         }
1991
1992         if( p_stream->lang[0] != 0 )
1993         {
1994             uint8_t data[4];
1995
1996             /* I construct the content myself, way faster than looking at
1997              * over complicated/mind broken libdvbpsi way */
1998             data[0] = p_stream->lang[0];
1999             data[1] = p_stream->lang[1];
2000             data[2] = p_stream->lang[2];
2001             data[3] = 0x00; /* audio type: 0x00 undefined */
2002
2003             dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data );
2004         }
2005     }
2006
2007     p_section = dvbpsi_GenPMTSections( &pmt );
2008
2009     p_pmt = WritePSISection( p_mux->p_sout, p_section );
2010
2011     PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
2012
2013     dvbpsi_DeletePSISections( p_section );
2014     dvbpsi_EmptyPMT( &pmt );
2015 }
2016
2017 #endif
2018