diff --git a/h222.c b/h222.c index 1d322ad..1b527cf 100644 --- a/h222.c +++ b/h222.c @@ -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)"; diff --git a/misc_fns.h b/misc_fns.h index 2a3c697..0cec33a 100644 --- a/misc_fns.h +++ b/misc_fns.h @@ -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: diff --git a/ts.c b/ts.c index 0bef0b0..10bdb66 100644 --- a/ts.c +++ b/ts.c @@ -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 }; diff --git a/tsreport.c b/tsreport.c index c7885bc..9b10f12 100644 --- a/tsreport.c +++ b/tsreport.c @@ -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)