private static Interpolator interpolatorFor(PointF cp1, PointF cp2) {
    Interpolator interpolator = null;
    cp1.x = MiscUtils.clamp(cp1.x, -1f, 1f);
    cp1.y = MiscUtils.clamp(cp1.y, -MAX_CP_VALUE, MAX_CP_VALUE);
    cp2.x = MiscUtils.clamp(cp2.x, -1f, 1f);
    cp2.y = MiscUtils.clamp(cp2.y, -MAX_CP_VALUE, MAX_CP_VALUE);
    int hash = Utils.hashFor(cp1.x, cp1.y, cp2.x, cp2.y);
    WeakReference<Interpolator> interpolatorRef = L.getDisablePathInterpolatorCache() ? null : getInterpolator(hash);
    if (interpolatorRef != null) {
      interpolator = interpolatorRef.get();
    }
    if (interpolatorRef == null || interpolator == null) {
      try {
        interpolator = PathInterpolatorCompat.create(cp1.x, cp1.y, cp2.x, cp2.y);
      } catch (IllegalArgumentException e) {
        if ("The Path cannot loop back on itself.".equals(e.getMessage())) {
          // If a control point extends beyond the previous/next point then it will cause the value of the interpolator to no
          // longer monotonously increase. This clips the control point bounds to prevent that from happening.
          // NOTE: this will make the rendered animation behave slightly differently than the original.
          interpolator = PathInterpolatorCompat.create(Math.min(cp1.x, 1f), cp1.y, Math.max(cp2.x, 0f), cp2.y);
        } else {
          // We failed to create the interpolator. Fall back to linear.
          interpolator = new LinearInterpolator();
        }
      }
      if (!L.getDisablePathInterpolatorCache()) {
        try {
          putInterpolator(hash, new WeakReference<>(interpolator));
        } catch (ArrayIndexOutOfBoundsException e) {
          // It is not clear why but SparseArrayCompat sometimes fails with this:
          //     https://github.com/airbnb/lottie-android/issues/452
          // Because this is not a critical operation, we can safely just ignore it.
          // I was unable to repro this to attempt a proper fix.
        }
      }
    }
    return interpolator;
  }
beginObject will already be called on the keyframe so it can be differentiated with
a non animated value.
lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java