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
228 vlc_fourcc_t i_codec;
232 int i_continuity_counter;
234 /* to be used for carriege of DIV3 */
235 vlc_fourcc_t i_bih_codec;
236 int i_bih_width, i_bih_height;
238 /* Specific to mpeg4 in mpeg2ts */
241 int i_decoder_specific_info;
242 uint8_t *p_decoder_specific_info;
244 /* language is iso639-2T */
247 sout_buffer_chain_t chain_pes;
249 mtime_t i_pes_length;
251 vlc_bool_t b_key_frame;
255 struct sout_mux_sys_t
258 sout_input_t *p_pcr_input;
265 int i_pid_free; // first usable pid
267 int i_pat_version_number;
270 int i_pmt_version_number;
271 ts_stream_t pmt; // Up to now only one program
275 int i_null_continuity_counter; /* Needed ? */
277 /* for TS building */
278 int64_t i_bitrate_min;
279 int64_t i_bitrate_max;
281 int64_t i_shaping_delay;
286 vlc_bool_t b_use_key_frames;
288 mtime_t i_pcr; /* last PCR emited */
291 vlc_bool_t b_crypt_audio;
295 /* Reserve a pid and return it */
296 static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
299 if ( i_cat == VIDEO_ES && p_sys->i_pid_video )
301 i_pid = p_sys->i_pid_video;
302 p_sys->i_pid_video = 0;
304 else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio )
306 i_pid = p_sys->i_pid_audio;
307 p_sys->i_pid_audio = 0;
311 i_pid = ++p_sys->i_pid_free;
316 /*****************************************************************************
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 * );
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 );
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 );
334 static void PEStoTS ( sout_instance_t *, sout_buffer_chain_t *, block_t *, ts_stream_t * );
336 /*****************************************************************************
338 *****************************************************************************/
339 static int Open( vlc_object_t *p_this )
341 sout_mux_t *p_mux =(sout_mux_t*)p_this;
342 sout_mux_sys_t *p_sys;
345 msg_Dbg( p_mux, "Open" );
346 sout_ParseCfg( p_mux, SOUT_CFG_PREFIX, ppsz_sout_options, p_mux->p_cfg );
348 p_sys = malloc( sizeof( sout_mux_sys_t ) );
350 p_mux->pf_capacity = Capability;
351 p_mux->pf_addstream = AddStream;
352 p_mux->pf_delstream = DelStream;
354 p_mux->p_sys = p_sys;
356 srand( (uint32_t)mdate() );
358 p_sys->i_audio_bound = 0;
359 p_sys->i_video_bound = 0;
361 p_sys->i_pat_version_number = rand() % 32;
362 p_sys->pat.i_pid = 0;
363 p_sys->pat.i_continuity_counter = 0;
365 p_sys->i_pmt_version_number = rand() % 32;
366 p_sys->pmt.i_pid = 0x42;
367 p_sys->pmt.i_continuity_counter = 0;
369 p_sys->i_pid_free = 0x43;
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 )
375 p_sys->i_pid_free = p_sys->i_pid_video + 1;
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 )
382 p_sys->i_pid_free = p_sys->i_pid_audio + 1;
385 p_sys->i_pcr_pid = 0x1fff;
386 p_sys->p_pcr_input = NULL;
388 p_sys->i_mpeg4_streams = 0;
390 p_sys->i_null_continuity_counter = 0;
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;*/
396 var_Get( p_mux, SOUT_CFG_PREFIX "bmax", &val );
397 p_sys->i_bitrate_max = 0;/*val.i_int;*/
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 )
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;
407 if( p_sys->i_bitrate_min > 0 || p_sys->i_bitrate_max > 0 )
409 msg_Err( p_mux, "bmin and bmax no more supported (if you need them report it)" );
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 )
417 "invalid shaping ("I64Fd"ms) resetting to 200ms",
418 p_sys->i_shaping_delay / 1000 );
419 p_sys->i_shaping_delay = 200000;
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 )
428 "invalid pcr delay ("I64Fd"ms) resetting to 30ms",
429 p_sys->i_pcr_delay / 1000 );
430 p_sys->i_pcr_delay = 30000;
433 var_Get( p_mux, SOUT_CFG_PREFIX "dts-delay", &val );
434 p_sys->i_dts_delay = (int64_t)val.i_int * 1000;
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 );
439 var_Get( p_mux, SOUT_CFG_PREFIX "use-key-frames", &val );
440 p_sys->b_use_key_frames = val.b_bool;
442 /* for TS generation */
446 var_Get( p_mux, SOUT_CFG_PREFIX "csa-ck", &val );
449 char *psz = val.psz_string;
452 if( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) )
456 if( strlen( psz ) != 16 )
458 msg_Dbg( p_mux, "invalid csa ck (it must be 16 chars long)" );
462 uint64_t i_ck = strtoll( psz, NULL, 16 );
466 for( i = 0; i < 8; i++ )
468 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
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] );
474 p_sys->csa = csa_New();
475 csa_SetCW( p_sys->csa, ck, ck );
478 if( val.psz_string ) free( val.psz_string );
480 var_Get( p_mux, SOUT_CFG_PREFIX "crypt-audio", &val );
481 p_sys->b_crypt_audio = val.b_bool;
486 /*****************************************************************************
488 *****************************************************************************/
489 static void Close( vlc_object_t * p_this )
491 sout_mux_t *p_mux = (sout_mux_t*)p_this;
492 sout_mux_sys_t *p_sys = p_mux->p_sys;
494 msg_Dbg( p_mux, "Close" );
497 csa_Delete( p_sys->csa );
503 /*****************************************************************************
505 *****************************************************************************/
506 static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
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 );
514 return( SOUT_MUX_CAP_ERR_UNIMPLEMENTED );
518 /*****************************************************************************
519 * AddStream: called for each stream addition
520 *****************************************************************************/
521 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
523 sout_mux_sys_t *p_sys = p_mux->p_sys;
524 ts_stream_t *p_stream;
526 p_input->p_sys = p_stream = malloc( sizeof( ts_stream_t ) );
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;
535 msg_Dbg( p_mux, "adding input codec=%4.4s pid=%d", (char*)&p_input->p_fmt->i_codec, p_stream->i_pid );
537 /* All others fields depand on codec */
538 switch( p_input->p_fmt->i_cat )
541 switch( p_input->p_fmt->i_codec )
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;
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;
554 case VLC_FOURCC( 'h', '2','6', '4' ):
555 p_stream->i_stream_type = 0x1b;
556 p_stream->i_stream_id = 0xe0;
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;
578 p_sys->i_video_bound++;
582 switch( p_input->p_fmt->i_codec )
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;
588 case VLC_FOURCC( 'a', '5','2', ' ' ):
589 p_stream->i_stream_type = 0x81;
590 p_stream->i_stream_id = 0xbd;
592 case VLC_FOURCC( 'l', 'p','c', 'm' ):
593 p_stream->i_stream_type = 0x83;
594 p_stream->i_stream_id = 0xbd;
596 case VLC_FOURCC( 'd', 't','s', ' ' ):
597 p_stream->i_stream_type = 0x85;
598 p_stream->i_stream_id = 0xbd;
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;
611 p_sys->i_audio_bound++;
615 switch( p_input->p_fmt->i_codec )
617 case VLC_FOURCC( 's', 'p','u', ' ' ):
618 p_stream->i_stream_type = 0x82;
619 p_stream->i_stream_id = 0xbd;
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;
640 p_stream->lang[2] = '\0';
641 if( p_input->p_fmt->psz_language )
643 char *psz = p_input->p_fmt->psz_language;
644 const iso639_lang_t *pl = NULL;
646 if( strlen( psz ) == 2 )
648 pl = GetLang_1( psz );
650 else if( strlen( psz ) == 3 )
652 pl = GetLang_2B( psz );
653 if( !strcmp( pl->psz_iso639_1, "??" ) )
655 pl = GetLang_2T( psz );
658 if( pl && strcmp( pl->psz_iso639_1, "??" ) )
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];
664 msg_Dbg( p_mux, " - lang=%c%c%c",
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 )
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 );
683 /* Create decoder specific info for subt */
684 if( p_stream->i_codec == VLC_FOURCC( 's', 'u','b', 't' ) )
688 p_stream->i_decoder_specific_info = 55;
689 p_stream->p_decoder_specific_info = p = malloc( p_stream->i_decoder_specific_info );
691 p[0] = 0x10; /* textFormat, 0x10 for 3GPP TS 26.245 */
692 p[1] = 0x00; /* flags: 1b: associated video info flag
696 p[2] = 52; /* remaining size */
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) */
704 p[0] = p[1] = p[2] = 0x00; p+=3;/* background rgb */
705 *p++ = 0xff; /* background a */
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 */
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 */
716 *p++ = 0; /* font style flags */
717 *p++ = 12; /* font size */
719 p[0] = p[1] = p[2] = 0x00; p+=3;/* foreground rgb */
720 *p++ = 0x00; /* foreground a */
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 */
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;
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;
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 ) )
744 if( p_sys->p_pcr_input )
746 /* There was already a PCR stream, so clean context */
749 p_sys->i_pcr_pid = p_stream->i_pid;
750 p_sys->p_pcr_input = p_input;
752 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
758 /*****************************************************************************
759 * DelStream: called before a stream deletion
760 *****************************************************************************/
761 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
763 sout_mux_sys_t *p_sys = p_mux->p_sys;
764 ts_stream_t *p_stream;
767 p_stream = (ts_stream_t*)p_input->p_sys;
768 msg_Dbg( p_mux, "removing input pid=%d", p_stream->i_pid );
770 if( p_sys->i_pcr_pid == p_stream->i_pid )
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++ )
779 if( p_mux->pp_inputs[i] == p_input )
784 if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
787 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
788 p_sys->p_pcr_input= p_mux->pp_inputs[i];
791 else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
792 p_sys->i_pcr_pid == 0x1fff )
795 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
796 p_sys->p_pcr_input= p_mux->pp_inputs[i];
799 if( p_sys->p_pcr_input )
801 /* Empty TS buffer */
804 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
807 /* Empty all data in chain_pes */
808 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
810 if( p_stream->p_decoder_specific_info )
812 free( p_stream->p_decoder_specific_info );
814 if( p_stream->i_stream_id == 0xfa ||
815 p_stream->i_stream_id == 0xfb ||
816 p_stream->i_stream_id == 0xfe )
818 p_sys->i_mpeg4_streams--;
821 var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );
824 int i_pid_video = val.i_int;
825 if ( i_pid_video == p_stream->i_pid )
827 p_sys->i_pid_video = i_pid_video;
828 msg_Dbg( p_mux, "freeing video PID %d", i_pid_video );
831 var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );
834 int i_pid_audio = val.i_int;
835 if ( i_pid_audio == p_stream->i_pid )
837 p_sys->i_pid_audio = i_pid_audio;
838 msg_Dbg( p_mux, "freeing audio PID %d", i_pid_audio );
843 /* We only change PMT version (PAT isn't changed) */
844 p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
849 /*****************************************************************************
850 * Mux: Call each time there is new data for at least one stream
851 *****************************************************************************
853 *****************************************************************************/
854 static int Mux( sout_mux_t *p_mux )
856 sout_mux_sys_t *p_sys = p_mux->p_sys;
857 ts_stream_t *p_pcr_stream;
859 if( p_sys->i_pcr_pid == 0x1fff )
861 msg_Dbg( p_mux, "waiting for PCR streams" );
865 p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
869 sout_buffer_chain_t chain_ts;
873 mtime_t i_pcr_length;
874 mtime_t i_shaping_delay;
877 if( p_pcr_stream->b_key_frame )
879 i_shaping_delay = p_pcr_stream->i_pes_length;
883 i_shaping_delay = p_sys->i_shaping_delay;
886 /* 1: get enough PES packet for all input */
889 vlc_bool_t b_ok = VLC_TRUE;
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++ )
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;
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 )
908 if( p_input->p_fifo->i_depth <= 50 )
910 if( p_input->p_fmt->i_cat == AUDIO_ES ||
911 p_input->p_fmt->i_cat == VIDEO_ES )
913 /* We need more data */
916 else if( p_input->p_fifo->i_depth <= 0 )
918 /* spu, only one packet is needed */
924 p_data = block_FifoGet( p_input->p_fifo );
925 if( p_input->p_fmt->i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) )
927 i_spu_length = p_data->i_length; /* save info for SPU */
928 i_spu_dts = p_data->i_dts;
930 if( p_input->p_fifo->i_depth > 0 )
932 block_t *p_next = block_FifoShow( p_input->p_fifo );
934 p_data->i_length = p_next->i_dts - p_data->i_dts;
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 ) )
941 msg_Warn( p_mux, "packet with too strange dts (dts=%lld,old=%lld,pcr=%lld)",
944 p_pcr_stream->i_pes_dts );
945 block_Release( p_data );
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;
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;
960 if( p_input->p_fmt->i_cat == SPU_ES )
963 p_data->i_length = 1000;
964 if( p_input->p_fmt->i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) )
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;
971 /* remove trailling \0 if any */
972 if( p_data->i_buffer > 2 && p_data->p_buffer[p_data->i_buffer -1] == '\0' )
976 else if( p_data->i_length < 0 || p_data->i_length > 2000000 )
978 /* FIXME choose a better value, but anyway we should never
980 p_data->i_length = 1000;
983 p_stream->i_pes_length += p_data->i_length;
984 if( p_stream->i_pes_dts == 0 )
986 p_stream->i_pes_dts = p_data->i_dts;
990 if( p_stream->i_stream_id == 0xa0 && p_data->i_pts <= 0 )
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;
995 E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 );
997 BufferChainAppend( &p_stream->chain_pes, p_data );
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) )
1003 i_shaping_delay = p_stream->i_pes_length;
1004 p_stream->b_key_frame = 1;
1007 /* Append a empty sub (sub text only) */
1008 if( i_spu_length > 0 )
1010 block_t *p_spu = block_New( p_mux, 3 );
1012 p_spu->i_dts = p_spu->i_pts = i_spu_dts + i_spu_length;
1013 p_spu->i_length = 1000;
1015 p_spu->p_buffer[0] = 0;
1016 p_spu->p_buffer[1] = 1;
1017 p_spu->p_buffer[2] = ' ';
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 );
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;
1038 /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
1039 /* 2: calculate non accurate total size of muxed ts */
1041 for( i = 0; i < p_mux->i_nb_inputs; i++ )
1043 ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
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 )
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 )
1052 mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts;
1058 i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
1060 i_packet_count += ( i_size + 183 ) / 184;
1063 /* add overhead for PCR (not really exact) */
1064 i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176;
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 );
1073 i_packet_count += chain_ts.i_depth;
1074 /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
1080 ts_stream_t *p_stream;
1081 sout_input_t *p_input;
1085 /* Select stream (lowest dts) */
1086 for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
1088 p_input = p_mux->pp_inputs[i];
1089 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
1091 if( p_stream->i_pes_dts == 0 )
1096 if( i_stream == -1 ||
1097 p_stream->i_pes_dts < i_dts )
1100 i_dts = p_stream->i_pes_dts;
1103 if( i_stream == -1 || i_dts > i_pcr_dts + i_pcr_length )
1107 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1109 /* do we need to issue pcr */
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 )
1115 p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count;
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) )
1123 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
1128 BufferChainAppend( &chain_ts, p_ts );
1131 /* 4: date and send */
1132 TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
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 )
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;
1144 BufferChainInit( &new_chain );
1146 if ( i_pcr_length <= 0 )
1148 i_pcr_length = i_packet_count;
1151 for( i = 0; i < i_packet_count; i++ )
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;
1156 BufferChainAppend( &new_chain, p_ts );
1159 p_ts->i_dts + p_sys->i_dts_delay * 2/3 < i_new_dts )
1161 mtime_t i_max_diff = i_new_dts - p_ts->i_dts;
1162 mtime_t i_cut_dts = p_ts->i_dts;
1164 p_ts = BufferChainPeek( p_chain_ts );
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 )
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 );
1174 p_ts = BufferChainPeek( p_chain_ts );
1176 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
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,
1185 if ( p_chain_ts->i_depth )
1187 p_chain_ts, i_pcr_dts + i_pcr_length - i_cut_dts,
1193 if ( new_chain.i_depth )
1194 TSDate( p_mux, &new_chain, i_pcr_length, i_pcr_dts );
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 )
1200 sout_mux_sys_t *p_sys = p_mux->p_sys;
1201 int i_packet_count = p_chain_ts->i_depth;
1204 if ( i_pcr_length / 1000 > 0 )
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 )
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);
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);
1227 /* This shouldn't happen, but happens in some rare heavy load
1228 * and packet losses conditions. */
1229 i_pcr_length = i_packet_count;
1232 /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
1233 for( i = 0; i < i_packet_count; i++ )
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;
1238 p_ts->i_dts = i_new_dts;
1239 p_ts->i_length = i_pcr_length / i_packet_count;
1241 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_PCR )
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 );
1246 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_CSA )
1248 csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
1252 p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
1254 sout_AccessOutWrite( p_mux->p_access, p_ts );
1258 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr )
1260 block_t *p_pes = p_stream->chain_pes.p_first;
1263 vlc_bool_t b_new_pes = VLC_FALSE;
1264 vlc_bool_t b_adaptation_field = VLC_FALSE;
1266 int i_payload_max = 184 - ( b_pcr ? 8 : 0 );
1269 if( p_stream->i_pes_used <= 0 )
1271 b_new_pes = VLC_TRUE;
1273 i_payload = __MIN( (int)p_pes->i_buffer - p_stream->i_pes_used, i_payload_max );
1275 if( b_pcr || i_payload < i_payload_max )
1277 b_adaptation_field = VLC_TRUE;
1280 p_ts = block_New( p_mux, 188 );
1281 p_ts->i_dts = p_pes->i_dts;
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;
1288 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1290 if( b_adaptation_field )
1296 int i_stuffing = i_payload_max - i_payload;
1298 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
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;
1309 for( i = 12; i < 12 + i_stuffing; i++ )
1311 p_ts->p_buffer[i] = 0xff;
1316 int i_stuffing = i_payload_max - i_payload;
1318 p_ts->p_buffer[4] = i_stuffing - 1;
1319 if( i_stuffing > 1 )
1321 p_ts->p_buffer[5] = 0x00;
1322 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1324 p_ts->p_buffer[i] = 0xff;
1331 memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
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;
1337 if( p_stream->i_pes_used >= (int)p_pes->i_buffer )
1339 p_pes = BufferChainGet( &p_stream->chain_pes );
1340 block_Release( p_pes );
1342 p_pes = p_stream->chain_pes.p_first;
1345 p_stream->i_pes_dts = p_pes->i_dts;
1346 p_stream->i_pes_length = 0;
1349 p_stream->i_pes_length += p_pes->i_length;
1351 p_pes = p_pes->p_next;
1356 p_stream->i_pes_dts = 0;
1357 p_stream->i_pes_length = 0;
1359 p_stream->i_pes_used = 0;
1366 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
1368 mtime_t i_pcr = 9 * i_dts / 100;
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;
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 )
1380 sout_mux_sys_t *p_sys = p_mux->p_sys;
1381 sout_buffer_chain_t s = *c;
1384 int i_packets_min = 0;
1385 int i_packets_max = 0;
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;
1396 if( i_packets < i_packets_min && i_packets_min > 0 )
1399 int i_div = ( i_packets_min - i_packets ) / i_packets;
1400 int i_mod = ( i_packets_min - i_packets ) % i_packets;
1403 /* We need to pad with null packets (pid=0x1fff)
1404 * We try to melt null packets with true packets */
1406 "packets=%d but min=%d -> adding %d packets of padding",
1407 i_packets, i_packets_min, i_packets_min - i_packets );
1409 BufferChainInit( c );
1410 while( ( p_pk = BufferChainGet( &s ) ) )
1414 BufferChainAppend( c, p_pk );
1416 i_null = i_div + ( i_rest + i_mod ) / i_packets;
1418 for( i = 0; i < i_null; i++ )
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;
1431 BufferChainAppend( c, p_null );
1434 i_rest = ( i_rest + i_mod ) % i_packets;
1437 else if( i_packets > i_packets_max && i_packets_max > 0 )
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 */
1446 "packets=%d but max=%d -> removing %d packets -> stream broken",
1447 i_packets, i_packets_max, i_packets - i_packets_max );
1449 BufferChainInit( c );
1450 for( i = 0; i < i_packets_max; i++ )
1452 BufferChainAppend( c, BufferChainGet( &s ) );
1455 while( ( p_pk = BufferChainGet( &s ) ) )
1457 sout_BufferDelete( p_mux->p_sout, p_pk );
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 )
1471 /* get PES total size */
1472 i_size = p_pes->i_buffer;
1473 p_data = p_pes->p_buffer;
1475 b_new_pes = VLC_TRUE;
1479 int b_adaptation_field;
1483 p_ts = block_New( p_sout, 188 );
1486 * 1b transport_error_indicator
1487 * 1b payload_unit_start
1488 * 1b transport_priority
1490 * 2b transport_scrambling_control
1491 * 2b if adaptation_field 0x03 else 0x01
1492 * 4b continuity_counter
1495 i_copy = __MIN( i_size, 184 );
1496 b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
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;
1505 b_new_pes = VLC_FALSE;
1506 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1508 if( b_adaptation_field )
1510 int i_stuffing = 184 - i_copy;
1513 p_ts->p_buffer[4] = i_stuffing - 1;
1514 if( i_stuffing > 1 )
1516 p_ts->p_buffer[5] = 0x00;
1517 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1519 p_ts->p_buffer[i] = 0xff;
1524 memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1528 BufferChainAppend( c, p_ts );
1532 block_t *p_next = p_pes->p_next;
1534 p_pes->p_next = NULL;
1535 block_Release( p_pes );
1536 if( p_next == NULL )
1540 b_new_pes = VLC_TRUE;
1542 i_size = p_pes->i_buffer;
1543 p_data = p_pes->p_buffer;
1550 #if defined MODULE_NAME_IS_mux_ts
1551 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1553 static uint32_t CRC32[256] =
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
1621 uint32_t i_crc = 0xffffffff;
1623 /* Calculate the CRC */
1624 while( i_count > 0 )
1626 i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1634 static void GetPAT( sout_mux_t *p_mux,
1635 sout_buffer_chain_t *c )
1637 sout_mux_sys_t *p_sys = p_mux->p_sys;
1641 p_pat = block_New( p_mux, 1024 );
1645 p_pat->i_length = 0;
1647 bits_initwrite( &bits, 1024, p_pat->p_buffer );
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
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
1666 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1668 p_pat->i_buffer = bits.i_data;
1670 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1673 static void GetPMT( sout_mux_t *p_mux,
1674 sout_buffer_chain_t *c )
1676 sout_mux_sys_t *p_sys = p_mux->p_sys;
1681 p_pmt = block_New( p_mux, 1024 );
1685 p_pmt->i_length = 0;
1687 bits_initwrite( &bits, 1024, p_pmt->p_buffer );
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
1702 bits_write( &bits, 3, 0 ); // reserved
1704 bits_write( &bits, 13, p_sys->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
1705 bits_write( &bits, 4, 0 ); // reserved FIXME
1707 bits_write( &bits, 12, 0 ); // program info len FIXME
1709 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1711 ts_stream_t *p_stream;
1713 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
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
1722 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1724 p_pmt->i_buffer = bits.i_data;
1726 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1728 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1730 static block_t *WritePSISection( sout_instance_t *p_sout,
1731 dvbpsi_psi_section_t* p_section )
1733 block_t *p_psi, *p_first = NULL;
1740 i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1741 ( p_section->b_syntax_indicator ? 4 : 0 );
1743 p_psi = block_New( p_sout, i_size + 1 );
1746 p_psi->i_length = 0;
1747 p_psi->i_buffer = i_size + 1;
1749 p_psi->p_buffer[0] = 0; // pointer
1750 memcpy( p_psi->p_buffer + 1,
1754 block_ChainAppend( &p_first, p_psi );
1756 p_section = p_section->p_next;
1762 static void GetPAT( sout_mux_t *p_mux,
1763 sout_buffer_chain_t *c )
1765 sout_mux_sys_t *p_sys = p_mux->p_sys;
1768 dvbpsi_psi_section_t *p_section;
1770 dvbpsi_InitPAT( &pat,
1772 p_sys->i_pat_version_number,
1773 1 ); // b_current_next
1774 /* add all program (only one) */
1775 dvbpsi_PATAddProgram( &pat,
1777 p_sys->pmt.i_pid ); // i_pid
1779 p_section = dvbpsi_GenPATSections( &pat,
1780 0 ); // max program per section
1782 p_pat = WritePSISection( p_mux->p_sout, p_section );
1784 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1786 dvbpsi_DeletePSISections( p_section );
1787 dvbpsi_EmptyPAT( &pat );
1790 static uint32_t GetDescriptorLength24b( int i_length )
1792 uint32_t i_l1, i_l2, i_l3;
1794 i_l1 = i_length&0x7f;
1795 i_l2 = ( i_length >> 7 )&0x7f;
1796 i_l3 = ( i_length >> 14 )&0x7f;
1798 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1801 static void GetPMT( sout_mux_t *p_mux,
1802 sout_buffer_chain_t *c )
1804 sout_mux_sys_t *p_sys = p_mux->p_sys;
1808 dvbpsi_pmt_es_t *p_es;
1809 dvbpsi_psi_section_t *p_section;
1813 dvbpsi_InitPMT( &pmt,
1814 0x01, // program number
1815 p_sys->i_pmt_version_number,
1816 1, // b_current_next
1819 if( p_sys->i_mpeg4_streams > 0 )
1823 bits_buffer_t bits_fix_IOD;
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 );
1830 bits_initwrite( &bits, 4096, iod );
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++ )
1849 ts_stream_t *p_stream;
1850 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1852 if( p_stream->i_stream_id == 0xfa ||
1853 p_stream->i_stream_id == 0xfb ||
1854 p_stream->i_stream_id == 0xfe )
1856 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
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
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 )
1875 bits_write( &bits, 8, 0x20 ); // Visual 14496-2
1876 bits_write( &bits, 6, 0x04 ); // VisualStream
1878 else if( p_stream->i_stream_type == 0x11 )
1880 bits_write( &bits, 8, 0x40 ); // Audio 14496-3
1881 bits_write( &bits, 6, 0x05 ); // AudioStream
1883 else if( p_stream->i_stream_type == 0x12 && p_stream->i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) )
1885 bits_write( &bits, 8, 0x0B ); // Text Stream
1886 bits_write( &bits, 6, 0x04 ); // VisualStream
1890 bits_write( &bits, 8, 0x00 );
1891 bits_write( &bits, 6, 0x00 );
1893 msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
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
1901 if( p_stream->i_decoder_specific_info > 0 )
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++ )
1911 bits_write( &bits, 8, ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1914 /* fix Decoder length */
1915 bits_write( &bits_fix_Decoder, 24,
1916 GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
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 );
1929 /* fix ESDescr length */
1930 bits_write( &bits_fix_ESDescr, 24,
1931 GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
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,
1944 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1946 ts_stream_t *p_stream;
1948 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1950 p_es = dvbpsi_PMTAddES( &pmt,
1951 p_stream->i_stream_type,
1953 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
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 );
1962 else if( p_stream->i_stream_type == 0xa0 )
1965 int i_extra = __MIN( p_stream->i_decoder_specific_info,
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;
1978 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1981 /* 0xa0 is private */
1982 dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
1984 else if( p_stream->i_stream_type == 0x81 )
1986 uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1988 /* "registration" descriptor : "AC-3" */
1989 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1992 if( p_stream->lang[0] != 0 )
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 */
2003 dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data );
2007 p_section = dvbpsi_GenPMTSections( &pmt );
2009 p_pmt = WritePSISection( p_mux->p_sout, p_section );
2011 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
2013 dvbpsi_DeletePSISections( p_section );
2014 dvbpsi_EmptyPMT( &pmt );