From 08cba957ead7864661b55cff12e50f3f0a548ebb Mon Sep 17 00:00:00 2001 From: Kieran Kunhya Date: Mon, 10 Jan 2011 14:02:33 +0000 Subject: [PATCH] Add DVB code. --- dvb/dvb.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++--- dvb/dvb.h | 21 ++++-- 2 files changed, 228 insertions(+), 14 deletions(-) diff --git a/dvb/dvb.c b/dvb/dvb.c index 3651b90..7c27497 100644 --- a/dvb/dvb.c +++ b/dvb/dvb.c @@ -22,6 +22,26 @@ #include "dvb.h" /**** 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 ) { 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 } -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 ) { 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 ) 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, 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 - 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 <= H264_MAIN ); // constraint_set1_flag + bs_write1( &q, stream->mpegvideo_ctx->profile == AVC_BASELINE ); // constraint_set0_flag + bs_write1( &q, stream->mpegvideo_ctx->profile <= AVC_MAIN ); // constraint_set1_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 - else if( stream->mpegvideo_ctx->profile == H264_HIGH_10_INTRA || - stream->mpegvideo_ctx->profile == H264_CAVLC_444_INTRA || - stream->mpegvideo_ctx->profile == H264_HIGH_444_INTRA ) + else if( stream->mpegvideo_ctx->profile == AVC_HIGH_10_INTRA || + stream->mpegvideo_ctx->profile == AVC_CAVLC_444_INTRA || + stream->mpegvideo_ctx->profile == AVC_HIGH_444_INTRA ) bs_write1( &q, 1 ); // constraint_set3_flag else 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 write_bytes( s, temp, bs_pos( &q ) >> 3 ); } + + diff --git a/dvb/dvb.h b/dvb/dvb.h index 5469ef8..b598c17 100644 --- a/dvb/dvb.h +++ b/dvb/dvb.h @@ -22,10 +22,12 @@ #define LIBMPEGTS_DVB_H /* Descriptor Tags */ -#define DVB_SERVICE_DESCRIPTOR_TAG 0x48 +#define DVB_SERVICE_DESCRIPTOR_TAG 0x48 #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_ADAPTATION_FIELD_DATA_DESCRIPTOR 0x70 #define DVB_EAC3_DESCRIPTOR_TAG 0x7a #define DVB_AAC_DESCRIPTOR_TAG 0x7c @@ -42,15 +44,24 @@ /* Default Retransmit times (ms) */ #define EIT_MAX_RETRANS_TIME 2000 #define EIT_OTHER_TS_MAX_RETRANS_TIME 10000 -#define TDT_MAX_RETRANS_TIME 25000 -#define TOT_MAX_RETRANS_TIME 25000 +#define TDT_MAX_RETRANS_TIME 25000 +#define TOT_MAX_RETRANS_TIME 25000 /* Private Data Bytes data_field_tags */ #define ANNOUNCEMENT_SWITCHING_DATA_FIELD 0x01 #define AU_INFORMATION_DATA_FIELD 0x02 #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_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 ); #endif