Preserve native broadcast video and add patient shared stream startup
This commit is contained in:
@@ -26,7 +26,28 @@ public static class TransportStreamClock
|
||||
}
|
||||
private static bool Pes(byte[] data, int start, int p) => p >= 0 && (data[start + 1] & 64) != 0 && p + 14 <= start + 188
|
||||
&& data[p] == 0 && data[p + 1] == 0 && data[p + 2] == 1 && (data[p + 7] & 128) != 0;
|
||||
public static byte[] Rebase(byte[] input, long videoStart90k, bool alignAudio = true)
|
||||
public static (long Decode, long Earliest, long Latest)? ClockBounds(byte[] input)
|
||||
{
|
||||
if (input.Length % 188 != 0) return null;
|
||||
long? decode = null;
|
||||
var times = new List<long>();
|
||||
for (var start = 0; start < input.Length; start += 188)
|
||||
{
|
||||
var p = Payload(input, start);
|
||||
if (!Pes(input, start, p)) continue;
|
||||
var pts = ReadPts(input, p + 9);
|
||||
times.Add(pts);
|
||||
var dts = (input[p + 7] & 192) == 192 && p + 19 <= start + 188 ? ReadPts(input, p + 14) : pts;
|
||||
times.Add(dts);
|
||||
if (decode == null && input[p + 3] >= 224 && input[p + 3] <= 239) decode = dts;
|
||||
}
|
||||
if (decode == null) return null;
|
||||
long Unwrap(long value) => decode.Value + ((value - decode.Value + (1L << 32)) & ClockMask) - (1L << 32);
|
||||
long min = decode.Value, max = decode.Value;
|
||||
foreach (var time in times) { var value = Unwrap(time); min = Math.Min(min, value); max = Math.Max(max, value); }
|
||||
return (decode.Value, min, max);
|
||||
}
|
||||
public static byte[] Rebase(byte[] input, long videoStart90k, bool alignAudio = true, long? offset90k = null)
|
||||
{
|
||||
if (input.Length % 188 != 0) throw new InvalidDataException("Unaligned MPEG-TS segment");
|
||||
long? firstVideo = null, firstAudio = null;
|
||||
@@ -40,7 +61,7 @@ public static class TransportStreamClock
|
||||
if (firstVideo != null && firstAudio != null) break;
|
||||
}
|
||||
if (firstVideo == null) throw new InvalidDataException("MPEG-TS segment lacks a video presentation timestamp");
|
||||
var offset = videoStart90k - firstVideo.Value;
|
||||
var offset = offset90k ?? (videoStart90k - firstVideo.Value);
|
||||
// Independent AAC encoders and HLS boundaries have different priming
|
||||
// offsets. Anchor the first audio PES of each segment as well, so a
|
||||
// switch cannot send an audio timestamp backwards by a few milliseconds.
|
||||
|
||||
Reference in New Issue
Block a user