kopia lustrzana https://github.com/F5OEO/tstools
Added max bitrate calculation code to buffering report
--HG-- extra : convert_revision : svn%3Aeff31bef-be4a-0410-a8fe-e47997df2690/trunk%40152issue20
rodzic
b844aaf880
commit
029940f3c2
106
tsreport.c
106
tsreport.c
|
@ -77,6 +77,21 @@ struct diff_from_pcr
|
||||||
unsigned int num; // the number of TS records compared
|
unsigned int num; // the number of TS records compared
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct avg_rate_elss
|
||||||
|
{
|
||||||
|
uint64_t time;
|
||||||
|
uint64_t bytes;
|
||||||
|
} avg_rate_el_t;
|
||||||
|
|
||||||
|
typedef struct avg_ratess
|
||||||
|
{
|
||||||
|
unsigned int max_els;
|
||||||
|
unsigned int in_el;
|
||||||
|
unsigned int out_el;
|
||||||
|
avg_rate_el_t * els;
|
||||||
|
uint64_t max_rate;
|
||||||
|
} avg_rate_t;
|
||||||
|
|
||||||
struct stream_data {
|
struct stream_data {
|
||||||
uint32_t pid;
|
uint32_t pid;
|
||||||
int stream_type;
|
int stream_type;
|
||||||
|
@ -92,6 +107,7 @@ struct stream_data {
|
||||||
// PTS/DTS in the file, when we're finishing up
|
// PTS/DTS in the file, when we're finishing up
|
||||||
uint64_t pts;
|
uint64_t pts;
|
||||||
uint64_t dts;
|
uint64_t dts;
|
||||||
|
uint64_t pcr;
|
||||||
|
|
||||||
int err_pts_lt_dts;
|
int err_pts_lt_dts;
|
||||||
int err_dts_lt_prev_dts;
|
int err_dts_lt_prev_dts;
|
||||||
|
@ -103,6 +119,11 @@ struct stream_data {
|
||||||
struct diff_from_pcr pcr_dts_diff;
|
struct diff_from_pcr pcr_dts_diff;
|
||||||
|
|
||||||
int pts_ne_dts;
|
int pts_ne_dts;
|
||||||
|
|
||||||
|
int pcr_seen;
|
||||||
|
uint64_t first_pcr;
|
||||||
|
uint64_t ts_bytes;
|
||||||
|
avg_rate_t rate;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pid_index(struct stream_data *data,
|
static int pid_index(struct stream_data *data,
|
||||||
|
@ -116,6 +137,59 @@ static int pid_index(struct stream_data *data,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (x - y) with allowance for PCR wrap - unsigned version
|
||||||
|
static uint64_t
|
||||||
|
pcr_unsigned_diff(uint64_t x, uint64_t y)
|
||||||
|
{
|
||||||
|
return x > y ? x - y :
|
||||||
|
300ULL * (1ULL << 33) - (y - x);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
avg_rate_inc(avg_rate_t * ar, unsigned int n)
|
||||||
|
{
|
||||||
|
return n + 1 >= ar->max_els ? 0 : n + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
avg_rate_add(avg_rate_t * ar, uint64_t time, uint64_t bytes)
|
||||||
|
{
|
||||||
|
uint64_t gap = 27000000 / 2; // 0.5 sec
|
||||||
|
uint64_t delta_b;
|
||||||
|
uint64_t delta_t;
|
||||||
|
uint64_t rate;
|
||||||
|
|
||||||
|
if (ar->els == NULL)
|
||||||
|
{
|
||||||
|
ar->max_els = 1024;
|
||||||
|
ar->els = calloc(ar->max_els, sizeof(ar->els[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ar->in_el != ar->out_el && pcr_unsigned_diff(time, ar->els[ar->out_el].time) > gap)
|
||||||
|
{
|
||||||
|
ar->out_el = avg_rate_inc(ar, ar->out_el);
|
||||||
|
}
|
||||||
|
|
||||||
|
ar->els[ar->in_el].time = time;
|
||||||
|
ar->els[ar->in_el].bytes = bytes;
|
||||||
|
|
||||||
|
delta_b = bytes - ar->els[ar->out_el].bytes;
|
||||||
|
delta_t = pcr_unsigned_diff(time, ar->els[ar->out_el].time);
|
||||||
|
|
||||||
|
if (delta_t != 0)
|
||||||
|
{
|
||||||
|
rate = (delta_b * 8LL * 27000000LL) / delta_t;
|
||||||
|
if (rate > ar->max_rate)
|
||||||
|
{
|
||||||
|
ar->max_rate = rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ar->in_el = avg_rate_inc(ar, ar->in_el);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Report on the given file
|
* Report on the given file
|
||||||
*
|
*
|
||||||
|
@ -178,6 +252,7 @@ static int report_buffering_stats(TS_reader_p tsreader,
|
||||||
stats[ii].pcr_dts_diff.min = LONG_MAX;
|
stats[ii].pcr_dts_diff.min = LONG_MAX;
|
||||||
stats[ii].pcr_pts_diff.max = LONG_MIN;
|
stats[ii].pcr_pts_diff.max = LONG_MIN;
|
||||||
stats[ii].pcr_dts_diff.max = LONG_MIN;
|
stats[ii].pcr_dts_diff.max = LONG_MIN;
|
||||||
|
stats[ii].first_pcr = ~(uint64_t)0;
|
||||||
stats[ii].last_cc = -1;
|
stats[ii].last_cc = -1;
|
||||||
}
|
}
|
||||||
predict.min_pcr_error = LONG_MAX;
|
predict.min_pcr_error = LONG_MAX;
|
||||||
|
@ -355,6 +430,14 @@ static int report_buffering_stats(TS_reader_p tsreader,
|
||||||
predict.prev_pcr = adapt_pcr;
|
predict.prev_pcr = adapt_pcr;
|
||||||
predict.prev_pcr_posn = posn;
|
predict.prev_pcr_posn = posn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i != num_streams; ++i)
|
||||||
|
{
|
||||||
|
stats[i].pcr_seen = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
} // end of working with a PCR PID packet
|
} // end of working with a PCR PID packet
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|
||||||
|
@ -405,6 +488,19 @@ static int report_buffering_stats(TS_reader_p tsreader,
|
||||||
stats[index].last_cc = cc;
|
stats[index].last_cc = cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
if (stats[index].pcr_seen)
|
||||||
|
{
|
||||||
|
stats[index].pcr_seen = FALSE;
|
||||||
|
avg_rate_add(&stats[index].rate, acc_pcr, stats[index].ts_bytes);
|
||||||
|
}
|
||||||
|
if (stats[index].first_pcr == ~(uint64_t)0)
|
||||||
|
stats[index].first_pcr = acc_pcr;
|
||||||
|
stats[index].pcr = acc_pcr;
|
||||||
|
stats[index].ts_bytes += 188;
|
||||||
|
}
|
||||||
|
|
||||||
if (index != -1 && payload && payload_unit_start_indicator)
|
if (index != -1 && payload && payload_unit_start_indicator)
|
||||||
{
|
{
|
||||||
// We are the start of a PES packet
|
// We are the start of a PES packet
|
||||||
|
@ -648,6 +744,13 @@ static int report_buffering_stats(TS_reader_p tsreader,
|
||||||
fmtx_timestamp(stats[ii].first_dts, tfmt_abs),
|
fmtx_timestamp(stats[ii].first_dts, tfmt_abs),
|
||||||
fmtx_timestamp(stats[ii].dts, tfmt_abs));
|
fmtx_timestamp(stats[ii].dts, tfmt_abs));
|
||||||
|
|
||||||
|
{
|
||||||
|
// Calculate rate over the range of PCRs seen in this stream
|
||||||
|
uint64_t avg = stats[ii].pcr == stats[ii].first_pcr ? 0LL :
|
||||||
|
((stats[ii].ts_bytes - 188LL) * 8LL * 27000000LL) / (stats[ii].pcr - stats[ii].first_pcr);
|
||||||
|
fprint_msg(" Stream: %llu bytes; rate: avg %llu bits/s, max %llu bits/s\n", stats[ii].ts_bytes, avg, stats[ii].rate.max_rate);
|
||||||
|
}
|
||||||
|
|
||||||
if (stats[ii].err_cc_error != 0)
|
if (stats[ii].err_cc_error != 0)
|
||||||
fprint_msg(" ### CC error * %d\n", stats[ii].err_cc_error);
|
fprint_msg(" ### CC error * %d\n", stats[ii].err_cc_error);
|
||||||
if (stats[ii].err_cc_dup_error != 0)
|
if (stats[ii].err_cc_dup_error != 0)
|
||||||
|
@ -1031,7 +1134,8 @@ static void print_usage()
|
||||||
"Buffering information:\n"
|
"Buffering information:\n"
|
||||||
" -buffering, -b Report on the differences between PCR and PTS, and\n"
|
" -buffering, -b Report on the differences between PCR and PTS, and\n"
|
||||||
" between PCR and DTS. This is relevant to the size of\n"
|
" between PCR and DTS. This is relevant to the size of\n"
|
||||||
" buffers needed in the decoder.\n"
|
" buffers needed in the decoder. Also reports bitrates;\n"
|
||||||
|
" the max bitrate is calculated over 0.5sec\n"
|
||||||
" -o <file> Output CSV data for -buffering to the named file.\n"
|
" -o <file> Output CSV data for -buffering to the named file.\n"
|
||||||
" -32 Truncate 33 bit values in the CSV output to 32 bits\n"
|
" -32 Truncate 33 bit values in the CSV output to 32 bits\n"
|
||||||
" (losing the top bit).\n"
|
" (losing the top bit).\n"
|
||||||
|
|
Ładowanie…
Reference in New Issue