Fix color space in Dav1dDecoder

Propagate color space data from dav1d sequence header.

Bug: webrtc:456521750
Change-Id: I80fae22c1bea1682128beee12f74191b5736e89f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/420360
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#46131}
diff --git a/AUTHORS b/AUTHORS
index 49e1b80..7ac1af3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -17,6 +17,7 @@
 Alexander Brauckmann <a.brauckmann@gmail.com>
 Alexandre Gouaillard <agouaillard@gmail.com>
 Alex Henrie <alexhenrie24@gmail.com>
+Ambareesh Balaji <ambareeshbalaji@gmail.com>
 Andrei Volykhin <andrei.volykhin@gmail.com>
 Andrew MacDonald <andrew@webrtc.org>
 Andrey Efremov <yoklmnprst@ya.ru>
diff --git a/modules/video_coding/codecs/av1/BUILD.gn b/modules/video_coding/codecs/av1/BUILD.gn
index 8b635ef..04d2d3c 100644
--- a/modules/video_coding/codecs/av1/BUILD.gn
+++ b/modules/video_coding/codecs/av1/BUILD.gn
@@ -43,6 +43,7 @@
     "../../../../api/environment",
     "../../../../api/video:encoded_image",
     "../../../../api/video:video_frame",
+    "../../../../api/video:video_rtp_headers",
     "../../../../api/video_codecs:video_codecs_api",
     "../../../../common_video",
     "../../../../rtc_base:logging",
@@ -138,6 +139,7 @@
       "../../../../api/video:video_bitrate_allocation",
       "../../../../api/video:video_frame",
       "../../../../api/video:video_frame_type",
+      "../../../../api/video:video_rtp_headers",
       "../../../../api/video_codecs:scalability_mode",
       "../../../../api/video_codecs:video_codecs_api",
       "../../../../rtc_base:checks",
diff --git a/modules/video_coding/codecs/av1/dav1d_decoder.cc b/modules/video_coding/codecs/av1/dav1d_decoder.cc
index 235916f..7a52dfa 100644
--- a/modules/video_coding/codecs/av1/dav1d_decoder.cc
+++ b/modules/video_coding/codecs/av1/dav1d_decoder.cc
@@ -18,6 +18,7 @@
 #include "api/environment/environment.h"
 #include "api/ref_counted_base.h"
 #include "api/scoped_refptr.h"
+#include "api/video/color_space.h"
 #include "api/video/encoded_image.h"
 #include "api/video/video_frame.h"
 #include "api/video/video_frame_buffer.h"
@@ -214,12 +215,23 @@
     return WEBRTC_VIDEO_CODEC_ERROR;
   }
 
+  ColorSpace color_space(
+      ColorSpace::PrimaryID::kUnspecified, ColorSpace::TransferID::kUnspecified,
+      ColorSpace::MatrixID::kUnspecified,
+      dav1d_picture.seq_hdr->color_range ? ColorSpace::RangeID::kFull
+                                         : ColorSpace::RangeID::kLimited);
+  // AV1 color space defines match ISO 23001-8:2016 via ISO/IEC 23091-4/ITU-T
+  // H.273. https://aomediacodec.github.io/av1-spec/#color-config-semantics
+  color_space.set_primaries_from_uint8(dav1d_picture.seq_hdr->pri);
+  color_space.set_transfer_from_uint8(dav1d_picture.seq_hdr->trc);
+  color_space.set_matrix_from_uint8(dav1d_picture.seq_hdr->mtrx);
+
   VideoFrame decoded_frame =
       VideoFrame::Builder()
           .set_video_frame_buffer(wrapped_buffer)
           .set_rtp_timestamp(encoded_image.RtpTimestamp())
           .set_ntp_time_ms(encoded_image.ntp_time_ms_)
-          .set_color_space(encoded_image.ColorSpace())
+          .set_color_space(color_space)
           .build();
 
   // Corresponds to QP_base in
diff --git a/modules/video_coding/codecs/av1/dav1d_decoder_unittest.cc b/modules/video_coding/codecs/av1/dav1d_decoder_unittest.cc
index 08b8682..1c6477b 100644
--- a/modules/video_coding/codecs/av1/dav1d_decoder_unittest.cc
+++ b/modules/video_coding/codecs/av1/dav1d_decoder_unittest.cc
@@ -18,6 +18,7 @@
 #include "api/array_view.h"
 #include "api/environment/environment.h"
 #include "api/environment/environment_factory.h"
+#include "api/video/color_space.h"
 #include "api/video/encoded_image.h"
 #include "api/video/video_frame.h"
 #include "api/video_codecs/video_decoder.h"
@@ -39,6 +40,11 @@
     0x20, 0x03, 0xe0, 0x01, 0xf2, 0xb0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
     0x00, 0xf2, 0x44, 0xd6, 0xa5, 0x3b, 0x7c, 0x8b, 0x7c, 0x8c, 0x6b, 0x9a};
 
+constexpr uint8_t kAv1FrameWithBT709FullRangeColorSpace[] = {
+    0x12, 0x00, 0x0a, 0x0d, 0x00, 0x00, 0x00, 0x02, 0xaf, 0xff, 0x89, 0x5f,
+    0x22, 0x02, 0x02, 0x03, 0x08, 0x32, 0x0e, 0x10, 0x00, 0xac, 0x02, 0x05,
+    0x14, 0x20, 0x81, 0x00, 0x02, 0x00, 0x95, 0xe1, 0xe0};
+
 EncodedImage CreateEncodedImage(ArrayView<const uint8_t> data) {
   EncodedImage image;
   image.SetEncodedData(EncodedImageBuffer::Create(data.data(), data.size()));
@@ -113,6 +119,18 @@
   EXPECT_EQ(decoder.decoded_frame().height(), 20);
 }
 
+TEST(Dav1dDecoderTest, SetsColorSpaceOnDecodedFrame) {
+  TestAv1Decoder decoder(CreateEnvironment());
+  decoder.Decode(
+      CreateEncodedImage(kAv1FrameWithBT709FullRangeColorSpace));
+  auto color_space = decoder.decoded_frame().color_space();
+  EXPECT_TRUE(color_space.has_value());
+  EXPECT_EQ(color_space->primaries(), ColorSpace::PrimaryID::kBT709);
+  EXPECT_EQ(color_space->transfer(), ColorSpace::TransferID::kBT709);
+  EXPECT_EQ(color_space->matrix(), ColorSpace::MatrixID::kBT709);
+  EXPECT_EQ(color_space->range(), ColorSpace::RangeID::kFull);
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace webrtc