Added max bitrate calculation code to buffering report

--HG--
extra : convert_revision : svn%3Aeff31bef-be4a-0410-a8fe-e47997df2690/trunk%40152
issue20
jc44 2009-12-03 12:04:12 +00:00
rodzic b844aaf880
commit 029940f3c2
1 zmienionych plików z 105 dodań i 1 usunięć

Wyświetl plik

@ -77,6 +77,21 @@ struct diff_from_pcr
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 {
uint32_t pid;
int stream_type;
@ -92,6 +107,7 @@ struct stream_data {
// PTS/DTS in the file, when we're finishing up
uint64_t pts;
uint64_t dts;
uint64_t pcr;
int err_pts_lt_dts;
int err_dts_lt_prev_dts;
@ -103,6 +119,11 @@ struct stream_data {
struct diff_from_pcr pcr_dts_diff;
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,
@ -116,6 +137,59 @@ static int pid_index(struct stream_data *data,
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
*
@ -178,6 +252,7 @@ static int report_buffering_stats(TS_reader_p tsreader,
stats[ii].pcr_dts_diff.min = LONG_MAX;
stats[ii].pcr_pts_diff.max = LONG_MIN;
stats[ii].pcr_dts_diff.max = LONG_MIN;
stats[ii].first_pcr = ~(uint64_t)0;
stats[ii].last_cc = -1;
}
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_posn = posn;
}
{
int i;
for (i = 0; i != num_streams; ++i)
{
stats[i].pcr_seen = TRUE;
}
}
} // 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;
}
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)
{
// 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].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)
fprint_msg(" ### CC error * %d\n", stats[ii].err_cc_error);
if (stats[ii].err_cc_dup_error != 0)
@ -1031,7 +1134,8 @@ static void print_usage()
"Buffering information:\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"
" 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"
" -32 Truncate 33 bit values in the CSV output to 32 bits\n"
" (losing the top bit).\n"