gliese1337/HLS.js

Integer overflows when processing PTS

Closed this issue · 6 comments

When a single stream is processed for a while (around 5.5 hours) the PTS values actually get so large that they go past 2147479560 and overflow.

In the C code that the demuxer was ported from the use an unsigned 64 bit int to store the PTS values -- JavaScript is a bit different unfortunately and stores numbers as floats. For me this results in PTS values swappin' over to negative.

One solution would be to use BigInt but that is not supported in Internet Explorer.

Oo, good find. Porting the whole thing to WebAssembly would fix it, as well....

Just handling up to 64-bit values without BigInts shouldn't be too terribly difficult, though. You just need a pair of JS numbers, and some logic to handle overflow from the lower word to the upper word--much simpler than a generic BigNum library. I might be able to get to that in the next couple of weeks, if you or someone else doesn't submit a PR first.

@gliese1337 Just so I understand: in that solution would pts then be split into two parts (and so it would be up to the end user to combine them if they want the full value)?

@slifty Yes, that is the idea. Presumably, DTS would have the same issue; so, I'd probably keep the pts and dts fields to hold the lower-order bits for backwards compatibility and because that will handle the vast majority of use cases, and then add pts_high and dts_high for the extra high bits (and maybe add pts_low and dts_low as aliases for plain pts and dts).

@gliese1337 got it! That makes sense.

OK, I looked at this a little more in-depth, and a solution turns out to be not even as complex as I had thought. PTS values will totally fit inside a JS number, just not inside the signed-32-bit integers to which numbers are cast for bitwise operations. Simply replacing a bitshift and OR with a multiply and add for the 3 highest-order bits during decoding should solve the problem with no need for any API changes. So, that is what I have done.

Oh that's excellent!