[go: nahoru, domu]

Multiplanar: Add GetVideoColorSpace() for various decoders

This change adds GetVideoColorSpace() that returns the color space
set to the CodecPicture for various decoders - av1, h264, h265, vp8
and vp9. It stores the VideoColorSpace within decoder which is then
used for comparison with the new color space set based on preference
between key frame's color space (header) and the container color
space. Upon differences in color space, a ColorSpaceChange is triggered
which recreates picture buffers and in turn recreates shared images.

Bug: 1444189
Change-Id: I232838233c365a0e01c87c26e289e6a7766b4726
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4567152
Commit-Queue: Saifuddin Hitawala <hitawala@chromium.org>
Reviewed-by: Dan Sanders <sandersd@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1151419}
diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc
index af26ea05..f0958952 100644
--- a/media/gpu/vp9_decoder.cc
+++ b/media/gpu/vp9_decoder.cc
@@ -289,6 +289,14 @@
       return kDecodeError;
     }
 
+    VideoColorSpace new_color_space;
+    // For VP9, container color spaces override video stream color spaces.
+    if (container_color_space_.IsSpecified()) {
+      new_color_space = container_color_space_;
+    } else if (curr_frame_hdr_->GetColorSpace().IsSpecified()) {
+      new_color_space = curr_frame_hdr_->GetColorSpace();
+    }
+
     DCHECK(!new_pic_size.IsEmpty());
 
     const bool is_pic_size_different = new_pic_size != pic_size_;
@@ -334,10 +342,24 @@
       visible_rect_ = new_render_rect;
       profile_ = new_profile;
       bit_depth_ = curr_frame_hdr_->bit_depth;
+      picture_color_space_ = new_color_space;
       size_change_failure_counter_ = 0;
       return kConfigChange;
     }
 
+    if (new_color_space.IsSpecified() &&
+        new_color_space != picture_color_space_ &&
+        curr_frame_hdr_->IsKeyframe()) {
+      // TODO(posciak): This requires us to be on a keyframe (see above) and is
+      // required, because VDA clients expect all surfaces to be returned before
+      // they can cycle surface sets after receiving kConfigChange.
+      // This is only an implementation detail of VDAs and can be improved.
+      ref_frames_.Clear();
+
+      picture_color_space_ = new_color_space;
+      return kColorSpaceChange;
+    }
+
     scoped_refptr<VP9Picture> pic = accelerator_->CreateVP9Picture();
     if (!pic) {
       return kRanOutOfSurfaces;
@@ -349,11 +371,8 @@
 
     pic->set_decrypt_config(std::move(decrypt_config_));
 
-    // For VP9, container color spaces override video stream color spaces.
-    if (container_color_space_.IsSpecified())
-      pic->set_colorspace(container_color_space_);
-    else if (curr_frame_hdr_)
-      pic->set_colorspace(curr_frame_hdr_->GetColorSpace());
+    // Set the color space for the picture.
+    pic->set_colorspace(picture_color_space_);
 
     pic->frame_hdr = std::move(curr_frame_hdr_);
 
@@ -440,6 +459,10 @@
   return chroma_sampling_;
 }
 
+VideoColorSpace VP9Decoder::GetVideoColorSpace() const {
+  return picture_color_space_;
+}
+
 absl::optional<gfx::HDRMetadata> VP9Decoder::GetHDRMetadata() const {
   // VP9 only allow HDR metadata exists in the container.
   return absl::nullopt;