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 = 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 case VLC_FOURCC( 'h', '2','6', '4' ):
503 p_stream->i_stream_type = 0x1b;
504 p_stream->i_stream_id = 0xe0;
506 /* XXX dirty dirty but somebody want that : using crapy MS-codec XXX */
507 /* I didn't want to do that :P */
508 case VLC_FOURCC( 'H', '2', '6', '3' ):
509 case VLC_FOURCC( 'I', '2', '6', '3' ):
510 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
511 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
512 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
513 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
514 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
515 case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
516 p_stream->i_stream_type = 0xa0; // private
517 p_stream->i_stream_id = 0xa0; // beurk
518 p_stream->i_bih_codec = p_input->p_fmt->i_codec;
519 p_stream->i_bih_width = p_input->p_fmt->video.i_width;
520 p_stream->i_bih_height = p_input->p_fmt->video.i_height;
526 p_sys->i_video_bound++;
530 switch( p_input->p_fmt->i_codec )
532 case VLC_FOURCC( 'm', 'p','g', 'a' ):
533 p_stream->i_stream_type = p_input->p_fmt->audio.i_rate >= 32000 ? 0x03 : 0x04;
534 p_stream->i_stream_id = 0xc0;
536 case VLC_FOURCC( 'a', '5','2', ' ' ):
537 p_stream->i_stream_type = 0x81;
538 p_stream->i_stream_id = 0xbd;
540 case VLC_FOURCC( 'l', 'p','c', 'm' ):
541 p_stream->i_stream_type = 0x83;
542 p_stream->i_stream_id = 0xbd;
544 case VLC_FOURCC( 'd', 't','s', ' ' ):
545 p_stream->i_stream_type = 0x85;
546 p_stream->i_stream_id = 0xbd;
549 case VLC_FOURCC( 'm', 'p','4', 'a' ):
550 p_stream->i_stream_type = 0x11;
551 p_stream->i_stream_id = 0xfa;
552 p_sys->i_mpeg4_streams++;
553 p_stream->i_es_id = p_stream->i_pid;
559 p_sys->i_audio_bound++;
563 switch( p_input->p_fmt->i_codec )
565 case VLC_FOURCC( 's', 'p','u', ' ' ):
566 p_stream->i_stream_type = 0x82;
567 p_stream->i_stream_id = 0xbd;
582 p_stream->lang[2] = '\0';
583 if( p_input->p_fmt->psz_language )
585 char *psz = p_input->p_fmt->psz_language;
586 const iso639_lang_t *pl = NULL;
588 if( strlen( psz ) == 2 )
590 pl = GetLang_1( psz );
592 else if( strlen( psz ) == 3 )
594 pl = GetLang_2B( psz );
595 if( !strcmp( pl->psz_iso639_1, "??" ) )
597 pl = GetLang_2T( psz );
600 if( pl && strcmp( pl->psz_iso639_1, "??" ) )
602 p_stream->lang[0] = pl->psz_iso639_2T[0];
603 p_stream->lang[1] = pl->psz_iso639_2T[1];
604 p_stream->lang[2] = pl->psz_iso639_2T[2];
606 msg_Dbg( p_mux, " - lang=%c%c%c",
614 /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
615 p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
616 if( p_stream->i_decoder_specific_info > 0 )
618 p_stream->p_decoder_specific_info =
619 malloc( p_stream->i_decoder_specific_info );
620 memcpy( p_stream->p_decoder_specific_info,
621 p_input->p_fmt->p_extra,
622 p_input->p_fmt->i_extra );
626 BufferChainInit( &p_stream->chain_pes );
627 p_stream->i_pes_dts = 0;
628 p_stream->i_pes_length = 0;
629 p_stream->i_pes_used = 0;
630 p_stream->b_key_frame = 0;
632 /* We only change PMT version (PAT isn't changed) */
633 p_sys->i_pmt_version_number = ( p_sys->i_pmt_version_number + 1 )%32;
636 if( p_input->p_fmt->i_cat != SPU_ES &&
637 ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) )
639 if( p_sys->p_pcr_input )
641 /* There was already a PCR stream, so clean context */
644 p_sys->i_pcr_pid = p_stream->i_pid;
645 p_sys->p_pcr_input = p_input;
647 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
653 /*****************************************************************************
654 * DelStream: called before a stream deletion
655 *****************************************************************************/
656 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
658 sout_mux_sys_t *p_sys = p_mux->p_sys;
659 ts_stream_t *p_stream;
662 p_stream = (ts_stream_t*)p_input->p_sys;
663 msg_Dbg( p_mux, "removing input pid=%d", p_stream->i_pid );
665 if( p_sys->i_pcr_pid == p_stream->i_pid )
669 /* Find a new pcr stream (Prefer Video Stream) */
670 p_sys->i_pcr_pid = 0x1fff;
671 p_sys->p_pcr_input = NULL;
672 for( i = 0; i < p_mux->i_nb_inputs; i++ )
674 if( p_mux->pp_inputs[i] == p_input )
679 if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
682 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
683 p_sys->p_pcr_input= p_mux->pp_inputs[i];
686 else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
687 p_sys->i_pcr_pid == 0x1fff )
690 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
691 p_sys->p_pcr_input= p_mux->pp_inputs[i];
694 if( p_sys->p_pcr_input )
696 /* Empty TS buffer */
699 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
702 /* Empty all data in chain_pes */
703 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
705 if( p_stream->p_decoder_specific_info )
707 free( p_stream->p_decoder_specific_info );
709 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
711 p_sys->i_mpeg4_streams--;
713 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-video" ) ) )
715 int i_pid_video = strtol( val, NULL, 0 );
716 if ( i_pid_video == p_stream->i_pid )
718 p_sys->i_pid_video = i_pid_video;
719 msg_Dbg( p_mux, "freeing video PID %d", i_pid_video );
722 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-audio" ) ) )
724 int i_pid_audio = strtol( val, NULL, 0 );
725 if ( i_pid_audio == p_stream->i_pid )
727 p_sys->i_pid_audio = i_pid_audio;
728 msg_Dbg( p_mux, "freeing audio PID %d", i_pid_audio );
733 /* We only change PMT version (PAT isn't changed) */
734 p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
739 /*****************************************************************************
740 * Mux: Call each time there is new data for at least one stream
741 *****************************************************************************
743 *****************************************************************************/
744 static int Mux( sout_mux_t *p_mux )
746 sout_mux_sys_t *p_sys = p_mux->p_sys;
747 ts_stream_t *p_pcr_stream;
749 if( p_sys->i_pcr_pid == 0x1fff )
751 msg_Dbg( p_mux, "waiting for PCR streams" );
755 p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
759 sout_buffer_chain_t chain_ts;
763 mtime_t i_pcr_length;
764 mtime_t i_shaping_delay;
767 if( p_pcr_stream->b_key_frame )
769 i_shaping_delay = p_pcr_stream->i_pes_length;
773 i_shaping_delay = p_sys->i_shaping_delay;
776 /* 1: get enough PES packet for all input */
779 vlc_bool_t b_ok = VLC_TRUE;
782 /* Accumulate enough data in the pcr stream (>i_shaping_delay) */
783 /* Accumulate enough data in all other stream ( >= length of pcr) */
784 for( i = 0; i < p_mux->i_nb_inputs; i++ )
786 sout_input_t *p_input = p_mux->pp_inputs[i];
787 ts_stream_t *p_stream = (ts_stream_t*)p_input->p_sys;
789 if( ( p_stream == p_pcr_stream
790 && p_stream->i_pes_length < i_shaping_delay ) ||
791 p_stream->i_pes_dts + p_stream->i_pes_length
792 < p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
795 if( p_input->p_fifo->i_depth <= 1 )
797 if( p_input->p_fmt->i_cat == AUDIO_ES ||
798 p_input->p_fmt->i_cat == VIDEO_ES )
800 /* We need more data */
803 else if( p_input->p_fifo->i_depth <= 0 )
805 /* spu, only one packet is needed */
811 p_data = block_FifoGet( p_input->p_fifo );
812 if( p_input->p_fifo->i_depth > 0 )
814 block_t *p_next = block_FifoShow( p_input->p_fifo );
816 p_data->i_length = p_next->i_dts - p_data->i_dts;
819 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 ) ||
820 p_data->i_dts < p_stream->i_pes_dts ||
821 ( p_stream->i_pes_dts > 0 && p_data->i_dts - 2000000 > p_stream->i_pes_dts + p_stream->i_pes_length ) )
823 msg_Warn( p_mux, "packet with too strange dts (dts=%lld,old=%lld,pcr=%lld)",
826 p_pcr_stream->i_pes_dts );
827 block_Release( p_data );
829 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
830 p_stream->i_pes_dts = 0;
831 p_stream->i_pes_used = 0;
832 p_stream->i_pes_length = 0;
834 BufferChainClean( p_mux->p_sout, &p_pcr_stream->chain_pes );
835 p_pcr_stream->i_pes_dts = 0;
836 p_pcr_stream->i_pes_used = 0;
837 p_pcr_stream->i_pes_length = 0;
842 if( p_data->i_length < 0 || p_data->i_length > 2000000 )
844 /* FIXME choose a better value, but anyway we should never
846 p_data->i_length = 1000;
848 p_stream->i_pes_length += p_data->i_length;
849 if( p_stream->i_pes_dts == 0 )
851 p_stream->i_pes_dts = p_data->i_dts;
855 if( p_stream->i_stream_id == 0xa0 && p_data->i_pts <= 0 )
857 /* XXX yes I know, it's awfull, but it's needed, so don't remove it ... */
858 p_data->i_pts = p_data->i_dts;
860 E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 );
862 BufferChainAppend( &p_stream->chain_pes, p_data );
864 if( p_sys->b_use_key_frames && p_stream == p_pcr_stream
865 && (p_data->i_flags & BLOCK_FLAG_TYPE_I )
866 && (p_stream->i_pes_length > 300000) )
868 i_shaping_delay = p_stream->i_pes_length;
869 p_stream->b_key_frame = 1;
882 i_pcr_dts = p_pcr_stream->i_pes_dts;
883 i_pcr_length = p_pcr_stream->i_pes_length;
884 p_pcr_stream->b_key_frame = 0;
886 /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
887 /* 2: calculate non accurate total size of muxed ts */
889 for( i = 0; i < p_mux->i_nb_inputs; i++ )
891 ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
894 /* False for pcr stream but it will be enough to do PCR algo */
895 for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL; p_pes = p_pes->p_next )
897 int i_size = p_pes->i_buffer;
898 if( p_pes->i_dts + p_pes->i_length > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
900 mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts;
906 i_size = p_pes->i_buffer * i_frag / p_pes->i_length;
908 i_packet_count += ( i_size + 183 ) / 184;
911 /* add overhead for PCR (not really exact) */
912 i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176;
915 /* 3: mux PES into TS */
916 BufferChainInit( &chain_ts );
917 /* append PAT/PMT -> FIXME with big pcr delay it won't have enough pat/pmt */
918 GetPAT( p_mux, &chain_ts);
919 GetPMT( p_mux, &chain_ts );
921 i_packet_count += chain_ts.i_depth;
922 /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
928 ts_stream_t *p_stream;
929 sout_input_t *p_input;
933 /* Select stream (lowest dts) */
934 for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
936 p_input = p_mux->pp_inputs[i];
937 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
939 if( p_stream->i_pes_dts == 0 )
944 if( i_stream == -1 ||
945 p_stream->i_pes_dts < i_dts )
948 i_dts = p_stream->i_pes_dts;
955 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
957 /* do we need to issue pcr */
959 if( p_stream == p_pcr_stream &&
960 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >= p_sys->i_pcr + p_sys->i_pcr_delay )
963 p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count;
966 /* Build the TS packet */
967 p_ts = TSNew( p_mux, p_stream, b_pcr );
968 if( p_sys->csa != NULL &&
969 (p_input->p_fmt->i_cat != AUDIO_ES || p_sys->b_crypt_audio) )
971 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
976 BufferChainAppend( &chain_ts, p_ts );
979 /* 4: date and send */
980 TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );
984 static void TSSchedule( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
985 mtime_t i_pcr_length, mtime_t i_pcr_dts )
987 sout_mux_sys_t *p_sys = p_mux->p_sys;
988 sout_buffer_chain_t new_chain;
989 int i_packet_count = p_chain_ts->i_depth;
992 BufferChainInit( &new_chain );
994 if ( i_pcr_length <= 0 )
996 i_pcr_length = i_packet_count;
999 for( i = 0; i < i_packet_count; i++ )
1001 block_t *p_ts = BufferChainGet( p_chain_ts );
1002 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1004 BufferChainAppend( &new_chain, p_ts );
1007 p_ts->i_dts + p_sys->i_dts_delay * 2/3 < i_new_dts )
1009 mtime_t i_max_diff = i_new_dts - p_ts->i_dts;
1010 mtime_t i_cut_dts = p_ts->i_dts;
1012 p_ts = BufferChainPeek( p_chain_ts );
1014 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1015 while ( p_ts != NULL && i_new_dts - p_ts->i_dts >= i_max_diff )
1017 p_ts = BufferChainGet( p_chain_ts );
1018 i_max_diff = i_new_dts - p_ts->i_dts;
1019 i_cut_dts = p_ts->i_dts;
1020 BufferChainAppend( &new_chain, p_ts );
1022 p_ts = BufferChainPeek( p_chain_ts );
1024 i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1026 msg_Dbg( p_mux, "adjusting rate at "I64Fd"/"I64Fd" (%d/%d)",
1027 i_cut_dts - i_pcr_dts, i_pcr_length, new_chain.i_depth,
1028 p_chain_ts->i_depth );
1029 if ( new_chain.i_depth )
1030 TSDate( p_mux, &new_chain,
1031 i_cut_dts - i_pcr_dts,
1033 if ( p_chain_ts->i_depth )
1035 p_chain_ts, i_pcr_dts + i_pcr_length - i_cut_dts,
1041 if ( new_chain.i_depth )
1042 TSDate( p_mux, &new_chain, i_pcr_length, i_pcr_dts );
1045 static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
1046 mtime_t i_pcr_length, mtime_t i_pcr_dts )
1048 sout_mux_sys_t *p_sys = p_mux->p_sys;
1049 int i_packet_count = p_chain_ts->i_depth;
1052 if ( i_pcr_length > 0 )
1054 int i_bitrate = ((uint64_t)i_packet_count * 188 * 8000)
1055 / (uint64_t)(i_pcr_length / 1000);
1056 if ( p_sys->i_bitrate_max && p_sys->i_bitrate_max < i_bitrate )
1059 "max bitrate exceeded at %lld (%d bi/s for %d pkt in %lld us)",
1060 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1061 i_bitrate, i_packet_count, i_pcr_length);
1067 "starting at %lld (%d bi/s for %d packets in %lld us)",
1068 i_pcr_dts + p_sys->i_shaping_delay * 3 / 2 - mdate(),
1069 i_bitrate, i_packet_count, i_pcr_length);
1075 /* This shouldn't happen, but happens in some rare heavy load
1076 * and packet losses conditions. */
1077 i_pcr_length = i_packet_count;
1080 /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
1081 for( i = 0; i < i_packet_count; i++ )
1083 block_t *p_ts = BufferChainGet( p_chain_ts );
1084 mtime_t i_new_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
1086 p_ts->i_dts = i_new_dts;
1087 p_ts->i_length = i_pcr_length / i_packet_count;
1089 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_PCR )
1091 /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
1092 TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
1094 if( p_ts->i_flags & SOUT_BUFFER_FLAGS_PRIVATE_CSA )
1096 csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
1100 p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
1102 sout_AccessOutWrite( p_mux->p_access, p_ts );
1106 static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr )
1108 block_t *p_pes = p_stream->chain_pes.p_first;
1111 vlc_bool_t b_new_pes = VLC_FALSE;
1112 vlc_bool_t b_adaptation_field = VLC_FALSE;
1114 int i_payload_max = 184 - ( b_pcr ? 8 : 0 );
1117 if( p_stream->i_pes_used <= 0 )
1119 b_new_pes = VLC_TRUE;
1121 i_payload = __MIN( (int)p_pes->i_buffer - p_stream->i_pes_used, i_payload_max );
1123 if( b_pcr || i_payload < i_payload_max )
1125 b_adaptation_field = VLC_TRUE;
1128 p_ts = block_New( p_mux, 188 );
1129 p_ts->i_dts = p_pes->i_dts;
1131 p_ts->p_buffer[0] = 0x47;
1132 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|( ( p_stream->i_pid >> 8 )&0x1f );
1133 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1134 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|p_stream->i_continuity_counter;
1136 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1138 if( b_adaptation_field )
1144 int i_stuffing = i_payload_max - i_payload;
1146 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
1148 p_ts->p_buffer[4] = 7 + i_stuffing;
1149 p_ts->p_buffer[5] = 0x10; /* flags */
1150 p_ts->p_buffer[6] = ( 0 )&0xff;
1151 p_ts->p_buffer[7] = ( 0 )&0xff;
1152 p_ts->p_buffer[8] = ( 0 )&0xff;
1153 p_ts->p_buffer[9] = ( 0 )&0xff;
1154 p_ts->p_buffer[10]= ( 0 )&0x80;
1155 p_ts->p_buffer[11]= 0;
1157 for( i = 12; i < 12 + i_stuffing; i++ )
1159 p_ts->p_buffer[i] = 0xff;
1164 int i_stuffing = i_payload_max - i_payload;
1166 p_ts->p_buffer[4] = i_stuffing - 1;
1167 if( i_stuffing > 1 )
1169 p_ts->p_buffer[5] = 0x00;
1170 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1172 p_ts->p_buffer[i] = 0xff;
1179 memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
1181 p_stream->i_pes_used += i_payload;
1182 p_stream->i_pes_dts = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_buffer;
1183 p_stream->i_pes_length -= p_pes->i_length * i_payload / p_pes->i_buffer;
1185 if( p_stream->i_pes_used >= (int)p_pes->i_buffer )
1187 p_pes = BufferChainGet( &p_stream->chain_pes );
1188 block_Release( p_pes );
1190 p_pes = p_stream->chain_pes.p_first;
1193 p_stream->i_pes_dts = p_pes->i_dts;
1194 p_stream->i_pes_length = 0;
1197 p_stream->i_pes_length += p_pes->i_length;
1199 p_pes = p_pes->p_next;
1204 p_stream->i_pes_dts = 0;
1205 p_stream->i_pes_length = 0;
1207 p_stream->i_pes_used = 0;
1214 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
1216 mtime_t i_pcr = 9 * i_dts / 100;
1218 p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
1219 p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
1220 p_ts->p_buffer[8] = ( i_pcr >> 9 )&0xff;
1221 p_ts->p_buffer[9] = ( i_pcr >> 1 )&0xff;
1222 p_ts->p_buffer[10]|= ( i_pcr << 7 )&0x80;
1226 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 )
1228 sout_mux_sys_t *p_sys = p_mux->p_sys;
1229 sout_buffer_chain_t s = *c;
1232 int i_packets_min = 0;
1233 int i_packets_max = 0;
1240 i_packets = c->i_depth;
1241 i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000 + 187 ) / 188;
1242 i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000 + 187 ) / 188;
1244 if( i_packets < i_packets_min && i_packets_min > 0 )
1247 int i_div = ( i_packets_min - i_packets ) / i_packets;
1248 int i_mod = ( i_packets_min - i_packets ) % i_packets;
1251 /* We need to pad with null packets (pid=0x1fff)
1252 * We try to melt null packets with true packets */
1254 "packets=%d but min=%d -> adding %d packets of padding",
1255 i_packets, i_packets_min, i_packets_min - i_packets );
1257 BufferChainInit( c );
1258 while( ( p_pk = BufferChainGet( &s ) ) )
1262 BufferChainAppend( c, p_pk );
1264 i_null = i_div + ( i_rest + i_mod ) / i_packets;
1266 for( i = 0; i < i_null; i++ )
1270 p_null = sout_BufferNew( p_mux->p_sout, 188 );
1271 p_null->p_buffer[0] = 0x47;
1272 p_null->p_buffer[1] = 0x1f;
1273 p_null->p_buffer[2] = 0xff;
1274 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
1275 memset( &p_null->p_buffer[4], 0, 184 );
1276 p_sys->i_null_continuity_counter =
1277 ( p_sys->i_null_continuity_counter + 1 ) % 16;
1279 BufferChainAppend( c, p_null );
1282 i_rest = ( i_rest + i_mod ) % i_packets;
1285 else if( i_packets > i_packets_max && i_packets_max > 0 )
1290 /* Arg, we need to drop packets, I don't do something clever (like
1291 * dropping complete pid, b frames, ... ), I just get the right amount
1292 * of packets and discard the others */
1294 "packets=%d but max=%d -> removing %d packets -> stream broken",
1295 i_packets, i_packets_max, i_packets - i_packets_max );
1297 BufferChainInit( c );
1298 for( i = 0; i < i_packets_max; i++ )
1300 BufferChainAppend( c, BufferChainGet( &s ) );
1303 while( ( p_pk = BufferChainGet( &s ) ) )
1305 sout_BufferDelete( p_mux->p_sout, p_pk );
1311 static void PEStoTS( sout_instance_t *p_sout,
1312 sout_buffer_chain_t *c, block_t *p_pes,
1313 ts_stream_t *p_stream )
1319 /* get PES total size */
1320 i_size = p_pes->i_buffer;
1321 p_data = p_pes->p_buffer;
1323 b_new_pes = VLC_TRUE;
1327 int b_adaptation_field;
1331 p_ts = block_New( p_sout, 188 );
1334 * 1b transport_error_indicator
1335 * 1b payload_unit_start
1336 * 1b transport_priority
1338 * 2b transport_scrambling_control
1339 * 2b if adaptation_field 0x03 else 0x01
1340 * 4b continuity_counter
1343 i_copy = __MIN( i_size, 184 );
1344 b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
1346 p_ts->p_buffer[0] = 0x47;
1347 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
1348 ( ( p_stream->i_pid >> 8 )&0x1f );
1349 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1350 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
1351 p_stream->i_continuity_counter;
1353 b_new_pes = VLC_FALSE;
1354 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1356 if( b_adaptation_field )
1358 int i_stuffing = 184 - i_copy;
1361 p_ts->p_buffer[4] = i_stuffing - 1;
1362 if( i_stuffing > 1 )
1364 p_ts->p_buffer[5] = 0x00;
1365 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1367 p_ts->p_buffer[i] = 0xff;
1372 memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1376 BufferChainAppend( c, p_ts );
1380 block_t *p_next = p_pes->p_next;
1382 p_pes->p_next = NULL;
1383 block_Release( p_pes );
1384 if( p_next == NULL )
1388 b_new_pes = VLC_TRUE;
1390 i_size = p_pes->i_buffer;
1391 p_data = p_pes->p_buffer;
1398 #if defined MODULE_NAME_IS_mux_ts
1399 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1401 static uint32_t CRC32[256] =
1403 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1404 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1405 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1406 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1407 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1408 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1409 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1410 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1411 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1412 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1413 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1414 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1415 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1416 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1417 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1418 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1419 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1420 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1421 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1422 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1423 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1424 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1425 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1426 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1427 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1428 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1429 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1430 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1431 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1432 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1433 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1434 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1435 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1436 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1437 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1438 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1439 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1440 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1441 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1442 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1443 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1444 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1445 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1446 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1447 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1448 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1449 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1450 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1451 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1452 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1453 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1454 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1455 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1456 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1457 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1458 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1459 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1460 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1461 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1462 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1463 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1464 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1465 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1466 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1469 uint32_t i_crc = 0xffffffff;
1471 /* Calculate the CRC */
1472 while( i_count > 0 )
1474 i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1482 static void GetPAT( sout_mux_t *p_mux,
1483 sout_buffer_chain_t *c )
1485 sout_mux_sys_t *p_sys = p_mux->p_sys;
1489 p_pat = block_New( p_mux, 1024 );
1493 p_pat->i_length = 0;
1495 bits_initwrite( &bits, 1024, p_pat->p_buffer );
1497 bits_write( &bits, 8, 0 ); // pointer
1498 bits_write( &bits, 8, 0x00 ); // table id
1499 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1500 bits_write( &bits, 1, 0 ); // 0
1501 bits_write( &bits, 2, 0x03 ); // reserved FIXME
1502 bits_write( &bits, 12, 13 ); // XXX for one program only XXX
1503 bits_write( &bits, 16, 0x01 ); // FIXME stream id
1504 bits_write( &bits, 2, 0x03 ); // FIXME
1505 bits_write( &bits, 5, p_sys->i_pat_version_number );
1506 bits_write( &bits, 1, 1 ); // current_next_indicator
1507 bits_write( &bits, 8, 0 ); // section number
1508 bits_write( &bits, 8, 0 ); // last section number
1510 bits_write( &bits, 16, 1 ); // program number
1511 bits_write( &bits, 3, 0x07 ); // reserved
1512 bits_write( &bits, 13, p_sys->pmt.i_pid ); // program map pid
1514 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1516 p_pat->i_buffer = bits.i_data;
1518 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1521 static void GetPMT( sout_mux_t *p_mux,
1522 sout_buffer_chain_t *c )
1524 sout_mux_sys_t *p_sys = p_mux->p_sys;
1529 p_pmt = block_New( p_mux, 1024 );
1533 p_pmt->i_length = 0;
1535 bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1537 bits_write( &bits, 8, 0 ); // pointer
1538 bits_write( &bits, 8, 0x02 ); // table id
1539 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1540 bits_write( &bits, 1, 0 ); // 0
1541 bits_write( &bits, 2, 0 ); // reserved FIXME
1542 bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1543 bits_write( &bits, 16, 1 ); // FIXME program number
1544 bits_write( &bits, 2, 0 ); // FIXME
1545 bits_write( &bits, 5, p_sys->i_pmt_version_number );
1546 bits_write( &bits, 1, 1 ); // current_next_indicator
1547 bits_write( &bits, 8, 0 ); // section number
1548 bits_write( &bits, 8, 0 ); // last section number
1550 bits_write( &bits, 3, 0 ); // reserved
1552 bits_write( &bits, 13, p_sys->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
1553 bits_write( &bits, 4, 0 ); // reserved FIXME
1555 bits_write( &bits, 12, 0 ); // program info len FIXME
1557 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1559 ts_stream_t *p_stream;
1561 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1563 bits_write( &bits, 8, p_stream->i_stream_type ); // stream_type
1564 bits_write( &bits, 3, 0 ); // reserved
1565 bits_write( &bits, 13, p_stream->i_pid ); // es pid
1566 bits_write( &bits, 4, 0 ); //reserved
1567 bits_write( &bits, 12, 0 ); // es info len FIXME
1570 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1572 p_pmt->i_buffer = bits.i_data;
1574 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1576 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1578 static block_t *WritePSISection( sout_instance_t *p_sout,
1579 dvbpsi_psi_section_t* p_section )
1581 block_t *p_psi, *p_first = NULL;
1588 i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1589 ( p_section->b_syntax_indicator ? 4 : 0 );
1591 p_psi = block_New( p_sout, i_size + 1 );
1594 p_psi->i_length = 0;
1595 p_psi->i_buffer = i_size + 1;
1597 p_psi->p_buffer[0] = 0; // pointer
1598 memcpy( p_psi->p_buffer + 1,
1602 block_ChainAppend( &p_first, p_psi );
1604 p_section = p_section->p_next;
1610 static void GetPAT( sout_mux_t *p_mux,
1611 sout_buffer_chain_t *c )
1613 sout_mux_sys_t *p_sys = p_mux->p_sys;
1616 dvbpsi_psi_section_t *p_section;
1618 dvbpsi_InitPAT( &pat,
1620 p_sys->i_pat_version_number,
1621 1 ); // b_current_next
1622 /* add all program (only one) */
1623 dvbpsi_PATAddProgram( &pat,
1625 p_sys->pmt.i_pid ); // i_pid
1627 p_section = dvbpsi_GenPATSections( &pat,
1628 0 ); // max program per section
1630 p_pat = WritePSISection( p_mux->p_sout, p_section );
1632 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1634 dvbpsi_DeletePSISections( p_section );
1635 dvbpsi_EmptyPAT( &pat );
1638 static uint32_t GetDescriptorLength24b( int i_length )
1640 uint32_t i_l1, i_l2, i_l3;
1642 i_l1 = i_length&0x7f;
1643 i_l2 = ( i_length >> 7 )&0x7f;
1644 i_l3 = ( i_length >> 14 )&0x7f;
1646 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1649 static void GetPMT( sout_mux_t *p_mux,
1650 sout_buffer_chain_t *c )
1652 sout_mux_sys_t *p_sys = p_mux->p_sys;
1656 dvbpsi_pmt_es_t *p_es;
1657 dvbpsi_psi_section_t *p_section;
1661 dvbpsi_InitPMT( &pmt,
1662 0x01, // program number
1663 p_sys->i_pmt_version_number,
1664 1, // b_current_next
1667 if( p_sys->i_mpeg4_streams > 0 )
1671 bits_buffer_t bits_fix_IOD;
1673 /* Make valgrind happy : it works at byte level not bit one so
1674 * bit_write confuse it (but DON'T CHANGE the way that bit_write is
1675 * working (needed when fixing some bits) */
1676 memset( iod, 0, 4096 );
1678 bits_initwrite( &bits, 4096, iod );
1680 bits_write( &bits, 8, 0x01 );
1681 // InitialObjectDescriptor
1682 bits_align( &bits );
1683 bits_write( &bits, 8, 0x02 ); // tag
1684 bits_fix_IOD = bits; // save states to fix length later
1685 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1686 bits_write( &bits, 10, 0x01 ); // ObjectDescriptorID
1687 bits_write( &bits, 1, 0x00 ); // URL Flag
1688 bits_write( &bits, 1, 0x00 ); // includeInlineProfileLevelFlag
1689 bits_write( &bits, 4, 0x0f ); // reserved
1690 bits_write( &bits, 8, 0xff ); // ODProfile (no ODcapability )
1691 bits_write( &bits, 8, 0xff ); // sceneProfile
1692 bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified)
1693 bits_write( &bits, 8, 0xfe ); // visualProfile( // )
1694 bits_write( &bits, 8, 0xff ); // graphicProfile (no )
1695 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1697 ts_stream_t *p_stream;
1698 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1700 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1702 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1704 bits_align( &bits );
1705 bits_write( &bits, 8, 0x03 ); // ES_DescrTag
1706 bits_fix_ESDescr = bits;
1707 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable size
1708 bits_write( &bits, 16, p_stream->i_es_id );
1709 bits_write( &bits, 1, 0x00 ); // streamDependency
1710 bits_write( &bits, 1, 0x00 ); // URL Flag
1711 bits_write( &bits, 1, 0x00 ); // OCRStreamFlag
1712 bits_write( &bits, 5, 0x1f ); // streamPriority
1714 // DecoderConfigDesciptor
1715 bits_align( &bits );
1716 bits_write( &bits, 8, 0x04 ); // DecoderConfigDescrTag
1717 bits_fix_Decoder = bits;
1718 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) );
1719 if( p_stream->i_stream_type == 0x10 )
1721 bits_write( &bits, 8, 0x20 ); // Visual 14496-2
1722 bits_write( &bits, 6, 0x04 ); // VisualStream
1724 else if( p_stream->i_stream_type == 0x11 )
1726 bits_write( &bits, 8, 0x40 ); // Audio 14496-3
1727 bits_write( &bits, 6, 0x05 ); // AudioStream
1731 bits_write( &bits, 8, 0x00 );
1732 bits_write( &bits, 6, 0x00 );
1734 msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1736 bits_write( &bits, 1, 0x00 ); // UpStream
1737 bits_write( &bits, 1, 0x01 ); // reserved
1738 bits_write( &bits, 24, 1024 * 1024 ); // bufferSizeDB
1739 bits_write( &bits, 32, 0x7fffffff ); // maxBitrate
1740 bits_write( &bits, 32, 0 ); // avgBitrate
1742 if( p_stream->i_decoder_specific_info > 0 )
1745 // DecoderSpecificInfo
1746 bits_align( &bits );
1747 bits_write( &bits, 8, 0x05 ); // tag
1748 bits_write( &bits, 24,
1749 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1750 for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1752 bits_write( &bits, 8, ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1755 /* fix Decoder length */
1756 bits_write( &bits_fix_Decoder, 24,
1757 GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1759 /* SLConfigDescriptor : predifined (0x01) */
1760 bits_align( &bits );
1761 bits_write( &bits, 8, 0x06 ); // tag
1762 bits_write( &bits, 24, GetDescriptorLength24b( 8 ) );
1763 bits_write( &bits, 8, 0x01 ); // predefined
1764 bits_write( &bits, 1, 0 ); // durationFlag
1765 bits_write( &bits, 32, 0 ); // OCRResolution
1766 bits_write( &bits, 8, 0 ); // OCRLength
1767 bits_write( &bits, 8, 0 ); // InstantBitrateLength
1768 bits_align( &bits );
1770 /* fix ESDescr length */
1771 bits_write( &bits_fix_ESDescr, 24,
1772 GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1775 bits_align( &bits );
1776 /* fix IOD length */
1777 bits_write( &bits_fix_IOD, 24,
1778 GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1779 dvbpsi_PMTAddDescriptor( &pmt,
1785 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1787 ts_stream_t *p_stream;
1789 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1791 p_es = dvbpsi_PMTAddES( &pmt,
1792 p_stream->i_stream_type,
1794 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1799 es_id[0] = (p_stream->i_es_id >> 8)&0xff;
1800 es_id[1] = (p_stream->i_es_id)&0xff;
1801 dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
1803 else if( p_stream->i_stream_type == 0xa0 )
1806 int i_extra = __MIN( p_stream->i_decoder_specific_info,
1809 /* private DIV3 descripor */
1810 memcpy( &data[0], &p_stream->i_bih_codec, 4 );
1811 data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
1812 data[5] = ( p_stream->i_bih_width )&0xff;
1813 data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
1814 data[7] = ( p_stream->i_bih_height )&0xff;
1815 data[8] = ( i_extra >> 8 )&0xff;
1816 data[9] = ( i_extra )&0xff;
1819 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1822 /* 0xa0 is private */
1823 dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
1825 else if( p_stream->i_stream_type == 0x81 )
1827 uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1829 /* "registration" descriptor : "AC-3" */
1830 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1833 if( p_stream->lang[0] != 0 )
1837 /* I construct the content myself, way faster than looking at
1838 * over complicated/mind broken libdvbpsi way */
1839 data[0] = p_stream->lang[0];
1840 data[1] = p_stream->lang[1];
1841 data[2] = p_stream->lang[2];
1842 data[3] = 0x00; /* audio type: 0x00 undefined */
1844 dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4, data );
1848 p_section = dvbpsi_GenPMTSections( &pmt );
1850 p_pmt = WritePSISection( p_mux->p_sout, p_section );
1852 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1854 dvbpsi_DeletePSISections( p_section );
1855 dvbpsi_EmptyPMT( &pmt );