1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2001-2005, 2015 VLC authors and VideoLAN
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.
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.
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 *****************************************************************************/
24 #include <vlc_common.h>
25 #include <vlc_block.h>
26 #include <vlc_fourcc.h>
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>
38 #include "dvbpsi_compat.h"
45 block_t *WritePSISection( dvbpsi_psi_section_t* p_section )
47 block_t *p_psi, *p_first = NULL;
51 int i_size = (uint32_t)(p_section->p_payload_end - p_section->p_data) +
52 (p_section->b_syntax_indicator ? 4 : 0);
54 p_psi = block_Alloc( i_size + 1 );
60 p_psi->i_buffer = i_size + 1;
62 p_psi->p_buffer[0] = 0; /* pointer */
63 memcpy( p_psi->p_buffer + 1,
67 block_ChainAppend( &p_first, p_psi );
69 p_section = p_section->p_next;
76 block_ChainRelease( p_first );
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,
84 unsigned i_programs, ts_stream_t *p_pmt, const int *pi_programs_number )
87 dvbpsi_psi_section_t *p_section;
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 );
94 #if (DVBPSI_VERSION_INT >= DVBPSI_VERSION_WANTED(1,0,0))
95 p_section = dvbpsi_pat_sections_generate( p_dvbpsi, &patpsi, 0 );
97 p_section = dvbpsi_GenPATSections( &pat, 0 /* max program per section */ );
99 block_t *p_block = WritePSISection( p_section );
101 PEStoTS( p_opaque, pf_callback, p_block, p_pat->i_pid,
102 &p_pat->b_discontinuity, &p_pat->i_continuity_counter );
104 dvbpsi_DeletePSISections( p_section );
105 dvbpsi_EmptyPAT( &patpsi );
109 static uint32_t GetDescriptorLength24b( int i_length )
111 uint32_t i_l1, i_l2, i_l3;
113 i_l1 = i_length&0x7f;
114 i_l2 = ( i_length >> 7 )&0x7f;
115 i_l3 = ( i_length >> 14 )&0x7f;
117 return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
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 )
124 bits_buffer_t bits, bits_fix_IOD;
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 );
131 bits_initwrite( &bits, 4096, iod );
132 /* IOD_label_scope */
133 bits_write( &bits, 8, 0x11 );
135 bits_write( &bits, 8, 0x01 );
136 /* InitialObjectDescriptor */
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++ )
153 const pes_mapped_stream_t *p_stream = &p_mapped_streams[i];
155 if( p_stream->pes->i_stream_id != 0xfa && p_stream->pes->i_stream_id != 0xfb &&
156 p_stream->pes->i_stream_id != 0xfe )
159 bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
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 */
172 /* DecoderConfigDesciptor */
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 )
179 bits_write( &bits, 8, 0x20 ); /* Visual 14496-2 */
180 bits_write( &bits, 6, 0x04 ); /* VisualStream */
182 else if( p_stream->pes->i_stream_type == 0x1b )
184 bits_write( &bits, 8, 0x21 ); /* Visual 14496-2 */
185 bits_write( &bits, 6, 0x04 ); /* VisualStream */
187 else if( p_stream->pes->i_stream_type == 0x11 ||
188 p_stream->pes->i_stream_type == 0x0f )
190 bits_write( &bits, 8, 0x40 ); /* Audio 14496-3 */
191 bits_write( &bits, 6, 0x05 ); /* AudioStream */
193 else if( p_stream->pes->i_stream_type == 0x12 &&
194 p_stream->pes->i_codec == VLC_CODEC_SUBT )
196 bits_write( &bits, 8, 0x0B ); /* Text Stream */
197 bits_write( &bits, 6, 0x04 ); /* VisualStream */
201 bits_write( &bits, 8, 0x00 );
202 bits_write( &bits, 6, 0x00 );
204 msg_Err( p_object, "Unsupported stream_type => broken IOD" );
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 */
212 if( p_stream->pes->i_extra > 0 )
214 /* DecoderSpecificInfo */
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++ )
221 bits_write( &bits, 8,
222 ((uint8_t*)p_stream->pes->p_extra)[j] );
225 /* fix Decoder length */
226 bits_write( &bits_fix_Decoder, 24,
227 GetDescriptorLength24b( bits.i_data -
228 bits_fix_Decoder.i_data - 3 ) );
230 /* SLConfigDescriptor : predefined (0x01) */
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 */
241 /* fix ESDescr length */
242 bits_write( &bits_fix_ESDescr, 24,
243 GetDescriptorLength24b( bits.i_data -
244 bits_fix_ESDescr.i_data - 3 ) );
248 bits_write( &bits_fix_IOD, 24,
249 GetDescriptorLength24b(bits.i_data - bits_fix_IOD.i_data - 3 ));
251 dvbpsi_PMTAddDescriptor(&p_dvbpmt[0], 0x1d, bits.i_data, bits.p_data);
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,
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 )
262 dvbpsi_pmt_t *dvbpmt = malloc( i_programs * sizeof(dvbpsi_pmt_t) );
268 dvbpsi_InitSDT( &sdtpsi, i_tsid, 1, 1, p_sdt->i_netid );
270 for (unsigned i = 0; i < i_programs; i++ )
272 dvbpsi_InitPMT( &dvbpmt[i],
273 pi_programs_number[i], /* program number */
274 i_pmt_version_number,
275 1, /* b_current_next */
281 dvbpsi_sdt_service_t *p_service = dvbpsi_SDTAddService( &sdtpsi,
282 pi_programs_number[i], /* service id */
283 0, /* eit schedule */
285 4, /* running status ("4=RUNNING") */
288 const char *psz_sdtprov = p_sdt->desc[i].psz_provider;
289 const char *psz_sdtserv = p_sdt->desc[i].psz_service_name;
291 if( !psz_sdtprov || !psz_sdtserv )
293 size_t provlen = VLC_CLIP(strlen(psz_sdtprov), 0, 255);
294 size_t servlen = VLC_CLIP(strlen(psz_sdtserv), 0, 255);
296 uint8_t psz_sdt_desc[3 + provlen + servlen];
298 psz_sdt_desc[0] = 0x01; /* digital television service */
300 /* service provider name length */
301 psz_sdt_desc[1] = (char)provlen;
302 memcpy( &psz_sdt_desc[2], psz_sdtprov, provlen );
304 /* service name length */
305 psz_sdt_desc[ 2 + provlen ] = (char)servlen;
306 memcpy( &psz_sdt_desc[3+provlen], psz_sdtserv, servlen );
308 #if (DVBPSI_VERSION_INT >= DVBPSI_VERSION_WANTED(1,0,0))
309 dvbpsi_sdt_service_descriptor_add( p_service, 0x48,
310 (3 + provlen + servlen),
313 dvbpsi_SDTServiceAddDescriptor( p_service, 0x48,
314 3 + provlen + servlen, psz_sdt_desc );
318 for (unsigned i = 0; i < i_mapped_streams; i++ )
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 )
325 /* Has at least 1 MPEG4 stream */
326 GetPMTmpeg4( p_object, dvbpmt, i_mapped_streams, p_mapped_streams );
331 for (unsigned i = 0; i < i_mapped_streams; i++ )
333 const pes_mapped_stream_t *p_stream = &p_mapped_streams[i];
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 );
338 if( p_stream->pes->i_stream_id == 0xfa || p_stream->pes->i_stream_id == 0xfb )
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 );
347 else if( p_stream->pes->i_stream_type == 0xa0 )
350 int i_extra = __MIN( p_stream->pes->i_extra, 502 );
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;
362 memcpy( &data[10], p_stream->pes->p_extra, i_extra );
365 /* 0xa0 is private */
366 dvbpsi_PMTESAddDescriptor( p_es, 0xa0, i_extra + 10, data );
368 else if( p_stream->pes->i_stream_type == 0x81 )
370 uint8_t format[4] = { 'A', 'C', '-', '3'};
372 /* "registration" descriptor : "AC-3" */
373 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, format );
375 else if( p_stream->pes->i_codec == VLC_CODEC_DIRAC )
377 /* Dirac registration descriptor */
379 uint8_t data[4] = { 'd', 'r', 'a', 'c' };
380 dvbpsi_PMTESAddDescriptor( p_es, 0x05, 4, data );
382 else if( p_stream->pes->i_codec == VLC_CODEC_DTS )
384 /* DTS registration descriptor (ETSI TS 101 154 Annex F) */
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 );
390 else if( p_stream->pes->i_codec == VLC_CODEC_EAC3 )
392 uint8_t data[1] = { 0x00 };
393 dvbpsi_PMTESAddDescriptor( p_es, 0x7a, 1, data );
395 else if( p_stream->pes->i_codec == VLC_CODEC_OPUS )
398 0x80, /* tag extension */
399 p_stream->fmt->audio.i_channels
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 );
406 else if( p_stream->pes->i_codec == VLC_CODEC_TELETEXT )
408 if( p_stream->pes->i_extra )
410 dvbpsi_PMTESAddDescriptor( p_es, 0x56,
411 p_stream->pes->i_extra,
412 p_stream->pes->p_extra );
416 else if( p_stream->pes->i_codec == VLC_CODEC_DVBS )
419 if( p_stream->pes->i_extra )
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 );
428 /* from the dvbsub transcoder */
429 dvbpsi_subtitling_dr_t descr;
430 dvbpsi_subtitle_t sub;
431 dvbpsi_descriptor_t *p_descr;
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;
438 descr.i_subtitles_number = 1;
439 descr.p_subtitle[0] = sub;
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 );
449 if( p_stream->pes->i_langs )
451 dvbpsi_PMTESAddDescriptor( p_es, 0x0a, 4*p_stream->pes->i_langs,
452 p_stream->pes->lang);
456 for (unsigned i = 0; i < i_programs; i++ )
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] );
462 sect = dvbpsi_GenPMTSections( &dvbpmt[i] );
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] );
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 );
477 sect = dvbpsi_GenSDTSections( &sdt );
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 );