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 */
224 vlc_bool_t b_crypt_audio;
228 /* Reserve a pid and return it */
229 static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
232 if ( i_cat == VIDEO_ES && p_sys->i_pid_video )
234 i_pid = p_sys->i_pid_video;
235 p_sys->i_pid_video = 0;
237 else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio )
239 i_pid = p_sys->i_pid_audio;
240 p_sys->i_pid_audio = 0;
244 i_pid = ++p_sys->i_pid_free;
249 /*****************************************************************************
251 *****************************************************************************/
252 static int Capability(sout_mux_t *, int, void *, void * );
253 static int AddStream( sout_mux_t *, sout_input_t * );
254 static int DelStream( sout_mux_t *, sout_input_t * );
255 static int Mux ( sout_mux_t * );
257 static void TSSchedule ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
258 mtime_t i_pcr_length, mtime_t i_pcr_dts );
259 static void TSDate ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
260 mtime_t i_pcr_length, mtime_t i_pcr_dts );
261 static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
262 static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
264 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr );
265 static void TSSetPCR( block_t *p_ts, mtime_t i_dts );
267 static void PEStoTS ( sout_instance_t *, sout_buffer_chain_t *, block_t *, ts_stream_t * );
269 /*****************************************************************************
271 *****************************************************************************/
272 static int Open( vlc_object_t *p_this )
274 sout_mux_t *p_mux =(sout_mux_t*)p_this;
275 sout_mux_sys_t *p_sys;
278 msg_Dbg( p_mux, "Open" );
280 p_sys = malloc( sizeof( sout_mux_sys_t ) );
282 p_mux->pf_capacity = Capability;
283 p_mux->pf_addstream = AddStream;
284 p_mux->pf_delstream = DelStream;
286 p_mux->p_sys = p_sys;
288 srand( (uint32_t)mdate() );
290 p_sys->i_audio_bound = 0;
291 p_sys->i_video_bound = 0;
293 p_sys->i_pat_version_number = rand() % 32;
294 p_sys->pat.i_pid = 0;
295 p_sys->pat.i_continuity_counter = 0;
297 p_sys->i_pmt_version_number = rand() % 32;
298 p_sys->pmt.i_pid = 0x42;
299 p_sys->pmt.i_continuity_counter = 0;
301 p_sys->i_pid_free = 0x43;
303 p_sys->i_pid_video = 0;
304 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-video" ) ) )
306 p_sys->i_pid_video = strtol( val, NULL, 0 );
307 if ( p_sys->i_pid_video > p_sys->i_pid_free )
309 p_sys->i_pid_free = p_sys->i_pid_video + 1;
312 p_sys->i_pid_audio = 0;
313 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-audio" ) ) )
315 p_sys->i_pid_audio = strtol( val, NULL, 0 );
316 if ( p_sys->i_pid_audio > p_sys->i_pid_free )
318 p_sys->i_pid_free = p_sys->i_pid_audio + 1;
322 p_sys->i_pcr_pid = 0x1fff;
323 p_sys->p_pcr_input = NULL;
325 p_sys->i_mpeg4_streams = 0;
327 p_sys->i_null_continuity_counter = 0;
329 /* Allow to create constrained stream */
330 p_sys->i_bitrate_min = 0;
331 p_sys->i_bitrate_max = 0;
332 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "bmin" ) ) )
334 p_sys->i_bitrate_min = atoll( val );
336 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "bmax" ) ) )
338 p_sys->i_bitrate_max = atoll( val );
340 if( p_sys->i_bitrate_min > 0 && p_sys->i_bitrate_max > 0 &&
341 p_sys->i_bitrate_min > p_sys->i_bitrate_max )
343 msg_Err( p_mux, "incompatible minimum and maximum bitrate, "
344 "disabling bitrate control" );
345 p_sys->i_bitrate_min = 0;
346 p_sys->i_bitrate_max = 0;
348 if( p_sys->i_bitrate_min > 0 || p_sys->i_bitrate_max > 0 )
350 msg_Err( p_mux, "bmin and bmax no more supported (if you need them report it)" );
353 p_sys->i_shaping_delay = 200000;
354 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "shaping" ) ) )
356 p_sys->i_shaping_delay = (int64_t)atoi( val ) * 1000;
357 if( p_sys->i_shaping_delay <= 0 )
360 "invalid shaping ("I64Fd"ms) reseting to 200ms",
361 p_sys->i_shaping_delay / 1000 );
362 p_sys->i_shaping_delay = 200000;
365 p_sys->i_pcr_delay = 30000;
366 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pcr" ) ) )
368 p_sys->i_pcr_delay = (int64_t)atoi( val ) * 1000;
369 if( p_sys->i_pcr_delay <= 0 ||
370 p_sys->i_pcr_delay >= p_sys->i_shaping_delay )
373 "invalid pcr delay ("I64Fd"ms) reseting to 30ms",
374 p_sys->i_pcr_delay / 1000 );
375 p_sys->i_pcr_delay = 30000;
378 p_sys->b_use_key_frames = VLC_FALSE;
379 if( sout_cfg_find( p_mux->p_cfg, "use-key-frames" ) )
381 p_sys->b_use_key_frames = VLC_TRUE;
384 p_sys->i_dts_delay = 200000;
385 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "dts-delay" ) ) )
387 p_sys->i_dts_delay = (int64_t)atoi( val ) * 1000;
390 msg_Dbg( p_mux, "shaping="I64Fd" pcr="I64Fd" dts_delay="I64Fd,
391 p_sys->i_shaping_delay, p_sys->i_pcr_delay, p_sys->i_dts_delay );
393 /* for TS generation */
397 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "csa-ck" ) ) )
400 if( val[0] == '0' && ( val[1] == 'x' || val[1] == 'X' ) )
404 if( strlen( val ) != 16 )
406 msg_Dbg( p_mux, "invalid csa ck (it must be 16 chars long)" );
410 uint64_t i_ck = strtoll( val, NULL, 16 );
414 for( i = 0; i < 8; i++ )
416 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
419 msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x",
420 ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
422 p_sys->csa = csa_New();
423 csa_SetCW( p_sys->csa, ck, ck );
426 p_sys->b_crypt_audio = VLC_TRUE;
427 if( sout_cfg_find( p_mux->p_cfg, "no-crypt-audio" ) )
429 p_sys->b_crypt_audio = VLC_FALSE;
435 /*****************************************************************************
437 *****************************************************************************/
438 static void Close( vlc_object_t * p_this )
440 sout_mux_t *p_mux = (sout_mux_t*)p_this;
441 sout_mux_sys_t *p_sys = p_mux->p_sys;
443 msg_Dbg( p_mux, "Close" );
446 csa_Delete( p_sys->csa );
452 /*****************************************************************************
454 *****************************************************************************/
455 static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
459 case SOUT_MUX_CAP_GET_ADD_STREAM_ANY_TIME:
460 *(vlc_bool_t*)p_answer = VLC_TRUE;
461 return( SOUT_MUX_CAP_ERR_OK );
463 return( SOUT_MUX_CAP_ERR_UNIMPLEMENTED );
467 /*****************************************************************************
468 * AddStream: called for each stream addition
469 *****************************************************************************/
470 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
472 sout_mux_sys_t *p_sys = p_mux->p_sys;
473 ts_stream_t *p_stream;
475 p_input->p_sys = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
477 /* Init this new stream */
478 p_stream->i_pid = AllocatePID( p_sys, p_input->p_fmt->i_cat );
479 p_stream->i_continuity_counter = 0;
480 p_stream->i_decoder_specific_info = 0;
481 p_stream->p_decoder_specific_info = NULL;
483 msg_Dbg( p_mux, "adding input codec=%4.4s pid=%d", (char*)&p_input->p_fmt->i_codec, p_stream->i_pid );
485 /* All others fields depand on codec */
486 switch( p_input->p_fmt->i_cat )
489 switch( p_input->p_fmt->i_codec )
491 case VLC_FOURCC( 'm', 'p','g', 'v' ):
492 /* TODO: do we need to check MPEG-I/II ? */
493 p_stream->i_stream_type = 0x02;
494 p_stream->i_stream_id = 0xe0;
496 case VLC_FOURCC( 'm', 'p','4', 'v' ):
497 p_stream->i_stream_type = 0x10;
498 p_stream->i_stream_id = 0xfa;
499 p_sys->i_mpeg4_streams++;
500 p_stream->i_es_id = p_stream->i_pid;
502 /* XXX dirty dirty but somebody want that : using crapy MS-codec XXX */
503 /* I didn't want to do that :P */
504 case VLC_FOURCC( 'H', '2', '6', '3' ):
505 case VLC_FOURCC( 'I', '2', '6', '3' ):
506 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
507 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
508 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
509 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
510 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
511 case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
512 p_stream->i_stream_type = 0xa0; // private
513 p_stream->i_stream_id = 0xa0; // beurk
514 p_stream->i_bih_codec = p_input->p_fmt->i_codec;
515 p_stream->i_bih_width = p_input->p_fmt->video.i_width;
516 p_stream->i_bih_height = p_input->p_fmt->video.i_height;
522 p_sys->i_video_bound++;
526 switch( p_input->p_fmt->i_codec )
528 case VLC_FOURCC( 'm', 'p','g', 'a' ):
529 p_stream->i_stream_type = p_input->p_fmt->audio.i_rate >= 32000 ? 0x03 : 0x04;
530 p_stream->i_stream_id = 0xc0;
532 case VLC_FOURCC( 'a', '5','2', ' ' ):
533 p_stream->i_stream_type = 0x81;
534 p_stream->i_stream_id = 0xbd;
536 case VLC_FOURCC( 'l', 'p','c', 'm' ):
537 p_stream->i_stream_type = 0x83;
538 p_stream->i_stream_id = 0xbd;
540 case VLC_FOURCC( 'd', 't','s', ' ' ):
541 p_stream->i_stream_type = 0x85;
542 p_stream->i_stream_id = 0xbd;
545 case VLC_FOURCC( 'm', 'p','4', 'a' ):
546 p_stream->i_stream_type = 0x11;
547 p_stream->i_stream_id = 0xfa;
548 p_sys->i_mpeg4_streams++;
549 p_stream->i_es_id = p_stream->i_pid;
555 p_sys->i_audio_bound++;
559 switch( p_input->p_fmt->i_codec )
561 case VLC_FOURCC( 's', 'p','u', ' ' ):
562 p_stream->i_stream_type = 0x82;
563 p_stream->i_stream_id = 0xbd;
578 p_stream->lang[2] = '\0';
579 if( p_input->p_fmt->psz_language )
581 char *psz = p_input->p_fmt->psz_language;
582 const iso639_lang_t *pl = NULL;
584 if( strlen( psz ) == 2 )
586 pl = GetLang_1( psz );
588 else if( strlen( psz ) == 3 )
590 pl = GetLang_2B( psz );
591 if( !strcmp( pl->psz_iso639_1, "??" ) )
593 pl = GetLang_2T( psz );
596 if( pl && strcmp( pl->psz_iso639_1, "??" ) )
598 p_stream->lang[0] = pl->psz_iso639_2T[0];
599 p_stream->lang[1] = pl->psz_iso639_2T[1];
600 p_stream->lang[2] = pl->psz_iso639_2T[2];
602 msg_Dbg( p_mux, " - lang=%c%c%c",
610 /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
611 p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
612 if( p_stream->i_decoder_specific_info > 0 )
614 p_stream->p_decoder_specific_info =
615 malloc( p_stream->i_decoder_specific_info );
616 memcpy( p_stream->p_decoder_specific_info,
617 p_input->p_fmt->p_extra,
618 p_input->p_fmt->i_extra );
622 BufferChainInit( &p_stream->chain_pes );
623 p_stream->i_pes_dts = 0;
624 p_stream->i_pes_length = 0;
625 p_stream->i_pes_used = 0;
626 p_stream->b_key_frame = 0;
628 /* We only change PMT version (PAT isn't changed) */
629 p_sys->i_pmt_version_number = ( p_sys->i_pmt_version_number + 1 )%32;
632 if( p_input->p_fmt->i_cat != SPU_ES &&
633 ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) )
635 if( p_sys->p_pcr_input )
637 /* There was already a PCR stream, so clean context */
640 p_sys->i_pcr_pid = p_stream->i_pid;
641 p_sys->p_pcr_input = p_input;
643 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
649 /*****************************************************************************
650 * DelStream: called before a stream deletion
651 *****************************************************************************/
652 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
654 sout_mux_sys_t *p_sys = p_mux->p_sys;
655 ts_stream_t *p_stream;
658 p_stream = (ts_stream_t*)p_input->p_sys;
659 msg_Dbg( p_mux, "removing input pid=%d", p_stream->i_pid );
661 if( p_sys->i_pcr_pid == p_stream->i_pid )
665 /* Find a new pcr stream (Prefer Video Stream) */
666 p_sys->i_pcr_pid = 0x1fff;
667 p_sys->p_pcr_input = NULL;
668 for( i = 0; i < p_mux->i_nb_inputs; i++ )
670 if( p_mux->pp_inputs[i] == p_input )
675 if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
678 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
679 p_sys->p_pcr_input= p_mux->pp_inputs[i];
682 else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
683 p_sys->i_pcr_pid == 0x1fff )
686 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
687 p_sys->p_pcr_input= p_mux->pp_inputs[i];
690 if( p_sys->p_pcr_input )
692 /* Empty TS buffer */
695 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
698 /* Empty all data in chain_pes */
699 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
701 if( p_stream->p_decoder_specific_info )
703 free( p_stream->p_decoder_specific_info );
705 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
707 p_sys->i_mpeg4_streams--;
709 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-video" ) ) )
711 int i_pid_video = strtol( val, NULL, 0 );
712 if ( i_pid_video == p_stream->i_pid )
714 p_sys->i_pid_video = i_pid_video;
715 msg_Dbg( p_mux, "freeing video PID %d", i_pid_video );
718 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-audio" ) ) )
720 int i_pid_audio = strtol( val, NULL, 0 );
721 if ( i_pid_audio == p_stream->i_pid )
723 p_sys->i_pid_audio = i_pid_audio;
724 msg_Dbg( p_mux, "freeing audio PID %d", i_pid_audio );
729 /* We only change PMT version (PAT isn't changed) */
730 p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
735 /*****************************************************************************
736 * Mux: Call each time there is new data for at least one stream
737 *****************************************************************************
739 *****************************************************************************/
740 static int Mux( sout_mux_t *p_mux )
742 sout_mux_sys_t *p_sys = p_mux->p_sys;
743 ts_stream_t *p_pcr_stream;
745 if( p_sys->i_pcr_pid == 0x1fff )
747 msg_Dbg( p_mux, "waiting for PCR streams" );
751 p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
755 sout_buffer_chain_t chain_ts;
759 mtime_t i_pcr_length;
760 mtime_t i_shaping_delay;
763 if( p_pcr_stream->b_key_frame )
765 i_shaping_delay = p_pcr_stream->i_pes_length;
769 i_shaping_delay = p_sys->i_shaping_delay;
772 /* 1: get enough PES packet for all input */
775 vlc_bool_t b_ok = VLC_TRUE;
778 /* Accumulate enough data in the pcr stream (>i_shaping_delay) */
779 /* Accumulate enough data in all other stream ( >= length of pcr) */
780 for( i = 0; i < p_mux->i_nb_inputs; i++ )
782 sout_input_t *p_input = p_mux->pp_inputs[i];
783 ts_stream_t *p_stream = (ts_stream_t*)p_input->p_sys;
785 if( ( p_stream == p_pcr_stream
786 && p_stream->i_pes_length < i_shaping_delay ) ||
787 p_stream->i_pes_dts + p_stream->i_pes_length
788 < p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
791 if( p_input->p_fifo->i_depth <= 1 )
793 if( p_input->p_fmt->i_cat == AUDIO_ES ||
794 p_input->p_fmt->i_cat == VIDEO_ES )
796 /* We need more data */
799 else if( p_input->p_fifo->i_depth <= 0 )
801 /* spu, only one packet is needed */
807 p_data = block_FifoGet( p_input->p_fifo );
808 if( p_input->p_fifo->i_depth > 0 )
810 block_t *p_next = block_FifoShow( p_input->p_fifo );
812 p_data->i_length = p_next->i_dts - p_data->i_dts;
815 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 ) ||
816 p_data->i_dts < p_stream->i_pes_dts ||
817 ( p_stream->i_pes_dts > 0 && p_data->i_dts - 2000000 > p_stream->i_pes_dts + p_stream->i_pes_length ) )
819 msg_Warn( p_mux, "packet with too strange dts (dts=%lld,old=%lld,pcr=%lld)",
822 p_pcr_stream->i_pes_dts );
823 block_Release( p_data );
825 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
826 p_stream->i_pes_dts = 0;
827 p_stream->i_pes_used = 0;
828 p_stream->i_pes_length = 0;
830 BufferChainClean( p_mux->p_sout, &p_pcr_stream->chain_pes );
831 p_pcr_stream->i_pes_dts = 0;
832 p_pcr_stream->i_pes_used = 0;
833 p_pcr_stream->i_pes_length = 0;
838 if( p_data->i_length < 0 || p_data->i_length > 2000000 )
840 /* FIXME choose a better value, but anyway we should never
842 p_data->i_length = 1000;
844 p_stream->i_pes_length += p_data->i_length;
845 if( p_stream->i_pes_dts == 0 )
847 p_stream->i_pes_dts = p_data->i_dts;
851 if( p_stream->i_stream_id == 0xa0 && p_data->i_pts <= 0 )
853 /* XXX yes I know, it's awfull, but it's needed, so don't remove it ... */
854 p_data->i_pts = p_data->i_dts;
856 E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 );
858 BufferChainAppend( &p_stream->chain_pes, p_data );
860 if( p_sys->b_use_key_frames && p_stream == p_pcr_stream
861 && (p_data->i_flags & BLOCK_FLAG_TYPE_I )
862 && (p_stream->i_pes_length > 300000) )
864 i_shaping_delay = p_stream->i_pes_length;
865 p_stream->b_key_frame = 1;
878 i_pcr_dts = p_pcr_stream->i_pes_dts;
879 i_pcr_length = p_pcr_stream->i_pes_length;
880 p_pcr_stream->b_key_frame = 0;
882 /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
883 /* 2: calculate non accurate total size of muxed ts */
885 for( i = 0; i < p_mux->i_nb_inputs; i++ )
887 ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
890 /* False for pcr stream but it will be enough to do PCR algo */
891 for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL; p_pes = p_pes->p_next )
893 int i_size = p_pes->i_buffer;
894 if( p_pes->i_dts + p_pes->i_length > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
896 mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts;
902 i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
904 i_packet_count += ( i_size + 183 ) / 184;
907 /* add overhead for PCR (not really exact) */
908 i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176;
911 /* 3: mux PES into TS */
912 BufferChainInit( &chain_ts );
913 /* append PAT/PMT -> FIXME with big pcr delay it won't have enough pat/pmt */
914 GetPAT( p_mux, &chain_ts);
915 GetPMT( p_mux, &chain_ts );
917 i_packet_count += chain_ts.i_depth;
918 /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
924 ts_stream_t *p_stream;
925 sout_input_t *p_input;
929 /* Select stream (lowest dts) */
930 for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
932 p_input = p_mux->pp_inputs[i];
933 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
935 if( p_stream->i_pes_dts == 0 )
940 if( i_stream == -1 ||
941 p_stream->i_pes_dts < i_dts )
944 i_dts = p_stream->i_pes_dts;
951 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
953 /* do we need to issue pcr */
955 if( p_stream == p_pcr_stream &&
956 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >= p_sys->i_pcr + p_sys->i_pcr_delay )
959 p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count;
962 /* Build the TS packet */
963 p_ts = TSNew( p_mux, p_stream, b_pcr );
964 if( p_sys->csa != NULL &&
965 (p_input->p_fmt->i_cat != AUDIO_ES || p_sys->b_crypt_audio) )
967 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
972 BufferChainAppend( &chain_ts, p_ts );
975 /* 4: date and send */
976 TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
980 static void TSSchedule( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
981 mtime_t i_pcr_length, mtime_t i_pcr_dts )
983 sout_mux_sys_t *p_sys = p_mux->p_sys;
984 sout_buffer_chain_t new_chain;
985 int i_packet_count = p_chain_ts->i_depth;
988 BufferChainInit( &new_chain );
990 if ( i_pcr_length <= 0 )
992 i_pcr_length = i_packet_count;
995 for( i = 0; i < i_packet_count; i++ )
997 block_t *p_ts = BufferChainGet( p_chain_ts );
998 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1000 BufferChainAppend( &new_chain, p_ts );
1003 p_ts->i_dts + p_sys->i_dts_delay * 2/3 < i_new_dts )
1005 mtime_t i_max_diff = i_new_dts - p_ts->i_dts;
1006 mtime_t i_cut_dts = p_ts->i_dts;
1008 p_ts = BufferChainPeek( p_chain_ts );
1010 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1011 while ( p_ts != NULL && i_new_dts - p_ts->i_dts >= i_max_diff )
1013 p_ts = BufferChainGet( p_chain_ts );
1014 i_max_diff = i_new_dts - p_ts->i_dts;
1015 i_cut_dts = p_ts->i_dts;
1016 BufferChainAppend( &new_chain, p_ts );
1018 p_ts = BufferChainPeek( p_chain_ts );
1020 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1022 msg_Dbg( p_mux, "adjusting rate at "I64Fd"/"I64Fd" (%d/%d)",
1023 i_cut_dts - i_pcr_dts, i_pcr_length, new_chain.i_depth,
1024 p_chain_ts->i_depth );
1025 if ( new_chain.i_depth )
1026 TSDate( p_mux, &new_chain,
1027 i_cut_dts - i_pcr_dts,
1029 if ( p_chain_ts->i_depth )
1031 p_chain_ts, i_pcr_dts + i_pcr_length - i_cut_dts,
1037 if ( new_chain.i_depth )
1038 TSDate( p_mux, &new_chain, i_pcr_length, i_pcr_dts );
1041 static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1042 mtime_t i_pcr_length, mtime_t i_pcr_dts )
1044 sout_mux_sys_t *p_sys = p_mux->p_sys;
1045 int i_packet_count = p_chain_ts->i_depth;
1048 if ( i_pcr_length > 0 )
1050 int i_bitrate = ((uint64_t)i_packet_count * 188 * 8000)
1051 / (uint64_t)(i_pcr_length / 1000);
1052 if ( p_sys->i_bitrate_max && p_sys->i_bitrate_max < i_bitrate )
1055 "max bitrate exceeded at %lld (%d bi/s for %d pkt in %lld us)",
1056 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1057 i_bitrate, i_packet_count, i_pcr_length);
1063 "starting at %lld (%d bi/s for %d packets in %lld us)",
1064 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1065 i_bitrate, i_packet_count, i_pcr_length);
1071 /* This shouldn't happen, but happens in some rare heavy load
1072 * and packet losses conditions. */
1073 i_pcr_length = i_packet_count;
1076 /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
1077 for( i = 0; i < i_packet_count; i++ )
1079 block_t *p_ts = BufferChainGet( p_chain_ts );
1080 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1082 p_ts->i_dts = i_new_dts;
1083 p_ts->i_length = i_pcr_length / i_packet_count;
1085 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_PCR )
1087 /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
1088 TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
1090 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_CSA )
1092 csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
1096 p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
1098 sout_AccessOutWrite( p_mux->p_access, p_ts );
1102 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr )
1104 block_t *p_pes = p_stream->chain_pes.p_first;
1107 vlc_bool_t b_new_pes = VLC_FALSE;
1108 vlc_bool_t b_adaptation_field = VLC_FALSE;
1110 int i_payload_max = 184 - ( b_pcr ? 8 : 0 );
1113 if( p_stream->i_pes_used <= 0 )
1115 b_new_pes = VLC_TRUE;
1117 i_payload = __MIN( (int)p_pes->i_buffer - p_stream->i_pes_used, i_payload_max );
1119 if( b_pcr || i_payload < i_payload_max )
1121 b_adaptation_field = VLC_TRUE;
1124 p_ts = block_New( p_mux, 188 );
1125 p_ts->i_dts = p_pes->i_dts;
1127 p_ts->p_buffer[0] = 0x47;
1128 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|( ( p_stream->i_pid >> 8 )&0x1f );
1129 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1130 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|p_stream->i_continuity_counter;
1132 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1134 if( b_adaptation_field )
1140 int i_stuffing = i_payload_max - i_payload;
1142 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
1144 p_ts->p_buffer[4] = 7 + i_stuffing;
1145 p_ts->p_buffer[5] = 0x10; /* flags */
1146 p_ts->p_buffer[6] = ( 0 )&0xff;
1147 p_ts->p_buffer[7] = ( 0 )&0xff;
1148 p_ts->p_buffer[8] = ( 0 )&0xff;
1149 p_ts->p_buffer[9] = ( 0 )&0xff;
1150 p_ts->p_buffer[10]= ( 0 )&0x80;
1151 p_ts->p_buffer[11]= 0;
1153 for( i = 12; i < 12 + i_stuffing; i++ )
1155 p_ts->p_buffer[i] = 0xff;
1160 int i_stuffing = i_payload_max - i_payload;
1162 p_ts->p_buffer[4] = i_stuffing - 1;
1163 if( i_stuffing > 1 )
1165 p_ts->p_buffer[5] = 0x00;
1166 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1168 p_ts->p_buffer[i] = 0xff;
1175 memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
1177 p_stream->i_pes_used += i_payload;
1178 p_stream->i_pes_dts = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_buffer;
1179 p_stream->i_pes_length -= p_pes->i_length * i_payload / p_pes->i_buffer;
1181 if( p_stream->i_pes_used >= (int)p_pes->i_buffer )
1183 p_pes = BufferChainGet( &p_stream->chain_pes );
1184 block_Release( p_pes );
1186 p_pes = p_stream->chain_pes.p_first;
1189 p_stream->i_pes_dts = p_pes->i_dts;
1190 p_stream->i_pes_length = 0;
1193 p_stream->i_pes_length += p_pes->i_length;
1195 p_pes = p_pes->p_next;
1200 p_stream->i_pes_dts = 0;
1201 p_stream->i_pes_length = 0;
1203 p_stream->i_pes_used = 0;
1210 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
1212 mtime_t i_pcr = 9 * i_dts / 100;
1214 p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
1215 p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
1216 p_ts->p_buffer[8] = ( i_pcr >> 9 )&0xff;
1217 p_ts->p_buffer[9] = ( i_pcr >> 1 )&0xff;
1218 p_ts->p_buffer[10]|= ( i_pcr << 7 )&0x80;
1222 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 )
1224 sout_mux_sys_t *p_sys = p_mux->p_sys;
1225 sout_buffer_chain_t s = *c;
1228 int i_packets_min = 0;
1229 int i_packets_max = 0;
1236 i_packets = c->i_depth;
1237 i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000 + 187 ) / 188;
1238 i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000 + 187 ) / 188;
1240 if( i_packets < i_packets_min && i_packets_min > 0 )
1243 int i_div = ( i_packets_min - i_packets ) / i_packets;
1244 int i_mod = ( i_packets_min - i_packets ) % i_packets;
1247 /* We need to pad with null packets (pid=0x1fff)
1248 * We try to melt null packets with true packets */
1250 "packets=%d but min=%d -> adding %d packets of padding",
1251 i_packets, i_packets_min, i_packets_min - i_packets );
1253 BufferChainInit( c );
1254 while( ( p_pk = BufferChainGet( &s ) ) )
1258 BufferChainAppend( c, p_pk );
1260 i_null = i_div + ( i_rest + i_mod ) / i_packets;
1262 for( i = 0; i < i_null; i++ )
1266 p_null = sout_BufferNew( p_mux->p_sout, 188 );
1267 p_null->p_buffer[0] = 0x47;
1268 p_null->p_buffer[1] = 0x1f;
1269 p_null->p_buffer[2] = 0xff;
1270 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
1271 memset( &p_null->p_buffer[4], 0, 184 );
1272 p_sys->i_null_continuity_counter =
1273 ( p_sys->i_null_continuity_counter + 1 ) % 16;
1275 BufferChainAppend( c, p_null );
1278 i_rest = ( i_rest + i_mod ) % i_packets;
1281 else if( i_packets > i_packets_max && i_packets_max > 0 )
1286 /* Arg, we need to drop packets, I don't do something clever (like
1287 * dropping complete pid, b frames, ... ), I just get the right amount
1288 * of packets and discard the others */
1290 "packets=%d but max=%d -> removing %d packets -> stream broken",
1291 i_packets, i_packets_max, i_packets - i_packets_max );
1293 BufferChainInit( c );
1294 for( i = 0; i < i_packets_max; i++ )
1296 BufferChainAppend( c, BufferChainGet( &s ) );
1299 while( ( p_pk = BufferChainGet( &s ) ) )
1301 sout_BufferDelete( p_mux->p_sout, p_pk );
1307 static void PEStoTS( sout_instance_t *p_sout,
1308 sout_buffer_chain_t *c, block_t *p_pes,
1309 ts_stream_t *p_stream )
1315 /* get PES total size */
1316 i_size = p_pes->i_buffer;
1317 p_data = p_pes->p_buffer;
1319 b_new_pes = VLC_TRUE;
1323 int b_adaptation_field;
1327 p_ts = block_New( p_sout, 188 );
1330 * 1b transport_error_indicator
1331 * 1b payload_unit_start
1332 * 1b transport_priority
1334 * 2b transport_scrambling_control
1335 * 2b if adaptation_field 0x03 else 0x01
1336 * 4b continuity_counter
1339 i_copy = __MIN( i_size, 184 );
1340 b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
1342 p_ts->p_buffer[0] = 0x47;
1343 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
1344 ( ( p_stream->i_pid >> 8 )&0x1f );
1345 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1346 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
1347 p_stream->i_continuity_counter;
1349 b_new_pes = VLC_FALSE;
1350 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1352 if( b_adaptation_field )
1354 int i_stuffing = 184 - i_copy;
1357 p_ts->p_buffer[4] = i_stuffing - 1;
1358 if( i_stuffing > 1 )
1360 p_ts->p_buffer[5] = 0x00;
1361 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1363 p_ts->p_buffer[i] = 0xff;
1368 memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1372 BufferChainAppend( c, p_ts );
1376 block_t *p_next = p_pes->p_next;
1378 p_pes->p_next = NULL;
1379 block_Release( p_pes );
1380 if( p_next == NULL )
1384 b_new_pes = VLC_TRUE;
1386 i_size = p_pes->i_buffer;
1387 p_data = p_pes->p_buffer;
1394 #if defined MODULE_NAME_IS_mux_ts
1395 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1397 static uint32_t CRC32[256] =
1399 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1400 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1401 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1402 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1403 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1404 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1405 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1406 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1407 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1408 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1409 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1410 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1411 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1412 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1413 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1414 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1415 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1416 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1417 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1418 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1419 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1420 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1421 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1422 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1423 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1424 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1425 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1426 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1427 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1428 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1429 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1430 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1431 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1432 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1433 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1434 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1435 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1436 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1437 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1438 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1439 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1440 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1441 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1442 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1443 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1444 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1445 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1446 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1447 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1448 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1449 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1450 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1451 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1452 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1453 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1454 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1455 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1456 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1457 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1458 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1459 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1460 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1461 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1462 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1465 uint32_t i_crc = 0xffffffff;
1467 /* Calculate the CRC */
1468 while( i_count > 0 )
1470 i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1478 static void GetPAT( sout_mux_t *p_mux,
1479 sout_buffer_chain_t *c )
1481 sout_mux_sys_t *p_sys = p_mux->p_sys;
1485 p_pat = block_New( p_mux, 1024 );
1489 p_pat->i_length = 0;
1491 bits_initwrite( &bits, 1024, p_pat->p_buffer );
1493 bits_write( &bits, 8, 0 ); // pointer
1494 bits_write( &bits, 8, 0x00 ); // table id
1495 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1496 bits_write( &bits, 1, 0 ); // 0
1497 bits_write( &bits, 2, 0x03 ); // reserved FIXME
1498 bits_write( &bits, 12, 13 ); // XXX for one program only XXX
1499 bits_write( &bits, 16, 0x01 ); // FIXME stream id
1500 bits_write( &bits, 2, 0x03 ); // FIXME
1501 bits_write( &bits, 5, p_sys->i_pat_version_number );
1502 bits_write( &bits, 1, 1 ); // current_next_indicator
1503 bits_write( &bits, 8, 0 ); // section number
1504 bits_write( &bits, 8, 0 ); // last section number
1506 bits_write( &bits, 16, 1 ); // program number
1507 bits_write( &bits, 3, 0x07 ); // reserved
1508 bits_write( &bits, 13, p_sys->pmt.i_pid ); // program map pid
1510 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1512 p_pat->i_buffer = bits.i_data;
1514 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1517 static void GetPMT( sout_mux_t *p_mux,
1518 sout_buffer_chain_t *c )
1520 sout_mux_sys_t *p_sys = p_mux->p_sys;
1525 p_pmt = block_New( p_mux, 1024 );
1529 p_pmt->i_length = 0;
1531 bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1533 bits_write( &bits, 8, 0 ); // pointer
1534 bits_write( &bits, 8, 0x02 ); // table id
1535 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1536 bits_write( &bits, 1, 0 ); // 0
1537 bits_write( &bits, 2, 0 ); // reserved FIXME
1538 bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1539 bits_write( &bits, 16, 1 ); // FIXME program number
1540 bits_write( &bits, 2, 0 ); // FIXME
1541 bits_write( &bits, 5, p_sys->i_pmt_version_number );
1542 bits_write( &bits, 1, 1 ); // current_next_indicator
1543 bits_write( &bits, 8, 0 ); // section number
1544 bits_write( &bits, 8, 0 ); // last section number
1546 bits_write( &bits, 3, 0 ); // reserved
1548 bits_write( &bits, 13, p_sys->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
1549 bits_write( &bits, 4, 0 ); // reserved FIXME
1551 bits_write( &bits, 12, 0 ); // program info len FIXME
1553 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1555 ts_stream_t *p_stream;
1557 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1559 bits_write( &bits, 8, p_stream->i_stream_type ); // stream_type
1560 bits_write( &bits, 3, 0 ); // reserved
1561 bits_write( &bits, 13, p_stream->i_pid ); // es pid
1562 bits_write( &bits, 4, 0 ); //reserved
1563 bits_write( &bits, 12, 0 ); // es info len FIXME
1566 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1568 p_pmt->i_buffer = bits.i_data;
1570 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1572 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1574 static block_t *WritePSISection( sout_instance_t *p_sout,
1575 dvbpsi_psi_section_t* p_section )
1577 block_t *p_psi, *p_first = NULL;
1584 i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1585 ( p_section->b_syntax_indicator ? 4 : 0 );
1587 p_psi = block_New( p_sout, i_size + 1 );
1590 p_psi->i_length = 0;
1591 p_psi->i_buffer = i_size + 1;
1593 p_psi->p_buffer[0] = 0; // pointer
1594 memcpy( p_psi->p_buffer + 1,
1598 block_ChainAppend( &p_first, p_psi );
1600 p_section = p_section->p_next;
1606 static void GetPAT( sout_mux_t *p_mux,
1607 sout_buffer_chain_t *c )
1609 sout_mux_sys_t *p_sys = p_mux->p_sys;
1612 dvbpsi_psi_section_t *p_section;
1614 dvbpsi_InitPAT( &pat,
1616 p_sys->i_pat_version_number,
1617 1 ); // b_current_next
1618 /* add all program (only one) */
1619 dvbpsi_PATAddProgram( &pat,
1621 p_sys->pmt.i_pid ); // i_pid
1623 p_section = dvbpsi_GenPATSections( &pat,
1624 0 ); // max program per section
1626 p_pat = WritePSISection( p_mux->p_sout, p_section );
1628 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1630 dvbpsi_DeletePSISections( p_section );
1631 dvbpsi_EmptyPAT( &pat );
1634 static uint32_t GetDescriptorLength24b( int i_length )
1636 uint32_t i_l1, i_l2, i_l3;
1638 i_l1 = i_length&0x7f;
1639 i_l2 = ( i_length >> 7 )&0x7f;
1640 i_l3 = ( i_length >> 14 )&0x7f;
1642 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1645 static void GetPMT( sout_mux_t *p_mux,
1646 sout_buffer_chain_t *c )
1648 sout_mux_sys_t *p_sys = p_mux->p_sys;
1652 dvbpsi_pmt_es_t *p_es;
1653 dvbpsi_psi_section_t *p_section;
1657 dvbpsi_InitPMT( &pmt,
1658 0x01, // program number
1659 p_sys->i_pmt_version_number,
1660 1, // b_current_next
1663 if( p_sys->i_mpeg4_streams > 0 )
1667 bits_buffer_t bits_fix_IOD;
1669 /* Make valgrind happy : it works at byte level not bit one so
1670 * bit_write confuse it (but DON'T CHANGE the way that bit_write is
1671 * working (needed when fixing some bits) */
1672 memset( iod, 0, 4096 );
1674 bits_initwrite( &bits, 4096, iod );
1676 bits_write( &bits, 8, 0x01 );
1677 // InitialObjectDescriptor
1678 bits_align( &bits );
1679 bits_write( &bits, 8, 0x02 ); // tag
1680 bits_fix_IOD = bits; // save states to fix length later
1681 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1682 bits_write( &bits, 10, 0x01 ); // ObjectDescriptorID
1683 bits_write( &bits, 1, 0x00 ); // URL Flag
1684 bits_write( &bits, 1, 0x00 ); // includeInlineProfileLevelFlag
1685 bits_write( &bits, 4, 0x0f ); // reserved
1686 bits_write( &bits, 8, 0xff ); // ODProfile (no ODcapability )
1687 bits_write( &bits, 8, 0xff ); // sceneProfile
1688 bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified)
1689 bits_write( &bits, 8, 0xfe ); // visualProfile( // )
1690 bits_write( &bits, 8, 0xff ); // graphicProfile (no )
1691 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1693 ts_stream_t *p_stream;
1694 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1696 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1698 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1700 bits_align( &bits );
1701 bits_write( &bits, 8, 0x03 ); // ES_DescrTag
1702 bits_fix_ESDescr = bits;
1703 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable size
1704 bits_write( &bits, 16, p_stream->i_es_id );
1705 bits_write( &bits, 1, 0x00 ); // streamDependency
1706 bits_write( &bits, 1, 0x00 ); // URL Flag
1707 bits_write( &bits, 1, 0x00 ); // OCRStreamFlag
1708 bits_write( &bits, 5, 0x1f ); // streamPriority
1710 // DecoderConfigDesciptor
1711 bits_align( &bits );
1712 bits_write( &bits, 8, 0x04 ); // DecoderConfigDescrTag
1713 bits_fix_Decoder = bits;
1714 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) );
1715 if( p_stream->i_stream_type == 0x10 )
1717 bits_write( &bits, 8, 0x20 ); // Visual 14496-2
1718 bits_write( &bits, 6, 0x04 ); // VisualStream
1720 else if( p_stream->i_stream_type == 0x11 )
1722 bits_write( &bits, 8, 0x40 ); // Audio 14496-3
1723 bits_write( &bits, 6, 0x05 ); // AudioStream
1727 bits_write( &bits, 8, 0x00 );
1728 bits_write( &bits, 6, 0x00 );
1730 msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1732 bits_write( &bits, 1, 0x00 ); // UpStream
1733 bits_write( &bits, 1, 0x01 ); // reserved
1734 bits_write( &bits, 24, 1024 * 1024 ); // bufferSizeDB
1735 bits_write( &bits, 32, 0x7fffffff ); // maxBitrate
1736 bits_write( &bits, 32, 0 ); // avgBitrate
1738 if( p_stream->i_decoder_specific_info > 0 )
1741 // DecoderSpecificInfo
1742 bits_align( &bits );
1743 bits_write( &bits, 8, 0x05 ); // tag
1744 bits_write( &bits, 24,
1745 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1746 for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1748 bits_write( &bits, 8, ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1751 /* fix Decoder length */
1752 bits_write( &bits_fix_Decoder, 24,
1753 GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1755 /* SLConfigDescriptor : predifined (0x01) */
1756 bits_align( &bits );
1757 bits_write( &bits, 8, 0x06 ); // tag
1758 bits_write( &bits, 24, GetDescriptorLength24b( 8 ) );
1759 bits_write( &bits, 8, 0x01 ); // predefined
1760 bits_write( &bits, 1, 0 ); // durationFlag
1761 bits_write( &bits, 32, 0 ); // OCRResolution
1762 bits_write( &bits, 8, 0 ); // OCRLength
1763 bits_write( &bits, 8, 0 ); // InstantBitrateLength
1764 bits_align( &bits );
1766 /* fix ESDescr length */
1767 bits_write( &bits_fix_ESDescr, 24,
1768 GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1771 bits_align( &bits );
1772 /* fix IOD length */
1773 bits_write( &bits_fix_IOD, 24,
1774 GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1775 dvbpsi_PMTAddDescriptor( &pmt,
1781 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1783 ts_stream_t *p_stream;
1785 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1787 p_es = dvbpsi_PMTAddES( &pmt,
1788 p_stream->i_stream_type,
1790 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1795 es_id[0] = (p_stream->i_es_id >> 8)&0xff;
1796 es_id[1] = (p_stream->i_es_id)&0xff;
1797 dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
1799 else if( p_stream->i_stream_type == 0xa0 )
1802 int i_extra = __MIN( p_stream->i_decoder_specific_info,
1805 /* private DIV3 descripor */
1806 memcpy( &data[0], &p_stream->i_bih_codec, 4 );
1807 data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
1808 data[5] = ( p_stream->i_bih_width )&0xff;
1809 data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
1810 data[7] = ( p_stream->i_bih_height )&0xff;
1811 data[8] = ( i_extra >> 8 )&0xff;
1812 data[9] = ( i_extra )&0xff;
1815 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1818 /* 0xa0 is private */
1819 dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
1821 else if( p_stream->i_stream_type == 0x81 )
1823 uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1825 /* "registration" descriptor : "AC-3" */
1826 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1829 if( p_stream->lang[0] != 0 )
1833 /* I construct the content myself, way faster than looking at
1834 * over complicated/mind broken libdvbpsi way */
1835 data[0] = p_stream->lang[0];
1836 data[1] = p_stream->lang[1];
1837 data[2] = p_stream->lang[2];
1838 data[3] = 0x00; /* audio type: 0x00 undefined */
1840 dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data );
1844 p_section = dvbpsi_GenPMTSections( &pmt );
1846 p_pmt = WritePSISection( p_mux->p_sout, p_section );
1848 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1850 dvbpsi_DeletePSISections( p_section );
1851 dvbpsi_EmptyPMT( &pmt );