From 8b5bc7296b580d4989f491aa5f4d1cd0fa51afc5 Mon Sep 17 00:00:00 2001 From: Kieran Kunhya Date: Fri, 14 Jun 2013 19:06:22 +0100 Subject: [PATCH 1/4] First stab at TS mux reconfiguration --- common.h | 2 ++ libmpegts.c | 55 +++++++++++++++++++++++++++++++++++------------------ libmpegts.h | 9 +++++++++ 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/common.h b/common.h index fc371e6..8cd968e 100644 --- a/common.h +++ b/common.h @@ -48,6 +48,7 @@ #define TS_PACKET_SIZE 188 #define TS_CLOCK 27000000LL #define TS_START 10 +#define TIMESTAMP_CLOCK 90000LL // arbitrary #define MAX_PROGRAMS 100 @@ -284,6 +285,7 @@ struct ts_writer_t uint64_t bytes_written; uint64_t packets_written; + uint64_t pcr_start; int ts_type; int ts_id; diff --git a/libmpegts.c b/libmpegts.c index bf6a649..f83d901 100644 --- a/libmpegts.c +++ b/libmpegts.c @@ -204,12 +204,12 @@ static int check_pcr( ts_writer_t *w, ts_int_program_t *program ) static int64_t get_pcr_int( ts_writer_t *w, double offset ) { - return (int64_t)((8.0 * (w->packets_written * TS_PACKET_SIZE + offset) / w->ts_muxrate) * TS_CLOCK + 0.5) + TS_START * TS_CLOCK; + return (int64_t)((8.0 * (w->packets_written * TS_PACKET_SIZE + offset) / w->ts_muxrate) * TS_CLOCK + 0.5) + w->pcr_start; } static double get_pcr_double( ts_writer_t *w, double offset ) { - return (8.0 * (w->packets_written * TS_PACKET_SIZE + offset) / w->ts_muxrate) + TS_START; + return (8.0 * (w->packets_written * TS_PACKET_SIZE + offset) / w->ts_muxrate) + (double)w->pcr_start / TS_CLOCK; } /**** Buffer management ****/ @@ -853,6 +853,20 @@ static int check_bitstream( ts_writer_t *w ) return 0; } +/* set updatable ts parameters */ +static void update_ts_params( ts_writer_t *w, ts_main_t *params ) +{ + w->ts_muxrate = params->muxrate; + w->cbr = params->cbr; + w->legacy_constraints = params->legacy_constraints; + + w->pcr_period = params->pcr_period ? params->pcr_period : PCR_MAX_RETRANS_TIME; + w->pat_period = params->pat_period ? params->pat_period : PAT_MAX_RETRANS_TIME; + w->sdt_period = params->sdt_period ? params->sdt_period : SDT_MAX_RETRANS_TIME; + + w->r_sys = MAX( R_SYS_DEFAULT, (double)w->ts_muxrate / 500 ); +} + ts_writer_t *ts_create_writer( void ) { ts_writer_t *w = calloc( 1, sizeof(*w) ); @@ -1048,22 +1062,16 @@ int ts_setup_transport_stream( ts_writer_t *w, ts_main_t *params ) cur_program->pcr_stream = pcr_stream; } - w->ts_id = params->ts_id; - w->ts_muxrate = params->muxrate; - w->cbr = params->cbr; - w->ts_type = params->ts_type; + update_ts_params( w, params ); + w->network_pid = params->network_pid; - w->legacy_constraints = params->legacy_constraints; - - w->pcr_period = params->pcr_period ? params->pcr_period : PCR_MAX_RETRANS_TIME; - w->pat_period = params->pat_period ? params->pat_period : PAT_MAX_RETRANS_TIME; - w->sdt_period = params->sdt_period ? params->sdt_period : SDT_MAX_RETRANS_TIME; - + w->ts_type = params->ts_type; w->network_id = params->network_id ? params->network_id : DEFAULT_NID; - + w->ts_id = params->ts_id; w->tb.buf_size = TB_SIZE; w->rx_sys = RX_SYS; - w->r_sys = MAX( R_SYS_DEFAULT, (double)w->ts_muxrate / 500 ); + + w->pcr_start = TS_START * TS_CLOCK; // FIXME realloc if necessary @@ -1081,6 +1089,17 @@ int ts_setup_transport_stream( ts_writer_t *w, ts_main_t *params ) return 0; } +int ts_update_transport_stream( ts_writer_t *w, ts_main_t *params ) +{ + int64_t cur_pcr = get_pcr_int( w, 0 ); + if( params->muxrate != w->ts_muxrate ) + { + update_ts_params( w, params ); + w->packets_written = 0; + w->pcr_start = cur_pcr; + } +} + /* Codec-specific features */ int ts_setup_mpegvideo_stream( ts_writer_t *w, int pid, int level, int profile, int vbv_maxrate, int vbv_bufsize, int frame_rate ) @@ -1601,14 +1620,14 @@ int ts_write_frames( ts_writer_t *w, ts_frame_t *frames, int num_frames, uint8_t new_pes[i]->stream = stream; new_pes[i]->random_access = !!frames[i].random_access; new_pes[i]->priority = !!frames[i].priority; - new_pes[i]->dts = frames[i].dts + TS_START * 90000LL; - new_pes[i]->pts = frames[i].pts + TS_START * 90000LL; + new_pes[i]->dts = frames[i].dts + TS_START * TIMESTAMP_CLOCK; + new_pes[i]->pts = frames[i].pts + TS_START * TIMESTAMP_CLOCK; if( IS_VIDEO( stream ) ) { new_pes[i]->frame_type = frames[i].frame_type; - new_pes[i]->initial_arrival_time = frames[i].cpb_initial_arrival_time + TS_START * 27000000LL; - new_pes[i]->final_arrival_time = frames[i].cpb_final_arrival_time + TS_START * 27000000LL; + new_pes[i]->initial_arrival_time = frames[i].cpb_initial_arrival_time + TS_START * TS_CLOCK; + new_pes[i]->final_arrival_time = frames[i].cpb_final_arrival_time + TS_START * TS_CLOCK; new_pes[i]->ref_pic_idc = frames[i].ref_pic_idc; new_pes[i]->write_pulldown_info = frames[i].write_pulldown_info; new_pes[i]->pic_struct = frames[i].pic_struct; diff --git a/libmpegts.h b/libmpegts.h index ff7415f..ffc996f 100644 --- a/libmpegts.h +++ b/libmpegts.h @@ -329,6 +329,15 @@ typedef struct ts_main_t int ts_setup_transport_stream( ts_writer_t *w, ts_main_t *params ); +/* update transport stream + * + * muxrate is the only tested parameter + * + * TODO: implement versioning so other parameters can be updated + * + */ +int ts_update_transport_stream( ts_writer_t *w, ts_main_t *params ); + /**** Additional Codec-Specific functions ****/ /* Many formats require extra information. Setup the relevant information using the following functions */ From 75b0b98d0d9d9d4b6240f7816bf15cff3781a2e4 Mon Sep 17 00:00:00 2001 From: Kieran Kunhya Date: Fri, 14 Jun 2013 19:14:26 +0100 Subject: [PATCH 2/4] Make ts_update_transport_stream void for the time being --- libmpegts.c | 2 +- libmpegts.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmpegts.c b/libmpegts.c index f83d901..94516ea 100644 --- a/libmpegts.c +++ b/libmpegts.c @@ -1089,7 +1089,7 @@ int ts_setup_transport_stream( ts_writer_t *w, ts_main_t *params ) return 0; } -int ts_update_transport_stream( ts_writer_t *w, ts_main_t *params ) +void ts_update_transport_stream( ts_writer_t *w, ts_main_t *params ) { int64_t cur_pcr = get_pcr_int( w, 0 ); if( params->muxrate != w->ts_muxrate ) diff --git a/libmpegts.h b/libmpegts.h index ffc996f..2d694e9 100644 --- a/libmpegts.h +++ b/libmpegts.h @@ -336,7 +336,7 @@ int ts_setup_transport_stream( ts_writer_t *w, ts_main_t *params ); * TODO: implement versioning so other parameters can be updated * */ -int ts_update_transport_stream( ts_writer_t *w, ts_main_t *params ); +void ts_update_transport_stream( ts_writer_t *w, ts_main_t *params ); /**** Additional Codec-Specific functions ****/ /* Many formats require extra information. Setup the relevant information using the following functions */ From 5c123b89f907174bf091bebdfc34595d20d1c085 Mon Sep 17 00:00:00 2001 From: Kieran Kunhya Date: Fri, 14 Jun 2013 20:34:41 +0100 Subject: [PATCH 3/4] Improve PCR generation after reconfig --- libmpegts.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/libmpegts.c b/libmpegts.c index 94516ea..1ad0e20 100644 --- a/libmpegts.c +++ b/libmpegts.c @@ -190,14 +190,10 @@ static void write_iso_lang_descriptor( bs_t *s, ts_int_stream_t *stream ) static int check_pcr( ts_writer_t *w, ts_int_program_t *program ) { // if the next packet written goes over the max pcr retransmit boundary, write the pcr in the next packet - double next_pkt_pcr = ((w->packets_written * TS_PACKET_SIZE) + (TS_PACKET_SIZE + 7)) * 8.0 / w->ts_muxrate - - (double)program->last_pcr / TS_CLOCK; - next_pkt_pcr += TS_START; + int64_t next_pkt_pcr = get_pcr_int( w, (TS_PACKET_SIZE + 7) * 8 ) - program->last_pcr; - if( next_pkt_pcr >= (double)w->pcr_period / 1000 ) - { + if( next_pkt_pcr >= w->pcr_period * (TS_CLOCK/1000) ) return 1; - } return 0; } @@ -2025,7 +2021,7 @@ int increase_pcr( ts_writer_t *w, int num_packets, int imaginary ) // TODO do this for all programs ts_int_program_t *program = w->programs[0]; - double next_pcr = TS_START + (w->packets_written + num_packets) * 8.0 * TS_PACKET_SIZE / w->ts_muxrate; + double next_pcr = get_pcr_double( w, num_packets * TS_PACKET_SIZE ); /* buffer drip (TODO: all buffers?) */ drip_buffer( w, program, w->rx_sys, &w->tb, next_pcr ); for( int i = 0; i < program->num_streams; i++ ) @@ -2037,6 +2033,7 @@ int increase_pcr( ts_writer_t *w, int num_packets, int imaginary ) if( !imaginary ) { + // FIXME this is wrong for multiple packets if( w->num_pcrs > w->pcr_list_alloced ) { temp = realloc( w->pcr_list, w->pcr_list_alloced * 2 * sizeof(int64_t) ); From ea148ff4af8074519b596070ee66f04d7c258a49 Mon Sep 17 00:00:00 2001 From: Kieran Kunhya Date: Fri, 14 Jun 2013 20:37:14 +0100 Subject: [PATCH 4/4] Fix build --- libmpegts.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libmpegts.c b/libmpegts.c index 1ad0e20..73c604d 100644 --- a/libmpegts.c +++ b/libmpegts.c @@ -187,6 +187,16 @@ static void write_iso_lang_descriptor( bs_t *s, ts_int_stream_t *stream ) } /**** PCR functions ****/ +static int64_t get_pcr_int( ts_writer_t *w, double offset ) +{ + return (int64_t)((8.0 * (w->packets_written * TS_PACKET_SIZE + offset) / w->ts_muxrate) * TS_CLOCK + 0.5) + w->pcr_start; +} + +static double get_pcr_double( ts_writer_t *w, double offset ) +{ + return (8.0 * (w->packets_written * TS_PACKET_SIZE + offset) / w->ts_muxrate) + (double)w->pcr_start / TS_CLOCK; +} + static int check_pcr( ts_writer_t *w, ts_int_program_t *program ) { // if the next packet written goes over the max pcr retransmit boundary, write the pcr in the next packet @@ -198,16 +208,6 @@ static int check_pcr( ts_writer_t *w, ts_int_program_t *program ) return 0; } -static int64_t get_pcr_int( ts_writer_t *w, double offset ) -{ - return (int64_t)((8.0 * (w->packets_written * TS_PACKET_SIZE + offset) / w->ts_muxrate) * TS_CLOCK + 0.5) + w->pcr_start; -} - -static double get_pcr_double( ts_writer_t *w, double offset ) -{ - return (8.0 * (w->packets_written * TS_PACKET_SIZE + offset) / w->ts_muxrate) + (double)w->pcr_start / TS_CLOCK; -} - /**** Buffer management ****/ static void add_to_buffer( buffer_t *buffer ) {