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 * );
81 #if defined MODULE_NAME_IS_mux_ts
82 set_description( _("TS muxer") );
83 set_capability( "sout mux", 100 );
85 add_shortcut( "ts_nodvbpsi" );
86 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
87 set_description( _("TS muxer (libdvbpsi)") );
88 set_capability( "sout mux", 120 );
90 add_shortcut( "ts_dvbpsi" );
92 set_callbacks( Open, Close );
95 /*****************************************************************************
96 * Local data structures
97 *****************************************************************************/
98 #define SOUT_BUFFER_FLAGS_PRIVATE_PCR ( 1 << BLOCK_FLAG_PRIVATE_SHIFT )
99 #define SOUT_BUFFER_FLAGS_PRIVATE_CSA ( 2 << BLOCK_FLAG_PRIVATE_SHIFT )
105 } sout_buffer_chain_t;
107 static inline void BufferChainInit ( sout_buffer_chain_t *c )
111 c->pp_last = &c->p_first;
113 static inline void BufferChainAppend( sout_buffer_chain_t *c, block_t *b )
123 c->pp_last = &b->p_next;
125 static inline block_t *BufferChainGet( sout_buffer_chain_t *c )
127 block_t *b = c->p_first;
132 c->p_first = b->p_next;
134 if( c->p_first == NULL )
136 c->pp_last = &c->p_first;
143 static inline block_t *BufferChainPeek( sout_buffer_chain_t *c )
145 block_t *b = c->p_first;
149 static inline void BufferChainClean( sout_instance_t *p_sout, sout_buffer_chain_t *c )
153 while( ( b = BufferChainGet( c ) ) )
157 BufferChainInit( c );
160 typedef struct ts_stream_t
165 int i_continuity_counter;
167 /* to be used for carriege of DIV3 */
168 vlc_fourcc_t i_bih_codec;
169 int i_bih_width, i_bih_height;
171 /* Specific to mpeg4 in mpeg2ts */
174 int i_decoder_specific_info;
175 uint8_t *p_decoder_specific_info;
177 /* language is iso639-2T */
180 sout_buffer_chain_t chain_pes;
182 mtime_t i_pes_length;
184 vlc_bool_t b_key_frame;
188 struct sout_mux_sys_t
191 sout_input_t *p_pcr_input;
198 int i_pid_free; // first usable pid
200 int i_pat_version_number;
203 int i_pmt_version_number;
204 ts_stream_t pmt; // Up to now only one program
208 int i_null_continuity_counter; /* Needed ? */
210 /* for TS building */
211 int64_t i_bitrate_min;
212 int64_t i_bitrate_max;
214 int64_t i_shaping_delay;
219 vlc_bool_t b_use_key_frames;
221 mtime_t i_pcr; /* last PCR emited */
227 /* Reserve a pid and return it */
228 static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
231 if ( i_cat == VIDEO_ES && p_sys->i_pid_video )
233 i_pid = p_sys->i_pid_video;
234 p_sys->i_pid_video = 0;
236 else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio )
238 i_pid = p_sys->i_pid_audio;
239 p_sys->i_pid_audio = 0;
243 i_pid = ++p_sys->i_pid_free;
248 /*****************************************************************************
250 *****************************************************************************/
251 static int Capability(sout_mux_t *, int, void *, void * );
252 static int AddStream( sout_mux_t *, sout_input_t * );
253 static int DelStream( sout_mux_t *, sout_input_t * );
254 static int Mux ( sout_mux_t * );
256 static void TSSchedule ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
257 mtime_t i_pcr_length, mtime_t i_pcr_dts );
258 static void TSDate ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
259 mtime_t i_pcr_length, mtime_t i_pcr_dts );
260 static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
261 static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
263 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr );
264 static void TSSetPCR( block_t *p_ts, mtime_t i_dts );
266 static void PEStoTS ( sout_instance_t *, sout_buffer_chain_t *, block_t *, ts_stream_t * );
268 /*****************************************************************************
270 *****************************************************************************/
271 static int Open( vlc_object_t *p_this )
273 sout_mux_t *p_mux =(sout_mux_t*)p_this;
274 sout_mux_sys_t *p_sys;
277 msg_Dbg( p_mux, "Open" );
279 p_sys = malloc( sizeof( sout_mux_sys_t ) );
281 p_mux->pf_capacity = Capability;
282 p_mux->pf_addstream = AddStream;
283 p_mux->pf_delstream = DelStream;
285 p_mux->p_sys = p_sys;
287 srand( (uint32_t)mdate() );
289 p_sys->i_audio_bound = 0;
290 p_sys->i_video_bound = 0;
292 p_sys->i_pat_version_number = rand() % 32;
293 p_sys->pat.i_pid = 0;
294 p_sys->pat.i_continuity_counter = 0;
296 p_sys->i_pmt_version_number = rand() % 32;
297 p_sys->pmt.i_pid = 0x42;
298 p_sys->pmt.i_continuity_counter = 0;
300 p_sys->i_pid_free = 0x43;
302 p_sys->i_pid_video = 0;
303 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-video" ) ) )
305 p_sys->i_pid_video = strtol( val, NULL, 0 );
306 if ( p_sys->i_pid_video > p_sys->i_pid_free )
308 p_sys->i_pid_free = p_sys->i_pid_video + 1;
311 p_sys->i_pid_audio = 0;
312 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-audio" ) ) )
314 p_sys->i_pid_audio = strtol( val, NULL, 0 );
315 if ( p_sys->i_pid_audio > p_sys->i_pid_free )
317 p_sys->i_pid_free = p_sys->i_pid_audio + 1;
321 p_sys->i_pcr_pid = 0x1fff;
322 p_sys->p_pcr_input = NULL;
324 p_sys->i_mpeg4_streams = 0;
326 p_sys->i_null_continuity_counter = 0;
328 /* Allow to create constrained stream */
329 p_sys->i_bitrate_min = 0;
330 p_sys->i_bitrate_max = 0;
331 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "bmin" ) ) )
333 p_sys->i_bitrate_min = atoll( val );
335 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "bmax" ) ) )
337 p_sys->i_bitrate_max = atoll( val );
339 if( p_sys->i_bitrate_min > 0 && p_sys->i_bitrate_max > 0 &&
340 p_sys->i_bitrate_min > p_sys->i_bitrate_max )
342 msg_Err( p_mux, "incompatible minimum and maximum bitrate, "
343 "disabling bitrate control" );
344 p_sys->i_bitrate_min = 0;
345 p_sys->i_bitrate_max = 0;
347 if( p_sys->i_bitrate_min > 0 || p_sys->i_bitrate_max > 0 )
349 msg_Err( p_mux, "bmin and bmax no more supported (if you need them report it)" );
352 p_sys->i_shaping_delay = 200000;
353 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "shaping" ) ) )
355 p_sys->i_shaping_delay = (int64_t)atoi( val ) * 1000;
356 if( p_sys->i_shaping_delay <= 0 )
359 "invalid shaping ("I64Fd"ms) reseting to 200ms",
360 p_sys->i_shaping_delay / 1000 );
361 p_sys->i_shaping_delay = 200000;
364 p_sys->i_pcr_delay = 30000;
365 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pcr" ) ) )
367 p_sys->i_pcr_delay = (int64_t)atoi( val ) * 1000;
368 if( p_sys->i_pcr_delay <= 0 ||
369 p_sys->i_pcr_delay >= p_sys->i_shaping_delay )
372 "invalid pcr delay ("I64Fd"ms) reseting to 30ms",
373 p_sys->i_pcr_delay / 1000 );
374 p_sys->i_pcr_delay = 30000;
377 p_sys->b_use_key_frames = 0;
378 if( sout_cfg_find( p_mux->p_cfg, "use-key-frames" ) )
380 p_sys->b_use_key_frames = 1;
383 p_sys->i_dts_delay = 200000;
384 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "dts-delay" ) ) )
386 p_sys->i_dts_delay = (int64_t)atoi( val ) * 1000;
389 msg_Dbg( p_mux, "shaping="I64Fd" pcr="I64Fd" dts_delay="I64Fd,
390 p_sys->i_shaping_delay, p_sys->i_pcr_delay, p_sys->i_dts_delay );
392 /* for TS generation */
396 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "csa-ck" ) ) )
399 if( val[0] == '0' && ( val[1] == 'x' || val[1] == 'X' ) )
403 if( strlen( val ) != 16 )
405 msg_Dbg( p_mux, "invalid csa ck (it must be 16 chars long)" );
409 /* Avoid using strtoll */
416 i_ck = ((int64_t)strtol( val, NULL, 16 )) << 32;
418 i_ck += (uint64_t)strtol( &val[8], NULL, 16 );
419 for( i = 0; i < 8; i++ )
421 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
424 msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x",
425 ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
427 p_sys->csa = csa_New();
428 csa_SetCW( p_sys->csa, ck, ck );
434 /*****************************************************************************
436 *****************************************************************************/
437 static void Close( vlc_object_t * p_this )
439 sout_mux_t *p_mux = (sout_mux_t*)p_this;
440 sout_mux_sys_t *p_sys = p_mux->p_sys;
442 msg_Dbg( p_mux, "Close" );
445 csa_Delete( p_sys->csa );
451 /*****************************************************************************
453 *****************************************************************************/
454 static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
458 case SOUT_MUX_CAP_GET_ADD_STREAM_ANY_TIME:
459 *(vlc_bool_t*)p_answer = VLC_TRUE;
460 return( SOUT_MUX_CAP_ERR_OK );
462 return( SOUT_MUX_CAP_ERR_UNIMPLEMENTED );
466 /*****************************************************************************
467 * AddStream: called for each stream addition
468 *****************************************************************************/
469 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
471 sout_mux_sys_t *p_sys = p_mux->p_sys;
472 ts_stream_t *p_stream;
474 p_input->p_sys = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
476 /* Init this new stream */
477 p_stream->i_pid = AllocatePID( p_sys, p_input->p_fmt->i_cat );
478 p_stream->i_continuity_counter = 0;
479 p_stream->i_decoder_specific_info = 0;
480 p_stream->p_decoder_specific_info = NULL;
482 msg_Dbg( p_mux, "adding input codec=%4.4s pid=%d", (char*)&p_input->p_fmt->i_codec, p_stream->i_pid );
484 /* All others fields depand on codec */
485 switch( p_input->p_fmt->i_cat )
488 switch( p_input->p_fmt->i_codec )
490 case VLC_FOURCC( 'm', 'p','g', 'v' ):
491 /* TODO: do we need to check MPEG-I/II ? */
492 p_stream->i_stream_type = 0x02;
493 p_stream->i_stream_id = 0xe0;
495 case VLC_FOURCC( 'm', 'p','4', 'v' ):
496 p_stream->i_stream_type = 0x10;
497 p_stream->i_stream_id = 0xfa;
498 p_sys->i_mpeg4_streams++;
499 p_stream->i_es_id = p_stream->i_pid;
501 /* XXX dirty dirty but somebody want that : using crapy MS-codec XXX */
502 /* I didn't want to do that :P */
503 case VLC_FOURCC( 'H', '2', '6', '3' ):
504 case VLC_FOURCC( 'I', '2', '6', '3' ):
505 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
506 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
507 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
508 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
509 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
510 case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
511 p_stream->i_stream_type = 0xa0; // private
512 p_stream->i_stream_id = 0xa0; // beurk
513 p_stream->i_bih_codec = p_input->p_fmt->i_codec;
514 p_stream->i_bih_width = p_input->p_fmt->video.i_width;
515 p_stream->i_bih_height = p_input->p_fmt->video.i_height;
521 p_sys->i_video_bound++;
525 switch( p_input->p_fmt->i_codec )
527 case VLC_FOURCC( 'm', 'p','g', 'a' ):
528 p_stream->i_stream_type = p_input->p_fmt->audio.i_rate >= 32000 ? 0x03 : 0x04;
529 p_stream->i_stream_id = 0xc0;
531 case VLC_FOURCC( 'a', '5','2', ' ' ):
532 p_stream->i_stream_type = 0x81;
533 p_stream->i_stream_id = 0xbd;
535 case VLC_FOURCC( 'l', 'p','c', 'm' ):
536 p_stream->i_stream_type = 0x83;
537 p_stream->i_stream_id = 0xbd;
539 case VLC_FOURCC( 'd', 't','s', ' ' ):
540 p_stream->i_stream_type = 0x85;
541 p_stream->i_stream_id = 0xbd;
544 case VLC_FOURCC( 'm', 'p','4', 'a' ):
545 p_stream->i_stream_type = 0x11;
546 p_stream->i_stream_id = 0xfa;
547 p_sys->i_mpeg4_streams++;
548 p_stream->i_es_id = p_stream->i_pid;
554 p_sys->i_audio_bound++;
558 switch( p_input->p_fmt->i_codec )
560 case VLC_FOURCC( 's', 'p','u', ' ' ):
561 p_stream->i_stream_type = 0x82;
562 p_stream->i_stream_id = 0xbd;
577 p_stream->lang[2] = '\0';
578 if( p_input->p_fmt->psz_language )
580 char *psz = p_input->p_fmt->psz_language;
581 const iso639_lang_t *pl = NULL;
583 if( strlen( psz ) == 2 )
585 pl = GetLang_1( psz );
587 else if( strlen( psz ) == 3 )
589 pl = GetLang_2B( psz );
590 if( !strcmp( pl->psz_iso639_1, "??" ) )
592 pl = GetLang_2T( psz );
595 if( pl && strcmp( pl->psz_iso639_1, "??" ) )
597 p_stream->lang[0] = pl->psz_iso639_2T[0];
598 p_stream->lang[1] = pl->psz_iso639_2T[1];
599 p_stream->lang[2] = pl->psz_iso639_2T[2];
601 msg_Dbg( p_mux, " - lang=%c%c%c",
609 /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
610 p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
611 if( p_stream->i_decoder_specific_info > 0 )
613 p_stream->p_decoder_specific_info =
614 malloc( p_stream->i_decoder_specific_info );
615 memcpy( p_stream->p_decoder_specific_info,
616 p_input->p_fmt->p_extra,
617 p_input->p_fmt->i_extra );
621 BufferChainInit( &p_stream->chain_pes );
622 p_stream->i_pes_dts = 0;
623 p_stream->i_pes_length = 0;
624 p_stream->i_pes_used = 0;
625 p_stream->b_key_frame = 0;
627 /* We only change PMT version (PAT isn't changed) */
628 p_sys->i_pmt_version_number = ( p_sys->i_pmt_version_number + 1 )%32;
631 if( p_input->p_fmt->i_cat != SPU_ES &&
632 ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) )
634 if( p_sys->p_pcr_input )
636 /* There was already a PCR stream, so clean context */
639 p_sys->i_pcr_pid = p_stream->i_pid;
640 p_sys->p_pcr_input = p_input;
642 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
648 /*****************************************************************************
649 * DelStream: called before a stream deletion
650 *****************************************************************************/
651 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
653 sout_mux_sys_t *p_sys = p_mux->p_sys;
654 ts_stream_t *p_stream;
657 p_stream = (ts_stream_t*)p_input->p_sys;
658 msg_Dbg( p_mux, "removing input pid=%d", p_stream->i_pid );
660 if( p_sys->i_pcr_pid == p_stream->i_pid )
664 /* Find a new pcr stream (Prefer Video Stream) */
665 p_sys->i_pcr_pid = 0x1fff;
666 p_sys->p_pcr_input = NULL;
667 for( i = 0; i < p_mux->i_nb_inputs; i++ )
669 if( p_mux->pp_inputs[i] == p_input )
674 if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
677 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
678 p_sys->p_pcr_input= p_mux->pp_inputs[i];
681 else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
682 p_sys->i_pcr_pid == 0x1fff )
685 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
686 p_sys->p_pcr_input= p_mux->pp_inputs[i];
689 if( p_sys->p_pcr_input )
691 /* Empty TS buffer */
694 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
697 /* Empty all data in chain_pes */
698 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
700 if( p_stream->p_decoder_specific_info )
702 free( p_stream->p_decoder_specific_info );
704 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
706 p_sys->i_mpeg4_streams--;
708 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-video" ) ) )
710 int i_pid_video = strtol( val, NULL, 0 );
711 if ( i_pid_video == p_stream->i_pid )
713 p_sys->i_pid_video = i_pid_video;
714 msg_Dbg( p_mux, "freeing video PID %d", i_pid_video );
717 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-audio" ) ) )
719 int i_pid_audio = strtol( val, NULL, 0 );
720 if ( i_pid_audio == p_stream->i_pid )
722 p_sys->i_pid_audio = i_pid_audio;
723 msg_Dbg( p_mux, "freeing audio PID %d", i_pid_audio );
728 /* We only change PMT version (PAT isn't changed) */
729 p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
734 /*****************************************************************************
735 * Mux: Call each time there is new data for at least one stream
736 *****************************************************************************
738 *****************************************************************************/
739 static int Mux( sout_mux_t *p_mux )
741 sout_mux_sys_t *p_sys = p_mux->p_sys;
742 ts_stream_t *p_pcr_stream;
744 if( p_sys->i_pcr_pid == 0x1fff )
746 msg_Dbg( p_mux, "waiting for PCR streams" );
750 p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
754 sout_buffer_chain_t chain_ts;
758 mtime_t i_pcr_length;
759 mtime_t i_shaping_delay;
762 if( p_pcr_stream->b_key_frame )
764 i_shaping_delay = p_pcr_stream->i_pes_length;
768 i_shaping_delay = p_sys->i_shaping_delay;
771 /* 1: get enough PES packet for all input */
774 vlc_bool_t b_ok = VLC_TRUE;
777 /* Accumulate enough data in the pcr stream (>i_shaping_delay) */
778 /* Accumulate enough data in all other stream ( >= length of pcr) */
779 for( i = 0; i < p_mux->i_nb_inputs; i++ )
781 sout_input_t *p_input = p_mux->pp_inputs[i];
782 ts_stream_t *p_stream = (ts_stream_t*)p_input->p_sys;
784 if( ( p_stream == p_pcr_stream
785 && p_stream->i_pes_length < i_shaping_delay ) ||
786 p_stream->i_pes_dts + p_stream->i_pes_length
787 < p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
790 if( p_input->p_fifo->i_depth <= 1 )
792 if( p_input->p_fmt->i_cat == AUDIO_ES ||
793 p_input->p_fmt->i_cat == VIDEO_ES )
795 /* We need more data */
798 else if( p_input->p_fifo->i_depth <= 0 )
800 /* spu, only one packet is needed */
806 p_data = block_FifoGet( p_input->p_fifo );
807 if( p_input->p_fifo->i_depth > 0 )
809 block_t *p_next = block_FifoShow( p_input->p_fifo );
811 p_data->i_length = p_next->i_dts - p_data->i_dts;
814 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 ) ||
815 p_data->i_dts < p_stream->i_pes_dts ||
816 ( p_stream->i_pes_dts > 0 && p_data->i_dts - 2000000 > p_stream->i_pes_dts + p_stream->i_pes_length ) )
818 msg_Warn( p_mux, "packet with too strange dts (dts=%lld,old=%lld,pcr=%lld)",
821 p_pcr_stream->i_pes_dts );
822 block_Release( p_data );
824 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
825 p_stream->i_pes_dts = 0;
826 p_stream->i_pes_used = 0;
827 p_stream->i_pes_length = 0;
829 BufferChainClean( p_mux->p_sout, &p_pcr_stream->chain_pes );
830 p_pcr_stream->i_pes_dts = 0;
831 p_pcr_stream->i_pes_used = 0;
832 p_pcr_stream->i_pes_length = 0;
837 if( p_data->i_length < 0 || p_data->i_length > 2000000 )
839 /* FIXME choose a better value, but anyway we should never
841 p_data->i_length = 1000;
843 p_stream->i_pes_length += p_data->i_length;
844 if( p_stream->i_pes_dts == 0 )
846 p_stream->i_pes_dts = p_data->i_dts;
850 if( p_stream->i_stream_id == 0xa0 && p_data->i_pts <= 0 )
852 /* XXX yes I know, it's awfull, but it's needed, so don't remove it ... */
853 p_data->i_pts = p_data->i_dts;
855 E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 );
857 BufferChainAppend( &p_stream->chain_pes, p_data );
859 if( p_sys->b_use_key_frames && p_stream == p_pcr_stream
860 && (p_data->i_flags & BLOCK_FLAG_TYPE_I )
861 && (p_stream->i_pes_length > 300000) )
863 i_shaping_delay = p_stream->i_pes_length;
864 p_stream->b_key_frame = 1;
877 i_pcr_dts = p_pcr_stream->i_pes_dts;
878 i_pcr_length = p_pcr_stream->i_pes_length;
879 p_pcr_stream->b_key_frame = 0;
881 /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
882 /* 2: calculate non accurate total size of muxed ts */
884 for( i = 0; i < p_mux->i_nb_inputs; i++ )
886 ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
889 /* False for pcr stream but it will be enough to do PCR algo */
890 for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL; p_pes = p_pes->p_next )
892 int i_size = p_pes->i_buffer;
893 if( p_pes->i_dts + p_pes->i_length > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
895 mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts;
901 i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
903 i_packet_count += ( i_size + 183 ) / 184;
906 /* add overhead for PCR (not really exact) */
907 i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176;
910 /* 3: mux PES into TS */
911 BufferChainInit( &chain_ts );
912 /* append PAT/PMT -> FIXME with big pcr delay it won't have enough pat/pmt */
913 GetPAT( p_mux, &chain_ts);
914 GetPMT( p_mux, &chain_ts );
916 i_packet_count += chain_ts.i_depth;
917 /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
923 ts_stream_t *p_stream;
927 /* Select stream (lowest dts) */
928 for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
930 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
932 if( p_stream->i_pes_dts == 0 )
937 if( i_stream == -1 ||
938 p_stream->i_pes_dts < i_dts )
941 i_dts = p_stream->i_pes_dts;
948 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
950 /* do we need to issue pcr */
952 if( p_stream == p_pcr_stream &&
953 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >= p_sys->i_pcr + p_sys->i_pcr_delay )
956 p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count;
959 /* Build the TS packet */
960 p_ts = TSNew( p_mux, p_stream, b_pcr );
963 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
968 BufferChainAppend( &chain_ts, p_ts );
971 /* 4: date and send */
972 TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
976 static void TSSchedule( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
977 mtime_t i_pcr_length, mtime_t i_pcr_dts )
979 sout_mux_sys_t *p_sys = p_mux->p_sys;
980 sout_buffer_chain_t new_chain;
981 int i_packet_count = p_chain_ts->i_depth;
984 BufferChainInit( &new_chain );
986 if ( i_pcr_length <= 0 )
988 i_pcr_length = i_packet_count;
991 for( i = 0; i < i_packet_count; i++ )
993 block_t *p_ts = BufferChainGet( p_chain_ts );
994 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
996 BufferChainAppend( &new_chain, p_ts );
999 p_ts->i_dts + p_sys->i_dts_delay * 2/3 < i_new_dts )
1001 mtime_t i_max_diff = i_new_dts - p_ts->i_dts;
1002 mtime_t i_cut_dts = p_ts->i_dts;
1004 p_ts = BufferChainPeek( p_chain_ts );
1006 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1007 while ( p_ts != NULL && i_new_dts - p_ts->i_dts >= i_max_diff )
1009 p_ts = BufferChainGet( p_chain_ts );
1010 i_max_diff = i_new_dts - p_ts->i_dts;
1011 i_cut_dts = p_ts->i_dts;
1012 BufferChainAppend( &new_chain, p_ts );
1014 p_ts = BufferChainPeek( p_chain_ts );
1016 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1018 msg_Dbg( p_mux, "adjusting rate at "I64Fd"/"I64Fd" (%d/%d)",
1019 i_cut_dts - i_pcr_dts, i_pcr_length, new_chain.i_depth,
1020 p_chain_ts->i_depth );
1021 if ( new_chain.i_depth )
1022 TSDate( p_mux, &new_chain,
1023 i_cut_dts - i_pcr_dts,
1025 if ( p_chain_ts->i_depth )
1027 p_chain_ts, i_pcr_dts + i_pcr_length - i_cut_dts,
1033 if ( new_chain.i_depth )
1034 TSDate( p_mux, &new_chain, i_pcr_length, i_pcr_dts );
1037 static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1038 mtime_t i_pcr_length, mtime_t i_pcr_dts )
1040 sout_mux_sys_t *p_sys = p_mux->p_sys;
1041 int i_packet_count = p_chain_ts->i_depth;
1044 if ( i_pcr_length > 0 )
1046 int i_bitrate = ((uint64_t)i_packet_count * 188 * 8000)
1047 / (uint64_t)(i_pcr_length / 1000);
1048 if ( p_sys->i_bitrate_max && p_sys->i_bitrate_max < i_bitrate )
1051 "max bitrate exceeded at %lld (%d bi/s for %d pkt in %lld us)",
1052 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1053 i_bitrate, i_packet_count, i_pcr_length);
1059 "starting at %lld (%d bi/s for %d packets in %lld us)",
1060 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1061 i_bitrate, i_packet_count, i_pcr_length);
1067 /* This shouldn't happen, but happens in some rare heavy load
1068 * and packet losses conditions. */
1069 i_pcr_length = i_packet_count;
1072 /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
1073 for( i = 0; i < i_packet_count; i++ )
1075 block_t *p_ts = BufferChainGet( p_chain_ts );
1076 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1078 p_ts->i_dts = i_new_dts;
1079 p_ts->i_length = i_pcr_length / i_packet_count;
1081 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_PCR )
1083 /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
1084 TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
1086 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_CSA )
1088 csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
1092 p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
1094 sout_AccessOutWrite( p_mux->p_access, p_ts );
1098 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr )
1100 block_t *p_pes = p_stream->chain_pes.p_first;
1103 vlc_bool_t b_new_pes = VLC_FALSE;
1104 vlc_bool_t b_adaptation_field = VLC_FALSE;
1106 int i_payload_max = 184 - ( b_pcr ? 8 : 0 );
1109 if( p_stream->i_pes_used <= 0 )
1111 b_new_pes = VLC_TRUE;
1113 i_payload = __MIN( (int)p_pes->i_buffer - p_stream->i_pes_used, i_payload_max );
1115 if( b_pcr || i_payload < i_payload_max )
1117 b_adaptation_field = VLC_TRUE;
1120 p_ts = block_New( p_mux, 188 );
1121 p_ts->i_dts = p_pes->i_dts;
1123 p_ts->p_buffer[0] = 0x47;
1124 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|( ( p_stream->i_pid >> 8 )&0x1f );
1125 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1126 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|p_stream->i_continuity_counter;
1128 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1130 if( b_adaptation_field )
1136 int i_stuffing = i_payload_max - i_payload;
1138 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
1140 p_ts->p_buffer[4] = 7 + i_stuffing;
1141 p_ts->p_buffer[5] = 0x10; /* flags */
1142 p_ts->p_buffer[6] = ( 0 )&0xff;
1143 p_ts->p_buffer[7] = ( 0 )&0xff;
1144 p_ts->p_buffer[8] = ( 0 )&0xff;
1145 p_ts->p_buffer[9] = ( 0 )&0xff;
1146 p_ts->p_buffer[10]= ( 0 )&0x80;
1147 p_ts->p_buffer[11]= 0;
1149 for( i = 12; i < 12 + i_stuffing; i++ )
1151 p_ts->p_buffer[i] = 0xff;
1156 int i_stuffing = i_payload_max - i_payload;
1158 p_ts->p_buffer[4] = i_stuffing - 1;
1159 if( i_stuffing > 1 )
1161 p_ts->p_buffer[5] = 0x00;
1162 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1164 p_ts->p_buffer[i] = 0xff;
1171 memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
1173 p_stream->i_pes_used += i_payload;
1174 p_stream->i_pes_dts = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_buffer;
1175 p_stream->i_pes_length -= p_pes->i_length * i_payload / p_pes->i_buffer;
1177 if( p_stream->i_pes_used >= (int)p_pes->i_buffer )
1179 p_pes = BufferChainGet( &p_stream->chain_pes );
1180 block_Release( p_pes );
1182 p_pes = p_stream->chain_pes.p_first;
1185 p_stream->i_pes_dts = p_pes->i_dts;
1186 p_stream->i_pes_length = 0;
1189 p_stream->i_pes_length += p_pes->i_length;
1191 p_pes = p_pes->p_next;
1196 p_stream->i_pes_dts = 0;
1197 p_stream->i_pes_length = 0;
1199 p_stream->i_pes_used = 0;
1206 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
1208 mtime_t i_pcr = 9 * i_dts / 100;
1210 p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
1211 p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
1212 p_ts->p_buffer[8] = ( i_pcr >> 9 )&0xff;
1213 p_ts->p_buffer[9] = ( i_pcr >> 1 )&0xff;
1214 p_ts->p_buffer[10]|= ( i_pcr << 7 )&0x80;
1218 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 )
1220 sout_mux_sys_t *p_sys = p_mux->p_sys;
1221 sout_buffer_chain_t s = *c;
1224 int i_packets_min = 0;
1225 int i_packets_max = 0;
1232 i_packets = c->i_depth;
1233 i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000 + 187 ) / 188;
1234 i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000 + 187 ) / 188;
1236 if( i_packets < i_packets_min && i_packets_min > 0 )
1239 int i_div = ( i_packets_min - i_packets ) / i_packets;
1240 int i_mod = ( i_packets_min - i_packets ) % i_packets;
1243 /* We need to pad with null packets (pid=0x1fff)
1244 * We try to melt null packets with true packets */
1246 "packets=%d but min=%d -> adding %d packets of padding",
1247 i_packets, i_packets_min, i_packets_min - i_packets );
1249 BufferChainInit( c );
1250 while( ( p_pk = BufferChainGet( &s ) ) )
1254 BufferChainAppend( c, p_pk );
1256 i_null = i_div + ( i_rest + i_mod ) / i_packets;
1258 for( i = 0; i < i_null; i++ )
1262 p_null = sout_BufferNew( p_mux->p_sout, 188 );
1263 p_null->p_buffer[0] = 0x47;
1264 p_null->p_buffer[1] = 0x1f;
1265 p_null->p_buffer[2] = 0xff;
1266 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
1267 memset( &p_null->p_buffer[4], 0, 184 );
1268 p_sys->i_null_continuity_counter =
1269 ( p_sys->i_null_continuity_counter + 1 ) % 16;
1271 BufferChainAppend( c, p_null );
1274 i_rest = ( i_rest + i_mod ) % i_packets;
1277 else if( i_packets > i_packets_max && i_packets_max > 0 )
1282 /* Arg, we need to drop packets, I don't do something clever (like
1283 * dropping complete pid, b frames, ... ), I just get the right amount
1284 * of packets and discard the others */
1286 "packets=%d but max=%d -> removing %d packets -> stream broken",
1287 i_packets, i_packets_max, i_packets - i_packets_max );
1289 BufferChainInit( c );
1290 for( i = 0; i < i_packets_max; i++ )
1292 BufferChainAppend( c, BufferChainGet( &s ) );
1295 while( ( p_pk = BufferChainGet( &s ) ) )
1297 sout_BufferDelete( p_mux->p_sout, p_pk );
1303 static void PEStoTS( sout_instance_t *p_sout,
1304 sout_buffer_chain_t *c, block_t *p_pes,
1305 ts_stream_t *p_stream )
1311 /* get PES total size */
1312 i_size = p_pes->i_buffer;
1313 p_data = p_pes->p_buffer;
1315 b_new_pes = VLC_TRUE;
1319 int b_adaptation_field;
1323 p_ts = block_New( p_sout, 188 );
1326 * 1b transport_error_indicator
1327 * 1b payload_unit_start
1328 * 1b transport_priority
1330 * 2b transport_scrambling_control
1331 * 2b if adaptation_field 0x03 else 0x01
1332 * 4b continuity_counter
1335 i_copy = __MIN( i_size, 184 );
1336 b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
1338 p_ts->p_buffer[0] = 0x47;
1339 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
1340 ( ( p_stream->i_pid >> 8 )&0x1f );
1341 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1342 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
1343 p_stream->i_continuity_counter;
1345 b_new_pes = VLC_FALSE;
1346 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1348 if( b_adaptation_field )
1350 int i_stuffing = 184 - i_copy;
1353 p_ts->p_buffer[4] = i_stuffing - 1;
1354 if( i_stuffing > 1 )
1356 p_ts->p_buffer[5] = 0x00;
1357 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1359 p_ts->p_buffer[i] = 0xff;
1364 memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1368 BufferChainAppend( c, p_ts );
1372 block_t *p_next = p_pes->p_next;
1374 p_pes->p_next = NULL;
1375 block_Release( p_pes );
1376 if( p_next == NULL )
1380 b_new_pes = VLC_TRUE;
1382 i_size = p_pes->i_buffer;
1383 p_data = p_pes->p_buffer;
1390 #if defined MODULE_NAME_IS_mux_ts
1391 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1393 static uint32_t CRC32[256] =
1395 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1396 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1397 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1398 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1399 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1400 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1401 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1402 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1403 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1404 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1405 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1406 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1407 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1408 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1409 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1410 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1411 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1412 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1413 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1414 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1415 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1416 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1417 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1418 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1419 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1420 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1421 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1422 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1423 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1424 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1425 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1426 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1427 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1428 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1429 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1430 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1431 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1432 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1433 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1434 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1435 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1436 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1437 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1438 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1439 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1440 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1441 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1442 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1443 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1444 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1445 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1446 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1447 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1448 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1449 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1450 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1451 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1452 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1453 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1454 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1455 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1456 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1457 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1458 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1461 uint32_t i_crc = 0xffffffff;
1463 /* Calculate the CRC */
1464 while( i_count > 0 )
1466 i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1474 static void GetPAT( sout_mux_t *p_mux,
1475 sout_buffer_chain_t *c )
1477 sout_mux_sys_t *p_sys = p_mux->p_sys;
1481 p_pat = block_New( p_mux, 1024 );
1485 p_pat->i_length = 0;
1487 bits_initwrite( &bits, 1024, p_pat->p_buffer );
1489 bits_write( &bits, 8, 0 ); // pointer
1490 bits_write( &bits, 8, 0x00 ); // table id
1491 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1492 bits_write( &bits, 1, 0 ); // 0
1493 bits_write( &bits, 2, 0x03 ); // reserved FIXME
1494 bits_write( &bits, 12, 13 ); // XXX for one program only XXX
1495 bits_write( &bits, 16, 0x01 ); // FIXME stream id
1496 bits_write( &bits, 2, 0x03 ); // FIXME
1497 bits_write( &bits, 5, p_sys->i_pat_version_number );
1498 bits_write( &bits, 1, 1 ); // current_next_indicator
1499 bits_write( &bits, 8, 0 ); // section number
1500 bits_write( &bits, 8, 0 ); // last section number
1502 bits_write( &bits, 16, 1 ); // program number
1503 bits_write( &bits, 3, 0x07 ); // reserved
1504 bits_write( &bits, 13, p_sys->pmt.i_pid ); // program map pid
1506 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1508 p_pat->i_buffer = bits.i_data;
1510 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1513 static void GetPMT( sout_mux_t *p_mux,
1514 sout_buffer_chain_t *c )
1516 sout_mux_sys_t *p_sys = p_mux->p_sys;
1521 p_pmt = block_New( p_mux, 1024 );
1525 p_pmt->i_length = 0;
1527 bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1529 bits_write( &bits, 8, 0 ); // pointer
1530 bits_write( &bits, 8, 0x02 ); // table id
1531 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1532 bits_write( &bits, 1, 0 ); // 0
1533 bits_write( &bits, 2, 0 ); // reserved FIXME
1534 bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1535 bits_write( &bits, 16, 1 ); // FIXME program number
1536 bits_write( &bits, 2, 0 ); // FIXME
1537 bits_write( &bits, 5, p_sys->i_pmt_version_number );
1538 bits_write( &bits, 1, 1 ); // current_next_indicator
1539 bits_write( &bits, 8, 0 ); // section number
1540 bits_write( &bits, 8, 0 ); // last section number
1542 bits_write( &bits, 3, 0 ); // reserved
1544 bits_write( &bits, 13, p_sys->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
1545 bits_write( &bits, 4, 0 ); // reserved FIXME
1547 bits_write( &bits, 12, 0 ); // program info len FIXME
1549 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1551 ts_stream_t *p_stream;
1553 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1555 bits_write( &bits, 8, p_stream->i_stream_type ); // stream_type
1556 bits_write( &bits, 3, 0 ); // reserved
1557 bits_write( &bits, 13, p_stream->i_pid ); // es pid
1558 bits_write( &bits, 4, 0 ); //reserved
1559 bits_write( &bits, 12, 0 ); // es info len FIXME
1562 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1564 p_pmt->i_buffer = bits.i_data;
1566 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1568 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1570 static block_t *WritePSISection( sout_instance_t *p_sout,
1571 dvbpsi_psi_section_t* p_section )
1573 block_t *p_psi, *p_first = NULL;
1580 i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1581 ( p_section->b_syntax_indicator ? 4 : 0 );
1583 p_psi = block_New( p_sout, i_size + 1 );
1586 p_psi->i_length = 0;
1587 p_psi->i_buffer = i_size + 1;
1589 p_psi->p_buffer[0] = 0; // pointer
1590 memcpy( p_psi->p_buffer + 1,
1594 block_ChainAppend( &p_first, p_psi );
1596 p_section = p_section->p_next;
1602 static void GetPAT( sout_mux_t *p_mux,
1603 sout_buffer_chain_t *c )
1605 sout_mux_sys_t *p_sys = p_mux->p_sys;
1608 dvbpsi_psi_section_t *p_section;
1610 dvbpsi_InitPAT( &pat,
1612 p_sys->i_pat_version_number,
1613 1 ); // b_current_next
1614 /* add all program (only one) */
1615 dvbpsi_PATAddProgram( &pat,
1617 p_sys->pmt.i_pid ); // i_pid
1619 p_section = dvbpsi_GenPATSections( &pat,
1620 0 ); // max program per section
1622 p_pat = WritePSISection( p_mux->p_sout, p_section );
1624 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1626 dvbpsi_DeletePSISections( p_section );
1627 dvbpsi_EmptyPAT( &pat );
1630 static uint32_t GetDescriptorLength24b( int i_length )
1632 uint32_t i_l1, i_l2, i_l3;
1634 i_l1 = i_length&0x7f;
1635 i_l2 = ( i_length >> 7 )&0x7f;
1636 i_l3 = ( i_length >> 14 )&0x7f;
1638 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1641 static void GetPMT( sout_mux_t *p_mux,
1642 sout_buffer_chain_t *c )
1644 sout_mux_sys_t *p_sys = p_mux->p_sys;
1648 dvbpsi_pmt_es_t *p_es;
1649 dvbpsi_psi_section_t *p_section;
1653 dvbpsi_InitPMT( &pmt,
1654 0x01, // program number
1655 p_sys->i_pmt_version_number,
1656 1, // b_current_next
1659 if( p_sys->i_mpeg4_streams > 0 )
1663 bits_buffer_t bits_fix_IOD;
1665 /* Make valgrind happy : it works at byte level not bit one so
1666 * bit_write confuse it (but DON'T CHANGE the way that bit_write is
1667 * working (needed when fixing some bits) */
1668 memset( iod, 0, 4096 );
1670 bits_initwrite( &bits, 4096, iod );
1672 bits_write( &bits, 8, 0x01 );
1673 // InitialObjectDescriptor
1674 bits_align( &bits );
1675 bits_write( &bits, 8, 0x02 ); // tag
1676 bits_fix_IOD = bits; // save states to fix length later
1677 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1678 bits_write( &bits, 10, 0x01 ); // ObjectDescriptorID
1679 bits_write( &bits, 1, 0x00 ); // URL Flag
1680 bits_write( &bits, 1, 0x00 ); // includeInlineProfileLevelFlag
1681 bits_write( &bits, 4, 0x0f ); // reserved
1682 bits_write( &bits, 8, 0xff ); // ODProfile (no ODcapability )
1683 bits_write( &bits, 8, 0xff ); // sceneProfile
1684 bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified)
1685 bits_write( &bits, 8, 0xfe ); // visualProfile( // )
1686 bits_write( &bits, 8, 0xff ); // graphicProfile (no )
1687 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1689 ts_stream_t *p_stream;
1690 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1692 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1694 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1696 bits_align( &bits );
1697 bits_write( &bits, 8, 0x03 ); // ES_DescrTag
1698 bits_fix_ESDescr = bits;
1699 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable size
1700 bits_write( &bits, 16, p_stream->i_es_id );
1701 bits_write( &bits, 1, 0x00 ); // streamDependency
1702 bits_write( &bits, 1, 0x00 ); // URL Flag
1703 bits_write( &bits, 1, 0x00 ); // OCRStreamFlag
1704 bits_write( &bits, 5, 0x1f ); // streamPriority
1706 // DecoderConfigDesciptor
1707 bits_align( &bits );
1708 bits_write( &bits, 8, 0x04 ); // DecoderConfigDescrTag
1709 bits_fix_Decoder = bits;
1710 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) );
1711 if( p_stream->i_stream_type == 0x10 )
1713 bits_write( &bits, 8, 0x20 ); // Visual 14496-2
1714 bits_write( &bits, 6, 0x04 ); // VisualStream
1716 else if( p_stream->i_stream_type == 0x11 )
1718 bits_write( &bits, 8, 0x40 ); // Audio 14496-3
1719 bits_write( &bits, 6, 0x05 ); // AudioStream
1723 bits_write( &bits, 8, 0x00 );
1724 bits_write( &bits, 6, 0x00 );
1726 msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1728 bits_write( &bits, 1, 0x00 ); // UpStream
1729 bits_write( &bits, 1, 0x01 ); // reserved
1730 bits_write( &bits, 24, 1024 * 1024 ); // bufferSizeDB
1731 bits_write( &bits, 32, 0x7fffffff ); // maxBitrate
1732 bits_write( &bits, 32, 0 ); // avgBitrate
1734 if( p_stream->i_decoder_specific_info > 0 )
1737 // DecoderSpecificInfo
1738 bits_align( &bits );
1739 bits_write( &bits, 8, 0x05 ); // tag
1740 bits_write( &bits, 24,
1741 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1742 for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1744 bits_write( &bits, 8, ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1747 /* fix Decoder length */
1748 bits_write( &bits_fix_Decoder, 24,
1749 GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1751 /* SLConfigDescriptor : predifined (0x01) */
1752 bits_align( &bits );
1753 bits_write( &bits, 8, 0x06 ); // tag
1754 bits_write( &bits, 24, GetDescriptorLength24b( 8 ) );
1755 bits_write( &bits, 8, 0x01 ); // predefined
1756 bits_write( &bits, 1, 0 ); // durationFlag
1757 bits_write( &bits, 32, 0 ); // OCRResolution
1758 bits_write( &bits, 8, 0 ); // OCRLength
1759 bits_write( &bits, 8, 0 ); // InstantBitrateLength
1760 bits_align( &bits );
1762 /* fix ESDescr length */
1763 bits_write( &bits_fix_ESDescr, 24,
1764 GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1767 bits_align( &bits );
1768 /* fix IOD length */
1769 bits_write( &bits_fix_IOD, 24,
1770 GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1771 dvbpsi_PMTAddDescriptor( &pmt,
1777 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1779 ts_stream_t *p_stream;
1781 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1783 p_es = dvbpsi_PMTAddES( &pmt,
1784 p_stream->i_stream_type,
1786 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1791 es_id[0] = (p_stream->i_es_id >> 8)&0xff;
1792 es_id[1] = (p_stream->i_es_id)&0xff;
1793 dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
1795 else if( p_stream->i_stream_type == 0xa0 )
1798 int i_extra = __MIN( p_stream->i_decoder_specific_info,
1801 /* private DIV3 descripor */
1802 memcpy( &data[0], &p_stream->i_bih_codec, 4 );
1803 data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
1804 data[5] = ( p_stream->i_bih_width )&0xff;
1805 data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
1806 data[7] = ( p_stream->i_bih_height )&0xff;
1807 data[8] = ( i_extra >> 8 )&0xff;
1808 data[9] = ( i_extra )&0xff;
1811 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1814 /* 0xa0 is private */
1815 dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
1817 else if( p_stream->i_stream_type == 0x81 )
1819 uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1821 /* "registration" descriptor : "AC-3" */
1822 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1825 if( p_stream->lang[0] != 0 )
1829 /* I construct the content myself, way faster than looking at
1830 * over complicated/mind broken libdvbpsi way */
1831 data[0] = p_stream->lang[0];
1832 data[1] = p_stream->lang[1];
1833 data[2] = p_stream->lang[2];
1834 data[3] = 0x00; /* audio type: 0x00 undefined */
1836 dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data );
1840 p_section = dvbpsi_GenPMTSections( &pmt );
1842 p_pmt = WritePSISection( p_mux->p_sout, p_section );
1844 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1846 dvbpsi_DeletePSISections( p_section );
1847 dvbpsi_EmptyPMT( &pmt );