Add support for DVB VBI.

sdt
Kieran Kunhya 2011-05-02 19:57:40 +01:00
rodzic e2a26327a1
commit 717199bf6e
5 zmienionych plików z 155 dodań i 8 usunięć

Wyświetl plik

@ -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;

Wyświetl plik

@ -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 )
{

Wyświetl plik

@ -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 );

Wyświetl plik

@ -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++ )

Wyświetl plik

@ -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
* */