kopia lustrzana https://github.com/kierank/libmpegts
Add support for DVB VBI.
rodzic
e2a26327a1
commit
717199bf6e
3
common.h
3
common.h
|
|
@ -174,6 +174,9 @@ typedef struct
|
|||
int num_dvb_ttx;
|
||||
ts_dvb_ttx_t *dvb_ttx_ctx;
|
||||
|
||||
int num_dvb_vbi;
|
||||
ts_dvb_vbi_t *dvb_vbi_ctx;
|
||||
|
||||
int num_channels;
|
||||
int max_frame_size;
|
||||
|
||||
|
|
|
|||
38
dvb/dvb.c
38
dvb/dvb.c
|
|
@ -62,11 +62,15 @@ void write_stream_identifier_descriptor( bs_t *s, uint8_t stream_identifier )
|
|||
bs_write( s, 8, stream_identifier ); // component_tag
|
||||
}
|
||||
|
||||
void write_teletext_descriptor( bs_t *s, ts_int_stream_t *stream )
|
||||
void write_teletext_descriptor( bs_t *s, ts_int_stream_t *stream, int vbi )
|
||||
{
|
||||
ts_dvb_ttx_t *teletext;
|
||||
|
||||
bs_write( s, 8, DVB_TELETEXT_DESCRIPTOR_TAG ); // descriptor_tag
|
||||
if( vbi )
|
||||
bs_write( s, 8, DVB_VBI_TELETEXT_DESCRIPTOR_TAG ); // descriptor_tag
|
||||
else
|
||||
bs_write( s, 8, DVB_TELETEXT_DESCRIPTOR_TAG ); // descriptor_tag
|
||||
|
||||
bs_write( s, 8, stream->num_dvb_ttx * 5 ); // descriptor_length
|
||||
for( int i = 0; i < stream->num_dvb_ttx; i++ )
|
||||
{
|
||||
|
|
@ -79,6 +83,36 @@ void write_teletext_descriptor( bs_t *s, ts_int_stream_t *stream )
|
|||
}
|
||||
}
|
||||
|
||||
void write_vbi_descriptor( bs_t *s, ts_int_stream_t *stream )
|
||||
{
|
||||
bs_t q;
|
||||
uint8_t temp[1024];
|
||||
ts_dvb_vbi_t *vbi;
|
||||
|
||||
bs_init( &q, temp, 1024 );
|
||||
|
||||
bs_write( s, 8, DVB_VBI_DESCRIPTOR_TAG ); // descriptor_tag
|
||||
|
||||
for( int i = 0; i < stream->num_dvb_ttx; i++ )
|
||||
{
|
||||
vbi = &stream->dvb_vbi_ctx[i];
|
||||
|
||||
bs_write( &q, 8, vbi->data_service_id ); // data_service_id
|
||||
bs_write( &q, 8, vbi->num_lines ); // data_service_descriptor_length
|
||||
|
||||
for( int j = 0; j < vbi->num_lines; j++ )
|
||||
{
|
||||
bs_write( &q, 2, 0x3 ); // reserved
|
||||
bs_write( &q, 1, vbi->lines[j].field_parity ); // field_parity
|
||||
bs_write( &q, 5, vbi->lines[j].line_offset ); // line_offset
|
||||
}
|
||||
}
|
||||
|
||||
bs_flush( &q );
|
||||
bs_write( s, 8, bs_pos( &q ) >> 3 ); // descriptor_length
|
||||
write_bytes( s, temp, bs_pos( &q ) >> 3 );
|
||||
}
|
||||
|
||||
/*
|
||||
static void write_service_descriptor( bs_t *s )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#define LIBMPEGTS_DVB_H
|
||||
|
||||
/* Descriptor Tags */
|
||||
#define DVB_VBI_DESCRIPTOR_TAG 0x45
|
||||
#define DVB_VBI_TELETEXT_DESCRIPTOR_TAG 0x46
|
||||
#define DVB_SERVICE_DESCRIPTOR_TAG 0x48
|
||||
#define DVB_STREAM_IDENTIFIER_DESCRIPTOR_TAG 0x52
|
||||
#define DVB_TELETEXT_DESCRIPTOR_TAG 0x56
|
||||
|
|
@ -56,7 +58,8 @@ void write_aac_descriptor( bs_t *s, ts_int_stream_t *stream );
|
|||
void write_adaptation_field_data_descriptor( bs_t *s, uint8_t identifier );
|
||||
void write_dvb_subtitling_descriptor( bs_t *s, ts_int_stream_t *stream );
|
||||
void write_stream_identifier_descriptor( bs_t *s, uint8_t stream_identifier );
|
||||
void write_teletext_descriptor( bs_t *s, ts_int_stream_t *stream );
|
||||
void write_teletext_descriptor( bs_t *s, ts_int_stream_t *stream, int vbi );
|
||||
void write_vbi_descriptor( bs_t *s, ts_int_stream_t *stream );
|
||||
|
||||
int write_nit( ts_writer_t *w );
|
||||
//void write_sdt( ts_writer_t *w );
|
||||
|
|
|
|||
85
libmpegts.c
85
libmpegts.c
|
|
@ -29,7 +29,7 @@
|
|||
#include "crc/crc.h"
|
||||
#include <math.h>
|
||||
|
||||
static int steam_type_table[26][2] =
|
||||
static const int steam_type_table[27][2] =
|
||||
{
|
||||
{ LIBMPEGTS_VIDEO_MPEG2, VIDEO_MPEG2 },
|
||||
{ LIBMPEGTS_VIDEO_AVC, VIDEO_AVC },
|
||||
|
|
@ -54,6 +54,7 @@ static int steam_type_table[26][2] =
|
|||
{ LIBMPEGTS_AUDIO_302M, PRIVATE_DATA },
|
||||
{ LIBMPEGTS_DVB_SUB, PRIVATE_DATA },
|
||||
{ LIBMPEGTS_DVB_TELETEXT, PRIVATE_DATA },
|
||||
{ LIBMPEGTS_DVB_VBI, PRIVATE_DATA },
|
||||
{ LIBMPEGTS_ANCILLARY_RDD11, PRIVATE_DATA },
|
||||
{ LIBMPEGTS_ANCILLARY_2038, PRIVATE_DATA },
|
||||
{ 0 },
|
||||
|
|
@ -627,6 +628,66 @@ int ts_setup_dvb_teletext( ts_writer_t *w, int pid, int num_teletexts, ts_dvb_tt
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ts_setup_dvb_vbi( ts_writer_t *w, int pid, int num_vbis, ts_dvb_vbi_t *vbis )
|
||||
{
|
||||
if( w->ts_type == TS_TYPE_BLU_RAY )
|
||||
{
|
||||
fprintf( stderr, "VBI not allowed in Blu-Ray\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
ts_int_stream_t *stream = find_stream( w, pid );
|
||||
|
||||
if( !stream )
|
||||
{
|
||||
fprintf( stderr, "Invalid PID\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !vbis || !num_vbis )
|
||||
{
|
||||
fprintf( stderr, "Invalid Number of VBI services\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( stream->dvb_vbi_ctx )
|
||||
free( stream->dvb_vbi_ctx );
|
||||
|
||||
stream->dvb_vbi_ctx = calloc( 1, num_vbis * sizeof(ts_dvb_vbi_t) );
|
||||
if( !stream->dvb_vbi_ctx )
|
||||
return -1;
|
||||
|
||||
stream->num_dvb_vbi = num_vbis;
|
||||
memcpy( stream->dvb_vbi_ctx, vbis, num_vbis * sizeof(ts_dvb_vbi_t) );
|
||||
|
||||
for( int i = 0; i < stream->num_dvb_vbi; i++ )
|
||||
{
|
||||
stream->dvb_vbi_ctx[i].lines = calloc( 1, vbis[i].num_lines * sizeof(ts_dvb_vbi_line_t) );
|
||||
if( !stream->dvb_vbi_ctx[i].lines )
|
||||
goto fail;
|
||||
memcpy( stream->dvb_vbi_ctx[i].lines, vbis[i].lines, vbis[i].num_lines * sizeof(ts_dvb_vbi_line_t) );
|
||||
}
|
||||
|
||||
/* VBI uses teletext T-STD */
|
||||
stream->tb.buf_size = TELETEXT_T_BS;
|
||||
stream->rx = TELETEXT_RXN;
|
||||
stream->mb.buf_size = TELETEXT_BTTX;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
||||
for( int i = 0; i < stream->num_dvb_vbi; i++ )
|
||||
{
|
||||
if( stream->dvb_vbi_ctx[i].lines )
|
||||
free( stream->dvb_vbi_ctx[i].lines );
|
||||
}
|
||||
|
||||
free( stream->dvb_vbi_ctx );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ts_write_frames( ts_writer_t *w, ts_frame_t *frames, int num_frames, uint8_t **out, int *len, int64_t **pcr_list )
|
||||
{
|
||||
ts_int_program_t *program = w->programs[0];
|
||||
|
|
@ -700,6 +761,14 @@ int ts_write_frames( ts_writer_t *w, ts_frame_t *frames, int num_frames, uint8_t
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
else if( stream->stream_format == LIBMPEGTS_DVB_VBI )
|
||||
{
|
||||
if( !stream->dvb_vbi_ctx )
|
||||
{
|
||||
fprintf( stderr, "DVB VBI stream needs additional information. Call ts_setup_dvb_vbi \n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// TODO more
|
||||
|
||||
w->buffered_frames[i] = calloc( 1, sizeof(ts_int_pes_t) );
|
||||
|
|
@ -1618,7 +1687,13 @@ static int write_pmt( ts_writer_t *w, ts_int_program_t *program )
|
|||
else if( stream->stream_format == LIBMPEGTS_DVB_SUB )
|
||||
write_dvb_subtitling_descriptor( &q, stream );
|
||||
else if( stream->stream_format == LIBMPEGTS_DVB_TELETEXT )
|
||||
write_teletext_descriptor( &q, stream );
|
||||
write_teletext_descriptor( &q, stream, 0 );
|
||||
else if( stream->stream_format == LIBMPEGTS_DVB_VBI )
|
||||
{
|
||||
write_vbi_descriptor( &q, stream );
|
||||
if( stream->num_dvb_ttx )
|
||||
write_teletext_descriptor( &q, stream, 1 );
|
||||
}
|
||||
else if( stream->stream_format == LIBMPEGTS_ANCILLARY_RDD11 )
|
||||
write_registration_descriptor( &q, PRIVATE_DATA_DESCRIPTOR_TAG, 4, "LU-A" );
|
||||
else if( stream->stream_format == LIBMPEGTS_ANCILLARY_2038 )
|
||||
|
|
@ -1812,7 +1887,7 @@ static int write_pes( ts_writer_t *w, ts_int_program_t *program, ts_frame_t *in_
|
|||
bs_write1( &q, 0 ); // PES_CRC_flag
|
||||
bs_write1( &q, 0 ); // PES_extension_flag
|
||||
|
||||
if( stream->stream_format == LIBMPEGTS_DVB_TELETEXT )
|
||||
if( stream->stream_format == LIBMPEGTS_DVB_TELETEXT || stream->stream_format == LIBMPEGTS_DVB_VBI )
|
||||
bs_write( &q, 8, 0x24 ); // PES_header_data_length
|
||||
else if( same_timestamps )
|
||||
bs_write( &q, 8, 0x05 ); // PES_header_data_length (PTS only)
|
||||
|
|
@ -1829,8 +1904,8 @@ static int write_pes( ts_writer_t *w, ts_int_program_t *program, ts_frame_t *in_
|
|||
write_timestamp( &q, out_pes->dts % mod ); // DTS
|
||||
}
|
||||
|
||||
/* TTX requires extra stuffing */
|
||||
if( stream->stream_format == LIBMPEGTS_DVB_TELETEXT )
|
||||
/* TTX and VBI require extra stuffing */
|
||||
if( stream->stream_format == LIBMPEGTS_DVB_TELETEXT || stream->stream_format == LIBMPEGTS_DVB_VBI )
|
||||
{
|
||||
int num_stuffing = 45 - (bs_pos( &q ) >> 3);
|
||||
for( int i = 0; i < num_stuffing; i++ )
|
||||
|
|
|
|||
32
libmpegts.h
32
libmpegts.h
|
|
@ -66,6 +66,7 @@
|
|||
/* DVB Stream Formats */
|
||||
#define LIBMPEGTS_DVB_SUB 128
|
||||
#define LIBMPEGTS_DVB_TELETEXT 129
|
||||
#define LIBMPEGTS_DVB_VBI 130
|
||||
|
||||
/* Misc */
|
||||
|
||||
|
|
@ -464,6 +465,37 @@ typedef struct
|
|||
|
||||
int ts_setup_dvb_teletext( ts_writer_t *w, int pid, int num_teletexts, ts_dvb_ttx_t *teletexts );
|
||||
|
||||
/* ts_dvb_vbi_t
|
||||
* field_parity - 1 for first field (odd), 0 for second field (even)
|
||||
* line_offset - line number on which data is presented if it is transcoded into the VBI
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int field_parity;
|
||||
int line_offset;
|
||||
} ts_dvb_vbi_line_t;
|
||||
|
||||
#define LIBMPEGTS_DVB_VBI_DATA_SERVICE_ID_TTX 0x01 /* Requires call to ts_setup_dvb_teletext */
|
||||
#define LIBMPEGTS_DVB_VBI_DATA_SERVICE_ID_INVERTED_TTX 0x02
|
||||
#define LIBMPEGTS_DVB_VBI_DATA_SERVICE_ID_VPS 0x04
|
||||
#define LIBMPEGTS_DVB_VBI_DATA_SERVICE_ID_WSS 0x05
|
||||
#define LIBMPEGTS_DVB_VBI_DATA_SERVICE_ID_CC 0x06
|
||||
#define LIBMPEGTS_DVB_VBI_DATA_SERVICE_ID_MONO_SAMPLES 0x07
|
||||
|
||||
/* ts_dvb_vbi_t
|
||||
* data_service_id - see above #defines
|
||||
* lines - one ts_dvb_vbi_line_t per line
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int data_service_id;
|
||||
int num_lines;
|
||||
ts_dvb_vbi_line_t *lines;
|
||||
} ts_dvb_vbi_t;
|
||||
|
||||
int ts_setup_dvb_vbi( ts_writer_t *w, int pid, int num_vbis, ts_dvb_vbi_t *vbis );
|
||||
|
||||
/* SDT
|
||||
* */
|
||||
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue