[FFmpeg-devel] [PATCH] [libavutil] Add saturated add/sub operations for int64_t.
Dale Curtis
dalecurtis at chromium.org
Tue May 5 00:19:47 EEST 2020
On Mon, May 4, 2020 at 1:48 PM Michael Niedermayer <michael at niedermayer.cc>
wrote:
> this could be done, but iam unsure this API is optimal
>
> Maybe its best to show an example, why iam unsure about the API
>
Thanks, but maybe a more concrete case to look at would be the patch I sent
for fixing skip samples: "Avoid integer overflow on start_time with
skip_samples." Here's the current proposed fix:
@@ -1155,8 +1155,11 @@ static void
update_initial_timestamps(AVFormatContext *s, int stream_index,
if (st->start_time == AV_NOPTS_VALUE && pktl_it->pkt.pts !=
AV_NOPTS_VALUE) {
st->start_time = pktl_it->pkt.pts;
- if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
st->codecpar->sample_rate)
- st->start_time += av_rescale_q(st->skip_samples,
(AVRational){1, st->codecpar->sample_rate}, st->time_base);
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
st->codecpar->sample_rate) {
+ int64_t skip_time = av_rescale_q(st->skip_samples,
(AVRational){1, st->codecpar->sample_rate}, st->time_base);
+ if (st->start_time > 0 ? skip_time <= INT64_MAX -
st->start_time : skip_time >= INT64_MIN - st->start_time)
+ st->start_time += skip_time;
+ }
}
}
With the APIs we're discussing the new fix would be either:
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
st->codecpar->sample_rate)
- st->start_time += av_rescale_q(st->skip_samples,
(AVRational){1, st->codecpar->sample_rate}, st->time_base);
+ st->start_time = av_sat_add64(st->start_time,
av_rescale_q(st->skip_samples, (AVRational){1, st->codecpar->sample_rate},
st->time_base))
or with checked overflow:
- if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
st->codecpar->sample_rate)
- st->start_time += av_rescale_q(st->skip_samples,
(AVRational){1, st->codecpar->sample_rate}, st->time_base);
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
st->codecpar->sample_rate) {
+ int64_t tmp;
+ if (!av_checked_sat_add64(st->start_time,
av_rescale_q(st->skip_samples, (AVRational){1, st->codecpar->sample_rate},
st->time_base), &tmp))
+ st->start_time = tmp;
+ }
> lets consider a simple random expression
> a*x + b*y
>
> overflow = av_checked_sat_mul64(a, x, &T0);
> overflow |= av_checked_sat_mul64(b, y, &T1);
> overflow |= av_checked_sat_add64(T0, T1, &result);
> if (overflow)
> ...
>
> vs.
>
> int64_t result = av_add_eint64( av_mul_eint64(a, x),
> av_mul_eint64(b, y) );
> if (!av_is_finite_eint64(result))
> ....
>
> To me the 2nd variant looks easier to read, (eint here is supposed to mean
> extended integer, that is extended by +/- infinity and NaN with IEEE like
> semantics)
> also the NaN element should have the same value as AV_NOPTS_VALUE, that
> would
> likely be most usefull.
> This could also allow the removial of alot of AV_NOPTS_VALUE special
> casing ...
>
Are you just proposing sentinel values for those extensions? E.g., +inf =
INT64_MAX, -inf=-INT64_MAX, nan=INT64_MIN? It seems like you could just
layer that on top of the saturated versions I'm proposing here. I don't
think I'd recommend that solution though, instead it seems more legible and
familiar to just use a float/double type in those cases where it'd be
relevant. Once you start introducing sentinel checks everywhere, I doubt
you'd keep much if any performance over a known type like float/double.
>
> But this is independant of the pure integer saturation API and should
> probably
> not hold it up when that itself is needed.
>
> thx
>
More information about the ffmpeg-devel
mailing list