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_PACKET_SIZE 188
|
||||||
#define TS_CLOCK 27000000LL
|
#define TS_CLOCK 27000000LL
|
||||||
#define TS_START 10
|
#define TS_START 10
|
||||||
|
#define TIMESTAMP_CLOCK 90000LL
|
||||||
|
|
||||||
// arbitrary
|
// arbitrary
|
||||||
#define MAX_PROGRAMS 100
|
#define MAX_PROGRAMS 100
|
||||||
|
@ -287,6 +288,7 @@ struct ts_writer_t
|
||||||
|
|
||||||
uint64_t bytes_written;
|
uint64_t bytes_written;
|
||||||
uint64_t packets_written;
|
uint64_t packets_written;
|
||||||
|
uint64_t pcr_start;
|
||||||
|
|
||||||
int ts_type;
|
int ts_type;
|
||||||
int ts_id;
|
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 ****/
|
/**** 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 )
|
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 )
|
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 ****/
|
/**** Buffer management ****/
|
||||||
|
@ -868,6 +864,20 @@ static int check_bitstream( ts_writer_t *w )
|
||||||
return 0;
|
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 *ts_create_writer( void )
|
||||||
{
|
{
|
||||||
ts_writer_t *w = calloc( 1, sizeof(*w) );
|
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;
|
cur_program->pcr_stream = pcr_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
w->ts_id = params->ts_id;
|
update_ts_params( w, params );
|
||||||
w->ts_muxrate = params->muxrate;
|
|
||||||
w->cbr = params->cbr;
|
|
||||||
w->ts_type = params->ts_type;
|
|
||||||
w->network_pid = params->network_pid;
|
w->network_pid = params->network_pid;
|
||||||
w->legacy_constraints = params->legacy_constraints;
|
w->ts_type = params->ts_type;
|
||||||
|
|
||||||
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->network_id = params->network_id ? params->network_id : DEFAULT_NID;
|
w->network_id = params->network_id ? params->network_id : DEFAULT_NID;
|
||||||
|
w->ts_id = params->ts_id;
|
||||||
w->tb.buf_size = TB_SIZE;
|
w->tb.buf_size = TB_SIZE;
|
||||||
w->rx_sys = RX_SYS;
|
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
|
// FIXME realloc if necessary
|
||||||
|
|
||||||
|
@ -1097,6 +1101,17 @@ int ts_setup_transport_stream( ts_writer_t *w, ts_main_t *params )
|
||||||
return 0;
|
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 */
|
/* 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 )
|
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]->stream = stream;
|
||||||
new_pes[i]->random_access = !!frames[i].random_access;
|
new_pes[i]->random_access = !!frames[i].random_access;
|
||||||
new_pes[i]->priority = !!frames[i].priority;
|
new_pes[i]->priority = !!frames[i].priority;
|
||||||
new_pes[i]->dts = frames[i].dts + TS_START * 90000LL;
|
new_pes[i]->dts = frames[i].dts + TS_START * TIMESTAMP_CLOCK;
|
||||||
new_pes[i]->pts = frames[i].pts + TS_START * 90000LL;
|
new_pes[i]->pts = frames[i].pts + TS_START * TIMESTAMP_CLOCK;
|
||||||
|
|
||||||
if( IS_VIDEO( stream ) )
|
if( IS_VIDEO( stream ) )
|
||||||
{
|
{
|
||||||
new_pes[i]->frame_type = frames[i].frame_type;
|
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]->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 * 27000000LL;
|
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]->ref_pic_idc = frames[i].ref_pic_idc;
|
||||||
new_pes[i]->write_pulldown_info = frames[i].write_pulldown_info;
|
new_pes[i]->write_pulldown_info = frames[i].write_pulldown_info;
|
||||||
new_pes[i]->pic_struct = frames[i].pic_struct;
|
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
|
// TODO do this for all programs
|
||||||
ts_int_program_t *program = w->programs[0];
|
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?) */
|
/* buffer drip (TODO: all buffers?) */
|
||||||
drip_buffer( w, program, w->rx_sys, &w->tb, next_pcr );
|
drip_buffer( w, program, w->rx_sys, &w->tb, next_pcr );
|
||||||
for( int i = 0; i < program->num_streams; i++ )
|
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 )
|
if( !imaginary )
|
||||||
{
|
{
|
||||||
|
// FIXME this is wrong for multiple packets
|
||||||
if( w->num_pcrs > w->pcr_list_alloced )
|
if( w->num_pcrs > w->pcr_list_alloced )
|
||||||
{
|
{
|
||||||
temp = realloc( w->pcr_list, w->pcr_list_alloced * 2 * sizeof(int64_t) );
|
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 );
|
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 ****/
|
/**** Additional Codec-Specific functions ****/
|
||||||
/* Many formats require extra information. Setup the relevant information using the following functions */
|
/* Many formats require extra information. Setup the relevant information using the following functions */
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue