kopia lustrzana https://github.com/kierank/libmpegts
Merge branch 'reconfig' into staging
commit
43b49f2567
2
common.h
2
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
|
||||
|
@ -287,6 +288,7 @@ struct ts_writer_t
|
|||
|
||||
uint64_t bytes_written;
|
||||
uint64_t packets_written;
|
||||
uint64_t pcr_start;
|
||||
|
||||
int ts_type;
|
||||
int ts_id;
|
||||
|
|
84
libmpegts.c
84
libmpegts.c
|
@ -197,29 +197,25 @@ static void write_opus_descriptor( bs_t *s, ts_int_stream_t *stream )
|
|||
}
|
||||
|
||||
/**** PCR functions ****/
|
||||
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;
|
||||
|
||||
if( next_pkt_pcr >= (double)w->pcr_period / 1000 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
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) + 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;
|
||||
}
|
||||
|
||||
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
|
||||
int64_t next_pkt_pcr = get_pcr_int( w, (TS_PACKET_SIZE + 7) * 8 ) - program->last_pcr;
|
||||
|
||||
if( next_pkt_pcr >= w->pcr_period * (TS_CLOCK/1000) )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**** Buffer management ****/
|
||||
|
@ -868,6 +864,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) );
|
||||
|
@ -1064,22 +1074,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
|
||||
|
||||
|
@ -1097,6 +1101,17 @@ int ts_setup_transport_stream( ts_writer_t *w, ts_main_t *params )
|
|||
return 0;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
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 )
|
||||
|
@ -1632,14 +1647,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;
|
||||
|
@ -2056,7 +2071,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++ )
|
||||
|
@ -2068,6 +2083,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) );
|
||||
|
|
|
@ -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
|
||||
*
|
||||
*/
|
||||
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 */
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue