1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: ts.c,v 1.15 2003/03/11 19:02:30 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 *****************************************************************************/
30 #include <sys/types.h>
37 #include <vlc/input.h>
48 #if defined MODULE_NAME_IS_mux_ts_dvbpsi
49 # ifdef HAVE_DVBPSI_DR_H
50 # include <dvbpsi/dvbpsi.h>
51 # include <dvbpsi/descriptor.h>
52 # include <dvbpsi/pat.h>
53 # include <dvbpsi/pmt.h>
54 # include <dvbpsi/dr.h>
55 # include <dvbpsi/psi.h>
58 # include "descriptor.h"
59 # include "tables/pat.h"
60 # include "tables/pmt.h"
61 # include "descriptors/dr.h"
66 typedef struct ts_stream_s
71 int i_continuity_counter;
73 /* to be used for carriege of DIV3 */
74 vlc_fourcc_t i_bih_codec;
75 int i_bih_width, i_bih_height;
77 /* Specific to mpeg4 in mpeg2ts */
81 int i_decoder_specific_info_len;
82 uint8_t *p_decoder_specific_info;
95 int i_pid_free; // first usable pid
97 int i_pat_version_number;
100 int i_pmt_version_number;
101 ts_stream_t pmt; // Up to now only one program
103 int i_ts_packet;// To known when to put pat/mpt
110 /*****************************************************************************
111 * Exported prototypes
112 *****************************************************************************/
113 static int Open ( vlc_object_t * );
114 static void Close ( vlc_object_t * );
117 static int Capability(sout_mux_t *, int, void *, void * );
118 static int AddStream( sout_mux_t *, sout_input_t * );
119 static int DelStream( sout_mux_t *, sout_input_t * );
120 static int Mux ( sout_mux_t * );
124 /* Reserve a pid and return it */
125 static int AllocatePID( sout_mux_sys_t *p_sys )
127 return( ++p_sys->i_pid_free );
130 static int GetPAT( sout_mux_t *p_mux, sout_buffer_t **pp_ts );
131 static int GetPMT( sout_mux_t *p_mux, sout_buffer_t **pp_ts );
133 /*****************************************************************************
135 *****************************************************************************/
137 #if defined MODULE_NAME_IS_mux_ts
138 set_description( _("TS muxer") );
139 set_capability( "sout mux", 100 );
140 add_shortcut( "ts" );
141 add_shortcut( "ts_nodvbpsi" );
142 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
143 set_description( _("TS muxer (libdvbpsi)") );
144 set_capability( "sout mux", 120 );
145 add_shortcut( "ts" );
146 add_shortcut( "ts_dvbpsi" );
148 set_callbacks( Open, Close );
151 /*****************************************************************************
153 *****************************************************************************/
154 static int Open( vlc_object_t *p_this )
156 sout_mux_t *p_mux =(sout_mux_t*)p_this;
157 sout_mux_sys_t *p_sys;
159 msg_Info( p_mux, "Open" );
161 p_sys = malloc( sizeof( sout_mux_sys_t ) );
163 p_mux->pf_capacity = Capability;
164 p_mux->pf_addstream = AddStream;
165 p_mux->pf_delstream = DelStream;
167 p_mux->p_sys = p_sys;
168 p_mux->i_preheader = 30; // really enough for a pes header
170 srand( (uint32_t)mdate() );
172 p_sys->i_stream_id_mpga = 0xc0;
173 p_sys->i_stream_id_a52 = 0x80;
174 p_sys->i_stream_id_mpgv = 0xe0;
176 p_sys->i_audio_bound = 0;
177 p_sys->i_video_bound = 0;
179 p_sys->i_pat_version_number = rand() % 32;
180 p_sys->pat.i_pid = 0;
181 p_sys->pat.i_continuity_counter = 0;
183 p_sys->i_pmt_version_number = rand() % 32;
184 p_sys->pmt.i_pid = 0x10;
185 p_sys->pmt.i_continuity_counter = 0;
187 p_sys->i_pid_free = 0x11;
188 p_sys->i_pcr_pid = 0x1fff;
190 p_sys->i_mpeg4_streams = 0;
195 /*****************************************************************************
197 *****************************************************************************/
199 static void Close( vlc_object_t * p_this )
201 sout_mux_t *p_mux = (sout_mux_t*)p_this;
202 sout_mux_sys_t *p_sys = p_mux->p_sys;
204 msg_Info( p_mux, "Close" );
210 static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
214 case SOUT_MUX_CAP_GET_ADD_STREAM_ANY_TIME:
215 *(vlc_bool_t*)p_answer = VLC_TRUE;
216 return( SOUT_MUX_CAP_ERR_OK );
218 return( SOUT_MUX_CAP_ERR_UNIMPLEMENTED );
222 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
224 sout_mux_sys_t *p_sys = p_mux->p_sys;
225 ts_stream_t *p_stream;
226 BITMAPINFOHEADER *p_bih;
229 msg_Dbg( p_mux, "adding input" );
230 p_input->p_sys = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
232 p_stream->i_pid = AllocatePID( p_sys );
233 if( p_sys->i_pcr_pid == 0x1fff )
235 p_sys->i_pcr_pid = p_stream->i_pid;
237 p_stream->i_continuity_counter = 0;
239 switch( p_input->input_format.i_cat )
242 switch( p_input->input_format.i_fourcc )
244 case VLC_FOURCC( 'm', 'p','g', 'v' ):
245 p_stream->i_stream_type = 0x02;
246 p_stream->i_stream_id = p_sys->i_stream_id_mpgv;
247 p_sys->i_stream_id_mpgv++;
249 case VLC_FOURCC( 'm', 'p','4', 'v' ):
250 p_stream->i_stream_type = 0x10;
251 p_stream->i_stream_id = 0xfa;
252 p_sys->i_mpeg4_streams++;
253 p_stream->i_es_id = p_stream->i_pid;
254 p_stream->i_sl_predefined = 0x01; // NULL SL header
256 /* XXX dirty dirty but somebody want that : using crapy MS-codec XXX */
257 /* I didn't want to do that :P */
258 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
259 case VLC_FOURCC( 'H', '2', '6', '3' ):
260 case VLC_FOURCC( 'I', '2', '6', '3' ):
261 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
262 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
263 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
264 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
265 p_stream->i_stream_type = 0xa0; // private
266 p_stream->i_stream_id = 0xa0; // beurk
271 p_sys->i_video_bound++;
272 p_bih = (BITMAPINFOHEADER*)p_input->input_format.p_format;
275 p_stream->i_bih_codec = p_input->input_format.i_fourcc;
276 p_stream->i_bih_width = p_bih->biWidth;
277 p_stream->i_bih_height = p_bih->biHeight;
281 p_stream->i_bih_codec = 0x0;
282 p_stream->i_bih_width = 0;
283 p_stream->i_bih_height = 0;
286 if( p_bih && p_bih->biSize > sizeof( BITMAPINFOHEADER ) )
288 p_stream->i_decoder_specific_info_len =
289 p_bih->biSize - sizeof( BITMAPINFOHEADER );
290 p_stream->p_decoder_specific_info =
291 malloc( p_stream->i_decoder_specific_info_len );
292 memcpy( p_stream->p_decoder_specific_info,
294 p_stream->i_decoder_specific_info_len );
298 p_stream->p_decoder_specific_info = NULL;
299 p_stream->i_decoder_specific_info_len = 0;
303 switch( p_input->input_format.i_fourcc )
305 case VLC_FOURCC( 'a', '5','2', ' ' ):
306 case VLC_FOURCC( 'a', '5','2', 'b' ):
307 p_stream->i_stream_type = 0x81;
308 p_stream->i_stream_id = p_sys->i_stream_id_a52;
309 p_sys->i_stream_id_a52++;
311 case VLC_FOURCC( 'm', 'p','4', 'a' ):
312 p_stream->i_stream_type = 0x11;
313 p_stream->i_stream_id = 0xfa;
314 p_sys->i_mpeg4_streams++;
315 p_stream->i_es_id = p_stream->i_pid;
316 p_stream->i_sl_predefined = 0x01; // NULL SL header
318 case VLC_FOURCC( 'm', 'p','g', 'a' ):
319 p_stream->i_stream_type = 0x04;
320 p_stream->i_stream_id = p_sys->i_stream_id_mpga;
321 p_sys->i_stream_id_mpga++;
326 p_sys->i_audio_bound++;
327 p_wf = (WAVEFORMATEX*)p_input->input_format.p_format;
328 if( p_wf && p_wf->cbSize > 0 )
330 p_stream->i_decoder_specific_info_len = p_wf->cbSize;
331 p_stream->p_decoder_specific_info =
332 malloc( p_stream->i_decoder_specific_info_len );
333 memcpy( p_stream->p_decoder_specific_info,
335 p_stream->i_decoder_specific_info_len );
339 p_stream->p_decoder_specific_info = NULL;
340 p_stream->i_decoder_specific_info_len = 0;
347 p_sys->i_ts_packet = 0; // force pat/pmt recreation
348 p_sys->i_pat_version_number++; p_sys->i_pat_version_number %= 32;
349 p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
354 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
356 sout_mux_sys_t *p_sys = p_mux->p_sys;
357 ts_stream_t *p_stream;
359 msg_Dbg( p_mux, "removing input" );
360 p_stream = (ts_stream_t*)p_input->p_sys;
362 if( p_stream->p_decoder_specific_info )
364 free( p_stream->p_decoder_specific_info );
366 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
368 p_sys->i_mpeg4_streams--;
370 p_sys->i_ts_packet = 0; // force pat/pmt recreation
371 p_sys->i_pat_version_number++; p_sys->i_pat_version_number %= 32;
372 p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
379 static int MuxGetStream( sout_mux_t *p_mux,
387 for( i = 0, i_dts = 0, i_stream = -1; i < p_mux->i_nb_inputs; i++ )
391 p_fifo = p_mux->pp_inputs[i]->p_fifo;
393 if( p_fifo->i_depth > 1 )
395 sout_buffer_t *p_buf;
397 p_buf = sout_FifoShow( p_fifo );
398 if( i_stream < 0 || p_buf->i_dts < i_dts )
400 i_dts = p_buf->i_dts;
406 return( -1 ); // wait that all fifo have at least 2 packets
412 *pi_stream = i_stream;
422 static int PEStoTS( sout_instance_t *p_sout,
423 sout_buffer_t **pp_ts, sout_buffer_t *p_pes,
424 ts_stream_t *p_stream )
434 /* get PES total size */
435 i_size = p_pes->i_size;
436 p_data = p_pes->p_buffer;
438 if( p_pes->i_dts == 0 && p_pes->i_length > 0 )
440 i_dts = 1; // XXX <french> kludge immonde </french>
444 i_dts = p_pes->i_dts;
447 for( i_first = 1, b_new_pes = 1; p_pes != NULL; )
449 int i_adaptation_field;
455 p_ts = sout_BufferNew( p_sout, 188 );
461 i_payload = 184 - ( i_first && i_dts > 0 ? 8 : 0 );
462 i_copy = __MIN( i_size, i_payload );
464 i_adaptation_field = ( ( i_first && i_dts > 0 ) ||
465 i_size < i_payload ) ? 1 : 0;
468 bits_initwrite( &bits, 188, p_ts->p_buffer );
469 bits_write( &bits, 8, 0x47 ); /* sync byte */
470 bits_write( &bits, 1, 0 ); /* transport_error_indicator */
471 bits_write( &bits, 1, b_new_pes ? 1 : 0 ); /* payload_unit_start */
473 bits_write( &bits, 1, 0 ); /* transport_priority */
474 bits_write( &bits, 13, p_stream->i_pid );
475 bits_write( &bits, 2, 0 ); /* transport_scrambling_control */
476 bits_write( &bits, 2, ( i_adaptation_field ? 0x03 : 0x01 ) );
478 bits_write( &bits, 4, /* continuity_counter */
479 p_stream->i_continuity_counter );
480 p_stream->i_continuity_counter++;
481 p_stream->i_continuity_counter %= 16;
482 if( i_adaptation_field )
487 if( i_first && i_dts > 0 )
489 i_stuffing = i_payload - i_copy;
490 bits_write( &bits, 8, 7 + i_stuffing );
491 bits_write( &bits, 8, 0x10 ); /* various flags */
492 bits_write( &bits, 33, i_dts * 9 / 100);
493 bits_write( &bits, 6, 0 );
494 bits_write( &bits, 9, 0 );
495 i_dts = 0; /* XXX set dts only for first ts packet */
499 i_stuffing = i_payload - i_copy;
500 bits_write( &bits, 8, i_stuffing - 1);
501 if( i_stuffing - 1 > 0 )
503 bits_write( &bits, 8, 0 );
509 for( i = 0; i < i_stuffing; i++ )
511 bits_write( &bits, 8, 0xff );
515 memcpy( p_ts->p_buffer + bits.i_data,
521 sout_BufferChain( pp_ts, p_ts );
527 sout_buffer_t *p_next;
529 p_next = p_pes->p_next;
530 p_pes->p_next = NULL;
531 sout_BufferDelete( p_sout, p_pes );
536 i_size = p_pes->i_size;
537 p_data = p_pes->p_buffer;
549 static void SetTSDate( sout_buffer_t *p_ts, mtime_t i_dts, mtime_t i_length )
552 sout_buffer_t *p_tmp;
555 for( p_tmp = p_ts, i_count = 0; p_tmp != NULL; p_tmp = p_tmp->p_next )
559 i_delta = i_length / i_count;
561 for( p_tmp = p_ts; p_tmp != NULL; p_tmp = p_tmp->p_next )
563 p_tmp->i_dts = i_dts;
564 p_tmp->i_length = i_delta;
570 static int Mux( sout_mux_t *p_mux )
572 sout_mux_sys_t *p_sys = p_mux->p_sys;
575 sout_buffer_t *p_pat, *p_pmt, *p_ts;
579 mtime_t i_dts, i_length;
581 sout_input_t *p_input;
582 ts_stream_t *p_stream;
584 sout_buffer_t *p_data;
586 if( MuxGetStream( p_mux, &i_stream, &i_dts ) < 0 )
591 p_input = p_mux->pp_inputs[i_stream];
592 p_fifo = p_input->p_fifo;
593 p_stream = (ts_stream_t*)p_input->p_sys;
595 p_data = sout_FifoGet( p_fifo );
596 i_dts = p_data->i_dts;
597 i_length = p_data->i_length;
599 E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1);
600 PEStoTS( p_mux->p_sout, &p_data, p_data, p_stream );
602 if( p_sys->i_ts_packet % 30 == 0 )
605 GetPAT( p_mux, &p_pat );
606 GetPMT( p_mux, &p_pmt );
609 sout_BufferChain( &p_ts, p_pmt );
610 sout_BufferChain( &p_ts, p_data );
617 p_sys->i_ts_packet++;
618 SetTSDate( p_ts, i_dts, i_length );
620 sout_AccessOutWrite( p_mux->p_access, p_ts );
627 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
629 static uint32_t CRC32[256] =
631 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
632 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
633 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
634 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
635 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
636 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
637 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
638 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
639 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
640 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
641 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
642 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
643 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
644 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
645 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
646 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
647 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
648 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
649 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
650 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
651 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
652 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
653 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
654 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
655 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
656 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
657 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
658 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
659 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
660 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
661 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
662 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
663 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
664 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
665 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
666 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
667 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
668 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
669 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
670 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
671 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
672 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
673 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
674 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
675 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
676 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
677 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
678 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
679 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
680 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
681 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
682 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
683 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
684 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
685 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
686 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
687 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
688 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
689 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
690 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
691 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
692 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
693 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
694 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
697 uint32_t i_crc = 0xffffffff;
699 /* Calculate the CRC */
702 i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
710 #if defined MODULE_NAME_IS_mux_ts
711 static int GetPAT( sout_mux_t *p_mux,
712 sout_buffer_t **pp_ts )
714 sout_mux_sys_t *p_sys = p_mux->p_sys;
715 sout_buffer_t *p_pat;
718 p_pat = sout_BufferNew( p_mux->p_sout, 1024 );
724 bits_initwrite( &bits, 1024, p_pat->p_buffer );
726 bits_write( &bits, 8, 0 ); // pointer
727 bits_write( &bits, 8, 0x00 ); // table id
728 bits_write( &bits, 1, 1 ); // section_syntax_indicator
729 bits_write( &bits, 1, 0 ); // 0
730 bits_write( &bits, 2, 0x03 ); // reserved FIXME
731 bits_write( &bits, 12, 13 ); // XXX for one program only XXX
732 bits_write( &bits, 16, 0x01 ); // FIXME stream id
733 bits_write( &bits, 2, 0x03 ); // FIXME
734 bits_write( &bits, 5, p_sys->i_pat_version_number );
735 bits_write( &bits, 1, 1 ); // current_next_indicator
736 bits_write( &bits, 8, 0 ); // section number
737 bits_write( &bits, 8, 0 ); // last section number
739 bits_write( &bits, 16, 1 ); // program number
740 bits_write( &bits, 3, 0x07 ); // reserved
741 bits_write( &bits, 13, p_sys->pmt.i_pid ); // program map pid
743 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
745 p_pat->i_size = bits.i_data;
747 return( PEStoTS( p_mux->p_sout, pp_ts, p_pat, &p_sys->pat ) );
750 static int GetPMT( sout_mux_t *p_mux,
751 sout_buffer_t **pp_ts )
753 sout_mux_sys_t *p_sys = p_mux->p_sys;
754 sout_buffer_t *p_pmt;
758 p_pmt = sout_BufferNew( p_mux->p_sout, 1024 );
764 bits_initwrite( &bits, 1024, p_pmt->p_buffer );
766 bits_write( &bits, 8, 0 ); // pointer
767 bits_write( &bits, 8, 0x02 ); // table id
768 bits_write( &bits, 1, 1 ); // section_syntax_indicator
769 bits_write( &bits, 1, 0 ); // 0
770 bits_write( &bits, 2, 0 ); // reserved FIXME
771 bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
772 bits_write( &bits, 16, 1 ); // FIXME program number
773 bits_write( &bits, 2, 0 ); // FIXME
774 bits_write( &bits, 5, p_sys->i_pmt_version_number );
775 bits_write( &bits, 1, 0 ); // current_next_indicator
776 bits_write( &bits, 8, 0 ); // section number
777 bits_write( &bits, 8, 0 ); // last section number
779 bits_write( &bits, 3, 0 ); // reserved
781 bits_write( &bits, 13, p_sys->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
782 bits_write( &bits, 4, 0 ); // reserved FIXME
784 bits_write( &bits, 12, 0 ); // program info len FIXME
786 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
788 ts_stream_t *p_stream;
790 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
792 bits_write( &bits, 8, p_stream->i_stream_type ); // stream_type
793 bits_write( &bits, 3, 0 ); // reserved
794 bits_write( &bits, 13, p_stream->i_pid ); // es pid
795 bits_write( &bits, 4, 0 ); //reserved
796 bits_write( &bits, 12, 0 ); // es info len FIXME
799 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
801 p_pmt->i_size = bits.i_data;
803 return( PEStoTS( p_mux->p_sout, pp_ts, p_pmt, &p_sys->pmt ) );
806 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
808 static sout_buffer_t *WritePSISection( sout_instance_t *p_sout,
809 dvbpsi_psi_section_t* p_section )
811 sout_buffer_t *p_psi, *p_first = NULL;
818 i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+
819 ( p_section->b_syntax_indicator ? 4 : 0 );
821 p_psi = sout_BufferNew( p_sout, i_size + 1 );
825 p_psi->i_size = i_size + 1;
827 p_psi->p_buffer[0] = 0; // pointer
828 memcpy( p_psi->p_buffer + 1,
832 sout_BufferChain( &p_first, p_psi );
834 p_section = p_section->p_next;
840 static int GetPAT( sout_mux_t *p_mux,
841 sout_buffer_t **pp_ts )
843 sout_mux_sys_t *p_sys = p_mux->p_sys;
844 sout_buffer_t *p_pat;
846 dvbpsi_psi_section_t *p_section;
848 dvbpsi_InitPAT( &pat,
850 p_sys->i_pat_version_number,
851 0); // b_current_next
852 /* add all program (only one) */
853 dvbpsi_PATAddProgram( &pat,
855 p_sys->pmt.i_pid ); // i_pid
857 p_section = dvbpsi_GenPATSections( &pat,
858 0 ); // max program per section
860 p_pat = WritePSISection( p_mux->p_sout, p_section );
862 PEStoTS( p_mux->p_sout, pp_ts, p_pat, &p_sys->pat );
864 dvbpsi_DeletePSISections( p_section );
865 dvbpsi_EmptyPAT( &pat );
869 static uint32_t GetDescriptorLength24b( int i_length )
871 uint32_t i_l1, i_l2, i_l3;
873 i_l1 = i_length&0x7f;
874 i_l2 = ( i_length >> 7 )&0x7f;
875 i_l3 = ( i_length >> 14 )&0x7f;
877 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
880 static int GetPMT( sout_mux_t *p_mux,
881 sout_buffer_t **pp_ts )
883 sout_mux_sys_t *p_sys = p_mux->p_sys;
884 sout_buffer_t *p_pmt;
887 dvbpsi_pmt_es_t *p_es;
888 dvbpsi_psi_section_t *p_section;
892 dvbpsi_InitPMT( &pmt,
893 0x01, // program number
894 p_sys->i_pmt_version_number,
898 if( p_sys->i_mpeg4_streams > 0 )
902 bits_buffer_t bits_fix_IOD;
904 bits_initwrite( &bits, 4096, iod );
906 bits_write( &bits, 8, 0x01 );
907 // InitialObjectDescriptor
909 bits_write( &bits, 8, 0x02 ); // tag
910 bits_fix_IOD = bits; // save states to fix length later
911 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
912 bits_write( &bits, 10, 0x01 ); // ObjectDescriptorID
913 bits_write( &bits, 1, 0x00 ); // URL Flag
914 bits_write( &bits, 1, 0x00 ); // includeInlineProfileLevelFlag
915 bits_write( &bits, 4, 0x0f ); // reserved
916 bits_write( &bits, 8, 0xff ); // ODProfile (no ODcapability )
917 bits_write( &bits, 8, 0xff ); // sceneProfile
918 bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified)
919 bits_write( &bits, 8, 0xfe ); // visualProfile( // )
920 bits_write( &bits, 8, 0xff ); // graphicProfile (no )
921 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
923 ts_stream_t *p_stream;
924 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
926 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
928 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
931 bits_write( &bits, 8, 0x03 ); // ES_DescrTag
932 bits_fix_ESDescr = bits;
933 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable size
934 bits_write( &bits, 16, p_stream->i_es_id );
935 bits_write( &bits, 1, 0x00 ); // streamDependency
936 bits_write( &bits, 1, 0x00 ); // URL Flag
937 bits_write( &bits, 1, 0x00 ); // OCRStreamFlag
938 bits_write( &bits, 5, 0x1f ); // streamPriority
940 // DecoderConfigDesciptor
942 bits_write( &bits, 8, 0x04 ); // DecoderConfigDescrTag
943 bits_fix_Decoder = bits;
944 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) );
945 if( p_stream->i_stream_type == 0x10 )
947 bits_write( &bits, 8, 0x20 ); // Visual 14496-2
948 bits_write( &bits, 6, 0x04 ); // VisualStream
950 else if( p_stream->i_stream_type == 0x11 )
952 bits_write( &bits, 8, 0x40 ); // Audio 14496-3
953 bits_write( &bits, 6, 0x05 ); // AudioStream
957 bits_write( &bits, 8, 0x00 );
958 bits_write( &bits, 6, 0x00 );
960 msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
962 bits_write( &bits, 1, 0x00 ); // UpStream
963 bits_write( &bits, 1, 0x01 ); // reserved
964 bits_write( &bits, 24, 1024 * 1024 ); // bufferSizeDB
965 bits_write( &bits, 32, 0x7fffffff ); // maxBitrate
966 bits_write( &bits, 32, 0 ); // avgBitrate
968 if( p_stream->i_decoder_specific_info_len > 0 )
971 // DecoderSpecificInfo
973 bits_write( &bits, 8, 0x05 ); // tag
974 bits_write( &bits, 24,
975 GetDescriptorLength24b( p_stream->i_decoder_specific_info_len ) );
976 for( i = 0; i < p_stream->i_decoder_specific_info_len; i++ )
978 bits_write( &bits, 8, ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
981 /* fix Decoder length */
982 bits_write( &bits_fix_Decoder, 24,
983 GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
985 // SLConfigDescriptor
986 switch( p_stream->i_sl_predefined )
991 bits_write( &bits, 8, 0x06 ); // tag
992 bits_write( &bits, 24, GetDescriptorLength24b( 8 ) );
993 bits_write( &bits, 8, 0x01 ); // predefined
994 bits_write( &bits, 1, 0 ); // durationFlag
995 bits_write( &bits, 32, 0 ); // OCRResolution
996 bits_write( &bits, 8, 0 ); // OCRLength
997 bits_write( &bits, 8, 0 ); // InstantBitrateLength
1001 msg_Err( p_mux,"Unsupported SL profile => broken IOD");
1004 /* fix ESDescr length */
1005 bits_write( &bits_fix_ESDescr, 24,
1006 GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
1009 bits_align( &bits );
1010 /* fix IOD length */
1011 bits_write( &bits_fix_IOD, 24,
1012 GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1013 dvbpsi_PMTAddDescriptor( &pmt,
1019 for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
1021 ts_stream_t *p_stream;
1023 p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
1025 p_es = dvbpsi_PMTAddES( &pmt,
1026 p_stream->i_stream_type,
1028 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1034 bits_initwrite( &bits, 512, data );
1035 bits_write( &bits, 16, p_stream->i_es_id );
1037 dvbpsi_PMTESAddDescriptor( p_es,
1042 else if( p_stream->i_stream_id == 0xa0 )
1047 /* private DIV3 descripor */
1048 bits_initwrite( &bits, 512, data );
1049 bits_write( &bits, 32, p_stream->i_bih_codec );
1050 bits_write( &bits, 16, p_stream->i_bih_width );
1051 bits_write( &bits, 16, p_stream->i_bih_height );
1052 bits_write( &bits, 16, p_stream->i_decoder_specific_info_len );
1053 if( p_stream->i_decoder_specific_info_len > 0 )
1056 for( i = 0; i < p_stream->i_decoder_specific_info_len; i++ )
1058 bits_write( &bits, 8, p_stream->p_decoder_specific_info[i] );
1061 dvbpsi_PMTESAddDescriptor( p_es,
1068 p_section = dvbpsi_GenPMTSections( &pmt );
1070 p_pmt = WritePSISection( p_mux->p_sout, p_section );
1072 PEStoTS( p_mux->p_sout, pp_ts, p_pmt, &p_sys->pmt );
1074 dvbpsi_DeletePSISections( p_section );
1075 dvbpsi_EmptyPMT( &pmt );