]> git.sesse.net Git - vlc/blob - modules/mux/mpeg/tables.c
dash: fix invalid C++11 suffix literals
[vlc] / modules / mux / mpeg / tables.c
1 /*****************************************************************************
2  * tables.c
3  *****************************************************************************
4  * Copyright (C) 2001-2005, 2015 VLC authors and VideoLAN
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23
24 #include <vlc_common.h>
25 #include <vlc_block.h>
26 #include <vlc_fourcc.h>
27 #include <vlc_es.h>
28
29 # include <dvbpsi/dvbpsi.h>
30 # include <dvbpsi/demux.h>
31 # include <dvbpsi/descriptor.h>
32 # include <dvbpsi/pat.h>
33 # include <dvbpsi/pmt.h>
34 # include <dvbpsi/sdt.h>
35 # include <dvbpsi/dr.h>
36 # include <dvbpsi/psi.h>
37
38 #include "dvbpsi_compat.h"
39
40 #include "streams.h"
41 #include "tsutil.h"
42 #include "tables.h"
43 #include "bits.h"
44
45 block_t *WritePSISection( dvbpsi_psi_section_t* p_section )
46 {
47     block_t   *p_psi, *p_first = NULL;
48
49     while( p_section )
50     {
51         int i_size = (uint32_t)(p_section->p_payload_end - p_section->p_data) +
52                   (p_section->b_syntax_indicator ? 4 : 0);
53
54         p_psi = block_Alloc( i_size + 1 );
55         if( !p_psi )
56             goto error;
57         p_psi->i_pts = 0;
58         p_psi->i_dts = 0;
59         p_psi->i_length = 0;
60         p_psi->i_buffer = i_size + 1;
61
62         p_psi->p_buffer[0] = 0; /* pointer */
63         memcpy( p_psi->p_buffer + 1,
64                 p_section->p_data,
65                 i_size );
66
67         block_ChainAppend( &p_first, p_psi );
68
69         p_section = p_section->p_next;
70     }
71
72     return( p_first );
73
74 error:
75     if( p_first )
76         block_ChainRelease( p_first );
77     return NULL;
78 }
79
80 void BuildPAT( DVBPSI_HANDLE_PARAM(dvbpsi_t *p_dvbpsi)
81                void *p_opaque, PEStoTSCallback pf_callback,
82                int i_tsid, int i_pat_version_number,
83                ts_stream_t *p_pat,
84                unsigned i_programs, ts_stream_t *p_pmt, const int *pi_programs_number )
85 {
86     dvbpsi_pat_t         patpsi;
87     dvbpsi_psi_section_t *p_section;
88
89     dvbpsi_InitPAT( &patpsi, i_tsid, i_pat_version_number, 1 /* b_current_next */ );
90     /* add all programs */
91     for (unsigned i = 0; i < i_programs; i++ )
92         dvbpsi_PATAddProgram( &patpsi, pi_programs_number[i], p_pmt[i].i_pid );
93
94 #if (DVBPSI_VERSION_INT >= DVBPSI_VERSION_WANTED(1,0,0))
95     p_section = dvbpsi_pat_sections_generate( p_dvbpsi, &patpsi, 0 );
96 #else
97     p_section = dvbpsi_GenPATSections( &pat, 0 /* max program per section */ );
98 #endif
99     block_t *p_block = WritePSISection( p_section );
100
101     PEStoTS( p_opaque, pf_callback, p_block, p_pat->i_pid,
102              &p_pat->b_discontinuity, &p_pat->i_continuity_counter );
103
104     dvbpsi_DeletePSISections( p_section );
105     dvbpsi_EmptyPAT( &patpsi );
106 }
107 #if 1
108
109 static uint32_t GetDescriptorLength24b( int i_length )
110 {
111     uint32_t i_l1, i_l2, i_l3;
112
113     i_l1 = i_length&0x7f;
114     i_l2 = ( i_length >> 7 )&0x7f;
115     i_l3 = ( i_length >> 14 )&0x7f;
116
117     return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
118 }
119
120 static void GetPMTmpeg4( vlc_object_t *p_object, dvbpsi_pmt_t *p_dvbpmt,
121                          unsigned i_mapped_streams, const pes_mapped_stream_t *p_mapped_streams )
122 {
123     uint8_t iod[4096];
124     bits_buffer_t bits, bits_fix_IOD;
125
126     /* Make valgrind happy : it works at byte level not bit one so
127      * bit_write confuse it (but DON'T CHANGE the way that bit_write is
128      * working (needed when fixing some bits) */
129     memset( iod, 0, 4096 );
130
131     bits_initwrite( &bits, 4096, iod );
132     /* IOD_label_scope */
133     bits_write( &bits, 8,   0x11 );
134     /* IOD_label */
135     bits_write( &bits, 8,   0x01 );
136     /* InitialObjectDescriptor */
137     bits_align( &bits );
138     bits_write( &bits, 8,   0x02 );     /* tag */
139     bits_fix_IOD = bits;    /* save states to fix length later */
140     bits_write( &bits, 24,
141         GetDescriptorLength24b( 0 ) );  /* variable length (fixed later) */
142     bits_write( &bits, 10,  0x01 );     /* ObjectDescriptorID */
143     bits_write( &bits, 1,   0x00 );     /* URL Flag */
144     bits_write( &bits, 1,   0x00 );     /* includeInlineProfileLevelFlag */
145     bits_write( &bits, 4,   0x0f );     /* reserved */
146     bits_write( &bits, 8,   0xff );     /* ODProfile (no ODcapability ) */
147     bits_write( &bits, 8,   0xff );     /* sceneProfile */
148     bits_write( &bits, 8,   0xfe );     /* audioProfile (unspecified) */
149     bits_write( &bits, 8,   0xfe );     /* visualProfile( // ) */
150     bits_write( &bits, 8,   0xff );     /* graphicProfile (no ) */
151     for (unsigned i = 0; i < i_mapped_streams; i++ )
152     {
153         const pes_mapped_stream_t *p_stream = &p_mapped_streams[i];
154
155         if( p_stream->pes->i_stream_id != 0xfa && p_stream->pes->i_stream_id != 0xfb &&
156             p_stream->pes->i_stream_id != 0xfe )
157             continue;
158
159         bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
160         /* ES descriptor */
161         bits_align( &bits );
162         bits_write( &bits, 8,   0x03 );     /* ES_DescrTag */
163         bits_fix_ESDescr = bits;
164         bits_write( &bits, 24,
165                     GetDescriptorLength24b( 0 ) ); /* variable size */
166         bits_write( &bits, 16,  p_stream->pes->i_es_id );
167         bits_write( &bits, 1,   0x00 );     /* streamDependency */
168         bits_write( &bits, 1,   0x00 );     /* URL Flag */
169         bits_write( &bits, 1,   0x00 );     /* OCRStreamFlag */
170         bits_write( &bits, 5,   0x1f );     /* streamPriority */
171
172         /* DecoderConfigDesciptor */
173         bits_align( &bits );
174         bits_write( &bits, 8,   0x04 ); /* DecoderConfigDescrTag */
175         bits_fix_Decoder = bits;
176         bits_write( &bits, 24,  GetDescriptorLength24b( 0 ) );
177         if( p_stream->pes->i_stream_type == 0x10 )
178         {
179             bits_write( &bits, 8, 0x20 );   /* Visual 14496-2 */
180             bits_write( &bits, 6, 0x04 );   /* VisualStream */
181         }
182         else if( p_stream->pes->i_stream_type == 0x1b )
183         {
184             bits_write( &bits, 8, 0x21 );   /* Visual 14496-2 */
185             bits_write( &bits, 6, 0x04 );   /* VisualStream */
186         }
187         else if( p_stream->pes->i_stream_type == 0x11 ||
188                  p_stream->pes->i_stream_type == 0x0f )
189         {
190             bits_write( &bits, 8, 0x40 );   /* Audio 14496-3 */
191             bits_write( &bits, 6, 0x05 );   /* AudioStream */
192         }
193         else if( p_stream->pes->i_stream_type == 0x12 &&
194                  p_stream->pes->i_codec == VLC_CODEC_SUBT )
195         {
196             bits_write( &bits, 8, 0x0B );   /* Text Stream */
197             bits_write( &bits, 6, 0x04 );   /* VisualStream */
198         }
199         else
200         {
201             bits_write( &bits, 8, 0x00 );
202             bits_write( &bits, 6, 0x00 );
203
204             msg_Err( p_object, "Unsupported stream_type => broken IOD" );
205         }
206         bits_write( &bits, 1,   0x00 );         /* UpStream */
207         bits_write( &bits, 1,   0x01 );         /* reserved */
208         bits_write( &bits, 24,  1024 * 1024 );  /* bufferSizeDB */
209         bits_write( &bits, 32,  0x7fffffff );   /* maxBitrate */
210         bits_write( &bits, 32,  0 );            /* avgBitrate */
211
212         if( p_stream->pes->i_extra > 0 )
213         {
214             /* DecoderSpecificInfo */
215             bits_align( &bits );
216             bits_write( &bits, 8,   0x05 ); /* tag */
217             bits_write( &bits, 24, GetDescriptorLength24b(
218                         p_stream->pes->i_extra ) );
219             for (int j = 0; j < p_stream->pes->i_extra; j++ )
220             {
221                 bits_write( &bits, 8,
222                     ((uint8_t*)p_stream->pes->p_extra)[j] );
223             }
224         }
225         /* fix Decoder length */
226         bits_write( &bits_fix_Decoder, 24,
227                     GetDescriptorLength24b( bits.i_data -
228                     bits_fix_Decoder.i_data - 3 ) );
229
230         /* SLConfigDescriptor : predefined (0x01) */
231         bits_align( &bits );
232         bits_write( &bits, 8,   0x06 ); /* tag */
233         bits_write( &bits, 24,  GetDescriptorLength24b( 8 ) );
234         bits_write( &bits, 8,   0x01 );/* predefined */
235         bits_write( &bits, 1,   0 );   /* durationFlag */
236         bits_write( &bits, 32,  0 );   /* OCRResolution */
237         bits_write( &bits, 8,   0 );   /* OCRLength */
238         bits_write( &bits, 8,   0 );   /* InstantBitrateLength */
239         bits_align( &bits );
240
241         /* fix ESDescr length */
242         bits_write( &bits_fix_ESDescr, 24,
243                     GetDescriptorLength24b( bits.i_data -
244                     bits_fix_ESDescr.i_data - 3 ) );
245     }
246     bits_align( &bits );
247     /* fix IOD length */
248     bits_write( &bits_fix_IOD, 24,
249                 GetDescriptorLength24b(bits.i_data - bits_fix_IOD.i_data - 3 ));
250
251     dvbpsi_PMTAddDescriptor(&p_dvbpmt[0], 0x1d, bits.i_data, bits.p_data);
252 }
253
254 void BuildPMT( DVBPSI_HANDLE_PARAM(dvbpsi_t *p_dvbpsi) vlc_object_t *p_object,
255                void *p_opaque, PEStoTSCallback pf_callback,
256                int i_tsid, int i_pmt_version_number,
257                int i_pcr_pid,
258                sdt_psi_t *p_sdt,
259                unsigned i_programs, ts_stream_t *p_pmt, const int *pi_programs_number,
260                unsigned i_mapped_streams, const pes_mapped_stream_t *p_mapped_streams )
261 {
262     dvbpsi_pmt_t *dvbpmt = malloc( i_programs * sizeof(dvbpsi_pmt_t) );
263     if( !dvbpmt )
264             return;
265
266     dvbpsi_sdt_t sdtpsi;
267     if( p_sdt )
268         dvbpsi_InitSDT( &sdtpsi, i_tsid, 1, 1, p_sdt->i_netid );
269
270     for (unsigned i = 0; i < i_programs; i++ )
271     {
272         dvbpsi_InitPMT( &dvbpmt[i],
273                         pi_programs_number[i],   /* program number */
274                         i_pmt_version_number,
275                         1,      /* b_current_next */
276                         i_pcr_pid );
277
278         if( !p_sdt )
279             continue;
280
281         dvbpsi_sdt_service_t *p_service = dvbpsi_SDTAddService( &sdtpsi,
282             pi_programs_number[i],  /* service id */
283             0,         /* eit schedule */
284             0,         /* eit present */
285             4,         /* running status ("4=RUNNING") */
286             0 );       /* free ca */
287
288         const char *psz_sdtprov = p_sdt->desc[i].psz_provider;
289         const char *psz_sdtserv = p_sdt->desc[i].psz_service_name;
290
291         if( !psz_sdtprov || !psz_sdtserv )
292             continue;
293         size_t provlen = VLC_CLIP(strlen(psz_sdtprov), 0, 255);
294         size_t servlen = VLC_CLIP(strlen(psz_sdtserv), 0, 255);
295
296         uint8_t psz_sdt_desc[3 + provlen + servlen];
297
298         psz_sdt_desc[0] = 0x01; /* digital television service */
299
300         /* service provider name length */
301         psz_sdt_desc[1] = (char)provlen;
302         memcpy( &psz_sdt_desc[2], psz_sdtprov, provlen );
303
304         /* service name length */
305         psz_sdt_desc[ 2 + provlen ] = (char)servlen;
306         memcpy( &psz_sdt_desc[3+provlen], psz_sdtserv, servlen );
307
308 #if (DVBPSI_VERSION_INT >= DVBPSI_VERSION_WANTED(1,0,0))
309         dvbpsi_sdt_service_descriptor_add( p_service, 0x48,
310                                            (3 + provlen + servlen),
311                                            psz_sdt_desc );
312 #else
313         dvbpsi_SDTServiceAddDescriptor( p_service, 0x48,
314                 3 + provlen + servlen, psz_sdt_desc );
315 #endif
316     }
317
318     for (unsigned i = 0; i < i_mapped_streams; i++ )
319     {
320         const pes_mapped_stream_t *p_stream = &p_mapped_streams[i];
321         if( p_stream->pes->i_stream_id == 0xfa ||
322             p_stream->pes->i_stream_id == 0xfb ||
323             p_stream->pes->i_stream_id == 0xfe )
324         {
325             /* Has at least 1 MPEG4 stream */
326             GetPMTmpeg4( p_object, dvbpmt, i_mapped_streams, p_mapped_streams );
327             break;
328         }
329     }
330
331     for (unsigned i = 0; i < i_mapped_streams; i++ )
332     {
333         const pes_mapped_stream_t *p_stream = &p_mapped_streams[i];
334
335         dvbpsi_pmt_es_t *p_es = dvbpsi_PMTAddES( &dvbpmt[p_stream->i_mapped_prog],
336                     p_stream->pes->i_stream_type, p_stream->ts->i_pid );
337
338         if( p_stream->pes->i_stream_id == 0xfa || p_stream->pes->i_stream_id == 0xfb )
339         {
340             uint8_t     es_id[2];
341
342             /* SL descriptor */
343             es_id[0] = (p_stream->pes->i_es_id >> 8)&0xff;
344             es_id[1] = (p_stream->pes->i_es_id)&0xff;
345             dvbpsi_PMTESAddDescriptor( p_es, 0x1f, 2, es_id );
346         }
347         else if( p_stream->pes->i_stream_type == 0xa0 )
348         {
349             uint8_t data[512];
350             int i_extra = __MIN( p_stream->pes->i_extra, 502 );
351
352             /* private DIV3 descripor */
353             memcpy( &data[0], &p_stream->pes->i_bih_codec, 4 );
354             data[4] = ( p_stream->pes->i_bih_width >> 8 )&0xff;
355             data[5] = ( p_stream->pes->i_bih_width      )&0xff;
356             data[6] = ( p_stream->pes->i_bih_height>> 8 )&0xff;
357             data[7] = ( p_stream->pes->i_bih_height     )&0xff;
358             data[8] = ( i_extra >> 8 )&0xff;
359             data[9] = ( i_extra      )&0xff;
360             if( i_extra > 0 )
361             {
362                 memcpy( &data[10], p_stream->pes->p_extra, i_extra );
363             }
364
365             /* 0xa0 is private */
366             dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
367         }
368         else if( p_stream->pes->i_stream_type == 0x81 )
369         {
370             uint8_t format[4] = { 'A', 'C', '-', '3'};
371
372             /* "registration" descriptor : "AC-3" */
373             dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
374         }
375         else if( p_stream->pes->i_codec == VLC_CODEC_DIRAC )
376         {
377             /* Dirac registration descriptor */
378
379             uint8_t data[4] = { 'd', 'r', 'a', 'c' };
380             dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, data );
381         }
382         else if( p_stream->pes->i_codec == VLC_CODEC_DTS )
383         {
384             /* DTS registration descriptor (ETSI TS 101 154 Annex F) */
385
386             /* DTS format identifier, frame size 1024 - FIXME */
387             uint8_t data[4] = { 'D', 'T', 'S', '2' };
388             dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, data );
389         }
390         else if( p_stream->pes->i_codec == VLC_CODEC_EAC3 )
391         {
392             uint8_t data[1] = { 0x00 };
393             dvbpsi_PMTESAddDescriptor( p_es, 0x7a, 1, data );
394         }
395         else if( p_stream->pes->i_codec == VLC_CODEC_OPUS )
396         {
397             uint8_t data[2] = {
398                 0x80, /* tag extension */
399                 p_stream->fmt->audio.i_channels
400             };
401             dvbpsi_PMTESAddDescriptor( p_es, 0x7f, 2, data );
402             uint8_t format[4] = { 'O', 'p', 'u', 's'};
403             /* "registration" descriptor : "Opus" */
404             dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
405         }
406         else if( p_stream->pes->i_codec == VLC_CODEC_TELETEXT )
407         {
408             if( p_stream->pes->i_extra )
409             {
410                 dvbpsi_PMTESAddDescriptor( p_es, 0x56,
411                                            p_stream->pes->i_extra,
412                                            p_stream->pes->p_extra );
413             }
414             continue;
415         }
416         else if( p_stream->pes->i_codec == VLC_CODEC_DVBS )
417         {
418             /* DVB subtitles */
419             if( p_stream->pes->i_extra )
420             {
421                 /* pass-through from the TS demux */
422                 dvbpsi_PMTESAddDescriptor( p_es, 0x59,
423                                            p_stream->pes->i_extra,
424                                            p_stream->pes->p_extra );
425             }
426             else
427             {
428                 /* from the dvbsub transcoder */
429                 dvbpsi_subtitling_dr_t descr;
430                 dvbpsi_subtitle_t sub;
431                 dvbpsi_descriptor_t *p_descr;
432
433                 memcpy( sub.i_iso6392_language_code, p_stream->pes->lang, 3 );
434                 sub.i_subtitling_type = 0x10; /* no aspect-ratio criticality */
435                 sub.i_composition_page_id = p_stream->pes->i_es_id & 0xFF;
436                 sub.i_ancillary_page_id = p_stream->pes->i_es_id >> 16;
437
438                 descr.i_subtitles_number = 1;
439                 descr.p_subtitle[0] = sub;
440
441                 p_descr = dvbpsi_GenSubtitlingDr( &descr, 0 );
442                 /* Work around bug in old libdvbpsi */ p_descr->i_length = 8;
443                 dvbpsi_PMTESAddDescriptor( p_es, p_descr->i_tag,
444                                            p_descr->i_length, p_descr->p_data );
445             }
446             continue;
447         }
448
449         if( p_stream->pes->i_langs )
450         {
451             dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4*p_stream->pes->i_langs,
452                 p_stream->pes->lang);
453         }
454     }
455
456     for (unsigned i = 0; i < i_programs; i++ )
457     {
458         dvbpsi_psi_section_t *sect;
459 #if (DVBPSI_VERSION_INT >= DVBPSI_VERSION_WANTED(1,0,0))
460         sect = dvbpsi_pmt_sections_generate( p_dvbpsi, &dvbpmt[i] );
461 #else
462         sect = dvbpsi_GenPMTSections( &dvbpmt[i] );
463 #endif
464         block_t *pmt = WritePSISection( sect );
465         PEStoTS( p_opaque, pf_callback, pmt, p_pmt[i].i_pid,
466                  &p_pmt[i].b_discontinuity, &p_pmt[i].i_continuity_counter );
467         dvbpsi_DeletePSISections(sect);
468         dvbpsi_EmptyPMT( &dvbpmt[i] );
469     }
470
471     if( p_sdt )
472     {
473         dvbpsi_psi_section_t *sect;
474 #if (DVBPSI_VERSION_INT >= DVBPSI_VERSION_WANTED(1,0,0))
475         sect = dvbpsi_sdt_sections_generate( p_dvbpsi, &sdtpsi );
476 #else
477         sect = dvbpsi_GenSDTSections( &sdt );
478 #endif
479         block_t *p_sdtblock = WritePSISection( sect );
480         PEStoTS( p_opaque, pf_callback, p_sdtblock, p_sdt->ts.i_pid,
481                  &p_sdt->ts.b_discontinuity, &p_sdt->ts.i_continuity_counter );
482         dvbpsi_DeletePSISections( sect );
483         dvbpsi_EmptySDT( &sdtpsi );
484     }
485 }
486
487
488 #endif