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 E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 );
852 BufferChainAppend( &p_stream->chain_pes, p_data );
854 if( p_sys->b_use_key_frames && p_stream == p_pcr_stream
855 && (p_data->i_flags & BLOCK_FLAG_TYPE_I )
856 && (p_stream->i_pes_length > 300000) )
858 i_shaping_delay = p_stream->i_pes_length;
859 p_stream->b_key_frame = 1;
872 i_pcr_dts = p_pcr_stream->i_pes_dts;
873 i_pcr_length = p_pcr_stream->i_pes_length;
874 p_pcr_stream->b_key_frame = 0;
876 /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
877 /* 2: calculate non accurate total size of muxed ts */
879 for( i = 0; i < p_mux->i_nb_inputs; i++ )
881 ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
884 /* False for pcr stream but it will be enough to do PCR algo */
885 for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL; p_pes = p_pes->p_next )
887 int i_size = p_pes->i_buffer;
888 if( p_pes->i_dts + p_pes->i_length > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
890 mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts;
896 i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
898 i_packet_count += ( i_size + 183 ) / 184;
901 /* add overhead for PCR (not really exact) */
902 i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176;
905 /* 3: mux PES into TS */
906 BufferChainInit( &chain_ts );
907 /* append PAT/PMT -> FIXME with big pcr delay it won't have enough pat/pmt */
908 GetPAT( p_mux, &chain_ts);
909 GetPMT( p_mux, &chain_ts );
911 i_packet_count += chain_ts.i_depth;
912 /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
918 ts_stream_t *p_stream;
922 /* Select stream (lowest dts) */
923 for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
925 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
927 if( p_stream->i_pes_dts == 0 )
932 if( i_stream == -1 ||
933 p_stream->i_pes_dts < i_dts )
936 i_dts = p_stream->i_pes_dts;
943 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
945 /* do we need to issue pcr */
947 if( p_stream == p_pcr_stream &&
948 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >= p_sys->i_pcr + p_sys->i_pcr_delay )
951 p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count;
954 /* Build the TS packet */
955 p_ts = TSNew( p_mux, p_stream, b_pcr );
958 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
963 BufferChainAppend( &chain_ts, p_ts );
966 /* 4: date and send */
967 TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
971 static void TSSchedule( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
972 mtime_t i_pcr_length, mtime_t i_pcr_dts )
974 sout_mux_sys_t *p_sys = p_mux->p_sys;
975 sout_buffer_chain_t new_chain;
976 int i_packet_count = p_chain_ts->i_depth;
979 BufferChainInit( &new_chain );
981 if ( i_pcr_length <= 0 )
983 i_pcr_length = i_packet_count;
986 for( i = 0; i < i_packet_count; i++ )
988 block_t *p_ts = BufferChainGet( p_chain_ts );
989 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
991 BufferChainAppend( &new_chain, p_ts );
994 p_ts->i_dts + p_sys->i_dts_delay * 2/3 < i_new_dts )
996 mtime_t i_max_diff = i_new_dts - p_ts->i_dts;
997 mtime_t i_cut_dts = p_ts->i_dts;
999 p_ts = BufferChainPeek( p_chain_ts );
1001 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1002 while ( p_ts != NULL && i_new_dts - p_ts->i_dts >= i_max_diff )
1004 p_ts = BufferChainGet( p_chain_ts );
1005 i_max_diff = i_new_dts - p_ts->i_dts;
1006 i_cut_dts = p_ts->i_dts;
1007 BufferChainAppend( &new_chain, p_ts );
1009 p_ts = BufferChainPeek( p_chain_ts );
1011 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1013 msg_Dbg( p_mux, "adjusting rate at "I64Fd"/"I64Fd" (%d/%d)",
1014 i_cut_dts - i_pcr_dts, i_pcr_length, new_chain.i_depth,
1015 p_chain_ts->i_depth );
1016 if ( new_chain.i_depth )
1017 TSDate( p_mux, &new_chain,
1018 i_cut_dts - i_pcr_dts,
1020 if ( p_chain_ts->i_depth )
1022 p_chain_ts, i_pcr_dts + i_pcr_length - i_cut_dts,
1028 if ( new_chain.i_depth )
1029 TSDate( p_mux, &new_chain, i_pcr_length, i_pcr_dts );
1032 static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1033 mtime_t i_pcr_length, mtime_t i_pcr_dts )
1035 sout_mux_sys_t *p_sys = p_mux->p_sys;
1036 int i_packet_count = p_chain_ts->i_depth;
1039 if ( i_pcr_length > 0 )
1041 int i_bitrate = ((uint64_t)i_packet_count * 188 * 8000)
1042 / (uint64_t)(i_pcr_length / 1000);
1043 if ( p_sys->i_bitrate_max && p_sys->i_bitrate_max < i_bitrate )
1046 "max bitrate exceeded at %lld (%d bi/s for %d pkt in %lld us)",
1047 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1048 i_bitrate, i_packet_count, i_pcr_length);
1054 "starting at %lld (%d bi/s for %d packets in %lld us)",
1055 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1056 i_bitrate, i_packet_count, i_pcr_length);
1062 /* This shouldn't happen, but happens in some rare heavy load
1063 * and packet losses conditions. */
1064 i_pcr_length = i_packet_count;
1067 /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
1068 for( i = 0; i < i_packet_count; i++ )
1070 block_t *p_ts = BufferChainGet( p_chain_ts );
1071 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1073 p_ts->i_dts = i_new_dts;
1074 p_ts->i_length = i_pcr_length / i_packet_count;
1076 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_PCR )
1078 /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
1079 TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
1081 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_CSA )
1083 csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
1087 p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
1089 sout_AccessOutWrite( p_mux->p_access, p_ts );
1093 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr )
1095 block_t *p_pes = p_stream->chain_pes.p_first;
1098 vlc_bool_t b_new_pes = VLC_FALSE;
1099 vlc_bool_t b_adaptation_field = VLC_FALSE;
1101 int i_payload_max = 184 - ( b_pcr ? 8 : 0 );
1104 if( p_stream->i_pes_used <= 0 )
1106 b_new_pes = VLC_TRUE;
1108 i_payload = __MIN( (int)p_pes->i_buffer - p_stream->i_pes_used, i_payload_max );
1110 if( b_pcr || i_payload < i_payload_max )
1112 b_adaptation_field = VLC_TRUE;
1115 p_ts = block_New( p_mux, 188 );
1116 p_ts->i_dts = p_pes->i_dts;
1118 p_ts->p_buffer[0] = 0x47;
1119 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|( ( p_stream->i_pid >> 8 )&0x1f );
1120 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1121 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|p_stream->i_continuity_counter;
1123 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1125 if( b_adaptation_field )
1131 int i_stuffing = i_payload_max - i_payload;
1133 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
1135 p_ts->p_buffer[4] = 7 + i_stuffing;
1136 p_ts->p_buffer[5] = 0x10; /* flags */
1137 p_ts->p_buffer[6] = ( 0 )&0xff;
1138 p_ts->p_buffer[7] = ( 0 )&0xff;
1139 p_ts->p_buffer[8] = ( 0 )&0xff;
1140 p_ts->p_buffer[9] = ( 0 )&0xff;
1141 p_ts->p_buffer[10]= ( 0 )&0x80;
1142 p_ts->p_buffer[11]= 0;
1144 for( i = 12; i < 12 + i_stuffing; i++ )
1146 p_ts->p_buffer[i] = 0xff;
1151 int i_stuffing = i_payload_max - i_payload;
1153 p_ts->p_buffer[4] = i_stuffing - 1;
1154 if( i_stuffing > 1 )
1156 p_ts->p_buffer[5] = 0x00;
1157 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1159 p_ts->p_buffer[i] = 0xff;
1166 memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
1168 p_stream->i_pes_used += i_payload;
1169 p_stream->i_pes_dts = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_buffer;
1170 p_stream->i_pes_length -= p_pes->i_length * i_payload / p_pes->i_buffer;
1172 if( p_stream->i_pes_used >= (int)p_pes->i_buffer )
1174 p_pes = BufferChainGet( &p_stream->chain_pes );
1175 block_Release( p_pes );
1177 p_pes = p_stream->chain_pes.p_first;
1180 p_stream->i_pes_dts = p_pes->i_dts;
1181 p_stream->i_pes_length = 0;
1184 p_stream->i_pes_length += p_pes->i_length;
1186 p_pes = p_pes->p_next;
1191 p_stream->i_pes_dts = 0;
1192 p_stream->i_pes_length = 0;
1194 p_stream->i_pes_used = 0;
1201 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
1203 mtime_t i_pcr = 9 * i_dts / 100;
1205 p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
1206 p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
1207 p_ts->p_buffer[8] = ( i_pcr >> 9 )&0xff;
1208 p_ts->p_buffer[9] = ( i_pcr >> 1 )&0xff;
1209 p_ts->p_buffer[10]|= ( i_pcr << 7 )&0x80;
1213 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 )
1215 sout_mux_sys_t *p_sys = p_mux->p_sys;
1216 sout_buffer_chain_t s = *c;
1219 int i_packets_min = 0;
1220 int i_packets_max = 0;
1227 i_packets = c->i_depth;
1228 i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000 + 187 ) / 188;
1229 i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000 + 187 ) / 188;
1231 if( i_packets < i_packets_min && i_packets_min > 0 )
1234 int i_div = ( i_packets_min - i_packets ) / i_packets;
1235 int i_mod = ( i_packets_min - i_packets ) % i_packets;
1238 /* We need to pad with null packets (pid=0x1fff)
1239 * We try to melt null packets with true packets */
1241 "packets=%d but min=%d -> adding %d packets of padding",
1242 i_packets, i_packets_min, i_packets_min - i_packets );
1244 BufferChainInit( c );
1245 while( ( p_pk = BufferChainGet( &s ) ) )
1249 BufferChainAppend( c, p_pk );
1251 i_null = i_div + ( i_rest + i_mod ) / i_packets;
1253 for( i = 0; i < i_null; i++ )
1257 p_null = sout_BufferNew( p_mux->p_sout, 188 );
1258 p_null->p_buffer[0] = 0x47;
1259 p_null->p_buffer[1] = 0x1f;
1260 p_null->p_buffer[2] = 0xff;
1261 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
1262 memset( &p_null->p_buffer[4], 0, 184 );
1263 p_sys->i_null_continuity_counter =
1264 ( p_sys->i_null_continuity_counter + 1 ) % 16;
1266 BufferChainAppend( c, p_null );
1269 i_rest = ( i_rest + i_mod ) % i_packets;
1272 else if( i_packets > i_packets_max && i_packets_max > 0 )
1277 /* Arg, we need to drop packets, I don't do something clever (like
1278 * dropping complete pid, b frames, ... ), I just get the right amount
1279 * of packets and discard the others */
1281 "packets=%d but max=%d -> removing %d packets -> stream broken",
1282 i_packets, i_packets_max, i_packets - i_packets_max );
1284 BufferChainInit( c );
1285 for( i = 0; i < i_packets_max; i++ )
1287 BufferChainAppend( c, BufferChainGet( &s ) );
1290 while( ( p_pk = BufferChainGet( &s ) ) )
1292 sout_BufferDelete( p_mux->p_sout, p_pk );
1298 static void PEStoTS( sout_instance_t *p_sout,
1299 sout_buffer_chain_t *c, block_t *p_pes,
1300 ts_stream_t *p_stream )
1306 /* get PES total size */
1307 i_size = p_pes->i_buffer;
1308 p_data = p_pes->p_buffer;
1310 b_new_pes = VLC_TRUE;
1314 int b_adaptation_field;
1318 p_ts = block_New( p_sout, 188 );
1321 * 1b transport_error_indicator
1322 * 1b payload_unit_start
1323 * 1b transport_priority
1325 * 2b transport_scrambling_control
1326 * 2b if adaptation_field 0x03 else 0x01
1327 * 4b continuity_counter
1330 i_copy = __MIN( i_size, 184 );
1331 b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
1333 p_ts->p_buffer[0] = 0x47;
1334 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
1335 ( ( p_stream->i_pid >> 8 )&0x1f );
1336 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1337 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
1338 p_stream->i_continuity_counter;
1340 b_new_pes = VLC_FALSE;
1341 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1343 if( b_adaptation_field )
1345 int i_stuffing = 184 - i_copy;
1348 p_ts->p_buffer[4] = i_stuffing - 1;
1349 if( i_stuffing > 1 )
1351 p_ts->p_buffer[5] = 0x00;
1352 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1354 p_ts->p_buffer[i] = 0xff;
1359 memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1363 BufferChainAppend( c, p_ts );
1367 block_t *p_next = p_pes->p_next;
1369 p_pes->p_next = NULL;
1370 block_Release( p_pes );
1371 if( p_next == NULL )
1375 b_new_pes = VLC_TRUE;
1377 i_size = p_pes->i_buffer;
1378 p_data = p_pes->p_buffer;
1385 #if defined MODULE_NAME_IS_mux_ts
1386 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1388 static uint32_t CRC32[256] =
1390 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1391 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1392 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1393 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1394 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1395 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1396 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1397 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1398 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1399 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1400 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1401 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1402 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1403 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1404 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1405 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1406 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1407 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1408 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1409 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1410 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1411 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1412 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1413 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1414 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1415 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1416 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1417 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1418 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1419 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1420 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1421 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1422 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1423 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1424 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1425 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1426 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1427 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1428 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1429 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1430 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1431 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1432 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1433 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1434 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1435 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1436 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1437 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1438 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1439 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1440 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1441 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1442 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1443 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1444 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1445 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1446 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1447 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1448 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1449 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1450 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1451 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1452 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1453 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1456 uint32_t i_crc = 0xffffffff;
1458 /* Calculate the CRC */
1459 while( i_count > 0 )
1461 i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1469 static void GetPAT( sout_mux_t *p_mux,
1470 sout_buffer_chain_t *c )
1472 sout_mux_sys_t *p_sys = p_mux->p_sys;
1476 p_pat = block_New( p_mux, 1024 );
1480 p_pat->i_length = 0;
1482 bits_initwrite( &bits, 1024, p_pat->p_buffer );
1484 bits_write( &bits, 8, 0 ); // pointer
1485 bits_write( &bits, 8, 0x00 ); // table id
1486 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1487 bits_write( &bits, 1, 0 ); // 0
1488 bits_write( &bits, 2, 0x03 ); // reserved FIXME
1489 bits_write( &bits, 12, 13 ); // XXX for one program only XXX
1490 bits_write( &bits, 16, 0x01 ); // FIXME stream id
1491 bits_write( &bits, 2, 0x03 ); // FIXME
1492 bits_write( &bits, 5, p_sys->i_pat_version_number );
1493 bits_write( &bits, 1, 1 ); // current_next_indicator
1494 bits_write( &bits, 8, 0 ); // section number
1495 bits_write( &bits, 8, 0 ); // last section number
1497 bits_write( &bits, 16, 1 ); // program number
1498 bits_write( &bits, 3, 0x07 ); // reserved
1499 bits_write( &bits, 13, p_sys->pmt.i_pid ); // program map pid
1501 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1503 p_pat->i_buffer = bits.i_data;
1505 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1508 static void GetPMT( sout_mux_t *p_mux,
1509 sout_buffer_chain_t *c )
1511 sout_mux_sys_t *p_sys = p_mux->p_sys;
1516 p_pmt = block_New( p_mux, 1024 );
1520 p_pmt->i_length = 0;
1522 bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1524 bits_write( &bits, 8, 0 ); // pointer
1525 bits_write( &bits, 8, 0x02 ); // table id
1526 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1527 bits_write( &bits, 1, 0 ); // 0
1528 bits_write( &bits, 2, 0 ); // reserved FIXME
1529 bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1530 bits_write( &bits, 16, 1 ); // FIXME program number
1531 bits_write( &bits, 2, 0 ); // FIXME
1532 bits_write( &bits, 5, p_sys->i_pmt_version_number );
1533 bits_write( &bits, 1, 1 ); // current_next_indicator
1534 bits_write( &bits, 8, 0 ); // section number
1535 bits_write( &bits, 8, 0 ); // last section number
1537 bits_write( &bits, 3, 0 ); // reserved
1539 bits_write( &bits, 13, p_sys->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
1540 bits_write( &bits, 4, 0 ); // reserved FIXME
1542 bits_write( &bits, 12, 0 ); // program info len FIXME
1544 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1546 ts_stream_t *p_stream;
1548 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1550 bits_write( &bits, 8, p_stream->i_stream_type ); // stream_type
1551 bits_write( &bits, 3, 0 ); // reserved
1552 bits_write( &bits, 13, p_stream->i_pid ); // es pid
1553 bits_write( &bits, 4, 0 ); //reserved
1554 bits_write( &bits, 12, 0 ); // es info len FIXME
1557 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1559 p_pmt->i_buffer = bits.i_data;
1561 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1563 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1565 static block_t *WritePSISection( sout_instance_t *p_sout,
1566 dvbpsi_psi_section_t* p_section )
1568 block_t *p_psi, *p_first = NULL;
1575 i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1576 ( p_section->b_syntax_indicator ? 4 : 0 );
1578 p_psi = block_New( p_sout, i_size + 1 );
1581 p_psi->i_length = 0;
1582 p_psi->i_buffer = i_size + 1;
1584 p_psi->p_buffer[0] = 0; // pointer
1585 memcpy( p_psi->p_buffer + 1,
1589 block_ChainAppend( &p_first, p_psi );
1591 p_section = p_section->p_next;
1597 static void GetPAT( sout_mux_t *p_mux,
1598 sout_buffer_chain_t *c )
1600 sout_mux_sys_t *p_sys = p_mux->p_sys;
1603 dvbpsi_psi_section_t *p_section;
1605 dvbpsi_InitPAT( &pat,
1607 p_sys->i_pat_version_number,
1608 1 ); // b_current_next
1609 /* add all program (only one) */
1610 dvbpsi_PATAddProgram( &pat,
1612 p_sys->pmt.i_pid ); // i_pid
1614 p_section = dvbpsi_GenPATSections( &pat,
1615 0 ); // max program per section
1617 p_pat = WritePSISection( p_mux->p_sout, p_section );
1619 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1621 dvbpsi_DeletePSISections( p_section );
1622 dvbpsi_EmptyPAT( &pat );
1625 static uint32_t GetDescriptorLength24b( int i_length )
1627 uint32_t i_l1, i_l2, i_l3;
1629 i_l1 = i_length&0x7f;
1630 i_l2 = ( i_length >> 7 )&0x7f;
1631 i_l3 = ( i_length >> 14 )&0x7f;
1633 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1636 static void GetPMT( sout_mux_t *p_mux,
1637 sout_buffer_chain_t *c )
1639 sout_mux_sys_t *p_sys = p_mux->p_sys;
1643 dvbpsi_pmt_es_t *p_es;
1644 dvbpsi_psi_section_t *p_section;
1648 dvbpsi_InitPMT( &pmt,
1649 0x01, // program number
1650 p_sys->i_pmt_version_number,
1651 1, // b_current_next
1654 if( p_sys->i_mpeg4_streams > 0 )
1658 bits_buffer_t bits_fix_IOD;
1660 /* Make valgrind happy : it works at byte level not bit one so
1661 * bit_write confuse it (but DON'T CHANGE the way that bit_write is
1662 * working (needed when fixing some bits) */
1663 memset( iod, 0, 4096 );
1665 bits_initwrite( &bits, 4096, iod );
1667 bits_write( &bits, 8, 0x01 );
1668 // InitialObjectDescriptor
1669 bits_align( &bits );
1670 bits_write( &bits, 8, 0x02 ); // tag
1671 bits_fix_IOD = bits; // save states to fix length later
1672 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1673 bits_write( &bits, 10, 0x01 ); // ObjectDescriptorID
1674 bits_write( &bits, 1, 0x00 ); // URL Flag
1675 bits_write( &bits, 1, 0x00 ); // includeInlineProfileLevelFlag
1676 bits_write( &bits, 4, 0x0f ); // reserved
1677 bits_write( &bits, 8, 0xff ); // ODProfile (no ODcapability )
1678 bits_write( &bits, 8, 0xff ); // sceneProfile
1679 bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified)
1680 bits_write( &bits, 8, 0xfe ); // visualProfile( // )
1681 bits_write( &bits, 8, 0xff ); // graphicProfile (no )
1682 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1684 ts_stream_t *p_stream;
1685 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1687 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1689 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1691 bits_align( &bits );
1692 bits_write( &bits, 8, 0x03 ); // ES_DescrTag
1693 bits_fix_ESDescr = bits;
1694 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable size
1695 bits_write( &bits, 16, p_stream->i_es_id );
1696 bits_write( &bits, 1, 0x00 ); // streamDependency
1697 bits_write( &bits, 1, 0x00 ); // URL Flag
1698 bits_write( &bits, 1, 0x00 ); // OCRStreamFlag
1699 bits_write( &bits, 5, 0x1f ); // streamPriority
1701 // DecoderConfigDesciptor
1702 bits_align( &bits );
1703 bits_write( &bits, 8, 0x04 ); // DecoderConfigDescrTag
1704 bits_fix_Decoder = bits;
1705 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) );
1706 if( p_stream->i_stream_type == 0x10 )
1708 bits_write( &bits, 8, 0x20 ); // Visual 14496-2
1709 bits_write( &bits, 6, 0x04 ); // VisualStream
1711 else if( p_stream->i_stream_type == 0x11 )
1713 bits_write( &bits, 8, 0x40 ); // Audio 14496-3
1714 bits_write( &bits, 6, 0x05 ); // AudioStream
1718 bits_write( &bits, 8, 0x00 );
1719 bits_write( &bits, 6, 0x00 );
1721 msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1723 bits_write( &bits, 1, 0x00 ); // UpStream
1724 bits_write( &bits, 1, 0x01 ); // reserved
1725 bits_write( &bits, 24, 1024 * 1024 ); // bufferSizeDB
1726 bits_write( &bits, 32, 0x7fffffff ); // maxBitrate
1727 bits_write( &bits, 32, 0 ); // avgBitrate
1729 if( p_stream->i_decoder_specific_info > 0 )
1732 // DecoderSpecificInfo
1733 bits_align( &bits );
1734 bits_write( &bits, 8, 0x05 ); // tag
1735 bits_write( &bits, 24,
1736 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1737 for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1739 bits_write( &bits, 8, ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1742 /* fix Decoder length */
1743 bits_write( &bits_fix_Decoder, 24,
1744 GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1746 /* SLConfigDescriptor : predifined (0x01) */
1747 bits_align( &bits );
1748 bits_write( &bits, 8, 0x06 ); // tag
1749 bits_write( &bits, 24, GetDescriptorLength24b( 8 ) );
1750 bits_write( &bits, 8, 0x01 ); // predefined
1751 bits_write( &bits, 1, 0 ); // durationFlag
1752 bits_write( &bits, 32, 0 ); // OCRResolution
1753 bits_write( &bits, 8, 0 ); // OCRLength
1754 bits_write( &bits, 8, 0 ); // InstantBitrateLength
1755 bits_align( &bits );
1757 /* fix ESDescr length */
1758 bits_write( &bits_fix_ESDescr, 24,
1759 GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1762 bits_align( &bits );
1763 /* fix IOD length */
1764 bits_write( &bits_fix_IOD, 24,
1765 GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1766 dvbpsi_PMTAddDescriptor( &pmt,
1772 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1774 ts_stream_t *p_stream;
1776 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1778 p_es = dvbpsi_PMTAddES( &pmt,
1779 p_stream->i_stream_type,
1781 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1786 es_id[0] = (p_stream->i_es_id >> 8)&0xff;
1787 es_id[1] = (p_stream->i_es_id)&0xff;
1788 dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
1790 else if( p_stream->i_stream_type == 0xa0 )
1793 int i_extra = __MIN( p_stream->i_decoder_specific_info,
1796 /* private DIV3 descripor */
1797 memcpy( &data[0], &p_stream->i_bih_codec, 4 );
1798 data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
1799 data[5] = ( p_stream->i_bih_width )&0xff;
1800 data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
1801 data[7] = ( p_stream->i_bih_height )&0xff;
1802 data[8] = ( i_extra >> 8 )&0xff;
1803 data[9] = ( i_extra )&0xff;
1806 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1809 /* 0xa0 is private */
1810 dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
1812 else if( p_stream->i_stream_type == 0x81 )
1814 uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1816 /* "registration" descriptor : "AC-3" */
1817 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1820 if( p_stream->lang[0] != 0 )
1824 /* I construct the content myself, way faster than looking at
1825 * over complicated/mind broken libdvbpsi way */
1826 data[0] = p_stream->lang[0];
1827 data[1] = p_stream->lang[1];
1828 data[2] = p_stream->lang[2];
1829 data[3] = 0x00; /* audio type: 0x00 undefined */
1831 dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data );
1835 p_section = dvbpsi_GenPMTSections( &pmt );
1837 p_pmt = WritePSISection( p_mux->p_sout, p_section );
1839 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1841 dvbpsi_DeletePSISections( p_section );
1842 dvbpsi_EmptyPMT( &pmt );