1 /*****************************************************************************
2 * ts.c: MPEG-II TS Muxer
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: ts.c,v 1.42 2004/01/25 02:26:04 fenrir Exp $
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>
40 #if defined MODULE_NAME_IS_mux_ts_dvbpsi
41 # ifdef HAVE_DVBPSI_DR_H
42 # include <dvbpsi/dvbpsi.h>
43 # include <dvbpsi/descriptor.h>
44 # include <dvbpsi/pat.h>
45 # include <dvbpsi/pmt.h>
46 # include <dvbpsi/dr.h>
47 # include <dvbpsi/psi.h>
50 # include "descriptor.h"
51 # include "tables/pat.h"
52 # include "tables/pmt.h"
53 # include "descriptors/dr.h"
60 * - check PCR frequency requirement
62 * - check PCR/PCR "soft"
63 * - check if "registration" descriptor : "AC-3" should be a program
64 * descriptor or an es one. (xine want an es one)
66 * - remove creation of PAT/PMT without dvbpsi
69 * - subtitle support is far from perfect. I expect some subtitles drop
70 * if they arrive a bit late
71 * (We cannot rely on the fact that the fifo should be full)
73 /*****************************************************************************
75 *****************************************************************************/
76 static int Open ( vlc_object_t * );
77 static void Close ( vlc_object_t * );
80 #if defined MODULE_NAME_IS_mux_ts
81 set_description( _("TS muxer") );
82 set_capability( "sout mux", 100 );
84 add_shortcut( "ts_nodvbpsi" );
85 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
86 set_description( _("TS muxer (libdvbpsi)") );
87 set_capability( "sout mux", 120 );
89 add_shortcut( "ts_dvbpsi" );
91 set_callbacks( Open, Close );
94 /*****************************************************************************
96 *****************************************************************************/
97 static int Capability(sout_mux_t *, int, void *, void * );
98 static int AddStream( sout_mux_t *, sout_input_t * );
99 static int DelStream( sout_mux_t *, sout_input_t * );
100 static int Mux ( sout_mux_t * );
102 /*****************************************************************************
104 *****************************************************************************/
105 #define SOUT_BUFFER_FLAGS_PRIVATE_PCR ( 1 << SOUT_BUFFER_FLAGS_PRIVATE_SHIFT )
106 #define SOUT_BUFFER_FLAGS_PRIVATE_CSA ( 2 << SOUT_BUFFER_FLAGS_PRIVATE_SHIFT )
110 sout_buffer_t *p_first;
111 sout_buffer_t **pp_last;
112 } sout_buffer_chain_t;
114 static inline void BufferChainInit ( sout_buffer_chain_t *c )
118 c->pp_last = &c->p_first;
120 static inline void BufferChainAppend( sout_buffer_chain_t *c, sout_buffer_t *b )
130 c->pp_last = &b->p_next;
132 static inline sout_buffer_t *BufferChainGet( sout_buffer_chain_t *c )
134 sout_buffer_t *b = c->p_first;
139 c->p_first = b->p_next;
141 if( c->p_first == NULL )
143 c->pp_last = &c->p_first;
150 static inline void BufferChainClean( sout_instance_t *p_sout, sout_buffer_chain_t *c )
154 while( ( b = BufferChainGet( c ) ) )
156 sout_BufferDelete( p_sout, b );
158 BufferChainInit( c );
161 typedef struct ts_stream_s
166 int i_continuity_counter;
168 /* to be used for carriege of DIV3 */
169 vlc_fourcc_t i_bih_codec;
170 int i_bih_width, i_bih_height;
172 /* Specific to mpeg4 in mpeg2ts */
175 int i_decoder_specific_info;
176 uint8_t *p_decoder_specific_info;
178 sout_buffer_chain_t chain_pes;
180 mtime_t i_pes_length;
185 struct sout_mux_sys_t
188 sout_input_t *p_pcr_input;
195 int i_pid_free; // first usable pid
197 int i_pat_version_number;
200 int i_pmt_version_number;
201 ts_stream_t pmt; // Up to now only one program
205 int i_null_continuity_counter; /* Needed ? */
207 /* for TS building */
208 int64_t i_bitrate_min;
209 int64_t i_bitrate_max;
211 int64_t i_caching_delay;
216 mtime_t i_pcr; /* last PCR emited */
222 /* Reserve a pid and return it */
223 static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
226 if ( i_cat == VIDEO_ES && p_sys->i_pid_video )
228 i_pid = p_sys->i_pid_video;
229 p_sys->i_pid_video = 0;
231 else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio )
233 i_pid = p_sys->i_pid_audio;
234 p_sys->i_pid_audio = 0;
238 i_pid = ++p_sys->i_pid_free;
243 static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
244 static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );
246 static sout_buffer_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr );
247 static void TSSetPCR( sout_buffer_t *p_ts, mtime_t i_dts );
249 static void PEStoTS ( sout_instance_t *, sout_buffer_chain_t *, sout_buffer_t *, ts_stream_t * );
251 /*****************************************************************************
253 *****************************************************************************/
254 static int Open( vlc_object_t *p_this )
256 sout_mux_t *p_mux =(sout_mux_t*)p_this;
257 sout_mux_sys_t *p_sys;
260 msg_Dbg( p_mux, "Open" );
262 p_sys = malloc( sizeof( sout_mux_sys_t ) );
264 p_mux->pf_capacity = Capability;
265 p_mux->pf_addstream = AddStream;
266 p_mux->pf_delstream = DelStream;
268 p_mux->p_sys = p_sys;
269 p_mux->i_preheader = 30; // really enough for a pes header
271 srand( (uint32_t)mdate() );
273 p_sys->i_audio_bound = 0;
274 p_sys->i_video_bound = 0;
276 p_sys->i_pat_version_number = rand() % 32;
277 p_sys->pat.i_pid = 0;
278 p_sys->pat.i_continuity_counter = 0;
280 p_sys->i_pmt_version_number = rand() % 32;
281 p_sys->pmt.i_pid = 0x42;
282 p_sys->pmt.i_continuity_counter = 0;
284 p_sys->i_pid_free = 0x43;
286 p_sys->i_pid_video = 0;
287 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-video" ) ) )
289 p_sys->i_pid_video = strtol( val, NULL, 0 );
290 if ( p_sys->i_pid_video > p_sys->i_pid_free )
292 p_sys->i_pid_free = p_sys->i_pid_video + 1;
295 p_sys->i_pid_audio = 0;
296 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-audio" ) ) )
298 p_sys->i_pid_audio = strtol( val, NULL, 0 );
299 if ( p_sys->i_pid_audio > p_sys->i_pid_free )
301 p_sys->i_pid_free = p_sys->i_pid_audio + 1;
305 p_sys->i_pcr_pid = 0x1fff;
306 p_sys->p_pcr_input = NULL;
308 p_sys->i_mpeg4_streams = 0;
310 p_sys->i_null_continuity_counter = 0;
312 /* Allow to create constrained stream */
313 p_sys->i_bitrate_min = 0;
314 p_sys->i_bitrate_max = 0;
315 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "bmin" ) ) )
317 p_sys->i_bitrate_min = atoll( val );
319 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "bmax" ) ) )
321 p_sys->i_bitrate_max = atoll( val );
323 if( p_sys->i_bitrate_min > 0 && p_sys->i_bitrate_max > 0 &&
324 p_sys->i_bitrate_min > p_sys->i_bitrate_max )
326 msg_Err( p_mux, "incompatible minimum and maximum bitrate, "
327 "disabling bitrate control" );
328 p_sys->i_bitrate_min = 0;
329 p_sys->i_bitrate_max = 0;
331 if( p_sys->i_bitrate_min > 0 || p_sys->i_bitrate_max > 0 )
333 msg_Err( p_mux, "bmin and bmax no more supported (if you need them report it)" );
336 p_sys->i_caching_delay = 200000;
337 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "caching" ) ) )
339 p_sys->i_caching_delay = (int64_t)atoi( val ) * 1000;
340 if( p_sys->i_caching_delay <= 0 )
343 "invalid caching ("I64Fd"ms) reseting to 200ms",
344 p_sys->i_caching_delay / 1000 );
345 p_sys->i_caching_delay = 200000;
348 p_sys->i_pcr_delay = 30000;
349 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pcr" ) ) )
351 p_sys->i_pcr_delay = (int64_t)atoi( val ) * 1000;
352 if( p_sys->i_pcr_delay <= 0 ||
353 p_sys->i_pcr_delay >= p_sys->i_caching_delay )
356 "invalid pcr delay ("I64Fd"ms) reseting to 30ms",
357 p_sys->i_pcr_delay / 1000 );
358 p_sys->i_pcr_delay = 30000;
362 msg_Dbg( p_mux, "caching="I64Fd" pcr="I64Fd,
363 p_sys->i_caching_delay, p_sys->i_pcr_delay );
365 p_sys->i_dts_delay = 200000;
366 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "dts-delay" ) ) )
368 p_sys->i_dts_delay = (int64_t)atoi( val ) * 1000;
371 /* for TS generation */
375 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "csa-ck" ) ) )
378 if( val[0] == '0' && ( val[1] == 'x' || val[1] == 'X' ) )
382 if( strlen( val ) != 16 )
384 msg_Dbg( p_mux, "invalid csa ck (it must be 16 chars long)" );
388 uint64_t i_ck = strtoll( val, NULL, 16 );
391 for( i = 0; i < 8; i++ )
393 ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
396 msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x",
397 ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
399 p_sys->csa = csa_New();
400 csa_SetCW( p_sys->csa, ck, ck );
406 /*****************************************************************************
408 *****************************************************************************/
409 static void Close( vlc_object_t * p_this )
411 sout_mux_t *p_mux = (sout_mux_t*)p_this;
412 sout_mux_sys_t *p_sys = p_mux->p_sys;
414 msg_Dbg( p_mux, "Close" );
417 csa_Delete( p_sys->csa );
423 /*****************************************************************************
425 *****************************************************************************/
426 static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
430 case SOUT_MUX_CAP_GET_ADD_STREAM_ANY_TIME:
431 *(vlc_bool_t*)p_answer = VLC_TRUE;
432 return( SOUT_MUX_CAP_ERR_OK );
434 return( SOUT_MUX_CAP_ERR_UNIMPLEMENTED );
438 /*****************************************************************************
439 * AddStream: called for each stream addition
440 *****************************************************************************/
441 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
443 sout_mux_sys_t *p_sys = p_mux->p_sys;
444 ts_stream_t *p_stream;
446 p_input->p_sys = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
448 /* Init this new stream */
449 p_stream->i_pid = AllocatePID( p_sys, p_input->p_fmt->i_cat );
450 p_stream->i_continuity_counter = 0;
451 p_stream->i_decoder_specific_info = 0;
452 p_stream->p_decoder_specific_info = NULL;
454 msg_Dbg( p_mux, "adding input codec=%4.4s pid=%d", (char*)&p_input->p_fmt->i_codec, p_stream->i_pid );
456 /* All others fields depand on codec */
457 switch( p_input->p_fmt->i_cat )
460 switch( p_input->p_fmt->i_codec )
462 case VLC_FOURCC( 'm', 'p','g', 'v' ):
463 /* TODO: do we need to check MPEG-I/II ? */
464 p_stream->i_stream_type = 0x02;
465 p_stream->i_stream_id = 0xe0;
467 case VLC_FOURCC( 'm', 'p','4', 'v' ):
468 p_stream->i_stream_type = 0x10;
469 p_stream->i_stream_id = 0xfa;
470 p_sys->i_mpeg4_streams++;
471 p_stream->i_es_id = p_stream->i_pid;
473 /* XXX dirty dirty but somebody want that : using crapy MS-codec XXX */
474 /* I didn't want to do that :P */
475 case VLC_FOURCC( 'H', '2', '6', '3' ):
476 case VLC_FOURCC( 'I', '2', '6', '3' ):
477 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
478 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
479 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
480 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
481 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
482 case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
483 p_stream->i_stream_type = 0xa0; // private
484 p_stream->i_stream_id = 0xa0; // beurk
485 p_stream->i_bih_codec = p_input->p_fmt->i_codec;
486 p_stream->i_bih_width = p_input->p_fmt->video.i_width;
487 p_stream->i_bih_height = p_input->p_fmt->video.i_height;
493 p_sys->i_video_bound++;
497 switch( p_input->p_fmt->i_codec )
499 case VLC_FOURCC( 'm', 'p','g', 'a' ):
500 p_stream->i_stream_type = p_input->p_fmt->audio.i_rate >= 32000 ? 0x03 : 0x04;
501 p_stream->i_stream_id = 0xc0;
503 case VLC_FOURCC( 'a', '5','2', ' ' ):
504 p_stream->i_stream_type = 0x81;
505 p_stream->i_stream_id = 0xbd;
507 case VLC_FOURCC( 'l', 'p','c', 'm' ):
508 p_stream->i_stream_type = 0x83;
509 p_stream->i_stream_id = 0xbd;
511 case VLC_FOURCC( 'd', 't','s', ' ' ):
512 p_stream->i_stream_type = 0x85;
513 p_stream->i_stream_id = 0xbd;
516 case VLC_FOURCC( 'm', 'p','4', 'a' ):
517 p_stream->i_stream_type = 0x11;
518 p_stream->i_stream_id = 0xfa;
519 p_sys->i_mpeg4_streams++;
520 p_stream->i_es_id = p_stream->i_pid;
526 p_sys->i_audio_bound++;
530 switch( p_input->p_fmt->i_codec )
532 case VLC_FOURCC( 's', 'p','u', ' ' ):
533 p_stream->i_stream_type = 0x82;
534 p_stream->i_stream_id = 0xbd;
547 /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
548 p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
549 if( p_stream->i_decoder_specific_info > 0 )
551 p_stream->p_decoder_specific_info =
552 malloc( p_stream->i_decoder_specific_info );
553 memcpy( p_stream->p_decoder_specific_info,
554 p_input->p_fmt->p_extra,
555 p_input->p_fmt->i_extra );
559 BufferChainInit( &p_stream->chain_pes );
560 p_stream->i_pes_dts = 0;
561 p_stream->i_pes_length = 0;
562 p_stream->i_pes_used = 0;
564 /* We only change PMT version (PAT isn't changed) */
565 p_sys->i_pmt_version_number = ( p_sys->i_pmt_version_number + 1 )%32;
568 if( p_input->p_fmt->i_cat != SPU_ES &&
569 ( p_sys->i_pcr_pid == 0x1fff || p_input->p_fmt->i_cat == VIDEO_ES ) )
571 if( p_sys->p_pcr_input )
573 /* There was already a PCR stream, so clean context */
576 p_sys->i_pcr_pid = p_stream->i_pid;
577 p_sys->p_pcr_input = p_input;
579 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
585 /*****************************************************************************
586 * DelStream: called before a stream deletion
587 *****************************************************************************/
588 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
590 sout_mux_sys_t *p_sys = p_mux->p_sys;
591 ts_stream_t *p_stream;
594 p_stream = (ts_stream_t*)p_input->p_sys;
595 msg_Dbg( p_mux, "removing input pid=%d", p_stream->i_pid );
597 if( p_sys->i_pcr_pid == p_stream->i_pid )
601 /* Find a new pcr stream (Prefer Video Stream) */
602 p_sys->i_pcr_pid = 0x1fff;
603 p_sys->p_pcr_input = NULL;
604 for( i = 0; i < p_mux->i_nb_inputs; i++ )
606 if( p_mux->pp_inputs[i] == p_input )
611 if( p_mux->pp_inputs[i]->p_fmt->i_cat == VIDEO_ES )
614 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
615 p_sys->p_pcr_input= p_mux->pp_inputs[i];
618 else if( p_mux->pp_inputs[i]->p_fmt->i_cat != SPU_ES &&
619 p_sys->i_pcr_pid == 0x1fff )
622 ((ts_stream_t*)p_mux->pp_inputs[i]->p_sys)->i_pid;
623 p_sys->p_pcr_input= p_mux->pp_inputs[i];
626 if( p_sys->p_pcr_input )
628 /* Empty TS buffer */
631 msg_Dbg( p_mux, "new PCR PID is %d", p_sys->i_pcr_pid );
634 /* Empty all data in chain_pes */
635 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
637 if( p_stream->p_decoder_specific_info )
639 free( p_stream->p_decoder_specific_info );
641 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
643 p_sys->i_mpeg4_streams--;
645 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-video" ) ) )
647 int i_pid_video = strtol( val, NULL, 0 );
648 if ( i_pid_video == p_stream->i_pid )
650 p_sys->i_pid_video = i_pid_video;
651 msg_Dbg( p_mux, "freeing video PID %d", i_pid_video );
654 if( ( val = sout_cfg_find_value( p_mux->p_cfg, "pid-audio" ) ) )
656 int i_pid_audio = strtol( val, NULL, 0 );
657 if ( i_pid_audio == p_stream->i_pid )
659 p_sys->i_pid_audio = i_pid_audio;
660 msg_Dbg( p_mux, "freeing audio PID %d", i_pid_audio );
665 /* We only change PMT version (PAT isn't changed) */
666 p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
671 /*****************************************************************************
672 * Mux: Call each time there is new data for at least one stream
673 *****************************************************************************
675 *****************************************************************************/
676 static int Mux( sout_mux_t *p_mux )
678 sout_mux_sys_t *p_sys = p_mux->p_sys;
679 ts_stream_t *p_pcr_stream;
681 if( p_sys->i_pcr_pid == 0x1fff )
683 msg_Dbg( p_mux, "waiting PCR streams" );
687 p_pcr_stream = (ts_stream_t*)p_sys->p_pcr_input->p_sys;
691 sout_buffer_chain_t chain_ts;
695 mtime_t i_pcr_length;
698 /* 1: get enough PES packet for all input */
701 vlc_bool_t b_ok = VLC_TRUE;
702 sout_buffer_t *p_data;
704 /* Accumulate enough data in the pcr stream (>i_caching_delay) */
705 /* Accumulate enough data in all other stream ( >= length of pcr) */
706 for( i = 0; i < p_mux->i_nb_inputs; i++ )
708 sout_input_t *p_input = p_mux->pp_inputs[i];
709 ts_stream_t *p_stream = (ts_stream_t*)p_input->p_sys;
711 if( ( p_stream == p_pcr_stream && p_stream->i_pes_length <= p_sys->i_caching_delay ) ||
712 p_stream->i_pes_dts + p_stream->i_pes_length < p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
715 if( p_input->p_fifo->i_depth <= 1 )
717 if( p_input->p_fmt->i_cat == AUDIO_ES ||
718 p_input->p_fmt->i_cat == VIDEO_ES )
720 /* We need more data */
723 else if( p_input->p_fifo->i_depth <= 0 )
725 /* spu, only one packet is needed */
731 p_data = sout_FifoGet( p_input->p_fifo );
732 if( p_input->p_fifo->i_depth > 0 )
734 sout_buffer_t *p_next = sout_FifoShow( p_input->p_fifo );
736 p_data->i_length = p_next->i_dts - p_data->i_dts;
739 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 ) ||
740 p_data->i_dts < p_stream->i_pes_dts ||
741 ( p_stream->i_pes_dts > 0 && p_data->i_dts - 2000000 > p_stream->i_pes_dts + p_stream->i_pes_length ) )
743 msg_Warn( p_mux, "packet with too strange dts (dts=%lld,old=%lld,pcr=%lld)",
746 p_pcr_stream->i_pes_dts );
747 sout_BufferDelete( p_mux->p_sout, p_data );
749 BufferChainClean( p_mux->p_sout, &p_stream->chain_pes );
750 p_stream->i_pes_dts = 0;
751 p_stream->i_pes_used = 0;
752 p_stream->i_pes_length = 0;
754 BufferChainClean( p_mux->p_sout, &p_pcr_stream->chain_pes );
755 p_pcr_stream->i_pes_dts = 0;
756 p_pcr_stream->i_pes_used = 0;
757 p_pcr_stream->i_pes_length = 0;
762 p_stream->i_pes_length += p_data->i_length;
763 if( p_stream->i_pes_dts == 0 )
765 p_stream->i_pes_dts = p_data->i_dts;
769 E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1 );
771 BufferChainAppend( &p_stream->chain_pes, p_data );
783 i_pcr_dts = p_pcr_stream->i_pes_dts;
784 i_pcr_length = p_pcr_stream->i_pes_length;
786 /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */
787 /* 2: calculate non accurate total size of muxed ts */
789 for( i = 0; i < p_mux->i_nb_inputs; i++ )
791 ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
792 sout_buffer_t *p_pes;
794 /* False for pcr stream but it will be eough to do PCR algo */
795 for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL; p_pes = p_pes->p_next )
797 int i_size = p_pes->i_size;
798 if( p_pes->i_dts + p_pes->i_length > p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )
800 mtime_t i_frag = p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length - p_pes->i_dts;
806 i_size = p_pes->i_size * i_frag / p_pes->i_length;
808 i_packet_count += ( i_size + 183 ) / 184;
811 /* add overhead for PCR (not really exact) */
812 i_packet_count += ( 8 * i_pcr_length / p_sys->i_pcr_delay + 175 ) / 176;
815 /* 3: mux PES into TS */
816 BufferChainInit( &chain_ts );
817 /* append PAT/PMT -> FIXME with big pcr delay it won't have enough pat/pmt */
818 GetPAT( p_mux, &chain_ts);
819 GetPMT( p_mux, &chain_ts );
821 i_packet_count += chain_ts.i_depth;
822 /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */
828 ts_stream_t *p_stream;
832 /* Select stream (lowest dts)*/
833 for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )
835 p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;
837 if( p_stream->i_pes_dts == 0 )
842 if( i_stream == -1 ||
843 p_stream->i_pes_dts < i_dts )
846 i_dts = p_stream->i_pes_dts;
853 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
855 /* do we need to issue pcr */
857 if( p_stream == p_pcr_stream &&
858 i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >= p_sys->i_pcr + p_sys->i_pcr_delay )
861 p_sys->i_pcr = i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count;
864 /* Build the TS packet */
865 p_ts = TSNew( p_mux, p_stream, b_pcr );
868 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
873 BufferChainAppend( &chain_ts, p_ts );
876 /* 4: date and send */
877 i_packet_count = chain_ts.i_depth;
878 /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
879 for( i = 0; i < i_packet_count; i++ )
881 sout_buffer_t *p_ts = BufferChainGet( &chain_ts );
883 p_ts->i_dts = i_pcr_dts + i_pcr_length * i / i_packet_count;
884 p_ts->i_length = i_pcr_length / i_packet_count;
886 if( p_ts->i_flags&SOUT_BUFFER_FLAGS_PRIVATE_PCR )
888 /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
889 TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
891 if( p_ts->i_flags&SOUT_BUFFER_FLAGS_PRIVATE_CSA )
893 csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
897 p_ts->i_dts += 3*p_sys->i_caching_delay/2;
899 sout_AccessOutWrite( p_mux->p_access, p_ts );
904 static sout_buffer_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, vlc_bool_t b_pcr )
906 sout_buffer_t *p_pes = p_stream->chain_pes.p_first;
909 vlc_bool_t b_new_pes = VLC_FALSE;
910 vlc_bool_t b_adaptation_field = VLC_FALSE;
912 int i_payload_max = 184 - ( b_pcr ? 8 : 0 );
915 if( p_stream->i_pes_used <= 0 )
917 b_new_pes = VLC_TRUE;
919 i_payload = __MIN( (int)p_pes->i_size - p_stream->i_pes_used, i_payload_max );
921 if( b_pcr || i_payload < i_payload_max )
923 b_adaptation_field = VLC_TRUE;
926 p_ts = sout_BufferNew( p_mux->p_sout, 188 );
928 p_ts->p_buffer[0] = 0x47;
929 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|( ( p_stream->i_pid >> 8 )&0x1f );
930 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
931 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|p_stream->i_continuity_counter;
933 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
935 if( b_adaptation_field )
941 int i_stuffing = i_payload_max - i_payload;
943 p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_PCR;
945 p_ts->p_buffer[4] = 7 + i_stuffing;
946 p_ts->p_buffer[5] = 0x10; /* flags */
947 p_ts->p_buffer[6] = ( 0 )&0xff;
948 p_ts->p_buffer[7] = ( 0 )&0xff;
949 p_ts->p_buffer[8] = ( 0 )&0xff;
950 p_ts->p_buffer[9] = ( 0 )&0xff;
951 p_ts->p_buffer[10]= ( 0 )&0x80;
952 p_ts->p_buffer[11]= 0;
954 for( i = 12; i < 12 + i_stuffing; i++ )
956 p_ts->p_buffer[i] = 0xff;
961 int i_stuffing = i_payload_max - i_payload;
963 p_ts->p_buffer[4] = i_stuffing - 1;
966 p_ts->p_buffer[5] = 0x00;
967 for( i = 6; i < 6 + i_stuffing - 2; i++ )
969 p_ts->p_buffer[i] = 0xff;
976 memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload );
978 p_stream->i_pes_used += i_payload;
979 p_stream->i_pes_dts = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_size;
980 p_stream->i_pes_length -= p_pes->i_length * i_payload / p_pes->i_size;
982 if( p_stream->i_pes_used >= (int)p_pes->i_size )
984 p_pes = BufferChainGet( &p_stream->chain_pes );
985 sout_BufferDelete( p_mux->p_sout, p_pes );
987 p_pes = p_stream->chain_pes.p_first;
990 p_stream->i_pes_dts = p_pes->i_dts;
991 p_stream->i_pes_length = 0;
994 p_stream->i_pes_length += p_pes->i_length;
996 p_pes = p_pes->p_next;
1001 p_stream->i_pes_dts = 0;
1002 p_stream->i_pes_length = 0;
1004 p_stream->i_pes_used = 0;
1011 static void TSSetPCR( sout_buffer_t *p_ts, mtime_t i_dts )
1013 mtime_t i_pcr = 9 * i_dts / 100;
1015 p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff;
1016 p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff;
1017 p_ts->p_buffer[8] = ( i_pcr >> 9 )&0xff;
1018 p_ts->p_buffer[9] = ( i_pcr >> 1 )&0xff;
1019 p_ts->p_buffer[10]|= ( i_pcr << 7 )&0x80;
1023 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 )
1025 sout_mux_sys_t *p_sys = p_mux->p_sys;
1026 sout_buffer_chain_t s = *c;
1029 int i_packets_min = 0;
1030 int i_packets_max = 0;
1037 i_packets = c->i_depth;
1038 i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000 + 187 ) / 188;
1039 i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000 + 187 ) / 188;
1041 if( i_packets < i_packets_min && i_packets_min > 0 )
1043 sout_buffer_t *p_pk;
1044 int i_div = ( i_packets_min - i_packets ) / i_packets;
1045 int i_mod = ( i_packets_min - i_packets ) % i_packets;
1048 /* We need to pad with null packets (pid=0x1fff)
1049 * We try to melt null packets with true packets */
1051 "packets=%d but min=%d -> adding %d packets of padding",
1052 i_packets, i_packets_min, i_packets_min - i_packets );
1054 BufferChainInit( c );
1055 while( ( p_pk = BufferChainGet( &s ) ) )
1059 BufferChainAppend( c, p_pk );
1061 i_null = i_div + ( i_rest + i_mod ) / i_packets;
1063 for( i = 0; i < i_null; i++ )
1065 sout_buffer_t *p_null;
1067 p_null = sout_BufferNew( p_mux->p_sout, 188 );
1068 p_null->p_buffer[0] = 0x47;
1069 p_null->p_buffer[1] = 0x1f;
1070 p_null->p_buffer[2] = 0xff;
1071 p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter;
1072 memset( &p_null->p_buffer[4], 0, 184 );
1073 p_sys->i_null_continuity_counter =
1074 ( p_sys->i_null_continuity_counter + 1 ) % 16;
1076 BufferChainAppend( c, p_null );
1079 i_rest = ( i_rest + i_mod ) % i_packets;
1082 else if( i_packets > i_packets_max && i_packets_max > 0 )
1084 sout_buffer_t *p_pk;
1087 /* Arg, we need to drop packets, I don't do something clever (like
1088 * dropping complete pid, b frames, ... ), I just get the right amount
1089 * of packets and discard the others */
1091 "packets=%d but max=%d -> removing %d packets -> stream broken",
1092 i_packets, i_packets_max, i_packets - i_packets_max );
1094 BufferChainInit( c );
1095 for( i = 0; i < i_packets_max; i++ )
1097 BufferChainAppend( c, BufferChainGet( &s ) );
1100 while( ( p_pk = BufferChainGet( &s ) ) )
1102 sout_BufferDelete( p_mux->p_sout, p_pk );
1108 static void PEStoTS( sout_instance_t *p_sout,
1109 sout_buffer_chain_t *c, sout_buffer_t *p_pes,
1110 ts_stream_t *p_stream )
1116 /* get PES total size */
1117 i_size = p_pes->i_size;
1118 p_data = p_pes->p_buffer;
1120 b_new_pes = VLC_TRUE;
1124 int b_adaptation_field;
1126 sout_buffer_t *p_ts;
1128 p_ts = sout_BufferNew( p_sout, 188 );
1131 * 1b transport_error_indicator
1132 * 1b payload_unit_start
1133 * 1b transport_priority
1135 * 2b transport_scrambling_control
1136 * 2b if adaptation_field 0x03 else 0x01
1137 * 4b continuity_counter
1140 i_copy = __MIN( i_size, 184 );
1141 b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE;
1143 p_ts->p_buffer[0] = 0x47;
1144 p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )|
1145 ( ( p_stream->i_pid >> 8 )&0x1f );
1146 p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
1147 p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )|
1148 p_stream->i_continuity_counter;
1150 b_new_pes = VLC_FALSE;
1151 p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
1153 if( b_adaptation_field )
1155 int i_stuffing = 184 - i_copy;
1158 p_ts->p_buffer[4] = i_stuffing - 1;
1159 if( i_stuffing > 1 )
1161 p_ts->p_buffer[5] = 0x00;
1162 for( i = 6; i < 6 + i_stuffing - 2; i++ )
1164 p_ts->p_buffer[i] = 0xff;
1169 memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy );
1173 BufferChainAppend( c, p_ts );
1177 sout_buffer_t *p_next = p_pes->p_next;
1179 p_pes->p_next = NULL;
1180 sout_BufferDelete( p_sout, p_pes );
1181 if( p_next == NULL )
1185 b_new_pes = VLC_TRUE;
1187 i_size = p_pes->i_size;
1188 p_data = p_pes->p_buffer;
1195 #if defined MODULE_NAME_IS_mux_ts
1196 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
1198 static uint32_t CRC32[256] =
1200 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
1201 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
1202 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1203 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1204 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
1205 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1206 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
1207 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
1208 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1209 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
1210 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
1211 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1212 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
1213 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1214 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1215 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
1216 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
1217 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1218 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1219 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
1220 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1221 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
1222 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
1223 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1224 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
1225 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
1226 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1227 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
1228 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1229 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1230 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
1231 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
1232 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1233 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1234 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
1235 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1236 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
1237 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
1238 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1239 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
1240 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
1241 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1242 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
1243 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1244 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1245 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
1246 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
1247 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1248 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1249 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
1250 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1251 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
1252 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
1253 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1254 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
1255 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
1256 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1257 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
1258 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1259 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1260 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
1261 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
1262 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1263 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1266 uint32_t i_crc = 0xffffffff;
1268 /* Calculate the CRC */
1269 while( i_count > 0 )
1271 i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
1279 static void GetPAT( sout_mux_t *p_mux,
1280 sout_buffer_chain_t *c )
1282 sout_mux_sys_t *p_sys = p_mux->p_sys;
1283 sout_buffer_t *p_pat;
1286 p_pat = sout_BufferNew( p_mux->p_sout, 1024 );
1290 p_pat->i_length = 0;
1292 bits_initwrite( &bits, 1024, p_pat->p_buffer );
1294 bits_write( &bits, 8, 0 ); // pointer
1295 bits_write( &bits, 8, 0x00 ); // table id
1296 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1297 bits_write( &bits, 1, 0 ); // 0
1298 bits_write( &bits, 2, 0x03 ); // reserved FIXME
1299 bits_write( &bits, 12, 13 ); // XXX for one program only XXX
1300 bits_write( &bits, 16, 0x01 ); // FIXME stream id
1301 bits_write( &bits, 2, 0x03 ); // FIXME
1302 bits_write( &bits, 5, p_sys->i_pat_version_number );
1303 bits_write( &bits, 1, 1 ); // current_next_indicator
1304 bits_write( &bits, 8, 0 ); // section number
1305 bits_write( &bits, 8, 0 ); // last section number
1307 bits_write( &bits, 16, 1 ); // program number
1308 bits_write( &bits, 3, 0x07 ); // reserved
1309 bits_write( &bits, 13, p_sys->pmt.i_pid ); // program map pid
1311 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1313 p_pat->i_size = bits.i_data;
1315 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1318 static void GetPMT( sout_mux_t *p_mux,
1319 sout_buffer_chain_t *c )
1321 sout_mux_sys_t *p_sys = p_mux->p_sys;
1322 sout_buffer_t *p_pmt;
1326 p_pmt = sout_BufferNew( p_mux->p_sout, 1024 );
1330 p_pmt->i_length = 0;
1332 bits_initwrite( &bits, 1024, p_pmt->p_buffer );
1334 bits_write( &bits, 8, 0 ); // pointer
1335 bits_write( &bits, 8, 0x02 ); // table id
1336 bits_write( &bits, 1, 1 ); // section_syntax_indicator
1337 bits_write( &bits, 1, 0 ); // 0
1338 bits_write( &bits, 2, 0 ); // reserved FIXME
1339 bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
1340 bits_write( &bits, 16, 1 ); // FIXME program number
1341 bits_write( &bits, 2, 0 ); // FIXME
1342 bits_write( &bits, 5, p_sys->i_pmt_version_number );
1343 bits_write( &bits, 1, 1 ); // current_next_indicator
1344 bits_write( &bits, 8, 0 ); // section number
1345 bits_write( &bits, 8, 0 ); // last section number
1347 bits_write( &bits, 3, 0 ); // reserved
1349 bits_write( &bits, 13, p_sys->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
1350 bits_write( &bits, 4, 0 ); // reserved FIXME
1352 bits_write( &bits, 12, 0 ); // program info len FIXME
1354 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1356 ts_stream_t *p_stream;
1358 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1360 bits_write( &bits, 8, p_stream->i_stream_type ); // stream_type
1361 bits_write( &bits, 3, 0 ); // reserved
1362 bits_write( &bits, 13, p_stream->i_pid ); // es pid
1363 bits_write( &bits, 4, 0 ); //reserved
1364 bits_write( &bits, 12, 0 ); // es info len FIXME
1367 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
1369 p_pmt->i_size = bits.i_data;
1371 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1373 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
1375 static sout_buffer_t *WritePSISection( sout_instance_t *p_sout,
1376 dvbpsi_psi_section_t* p_section )
1378 sout_buffer_t *p_psi, *p_first = NULL;
1385 i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+
1386 ( p_section->b_syntax_indicator ? 4 : 0 );
1388 p_psi = sout_BufferNew( p_sout, i_size + 1 );
1391 p_psi->i_length = 0;
1392 p_psi->i_size = i_size + 1;
1394 p_psi->p_buffer[0] = 0; // pointer
1395 memcpy( p_psi->p_buffer + 1,
1399 sout_BufferChain( &p_first, p_psi );
1401 p_section = p_section->p_next;
1407 static void GetPAT( sout_mux_t *p_mux,
1408 sout_buffer_chain_t *c )
1410 sout_mux_sys_t *p_sys = p_mux->p_sys;
1411 sout_buffer_t *p_pat;
1413 dvbpsi_psi_section_t *p_section;
1415 dvbpsi_InitPAT( &pat,
1417 p_sys->i_pat_version_number,
1418 1 ); // b_current_next
1419 /* add all program (only one) */
1420 dvbpsi_PATAddProgram( &pat,
1422 p_sys->pmt.i_pid ); // i_pid
1424 p_section = dvbpsi_GenPATSections( &pat,
1425 0 ); // max program per section
1427 p_pat = WritePSISection( p_mux->p_sout, p_section );
1429 PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat );
1431 dvbpsi_DeletePSISections( p_section );
1432 dvbpsi_EmptyPAT( &pat );
1435 static uint32_t GetDescriptorLength24b( int i_length )
1437 uint32_t i_l1, i_l2, i_l3;
1439 i_l1 = i_length&0x7f;
1440 i_l2 = ( i_length >> 7 )&0x7f;
1441 i_l3 = ( i_length >> 14 )&0x7f;
1443 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
1446 static void GetPMT( sout_mux_t *p_mux,
1447 sout_buffer_chain_t *c )
1449 sout_mux_sys_t *p_sys = p_mux->p_sys;
1450 sout_buffer_t *p_pmt;
1453 dvbpsi_pmt_es_t *p_es;
1454 dvbpsi_psi_section_t *p_section;
1458 dvbpsi_InitPMT( &pmt,
1459 0x01, // program number
1460 p_sys->i_pmt_version_number,
1461 1, // b_current_next
1464 if( p_sys->i_mpeg4_streams > 0 )
1468 bits_buffer_t bits_fix_IOD;
1470 /* Make valgrind happy : it works at byte level not bit one so
1471 * bit_write confuse it (but DON'T CHANGE the way that bit_write is
1472 * working (needed when fixing some bits) */
1473 memset( iod, 0, 4096 );
1475 bits_initwrite( &bits, 4096, iod );
1477 bits_write( &bits, 8, 0x01 );
1478 // InitialObjectDescriptor
1479 bits_align( &bits );
1480 bits_write( &bits, 8, 0x02 ); // tag
1481 bits_fix_IOD = bits; // save states to fix length later
1482 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
1483 bits_write( &bits, 10, 0x01 ); // ObjectDescriptorID
1484 bits_write( &bits, 1, 0x00 ); // URL Flag
1485 bits_write( &bits, 1, 0x00 ); // includeInlineProfileLevelFlag
1486 bits_write( &bits, 4, 0x0f ); // reserved
1487 bits_write( &bits, 8, 0xff ); // ODProfile (no ODcapability )
1488 bits_write( &bits, 8, 0xff ); // sceneProfile
1489 bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified)
1490 bits_write( &bits, 8, 0xfe ); // visualProfile( // )
1491 bits_write( &bits, 8, 0xff ); // graphicProfile (no )
1492 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1494 ts_stream_t *p_stream;
1495 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1497 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1499 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
1501 bits_align( &bits );
1502 bits_write( &bits, 8, 0x03 ); // ES_DescrTag
1503 bits_fix_ESDescr = bits;
1504 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable size
1505 bits_write( &bits, 16, p_stream->i_es_id );
1506 bits_write( &bits, 1, 0x00 ); // streamDependency
1507 bits_write( &bits, 1, 0x00 ); // URL Flag
1508 bits_write( &bits, 1, 0x00 ); // OCRStreamFlag
1509 bits_write( &bits, 5, 0x1f ); // streamPriority
1511 // DecoderConfigDesciptor
1512 bits_align( &bits );
1513 bits_write( &bits, 8, 0x04 ); // DecoderConfigDescrTag
1514 bits_fix_Decoder = bits;
1515 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) );
1516 if( p_stream->i_stream_type == 0x10 )
1518 bits_write( &bits, 8, 0x20 ); // Visual 14496-2
1519 bits_write( &bits, 6, 0x04 ); // VisualStream
1521 else if( p_stream->i_stream_type == 0x11 )
1523 bits_write( &bits, 8, 0x40 ); // Audio 14496-3
1524 bits_write( &bits, 6, 0x05 ); // AudioStream
1528 bits_write( &bits, 8, 0x00 );
1529 bits_write( &bits, 6, 0x00 );
1531 msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
1533 bits_write( &bits, 1, 0x00 ); // UpStream
1534 bits_write( &bits, 1, 0x01 ); // reserved
1535 bits_write( &bits, 24, 1024 * 1024 ); // bufferSizeDB
1536 bits_write( &bits, 32, 0x7fffffff ); // maxBitrate
1537 bits_write( &bits, 32, 0 ); // avgBitrate
1539 if( p_stream->i_decoder_specific_info > 0 )
1542 // DecoderSpecificInfo
1543 bits_align( &bits );
1544 bits_write( &bits, 8, 0x05 ); // tag
1545 bits_write( &bits, 24,
1546 GetDescriptorLength24b( p_stream->i_decoder_specific_info ) );
1547 for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
1549 bits_write( &bits, 8, ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
1552 /* fix Decoder length */
1553 bits_write( &bits_fix_Decoder, 24,
1554 GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
1556 /* SLConfigDescriptor : predifined (0x01) */
1557 bits_align( &bits );
1558 bits_write( &bits, 8, 0x06 ); // tag
1559 bits_write( &bits, 24, GetDescriptorLength24b( 8 ) );
1560 bits_write( &bits, 8, 0x01 ); // predefined
1561 bits_write( &bits, 1, 0 ); // durationFlag
1562 bits_write( &bits, 32, 0 ); // OCRResolution
1563 bits_write( &bits, 8, 0 ); // OCRLength
1564 bits_write( &bits, 8, 0 ); // InstantBitrateLength
1565 bits_align( &bits );
1567 /* fix ESDescr length */
1568 bits_write( &bits_fix_ESDescr, 24,
1569 GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1572 bits_align( &bits );
1573 /* fix IOD length */
1574 bits_write( &bits_fix_IOD, 24,
1575 GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1576 dvbpsi_PMTAddDescriptor( &pmt,
1582 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1584 ts_stream_t *p_stream;
1586 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1588 p_es = dvbpsi_PMTAddES( &pmt,
1589 p_stream->i_stream_type,
1591 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1596 es_id[0] = (p_stream->i_es_id >> 8)&0xff;
1597 es_id[1] = (p_stream->i_es_id)&0xff;
1598 dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
1600 else if( p_stream->i_stream_type == 0xa0 )
1603 int i_extra = __MIN( p_stream->i_decoder_specific_info,
1606 /* private DIV3 descripor */
1607 memcpy( &data[0], &p_stream->i_bih_codec, 4 );
1608 data[4] = ( p_stream->i_bih_width >> 8 )&0xff;
1609 data[5] = ( p_stream->i_bih_width )&0xff;
1610 data[6] = ( p_stream->i_bih_height>> 8 )&0xff;
1611 data[7] = ( p_stream->i_bih_height )&0xff;
1612 data[8] = ( i_extra >> 8 )&0xff;
1613 data[9] = ( i_extra )&0xff;
1616 memcpy( &data[10], p_stream->p_decoder_specific_info, i_extra );
1619 /* 0xa0 is private */
1620 dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
1622 else if( p_stream->i_stream_type == 0x81 )
1624 uint8_t format[4] = { 0x41, 0x43, 0x2d, 0x33 };
1626 /* "registration" descriptor : "AC-3" */
1627 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
1631 p_section = dvbpsi_GenPMTSections( &pmt );
1633 p_pmt = WritePSISection( p_mux->p_sout, p_section );
1635 PEStoTS( p_mux->p_sout, c, p_pmt, &p_sys->pmt );
1637 dvbpsi_DeletePSISections( p_section );
1638 dvbpsi_EmptyPMT( &pmt );