1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: ts.c,v 1.10 2003/02/24 10:45:55 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>
42 #elif defined( _MSC_VER ) && defined( _WIN32 ) && !defined( UNDER_CE )
50 #if defined MODULE_NAME_IS_mux_ts_dvbpsi
51 # ifdef HAVE_DVBPSI_DR_H
52 # include <dvbpsi/dvbpsi.h>
53 # include <dvbpsi/descriptor.h>
54 # include <dvbpsi/pat.h>
55 # include <dvbpsi/pmt.h>
56 # include <dvbpsi/dr.h>
57 # include <dvbpsi/psi.h>
60 # include "descriptor.h"
61 # include "tables/pat.h"
62 # include "tables/pmt.h"
63 # include "descriptors/dr.h"
68 typedef struct ts_stream_s
73 int i_continuity_counter;
75 /* to be used for carriege of DIV3 */
76 vlc_fourcc_t i_bih_codec;
77 int i_bih_width, i_bih_height;
79 /* Specific to mpeg4 in mpeg2ts */
83 int i_decoder_specific_info_len;
84 uint8_t *p_decoder_specific_info;
87 typedef struct sout_mux_s
97 int i_pid_free; // first usable pid
99 int i_pat_version_number;
102 int i_pmt_version_number;
103 ts_stream_t pmt; // Up to now only one program
105 int i_ts_packet;// To known when to put pat/mpt
112 /*****************************************************************************
113 * Exported prototypes
114 *****************************************************************************/
115 static int Open ( vlc_object_t * );
116 static void Close ( vlc_object_t * );
118 static int AddStream( sout_instance_t *, sout_input_t * );
119 static int DelStream( sout_instance_t *, sout_input_t * );
120 static int Mux ( sout_instance_t * );
124 /* Reserve a pid and return it */
125 static int AllocatePID( sout_mux_t *p_mux )
127 return( ++p_mux->i_pid_free );
130 static int GetPAT( sout_instance_t *p_sout, sout_buffer_t **pp_ts );
131 static int GetPMT( sout_instance_t *p_sout, 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 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
142 set_description( _("TS muxer (libdvbpsi)") );
143 set_capability( "sout mux", 120 );
144 add_shortcut( "ts_dvbpsi" );
146 set_callbacks( Open, Close );
149 /*****************************************************************************
151 *****************************************************************************/
152 static int Open( vlc_object_t *p_this )
154 sout_instance_t *p_sout = (sout_instance_t*)p_this;
157 msg_Info( p_sout, "Open" );
159 p_mux = malloc( sizeof( sout_mux_t ) );
161 p_sout->pf_mux_capacity = NULL;
162 p_sout->pf_mux_addstream = AddStream;
163 p_sout->pf_mux_delstream = DelStream;
164 p_sout->pf_mux = Mux;
165 p_sout->p_mux_data = (void*)p_mux;
166 p_sout->i_mux_preheader = 30; // really enough for a pes header
168 srand( (uint32_t)mdate() );
170 p_mux->i_stream_id_mpga = 0xc0;
171 p_mux->i_stream_id_a52 = 0x80;
172 p_mux->i_stream_id_mpgv = 0xe0;
174 p_mux->i_audio_bound = 0;
175 p_mux->i_video_bound = 0;
177 p_mux->i_pat_version_number = rand() % 32;
178 p_mux->pat.i_pid = 0;
179 p_mux->pat.i_continuity_counter = 0;
181 p_mux->i_pmt_version_number = rand() % 32;
182 p_mux->pmt.i_pid = 0x10;
183 p_mux->pmt.i_continuity_counter = 0;
185 p_mux->i_pid_free = 0x11;
186 p_mux->i_pcr_pid = 0x1fff;
188 p_mux->i_mpeg4_streams = 0;
193 /*****************************************************************************
195 *****************************************************************************/
197 static void Close( vlc_object_t * p_this )
199 sout_instance_t *p_sout = (sout_instance_t*)p_this;
200 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
202 msg_Info( p_sout, "Close" );
205 p_sout->p_mux_data = NULL;
209 static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
211 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
212 ts_stream_t *p_stream;
213 BITMAPINFOHEADER *p_bih;
216 msg_Dbg( p_sout, "adding input" );
217 p_input->p_mux_data = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
219 p_stream->i_pid = AllocatePID( p_mux );
220 if( p_mux->i_pcr_pid == 0x1fff )
222 p_mux->i_pcr_pid = p_stream->i_pid;
224 p_stream->i_continuity_counter = 0;
226 switch( p_input->input_format.i_cat )
229 switch( p_input->input_format.i_fourcc )
231 case VLC_FOURCC( 'm', 'p','g', 'v' ):
232 p_stream->i_stream_type = 0x02;
233 p_stream->i_stream_id = p_mux->i_stream_id_mpgv;
234 p_mux->i_stream_id_mpgv++;
236 case VLC_FOURCC( 'm', 'p','4', 'v' ):
237 p_stream->i_stream_type = 0x10;
238 p_stream->i_stream_id = 0xfa;
239 p_mux->i_mpeg4_streams++;
240 p_stream->i_es_id = p_stream->i_pid;
241 p_stream->i_sl_predefined = 0x01; // NULL SL header
243 /* XXX dirty dirty but somebody want that : using crapy MS-codec XXX */
244 /* I didn't want to do that :P */
245 case VLC_FOURCC( 'W', 'M', 'V', '2' ):
246 case VLC_FOURCC( 'H', '2', '6', '3' ):
247 case VLC_FOURCC( 'I', '2', '6', '3' ):
248 case VLC_FOURCC( 'W', 'M', 'V', '1' ):
249 case VLC_FOURCC( 'D', 'I', 'V', '3' ):
250 case VLC_FOURCC( 'D', 'I', 'V', '2' ):
251 case VLC_FOURCC( 'D', 'I', 'V', '1' ):
252 p_stream->i_stream_type = 0xa0; // private
253 p_stream->i_stream_id = 0xa0; // beurk
258 p_mux->i_video_bound++;
259 p_bih = (BITMAPINFOHEADER*)p_input->input_format.p_format;
262 p_stream->i_bih_codec = p_input->input_format.i_fourcc;
263 p_stream->i_bih_width = p_bih->biWidth;
264 p_stream->i_bih_height = p_bih->biHeight;
268 p_stream->i_bih_codec = 0x0;
269 p_stream->i_bih_width = 0;
270 p_stream->i_bih_height = 0;
273 if( p_bih && p_bih->biSize > sizeof( BITMAPINFOHEADER ) )
275 p_stream->i_decoder_specific_info_len =
276 p_bih->biSize - sizeof( BITMAPINFOHEADER );
277 p_stream->p_decoder_specific_info =
278 malloc( p_stream->i_decoder_specific_info_len );
279 memcpy( p_stream->p_decoder_specific_info,
281 p_stream->i_decoder_specific_info_len );
285 p_stream->p_decoder_specific_info = NULL;
286 p_stream->i_decoder_specific_info_len = 0;
290 switch( p_input->input_format.i_fourcc )
292 case VLC_FOURCC( 'a', '5','2', ' ' ):
293 case VLC_FOURCC( 'a', '5','2', 'b' ):
294 p_stream->i_stream_type = 0x81;
295 p_stream->i_stream_id = p_mux->i_stream_id_a52;
296 p_mux->i_stream_id_a52++;
298 case VLC_FOURCC( 'm', 'p','4', 'a' ):
299 p_stream->i_stream_type = 0x11;
300 p_stream->i_stream_id = 0xfa;
301 p_mux->i_mpeg4_streams++;
302 p_stream->i_es_id = p_stream->i_pid;
303 p_stream->i_sl_predefined = 0x01; // NULL SL header
305 case VLC_FOURCC( 'm', 'p','g', 'a' ):
306 p_stream->i_stream_type = 0x04;
307 p_stream->i_stream_id = p_mux->i_stream_id_mpga;
308 p_mux->i_stream_id_mpga++;
313 p_mux->i_audio_bound++;
314 p_wf = (WAVEFORMATEX*)p_input->input_format.p_format;
315 if( p_wf && p_wf->cbSize > 0 )
317 p_stream->i_decoder_specific_info_len = p_wf->cbSize;
318 p_stream->p_decoder_specific_info =
319 malloc( p_stream->i_decoder_specific_info_len );
320 memcpy( p_stream->p_decoder_specific_info,
322 p_stream->i_decoder_specific_info_len );
326 p_stream->p_decoder_specific_info = NULL;
327 p_stream->i_decoder_specific_info_len = 0;
334 p_mux->i_ts_packet = 0; // force pat/pmt recreation
335 p_mux->i_pat_version_number++; p_mux->i_pat_version_number %= 32;
336 p_mux->i_pmt_version_number++; p_mux->i_pmt_version_number %= 32;
341 static int DelStream( sout_instance_t *p_sout, sout_input_t *p_input )
343 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
344 ts_stream_t *p_stream;
346 msg_Dbg( p_sout, "removing input" );
347 p_stream = (ts_stream_t*)p_input->p_mux_data;
349 if( p_stream->p_decoder_specific_info )
351 free( p_stream->p_decoder_specific_info );
353 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
355 p_mux->i_mpeg4_streams--;
357 p_mux->i_ts_packet = 0; // force pat/pmt recreation
358 p_mux->i_pat_version_number++; p_mux->i_pat_version_number %= 32;
359 p_mux->i_pmt_version_number++; p_mux->i_pmt_version_number %= 32;
366 static int MuxGetStream( sout_instance_t *p_sout,
374 for( i = 0, i_dts = 0, i_stream = -1; i < p_sout->i_nb_inputs; i++ )
378 p_fifo = p_sout->pp_inputs[i]->p_fifo;
380 if( p_fifo->i_depth > 1 )
382 sout_buffer_t *p_buf;
384 p_buf = sout_FifoShow( p_fifo );
385 if( i_stream < 0 || p_buf->i_dts < i_dts )
387 i_dts = p_buf->i_dts;
393 return( -1 ); // wait that all fifo have at least 2 packets
399 *pi_stream = i_stream;
409 static int PEStoTS( sout_instance_t *p_sout,
410 sout_buffer_t **pp_ts, sout_buffer_t *p_pes,
411 ts_stream_t *p_stream )
421 /* get PES total size */
422 i_size = p_pes->i_size;
423 p_data = p_pes->p_buffer;
425 if( p_pes->i_dts == 0 && p_pes->i_length > 0 )
427 i_dts = 1; // XXX <french> kludge immonde </french>
431 i_dts = p_pes->i_dts;
434 for( i_first = 1, b_new_pes = 1; p_pes != NULL; )
436 int i_adaptation_field;
442 p_ts = sout_BufferNew( p_sout, 188 );
448 i_payload = 184 - ( i_first && i_dts > 0 ? 8 : 0 );
449 i_copy = __MIN( i_size, i_payload );
451 i_adaptation_field = ( ( i_first && i_dts > 0 ) ||
452 i_size < i_payload ) ? 1 : 0;
455 bits_initwrite( &bits, 188, p_ts->p_buffer );
456 bits_write( &bits, 8, 0x47 ); /* sync byte */
457 bits_write( &bits, 1, 0 ); /* transport_error_indicator */
458 bits_write( &bits, 1, b_new_pes ? 1 : 0 ); /* payload_unit_start */
460 bits_write( &bits, 1, 0 ); /* transport_priority */
461 bits_write( &bits, 13, p_stream->i_pid );
462 bits_write( &bits, 2, 0 ); /* transport_scrambling_control */
463 bits_write( &bits, 2, ( i_adaptation_field ? 0x03 : 0x01 ) );
465 bits_write( &bits, 4, /* continuity_counter */
466 p_stream->i_continuity_counter );
467 p_stream->i_continuity_counter++;
468 p_stream->i_continuity_counter %= 16;
469 if( i_adaptation_field )
474 if( i_first && i_dts > 0 )
476 i_stuffing = i_payload - i_copy;
477 bits_write( &bits, 8, 7 + i_stuffing );
478 bits_write( &bits, 8, 0x10 ); /* various flags */
479 bits_write( &bits, 33, i_dts * 9 / 100);
480 bits_write( &bits, 6, 0 );
481 bits_write( &bits, 9, 0 );
482 i_dts = 0; /* XXX set dts only for first ts packet */
486 i_stuffing = i_payload - i_copy;
487 bits_write( &bits, 8, i_stuffing - 1);
488 if( i_stuffing - 1 > 0 )
490 bits_write( &bits, 8, 0 );
496 for( i = 0; i < i_stuffing; i++ )
498 bits_write( &bits, 8, 0xff );
502 memcpy( p_ts->p_buffer + bits.i_data,
508 sout_BufferChain( pp_ts, p_ts );
514 sout_buffer_t *p_next;
516 p_next = p_pes->p_next;
517 p_pes->p_next = NULL;
518 sout_BufferDelete( p_sout, p_pes );
523 i_size = p_pes->i_size;
524 p_data = p_pes->p_buffer;
536 static void SetTSDate( sout_buffer_t *p_ts, mtime_t i_dts, mtime_t i_length )
539 sout_buffer_t *p_tmp;
542 for( p_tmp = p_ts, i_count = 0; p_tmp != NULL; p_tmp = p_tmp->p_next )
546 i_delta = i_length / i_count;
548 for( p_tmp = p_ts; p_tmp != NULL; p_tmp = p_tmp->p_next )
550 p_tmp->i_dts = i_dts;
551 p_tmp->i_length = i_delta;
557 static int Mux( sout_instance_t *p_sout )
559 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
562 sout_buffer_t *p_pat, *p_pmt, *p_ts;
566 mtime_t i_dts, i_length;
568 sout_input_t *p_input;
569 ts_stream_t *p_stream;
571 sout_buffer_t *p_data;
573 if( MuxGetStream( p_sout, &i_stream, &i_dts ) < 0 )
578 p_input = p_sout->pp_inputs[i_stream];
579 p_fifo = p_input->p_fifo;
580 p_stream = (ts_stream_t*)p_input->p_mux_data;
582 p_data = sout_FifoGet( p_fifo );
583 i_dts = p_data->i_dts;
584 i_length = p_data->i_length;
586 E_( EStoPES )( p_sout, &p_data, p_data, p_stream->i_stream_id, 1);
587 PEStoTS( p_sout, &p_data, p_data, p_stream );
589 if( p_mux->i_ts_packet % 30 == 0 )
592 GetPAT( p_sout, &p_pat );
593 GetPMT( p_sout, &p_pmt );
596 sout_BufferChain( &p_ts, p_pmt );
597 sout_BufferChain( &p_ts, p_data );
604 p_mux->i_ts_packet++;
605 SetTSDate( p_ts, i_dts, i_length );
607 sout_AccessOutWrite( p_sout->p_access, p_ts );
614 static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
616 static uint32_t CRC32[256] =
618 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
619 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
620 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
621 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
622 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
623 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
624 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
625 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
626 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
627 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
628 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
629 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
630 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
631 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
632 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
633 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
634 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
635 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
636 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
637 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
638 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
639 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
640 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
641 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
642 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
643 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
644 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
645 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
646 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
647 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
648 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
649 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
650 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
651 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
652 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
653 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
654 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
655 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
656 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
657 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
658 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
659 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
660 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
661 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
662 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
663 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
664 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
665 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
666 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
667 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
668 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
669 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
670 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
671 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
672 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
673 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
674 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
675 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
676 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
677 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
678 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
679 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
680 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
681 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
684 uint32_t i_crc = 0xffffffff;
686 /* Calculate the CRC */
689 i_crc = (i_crc<<8) ^ CRC32[ (i_crc>>24) ^ ((uint32_t)*p_begin) ];
697 #if defined MODULE_NAME_IS_mux_ts
698 static int GetPAT( sout_instance_t *p_sout,
699 sout_buffer_t **pp_ts )
701 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
702 sout_buffer_t *p_pat;
705 p_pat = sout_BufferNew( p_sout, 1024 );
711 bits_initwrite( &bits, 1024, p_pat->p_buffer );
713 bits_write( &bits, 8, 0 ); // pointer
714 bits_write( &bits, 8, 0x00 ); // table id
715 bits_write( &bits, 1, 1 ); // section_syntax_indicator
716 bits_write( &bits, 1, 0 ); // 0
717 bits_write( &bits, 2, 0x03 ); // reserved FIXME
718 bits_write( &bits, 12, 13 ); // XXX for one program only XXX
719 bits_write( &bits, 16, 0x01 ); // FIXME stream id
720 bits_write( &bits, 2, 0x03 ); // FIXME
721 bits_write( &bits, 5, p_mux->i_pat_version_number );
722 bits_write( &bits, 1, 1 ); // current_next_indicator
723 bits_write( &bits, 8, 0 ); // section number
724 bits_write( &bits, 8, 0 ); // last section number
726 bits_write( &bits, 16, 1 ); // program number
727 bits_write( &bits, 3, 0x07 ); // reserved
728 bits_write( &bits, 13, p_mux->pmt.i_pid ); // program map pid
730 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
732 p_pat->i_size = bits.i_data;
734 return( PEStoTS( p_sout, pp_ts, p_pat, &p_mux->pat ) );
737 static int GetPMT( sout_instance_t *p_sout,
738 sout_buffer_t **pp_ts )
740 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
741 sout_buffer_t *p_pmt;
745 p_pmt = sout_BufferNew( p_sout, 1024 );
751 bits_initwrite( &bits, 1024, p_pmt->p_buffer );
753 bits_write( &bits, 8, 0 ); // pointer
754 bits_write( &bits, 8, 0x02 ); // table id
755 bits_write( &bits, 1, 1 ); // section_syntax_indicator
756 bits_write( &bits, 1, 0 ); // 0
757 bits_write( &bits, 2, 0 ); // reserved FIXME
758 bits_write( &bits, 12, 13 + 5 * p_sout->i_nb_inputs );
759 bits_write( &bits, 16, 1 ); // FIXME program number
760 bits_write( &bits, 2, 0 ); // FIXME
761 bits_write( &bits, 5, p_mux->i_pmt_version_number );
762 bits_write( &bits, 1, 0 ); // current_next_indicator
763 bits_write( &bits, 8, 0 ); // section number
764 bits_write( &bits, 8, 0 ); // last section number
766 bits_write( &bits, 3, 0 ); // reserved
768 bits_write( &bits, 13, p_mux->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
769 bits_write( &bits, 4, 0 ); // reserved FIXME
771 bits_write( &bits, 12, 0 ); // program info len FIXME
773 for( i_stream = 0; i_stream < p_sout->i_nb_inputs; i_stream++ )
775 ts_stream_t *p_stream;
777 p_stream = (ts_stream_t*)p_sout->pp_inputs[i_stream]->p_mux_data;
779 bits_write( &bits, 8, p_stream->i_stream_type ); // stream_type
780 bits_write( &bits, 3, 0 ); // reserved
781 bits_write( &bits, 13, p_stream->i_pid ); // es pid
782 bits_write( &bits, 4, 0 ); //reserved
783 bits_write( &bits, 12, 0 ); // es info len FIXME
786 bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
788 p_pmt->i_size = bits.i_data;
790 return( PEStoTS( p_sout, pp_ts, p_pmt, &p_mux->pmt ) );
793 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
795 static sout_buffer_t *WritePSISection( sout_instance_t *p_sout,
796 dvbpsi_psi_section_t* p_section )
798 sout_buffer_t *p_psi, *p_first = NULL;
805 i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+
806 ( p_section->b_syntax_indicator ? 4 : 0 );
808 p_psi = sout_BufferNew( p_sout, i_size + 1 );
812 p_psi->i_size = i_size + 1;
814 p_psi->p_buffer[0] = 0; // pointer
815 memcpy( p_psi->p_buffer + 1,
819 sout_BufferChain( &p_first, p_psi );
821 p_section = p_section->p_next;
827 static int GetPAT( sout_instance_t *p_sout,
828 sout_buffer_t **pp_ts )
830 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
831 sout_buffer_t *p_pat;
833 dvbpsi_psi_section_t *p_section;
835 dvbpsi_InitPAT( &pat,
837 p_mux->i_pat_version_number,
838 0); // b_current_next
839 /* add all program (only one) */
840 dvbpsi_PATAddProgram( &pat,
842 p_mux->pmt.i_pid ); // i_pid
844 p_section = dvbpsi_GenPATSections( &pat,
845 0 ); // max program per section
847 p_pat = WritePSISection( p_sout, p_section );
849 PEStoTS( p_sout, pp_ts, p_pat, &p_mux->pat );
851 dvbpsi_DeletePSISections( p_section );
852 dvbpsi_EmptyPAT( &pat );
856 static uint32_t GetDescriptorLength24b( int i_length )
858 uint32_t i_l1, i_l2, i_l3;
860 i_l1 = i_length&0x7f;
861 i_l2 = ( i_length >> 7 )&0x7f;
862 i_l3 = ( i_length >> 14 )&0x7f;
864 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
867 static int GetPMT( sout_instance_t *p_sout,
868 sout_buffer_t **pp_ts )
870 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
871 sout_buffer_t *p_pmt;
874 dvbpsi_pmt_es_t* p_es;
875 dvbpsi_psi_section_t *p_section;
879 dvbpsi_InitPMT( &pmt,
880 0x01, // program number
881 p_mux->i_pmt_version_number,
885 if( p_mux->i_mpeg4_streams > 0 )
889 bits_buffer_t bits_fix_IOD;
891 bits_initwrite( &bits, 4096, iod );
893 bits_write( &bits, 8, 0x01 );
894 // InitialObjectDescriptor
896 bits_write( &bits, 8, 0x02 ); // tag
897 bits_fix_IOD = bits; // save states to fix length later
898 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable length (fixed later)
899 bits_write( &bits, 10, 0x01 ); // ObjectDescriptorID
900 bits_write( &bits, 1, 0x00 ); // URL Flag
901 bits_write( &bits, 1, 0x00 ); // includeInlineProfileLevelFlag
902 bits_write( &bits, 4, 0x0f ); // reserved
903 bits_write( &bits, 8, 0xff ); // ODProfile (no ODcapability )
904 bits_write( &bits, 8, 0xff ); // sceneProfile
905 bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified)
906 bits_write( &bits, 8, 0xfe ); // visualProfile( // )
907 bits_write( &bits, 8, 0xff ); // graphicProfile (no )
908 for( i_stream = 0; i_stream < p_sout->i_nb_inputs; i_stream++ )
910 ts_stream_t *p_stream;
911 p_stream = (ts_stream_t*)p_sout->pp_inputs[i_stream]->p_mux_data;
913 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
915 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
918 bits_write( &bits, 8, 0x03 ); // ES_DescrTag
919 bits_fix_ESDescr = bits;
920 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable size
921 bits_write( &bits, 16, p_stream->i_es_id );
922 bits_write( &bits, 1, 0x00 ); // streamDependency
923 bits_write( &bits, 1, 0x00 ); // URL Flag
924 bits_write( &bits, 1, 0x00 ); // OCRStreamFlag
925 bits_write( &bits, 5, 0x1f ); // streamPriority
927 // DecoderConfigDesciptor
929 bits_write( &bits, 8, 0x04 ); // DecoderConfigDescrTag
930 bits_fix_Decoder = bits;
931 bits_write( &bits, 24, GetDescriptorLength24b( 0 ) );
932 if( p_stream->i_stream_type == 0x10 )
934 bits_write( &bits, 8, 0x20 ); // Visual 14496-2
935 bits_write( &bits, 6, 0x04 ); // VisualStream
937 else if( p_stream->i_stream_type == 0x11 )
939 bits_write( &bits, 8, 0x40 ); // Audio 14496-3
940 bits_write( &bits, 6, 0x05 ); // AudioStream
944 bits_write( &bits, 8, 0x00 );
945 bits_write( &bits, 6, 0x00 );
947 msg_Err( p_sout,"Unsupported stream_type => broken IOD");
949 bits_write( &bits, 1, 0x00 ); // UpStream
950 bits_write( &bits, 1, 0x01 ); // reserved
951 bits_write( &bits, 24, 1024 * 1024 ); // bufferSizeDB
952 bits_write( &bits, 32, 0x7fffffff ); // maxBitrate
953 bits_write( &bits, 32, 0 ); // avgBitrate
955 if( p_stream->i_decoder_specific_info_len > 0 )
958 // DecoderSpecificInfo
960 bits_write( &bits, 8, 0x05 ); // tag
961 bits_write( &bits, 24,
962 GetDescriptorLength24b( p_stream->i_decoder_specific_info_len ) );
963 for( i = 0; i < p_stream->i_decoder_specific_info_len; i++ )
965 bits_write( &bits, 8, ((uint8_t*)p_stream->p_decoder_specific_info)[i] );
968 /* fix Decoder length */
969 bits_write( &bits_fix_Decoder, 24,
970 GetDescriptorLength24b( bits.i_data - bits_fix_Decoder.i_data - 3 ) );
972 // SLConfigDescriptor
973 switch( p_stream->i_sl_predefined )
978 bits_write( &bits, 8, 0x06 ); // tag
979 bits_write( &bits, 24, GetDescriptorLength24b( 8 ) );
980 bits_write( &bits, 8, 0x01 ); // predefined
981 bits_write( &bits, 1, 0 ); // durationFlag
982 bits_write( &bits, 32, 0 ); // OCRResolution
983 bits_write( &bits, 8, 0 ); // OCRLength
984 bits_write( &bits, 8, 0 ); // InstantBitrateLength
988 msg_Err( p_sout,"Unsupported SL profile => broken IOD");
991 /* fix ESDescr length */
992 bits_write( &bits_fix_ESDescr, 24,
993 GetDescriptorLength24b( bits.i_data - bits_fix_ESDescr.i_data - 3 ) );
998 bits_write( &bits_fix_IOD, 24,
999 GetDescriptorLength24b( bits.i_data - bits_fix_IOD.i_data - 3 ) );
1000 dvbpsi_PMTAddDescriptor( &pmt,
1006 for( i_stream = 0; i_stream < p_sout->i_nb_inputs; i_stream++ )
1008 ts_stream_t *p_stream;
1010 p_stream = (ts_stream_t*)p_sout->pp_inputs[i_stream]->p_mux_data;
1012 p_es = dvbpsi_PMTAddES( &pmt,
1013 p_stream->i_stream_type,
1015 if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
1021 bits_initwrite( &bits, 512, data );
1022 bits_write( &bits, 16, p_stream->i_es_id );
1024 dvbpsi_PMTESAddDescriptor( p_es,
1029 else if( p_stream->i_stream_id == 0xa0 )
1034 /* private DIV3 descripor */
1035 bits_initwrite( &bits, 512, data );
1036 bits_write( &bits, 32, p_stream->i_bih_codec );
1037 bits_write( &bits, 16, p_stream->i_bih_width );
1038 bits_write( &bits, 16, p_stream->i_bih_height );
1039 bits_write( &bits, 16, p_stream->i_decoder_specific_info_len );
1040 if( p_stream->i_decoder_specific_info_len > 0 )
1043 for( i = 0; i < p_stream->i_decoder_specific_info_len; i++ )
1045 bits_write( &bits, 8, p_stream->p_decoder_specific_info[i] );
1048 dvbpsi_PMTESAddDescriptor( p_es,
1055 p_section = dvbpsi_GenPMTSections( &pmt );
1057 p_pmt = WritePSISection( p_sout, p_section );
1059 PEStoTS( p_sout, pp_ts, p_pmt, &p_mux->pmt );
1061 dvbpsi_DeletePSISections( p_section );
1062 dvbpsi_EmptyPMT( &pmt );