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>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
32 #include <vlc/input.h>
41 #if defined MODULE_NAME_IS_mux_ts_dvbpsi
42 # ifdef HAVE_DVBPSI_DR_H
43 # include <dvbpsi/dvbpsi.h>
44 # include <dvbpsi/descriptor.h>
45 # include <dvbpsi/pat.h>
46 # include <dvbpsi/pmt.h>
47 # include <dvbpsi/dr.h>
48 # include <dvbpsi/psi.h>
51 # include "descriptor.h"
52 # include "tables/pat.h"
53 # include "tables/pmt.h"
54 # include "descriptors/dr.h"
61 * - check PCR frequency requirement
63 * - check PCR/PCR "soft"
64 * - check if "registration" descriptor : "AC-3" should be a program
65 * descriptor or an es one. (xine want an es one)
67 * - remove creation of PAT/PMT without dvbpsi
70 * - subtitle support is far from perfect. I expect some subtitles drop
71 * if they arrive a bit late
72 * (We cannot rely on the fact that the fifo should be full)
74 /*****************************************************************************
76 *****************************************************************************/
77 static int Open ( vlc_object_t * );
78 static void Close ( vlc_object_t * );
80 #define SOUT_CFG_PREFIX "sout-ts-"
83 #if defined MODULE_NAME_IS_mux_ts
84 set_description( _("TS muxer") );
85 set_capability( "sout mux", 100 );
87 add_shortcut( "ts_nodvbpsi" );
88 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
89 set_description( _("TS muxer (libdvbpsi)") );
90 set_capability( "sout mux", 120 );
92 add_shortcut( "ts_dvbpsi" );
94 add_integer( SOUT_CFG_PREFIX "pid-video", 0, NULL, "Video PID", "", VLC_TRUE );
95 add_integer( SOUT_CFG_PREFIX "pid-audio", 0, NULL, "Audio PID", "", VLC_TRUE );
97 add_integer( SOUT_CFG_PREFIX "bmin", 0, NULL, "Minimum bitrate", "", VLC_TRUE );
98 add_integer( SOUT_CFG_PREFIX "bmax", 0, NULL, "Maximum bitrate", "", VLC_TRUE );
100 add_integer( SOUT_CFG_PREFIX "shaping", 200, NULL, "Shapping delay(ms)", "", VLC_TRUE );
101 add_integer( SOUT_CFG_PREFIX "pcr", 30, NULL, "PCR delay(ms)", "", VLC_TRUE );
102 add_integer( SOUT_CFG_PREFIX "dts-delay", 200, NULL, "DTS delay(ms)", "", VLC_TRUE );
104 add_bool( SOUT_CFG_PREFIX "use-key-frames", VLC_FALSE, NULL, "Use key frame for shaping", "", VLC_TRUE );
106 add_bool( SOUT_CFG_PREFIX "crypt-audio", VLC_TRUE, NULL, "Crypt audio with CSA", "", VLC_TRUE );
108 add_string( SOUT_CFG_PREFIX "csa-ck", "", NULL, "CSA Key", "CSA Key", VLC_TRUE );
110 set_callbacks( Open, Close );
113 /*****************************************************************************
114 * Local data structures
115 *****************************************************************************/
116 static const char *ppsz_sout_options[] = {
117 "pid-video", "pid-audio",
128 #define SOUT_BUFFER_FLAGS_PRIVATE_PCR ( 1 << BLOCK_FLAG_PRIVATE_SHIFT )
129 #define SOUT_BUFFER_FLAGS_PRIVATE_CSA ( 2 << BLOCK_FLAG_PRIVATE_SHIFT )
135 } sout_buffer_chain_t;
137 static inline void BufferChainInit ( sout_buffer_chain_t *c )
141 c->pp_last = &c->p_first;
143 static inline void BufferChainAppend( sout_buffer_chain_t *c, block_t *b )
153 c->pp_last = &b->p_next;
155 static inline block_t *BufferChainGet( sout_buffer_chain_t *c )
157 block_t *b = c->p_first;
162 c->p_first = b->p_next;
164 if( c->p_first == NULL )
166 c->pp_last = &c->p_first;
173 static inline block_t *BufferChainPeek( sout_buffer_chain_t *c )
175 block_t *b = c->p_first;
179 static inline void BufferChainClean( sout_instance_t *p_sout, sout_buffer_chain_t *c )
183 while( ( b = BufferChainGet( c ) ) )
187 BufferChainInit( c );
190 typedef struct ts_stream_t
195 int i_continuity_counter;
197 /* to be used for carriege of DIV3 */
198 vlc_fourcc_t i_bih_codec;
199 int i_bih_width, i_bih_height;
201 /* Specific to mpeg4 in mpeg2ts */
204 int i_decoder_specific_info;
205 uint8_t *p_decoder_specific_info;
207 /* language is iso639-2T */
210 sout_buffer_chain_t chain_pes;
212 mtime_t i_pes_length;
214 vlc_bool_t b_key_frame;
218 struct sout_mux_sys_t
221 sout_input_t *p_pcr_input;
228 int i_pid_free; // first usable pid
230 int i_pat_version_number;
233 int i_pmt_version_number;
234 ts_stream_t pmt; // Up to now only one program
238 int i_null_continuity_counter; /* Needed ? */
240 /* for TS building */
241 int64_t i_bitrate_min;
242 int64_t i_bitrate_max;
244 int64_t i_shaping_delay;
249 vlc_bool_t b_use_key_frames;
251 mtime_t i_pcr; /* last PCR emited */
254 vlc_bool_t b_crypt_audio;
258 /* Reserve a pid and return it */
259 static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
262 if ( i_cat == VIDEO_ES && p_sys->i_pid_video )
264 i_pid = p_sys->i_pid_video;
265 p_sys->i_pid_video = 0;
267 else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio )
269 i_pid = p_sys->i_pid_audio;
270 p_sys->i_pid_audio = 0;
274 i_pid = ++p_sys->i_pid_free;
279 /*****************************************************************************
281 *****************************************************************************/
282 static int Capability(sout_mux_t *, int, void *, void * );
283 static int AddStream( sout_mux_t *, sout_input_t * );
284 static int DelStream( sout_mux_t *, sout_input_t * );
285 static int Mux ( sout_mux_t * );
287 static void TSSchedule ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
288 mtime_t i_pcr_length, mtime_t i_pcr_dts );
289 static void TSDate ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
290 mtime_t i_pcr_length, mtime_t i_pcr_dts );
291 static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
292 static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
294 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr );
295 static void TSSetPCR( block_t *p_ts, mtime_t i_dts );
297 static void PEStoTS ( sout_instance_t *, sout_buffer_chain_t *, block_t *, ts_stream_t * );
299 /*****************************************************************************
301 *****************************************************************************/
302 static int Open( vlc_object_t *p_this )
304 sout_mux_t *p_mux =(sout_mux_t*)p_this;
305 sout_mux_sys_t *p_sys;
308 msg_Dbg( p_mux, "Open" );
309 sout_ParseCfg( p_mux, SOUT_CFG_PREFIX, ppsz_sout_options, p_mux->p_cfg );
311 p_sys = malloc( sizeof( sout_mux_sys_t ) );
313 p_mux->pf_capacity = Capability;
314 p_mux->pf_addstream = AddStream;
315 p_mux->pf_delstream = DelStream;
317 p_mux->p_sys = p_sys;
319 srand( (uint32_t)mdate() );
321 p_sys->i_audio_bound = 0;
322 p_sys->i_video_bound = 0;
324 p_sys->i_pat_version_number = rand() % 32;
325 p_sys->pat.i_pid = 0;
326 p_sys->pat.i_continuity_counter = 0;
328 p_sys->i_pmt_version_number = rand() % 32;
329 p_sys->pmt.i_pid = 0x42;
330 p_sys->pmt.i_continuity_counter = 0;
332 p_sys->i_pid_free = 0x43;
334 var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );
335 p_sys->i_pid_video = val.i_int;
336 if ( p_sys->i_pid_video > p_sys->i_pid_free )
338 p_sys->i_pid_free = p_sys->i_pid_video + 1;
341 var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );
342 p_sys->i_pid_audio = val.i_int;
343 if ( p_sys->i_pid_audio > p_sys->i_pid_free )
345 p_sys->i_pid_free = p_sys->i_pid_audio + 1;
348 p_sys->i_pcr_pid = 0x1fff;
349 p_sys->p_pcr_input = NULL;
351 p_sys->i_mpeg4_streams = 0;
353 p_sys->i_null_continuity_counter = 0;
355 /* Allow to create constrained stream */
356 var_Get( p_mux, SOUT_CFG_PREFIX "bmin", &val );
357 p_sys->i_bitrate_min = val.i_int;
359 var_Get( p_mux, SOUT_CFG_PREFIX "bmax", &val );
360 p_sys->i_bitrate_max = val.i_int;
362 if( p_sys->i_bitrate_min > 0 && p_sys->i_bitrate_max > 0 &&
363 p_sys->i_bitrate_min > p_sys->i_bitrate_max )
365 msg_Err( p_mux, "incompatible minimum and maximum bitrate, "
366 "disabling bitrate control" );
367 p_sys->i_bitrate_min = 0;
368 p_sys->i_bitrate_max = 0;
370 if( p_sys->i_bitrate_min > 0 || p_sys->i_bitrate_max > 0 )
372 msg_Err( p_mux, "bmin and bmax no more supported (if you need them report it)" );
375 var_Get( p_mux, SOUT_CFG_PREFIX "shaping", &val );
376 p_sys->i_shaping_delay = (int64_t)val.i_int * 1000;
377 if( p_sys->i_shaping_delay <= 0 )
380 "invalid shaping ("I64Fd"ms) reseting to 200ms",
381 p_sys->i_shaping_delay / 1000 );
382 p_sys->i_shaping_delay = 200000;
385 var_Get( p_mux, SOUT_CFG_PREFIX "pcr", &val );
386 p_sys->i_pcr_delay = (int64_t)val.i_int * 1000;
387 if( p_sys->i_pcr_delay <= 0 ||
388 p_sys->i_pcr_delay >= p_sys->i_shaping_delay )
391 "invalid pcr delay ("I64Fd"ms) reseting to 30ms",
392 p_sys->i_pcr_delay / 1000 );
393 p_sys->i_pcr_delay = 30000;
396 var_Get( p_mux, SOUT_CFG_PREFIX "dts-delay", &val );
397 p_sys->i_dts_delay = (int64_t)val.i_int * 1000;
399 msg_Dbg( p_mux, "shaping="I64Fd" pcr="I64Fd" dts_delay="I64Fd,
400 p_sys->i_shaping_delay, p_sys->i_pcr_delay, p_sys->i_dts_delay );
402 var_Get( p_mux, SOUT_CFG_PREFIX "use-key-frames", &val );
403 p_sys->b_use_key_frames = val.b_bool;
405 /* for TS generation */
409 var_Get( p_mux, SOUT_CFG_PREFIX "csa-ck", &val );
412 char *psz = val.psz_string;
415 if( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) )
419 if( strlen( psz ) != 16 )
421 msg_Dbg( p_mux, "invalid csa ck (it must be 16 chars long)" );
425 uint64_t i_ck = strtoll( psz, NULL, 16 );
429 for( i = 0; i < 8; i++ )
431 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
434 msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x",
435 ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
437 p_sys->csa = csa_New();
438 csa_SetCW( p_sys->csa, ck, ck );
441 if( val.psz_string ) free( val.psz_string );
443 var_Get( p_mux, SOUT_CFG_PREFIX "crypt-audio", &val );
444 p_sys->b_crypt_audio = val.b_bool;
449 /*****************************************************************************
451 *****************************************************************************/
452 static void Close( vlc_object_t * p_this )
454 sout_mux_t *p_mux = (sout_mux_t*)p_this;
455 sout_mux_sys_t *p_sys = p_mux->p_sys;
457 msg_Dbg( p_mux, "Close" );
460 csa_Delete( p_sys->csa );
466 /*****************************************************************************
468 *****************************************************************************/
469 static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
473 case SOUT_MUX_CAP_GET_ADD_STREAM_ANY_TIME:
474 *(vlc_bool_t*)p_answer = VLC_TRUE;
475 return( SOUT_MUX_CAP_ERR_OK );
477 return( SOUT_MUX_CAP_ERR_UNIMPLEMENTED );
481 /*****************************************************************************
482 * AddStream: called for each stream addition
483 *****************************************************************************/
484 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
486 sout_mux_sys_t *p_sys = p_mux->p_sys;
487 ts_stream_t *p_stream;
489 p_input->p_sys = p_stream = malloc( sizeof( ts_stream_t ) );
491 /* Init this new stream */
492 p_stream->i_pid = AllocatePID( p_sys, p_input->p_fmt->i_cat );
493 p_stream->i_continuity_counter = 0;
494 p_stream->i_decoder_specific_info = 0;
495 p_stream->p_decoder_specific_info = NULL;
497 msg_Dbg( p_mux, "adding input codec=%4.4s pid=%d", (char*)&p_input->p_fmt->i_codec, p_stream->i_pid );
499 /* All others fields depand on codec */
500 switch( p_input->p_fmt->i_cat )
503 switch( p_input->p_fmt->i_codec )
505 case VLC_FOURCC( 'm', 'p','g', 'v' ):
506 /* TODO: do we need to check MPEG-I/II ? */
507 p_stream->i_stream_type = 0x02;
508 p_stream->i_stream_id = 0xe0;
510 case VLC_FOURCC( 'm', 'p','4', 'v' ):
511 p_stream->i_stream_type = 0x10;
512 p_stream->i_stream_id = 0xfa;
513 p_sys->i_mpeg4_streams++;
514 p_stream->i_es_id = p_stream->i_pid;
516 case VLC_FOURCC( 'h', '2','6', '4' ):
517 p_stream->i_stream_type = 0x1b;
518 p_stream->i_stream_id = 0xe0;
520 /* XXX dirty dirty but somebody want that : using crapy MS-codec XXX */
521 /* I didn't want to do that :P */
522 case VLC_FOURCC( 'H', '2', '6', '3' ):
523 case VLC_FOURCC( 'I', '2', '6', '3' ):
524 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
525 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
526 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
527 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
528 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
529 case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
530 p_stream->i_stream_type = 0xa0; // private
531 p_stream->i_stream_id = 0xa0; // beurk
532 p_stream->i_bih_codec = p_input->p_fmt->i_codec;
533 p_stream->i_bih_width = p_input->p_fmt->video.i_width;
534 p_stream->i_bih_height = p_input->p_fmt->video.i_height;
540 p_sys->i_video_bound++;
544 switch( p_input->p_fmt->i_codec )
546 case VLC_FOURCC( 'm', 'p','g', 'a' ):
547 p_stream->i_stream_type = p_input->p_fmt->audio.i_rate >= 32000 ? 0x03 : 0x04;
548 p_stream->i_stream_id = 0xc0;
550 case VLC_FOURCC( 'a', '5','2', ' ' ):
551 p_stream->i_stream_type = 0x81;
552 p_stream->i_stream_id = 0xbd;
554 case VLC_FOURCC( 'l', 'p','c', 'm' ):
555 p_stream->i_stream_type = 0x83;
556 p_stream->i_stream_id = 0xbd;
558 case VLC_FOURCC( 'd', 't','s', ' ' ):
559 p_stream->i_stream_type = 0x85;
560 p_stream->i_stream_id = 0xbd;
563 case VLC_FOURCC( 'm', 'p','4', 'a' ):
564 p_stream->i_stream_type = 0x11;
565 p_stream->i_stream_id = 0xfa;
566 p_sys->i_mpeg4_streams++;
567 p_stream->i_es_id = p_stream->i_pid;
573 p_sys->i_audio_bound++;
577 switch( p_input->p_fmt->i_codec )
579 case VLC_FOURCC( 's', 'p','u', ' ' ):
580 p_stream->i_stream_type = 0x82;
581 p_stream->i_stream_id = 0xbd;
596 p_stream->lang[2] = '\0';
597 if( p_input->p_fmt->psz_language )
599 char *psz = p_input->p_fmt->psz_language;
600 const iso639_lang_t *pl = NULL;
602 if( strlen( psz ) == 2 )
604 pl = GetLang_1( psz );
606 else if( strlen( psz ) == 3 )
608 pl = GetLang_2B( psz );
609 if( !strcmp( pl->psz_iso639_1, "??" ) )
611 pl = GetLang_2T( psz );
614 if( pl && strcmp( pl->psz_iso639_1, "??" ) )
616 p_stream->lang[0] = pl->psz_iso639_2T[0];
617 p_stream->lang[1] = pl->psz_iso639_2T[1];
618 p_stream->lang[2] = pl->psz_iso639_2T[2];
620 msg_Dbg( p_mux, " - lang=%c%c%c",
628 /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
629 p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
630 if( p_stream->i_decoder_specific_info > 0 )
632 p_stream->p_decoder_specific_info =
633 malloc( p_stream->i_decoder_specific_info );
634 memcpy( p_stream->p_decoder_specific_info,
635 p_input->p_fmt->p_extra,
636 p_input->p_fmt->i_extra );
640 BufferChainInit( &p_stream->chain_pes );
641 p_stream->i_pes_dts = 0;
642 p_stream->i_pes_length = 0;
643 p_stream->i_pes_used = 0;
644 p_stream->b_key_frame = 0;
646 /* We only change PMT version (PAT isn't changed) */
647 p_sys->i_pmt_version_number = ( p_sys->i_pmt_version_number + 1 )%32;
650 if( p_input->p_fmt->i_cat != SPU_ES &&
651 ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) )
653 if( p_sys->p_pcr_input )
655 /* There was already a PCR stream, so clean context */
658 p_sys->i_pcr_pid = p_stream->i_pid;
659 p_sys->p_pcr_input = p_input;
661 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
667 /*****************************************************************************
668 * DelStream: called before a stream deletion
669 *****************************************************************************/
670 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
672 sout_mux_sys_t *p_sys = p_mux->p_sys;
673 ts_stream_t *p_stream;
676 p_stream = (ts_stream_t*)p_input->p_sys;
677 msg_Dbg( p_mux, "removing input pid=%d", p_stream->i_pid );
679 if( p_sys->i_pcr_pid == p_stream->i_pid )
683 /* Find a new pcr stream (Prefer Video Stream) */
684 p_sys->i_pcr_pid = 0x1fff;
685 p_sys->p_pcr_input = NULL;
686 for( i = 0; i < p_mux->i_nb_inputs; i++ )
688 if( p_mux->pp_inputs[i] == p_input )
693 if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
696 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
697 p_sys->p_pcr_input= p_mux->pp_inputs[i];
700 else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
701 p_sys->i_pcr_pid == 0x1fff )
704 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
705 p_sys->p_pcr_input= p_mux->pp_inputs[i];
708 if( p_sys->p_pcr_input )
710 /* Empty TS buffer */
713 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
716 /* Empty all data in chain_pes */
717 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
719 if( p_stream->p_decoder_specific_info )
721 free( p_stream->p_decoder_specific_info );
723 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
725 p_sys->i_mpeg4_streams--;
728 var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val );
731 int i_pid_video = val.i_int;
732 if ( i_pid_video == p_stream->i_pid )
734 p_sys->i_pid_video = i_pid_video;
735 msg_Dbg( p_mux, "freeing video PID %d", i_pid_video );
738 var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val );
741 int i_pid_audio = val.i_int;
742 if ( i_pid_audio == p_stream->i_pid )
744 p_sys->i_pid_audio = i_pid_audio;
745 msg_Dbg( p_mux, "freeing audio PID %d", i_pid_audio );
750 /* We only change PMT version (PAT isn't changed) */
751 p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
756 /*****************************************************************************
757 * Mux: Call each time there is new data for at least one stream
758 *****************************************************************************
760 *****************************************************************************/
761 static int Mux( sout_mux_t *p_mux )
763 sout_mux_sys_t *p_sys = p_mux->p_sys;
764 ts_stream_t *p_pcr_stream;
766 if( p_sys->i_pcr_pid == 0x1fff )
768 msg_Dbg( p_mux, "waiting for PCR streams" );
772 p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
776 sout_buffer_chain_t chain_ts;
780 mtime_t i_pcr_length;
781 mtime_t i_shaping_delay;
784 if( p_pcr_stream->b_key_frame )
786 i_shaping_delay = p_pcr_stream->i_pes_length;
790 i_shaping_delay = p_sys->i_shaping_delay;
793 /* 1: get enough PES packet for all input */
796 vlc_bool_t b_ok = VLC_TRUE;
799 /* Accumulate enough data in the pcr stream (>i_shaping_delay) */
800 /* Accumulate enough data in all other stream ( >= length of pcr) */
801 for( i = 0; i < p_mux->i_nb_inputs; i++ )
803 sout_input_t *p_input = p_mux->pp_inputs[i];
804 ts_stream_t *p_stream = (ts_stream_t*)p_input->p_sys;
806 if( ( p_stream == p_pcr_stream
807 && p_stream->i_pes_length < i_shaping_delay ) ||
808 p_stream->i_pes_dts + p_stream->i_pes_length
809 < p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
812 if( p_input->p_fifo->i_depth <= 1 )
814 if( p_input->p_fmt->i_cat == AUDIO_ES ||
815 p_input->p_fmt->i_cat == VIDEO_ES )
817 /* We need more data */
820 else if( p_input->p_fifo->i_depth <= 0 )
822 /* spu, only one packet is needed */
828 p_data = block_FifoGet( p_input->p_fifo );
829 if( p_input->p_fifo->i_depth > 0 )
831 block_t *p_next = block_FifoShow( p_input->p_fifo );
833 p_data->i_length = p_next->i_dts - p_data->i_dts;
836 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 ) ||
837 p_data->i_dts < p_stream->i_pes_dts ||
838 ( p_stream->i_pes_dts > 0 && p_data->i_dts - 2000000 > p_stream->i_pes_dts + p_stream->i_pes_length ) )
840 msg_Warn( p_mux, "packet with too strange dts (dts=%lld,old=%lld,pcr=%lld)",
843 p_pcr_stream->i_pes_dts );
844 block_Release( p_data );
846 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
847 p_stream->i_pes_dts = 0;
848 p_stream->i_pes_used = 0;
849 p_stream->i_pes_length = 0;
851 BufferChainClean( p_mux->p_sout, &p_pcr_stream->chain_pes );
852 p_pcr_stream->i_pes_dts = 0;
853 p_pcr_stream->i_pes_used = 0;
854 p_pcr_stream->i_pes_length = 0;
859 if( p_data->i_length < 0 || p_data->i_length > 2000000 )
861 /* FIXME choose a better value, but anyway we should never
863 p_data->i_length = 1000;
865 p_stream->i_pes_length += p_data->i_length;
866 if( p_stream->i_pes_dts == 0 )
868 p_stream->i_pes_dts = p_data->i_dts;
872 if( p_stream->i_stream_id == 0xa0 && p_data->i_pts <= 0 )
874 /* XXX yes I know, it's awfull, but it's needed, so don't remove it ... */
875 p_data->i_pts = p_data->i_dts;
877 E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 );
879 BufferChainAppend( &p_stream->chain_pes, p_data );
881 if( p_sys->b_use_key_frames && p_stream == p_pcr_stream
882 && (p_data->i_flags & BLOCK_FLAG_TYPE_I )
883 && (p_stream->i_pes_length > 300000) )
885 i_shaping_delay = p_stream->i_pes_length;
886 p_stream->b_key_frame = 1;
899 i_pcr_dts = p_pcr_stream->i_pes_dts;
900 i_pcr_length = p_pcr_stream->i_pes_length;
901 p_pcr_stream->b_key_frame = 0;
903 /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
904 /* 2: calculate non accurate total size of muxed ts */
906 for( i = 0; i < p_mux->i_nb_inputs; i++ )
908 ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
911 /* False for pcr stream but it will be enough to do PCR algo */
912 for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL; p_pes = p_pes->p_next )
914 int i_size = p_pes->i_buffer;
915 if( p_pes->i_dts + p_pes->i_length > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
917 mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts;
923 i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
925 i_packet_count += ( i_size + 183 ) / 184;
928 /* add overhead for PCR (not really exact) */
929 i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176;
932 /* 3: mux PES into TS */
933 BufferChainInit( &chain_ts );
934 /* append PAT/PMT -> FIXME with big pcr delay it won't have enough pat/pmt */
935 GetPAT( p_mux, &chain_ts);
936 GetPMT( p_mux, &chain_ts );
938 i_packet_count += chain_ts.i_depth;
939 /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
945 ts_stream_t *p_stream;
946 sout_input_t *p_input;
950 /* Select stream (lowest dts) */
951 for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
953 p_input = p_mux->pp_inputs[i];
954 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
956 if( p_stream->i_pes_dts == 0 )
961 if( i_stream == -1 ||
962 p_stream->i_pes_dts < i_dts )
965 i_dts = p_stream->i_pes_dts;
972 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
974 /* do we need to issue pcr */
976 if( p_stream == p_pcr_stream &&
977 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >= p_sys->i_pcr + p_sys->i_pcr_delay )
980 p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count;
983 /* Build the TS packet */
984 p_ts = TSNew( p_mux, p_stream, b_pcr );
985 if( p_sys->csa != NULL &&
986 (p_input->p_fmt->i_cat != AUDIO_ES || p_sys->b_crypt_audio) )
988 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
993 BufferChainAppend( &chain_ts, p_ts );
996 /* 4: date and send */
997 TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
1001 static void TSSchedule( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1002 mtime_t i_pcr_length, mtime_t i_pcr_dts )
1004 sout_mux_sys_t *p_sys = p_mux->p_sys;
1005 sout_buffer_chain_t new_chain;
1006 int i_packet_count = p_chain_ts->i_depth;
1009 BufferChainInit( &new_chain );
1011 if ( i_pcr_length <= 0 )
1013 i_pcr_length = i_packet_count;
1016 for( i = 0; i < i_packet_count; i++ )
1018 block_t *p_ts = BufferChainGet( p_chain_ts );
1019 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1021 BufferChainAppend( &new_chain, p_ts );
1024 p_ts->i_dts + p_sys->i_dts_delay * 2/3 < i_new_dts )
1026 mtime_t i_max_diff = i_new_dts - p_ts->i_dts;
1027 mtime_t i_cut_dts = p_ts->i_dts;
1029 p_ts = BufferChainPeek( p_chain_ts );
1031 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1032 while ( p_ts != NULL && i_new_dts - p_ts->i_dts >= i_max_diff )
1034 p_ts = BufferChainGet( p_chain_ts );
1035 i_max_diff = i_new_dts - p_ts->i_dts;
1036 i_cut_dts = p_ts->i_dts;
1037 BufferChainAppend( &new_chain, p_ts );
1039 p_ts = BufferChainPeek( p_chain_ts );
1041 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1043 msg_Dbg( p_mux, "adjusting rate at "I64Fd"/"I64Fd" (%d/%d)",
1044 i_cut_dts - i_pcr_dts, i_pcr_length, new_chain.i_depth,
1045 p_chain_ts->i_depth );
1046 if ( new_chain.i_depth )
1047 TSDate( p_mux, &new_chain,
1048 i_cut_dts - i_pcr_dts,
1050 if ( p_chain_ts->i_depth )
1052 p_chain_ts, i_pcr_dts + i_pcr_length - i_cut_dts,
1058 if ( new_chain.i_depth )
1059 TSDate( p_mux, &new_chain, i_pcr_length, i_pcr_dts );
1062 static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1063 mtime_t i_pcr_length, mtime_t i_pcr_dts )
1065 sout_mux_sys_t *p_sys = p_mux->p_sys;
1066 int i_packet_count = p_chain_ts->i_depth;
1069 if ( i_pcr_length > 0 )
1071 int i_bitrate = ((uint64_t)i_packet_count * 188 * 8000)
1072 / (uint64_t)(i_pcr_length / 1000);
1073 if ( p_sys->i_bitrate_max && p_sys->i_bitrate_max < i_bitrate )
1076 "max bitrate exceeded at %lld (%d bi/s for %d pkt in %lld us)",
1077 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1078 i_bitrate, i_packet_count, i_pcr_length);
1084 "starting at %lld (%d bi/s for %d packets in %lld us)",
1085 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1086 i_bitrate, i_packet_count, i_pcr_length);
1092 /* This shouldn't happen, but happens in some rare heavy load
1093 * and packet losses conditions. */
1094 i_pcr_length = i_packet_count;
1097 /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
1098 for( i = 0; i < i_packet_count; i++ )
1100 block_t *p_ts = BufferChainGet( p_chain_ts );
1101 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1103 p_ts->i_dts = i_new_dts;
1104 p_ts->i_length = i_pcr_length / i_packet_count;
1106 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_PCR )
1108 /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
1109 TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
1111 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_CSA )
1113 csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
1117 p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
1119 sout_AccessOutWrite( p_mux->p_access, p_ts );
1123 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr )
1125 block_t *p_pes = p_stream->chain_pes.p_first;
1128 vlc_bool_t b_new_pes = VLC_FALSE;
1129 vlc_bool_t b_adaptation_field = VLC_FALSE;
1131 int i_payload_max = 184 - ( b_pcr ? 8 : 0 );
1134 if( p_stream->i_pes_used <= 0 )
1136 b_new_pes = VLC_TRUE;
1138 i_payload = __MIN( (int)p_pes->i_buffer - p_stream->i_pes_used, i_payload_max );
1140 if( b_pcr || i_payload < i_payload_max )
1142 b_adaptation_field = VLC_TRUE;
1145 p_ts = block_New( p_mux, 188 );
1146 p_ts->i_dts = p_pes->i_dts;
1148 p_ts->p_buffer[0] = 0x47;
1149 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|( ( p_stream->i_pid >> 8 )&0x1f );
1150 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1151 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|p_stream->i_continuity_counter;
1153 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1155 if( b_adaptation_field )
1161 int i_stuffing = i_payload_max - i_payload;
1163 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
1165 p_ts->p_buffer[4] = 7 + i_stuffing;
1166 p_ts->p_buffer[5] = 0x10; /* flags */
1167 p_ts->p_buffer[6] = ( 0 )&0xff;
1168 p_ts->p_buffer[7] = ( 0 )&0xff;
1169 p_ts->p_buffer[8] = ( 0 )&0xff;
1170 p_ts->p_buffer[9] = ( 0 )&0xff;
1171 p_ts->p_buffer[10]= ( 0 )&0x80;
1172 p_ts->p_buffer[11]= 0;
1174 for( i = 12; i < 12 + i_stuffing; i++ )
1176 p_ts->p_buffer[i] = 0xff;
1181 int i_stuffing = i_payload_max - i_payload;
1183 p_ts->p_buffer[4] = i_stuffing - 1;
1184 if( i_stuffing > 1 )
1186 p_ts->p_buffer[5] = 0x00;
1187 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1189 p_ts->p_buffer[i] = 0xff;
1196 memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
1198 p_stream->i_pes_used += i_payload;
1199 p_stream->i_pes_dts = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_buffer;
1200 p_stream->i_pes_length -= p_pes->i_length * i_payload / p_pes->i_buffer;
1202 if( p_stream->i_pes_used >= (int)p_pes->i_buffer )
1204 p_pes = BufferChainGet( &p_stream->chain_pes );
1205 block_Release( p_pes );
1207 p_pes = p_stream->chain_pes.p_first;
1210 p_stream->i_pes_dts = p_pes->i_dts;
1211 p_stream->i_pes_length = 0;
1214 p_stream->i_pes_length += p_pes->i_length;
1216 p_pes = p_pes->p_next;
1221 p_stream->i_pes_dts = 0;
1222 p_stream->i_pes_length = 0;
1224 p_stream->i_pes_used = 0;
1231 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
1233 mtime_t i_pcr = 9 * i_dts / 100;
1235 p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
1236 p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
1237 p_ts->p_buffer[8] = ( i_pcr >> 9 )&0xff;
1238 p_ts->p_buffer[9] = ( i_pcr >> 1 )&0xff;
1239 p_ts->p_buffer[10]|= ( i_pcr << 7 )&0x80;
1243 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 )
1245 sout_mux_sys_t *p_sys = p_mux->p_sys;
1246 sout_buffer_chain_t s = *c;
1249 int i_packets_min = 0;
1250 int i_packets_max = 0;
1257 i_packets = c->i_depth;
1258 i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000 + 187 ) / 188;
1259 i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000 + 187 ) / 188;
1261 if( i_packets < i_packets_min && i_packets_min > 0 )
1264 int i_div = ( i_packets_min - i_packets ) / i_packets;
1265 int i_mod = ( i_packets_min - i_packets ) % i_packets;
1268 /* We need to pad with null packets (pid=0x1fff)
1269 * We try to melt null packets with true packets */
1271 "packets=%d but min=%d -> adding %d packets of padding",
1272 i_packets, i_packets_min, i_packets_min - i_packets );
1274 BufferChainInit( c );
1275 while( ( p_pk = BufferChainGet( &s ) ) )
1279 BufferChainAppend( c, p_pk );
1281 i_null = i_div + ( i_rest + i_mod ) / i_packets;
1283 for( i = 0; i < i_null; i++ )
1287 p_null = sout_BufferNew( p_mux->p_sout, 188 );
1288 p_null->p_buffer[0] = 0x47;
1289 p_null->p_buffer[1] = 0x1f;
1290 p_null->p_buffer[2] = 0xff;
1291 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
1292 memset( &p_null->p_buffer[4], 0, 184 );
1293 p_sys->i_null_continuity_counter =
1294 ( p_sys->i_null_continuity_counter + 1 ) % 16;
1296 BufferChainAppend( c, p_null );
1299 i_rest = ( i_rest + i_mod ) % i_packets;
1302 else if( i_packets > i_packets_max && i_packets_max > 0 )
1307 /* Arg, we need to drop packets, I don't do something clever (like
1308 * dropping complete pid, b frames, ... ), I just get the right amount
1309 * of packets and discard the others */
1311 "packets=%d but max=%d -> removing %d packets -> stream broken",
1312 i_packets, i_packets_max, i_packets - i_packets_max );
1314 BufferChainInit( c );
1315 for( i = 0; i < i_packets_max; i++ )
1317 BufferChainAppend( c, BufferChainGet( &s ) );
1320 while( ( p_pk = BufferChainGet( &s ) ) )
1322 sout_BufferDelete( p_mux->p_sout, p_pk );
1328 static void PEStoTS( sout_instance_t *p_sout,
1329 sout_buffer_chain_t *c, block_t *p_pes,
1330 ts_stream_t *p_stream )
1336 /* get PES total size */
1337 i_size = p_pes->i_buffer;
1338 p_data = p_pes->p_buffer;
1340 b_new_pes = VLC_TRUE;
1344 int b_adaptation_field;
1348 p_ts = block_New( p_sout, 188 );
1351 * 1b transport_error_indicator
1352 * 1b payload_unit_start
1353 * 1b transport_priority
1355 * 2b transport_scrambling_control
1356 * 2b if adaptation_field 0x03 else 0x01
1357 * 4b continuity_counter
1360 i_copy = __MIN( i_size, 184 );
1361 b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
1363 p_ts->p_buffer[0] = 0x47;
1364 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
1365 ( ( p_stream->i_pid >> 8 )&0x1f );
1366 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1367 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
1368 p_stream->i_continuity_counter;
1370 b_new_pes = VLC_FALSE;
1371 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1373 if( b_adaptation_field )
1375 int i_stuffing = 184 - i_copy;
1378 p_ts->p_buffer[4] = i_stuffing - 1;
1379 if( i_stuffing > 1 )
1381 p_ts->p_buffer[5] = 0x00;
1382 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1384 p_ts->p_buffer[i] = 0xff;
1389 memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1393 BufferChainAppend( c, p_ts );
1397 block_t *p_next = p_pes->p_next;
1399 p_pes->p_next = NULL;
1400 block_Release( p_pes );
1401 if( p_next == NULL )
1405 b_new_pes = VLC_TRUE;
1407 i_size = p_pes->i_buffer;
1408 p_data = p_pes->p_buffer;
1415 #if defined MODULE_NAME_IS_mux_ts
1416 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1418 static uint32_t CRC32[256] =
1420 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1421 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1422 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1423 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1424 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1425 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1426 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1427 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1428 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1429 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1430 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1431 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1432 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1433 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1434 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1435 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1436 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1437 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1438 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1439 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1440 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1441 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1442 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1443 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1444 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1445 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1446 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1447 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1448 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1449 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1450 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1451 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1452 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1453 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1454 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1455 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1456 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1457 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1458 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1459 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1460 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1461 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1462 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1463 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1464 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1465 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1466 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1467 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1468 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1469 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1470 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1471 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1472 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1473 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1474 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1475 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1476 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1477 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1478 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1479 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1480 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1481 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1482 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1483 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1486 uint32_t i_crc = 0xffffffff;
1488 /* Calculate the CRC */
1489 while( i_count > 0 )
1491 i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1499 static void GetPAT( sout_mux_t *p_mux,
1500 sout_buffer_chain_t *c )
1502 sout_mux_sys_t *p_sys = p_mux->p_sys;
1506 p_pat = block_New( p_mux, 1024 );
1510 p_pat->i_length = 0;
1512 bits_initwrite( &bits, 1024, p_pat->p_buffer );
1514 bits_write( &bits, 8, 0 ); // pointer
1515 bits_write( &bits, 8, 0x00 ); // table id
1516 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1517 bits_write( &bits, 1, 0 ); // 0
1518 bits_write( &bits, 2, 0x03 ); // reserved FIXME
1519 bits_write( &bits, 12, 13 ); // XXX for one program only XXX
1520 bits_write( &bits, 16, 0x01 ); // FIXME stream id
1521 bits_write( &bits, 2, 0x03 ); // FIXME
1522 bits_write( &bits, 5, p_sys->i_pat_version_number );
1523 bits_write( &bits, 1, 1 ); // current_next_indicator
1524 bits_write( &bits, 8, 0 ); // section number
1525 bits_write( &bits, 8, 0 ); // last section number
1527 bits_write( &bits, 16, 1 ); // program number
1528 bits_write( &bits, 3, 0x07 ); // reserved
1529 bits_write( &bits, 13, p_sys->pmt.i_pid ); // program map pid
1531 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1533 p_pat->i_buffer = bits.i_data;
1535 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1538 static void GetPMT( sout_mux_t *p_mux,
1539 sout_buffer_chain_t *c )
1541 sout_mux_sys_t *p_sys = p_mux->p_sys;
1546 p_pmt = block_New( p_mux, 1024 );
1550 p_pmt->i_length = 0;
1552 bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1554 bits_write( &bits, 8, 0 ); // pointer
1555 bits_write( &bits, 8, 0x02 ); // table id
1556 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1557 bits_write( &bits, 1, 0 ); // 0
1558 bits_write( &bits, 2, 0 ); // reserved FIXME
1559 bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1560 bits_write( &bits, 16, 1 ); // FIXME program number
1561 bits_write( &bits, 2, 0 ); // FIXME
1562 bits_write( &bits, 5, p_sys->i_pmt_version_number );
1563 bits_write( &bits, 1, 1 ); // current_next_indicator
1564 bits_write( &bits, 8, 0 ); // section number
1565 bits_write( &bits, 8, 0 ); // last section number
1567 bits_write( &bits, 3, 0 ); // reserved
1569 bits_write( &bits, 13, p_sys->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
1570 bits_write( &bits, 4, 0 ); // reserved FIXME
1572 bits_write( &bits, 12, 0 ); // program info len FIXME
1574 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1576 ts_stream_t *p_stream;
1578 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1580 bits_write( &bits, 8, p_stream->i_stream_type ); // stream_type
1581 bits_write( &bits, 3, 0 ); // reserved
1582 bits_write( &bits, 13, p_stream->i_pid ); // es pid
1583 bits_write( &bits, 4, 0 ); //reserved
1584 bits_write( &bits, 12, 0 ); // es info len FIXME
1587 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1589 p_pmt->i_buffer = bits.i_data;
1591 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1593 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1595 static block_t *WritePSISection( sout_instance_t *p_sout,
1596 dvbpsi_psi_section_t* p_section )
1598 block_t *p_psi, *p_first = NULL;
1605 i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1606 ( p_section->b_syntax_indicator ? 4 : 0 );
1608 p_psi = block_New( p_sout, i_size + 1 );
1611 p_psi->i_length = 0;
1612 p_psi->i_buffer = i_size + 1;
1614 p_psi->p_buffer[0] = 0; // pointer
1615 memcpy( p_psi->p_buffer + 1,
1619 block_ChainAppend( &p_first, p_psi );
1621 p_section = p_section->p_next;
1627 static void GetPAT( sout_mux_t *p_mux,
1628 sout_buffer_chain_t *c )
1630 sout_mux_sys_t *p_sys = p_mux->p_sys;
1633 dvbpsi_psi_section_t *p_section;
1635 dvbpsi_InitPAT( &pat,
1637 p_sys->i_pat_version_number,
1638 1 ); // b_current_next
1639 /* add all program (only one) */
1640 dvbpsi_PATAddProgram( &pat,
1642 p_sys->pmt.i_pid ); // i_pid
1644 p_section = dvbpsi_GenPATSections( &pat,
1645 0 ); // max program per section
1647 p_pat = WritePSISection( p_mux->p_sout, p_section );
1649 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1651 dvbpsi_DeletePSISections( p_section );
1652 dvbpsi_EmptyPAT( &pat );
1655 static uint32_t GetDescriptorLength24b( int i_length )
1657 uint32_t i_l1, i_l2, i_l3;
1659 i_l1 = i_length&0x7f;
1660 i_l2 = ( i_length >> 7 )&0x7f;
1661 i_l3 = ( i_length >> 14 )&0x7f;
1663 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1666 static void GetPMT( sout_mux_t *p_mux,
1667 sout_buffer_chain_t *c )
1669 sout_mux_sys_t *p_sys = p_mux->p_sys;
1673 dvbpsi_pmt_es_t *p_es;
1674 dvbpsi_psi_section_t *p_section;
1678 dvbpsi_InitPMT( &pmt,
1679 0x01, // program number
1680 p_sys->i_pmt_version_number,
1681 1, // b_current_next
1684 if( p_sys->i_mpeg4_streams > 0 )
1688 bits_buffer_t bits_fix_IOD;
1690 /* Make valgrind happy : it works at byte level not bit one so
1691 * bit_write confuse it (but DON'T CHANGE the way that bit_write is
1692 * working (needed when fixing some bits) */
1693 memset( iod, 0, 4096 );
1695 bits_initwrite( &bits, 4096, iod );
1697 bits_write( &bits, 8, 0x01 );
1698 // InitialObjectDescriptor
1699 bits_align( &bits );
1700 bits_write( &bits, 8, 0x02 ); // tag
1701 bits_fix_IOD = bits; // save states to fix length later
1702 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1703 bits_write( &bits, 10, 0x01 ); // ObjectDescriptorID
1704 bits_write( &bits, 1, 0x00 ); // URL Flag
1705 bits_write( &bits, 1, 0x00 ); // includeInlineProfileLevelFlag
1706 bits_write( &bits, 4, 0x0f ); // reserved
1707 bits_write( &bits, 8, 0xff ); // ODProfile (no ODcapability )
1708 bits_write( &bits, 8, 0xff ); // sceneProfile
1709 bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified)
1710 bits_write( &bits, 8, 0xfe ); // visualProfile( // )
1711 bits_write( &bits, 8, 0xff ); // graphicProfile (no )
1712 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1714 ts_stream_t *p_stream;
1715 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1717 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1719 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1721 bits_align( &bits );
1722 bits_write( &bits, 8, 0x03 ); // ES_DescrTag
1723 bits_fix_ESDescr = bits;
1724 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable size
1725 bits_write( &bits, 16, p_stream->i_es_id );
1726 bits_write( &bits, 1, 0x00 ); // streamDependency
1727 bits_write( &bits, 1, 0x00 ); // URL Flag
1728 bits_write( &bits, 1, 0x00 ); // OCRStreamFlag
1729 bits_write( &bits, 5, 0x1f ); // streamPriority
1731 // DecoderConfigDesciptor
1732 bits_align( &bits );
1733 bits_write( &bits, 8, 0x04 ); // DecoderConfigDescrTag
1734 bits_fix_Decoder = bits;
1735 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) );
1736 if( p_stream->i_stream_type == 0x10 )
1738 bits_write( &bits, 8, 0x20 ); // Visual 14496-2
1739 bits_write( &bits, 6, 0x04 ); // VisualStream
1741 else if( p_stream->i_stream_type == 0x11 )
1743 bits_write( &bits, 8, 0x40 ); // Audio 14496-3
1744 bits_write( &bits, 6, 0x05 ); // AudioStream
1748 bits_write( &bits, 8, 0x00 );
1749 bits_write( &bits, 6, 0x00 );
1751 msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1753 bits_write( &bits, 1, 0x00 ); // UpStream
1754 bits_write( &bits, 1, 0x01 ); // reserved
1755 bits_write( &bits, 24, 1024 * 1024 ); // bufferSizeDB
1756 bits_write( &bits, 32, 0x7fffffff ); // maxBitrate
1757 bits_write( &bits, 32, 0 ); // avgBitrate
1759 if( p_stream->i_decoder_specific_info > 0 )
1762 // DecoderSpecificInfo
1763 bits_align( &bits );
1764 bits_write( &bits, 8, 0x05 ); // tag
1765 bits_write( &bits, 24,
1766 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1767 for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1769 bits_write( &bits, 8, ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1772 /* fix Decoder length */
1773 bits_write( &bits_fix_Decoder, 24,
1774 GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1776 /* SLConfigDescriptor : predifined (0x01) */
1777 bits_align( &bits );
1778 bits_write( &bits, 8, 0x06 ); // tag
1779 bits_write( &bits, 24, GetDescriptorLength24b( 8 ) );
1780 bits_write( &bits, 8, 0x01 ); // predefined
1781 bits_write( &bits, 1, 0 ); // durationFlag
1782 bits_write( &bits, 32, 0 ); // OCRResolution
1783 bits_write( &bits, 8, 0 ); // OCRLength
1784 bits_write( &bits, 8, 0 ); // InstantBitrateLength
1785 bits_align( &bits );
1787 /* fix ESDescr length */
1788 bits_write( &bits_fix_ESDescr, 24,
1789 GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1792 bits_align( &bits );
1793 /* fix IOD length */
1794 bits_write( &bits_fix_IOD, 24,
1795 GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1796 dvbpsi_PMTAddDescriptor( &pmt,
1802 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1804 ts_stream_t *p_stream;
1806 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1808 p_es = dvbpsi_PMTAddES( &pmt,
1809 p_stream->i_stream_type,
1811 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1816 es_id[0] = (p_stream->i_es_id >> 8)&0xff;
1817 es_id[1] = (p_stream->i_es_id)&0xff;
1818 dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
1820 else if( p_stream->i_stream_type == 0xa0 )
1823 int i_extra = __MIN( p_stream->i_decoder_specific_info,
1826 /* private DIV3 descripor */
1827 memcpy( &data[0], &p_stream->i_bih_codec, 4 );
1828 data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
1829 data[5] = ( p_stream->i_bih_width )&0xff;
1830 data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
1831 data[7] = ( p_stream->i_bih_height )&0xff;
1832 data[8] = ( i_extra >> 8 )&0xff;
1833 data[9] = ( i_extra )&0xff;
1836 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1839 /* 0xa0 is private */
1840 dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
1842 else if( p_stream->i_stream_type == 0x81 )
1844 uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1846 /* "registration" descriptor : "AC-3" */
1847 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1850 if( p_stream->lang[0] != 0 )
1854 /* I construct the content myself, way faster than looking at
1855 * over complicated/mind broken libdvbpsi way */
1856 data[0] = p_stream->lang[0];
1857 data[1] = p_stream->lang[1];
1858 data[2] = p_stream->lang[2];
1859 data[3] = 0x00; /* audio type: 0x00 undefined */
1861 dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data );
1865 p_section = dvbpsi_GenPMTSections( &pmt );
1867 p_pmt = WritePSISection( p_mux->p_sout, p_section );
1869 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1871 dvbpsi_DeletePSISections( p_section );
1872 dvbpsi_EmptyPMT( &pmt );