[go: nahoru, domu]

media/gpu: Support keyframeless VP9 resolution changes for testing

VP9 verification sets "frm_resize" and "sub8x8_sf" [1] change
resolutions mid-stream without Key-frames. This is an arcane
feature and rare in the wild, where the rule is to have keyframes
to signal new resolutions.

ToT VP9Decoder considers any resolution changes a kConfigChange,
which causes the client to drop reference frames and reallocate
surfaces and context(s). But VA-API VideoDecoders on Intel and
AMD do support reusing the current context and surfaces for
smaller resolutions; https://crrev.com/c/4032552 did just that,
hence verifying the test vectors, but breaking DRM overlays ([2]),
so it was reverted.

In the large scheme of things, though, we'd rather reallocate the
context and surfaces when the resolution decreases (to have a
smaller mem footprint, not to mention to keep DRM overlays working),
rather than reusing things just to satisfy a theoretical concern.

So after a few tries at fixing this in code ([3,4] - ugly stuff),
I decided to give up and take up the suggestion in [5] to make
this a test only feature. With that, this CL adds a test flag and
sets it from v_d_a_tests code.

[1] https://www.webmproject.org/vp9/levels/#test-descriptions
[2] I dug into this for a while and I believe this was due to
VAAPI reusing |coded_size| and reducing the visible area while
the DRM API really needed both to be accurate. Maybe I'll dig
some more and try to find a repro case to file a bug.
Also note that FFmpeg+VA_API does support this non-reallocation
mode but would have the same DRM overlays issue if it was to
support them.
[3] https://crrev.com/c/4409593
[4] https://crrev.com/c/4437095
[5] https://crrev.com/c/4409593/2/media/gpu/vaapi/vaapi_video_decoder.cc#1145

Bug: b:207057398

Change-Id: Idb920f9e8e12704148cacc68befd5c5fb480e0ca
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4444189
Commit-Queue: Miguel Casas-Sanchez <mcasas@chromium.org>
Reviewed-by: Andres Calderon Jaramillo <andrescj@chromium.org>
Code-Coverage: Findit <findit-for-me@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#1135030}
diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc
index 7d9fcbb..1e5bb2b3 100644
--- a/media/gpu/vp9_decoder.cc
+++ b/media/gpu/vp9_decoder.cc
@@ -291,11 +291,20 @@
     }
 
     DCHECK(!new_pic_size.IsEmpty());
-    if (new_pic_size != pic_size_ || new_profile != profile_ ||
-        curr_frame_hdr_->bit_depth != bit_depth_) {
+
+    const bool is_pic_size_different = new_pic_size != pic_size_;
+    const bool is_pic_size_larger = new_pic_size.width() > pic_size_.width() ||
+                                    new_pic_size.height() > pic_size_.height();
+    const bool is_new_configuration_different_enough =
+        (ignore_resolution_changes_to_smaller_for_testing_
+             ? is_pic_size_larger
+             : is_pic_size_different) ||
+        new_profile != profile_ || curr_frame_hdr_->bit_depth != bit_depth_;
+
+    if (is_new_configuration_different_enough) {
       DVLOG(1) << "New profile: " << GetProfileName(new_profile)
-               << ", New resolution: " << new_pic_size.ToString()
-               << ", New bit depth: "
+               << ", new resolution: " << new_pic_size.ToString()
+               << ", new bit depth: "
                << base::strict_cast<int>(curr_frame_hdr_->bit_depth);
 
       if (!curr_frame_hdr_->IsKeyframe() &&