1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: ts.c,v 1.3 2002/12/17 21:58:03 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 typedef struct ts_stream_s
55 int i_continuity_counter;
58 typedef struct sout_mux_s
68 int i_pid_free; // first usable pid
70 int i_pat_version_number;
73 int i_pmt_version_number;
74 ts_stream_t pmt; // Up to now only one program
76 int i_ts_packet;// To known when to put pat/mpt
80 /*****************************************************************************
82 *****************************************************************************/
83 static int Open ( vlc_object_t * );
84 static void Close ( vlc_object_t * );
86 static int AddStream( sout_instance_t *, sout_input_t * );
87 static int DelStream( sout_instance_t *, sout_input_t * );
88 static int Mux ( sout_instance_t * );
90 /* Reserve a pid and return it */
91 static int AllocatePID( sout_mux_t *p_mux )
93 return( ++p_mux->i_pid_free );
96 /*****************************************************************************
98 *****************************************************************************/
100 set_description( _("TS muxer") );
101 set_capability( "sout mux", 100 );
102 add_shortcut( "ts" );
103 set_callbacks( Open, Close );
106 /*****************************************************************************
108 *****************************************************************************/
109 static int Open( vlc_object_t *p_this )
111 sout_instance_t *p_sout = (sout_instance_t*)p_this;
114 msg_Info( p_sout, "Open" );
116 p_mux = malloc( sizeof( sout_mux_t ) );
118 p_sout->pf_mux_addstream = AddStream;
119 p_sout->pf_mux_delstream = DelStream;
120 p_sout->pf_mux = Mux;
121 p_sout->p_mux_data = (void*)p_mux;
123 p_mux->i_stream_id_mpga = 0xc0;
124 p_mux->i_stream_id_a52 = 0x80;
125 p_mux->i_stream_id_mpgv = 0xe0;
127 p_mux->i_audio_bound = 0;
128 p_mux->i_video_bound = 0;
130 p_mux->i_pat_version_number = 0;
131 p_mux->pat.i_pid = 0;
132 p_mux->pat.i_continuity_counter = 0;
134 p_mux->i_pmt_version_number = 0;
135 p_mux->pmt.i_pid = 0x10;
136 p_mux->pmt.i_continuity_counter = 0;
138 p_mux->i_pid_free = 0x11;
139 p_mux->i_pcr_pid = 0x1fff;
143 /*****************************************************************************
145 *****************************************************************************/
147 static void Close( vlc_object_t * p_this )
149 sout_instance_t *p_sout = (sout_instance_t*)p_this;
150 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
152 msg_Info( p_sout, "Close" );
155 p_sout->p_mux_data = NULL;
159 static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
161 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
162 ts_stream_t *p_stream;
164 msg_Dbg( p_sout, "adding input" );
165 p_input->p_mux_data = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
167 p_stream->i_pid = AllocatePID( p_mux );
168 if( p_mux->i_pcr_pid == 0x1fff )
170 p_mux->i_pcr_pid = p_stream->i_pid;
172 p_stream->i_continuity_counter = 0;
174 switch( p_input->input_format.i_cat )
177 switch( p_input->input_format.i_fourcc )
179 case VLC_FOURCC( 'm', 'p','g', 'v' ):
180 p_stream->i_stream_type = 0x02;
181 p_stream->i_stream_id = p_mux->i_stream_id_mpgv;
182 p_mux->i_stream_id_mpgv++;
184 case VLC_FOURCC( 'm', 'p','4', 'v' ):
185 p_stream->i_stream_type = 0x10;
186 p_stream->i_stream_id = 0xfa;
191 p_mux->i_video_bound++;
195 switch( p_input->input_format.i_fourcc )
197 case VLC_FOURCC( 'a', '5','2', ' ' ):
198 case VLC_FOURCC( 'a', '5','2', 'b' ):
199 p_stream->i_stream_type = 0x81;
200 p_stream->i_stream_id = p_mux->i_stream_id_a52;
201 p_mux->i_stream_id_a52++;
204 case VLC_FOURCC( 'm', 'p','4', 'a' ):
205 p_stream->i_stream_type = 0x11;
206 p_stream->i_stream_id = 0xfa;
207 p_mux->i_stream_id_mp4a++;
210 case VLC_FOURCC( 'm', 'p','g', 'a' ):
211 p_stream->i_stream_type = 0x04;
212 p_stream->i_stream_id = p_mux->i_stream_id_mpga;
213 p_mux->i_stream_id_mpga++;
218 p_mux->i_audio_bound++;
224 p_mux->i_ts_packet = 0; // force pat/pmt recreation
225 p_mux->i_pat_version_number++; p_mux->i_pat_version_number %= 32;
226 p_mux->i_pmt_version_number++; p_mux->i_pmt_version_number %= 32;
231 static int DelStream( sout_instance_t *p_sout, sout_input_t *p_input )
233 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
235 msg_Dbg( p_sout, "removing input" );
236 p_mux->i_ts_packet = 0; // force pat/pmt recreation
237 p_mux->i_pat_version_number++; p_mux->i_pat_version_number %= 32;
238 p_mux->i_pmt_version_number++; p_mux->i_pmt_version_number %= 32;
245 static int MuxGetStream( sout_instance_t *p_sout,
253 for( i = 0, i_dts = 0, i_stream = -1; i < p_sout->i_nb_inputs; i++ )
257 p_fifo = p_sout->pp_inputs[i]->p_fifo;
259 if( p_fifo->i_depth > 1 )
261 sout_buffer_t *p_buf;
263 p_buf = sout_FifoShow( p_fifo );
264 if( i_stream < 0 || p_buf->i_dts < i_dts )
266 i_dts = p_buf->i_dts;
272 return( -1 ); // wait that all fifo have at least 2 packets
278 *pi_stream = i_stream;
288 static int PEStoTS( sout_instance_t *p_sout,
289 sout_buffer_t **pp_ts, sout_buffer_t *p_pes,
290 ts_stream_t *p_stream )
293 sout_buffer_t *p_last_buffer = NULL;
298 /* get PES total size */
299 i_size = p_pes->i_size;
300 p_data = p_pes->p_buffer;
302 if( p_pes->i_dts == 0 && p_pes->i_length > 0 )
304 i_dts = 1; // XXX <french> kludge immonde </french>
308 i_dts = p_pes->i_dts;
311 for( i_first = 1, b_new_pes = 1; p_pes != NULL; )
313 int i_adaptation_field;
319 p_ts = sout_BufferNew( p_sout, 188 );
325 i_payload = 184 - ( i_first && i_dts > 0 ? 8 : 0 );
326 i_copy = __MIN( i_size, i_payload );
328 i_adaptation_field = ( ( i_first && i_dts > 0 ) ||
329 i_size < i_payload ) ? 1 : 0;
332 bits_initwrite( &bits, 188, p_ts->p_buffer );
333 bits_write( &bits, 8, 0x47 ); /* sync byte */
334 bits_write( &bits, 1, 0 ); /* transport_error_indicator */
335 bits_write( &bits, 1, b_new_pes ? 1 : 0 ); /* payload_unit_start */
337 bits_write( &bits, 1, 0 ); /* transport_priority */
338 bits_write( &bits, 13, p_stream->i_pid );
339 bits_write( &bits, 2, 0 ); /* transport_scrambling_control */
340 bits_write( &bits, 2, ( i_adaptation_field ? 0x03 : 0x01 ) );
342 bits_write( &bits, 4, /* continuity_counter */
343 p_stream->i_continuity_counter );
344 p_stream->i_continuity_counter++;
345 p_stream->i_continuity_counter %= 16;
346 if( i_adaptation_field )
351 if( i_first && i_dts > 0 )
353 i_stuffing = i_payload - i_copy;
354 bits_write( &bits, 8, 7 + i_stuffing );
355 bits_write( &bits, 8, 0x10 ); /* various flags */
356 bits_write( &bits, 33, i_dts * 9 / 100);
357 bits_write( &bits, 6, 0 );
358 bits_write( &bits, 9, 0 );
359 i_dts = 0; /* XXX set dts only for first ts packet */
363 i_stuffing = i_payload - i_copy;
364 bits_write( &bits, 8, i_stuffing - 1);
365 if( i_stuffing - 1 > 0 )
367 bits_write( &bits, 8, 0 );
373 for( i = 0; i < i_stuffing; i++ )
375 bits_write( &bits, 8, 0xff );
379 memcpy( p_ts->p_buffer + bits.i_data,
389 p_last_buffer = p_ts;
393 p_last_buffer->p_next = p_ts;
394 p_last_buffer = p_ts;
400 sout_buffer_t *p_next;
402 p_next = p_pes->p_next;
403 p_pes->p_next = NULL;
404 sout_BufferDelete( p_sout, p_pes );
409 i_size = p_pes->i_size;
410 p_data = p_pes->p_buffer;
422 static int GetPAT( sout_instance_t *p_sout,
423 sout_buffer_t **pp_ts )
425 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
426 sout_buffer_t *p_pat;
429 p_pat = sout_BufferNew( p_sout, 1024 );
435 bits_initwrite( &bits, 1024, p_pat->p_buffer );
437 bits_write( &bits, 8, 0 ); // pointer
438 bits_write( &bits, 8, 0x00 ); // table id
439 bits_write( &bits, 1, 1 ); // section_syntax_indicator
440 bits_write( &bits, 1, 0 ); // 0
441 bits_write( &bits, 2, 0 ); // reserved FIXME
442 bits_write( &bits, 12, 13 ); // XXX for one program only XXX
443 bits_write( &bits, 16, 0x01 ); // FIXME stream id
444 bits_write( &bits, 2, 0 ); // FIXME
445 bits_write( &bits, 5, p_mux->i_pat_version_number );
446 bits_write( &bits, 1, 1 ); // current_next_indicator
447 bits_write( &bits, 8, 0 ); // section number
448 bits_write( &bits, 8, 0 ); // last section number
450 bits_write( &bits, 16, 1 ); // program number
451 bits_write( &bits, 3, 0 ); // reserved
452 bits_write( &bits, 13, p_mux->pmt.i_pid ); // program map pid
454 bits_write( &bits, 32, 0 ); // FIXME FIXME FIXME
456 p_pat->i_size = bits.i_data;
458 return( PEStoTS( p_sout, pp_ts, p_pat, &p_mux->pat ) );
461 static int GetPMT( sout_instance_t *p_sout,
462 sout_buffer_t **pp_ts )
464 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
465 sout_buffer_t *p_pmt;
469 p_pmt = sout_BufferNew( p_sout, 1024 );
475 bits_initwrite( &bits, 1024, p_pmt->p_buffer );
477 bits_write( &bits, 8, 0 ); // pointer
478 bits_write( &bits, 8, 0x02 ); // table id
479 bits_write( &bits, 1, 1 ); // section_syntax_indicator
480 bits_write( &bits, 1, 0 ); // 0
481 bits_write( &bits, 2, 0 ); // reserved FIXME
482 bits_write( &bits, 12, 13 + 5 * p_sout->i_nb_inputs );
483 bits_write( &bits, 16, 1 ); // FIXME program number
484 bits_write( &bits, 2, 0 ); // FIXME
485 bits_write( &bits, 5, p_mux->i_pmt_version_number );
486 bits_write( &bits, 1, 1 ); // current_next_indicator
487 bits_write( &bits, 8, 0 ); // section number
488 bits_write( &bits, 8, 0 ); // last section number
490 bits_write( &bits, 3, 0 ); // reserved
492 bits_write( &bits, 13, p_mux->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
493 bits_write( &bits, 4, 0 ); // reserved FIXME
495 bits_write( &bits, 12, 0 ); // program info len FIXME
497 for( i_stream = 0; i_stream < p_sout->i_nb_inputs; i_stream++ )
499 ts_stream_t *p_stream;
501 p_stream = (ts_stream_t*)p_sout->pp_inputs[i_stream]->p_mux_data;
503 bits_write( &bits, 8, p_stream->i_stream_type ); // stream_type
504 bits_write( &bits, 3, 0 ); // reserved
505 bits_write( &bits, 13, p_stream->i_pid ); // es pid
506 bits_write( &bits, 4, 0 ); //reserved
507 bits_write( &bits, 12, 0 ); // es info len FIXME
510 bits_write( &bits, 32, 0 ); // FIXME FIXME FIXME
512 p_pmt->i_size = bits.i_data;
514 return( PEStoTS( p_sout, pp_ts, p_pmt, &p_mux->pmt ) );
518 static void SetTSDate( sout_buffer_t *p_ts, mtime_t i_dts, mtime_t i_length )
521 sout_buffer_t *p_tmp;
524 for( p_tmp = p_ts, i_count = 0; p_tmp != NULL; p_tmp = p_tmp->p_next )
528 i_delta = i_length / i_count;
530 for( p_tmp = p_ts; p_tmp != NULL; p_tmp = p_tmp->p_next )
532 p_tmp->i_dts = i_dts;
533 p_tmp->i_length = i_delta;
539 static int Mux( sout_instance_t *p_sout )
541 sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
544 sout_buffer_t *p_pat, *p_pmt, *p_ts;
548 mtime_t i_dts, i_length;
550 sout_input_t *p_input;
551 ts_stream_t *p_stream;
553 sout_buffer_t *p_data;
555 if( MuxGetStream( p_sout, &i_stream, &i_dts ) < 0 )
560 p_input = p_sout->pp_inputs[i_stream];
561 p_fifo = p_input->p_fifo;
562 p_stream = (ts_stream_t*)p_input->p_mux_data;
564 p_data = sout_FifoGet( p_fifo );
565 i_dts = p_data->i_dts;
566 i_length = p_data->i_length;
568 E_( EStoPES )( p_sout, &p_data, p_data, p_stream->i_stream_id, 1);
569 PEStoTS( p_sout, &p_data, p_data, p_stream );
571 if( p_mux->i_ts_packet % 30 == 0 )
574 GetPAT( p_sout, &p_pat );
575 GetPMT( p_sout, &p_pmt );
578 p_pat->p_next = p_pmt;
579 p_pmt->p_next = p_data;
588 p_mux->i_ts_packet++;
589 SetTSDate( p_ts, i_dts, i_length );
591 p_sout->pf_write( p_sout, p_ts );