((uint64_t)(d[pos+2] & 3) << 13) |
((uint64_t)(d[pos+3]) << 5) |
(d[pos+4] >> 3);
+ // we declare a discontinuity if there's a gap of more than
+ // 100ms between the last scr & this or if this scr goes back
+ // by more than half a frame time.
int64_t scr_delta = scr - state->last_scr;
- if ( scr_delta > (90*700) || scr_delta < 0 )
+ if ( scr_delta > 90*100 || scr_delta < -90*10 )
{
++state->scr_changes;
- state->scr_offset += scr_delta - state->frame_duration;
}
state->last_scr = scr;
}
{
dts = pts;
}
+ if ( state && state->flaky_clock )
+ {
+ // Program streams have an SCR in every PACK header so they
+ // can't lose their clock reference. But the PCR in Transport
+ // streams is typically on <.1% of the packets. If a PCR
+ // packet gets lost and it marks a clock discontinuity then
+ // the data following it will be referenced to the wrong
+ // clock & introduce huge gaps or throw our A/V sync off.
+ // We try to protect against that here by sanity checking
+ // timestamps against the current reference clock and discarding
+ // packets where the DTS is "too far" from its clock.
+ int64_t fdelta = dts - state->last_scr;
+ if ( fdelta < -300 * 90000LL || fdelta > 300 * 90000LL )
+ {
+ // packet too far behind or ahead of its clock reference
+ ++state->dts_drops;
+ pos = pes_packet_end;
+ continue;
+ }
+ }
}
pos = pes_header_end;