kopia lustrzana https://github.com/kierank/libmpegts
Add DVB code.
rodzic
353a7ea1af
commit
08cba957ea
221
dvb/dvb.c
221
dvb/dvb.c
|
@ -22,6 +22,26 @@
|
||||||
#include "dvb.h"
|
#include "dvb.h"
|
||||||
|
|
||||||
/**** PMT Second Loop Descriptors ****/
|
/**** PMT Second Loop Descriptors ****/
|
||||||
|
void write_aac_descriptor( bs_t *s, ts_int_stream_t *stream )
|
||||||
|
{
|
||||||
|
bs_write( s, 8, DVB_AAC_DESCRIPTOR_TAG ); // descriptor_tag
|
||||||
|
bs_write( s, 8, 1 ); // descriptor_length
|
||||||
|
bs_write( s, 8, stream->aac_profile ); // profile_and_level
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_adaptation_field_data_descriptor( bs_t *s, uint8_t identifier )
|
||||||
|
{
|
||||||
|
bs_write( s, 8, DVB_ADAPTATION_FIELD_DATA_DESCRIPTOR ); // descriptor_tag
|
||||||
|
bs_write( s, 8, 1 ); // descriptor_length
|
||||||
|
bs_write( s, 8, identifier ); // adaptation_field_data_identifier
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_dvb_subtitling_descriptor( bs_t *s )
|
||||||
|
{
|
||||||
|
bs_write( s, 8, DVB_SUBTITLING_DESCRIPTOR_TAG ); // descriptor_tag
|
||||||
|
bs_write( s, 8, 0 ); // descriptor_length FIXME
|
||||||
|
}
|
||||||
|
|
||||||
void write_stream_identifier_descriptor( bs_t *s, uint8_t stream_identifier )
|
void write_stream_identifier_descriptor( bs_t *s, uint8_t stream_identifier )
|
||||||
{
|
{
|
||||||
bs_write( s, 8, DVB_STREAM_IDENTIFIER_DESCRIPTOR_TAG ); // descriptor_tag
|
bs_write( s, 8, DVB_STREAM_IDENTIFIER_DESCRIPTOR_TAG ); // descriptor_tag
|
||||||
|
@ -29,7 +49,188 @@ void write_stream_identifier_descriptor( bs_t *s, uint8_t stream_identifier )
|
||||||
bs_write( s, 8, stream_identifier ); // component_tag
|
bs_write( s, 8, stream_identifier ); // component_tag
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_dvb_au_information( ts_writer_t *w, bs_t *s, ts_int_stream_t *stream, ts_int_frame_t *frame )
|
void write_teletext_descriptor( bs_t *s )
|
||||||
|
{
|
||||||
|
bs_write( s, 8, DVB_TELETEXT_DESCRIPTOR_TAG ); // descriptor_tag
|
||||||
|
bs_write( s, 8, 0 ); // descriptor_length
|
||||||
|
// FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static void write_service_descriptor( bs_t *s )
|
||||||
|
{
|
||||||
|
bs_write( s, 8, DVB_SERVICE_DESCRIPTOR_TAG ); // descriptor_tag
|
||||||
|
bs_write( s, 8, 0 ); // descriptor_length
|
||||||
|
bs_write( s, 8, 0 ); // service_type
|
||||||
|
bs_write( s, 8, 0 ); // service_provider_name_length
|
||||||
|
|
||||||
|
// TODO support more character codes
|
||||||
|
while( *provider_name != '\0' )
|
||||||
|
bs_write( s, 8, *provider_name++ );
|
||||||
|
|
||||||
|
bs_write( s, 8, name_len ); // service_name_length
|
||||||
|
|
||||||
|
while( *name != '\0' )
|
||||||
|
bs_write( s, 8, *name++ );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* DVB Service Information */
|
||||||
|
void write_nit( ts_writer_t *w )
|
||||||
|
{
|
||||||
|
int start;
|
||||||
|
|
||||||
|
bs_t *s = &w->out.bs;
|
||||||
|
|
||||||
|
write_packet_header( w, 1, w->network_pid, PAYLOAD_ONLY, &w->nit->cc );
|
||||||
|
|
||||||
|
bs_write( s, 8, 0 ); // pointer field
|
||||||
|
|
||||||
|
start = bs_pos( s );
|
||||||
|
bs_write( s, 8, NIT_TID ); // table_id = network_information_section
|
||||||
|
bs_write1( s, 1 ); // section_syntax_indicator
|
||||||
|
bs_write1( s, 1 ); // reserved_future_use
|
||||||
|
bs_write( s, 2, 0x03 ); // reserved
|
||||||
|
bs_write( s, 12, 0x13 ); // section_length
|
||||||
|
bs_write( s, 16, w->network_id ); // network_id
|
||||||
|
bs_write( s, 2, 0x02 ); // reserved
|
||||||
|
bs_write( s, 5, 0 ); // version_number
|
||||||
|
bs_write1( s, 1 ); // current_next_indicator
|
||||||
|
bs_write(s, 8, 0 ); // section_number
|
||||||
|
bs_write(s, 8, 0 ); // last_section_number
|
||||||
|
bs_write(s, 4, 0xf ); // reserved_future_use
|
||||||
|
bs_write(s, 12, 0 ); // network_descriptors_length
|
||||||
|
|
||||||
|
// network descriptor(s) here
|
||||||
|
|
||||||
|
bs_write(s, 4, 0xf ); // reserved_future_use
|
||||||
|
bs_write(s, 12, 0 ); // transport_stream_loop_length
|
||||||
|
|
||||||
|
bs_write( s, 16, w->ts_id ); // transport_stream_id
|
||||||
|
bs_write( s, 16, w->network_id ); // original_network_id
|
||||||
|
bs_write( s, 4, 0xf ); // reserved_future_use
|
||||||
|
bs_write(s, 12, 0 ); // transport_descriptors_length
|
||||||
|
|
||||||
|
// transport descriptor(s) here
|
||||||
|
|
||||||
|
bs_flush( s );
|
||||||
|
write_crc( s, start );
|
||||||
|
|
||||||
|
// -40 to include header and pointer field
|
||||||
|
write_padding( s, start - 40 );
|
||||||
|
increase_pcr( w, 1 );
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
/* "The SDT contains data describing the services in the system e.g. names of services, the service provider, etc" */
|
||||||
|
void write_sdt( ts_writer_t *w )
|
||||||
|
{
|
||||||
|
uint64_t start;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
bs_t *s = &w->out.bs;
|
||||||
|
|
||||||
|
write_packet_header( w, 1, SDT_PID, PAYLOAD_ONLY, &w->sdt->cc );
|
||||||
|
bs_write( s, 8, 0 ); // pointer field
|
||||||
|
|
||||||
|
start = bs_pos( s );
|
||||||
|
bs_write( s, 8, SDT_TID ); // table_id
|
||||||
|
bs_write1( s, 1 ); // section_syntax_indicator
|
||||||
|
bs_write1( s, 1 ); // reserved_future_use
|
||||||
|
bs_write1( s, 1 ); // reserved
|
||||||
|
|
||||||
|
// TODO temp
|
||||||
|
|
||||||
|
bs_write( s, 12, len ); // section_length
|
||||||
|
bs_write( s, 16, w->ts_id ); // transport_stream_id
|
||||||
|
bs_write( s, 2, 0x03 ); // reserved
|
||||||
|
bs_write( s, 5, 0 ); // version_number
|
||||||
|
bs_write1( s, 1 ); // current_next_indicator
|
||||||
|
bs_write( s, 8, 0 ); // section_number
|
||||||
|
bs_write( s, 8, 0 ); // last_section_number
|
||||||
|
bs_write( s, 8, w->nid ); // original_network_id
|
||||||
|
bs_write( s, 8, 0xff ); // reserved_future_use
|
||||||
|
|
||||||
|
for( i = 0; i < w->num_programs; i++ )
|
||||||
|
{
|
||||||
|
bs_write( s, 16, w->programs[i]->program_num & 0xffff ); // service_id (equivalent to program_number)
|
||||||
|
bs_write( s, 6, 0x7f ); // reserved_future_use
|
||||||
|
bs_write1( s, 0 ); // EIT_schedule_flag
|
||||||
|
bs_write1( s, 1 ); // EIT_present_following_flag
|
||||||
|
bs_write( s, 3, 0 ); // running_status
|
||||||
|
bs_write1( s, 1 ); // free_CA_mode
|
||||||
|
|
||||||
|
int provider_name_len = strlen( w->programs[i]->sdt_ctx->provider_name );
|
||||||
|
int name_len = strlen( w->programs[i]->sdt_ctx->service_name );
|
||||||
|
|
||||||
|
char *provider_name = w->programs[i]->sdt_ctx->provider_name;
|
||||||
|
char *name = w->programs[i]->sdt_ctx->service_name;
|
||||||
|
|
||||||
|
int descriptors_len = 5 + provider_name_len + name_len;
|
||||||
|
bs_write( s, 12, descriptors_len ); // descriptors_loop_length
|
||||||
|
|
||||||
|
// service descriptor (mandatory for DVB)
|
||||||
|
|
||||||
|
|
||||||
|
// other descriptor(s) here
|
||||||
|
}
|
||||||
|
|
||||||
|
bs_flush( s );
|
||||||
|
write_crc( s, start );
|
||||||
|
|
||||||
|
// -40 to include header and pointer field
|
||||||
|
write_padding( s, start - 40 );
|
||||||
|
increase_pcr( w, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
|
||||||
|
// "the EIT contains data concerning events or programmes such as event name, start time, duration, etc.; "
|
||||||
|
void write_eit( ts_writer_t *w )
|
||||||
|
{
|
||||||
|
uint64_t start;
|
||||||
|
|
||||||
|
bs_t *s = &w->out.bs;
|
||||||
|
|
||||||
|
write_packet_header( w, 1, EIT_PID, PAYLOAD_ONLY, &w->eit->cc );
|
||||||
|
bs_write( s, 8, 0 ); // pointer field
|
||||||
|
|
||||||
|
start = bs_pos( s );
|
||||||
|
bs_write( s, 8, EIT_TID ); // table_id
|
||||||
|
bs_write1( s, 0 ); // section_syntax_indicator CHECKME
|
||||||
|
bs_write1( s, 1 ); // reserved_future_use
|
||||||
|
bs_write( s, 2, 0x03); // reserved
|
||||||
|
|
||||||
|
|
||||||
|
bs_write( s, 12, len ); // section_length
|
||||||
|
|
||||||
|
}
|
||||||
|
// "the TDT gives information relating to the present time and date. This information is given in a separate
|
||||||
|
// table due to the frequent updating of this information. "
|
||||||
|
void write_tdt( ts_writer_t *w )
|
||||||
|
{
|
||||||
|
uint64_t start;
|
||||||
|
|
||||||
|
bs_t *s = &w->out.bs;
|
||||||
|
|
||||||
|
write_packet_header( w, 1, TDT_PID, PAYLOAD_ONLY, &w->tdt->cc );
|
||||||
|
bs_write( s, 8, 0 ); // pointer field
|
||||||
|
|
||||||
|
start = bs_pos( s );
|
||||||
|
bs_write( s, 8, TDT_TID ); // table_id
|
||||||
|
bs_write1( s, 0 ); // section_syntax_indicator
|
||||||
|
bs_write1( s, 1 ); // reserved_future_use
|
||||||
|
bs_write( s, 2, 0x03); // reserved
|
||||||
|
bs_write( s, 12, 0x05); // section_length
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
|
||||||
|
bs_write( s, 4, & 0x0f ); //
|
||||||
|
|
||||||
|
increase_pcr( w, 1 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// TODO TOT
|
||||||
|
|
||||||
void write_dvb_au_information( bs_t *s, ts_int_pes_t *pes )
|
void write_dvb_au_information( bs_t *s, ts_int_pes_t *pes )
|
||||||
{
|
{
|
||||||
bs_t q;
|
bs_t q;
|
||||||
|
@ -42,7 +243,7 @@ void write_dvb_au_information( bs_t *s, ts_int_pes_t *pes )
|
||||||
|
|
||||||
if( stream->stream_format == LIBMPEGTS_VIDEO_MPEG2 )
|
if( stream->stream_format == LIBMPEGTS_VIDEO_MPEG2 )
|
||||||
bs_write( &q, 4, 1 ); // AU_coding_format
|
bs_write( &q, 4, 1 ); // AU_coding_format
|
||||||
else if( stream->stream_format == LIBMPEGTS_VIDEO_H264 )
|
else if( stream->stream_format == LIBMPEGTS_VIDEO_AVC )
|
||||||
bs_write( &q, 4, 0x2 ); // AU_coding_format
|
bs_write( &q, 4, 0x2 ); // AU_coding_format
|
||||||
|
|
||||||
bs_write( &q, 4, pes->frame_type ); // AU_coding_type_information
|
bs_write( &q, 4, pes->frame_type ); // AU_coding_type_information
|
||||||
|
@ -61,16 +262,16 @@ void write_dvb_au_information( bs_t *s, ts_int_pes_t *pes )
|
||||||
|
|
||||||
bs_write( &q, 8, stream->mpegvideo_ctx->profile & 0xff ); // profile_idc
|
bs_write( &q, 8, stream->mpegvideo_ctx->profile & 0xff ); // profile_idc
|
||||||
|
|
||||||
if( stream->stream_format == LIBMPEGTS_VIDEO_H264 )
|
if( stream->stream_format == LIBMPEGTS_VIDEO_AVC )
|
||||||
{
|
{
|
||||||
bs_write1( &q, stream->mpegvideo_ctx->profile == H264_BASELINE ); // constraint_set0_flag
|
bs_write1( &q, stream->mpegvideo_ctx->profile == AVC_BASELINE ); // constraint_set0_flag
|
||||||
bs_write1( &q, stream->mpegvideo_ctx->profile <= H264_MAIN ); // constraint_set1_flag
|
bs_write1( &q, stream->mpegvideo_ctx->profile <= AVC_MAIN ); // constraint_set1_flag
|
||||||
bs_write1( &q, 0 ); // constraint_set2_flag
|
bs_write1( &q, 0 ); // constraint_set2_flag
|
||||||
if( stream->mpegvideo_ctx->level == 9 && stream->mpegvideo_ctx->profile <= H264_MAIN ) // level 1b
|
if( stream->mpegvideo_ctx->level == 9 && stream->mpegvideo_ctx->profile <= AVC_MAIN ) // level 1b
|
||||||
bs_write1( &q, 1 ); // constraint_set3_flag
|
bs_write1( &q, 1 ); // constraint_set3_flag
|
||||||
else if( stream->mpegvideo_ctx->profile == H264_HIGH_10_INTRA ||
|
else if( stream->mpegvideo_ctx->profile == AVC_HIGH_10_INTRA ||
|
||||||
stream->mpegvideo_ctx->profile == H264_CAVLC_444_INTRA ||
|
stream->mpegvideo_ctx->profile == AVC_CAVLC_444_INTRA ||
|
||||||
stream->mpegvideo_ctx->profile == H264_HIGH_444_INTRA )
|
stream->mpegvideo_ctx->profile == AVC_HIGH_444_INTRA )
|
||||||
bs_write1( &q, 1 ); // constraint_set3_flag
|
bs_write1( &q, 1 ); // constraint_set3_flag
|
||||||
else
|
else
|
||||||
bs_write1( &q, 0 ); // constraint_set3_flag
|
bs_write1( &q, 0 ); // constraint_set3_flag
|
||||||
|
@ -99,3 +300,5 @@ void write_dvb_au_information( bs_t *s, ts_int_pes_t *pes )
|
||||||
bs_write( s, 8, bs_pos( &q ) >> 3 ); // data_field_length
|
bs_write( s, 8, bs_pos( &q ) >> 3 ); // data_field_length
|
||||||
write_bytes( s, temp, bs_pos( &q ) >> 3 );
|
write_bytes( s, temp, bs_pos( &q ) >> 3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
13
dvb/dvb.h
13
dvb/dvb.h
|
@ -25,7 +25,9 @@
|
||||||
#define DVB_SERVICE_DESCRIPTOR_TAG 0x48
|
#define DVB_SERVICE_DESCRIPTOR_TAG 0x48
|
||||||
#define DVB_STREAM_IDENTIFIER_DESCRIPTOR_TAG 0x52
|
#define DVB_STREAM_IDENTIFIER_DESCRIPTOR_TAG 0x52
|
||||||
#define DVB_TELETEXT_DESCRIPTOR_TAG 0x56
|
#define DVB_TELETEXT_DESCRIPTOR_TAG 0x56
|
||||||
|
#define DVB_SUBTITLING_DESCRIPTOR_TAG 0x59
|
||||||
#define DVB_AC3_DESCRIPTOR_TAG 0x6a
|
#define DVB_AC3_DESCRIPTOR_TAG 0x6a
|
||||||
|
#define DVB_ADAPTATION_FIELD_DATA_DESCRIPTOR 0x70
|
||||||
#define DVB_EAC3_DESCRIPTOR_TAG 0x7a
|
#define DVB_EAC3_DESCRIPTOR_TAG 0x7a
|
||||||
#define DVB_AAC_DESCRIPTOR_TAG 0x7c
|
#define DVB_AAC_DESCRIPTOR_TAG 0x7c
|
||||||
|
|
||||||
|
@ -50,7 +52,16 @@
|
||||||
#define AU_INFORMATION_DATA_FIELD 0x02
|
#define AU_INFORMATION_DATA_FIELD 0x02
|
||||||
#define PVR_ASSIST_INFORMATION_DATA_FIELD 0x03
|
#define PVR_ASSIST_INFORMATION_DATA_FIELD 0x03
|
||||||
|
|
||||||
|
|
||||||
|
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_stream_identifier_descriptor( bs_t *s, uint8_t stream_identifier );
|
void write_stream_identifier_descriptor( bs_t *s, uint8_t stream_identifier );
|
||||||
void write_dvb_au_information( ts_writer_t *w, bs_t *s, ts_int_stream_t *stream, ts_int_frame_t *frame );
|
void write_teletext_descriptor( bs_t *s );
|
||||||
|
|
||||||
|
void write_nit( ts_writer_t *w );
|
||||||
|
//void write_sdt( ts_writer_t *w );
|
||||||
|
//void write_eit( ts_writer_t *w );
|
||||||
|
//void write_tdt( ts_writer_t *w );
|
||||||
|
|
||||||
void write_dvb_au_information( bs_t *s, ts_int_pes_t *pes );
|
void write_dvb_au_information( bs_t *s, ts_int_pes_t *pes );
|
||||||
#endif
|
#endif
|
||||||
|
|
Ładowanie…
Reference in New Issue