Add more information to RTPVideoHeader::GetAsMetadata().

Update GetAsMetadata() to include more of the RTPVideoHeader metadata.
The intent is to be able to both get and set all of these from
JavaScript behind a flag.

Planned follow-up CLs:
1. Also get codecs-specifics, starting with VP8.
2. Test refactoring/rename: Move tests to RTPVideoHeaderTest.
3. Add RTPVideoHeader::SetFromMetadata() covering everything gettable.
4. Chrome plumbing.

Bug: webrtc:14709
Change-Id: I78679b9ff4ca749d50f309a1713e71ceabb826dd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/285084
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38756}
diff --git a/api/video/BUILD.gn b/api/video/BUILD.gn
index db85e8e..5cd543e 100644
--- a/api/video/BUILD.gn
+++ b/api/video/BUILD.gn
@@ -332,6 +332,9 @@
     "video_frame_metadata.h",
   ]
   deps = [
+    ":video_frame",
+    ":video_frame_type",
+    ":video_rtp_headers",
     "..:array_view",
     "../../rtc_base/system:rtc_export",
     "../transport/rtp:dependency_descriptor",
@@ -406,6 +409,7 @@
     ]
     deps = [
       ":video_frame_metadata",
+      ":video_frame_type",
       ":video_stream_decoder_create",
       "../../modules/rtp_rtcp:rtp_video_header",
       "../../test:test_support",
diff --git a/api/video/video_frame_metadata.cc b/api/video/video_frame_metadata.cc
index 2d72c22..842aeb0 100644
--- a/api/video/video_frame_metadata.cc
+++ b/api/video/video_frame_metadata.cc
@@ -14,6 +14,14 @@
 
 VideoFrameMetadata::VideoFrameMetadata() = default;
 
+VideoFrameType VideoFrameMetadata::GetFrameType() const {
+  return frame_type_;
+}
+
+void VideoFrameMetadata::SetFrameType(VideoFrameType frame_type) {
+  frame_type_ = frame_type;
+}
+
 uint16_t VideoFrameMetadata::GetWidth() const {
   return width_;
 }
@@ -30,6 +38,22 @@
   height_ = height;
 }
 
+VideoRotation VideoFrameMetadata::GetRotation() const {
+  return rotation_;
+}
+
+void VideoFrameMetadata::SetRotation(VideoRotation rotation) {
+  rotation_ = rotation;
+}
+
+VideoContentType VideoFrameMetadata::GetContentType() const {
+  return content_type_;
+}
+
+void VideoFrameMetadata::SetContentType(VideoContentType content_type) {
+  content_type_ = content_type;
+}
+
 absl::optional<int64_t> VideoFrameMetadata::GetFrameId() const {
   return frame_id_;
 }
@@ -75,4 +99,29 @@
                                     decode_target_indications.end());
 }
 
+bool VideoFrameMetadata::GetIsLastFrameInPicture() const {
+  return is_last_frame_in_picture_;
+}
+
+void VideoFrameMetadata::SetIsLastFrameInPicture(
+    bool is_last_frame_in_picture) {
+  is_last_frame_in_picture_ = is_last_frame_in_picture;
+}
+
+uint8_t VideoFrameMetadata::GetSimulcastIdx() const {
+  return simulcast_idx_;
+}
+
+void VideoFrameMetadata::SetSimulcastIdx(uint8_t simulcast_idx) {
+  simulcast_idx_ = simulcast_idx;
+}
+
+VideoCodecType VideoFrameMetadata::GetCodec() const {
+  return codec_;
+}
+
+void VideoFrameMetadata::SetCodec(VideoCodecType codec) {
+  codec_ = codec;
+}
+
 }  // namespace webrtc
diff --git a/api/video/video_frame_metadata.h b/api/video/video_frame_metadata.h
index 0e8b268..6e3f32f 100644
--- a/api/video/video_frame_metadata.h
+++ b/api/video/video_frame_metadata.h
@@ -17,6 +17,10 @@
 #include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "api/transport/rtp/dependency_descriptor.h"
+#include "api/video/video_codec_type.h"
+#include "api/video/video_content_type.h"
+#include "api/video/video_frame_type.h"
+#include "api/video/video_rotation.h"
 #include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
@@ -29,12 +33,21 @@
   VideoFrameMetadata(const VideoFrameMetadata&) = default;
   VideoFrameMetadata& operator=(const VideoFrameMetadata&) = default;
 
+  VideoFrameType GetFrameType() const;
+  void SetFrameType(VideoFrameType frame_type);
+
   uint16_t GetWidth() const;
   void SetWidth(uint16_t width);
 
   uint16_t GetHeight() const;
   void SetHeight(uint16_t height);
 
+  VideoRotation GetRotation() const;
+  void SetRotation(VideoRotation rotation);
+
+  VideoContentType GetContentType() const;
+  void SetContentType(VideoContentType content_type);
+
   absl::optional<int64_t> GetFrameId() const;
   void SetFrameId(absl::optional<int64_t> frame_id);
 
@@ -52,14 +65,32 @@
   void SetDecodeTargetIndications(
       rtc::ArrayView<const DecodeTargetIndication> decode_target_indications);
 
+  bool GetIsLastFrameInPicture() const;
+  void SetIsLastFrameInPicture(bool is_last_frame_in_picture);
+
+  uint8_t GetSimulcastIdx() const;
+  void SetSimulcastIdx(uint8_t simulcast_idx);
+
+  VideoCodecType GetCodec() const;
+  void SetCodec(VideoCodecType codec);
+
  private:
+  VideoFrameType frame_type_ = VideoFrameType::kEmptyFrame;
   int16_t width_ = 0;
   int16_t height_ = 0;
+  VideoRotation rotation_ = VideoRotation::kVideoRotation_0;
+  VideoContentType content_type_ = VideoContentType::UNSPECIFIED;
+
+  // Corresponding to GenericDescriptorInfo.
   absl::optional<int64_t> frame_id_;
   int spatial_index_ = 0;
   int temporal_index_ = 0;
   absl::InlinedVector<int64_t, 5> frame_dependencies_;
   absl::InlinedVector<DecodeTargetIndication, 10> decode_target_indications_;
+
+  bool is_last_frame_in_picture_ = true;
+  uint8_t simulcast_idx_ = 0;
+  VideoCodecType codec_ = VideoCodecType::kVideoCodecGeneric;
 };
 }  // namespace webrtc
 
diff --git a/api/video/video_frame_metadata_unittest.cc b/api/video/video_frame_metadata_unittest.cc
index c8b1c08..1dd39e9 100644
--- a/api/video/video_frame_metadata_unittest.cc
+++ b/api/video/video_frame_metadata_unittest.cc
@@ -10,6 +10,7 @@
 
 #include "api/video/video_frame_metadata.h"
 
+#include "api/video/video_frame_type.h"
 #include "modules/rtp_rtcp/source/rtp_video_header.h"
 #include "test/gmock.h"
 #include "test/gtest.h"
@@ -20,6 +21,16 @@
 using ::testing::ElementsAre;
 using ::testing::IsEmpty;
 
+// TODO(https://crbug.com/webrtc/14709): Move all of these tests to
+// rtp_video_header_unittest.cc, they're excercising GetAsMetadata().
+
+TEST(VideoFrameMetadata, GetFrameTypeReturnsCorrectValue) {
+  RTPVideoHeader video_header;
+  video_header.frame_type = VideoFrameType::kVideoFrameKey;
+  VideoFrameMetadata metadata = video_header.GetAsMetadata();
+  EXPECT_EQ(metadata.GetFrameType(), VideoFrameType::kVideoFrameKey);
+}
+
 TEST(VideoFrameMetadata, GetWidthReturnsCorrectValue) {
   RTPVideoHeader video_header;
   video_header.width = 1280u;
@@ -34,6 +45,20 @@
   EXPECT_EQ(metadata.GetHeight(), video_header.height);
 }
 
+TEST(VideoFrameMetadata, GetRotationReturnsCorrectValue) {
+  RTPVideoHeader video_header;
+  video_header.rotation = VideoRotation::kVideoRotation_90;
+  VideoFrameMetadata metadata = video_header.GetAsMetadata();
+  EXPECT_EQ(metadata.GetRotation(), VideoRotation::kVideoRotation_90);
+}
+
+TEST(VideoFrameMetadata, GetContentTypeReturnsCorrectValue) {
+  RTPVideoHeader video_header;
+  video_header.content_type = VideoContentType::SCREENSHARE;
+  VideoFrameMetadata metadata = video_header.GetAsMetadata();
+  EXPECT_EQ(metadata.GetContentType(), VideoContentType::SCREENSHARE);
+}
+
 TEST(VideoFrameMetadata, GetFrameIdReturnsCorrectValue) {
   RTPVideoHeader video_header;
   RTPVideoHeader::GenericDescriptorInfo& generic =
@@ -116,5 +141,26 @@
   EXPECT_THAT(metadata.GetDecodeTargetIndications(), IsEmpty());
 }
 
+TEST(VideoFrameMetadata, GetIsLastFrameInPictureReturnsCorrectValue) {
+  RTPVideoHeader video_header;
+  video_header.is_last_frame_in_picture = false;
+  VideoFrameMetadata metadata = video_header.GetAsMetadata();
+  EXPECT_FALSE(metadata.GetIsLastFrameInPicture());
+}
+
+TEST(VideoFrameMetadata, GetSimulcastIdxReturnsCorrectValue) {
+  RTPVideoHeader video_header;
+  video_header.simulcastIdx = 123;
+  VideoFrameMetadata metadata = video_header.GetAsMetadata();
+  EXPECT_EQ(metadata.GetSimulcastIdx(), 123);
+}
+
+TEST(VideoFrameMetadata, GetCodecReturnsCorrectValue) {
+  RTPVideoHeader video_header;
+  video_header.codec = VideoCodecType::kVideoCodecVP9;
+  VideoFrameMetadata metadata = video_header.GetAsMetadata();
+  EXPECT_EQ(metadata.GetCodec(), VideoCodecType::kVideoCodecVP9);
+}
+
 }  // namespace
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_video_header.cc b/modules/rtp_rtcp/source/rtp_video_header.cc
index d800b7d..1da43ee 100644
--- a/modules/rtp_rtcp/source/rtp_video_header.cc
+++ b/modules/rtp_rtcp/source/rtp_video_header.cc
@@ -23,8 +23,11 @@
 
 VideoFrameMetadata RTPVideoHeader::GetAsMetadata() const {
   VideoFrameMetadata metadata;
+  metadata.SetFrameType(frame_type);
   metadata.SetWidth(width);
   metadata.SetHeight(height);
+  metadata.SetRotation(rotation);
+  metadata.SetContentType(content_type);
   if (generic) {
     metadata.SetFrameId(generic->frame_id);
     metadata.SetSpatialIndex(generic->spatial_index);
@@ -32,6 +35,9 @@
     metadata.SetFrameDependencies(generic->dependencies);
     metadata.SetDecodeTargetIndications(generic->decode_target_indications);
   }
+  metadata.SetIsLastFrameInPicture(is_last_frame_in_picture);
+  metadata.SetSimulcastIdx(simulcastIdx);
+  metadata.SetCodec(codec);
   return metadata;
 }