Fix some PCR & PTS wrap issues

Also hadd a few H265 defs
master
John Cox 2014-08-19 16:58:29 +01:00
rodzic 15a7be8f75
commit 1265079d48
4 zmienionych plików z 80 dodań i 28 usunięć

2
h222.c
Wyświetl plik

@ -66,6 +66,8 @@ extern const char *h222_stream_type_str(unsigned s)
case 0x19: return "Metadata in 13818-6 Synchronized Download Protocol";
case 0x1A: return "13818-11 MPEG-2 IPMP stream";
case 0x1B: return "H.264/14496-10 video (MPEG-4/AVC)";
case 0x24: return "HEVC video stream";
case 0x25: return "HEVC temporal video subset (profile Annex A H.265)";
case 0x42: return "AVS Video";
case 0x7F: return "IPMP stream";
case 0x81: return "User private (commonly Dolby/AC-3 in ATSC)";

Wyświetl plik

@ -436,9 +436,9 @@ static inline uint32_t uint_32_be(const uint8_t *const p)
static inline uint32_t uint_32_le(const uint8_t *const p)
{
return (((int)p[0]&0xff) |
(((int)p[1]&0xff) << 8) |
(((int)p[2]&0xff) << 16) |
(((int)p[3]&0xff) << 24));
(((int)p[1]&0xff) << 8) |
(((int)p[2]&0xff) << 16) |
(((int)p[3]&0xff) << 24));
}
@ -455,6 +455,52 @@ static inline uint16_t uint_16_le(const uint8_t *const p)
}
// ============================================================
// Time diffs
// ============================================================
#define PCR_UNSIGNED_WRAP (300ULL * (1ULL << 33))
// (x - y) with allowance for PCR wrap - unsigned version
static inline uint64_t
pcr_unsigned_diff(uint64_t x, uint64_t y)
{
return x > y ? x - y :
300ULL * (1ULL << 33) - (y - x);
}
#define PCR_SIGNED_WRAP (300LL * (1LL << 33))
#define PCR_SIGNED_MAX (PCR_SIGNED_WRAP / 2LL - 1LL)
#define PCR_SIGNED_MIN (-PCR_SIGNED_WRAP / 2LL)
// (x - y) with allowance for PCR wrap - signed version
static inline int64_t
pcr_signed_diff(uint64_t x, uint64_t y)
{
int64_t r = x - y;
return r < PCR_SIGNED_MIN ? r + PCR_SIGNED_WRAP :
r > PCR_SIGNED_MAX ? r - PCR_SIGNED_WRAP :
r;
}
// Deal with simple overflow
static inline uint64_t
pcr_unsigned_wrap(uint64_t x)
{
return x >= PCR_UNSIGNED_WRAP ? x - PCR_UNSIGNED_WRAP : x;
}
static inline int64_t
pts_signed_diff(uint64_t x, uint64_t y)
{
int64_t r = x - y;
return (r << 31) >> 31;
}
#endif // _misc_fns
// Local Variables:

24
ts.c
Wyświetl plik

@ -66,6 +66,7 @@ static int report_bad_reserved_bits = FALSE;
// library module...)
static int continuity_counter[0x1fff+1] = {0};
/*
* Return the next value of continuity_counter for the given pid
*/
@ -1590,8 +1591,8 @@ static int fill_TS_packet_buffer(TS_reader_p tsreader)
{
tsreader->pcrbuf->TS_buffer_prev_pcr = tsreader->pcrbuf->TS_buffer_end_pcr;
tsreader->pcrbuf->TS_buffer_end_pcr = pcr;
tsreader->pcrbuf->TS_buffer_time_per_TS = (tsreader->pcrbuf->TS_buffer_end_pcr -
tsreader->pcrbuf->TS_buffer_prev_pcr) /
tsreader->pcrbuf->TS_buffer_time_per_TS =
pcr_unsigned_diff(tsreader->pcrbuf->TS_buffer_end_pcr, tsreader->pcrbuf->TS_buffer_prev_pcr) /
tsreader->pcrbuf->TS_buffer_len;
return 0;
}
@ -1766,9 +1767,9 @@ extern int read_next_TS_packet_from_buffer(TS_reader_p tsreader,
}
else
{
*pcr = tsreader->pcrbuf->TS_buffer_prev_pcr +
*pcr = pcr_unsigned_wrap(tsreader->pcrbuf->TS_buffer_prev_pcr +
tsreader->pcrbuf->TS_buffer_time_per_TS *
tsreader->pcrbuf->TS_buffer_next;
tsreader->pcrbuf->TS_buffer_next);
}
return 0;
}
@ -2019,10 +2020,10 @@ extern void report_adaptation_timing(timing_p times,
{
fprint_msg(" Mean byterate %7" LLU_FORMAT_STUMP,
((packet_count - times->first_pcr_packet) * TS_PACKET_SIZE) *
TWENTY_SEVEN_MHZ / (pcr - times->first_pcr));
TWENTY_SEVEN_MHZ / pcr_unsigned_diff(pcr, times->first_pcr));
fprint_msg(" byterate %7" LLU_FORMAT_STUMP,
((packet_count - times->last_pcr_packet) * TS_PACKET_SIZE) *
TWENTY_SEVEN_MHZ / (pcr - times->last_pcr));
TWENTY_SEVEN_MHZ / pcr_unsigned_diff(pcr, times->last_pcr));
}
}
times->last_pcr_packet = packet_count;
@ -2303,6 +2304,17 @@ static const char * const descriptor_names[] =
"J2K video descriptor", // 50
"MVC operation point descriptor", // 51
"MPEG2 stereoscopic video format", // 52
"Stereoscopic_program_info_descriptor", // 53
"Stereoscopic_video_info_descriptor", // 54
"Transport_profile_descriptor", // 55
"HEVC video descriptor", // 56
"Reserved (57)", // 57
"Reserved (58)", // 58
"Reserved (59)", // 59
"Reserved (60)", // 60
"Reserved (61)", // 61
"Reserved (62)", // 62
"Extension descriptor", // 63
};

Wyświetl plik

@ -147,14 +147,6 @@ 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)
{
@ -403,7 +395,7 @@ static int report_buffering_stats(TS_reader_p tsreader,
// given the previous two PCRs and a linear rate?
uint64_t guess_pcr = estimate_pcr(posn,predict.prev_pcr_posn,
predict.prev_pcr,predict.pcr_rate);
int64_t delta = adapt_pcr - guess_pcr;
int64_t delta = pcr_signed_diff(adapt_pcr, guess_pcr);
if (delta < predict.min_pcr_error)
predict.min_pcr_error = delta;
if (delta > predict.max_pcr_error)
@ -420,7 +412,7 @@ static int report_buffering_stats(TS_reader_p tsreader,
if (predict.had_a_pcr)
{
if (predict.prev_pcr > adapt_pcr)
if (pcr_signed_diff(predict.prev_pcr, adapt_pcr) > 0)
{
fprint_err("!!! PCR %s at TS packet "
OFFSET_T_FORMAT " is not more than previous PCR %s\n",
@ -430,7 +422,7 @@ static int report_buffering_stats(TS_reader_p tsreader,
}
else
{
uint64_t delta_pcr = adapt_pcr - predict.prev_pcr;
uint64_t delta_pcr = pcr_unsigned_diff(adapt_pcr, predict.prev_pcr);
int delta_bytes = (int)(posn - predict.prev_pcr_posn);
predict.pcr_rate = ((double)delta_bytes * 27.0 / (double)delta_pcr) * 1000000.0;
predict.know_pcr_rate = TRUE;
@ -634,11 +626,11 @@ static int report_buffering_stats(TS_reader_p tsreader,
if (!got_pts)
continue;
pcr_time_now_div300 = acc_pcr/300;
pcr_time_now_div300 = acc_pcr/300ULL;
// Do a few simple checks
// For the sake of simplicity we ignore 33bit wrap...
if (stats[index].pts < stats[index].dts)
if (pts_signed_diff(stats[index].pts, stats[index].dts) < 0)
{
if (stats[index].err_pts_lt_dts++ == 0)
fprint_msg("### PID(%d): PTS (%s) < DTS (%s)\n",
@ -648,7 +640,7 @@ static int report_buffering_stats(TS_reader_p tsreader,
}
if (stats[index].had_a_dts)
{
int64_t dts_dts_diff = stats[index].dts - last_dts;
int64_t dts_dts_diff = pts_signed_diff(stats[index].dts, last_dts);
if (dts_dts_diff < stats[index].dts_dts_min)
stats[index].dts_dts_min = (long)dts_dts_diff;
if (dts_dts_diff > stats[index].dts_dts_max)
@ -663,7 +655,7 @@ static int report_buffering_stats(TS_reader_p tsreader,
fmtx_timestamp(last_dts, tfmt_abs));
}
}
if (stats[index].dts < pcr_time_now_div300)
if (pts_signed_diff(stats[index].dts, pcr_time_now_div300) < 0)
{
if (stats[index].err_dts_lt_pcr++ == 0)
fprint_msg("### PID(%d): DTS (%s) < PCR (%s)\n",
@ -736,7 +728,7 @@ static int report_buffering_stats(TS_reader_p tsreader,
IS_VIDEO_STREAM_TYPE(stats[index].stream_type)?"video":"");
}
difference = stats[index].pts - pcr_time_now_div300;
difference = pts_signed_diff(stats[index].pts, pcr_time_now_div300);
if (verbose)
{
fprint_msg(" PTS " LLU_FORMAT,stats[index].pts);
@ -760,7 +752,7 @@ static int report_buffering_stats(TS_reader_p tsreader,
if (got_dts)
{
difference = stats[index].dts - pcr_time_now_div300;
difference = pts_signed_diff(stats[index].dts, pcr_time_now_div300);
if (verbose)
{
fprint_msg(" DTS " LLU_FORMAT,stats[index].dts);
@ -802,7 +794,7 @@ static int report_buffering_stats(TS_reader_p tsreader,
if (predict.had_a_pcr && predict.prev_pcr_posn > first_pcr_posn)
{
// Multiply by 8 at the end to give us a bit more headroom in file size
int rate = (int)((predict.prev_pcr_posn - first_pcr_posn) * 27000000LL / (predict.prev_pcr - first_pcr)) * 8;
int rate = (int)((predict.prev_pcr_posn - first_pcr_posn) * 27000000LL / pcr_unsigned_diff(predict.prev_pcr, first_pcr)) * 8;
fprint_msg("Overall stream rate=%d bits/sec\n", rate);
}
@ -875,7 +867,7 @@ static int report_buffering_stats(TS_reader_p tsreader,
{
// Calculate rate over the range of PCRs seen in this stream
uint64_t avg = ss->pcr == ss->first_pcr ? 0LL :
((ss->ts_bytes - 188LL) * 8LL * 27000000LL) / (ss->pcr - ss->first_pcr);
((ss->ts_bytes - 188LL) * 8LL * 27000000LL) / pcr_unsigned_diff(ss->pcr, ss->first_pcr);
fprint_msg(" Stream: %llu bytes; rate: avg %llu bits/s, max %llu bits/s\n", ss->ts_bytes, avg, ss->rate.max_rate);
}
if (ss->discontinuity_flag_count != 0)