In vp9 encoder fuzzer exclude testing unsupported bitrate configurations

Bug: chromium:1251158, chromium:1250115
Change-Id: I8c96d7ea63dcde9ae8aeb4af9ea0543f67286062
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232612
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Emil Lundmark <lndmrk@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35065}
diff --git a/test/fuzzers/vp9_encoder_references_fuzzer.cc b/test/fuzzers/vp9_encoder_references_fuzzer.cc
index 3d8ceb7..5acea13 100644
--- a/test/fuzzers/vp9_encoder_references_fuzzer.cc
+++ b/test/fuzzers/vp9_encoder_references_fuzzer.cc
@@ -247,6 +247,46 @@
                                 /*max_payload_size=*/0);
 }
 
+bool IsSupported(int num_spatial_layers,
+                 int num_temporal_layers,
+                 const VideoBitrateAllocation& allocation) {
+  // VP9 encoder doesn't support certain configurations.
+  // BitrateAllocator shouldn't produce them.
+  if (allocation.get_sum_bps() == 0) {
+    // Ignore allocation that turns off all the layers.
+    // In such a case it is up to upper layer code not to call Encode.
+    return false;
+  }
+
+  for (int tid = 0; tid < num_temporal_layers; ++tid) {
+    int min_enabled_spatial_id = -1;
+    int max_enabled_spatial_id = -1;
+    int num_enabled_spatial_layers = 0;
+    for (int sid = 0; sid < num_spatial_layers; ++sid) {
+      if (allocation.GetBitrate(sid, tid) > 0) {
+        if (min_enabled_spatial_id == -1) {
+          min_enabled_spatial_id = sid;
+        }
+        max_enabled_spatial_id = sid;
+        ++num_enabled_spatial_layers;
+      }
+    }
+    if (num_enabled_spatial_layers == 0) {
+      // Each temporal layer should be enabled because skipping a full frame is
+      // not supported in non-flexible mode.
+      return false;
+    }
+    if (max_enabled_spatial_id - min_enabled_spatial_id + 1 !=
+        num_enabled_spatial_layers) {
+      // To avoid odd spatial dependencies, there should be no gaps in active
+      // spatial layers.
+      return false;
+    }
+  }
+
+  return true;
+}
+
 struct LibvpxState {
   LibvpxState() {
     pkt.kind = VPX_CODEC_CX_FRAME_PKT;
@@ -492,9 +532,9 @@
             parameters.bitrate.SetBitrate(sid, tid, kBitrateEnabledBps);
           }
         }
-        // Ignore allocation that turns off all the layers. in such case
-        // it is up to upper-layer code not to call Encode.
-        if (parameters.bitrate.get_sum_bps() > 0) {
+        if (IsSupported(codec.VP9()->numberOfSpatialLayers,
+                        codec.VP9()->numberOfTemporalLayers,
+                        parameters.bitrate)) {
           encoder.SetRates(parameters);
         }
       } break;