Fix an issue in usage of external frame flags.

For the case where the flags are passed in externally:
remove the constraint that LAST must be one of the references.

For this issue added an example for 3 temporal layers,
where the second top enhancement layer only predicts/references
the GF reference (not LAST).

Change-Id: Ic5f7cef5032e214ae0df4c61069392a425e40f99
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 67802f2..f8ea834 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -6186,34 +6186,30 @@
   // should be consistent with internal reference frame selection. Need to
   // ensure that there is not conflict between the two. In AV1 encoder, the
   // priority rank for 7 reference frames are: LAST, ALTREF, LAST2, LAST3,
-  // GOLDEN, BWDREF, ALTREF2. If only one reference frame is used, it must be
-  // LAST.
+  // GOLDEN, BWDREF, ALTREF2.
   cpi->ext_ref_frame_flags = AOM_REFFRAME_ALL;
   if (flags &
       (AOM_EFLAG_NO_REF_LAST | AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
        AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF | AOM_EFLAG_NO_REF_BWD |
        AOM_EFLAG_NO_REF_ARF2)) {
-    if (flags & AOM_EFLAG_NO_REF_LAST) {
-      cpi->ext_ref_frame_flags = 0;
+    int ref = AOM_REFFRAME_ALL;
+
+    if (flags & AOM_EFLAG_NO_REF_LAST) ref ^= AOM_LAST_FLAG;
+    if (flags & AOM_EFLAG_NO_REF_LAST2) ref ^= AOM_LAST2_FLAG;
+    if (flags & AOM_EFLAG_NO_REF_LAST3) ref ^= AOM_LAST3_FLAG;
+
+    if (flags & AOM_EFLAG_NO_REF_GF) ref ^= AOM_GOLD_FLAG;
+
+    if (flags & AOM_EFLAG_NO_REF_ARF) {
+      ref ^= AOM_ALT_FLAG;
+      ref ^= AOM_BWD_FLAG;
+      ref ^= AOM_ALT2_FLAG;
     } else {
-      int ref = AOM_REFFRAME_ALL;
-
-      if (flags & AOM_EFLAG_NO_REF_LAST2) ref ^= AOM_LAST2_FLAG;
-      if (flags & AOM_EFLAG_NO_REF_LAST3) ref ^= AOM_LAST3_FLAG;
-
-      if (flags & AOM_EFLAG_NO_REF_GF) ref ^= AOM_GOLD_FLAG;
-
-      if (flags & AOM_EFLAG_NO_REF_ARF) {
-        ref ^= AOM_ALT_FLAG;
-        ref ^= AOM_BWD_FLAG;
-        ref ^= AOM_ALT2_FLAG;
-      } else {
-        if (flags & AOM_EFLAG_NO_REF_BWD) ref ^= AOM_BWD_FLAG;
-        if (flags & AOM_EFLAG_NO_REF_ARF2) ref ^= AOM_ALT2_FLAG;
-      }
-
-      av1_use_as_reference(cpi, ref);
+      if (flags & AOM_EFLAG_NO_REF_BWD) ref ^= AOM_BWD_FLAG;
+      if (flags & AOM_EFLAG_NO_REF_ARF2) ref ^= AOM_ALT2_FLAG;
     }
+
+    av1_use_as_reference(cpi, ref);
   }
 
   if (flags &
diff --git a/examples/svc_encoder_rtc.c b/examples/svc_encoder_rtc.c
index 62ff8a0..c5d97cd 100644
--- a/examples/svc_encoder_rtc.c
+++ b/examples/svc_encoder_rtc.c
@@ -30,7 +30,7 @@
 
 void usage_exit(void) { exit(EXIT_FAILURE); }
 
-static int mode_to_num_layers[3] = { 1, 2, 3 };
+static int mode_to_num_layers[4] = { 1, 2, 3, 3 };
 
 // For rate control encoding stats.
 struct RateControlMetrics {
@@ -300,6 +300,33 @@
         layer_flags |= AOM_EFLAG_NO_REF_GF;
       }
       break;
+    case 3:
+      // 3-layer: but middle layer updates GF, so 2nd TL2 will only
+      // reference GF (not LAST). Other frames only reference LAST.
+      //   1    3   5    7
+      //     2        6
+      // 0        4        8
+      if (frame_cnt % 4 == 0) {
+        // Base layer.
+        layer_id->temporal_layer_id = 0;
+        // Update LAST on layer 0, only reference LAST.
+        ref_frame_config->refresh[0] = 1;
+        layer_flags |= AOM_EFLAG_NO_REF_GF;
+      } else if ((frame_cnt - 1) % 4 == 0) {
+        layer_id->temporal_layer_id = 2;
+        // First top layer: no updates, only reference LAST (TL0).
+        layer_flags |= AOM_EFLAG_NO_REF_GF;
+      } else if ((frame_cnt - 2) % 4 == 0) {
+        layer_id->temporal_layer_id = 1;
+        // Middle layer (TL1): update GF, only reference LAST (TL0).
+        ref_frame_config->refresh[3] = 1;
+        layer_flags |= AOM_EFLAG_NO_REF_GF;
+      } else if ((frame_cnt - 3) % 4 == 0) {
+        layer_id->temporal_layer_id = 2;
+        // Second top layer: no updates, only reference GF.
+        layer_flags |= AOM_EFLAG_NO_REF_LAST;
+      }
+      break;
     default: assert(0); die("Error: Unsupported temporal layering mode!\n");
   }
   return layer_flags;