Add setMinAndMaxFrame with 2 markers (#1448)

Fixes #1395
diff --git a/After Effects Samples/RGBMarker.aep b/After Effects Samples/RGBMarker.aep
new file mode 100644
index 0000000..cd9bfbd
--- /dev/null
+++ b/After Effects Samples/RGBMarker.aep
Binary files differ
diff --git a/LottieSample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt b/LottieSample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt
index a4ac57e..75568e6 100644
--- a/LottieSample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt
+++ b/LottieSample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt
@@ -767,6 +767,26 @@
             drawable.setMinAndMaxFrame("Marker A")
             drawable.frame = drawable.maxFrame.toInt()
         }
+
+        withDrawable("Tests/RGBMarker.json", "Marker", "->[Green, Blue)") { drawable ->
+            drawable.setMinAndMaxFrame("Green Section", "Blue Section", false)
+            drawable.frame = drawable.minFrame.toInt()
+        }
+
+        withDrawable("Tests/RGBMarker.json", "Marker", "->[Green, Blue]") { drawable ->
+            drawable.setMinAndMaxFrame("Green Section", "Blue Section", true)
+            drawable.frame = drawable.minFrame.toInt()
+        }
+
+        withDrawable("Tests/RGBMarker.json", "Marker", "[Green, Blue)<-") { drawable ->
+            drawable.setMinAndMaxFrame("Green Section", "Blue Section", false)
+            drawable.frame = drawable.maxFrame.toInt()
+        }
+
+        withDrawable("Tests/RGBMarker.json", "Marker", "[Green, Blue]<-") { drawable ->
+            drawable.setMinAndMaxFrame("Green Section", "Blue Section", true)
+            drawable.frame = drawable.maxFrame.toInt()
+        }
     }
 
     private suspend fun testText() {
diff --git a/LottieSample/src/main/assets/Tests/RGBMarker.json b/LottieSample/src/main/assets/Tests/RGBMarker.json
new file mode 100644
index 0000000..7e00a45
--- /dev/null
+++ b/LottieSample/src/main/assets/Tests/RGBMarker.json
@@ -0,0 +1 @@
+{"v":"5.5.8","fr":29.9700012207031,"ip":0,"op":181.000007372281,"w":400,"h":400,"nm":"Marker","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,200,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[350,350],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":1,"k":[{"t":0,"s":[1,0,0,1],"h":1},{"t":60,"s":[0,1,0,1],"h":1},{"t":120.0000048877,"s":[0,0,1,1],"h":1}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181.000007372281,"st":0,"bm":0}],"markers":[{"tm":0,"cm":"Red Section","dr":0},{"tm":60.0000024438501,"cm":"Green Section","dr":0},{"tm":120.0000048877,"cm":"Blue Section","dr":0}]}
\ No newline at end of file
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
index 4e0e063..82f4a64 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
@@ -601,6 +601,18 @@
   }
 
   /**
+   * Sets the minimum and maximum frame to the start marker start and the maximum frame to the end marker start.
+   * playEndMarkerStartFrame determines whether or not to play the frame that the end marker is on. If the end marker
+   * represents the end of the section that you want, it should be true. If the marker represents the beginning of the
+   * next section, it should be false.
+   *
+   * @throws IllegalArgumentException if either marker is not found.
+   */
+  public void setMinAndMaxFrame(final String startMarkerName, final String endMarkerName, final boolean playEndMarkerStartFrame) {
+    lottieDrawable.setMinAndMaxFrame(startMarkerName, endMarkerName, playEndMarkerStartFrame);
+  }
+
+  /**
    * @see #setMinFrame(int)
    * @see #setMaxFrame(int)
    */
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java b/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java
index 2cd16ab..15af03f 100644
--- a/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java
+++ b/lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java
@@ -592,6 +592,39 @@
   }
 
   /**
+   * Sets the minimum and maximum frame to the start marker start and the maximum frame to the end marker start.
+   * playEndMarkerStartFrame determines whether or not to play the frame that the end marker is on. If the end marker
+   * represents the end of the section that you want, it should be true. If the marker represents the beginning of the
+   * next section, it should be false.
+   *
+   * @throws IllegalArgumentException if either marker is not found.
+   */
+  public void setMinAndMaxFrame(final String startMarkerName, final String endMarkerName, final boolean playEndMarkerStartFrame) {
+    if (composition == null) {
+      lazyCompositionTasks.add(new LazyCompositionTask() {
+        @Override
+        public void run(LottieComposition composition) {
+          setMinAndMaxFrame(startMarkerName, endMarkerName, playEndMarkerStartFrame);
+        }
+      });
+      return;
+    }
+    Marker startMarker = composition.getMarker(startMarkerName);
+    if (startMarker == null) {
+      throw new IllegalArgumentException("Cannot find marker with name " + startMarkerName + ".");
+    }
+    int startFrame = (int) startMarker.startFrame;
+
+    Marker endMarker = composition.getMarker(endMarkerName);
+    if (endMarkerName == null) {
+      throw new IllegalArgumentException("Cannot find marker with name " + endMarkerName + ".");
+    }
+    int endFrame = (int) (endMarker.startFrame + (playEndMarkerStartFrame ? 1f : 0f));
+
+    setMinAndMaxFrame(startFrame, endFrame);
+  }
+
+  /**
    * @see #setMinFrame(int)
    * @see #setMaxFrame(int)
    */