1 /*****************************************************************************
2 * ts.c: MPEG-II TS Muxer
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Eric Petit <titer@videolan.org>
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.
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.
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 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
31 #include <vlc/input.h>
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>
50 # include "descriptor.h"
51 # include "tables/pat.h"
52 # include "tables/pmt.h"
53 # include "descriptors/dr.h"
60 * - check PCR frequency requirement
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)
66 * - remove creation of PAT/PMT without dvbpsi
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)
73 /*****************************************************************************
75 *****************************************************************************/
76 static int Open ( vlc_object_t * );
77 static void Close ( vlc_object_t * );
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.")
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.")
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)")
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.")
109 #define ACRYPT_TEXT N_("Crypt audio")
110 #define ACRYPT_LONGTEXT N_("Crypt audio using CSA")
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).")
116 #define SOUT_CFG_PREFIX "sout-ts-"
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" );
131 add_integer( SOUT_CFG_PREFIX "pid-video", 0, NULL,VPID_TEXT, VPID_LONGTEXT,
133 add_integer( SOUT_CFG_PREFIX "pid-audio", 0, NULL, APID_TEXT,
134 APID_LONGTEXT, VLC_TRUE );
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 );
141 add_integer( SOUT_CFG_PREFIX "pcr", 30, NULL, PCR_TEXT, PCR_LONGTEXT,
143 add_integer( SOUT_CFG_PREFIX "dts-delay", 200, NULL, DTS_TEXT,
144 DTS_LONGTEXT, VLC_TRUE );
146 add_bool( SOUT_CFG_PREFIX "crypt-audio", VLC_TRUE, NULL, ACRYPT_TEXT,
147 ACRYPT_LONGTEXT, VLC_TRUE );
149 add_string( SOUT_CFG_PREFIX "csa-ck", NULL, NULL, CK_TEXT, CK_LONGTEXT,
152 set_callbacks( Open, Close );
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
163 #define SOUT_BUFFER_FLAGS_PRIVATE_PCR ( 1 << BLOCK_FLAG_PRIVATE_SHIFT )
164 #define SOUT_BUFFER_FLAGS_PRIVATE_CSA ( 2 << BLOCK_FLAG_PRIVATE_SHIFT )
170 } sout_buffer_chain_t;
172 static inline void BufferChainInit ( sout_buffer_chain_t *c )
176 c->pp_last = &c->p_first;
178 static inline void BufferChainAppend( sout_buffer_chain_t *c, block_t *b )
188 c->pp_last = &b->p_next;
190 static inline block_t *BufferChainGet( sout_buffer_chain_t *c )
192 block_t *b = c->p_first;
197 c->p_first = b->p_next;
199 if( c->p_first == NULL )
201 c->pp_last = &c->p_first;
208 static inline block_t *BufferChainPeek( sout_buffer_chain_t *c )
210 block_t *b = c->p_first;
214 static inline void BufferChainClean( sout_instance_t *p_sout, sout_buffer_chain_t *c )
218 while( ( b = BufferChainGet( c ) ) )
222 BufferChainInit( c );
225 typedef struct ts_stream_t
230 int i_continuity_counter;
232 /* to be used for carriege of DIV3 */
233 vlc_fourcc_t i_bih_codec;
234 int i_bih_width, i_bih_height;
236 /* Specific to mpeg4 in mpeg2ts */
239 int i_decoder_specific_info;
240 uint8_t *p_decoder_specific_info;
242 /* language is iso639-2T */
245 sout_buffer_chain_t chain_pes;
247 mtime_t i_pes_length;
249 vlc_bool_t b_key_frame;
253 struct sout_mux_sys_t
256 sout_input_t *p_pcr_input;
263 int i_pid_free; // first usable pid
265 int i_pat_version_number;
268 int i_pmt_version_number;
269 ts_stream_t pmt; // Up to now only one program
273 int i_null_continuity_counter; /* Needed ? */
275 /* for TS building */
276 int64_t i_bitrate_min;
277 int64_t i_bitrate_max;
279 int64_t i_shaping_delay;
284 vlc_bool_t b_use_key_frames;
286 mtime_t i_pcr; /* last PCR emited */
289 vlc_bool_t b_crypt_audio;
293 /* Reserve a pid and return it */
294 static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
297 if ( i_cat == VIDEO_ES && p_sys->i_pid_video )
299 i_pid = p_sys->i_pid_video;
300 p_sys->i_pid_video = 0;
302 else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio )
304 i_pid = p_sys->i_pid_audio;
305 p_sys->i_pid_audio = 0;
309 i_pid = ++p_sys->i_pid_free;
314 /*****************************************************************************
316 *****************************************************************************/
317 static int Capability(sout_mux_t *, int, void *, void * );
318 static int AddStream( sout_mux_t *, sout_input_t * );
319 static int DelStream( sout_mux_t *, sout_input_t * );
320 static int Mux ( sout_mux_t * );
322 static void TSSchedule ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
323 mtime_t i_pcr_length, mtime_t i_pcr_dts );
324 static void TSDate ( 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 GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
327 static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
329 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr );
330 static void TSSetPCR( block_t *p_ts, mtime_t i_dts );
332 static void PEStoTS ( sout_instance_t *, sout_buffer_chain_t *, block_t *, ts_stream_t * );
334 /*****************************************************************************
336 *****************************************************************************/
337 static int Open( vlc_object_t *p_this )
339 sout_mux_t *p_mux =(sout_mux_t*)p_this;
340 sout_mux_sys_t *p_sys;
343 msg_Dbg( p_mux, "Open" );
344 sout_ParseCfg( p_mux, SOUT_CFG_PREFIX, ppsz_sout_options, p_mux->p_cfg );
346 p_sys = malloc( sizeof( sout_mux_sys_t ) );
348 p_mux->pf_capacity = Capability;
349 p_mux->pf_addstream = AddStream;
350 p_mux->pf_delstream = DelStream;
352 p_mux->p_sys = p_sys;
354 srand( (uint32_t)mdate() );
356 p_sys->i_audio_bound = 0;
357 p_sys->i_video_bound = 0;
359 p_sys->i_pat_version_number = rand() % 32;
360 p_sys->pat.i_pid = 0;
361 p_sys->pat.i_continuity_counter = 0;
363 p_sys->i_pmt_version_number = rand() % 32;
364 p_sys->pmt.i_pid = 0x42;
365 p_sys->pmt.i_continuity_counter = 0;
367 p_sys->i_pid_free = 0x43;
369 var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );
370 p_sys->i_pid_video = val.i_int;
371 if ( p_sys->i_pid_video > p_sys->i_pid_free )
373 p_sys->i_pid_free = p_sys->i_pid_video + 1;
376 var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );
377 p_sys->i_pid_audio = val.i_int;
378 if ( p_sys->i_pid_audio > p_sys->i_pid_free )
380 p_sys->i_pid_free = p_sys->i_pid_audio + 1;
383 p_sys->i_pcr_pid = 0x1fff;
384 p_sys->p_pcr_input = NULL;
386 p_sys->i_mpeg4_streams = 0;
388 p_sys->i_null_continuity_counter = 0;
390 /* Allow to create constrained stream */
391 var_Get( p_mux, SOUT_CFG_PREFIX "bmin", &val );
392 p_sys->i_bitrate_min = 0;/*val.i_int;*/
394 var_Get( p_mux, SOUT_CFG_PREFIX "bmax", &val );
395 p_sys->i_bitrate_max = 0;/*val.i_int;*/
397 if( p_sys->i_bitrate_min > 0 && p_sys->i_bitrate_max > 0 &&
398 p_sys->i_bitrate_min > p_sys->i_bitrate_max )
400 msg_Err( p_mux, "incompatible minimum and maximum bitrate, "
401 "disabling bitrate control" );
402 p_sys->i_bitrate_min = 0;
403 p_sys->i_bitrate_max = 0;
405 if( p_sys->i_bitrate_min > 0 || p_sys->i_bitrate_max > 0 )
407 msg_Err( p_mux, "bmin and bmax no more supported (if you need them report it)" );
410 var_Get( p_mux, SOUT_CFG_PREFIX "shaping", &val );
411 p_sys->i_shaping_delay = (int64_t)val.i_int * 1000;
412 if( p_sys->i_shaping_delay <= 0 )
415 "invalid shaping ("I64Fd"ms) reseting to 200ms",
416 p_sys->i_shaping_delay / 1000 );
417 p_sys->i_shaping_delay = 200000;
420 var_Get( p_mux, SOUT_CFG_PREFIX "pcr", &val );
421 p_sys->i_pcr_delay = (int64_t)val.i_int * 1000;
422 if( p_sys->i_pcr_delay <= 0 ||
423 p_sys->i_pcr_delay >= p_sys->i_shaping_delay )
426 "invalid pcr delay ("I64Fd"ms) reseting to 30ms",
427 p_sys->i_pcr_delay / 1000 );
428 p_sys->i_pcr_delay = 30000;
431 var_Get( p_mux, SOUT_CFG_PREFIX "dts-delay", &val );
432 p_sys->i_dts_delay = (int64_t)val.i_int * 1000;
434 msg_Dbg( p_mux, "shaping="I64Fd" pcr="I64Fd" dts_delay="I64Fd,
435 p_sys->i_shaping_delay, p_sys->i_pcr_delay, p_sys->i_dts_delay );
437 var_Get( p_mux, SOUT_CFG_PREFIX "use-key-frames", &val );
438 p_sys->b_use_key_frames = val.b_bool;
440 /* for TS generation */
444 var_Get( p_mux, SOUT_CFG_PREFIX "csa-ck", &val );
447 char *psz = val.psz_string;
450 if( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) )
454 if( strlen( psz ) != 16 )
456 msg_Dbg( p_mux, "invalid csa ck (it must be 16 chars long)" );
460 uint64_t i_ck = strtoll( psz, NULL, 16 );
464 for( i = 0; i < 8; i++ )
466 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
469 msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x",
470 ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
472 p_sys->csa = csa_New();
473 csa_SetCW( p_sys->csa, ck, ck );
476 if( val.psz_string ) free( val.psz_string );
478 var_Get( p_mux, SOUT_CFG_PREFIX "crypt-audio", &val );
479 p_sys->b_crypt_audio = val.b_bool;
484 /*****************************************************************************
486 *****************************************************************************/
487 static void Close( vlc_object_t * p_this )
489 sout_mux_t *p_mux = (sout_mux_t*)p_this;
490 sout_mux_sys_t *p_sys = p_mux->p_sys;
492 msg_Dbg( p_mux, "Close" );
495 csa_Delete( p_sys->csa );
501 /*****************************************************************************
503 *****************************************************************************/
504 static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
508 case SOUT_MUX_CAP_GET_ADD_STREAM_ANY_TIME:
509 *(vlc_bool_t*)p_answer = VLC_TRUE;
510 return( SOUT_MUX_CAP_ERR_OK );
512 return( SOUT_MUX_CAP_ERR_UNIMPLEMENTED );
516 /*****************************************************************************
517 * AddStream: called for each stream addition
518 *****************************************************************************/
519 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
521 sout_mux_sys_t *p_sys = p_mux->p_sys;
522 ts_stream_t *p_stream;
524 p_input->p_sys = p_stream = malloc( sizeof( ts_stream_t ) );
526 /* Init this new stream */
527 p_stream->i_pid = AllocatePID( p_sys, p_input->p_fmt->i_cat );
528 p_stream->i_continuity_counter = 0;
529 p_stream->i_decoder_specific_info = 0;
530 p_stream->p_decoder_specific_info = NULL;
532 msg_Dbg( p_mux, "adding input codec=%4.4s pid=%d", (char*)&p_input->p_fmt->i_codec, p_stream->i_pid );
534 /* All others fields depand on codec */
535 switch( p_input->p_fmt->i_cat )
538 switch( p_input->p_fmt->i_codec )
540 case VLC_FOURCC( 'm', 'p','g', 'v' ):
541 /* TODO: do we need to check MPEG-I/II ? */
542 p_stream->i_stream_type = 0x02;
543 p_stream->i_stream_id = 0xe0;
545 case VLC_FOURCC( 'm', 'p','4', 'v' ):
546 p_stream->i_stream_type = 0x10;
547 p_stream->i_stream_id = 0xfa;
548 p_sys->i_mpeg4_streams++;
549 p_stream->i_es_id = p_stream->i_pid;
551 case VLC_FOURCC( 'h', '2','6', '4' ):
552 p_stream->i_stream_type = 0x1b;
553 p_stream->i_stream_id = 0xe0;
555 /* XXX dirty dirty but somebody want that : using crapy MS-codec XXX */
556 /* I didn't want to do that :P */
557 case VLC_FOURCC( 'H', '2', '6', '3' ):
558 case VLC_FOURCC( 'I', '2', '6', '3' ):
559 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
560 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
561 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
562 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
563 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
564 case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
565 p_stream->i_stream_type = 0xa0; // private
566 p_stream->i_stream_id = 0xa0; // beurk
567 p_stream->i_bih_codec = p_input->p_fmt->i_codec;
568 p_stream->i_bih_width = p_input->p_fmt->video.i_width;
569 p_stream->i_bih_height = p_input->p_fmt->video.i_height;
575 p_sys->i_video_bound++;
579 switch( p_input->p_fmt->i_codec )
581 case VLC_FOURCC( 'm', 'p','g', 'a' ):
582 p_stream->i_stream_type = p_input->p_fmt->audio.i_rate >= 32000 ? 0x03 : 0x04;
583 p_stream->i_stream_id = 0xc0;
585 case VLC_FOURCC( 'a', '5','2', ' ' ):
586 p_stream->i_stream_type = 0x81;
587 p_stream->i_stream_id = 0xbd;
589 case VLC_FOURCC( 'l', 'p','c', 'm' ):
590 p_stream->i_stream_type = 0x83;
591 p_stream->i_stream_id = 0xbd;
593 case VLC_FOURCC( 'd', 't','s', ' ' ):
594 p_stream->i_stream_type = 0x85;
595 p_stream->i_stream_id = 0xbd;
598 case VLC_FOURCC( 'm', 'p','4', 'a' ):
599 p_stream->i_stream_type = 0x11;
600 p_stream->i_stream_id = 0xfa;
601 p_sys->i_mpeg4_streams++;
602 p_stream->i_es_id = p_stream->i_pid;
608 p_sys->i_audio_bound++;
612 switch( p_input->p_fmt->i_codec )
614 case VLC_FOURCC( 's', 'p','u', ' ' ):
615 p_stream->i_stream_type = 0x82;
616 p_stream->i_stream_id = 0xbd;
631 p_stream->lang[2] = '\0';
632 if( p_input->p_fmt->psz_language )
634 char *psz = p_input->p_fmt->psz_language;
635 const iso639_lang_t *pl = NULL;
637 if( strlen( psz ) == 2 )
639 pl = GetLang_1( psz );
641 else if( strlen( psz ) == 3 )
643 pl = GetLang_2B( psz );
644 if( !strcmp( pl->psz_iso639_1, "??" ) )
646 pl = GetLang_2T( psz );
649 if( pl && strcmp( pl->psz_iso639_1, "??" ) )
651 p_stream->lang[0] = pl->psz_iso639_2T[0];
652 p_stream->lang[1] = pl->psz_iso639_2T[1];
653 p_stream->lang[2] = pl->psz_iso639_2T[2];
655 msg_Dbg( p_mux, " - lang=%c%c%c",
663 /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
664 p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
665 if( p_stream->i_decoder_specific_info > 0 )
667 p_stream->p_decoder_specific_info =
668 malloc( p_stream->i_decoder_specific_info );
669 memcpy( p_stream->p_decoder_specific_info,
670 p_input->p_fmt->p_extra,
671 p_input->p_fmt->i_extra );
675 BufferChainInit( &p_stream->chain_pes );
676 p_stream->i_pes_dts = 0;
677 p_stream->i_pes_length = 0;
678 p_stream->i_pes_used = 0;
679 p_stream->b_key_frame = 0;
681 /* We only change PMT version (PAT isn't changed) */
682 p_sys->i_pmt_version_number = ( p_sys->i_pmt_version_number + 1 )%32;
685 if( p_input->p_fmt->i_cat != SPU_ES &&
686 ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) )
688 if( p_sys->p_pcr_input )
690 /* There was already a PCR stream, so clean context */
693 p_sys->i_pcr_pid = p_stream->i_pid;
694 p_sys->p_pcr_input = p_input;
696 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
702 /*****************************************************************************
703 * DelStream: called before a stream deletion
704 *****************************************************************************/
705 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
707 sout_mux_sys_t *p_sys = p_mux->p_sys;
708 ts_stream_t *p_stream;
711 p_stream = (ts_stream_t*)p_input->p_sys;
712 msg_Dbg( p_mux, "removing input pid=%d", p_stream->i_pid );
714 if( p_sys->i_pcr_pid == p_stream->i_pid )
718 /* Find a new pcr stream (Prefer Video Stream) */
719 p_sys->i_pcr_pid = 0x1fff;
720 p_sys->p_pcr_input = NULL;
721 for( i = 0; i < p_mux->i_nb_inputs; i++ )
723 if( p_mux->pp_inputs[i] == p_input )
728 if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
731 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
732 p_sys->p_pcr_input= p_mux->pp_inputs[i];
735 else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
736 p_sys->i_pcr_pid == 0x1fff )
739 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
740 p_sys->p_pcr_input= p_mux->pp_inputs[i];
743 if( p_sys->p_pcr_input )
745 /* Empty TS buffer */
748 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
751 /* Empty all data in chain_pes */
752 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
754 if( p_stream->p_decoder_specific_info )
756 free( p_stream->p_decoder_specific_info );
758 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
760 p_sys->i_mpeg4_streams--;
763 var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );
766 int i_pid_video = val.i_int;
767 if ( i_pid_video == p_stream->i_pid )
769 p_sys->i_pid_video = i_pid_video;
770 msg_Dbg( p_mux, "freeing video PID %d", i_pid_video );
773 var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );
776 int i_pid_audio = val.i_int;
777 if ( i_pid_audio == p_stream->i_pid )
779 p_sys->i_pid_audio = i_pid_audio;
780 msg_Dbg( p_mux, "freeing audio PID %d", i_pid_audio );
785 /* We only change PMT version (PAT isn't changed) */
786 p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
791 /*****************************************************************************
792 * Mux: Call each time there is new data for at least one stream
793 *****************************************************************************
795 *****************************************************************************/
796 static int Mux( sout_mux_t *p_mux )
798 sout_mux_sys_t *p_sys = p_mux->p_sys;
799 ts_stream_t *p_pcr_stream;
801 if( p_sys->i_pcr_pid == 0x1fff )
803 msg_Dbg( p_mux, "waiting for PCR streams" );
807 p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
811 sout_buffer_chain_t chain_ts;
815 mtime_t i_pcr_length;
816 mtime_t i_shaping_delay;
819 if( p_pcr_stream->b_key_frame )
821 i_shaping_delay = p_pcr_stream->i_pes_length;
825 i_shaping_delay = p_sys->i_shaping_delay;
828 /* 1: get enough PES packet for all input */
831 vlc_bool_t b_ok = VLC_TRUE;
834 /* Accumulate enough data in the pcr stream (>i_shaping_delay) */
835 /* Accumulate enough data in all other stream ( >= length of pcr) */
836 for( i = 0; i < p_mux->i_nb_inputs; i++ )
838 sout_input_t *p_input = p_mux->pp_inputs[i];
839 ts_stream_t *p_stream = (ts_stream_t*)p_input->p_sys;
841 if( ( p_stream == p_pcr_stream
842 && p_stream->i_pes_length < i_shaping_delay ) ||
843 p_stream->i_pes_dts + p_stream->i_pes_length
844 < p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
847 if( p_input->p_fifo->i_depth <= 1 )
849 if( p_input->p_fmt->i_cat == AUDIO_ES ||
850 p_input->p_fmt->i_cat == VIDEO_ES )
852 /* We need more data */
855 else if( p_input->p_fifo->i_depth <= 0 )
857 /* spu, only one packet is needed */
863 p_data = block_FifoGet( p_input->p_fifo );
864 if( p_input->p_fifo->i_depth > 0 )
866 block_t *p_next = block_FifoShow( p_input->p_fifo );
868 p_data->i_length = p_next->i_dts - p_data->i_dts;
871 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 ) ||
872 p_data->i_dts < p_stream->i_pes_dts ||
873 ( p_stream->i_pes_dts > 0 && p_data->i_dts - 2000000 > p_stream->i_pes_dts + p_stream->i_pes_length ) )
875 msg_Warn( p_mux, "packet with too strange dts (dts=%lld,old=%lld,pcr=%lld)",
878 p_pcr_stream->i_pes_dts );
879 block_Release( p_data );
881 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
882 p_stream->i_pes_dts = 0;
883 p_stream->i_pes_used = 0;
884 p_stream->i_pes_length = 0;
886 BufferChainClean( p_mux->p_sout, &p_pcr_stream->chain_pes );
887 p_pcr_stream->i_pes_dts = 0;
888 p_pcr_stream->i_pes_used = 0;
889 p_pcr_stream->i_pes_length = 0;
894 if( p_data->i_length < 0 || p_data->i_length > 2000000 )
896 /* FIXME choose a better value, but anyway we should never
898 p_data->i_length = 1000;
900 p_stream->i_pes_length += p_data->i_length;
901 if( p_stream->i_pes_dts == 0 )
903 p_stream->i_pes_dts = p_data->i_dts;
907 if( p_stream->i_stream_id == 0xa0 && p_data->i_pts <= 0 )
909 /* XXX yes I know, it's awfull, but it's needed, so don't remove it ... */
910 p_data->i_pts = p_data->i_dts;
912 E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 );
914 BufferChainAppend( &p_stream->chain_pes, p_data );
916 if( p_sys->b_use_key_frames && p_stream == p_pcr_stream
917 && (p_data->i_flags & BLOCK_FLAG_TYPE_I )
918 && (p_stream->i_pes_length > 300000) )
920 i_shaping_delay = p_stream->i_pes_length;
921 p_stream->b_key_frame = 1;
934 i_pcr_dts = p_pcr_stream->i_pes_dts;
935 i_pcr_length = p_pcr_stream->i_pes_length;
936 p_pcr_stream->b_key_frame = 0;
938 /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
939 /* 2: calculate non accurate total size of muxed ts */
941 for( i = 0; i < p_mux->i_nb_inputs; i++ )
943 ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
946 /* False for pcr stream but it will be enough to do PCR algo */
947 for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL; p_pes = p_pes->p_next )
949 int i_size = p_pes->i_buffer;
950 if( p_pes->i_dts + p_pes->i_length > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
952 mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts;
958 i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
960 i_packet_count += ( i_size + 183 ) / 184;
963 /* add overhead for PCR (not really exact) */
964 i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176;
967 /* 3: mux PES into TS */
968 BufferChainInit( &chain_ts );
969 /* append PAT/PMT -> FIXME with big pcr delay it won't have enough pat/pmt */
970 GetPAT( p_mux, &chain_ts);
971 GetPMT( p_mux, &chain_ts );
973 i_packet_count += chain_ts.i_depth;
974 /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
980 ts_stream_t *p_stream;
981 sout_input_t *p_input;
985 /* Select stream (lowest dts) */
986 for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
988 p_input = p_mux->pp_inputs[i];
989 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
991 if( p_stream->i_pes_dts == 0 )
996 if( i_stream == -1 ||
997 p_stream->i_pes_dts < i_dts )
1000 i_dts = p_stream->i_pes_dts;
1003 if( i_stream == -1 )
1007 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1009 /* do we need to issue pcr */
1011 if( p_stream == p_pcr_stream &&
1012 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >= p_sys->i_pcr + p_sys->i_pcr_delay )
1015 p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count;
1018 /* Build the TS packet */
1019 p_ts = TSNew( p_mux, p_stream, b_pcr );
1020 if( p_sys->csa != NULL &&
1021 (p_input->p_fmt->i_cat != AUDIO_ES || p_sys->b_crypt_audio) )
1023 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
1028 BufferChainAppend( &chain_ts, p_ts );
1031 /* 4: date and send */
1032 TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
1036 static void TSSchedule( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1037 mtime_t i_pcr_length, mtime_t i_pcr_dts )
1039 sout_mux_sys_t *p_sys = p_mux->p_sys;
1040 sout_buffer_chain_t new_chain;
1041 int i_packet_count = p_chain_ts->i_depth;
1044 BufferChainInit( &new_chain );
1046 if ( i_pcr_length <= 0 )
1048 i_pcr_length = i_packet_count;
1051 for( i = 0; i < i_packet_count; i++ )
1053 block_t *p_ts = BufferChainGet( p_chain_ts );
1054 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1056 BufferChainAppend( &new_chain, p_ts );
1059 p_ts->i_dts + p_sys->i_dts_delay * 2/3 < i_new_dts )
1061 mtime_t i_max_diff = i_new_dts - p_ts->i_dts;
1062 mtime_t i_cut_dts = p_ts->i_dts;
1064 p_ts = BufferChainPeek( p_chain_ts );
1066 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1067 while ( p_ts != NULL && i_new_dts - p_ts->i_dts >= i_max_diff )
1069 p_ts = BufferChainGet( p_chain_ts );
1070 i_max_diff = i_new_dts - p_ts->i_dts;
1071 i_cut_dts = p_ts->i_dts;
1072 BufferChainAppend( &new_chain, p_ts );
1074 p_ts = BufferChainPeek( p_chain_ts );
1076 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1078 msg_Dbg( p_mux, "adjusting rate at "I64Fd"/"I64Fd" (%d/%d)",
1079 i_cut_dts - i_pcr_dts, i_pcr_length, new_chain.i_depth,
1080 p_chain_ts->i_depth );
1081 if ( new_chain.i_depth )
1082 TSDate( p_mux, &new_chain,
1083 i_cut_dts - i_pcr_dts,
1085 if ( p_chain_ts->i_depth )
1087 p_chain_ts, i_pcr_dts + i_pcr_length - i_cut_dts,
1093 if ( new_chain.i_depth )
1094 TSDate( p_mux, &new_chain, i_pcr_length, i_pcr_dts );
1097 static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1098 mtime_t i_pcr_length, mtime_t i_pcr_dts )
1100 sout_mux_sys_t *p_sys = p_mux->p_sys;
1101 int i_packet_count = p_chain_ts->i_depth;
1104 if ( i_pcr_length > 0 )
1106 int i_bitrate = ((uint64_t)i_packet_count * 188 * 8000)
1107 / (uint64_t)(i_pcr_length / 1000);
1108 if ( p_sys->i_bitrate_max && p_sys->i_bitrate_max < i_bitrate )
1111 "max bitrate exceeded at %lld (%d bi/s for %d pkt in %lld us)",
1112 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1113 i_bitrate, i_packet_count, i_pcr_length);
1119 "starting at %lld (%d bi/s for %d packets in %lld us)",
1120 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1121 i_bitrate, i_packet_count, i_pcr_length);
1127 /* This shouldn't happen, but happens in some rare heavy load
1128 * and packet losses conditions. */
1129 i_pcr_length = i_packet_count;
1132 /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
1133 for( i = 0; i < i_packet_count; i++ )
1135 block_t *p_ts = BufferChainGet( p_chain_ts );
1136 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1138 p_ts->i_dts = i_new_dts;
1139 p_ts->i_length = i_pcr_length / i_packet_count;
1141 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_PCR )
1143 /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
1144 TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
1146 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_CSA )
1148 csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
1152 p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
1154 sout_AccessOutWrite( p_mux->p_access, p_ts );
1158 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr )
1160 block_t *p_pes = p_stream->chain_pes.p_first;
1163 vlc_bool_t b_new_pes = VLC_FALSE;
1164 vlc_bool_t b_adaptation_field = VLC_FALSE;
1166 int i_payload_max = 184 - ( b_pcr ? 8 : 0 );
1169 if( p_stream->i_pes_used <= 0 )
1171 b_new_pes = VLC_TRUE;
1173 i_payload = __MIN( (int)p_pes->i_buffer - p_stream->i_pes_used, i_payload_max );
1175 if( b_pcr || i_payload < i_payload_max )
1177 b_adaptation_field = VLC_TRUE;
1180 p_ts = block_New( p_mux, 188 );
1181 p_ts->i_dts = p_pes->i_dts;
1183 p_ts->p_buffer[0] = 0x47;
1184 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|( ( p_stream->i_pid >> 8 )&0x1f );
1185 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1186 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|p_stream->i_continuity_counter;
1188 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1190 if( b_adaptation_field )
1196 int i_stuffing = i_payload_max - i_payload;
1198 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
1200 p_ts->p_buffer[4] = 7 + i_stuffing;
1201 p_ts->p_buffer[5] = 0x10; /* flags */
1202 p_ts->p_buffer[6] = ( 0 )&0xff;
1203 p_ts->p_buffer[7] = ( 0 )&0xff;
1204 p_ts->p_buffer[8] = ( 0 )&0xff;
1205 p_ts->p_buffer[9] = ( 0 )&0xff;
1206 p_ts->p_buffer[10]= ( 0 )&0x80;
1207 p_ts->p_buffer[11]= 0;
1209 for( i = 12; i < 12 + i_stuffing; i++ )
1211 p_ts->p_buffer[i] = 0xff;
1216 int i_stuffing = i_payload_max - i_payload;
1218 p_ts->p_buffer[4] = i_stuffing - 1;
1219 if( i_stuffing > 1 )
1221 p_ts->p_buffer[5] = 0x00;
1222 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1224 p_ts->p_buffer[i] = 0xff;
1231 memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
1233 p_stream->i_pes_used += i_payload;
1234 p_stream->i_pes_dts = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_buffer;
1235 p_stream->i_pes_length -= p_pes->i_length * i_payload / p_pes->i_buffer;
1237 if( p_stream->i_pes_used >= (int)p_pes->i_buffer )
1239 p_pes = BufferChainGet( &p_stream->chain_pes );
1240 block_Release( p_pes );
1242 p_pes = p_stream->chain_pes.p_first;
1245 p_stream->i_pes_dts = p_pes->i_dts;
1246 p_stream->i_pes_length = 0;
1249 p_stream->i_pes_length += p_pes->i_length;
1251 p_pes = p_pes->p_next;
1256 p_stream->i_pes_dts = 0;
1257 p_stream->i_pes_length = 0;
1259 p_stream->i_pes_used = 0;
1266 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
1268 mtime_t i_pcr = 9 * i_dts / 100;
1270 p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
1271 p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
1272 p_ts->p_buffer[8] = ( i_pcr >> 9 )&0xff;
1273 p_ts->p_buffer[9] = ( i_pcr >> 1 )&0xff;
1274 p_ts->p_buffer[10]|= ( i_pcr << 7 )&0x80;
1278 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 )
1280 sout_mux_sys_t *p_sys = p_mux->p_sys;
1281 sout_buffer_chain_t s = *c;
1284 int i_packets_min = 0;
1285 int i_packets_max = 0;
1292 i_packets = c->i_depth;
1293 i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000 + 187 ) / 188;
1294 i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000 + 187 ) / 188;
1296 if( i_packets < i_packets_min && i_packets_min > 0 )
1299 int i_div = ( i_packets_min - i_packets ) / i_packets;
1300 int i_mod = ( i_packets_min - i_packets ) % i_packets;
1303 /* We need to pad with null packets (pid=0x1fff)
1304 * We try to melt null packets with true packets */
1306 "packets=%d but min=%d -> adding %d packets of padding",
1307 i_packets, i_packets_min, i_packets_min - i_packets );
1309 BufferChainInit( c );
1310 while( ( p_pk = BufferChainGet( &s ) ) )
1314 BufferChainAppend( c, p_pk );
1316 i_null = i_div + ( i_rest + i_mod ) / i_packets;
1318 for( i = 0; i < i_null; i++ )
1322 p_null = sout_BufferNew( p_mux->p_sout, 188 );
1323 p_null->p_buffer[0] = 0x47;
1324 p_null->p_buffer[1] = 0x1f;
1325 p_null->p_buffer[2] = 0xff;
1326 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
1327 memset( &p_null->p_buffer[4], 0, 184 );
1328 p_sys->i_null_continuity_counter =
1329 ( p_sys->i_null_continuity_counter + 1 ) % 16;
1331 BufferChainAppend( c, p_null );
1334 i_rest = ( i_rest + i_mod ) % i_packets;
1337 else if( i_packets > i_packets_max && i_packets_max > 0 )
1342 /* Arg, we need to drop packets, I don't do something clever (like
1343 * dropping complete pid, b frames, ... ), I just get the right amount
1344 * of packets and discard the others */
1346 "packets=%d but max=%d -> removing %d packets -> stream broken",
1347 i_packets, i_packets_max, i_packets - i_packets_max );
1349 BufferChainInit( c );
1350 for( i = 0; i < i_packets_max; i++ )
1352 BufferChainAppend( c, BufferChainGet( &s ) );
1355 while( ( p_pk = BufferChainGet( &s ) ) )
1357 sout_BufferDelete( p_mux->p_sout, p_pk );
1363 static void PEStoTS( sout_instance_t *p_sout,
1364 sout_buffer_chain_t *c, block_t *p_pes,
1365 ts_stream_t *p_stream )
1371 /* get PES total size */
1372 i_size = p_pes->i_buffer;
1373 p_data = p_pes->p_buffer;
1375 b_new_pes = VLC_TRUE;
1379 int b_adaptation_field;
1383 p_ts = block_New( p_sout, 188 );
1386 * 1b transport_error_indicator
1387 * 1b payload_unit_start
1388 * 1b transport_priority
1390 * 2b transport_scrambling_control
1391 * 2b if adaptation_field 0x03 else 0x01
1392 * 4b continuity_counter
1395 i_copy = __MIN( i_size, 184 );
1396 b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
1398 p_ts->p_buffer[0] = 0x47;
1399 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
1400 ( ( p_stream->i_pid >> 8 )&0x1f );
1401 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1402 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
1403 p_stream->i_continuity_counter;
1405 b_new_pes = VLC_FALSE;
1406 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1408 if( b_adaptation_field )
1410 int i_stuffing = 184 - i_copy;
1413 p_ts->p_buffer[4] = i_stuffing - 1;
1414 if( i_stuffing > 1 )
1416 p_ts->p_buffer[5] = 0x00;
1417 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1419 p_ts->p_buffer[i] = 0xff;
1424 memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1428 BufferChainAppend( c, p_ts );
1432 block_t *p_next = p_pes->p_next;
1434 p_pes->p_next = NULL;
1435 block_Release( p_pes );
1436 if( p_next == NULL )
1440 b_new_pes = VLC_TRUE;
1442 i_size = p_pes->i_buffer;
1443 p_data = p_pes->p_buffer;
1450 #if defined MODULE_NAME_IS_mux_ts
1451 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1453 static uint32_t CRC32[256] =
1455 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1456 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1457 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1458 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1459 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1460 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1461 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1462 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1463 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1464 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1465 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1466 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1467 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1468 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1469 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1470 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1471 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1472 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1473 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1474 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1475 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1476 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1477 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1478 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1479 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1480 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1481 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1482 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1483 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1484 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1485 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1486 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1487 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1488 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1489 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1490 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1491 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1492 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1493 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1494 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1495 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1496 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1497 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1498 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1499 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1500 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1501 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1502 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1503 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1504 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1505 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1506 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1507 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1508 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1509 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1510 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1511 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1512 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1513 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1514 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1515 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1516 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1517 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1518 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1521 uint32_t i_crc = 0xffffffff;
1523 /* Calculate the CRC */
1524 while( i_count > 0 )
1526 i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1534 static void GetPAT( sout_mux_t *p_mux,
1535 sout_buffer_chain_t *c )
1537 sout_mux_sys_t *p_sys = p_mux->p_sys;
1541 p_pat = block_New( p_mux, 1024 );
1545 p_pat->i_length = 0;
1547 bits_initwrite( &bits, 1024, p_pat->p_buffer );
1549 bits_write( &bits, 8, 0 ); // pointer
1550 bits_write( &bits, 8, 0x00 ); // table id
1551 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1552 bits_write( &bits, 1, 0 ); // 0
1553 bits_write( &bits, 2, 0x03 ); // reserved FIXME
1554 bits_write( &bits, 12, 13 ); // XXX for one program only XXX
1555 bits_write( &bits, 16, 0x01 ); // FIXME stream id
1556 bits_write( &bits, 2, 0x03 ); // FIXME
1557 bits_write( &bits, 5, p_sys->i_pat_version_number );
1558 bits_write( &bits, 1, 1 ); // current_next_indicator
1559 bits_write( &bits, 8, 0 ); // section number
1560 bits_write( &bits, 8, 0 ); // last section number
1562 bits_write( &bits, 16, 1 ); // program number
1563 bits_write( &bits, 3, 0x07 ); // reserved
1564 bits_write( &bits, 13, p_sys->pmt.i_pid ); // program map pid
1566 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1568 p_pat->i_buffer = bits.i_data;
1570 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1573 static void GetPMT( sout_mux_t *p_mux,
1574 sout_buffer_chain_t *c )
1576 sout_mux_sys_t *p_sys = p_mux->p_sys;
1581 p_pmt = block_New( p_mux, 1024 );
1585 p_pmt->i_length = 0;
1587 bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1589 bits_write( &bits, 8, 0 ); // pointer
1590 bits_write( &bits, 8, 0x02 ); // table id
1591 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1592 bits_write( &bits, 1, 0 ); // 0
1593 bits_write( &bits, 2, 0 ); // reserved FIXME
1594 bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1595 bits_write( &bits, 16, 1 ); // FIXME program number
1596 bits_write( &bits, 2, 0 ); // FIXME
1597 bits_write( &bits, 5, p_sys->i_pmt_version_number );
1598 bits_write( &bits, 1, 1 ); // current_next_indicator
1599 bits_write( &bits, 8, 0 ); // section number
1600 bits_write( &bits, 8, 0 ); // last section number
1602 bits_write( &bits, 3, 0 ); // reserved
1604 bits_write( &bits, 13, p_sys->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
1605 bits_write( &bits, 4, 0 ); // reserved FIXME
1607 bits_write( &bits, 12, 0 ); // program info len FIXME
1609 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1611 ts_stream_t *p_stream;
1613 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1615 bits_write( &bits, 8, p_stream->i_stream_type ); // stream_type
1616 bits_write( &bits, 3, 0 ); // reserved
1617 bits_write( &bits, 13, p_stream->i_pid ); // es pid
1618 bits_write( &bits, 4, 0 ); //reserved
1619 bits_write( &bits, 12, 0 ); // es info len FIXME
1622 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1624 p_pmt->i_buffer = bits.i_data;
1626 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1628 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1630 static block_t *WritePSISection( sout_instance_t *p_sout,
1631 dvbpsi_psi_section_t* p_section )
1633 block_t *p_psi, *p_first = NULL;
1640 i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1641 ( p_section->b_syntax_indicator ? 4 : 0 );
1643 p_psi = block_New( p_sout, i_size + 1 );
1646 p_psi->i_length = 0;
1647 p_psi->i_buffer = i_size + 1;
1649 p_psi->p_buffer[0] = 0; // pointer
1650 memcpy( p_psi->p_buffer + 1,
1654 block_ChainAppend( &p_first, p_psi );
1656 p_section = p_section->p_next;
1662 static void GetPAT( sout_mux_t *p_mux,
1663 sout_buffer_chain_t *c )
1665 sout_mux_sys_t *p_sys = p_mux->p_sys;
1668 dvbpsi_psi_section_t *p_section;
1670 dvbpsi_InitPAT( &pat,
1672 p_sys->i_pat_version_number,
1673 1 ); // b_current_next
1674 /* add all program (only one) */
1675 dvbpsi_PATAddProgram( &pat,
1677 p_sys->pmt.i_pid ); // i_pid
1679 p_section = dvbpsi_GenPATSections( &pat,
1680 0 ); // max program per section
1682 p_pat = WritePSISection( p_mux->p_sout, p_section );
1684 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1686 dvbpsi_DeletePSISections( p_section );
1687 dvbpsi_EmptyPAT( &pat );
1690 static uint32_t GetDescriptorLength24b( int i_length )
1692 uint32_t i_l1, i_l2, i_l3;
1694 i_l1 = i_length&0x7f;
1695 i_l2 = ( i_length >> 7 )&0x7f;
1696 i_l3 = ( i_length >> 14 )&0x7f;
1698 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1701 static void GetPMT( sout_mux_t *p_mux,
1702 sout_buffer_chain_t *c )
1704 sout_mux_sys_t *p_sys = p_mux->p_sys;
1708 dvbpsi_pmt_es_t *p_es;
1709 dvbpsi_psi_section_t *p_section;
1713 dvbpsi_InitPMT( &pmt,
1714 0x01, // program number
1715 p_sys->i_pmt_version_number,
1716 1, // b_current_next
1719 if( p_sys->i_mpeg4_streams > 0 )
1723 bits_buffer_t bits_fix_IOD;
1725 /* Make valgrind happy : it works at byte level not bit one so
1726 * bit_write confuse it (but DON'T CHANGE the way that bit_write is
1727 * working (needed when fixing some bits) */
1728 memset( iod, 0, 4096 );
1730 bits_initwrite( &bits, 4096, iod );
1732 bits_write( &bits, 8, 0x01 );
1733 // InitialObjectDescriptor
1734 bits_align( &bits );
1735 bits_write( &bits, 8, 0x02 ); // tag
1736 bits_fix_IOD = bits; // save states to fix length later
1737 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1738 bits_write( &bits, 10, 0x01 ); // ObjectDescriptorID
1739 bits_write( &bits, 1, 0x00 ); // URL Flag
1740 bits_write( &bits, 1, 0x00 ); // includeInlineProfileLevelFlag
1741 bits_write( &bits, 4, 0x0f ); // reserved
1742 bits_write( &bits, 8, 0xff ); // ODProfile (no ODcapability )
1743 bits_write( &bits, 8, 0xff ); // sceneProfile
1744 bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified)
1745 bits_write( &bits, 8, 0xfe ); // visualProfile( // )
1746 bits_write( &bits, 8, 0xff ); // graphicProfile (no )
1747 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1749 ts_stream_t *p_stream;
1750 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1752 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1754 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1756 bits_align( &bits );
1757 bits_write( &bits, 8, 0x03 ); // ES_DescrTag
1758 bits_fix_ESDescr = bits;
1759 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable size
1760 bits_write( &bits, 16, p_stream->i_es_id );
1761 bits_write( &bits, 1, 0x00 ); // streamDependency
1762 bits_write( &bits, 1, 0x00 ); // URL Flag
1763 bits_write( &bits, 1, 0x00 ); // OCRStreamFlag
1764 bits_write( &bits, 5, 0x1f ); // streamPriority
1766 // DecoderConfigDesciptor
1767 bits_align( &bits );
1768 bits_write( &bits, 8, 0x04 ); // DecoderConfigDescrTag
1769 bits_fix_Decoder = bits;
1770 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) );
1771 if( p_stream->i_stream_type == 0x10 )
1773 bits_write( &bits, 8, 0x20 ); // Visual 14496-2
1774 bits_write( &bits, 6, 0x04 ); // VisualStream
1776 else if( p_stream->i_stream_type == 0x11 )
1778 bits_write( &bits, 8, 0x40 ); // Audio 14496-3
1779 bits_write( &bits, 6, 0x05 ); // AudioStream
1783 bits_write( &bits, 8, 0x00 );
1784 bits_write( &bits, 6, 0x00 );
1786 msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1788 bits_write( &bits, 1, 0x00 ); // UpStream
1789 bits_write( &bits, 1, 0x01 ); // reserved
1790 bits_write( &bits, 24, 1024 * 1024 ); // bufferSizeDB
1791 bits_write( &bits, 32, 0x7fffffff ); // maxBitrate
1792 bits_write( &bits, 32, 0 ); // avgBitrate
1794 if( p_stream->i_decoder_specific_info > 0 )
1797 // DecoderSpecificInfo
1798 bits_align( &bits );
1799 bits_write( &bits, 8, 0x05 ); // tag
1800 bits_write( &bits, 24,
1801 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1802 for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1804 bits_write( &bits, 8, ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1807 /* fix Decoder length */
1808 bits_write( &bits_fix_Decoder, 24,
1809 GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1811 /* SLConfigDescriptor : predifined (0x01) */
1812 bits_align( &bits );
1813 bits_write( &bits, 8, 0x06 ); // tag
1814 bits_write( &bits, 24, GetDescriptorLength24b( 8 ) );
1815 bits_write( &bits, 8, 0x01 ); // predefined
1816 bits_write( &bits, 1, 0 ); // durationFlag
1817 bits_write( &bits, 32, 0 ); // OCRResolution
1818 bits_write( &bits, 8, 0 ); // OCRLength
1819 bits_write( &bits, 8, 0 ); // InstantBitrateLength
1820 bits_align( &bits );
1822 /* fix ESDescr length */
1823 bits_write( &bits_fix_ESDescr, 24,
1824 GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1827 bits_align( &bits );
1828 /* fix IOD length */
1829 bits_write( &bits_fix_IOD, 24,
1830 GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1831 dvbpsi_PMTAddDescriptor( &pmt,
1837 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1839 ts_stream_t *p_stream;
1841 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1843 p_es = dvbpsi_PMTAddES( &pmt,
1844 p_stream->i_stream_type,
1846 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1851 es_id[0] = (p_stream->i_es_id >> 8)&0xff;
1852 es_id[1] = (p_stream->i_es_id)&0xff;
1853 dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
1855 else if( p_stream->i_stream_type == 0xa0 )
1858 int i_extra = __MIN( p_stream->i_decoder_specific_info,
1861 /* private DIV3 descripor */
1862 memcpy( &data[0], &p_stream->i_bih_codec, 4 );
1863 data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
1864 data[5] = ( p_stream->i_bih_width )&0xff;
1865 data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
1866 data[7] = ( p_stream->i_bih_height )&0xff;
1867 data[8] = ( i_extra >> 8 )&0xff;
1868 data[9] = ( i_extra )&0xff;
1871 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1874 /* 0xa0 is private */
1875 dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
1877 else if( p_stream->i_stream_type == 0x81 )
1879 uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1881 /* "registration" descriptor : "AC-3" */
1882 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1885 if( p_stream->lang[0] != 0 )
1889 /* I construct the content myself, way faster than looking at
1890 * over complicated/mind broken libdvbpsi way */
1891 data[0] = p_stream->lang[0];
1892 data[1] = p_stream->lang[1];
1893 data[2] = p_stream->lang[2];
1894 data[3] = 0x00; /* audio type: 0x00 undefined */
1896 dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data );
1900 p_section = dvbpsi_GenPMTSections( &pmt );
1902 p_pmt = WritePSISection( p_mux->p_sout, p_section );
1904 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1906 dvbpsi_DeletePSISections( p_section );
1907 dvbpsi_EmptyPMT( &pmt );