]> git.sesse.net Git - vlc/blob - modules/mux/mpeg/ts.c
* bits.h: fixed a stupid bug.
[vlc] / modules / mux / mpeg / ts.c
1 /*****************************************************************************
2  * ts.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: ts.c,v 1.3 2002/12/17 21:58:03 fenrir Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Eric Petit <titer@videolan.org>
9  *
10  *
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.
15  *
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.
20  *
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  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <stdlib.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <fcntl.h>
35
36 #include <vlc/vlc.h>
37 #include <vlc/input.h>
38 #include <vlc/sout.h>
39
40 #ifdef HAVE_UNISTD_H
41 #   include <unistd.h>
42 #elif defined( _MSC_VER ) && defined( _WIN32 ) && !defined( UNDER_CE )
43 #   include <io.h>
44 #endif
45
46 #include "codecs.h"
47 #include "bits.h"
48 #include "pes.h"
49
50 typedef struct ts_stream_s
51 {
52     int             i_pid;
53     int             i_stream_type;
54     int             i_stream_id;
55     int             i_continuity_counter;
56 } ts_stream_t;
57
58 typedef struct sout_mux_s
59 {
60     int             i_pcr_pid;
61     int             i_stream_id_mpga;
62     int             i_stream_id_mpgv;
63     int             i_stream_id_a52;
64
65     int             i_audio_bound;
66     int             i_video_bound;
67
68     int             i_pid_free; // first usable pid
69
70     int             i_pat_version_number;
71     ts_stream_t     pat;
72
73     int             i_pmt_version_number;
74     ts_stream_t     pmt;        // Up to now only one program
75
76     int             i_ts_packet;// To known when to put pat/mpt
77 } sout_mux_t;
78
79
80 /*****************************************************************************
81  * Exported prototypes
82  *****************************************************************************/
83 static int     Open   ( vlc_object_t * );
84 static void    Close  ( vlc_object_t * );
85
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 * );
89
90 /* Reserve a pid and return it */
91 static int     AllocatePID( sout_mux_t *p_mux )
92 {
93     return( ++p_mux->i_pid_free );
94 }
95
96 /*****************************************************************************
97  * Module descriptor
98  *****************************************************************************/
99 vlc_module_begin();
100     set_description( _("TS muxer") );
101     set_capability( "sout mux", 100 );
102     add_shortcut( "ts" );
103     set_callbacks( Open, Close );
104 vlc_module_end();
105
106 /*****************************************************************************
107  * Open:
108  *****************************************************************************/
109 static int Open( vlc_object_t *p_this )
110 {
111     sout_instance_t     *p_sout = (sout_instance_t*)p_this;
112     sout_mux_t          *p_mux;
113
114     msg_Info( p_sout, "Open" );
115
116     p_mux = malloc( sizeof( sout_mux_t ) );
117
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;
122
123     p_mux->i_stream_id_mpga = 0xc0;
124     p_mux->i_stream_id_a52  = 0x80;
125     p_mux->i_stream_id_mpgv = 0xe0;
126
127     p_mux->i_audio_bound = 0;
128     p_mux->i_video_bound = 0;
129
130     p_mux->i_pat_version_number = 0;
131     p_mux->pat.i_pid = 0;
132     p_mux->pat.i_continuity_counter = 0;
133
134     p_mux->i_pmt_version_number = 0;
135     p_mux->pmt.i_pid = 0x10;
136     p_mux->pmt.i_continuity_counter = 0;
137
138     p_mux->i_pid_free = 0x11;
139     p_mux->i_pcr_pid = 0x1fff;
140     return VLC_SUCCESS;
141 }
142
143 /*****************************************************************************
144  * Close:
145  *****************************************************************************/
146
147 static void Close( vlc_object_t * p_this )
148 {
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;
151
152     msg_Info( p_sout, "Close" );
153
154     free( p_mux );
155     p_sout->p_mux_data = NULL;
156 }
157
158
159 static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
160 {
161     sout_mux_t          *p_mux = (sout_mux_t*)p_sout->p_mux_data;
162     ts_stream_t         *p_stream;
163
164     msg_Dbg( p_sout, "adding input" );
165     p_input->p_mux_data = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
166
167     p_stream->i_pid = AllocatePID( p_mux );
168     if( p_mux->i_pcr_pid == 0x1fff )
169     {
170         p_mux->i_pcr_pid = p_stream->i_pid;
171     }
172     p_stream->i_continuity_counter = 0;
173
174     switch( p_input->input_format.i_cat )
175     {
176         case VIDEO_ES:
177             switch( p_input->input_format.i_fourcc )
178             {
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++;
183                     break;
184                 case VLC_FOURCC( 'm', 'p','4', 'v' ):
185                     p_stream->i_stream_type = 0x10;
186                     p_stream->i_stream_id = 0xfa;
187                     break;
188                 default:
189                     return( -1 );
190             }
191             p_mux->i_video_bound++;
192
193             break;
194         case AUDIO_ES:
195             switch( p_input->input_format.i_fourcc )
196             {
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++;
202                     break;
203 #if 0
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++;
208                     break;
209 #endif
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++;
214                     break;
215                 default:
216                     return( -1 );
217             }
218             p_mux->i_audio_bound++;
219             break;
220         default:
221             return( -1 );
222     }
223
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;
227
228     return( 0 );
229 }
230
231 static int DelStream( sout_instance_t *p_sout, sout_input_t *p_input )
232 {
233     sout_mux_t          *p_mux = (sout_mux_t*)p_sout->p_mux_data;
234
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;
239
240     return( 0 );
241 }
242
243
244
245 static int MuxGetStream( sout_instance_t *p_sout,
246                          int        *pi_stream,
247                          mtime_t    *pi_dts )
248 {
249     mtime_t i_dts;
250     int     i_stream;
251     int     i;
252
253     for( i = 0, i_dts = 0, i_stream = -1; i < p_sout->i_nb_inputs; i++ )
254     {
255         sout_fifo_t  *p_fifo;
256
257         p_fifo = p_sout->pp_inputs[i]->p_fifo;
258
259         if( p_fifo->i_depth > 1 )
260         {
261             sout_buffer_t *p_buf;
262
263             p_buf = sout_FifoShow( p_fifo );
264             if( i_stream < 0 || p_buf->i_dts < i_dts )
265             {
266                 i_dts = p_buf->i_dts;
267                 i_stream = i;
268             }
269         }
270         else
271         {
272             return( -1 ); // wait that all fifo have at least 2 packets
273         }
274     }
275
276     if( pi_stream )
277     {
278         *pi_stream = i_stream;
279     }
280     if( pi_dts )
281     {
282         *pi_dts = i_dts;
283     }
284
285     return( i_stream );
286 }
287
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 )
291 {
292     int i_size;
293     sout_buffer_t *p_last_buffer = NULL;
294     uint8_t       *p_data;
295     int i_first;
296     mtime_t       i_dts;
297     int         b_new_pes;
298     /* get PES total size */
299     i_size = p_pes->i_size;
300     p_data = p_pes->p_buffer;
301
302     if( p_pes->i_dts == 0 && p_pes->i_length > 0 )
303     {
304         i_dts = 1; // XXX <french> kludge immonde </french>
305     }
306     else
307     {
308         i_dts = p_pes->i_dts;
309     }
310
311     for( i_first = 1, b_new_pes = 1; p_pes != NULL; )
312     {
313         int           i_adaptation_field;
314         int           i_payload;
315         int           i_copy;
316         bits_buffer_t bits;
317         sout_buffer_t *p_ts;
318
319         p_ts = sout_BufferNew( p_sout, 188 );
320
321         p_ts->i_pts = 0;
322         p_ts->i_dts = i_dts;
323
324
325         i_payload = 184 - ( i_first && i_dts > 0 ? 8 : 0 );
326         i_copy = __MIN( i_size, i_payload );
327
328         i_adaptation_field = ( ( i_first && i_dts > 0 ) || 
329                                i_size < i_payload ) ? 1 : 0;
330
331         /* write headers */
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 */
336         b_new_pes = 0;
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 ) );
341
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 )
347         {
348             int i;
349             int i_stuffing;
350
351             if( i_first && i_dts > 0 )
352             {
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 */
360             }
361             else
362             {
363                 i_stuffing = i_payload - i_copy;
364                 bits_write( &bits, 8, i_stuffing - 1);
365                 if( i_stuffing - 1 > 0 )
366                 {
367                     bits_write( &bits, 8, 0 );
368                 }
369                 i_stuffing -= 2;
370             }
371
372             /* put stuffing */
373             for( i = 0; i < i_stuffing; i++ )
374             {
375                 bits_write( &bits, 8, 0xff );
376             }
377         }
378         /* copy payload */
379         memcpy( p_ts->p_buffer + bits.i_data,
380                 p_data,
381                 i_copy );
382         p_data += i_copy;
383         i_size -= i_copy;
384
385         /* chain buffers */
386         if( i_first )
387         {
388             *pp_ts        = p_ts;
389             p_last_buffer = p_ts;
390         }
391         else
392         {
393             p_last_buffer->p_next = p_ts;
394             p_last_buffer         = p_ts;
395         }
396         i_first = 0;
397
398         if( i_size <= 0 )
399         {
400             sout_buffer_t *p_next;
401
402             p_next = p_pes->p_next;
403             p_pes->p_next = NULL;
404             sout_BufferDelete( p_sout, p_pes );
405             p_pes = p_next;
406             b_new_pes = 1;
407             if( p_pes )
408             {
409                 i_size = p_pes->i_size;
410                 p_data = p_pes->p_buffer;
411             }
412             else
413             {
414                 break;
415             }
416         }
417     }
418
419     return 0;
420 }
421
422 static int GetPAT( sout_instance_t *p_sout,
423                    sout_buffer_t **pp_ts )
424 {
425     sout_mux_t          *p_mux = (sout_mux_t*)p_sout->p_mux_data;
426     sout_buffer_t       *p_pat;
427     bits_buffer_t bits;
428
429     p_pat = sout_BufferNew( p_sout, 1024 );
430
431     p_pat->i_pts = 0;
432     p_pat->i_dts = 0;
433     p_pat->i_length = 0;
434
435     bits_initwrite( &bits, 1024, p_pat->p_buffer );
436
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
449
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
453
454     bits_write( &bits, 32, 0 );     // FIXME FIXME FIXME
455
456     p_pat->i_size = bits.i_data;
457
458     return( PEStoTS( p_sout, pp_ts, p_pat, &p_mux->pat ) );
459 }
460
461 static int GetPMT( sout_instance_t *p_sout,
462                    sout_buffer_t **pp_ts )
463 {
464     sout_mux_t          *p_mux = (sout_mux_t*)p_sout->p_mux_data;
465     sout_buffer_t       *p_pmt;
466     bits_buffer_t bits;
467     int           i_stream;
468
469     p_pmt = sout_BufferNew( p_sout, 1024 );
470
471     p_pmt->i_pts = 0;
472     p_pmt->i_dts = 0;
473     p_pmt->i_length = 0;
474
475     bits_initwrite( &bits, 1024, p_pmt->p_buffer );
476
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
489
490     bits_write( &bits,  3, 0 );     // reserved
491
492     bits_write( &bits, 13, p_mux->i_pcr_pid );     //  FIXME FXIME PCR_PID FIXME
493     bits_write( &bits,  4, 0 );     // reserved FIXME
494
495     bits_write( &bits, 12, 0 );    // program info len FIXME
496
497     for( i_stream = 0; i_stream < p_sout->i_nb_inputs; i_stream++ )
498     {
499         ts_stream_t *p_stream;
500
501         p_stream = (ts_stream_t*)p_sout->pp_inputs[i_stream]->p_mux_data;
502
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
508     }
509
510     bits_write( &bits, 32, 0 );     // FIXME FIXME FIXME
511
512     p_pmt->i_size = bits.i_data;
513
514     return( PEStoTS( p_sout, pp_ts, p_pmt, &p_mux->pmt ) );
515
516 }
517
518 static void SetTSDate( sout_buffer_t *p_ts, mtime_t i_dts, mtime_t i_length )
519 {
520     int i_count;
521     sout_buffer_t *p_tmp;
522     mtime_t i_delta;
523
524     for( p_tmp = p_ts, i_count = 0; p_tmp != NULL; p_tmp = p_tmp->p_next )
525     {
526         i_count++;
527     }
528     i_delta = i_length / i_count;
529
530     for( p_tmp = p_ts; p_tmp != NULL; p_tmp = p_tmp->p_next )
531     {
532         p_tmp->i_dts    = i_dts;
533         p_tmp->i_length = i_delta;
534
535         i_dts += i_delta;
536     }
537 }
538
539 static int Mux( sout_instance_t *p_sout )
540 {
541     sout_mux_t          *p_mux = (sout_mux_t*)p_sout->p_mux_data;
542     int     i_stream;
543
544     sout_buffer_t *p_pat, *p_pmt, *p_ts;
545
546     for( ;; )
547     {
548         mtime_t i_dts, i_length;
549
550         sout_input_t *p_input;
551         ts_stream_t *p_stream;
552         sout_fifo_t  *p_fifo;
553         sout_buffer_t *p_data;
554
555         if( MuxGetStream( p_sout, &i_stream, &i_dts ) < 0 )
556         {
557             return( 0 );
558         }
559
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;
563
564         p_data   = sout_FifoGet( p_fifo );
565         i_dts    = p_data->i_dts;
566         i_length = p_data->i_length;
567
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 );
570
571         if( p_mux->i_ts_packet % 30 == 0 )
572         {
573             /* create pat/pmt */
574             GetPAT( p_sout, &p_pat );
575             GetPMT( p_sout, &p_pmt );
576
577             p_ts = p_pat;
578             p_pat->p_next = p_pmt;
579             p_pmt->p_next = p_data;
580         }
581         else
582         {
583             p_pat = NULL;
584             p_pmt = NULL;
585             p_ts = p_data;
586         }
587
588         p_mux->i_ts_packet++;
589         SetTSDate( p_ts, i_dts, i_length );
590
591         p_sout->pf_write( p_sout, p_ts );
592     }
593
594     return( 0 );
595 }
596
597